fix(accounting): Belegvorbereitung im Hintergrund ausführen und Dubletten verhindern
- „Belege vorbereiten“ startet den Lauf im Hintergrund (202) und fragt den Status ab; ein laufender Vorgang wird nicht erneut gestartet und beim Wiederöffnen der Seite weiterverfolgt - Eingangsbeleg und Dateiverknüpfung werden in einer Transaktion angelegt; ist die Datei bereits verknüpft, wird der neue Beleg verworfen - Fehler einzelner Dateien brechen den Lauf nicht mehr ab Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -64,35 +64,89 @@ const setupPage = async () => {
|
||||
items.value = await useEntities(type).select("*, vendor(id,name), statementallocations(id,amount)",sort.value.column,sort.value.direction === "asc")
|
||||
}
|
||||
|
||||
// Funktion zum Vorbereiten der Belege
|
||||
const prepareInvoices = async () => {
|
||||
isPreparing.value = true
|
||||
try {
|
||||
await $api('/api/functions/services/prepareincominginvoices', { method: 'POST' })
|
||||
// Die Belegvorbereitung läuft im Backend im Hintergrund; hier wird nur der Status abgefragt.
|
||||
const preparationEndpoint = '/api/functions/services/prepareincominginvoices'
|
||||
let preparationPollTimer = null
|
||||
|
||||
toast.add({
|
||||
title: 'Erfolg',
|
||||
description: 'Eingangsbelege wurden vorbereitet.',
|
||||
icon: 'i-heroicons-check-circle',
|
||||
color: 'green'
|
||||
})
|
||||
|
||||
// Liste neu laden
|
||||
await setupPage()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
const showPreparationResult = (status) => {
|
||||
const result = status?.result
|
||||
if (result?.error && !result.created?.length) {
|
||||
toast.add({
|
||||
title: 'Fehler',
|
||||
description: 'Beim Vorbereiten der Belege ist ein Fehler aufgetreten.',
|
||||
description: result.error,
|
||||
icon: 'i-heroicons-exclamation-circle',
|
||||
color: 'red'
|
||||
})
|
||||
} finally {
|
||||
return
|
||||
}
|
||||
|
||||
const created = result?.created?.length || 0
|
||||
const skipped = result?.skipped?.length || 0
|
||||
toast.add({
|
||||
title: 'Belegvorbereitung abgeschlossen',
|
||||
description: `${created} Eingangsbeleg(e) vorbereitet${skipped ? `, ${skipped} Datei(en) übersprungen` : ''}.`,
|
||||
icon: 'i-heroicons-check-circle',
|
||||
color: 'green'
|
||||
})
|
||||
}
|
||||
|
||||
const pollPreparation = (notify) => {
|
||||
clearTimeout(preparationPollTimer)
|
||||
preparationPollTimer = setTimeout(async () => {
|
||||
try {
|
||||
const status = await $api(preparationEndpoint)
|
||||
if (status?.running) {
|
||||
pollPreparation(notify)
|
||||
return
|
||||
}
|
||||
isPreparing.value = false
|
||||
if (notify) showPreparationResult(status)
|
||||
await setupPage()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
pollPreparation(notify)
|
||||
}
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
const prepareInvoices = async () => {
|
||||
isPreparing.value = true
|
||||
try {
|
||||
await $api(preparationEndpoint, { method: 'POST' })
|
||||
toast.add({
|
||||
title: 'Belegvorbereitung gestartet',
|
||||
description: 'Die Belege werden im Hintergrund vorbereitet.',
|
||||
icon: 'i-heroicons-sparkles'
|
||||
})
|
||||
pollPreparation(true)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
isPreparing.value = false
|
||||
toast.add({
|
||||
title: 'Fehler',
|
||||
description: 'Die Belegvorbereitung konnte nicht gestartet werden.',
|
||||
icon: 'i-heroicons-exclamation-circle',
|
||||
color: 'red'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const resumePreparationStatus = async () => {
|
||||
try {
|
||||
const status = await $api(preparationEndpoint)
|
||||
if (status?.running) {
|
||||
isPreparing.value = true
|
||||
pollPreparation(true)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => clearTimeout(preparationPollTimer))
|
||||
|
||||
setupPage()
|
||||
resumePreparationStatus()
|
||||
|
||||
const selectedColumns = ref(tempStore.columns[type] ? [...tempStore.columns[type]] : dataType.templateColumns.filter(i => !i.disabledInTable))
|
||||
if (!selectedColumns.value.find((column) => column.key === openAmountColumnKey)) {
|
||||
|
||||
Reference in New Issue
Block a user