This commit is contained in:
2026-02-15 12:34:11 +01:00
parent be706a70f8
commit 29a84b899d

View File

@@ -7,6 +7,7 @@ import { useDraggable } from '@vueuse/core'
const dataStore = useDataStore()
const route = useRoute()
const mode = ref(route.params.mode)
const toast = useToast()
// --- Page Leave Logic ---
const isModified = ref(false) // Speichert, ob Änderungen vorgenommen wurden
@@ -119,6 +120,7 @@ const totalCalculated = computed(() => {
})
const hasAmount = (value) => value !== null && value !== undefined && value !== ""
const hasValidNumber = (value) => hasAmount(value) && Number.isFinite(Number(value))
const recalculateItem = (item, source) => {
const taxRate = Number(taxOptions.value.find(i => i.key === item.taxType)?.percentage || 0);
@@ -151,6 +153,15 @@ const moveGrossToNet = (item) => {
// --- Saving ---
const updateIncomingInvoice = async (setBooked = false) => {
if (setBooked && hasBlockingIncomingInvoiceErrors.value) {
toast.add({
title: "Buchen nicht möglich",
description: "Bitte beheben Sie zuerst die rot markierten Pflichtfehler.",
color: "rose"
})
return
}
let item = { ...itemInfo.value }
delete item.files
item.state = setBooked ? "Gebucht" : "Entwurf"
@@ -162,20 +173,32 @@ const updateIncomingInvoice = async (setBooked = false) => {
}
const findIncomingInvoiceErrors = computed(() => {
let errors = []
const errors = []
const i = itemInfo.value
if(!i.vendor) errors.push({message: "Es ist kein Lieferant ausgewählt", type: "breaking"})
if(!i.reference) errors.push({message: "Es ist keine Referenz angegeben", type: "breaking"})
if(!i.reference || !String(i.reference).trim()) errors.push({message: "Es ist keine Referenz angegeben", type: "breaking"})
if(!i.date) errors.push({message: "Es ist kein Datum ausgewählt", type: "breaking"})
if(!i.accounts || i.accounts.length === 0) errors.push({message: "Es ist keine Position vorhanden", type: "breaking"})
i.accounts.forEach((account, idx) => {
if(!account.account) errors.push({message: `Pos ${idx+1}: Keine Kategorie`, type: "breaking"})
if(account.amountNet === null) errors.push({message: `Pos ${idx+1}: Kein Betrag`, type: "breaking"})
if(!hasValidNumber(account.amountNet) && !hasValidNumber(account.amountGross)) {
errors.push({message: `Pos ${idx+1}: Kein gültiger Betrag`, type: "breaking"})
}
if(!account.taxType) errors.push({message: `Pos ${idx+1}: Kein Steuerschlüssel`, type: "breaking"})
if(hasValidNumber(account.amountNet) && !hasValidNumber(account.amountTax)) {
errors.push({message: `Pos ${idx+1}: Steuerbetrag fehlt, bitte Steuer neu berechnen`, type: "warning"})
}
})
return errors.sort((a,b) => (a.type === "breaking") ? -1 : 1)
const order = { breaking: 0, warning: 1 }
return errors.sort((a,b) => order[a.type] - order[b.type])
})
const blockingIncomingInvoiceErrors = computed(() => findIncomingInvoiceErrors.value.filter(i => i.type === "breaking"))
const warningIncomingInvoiceErrors = computed(() => findIncomingInvoiceErrors.value.filter(i => i.type === "warning"))
const hasBlockingIncomingInvoiceErrors = computed(() => blockingIncomingInvoiceErrors.value.length > 0)
</script>
<template>
@@ -208,7 +231,7 @@ const findIncomingInvoiceErrors = computed(() => {
<UButton
v-if="mode !== 'show'"
@click="updateIncomingInvoice(true)"
:disabled="findIncomingInvoiceErrors.filter(i => i.type === 'breaking').length > 0"
:disabled="hasBlockingIncomingInvoiceErrors"
>
Speichern & Buchen
</UButton>
@@ -263,14 +286,35 @@ const findIncomingInvoiceErrors = computed(() => {
<UAlert
v-if="findIncomingInvoiceErrors.length > 0"
title="Prüfung erforderlich"
:color="findIncomingInvoiceErrors.some(i => i.type === 'breaking') ? 'rose' : 'orange'"
:color="hasBlockingIncomingInvoiceErrors ? 'rose' : 'orange'"
variant="soft"
icon="i-heroicons-exclamation-triangle"
>
<template #description>
<ul class="list-disc list-inside text-sm mt-1">
<li v-for="(err, idx) in findIncomingInvoiceErrors" :key="idx">{{ err.message }}</li>
</ul>
<div class="space-y-3 text-sm mt-1">
<div v-if="blockingIncomingInvoiceErrors.length > 0">
<p class="font-semibold text-rose-700 dark:text-rose-300">Pflichtfehler</p>
<ul class="list-disc list-inside mt-1">
<li
v-for="(err, idx) in blockingIncomingInvoiceErrors"
:key="`blocking-${idx}-${err.message}`"
>
{{ err.message }}
</li>
</ul>
</div>
<div v-if="warningIncomingInvoiceErrors.length > 0">
<p class="font-semibold text-orange-700 dark:text-orange-300">Hinweise</p>
<ul class="list-disc list-inside mt-1">
<li
v-for="(err, idx) in warningIncomingInvoiceErrors"
:key="`warning-${idx}-${err.message}`"
>
{{ err.message }}
</li>
</ul>
</div>
</div>
</template>
</UAlert>