feat(accounting): fehlende PDF von Ausgangsbelegen nacherzeugen
Auf der Belegansicht erscheint "PDF nacherzeugen", wenn ein fertiggestellter Beleg kein angehängtes Dokument hat. Die PDF wird mit derselben Logik wie beim Fertigstellen erzeugt und angehängt, ohne den Datensatz zu speichern. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -730,6 +730,12 @@ const setupPage = async () => {
|
||||
await router.replace('/createDocument')
|
||||
return
|
||||
}
|
||||
|
||||
if (route.query.regeneratePdf && route.params.id) {
|
||||
await regenerateMissingPdf()
|
||||
return
|
||||
}
|
||||
|
||||
loaded.value = true
|
||||
|
||||
}
|
||||
@@ -1980,38 +1986,7 @@ const closeDocument = async () => {
|
||||
|
||||
await saveDocument("Gebucht")
|
||||
|
||||
await generateDocument()
|
||||
|
||||
let fileData = {}
|
||||
|
||||
fileData.project = itemInfo.value.project
|
||||
fileData.createddocument = itemInfo.value.id
|
||||
|
||||
let mappedType = documentStorageFallbackTypes[itemInfo.value.type] || itemInfo.value.type
|
||||
|
||||
const folders = await useEntities("folders").select()
|
||||
console.log(folders)
|
||||
fileData.folder = folders.find(i => i.function === mappedType && i.year === Number(dayjs().format("YYYY"))).id
|
||||
|
||||
const tags = await useEntities("filetags").select()
|
||||
console.log(tags)
|
||||
fileData.type = tags.find(i => i.createdDocumentType === mappedType).id
|
||||
|
||||
function dataURLtoFile(dataurl, filename) {
|
||||
var arr = dataurl.split(","),
|
||||
mime = arr[0].match(/:(.*?);/)[1],
|
||||
bstr = atob(arr[arr.length - 1]),
|
||||
n = bstr.length,
|
||||
u8arr = new Uint8Array(n);
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
return new File([u8arr], filename, {type: mime});
|
||||
}
|
||||
|
||||
let file = dataURLtoFile(uri.value, `${itemInfo.value.documentNumber}.pdf`)
|
||||
|
||||
await useFiles().uploadFiles(fileData, [file])
|
||||
await uploadGeneratedDocument()
|
||||
|
||||
guard.value = false
|
||||
|
||||
@@ -2021,6 +1996,77 @@ const closeDocument = async () => {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Erzeugt die PDF aus dem aktuellen Stand und hängt sie an den Beleg an, ohne den Datensatz zu speichern
|
||||
const uploadGeneratedDocument = async () => {
|
||||
await generateDocument()
|
||||
|
||||
if (!uri.value) throw new Error("PDF konnte nicht erzeugt werden")
|
||||
|
||||
let fileData = {}
|
||||
|
||||
fileData.project = itemInfo.value.project
|
||||
fileData.createddocument = itemInfo.value.id
|
||||
|
||||
let mappedType = documentStorageFallbackTypes[itemInfo.value.type] || itemInfo.value.type
|
||||
|
||||
const folders = await useEntities("folders").select()
|
||||
console.log(folders)
|
||||
fileData.folder = folders.find(i => i.function === mappedType && i.year === Number(dayjs().format("YYYY"))).id
|
||||
|
||||
const tags = await useEntities("filetags").select()
|
||||
console.log(tags)
|
||||
fileData.type = tags.find(i => i.createdDocumentType === mappedType).id
|
||||
|
||||
function dataURLtoFile(dataurl, filename) {
|
||||
var arr = dataurl.split(","),
|
||||
mime = arr[0].match(/:(.*?);/)[1],
|
||||
bstr = atob(arr[arr.length - 1]),
|
||||
n = bstr.length,
|
||||
u8arr = new Uint8Array(n);
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n);
|
||||
}
|
||||
return new File([u8arr], filename, {type: mime});
|
||||
}
|
||||
|
||||
let file = dataURLtoFile(uri.value, `${itemInfo.value.documentNumber}.pdf`)
|
||||
|
||||
await useFiles().uploadFiles(fileData, [file])
|
||||
}
|
||||
|
||||
const regenerateMissingPdf = async () => {
|
||||
guard.value = false
|
||||
const showPath = `/createDocument/show/${route.params.id}`
|
||||
|
||||
try {
|
||||
const document = await useEntities("createddocuments").selectSingle(route.params.id, "*,files(*)")
|
||||
|
||||
if (document?.state === "Entwurf" || document?.type === "serialInvoices") {
|
||||
toast.add({ title: "PDF kann nur für fertiggestellte Belege nacherzeugt werden", color: "error" })
|
||||
} else if ((document?.files || []).length > 0) {
|
||||
toast.add({ title: "Am Beleg ist bereits ein Dokument angehängt", color: "warning" })
|
||||
} else {
|
||||
// Vertrags- und Mandats-Watcher überschreiben beim Laden die Zahlungsdaten, für die PDF gilt der gespeicherte Stand
|
||||
const restoreStoredPaymentData = () => {
|
||||
itemInfo.value.payment_type = document.payment_type
|
||||
itemInfo.value.outgoingsepamandate = normalizeEntityId(document.outgoingsepamandate)
|
||||
}
|
||||
await nextTick()
|
||||
restoreStoredPaymentData()
|
||||
await nextTick()
|
||||
restoreStoredPaymentData()
|
||||
|
||||
await uploadGeneratedDocument()
|
||||
toast.add({ title: "PDF nacherzeugt", color: "success" })
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
toast.add({ title: "PDF konnte nicht nacherzeugt werden", description: error?.data?.error || error?.message, color: "error" })
|
||||
}
|
||||
|
||||
await router.replace(showPath)
|
||||
}
|
||||
|
||||
const getTextTemplateByType = (type, pos) => {
|
||||
|
||||
@@ -110,10 +110,18 @@ const setupPage = async () => {
|
||||
links.value = createddocuments.filter(i => i.createddocument?.id === itemInfo.value.id)
|
||||
}
|
||||
|
||||
linkedDocument.value = await useFiles().selectDocument(itemInfo.value.files[0].id)
|
||||
if (itemInfo.value.files?.length > 0) {
|
||||
linkedDocument.value = await useFiles().selectDocument(itemInfo.value.files[0].id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const canRegeneratePdf = computed(() => itemInfo.value.id
|
||||
&& itemInfo.value.state !== 'Entwurf'
|
||||
&& itemInfo.value.type !== 'serialInvoices'
|
||||
&& Array.isArray(itemInfo.value.files)
|
||||
&& itemInfo.value.files.length === 0)
|
||||
|
||||
setupPage()
|
||||
|
||||
const getStatementLike = (allocation) => allocation?.bankstatement || (typeof allocation?.bs_id === "object" ? allocation.bs_id : null)
|
||||
@@ -282,6 +290,12 @@ const togglePortalRelease = async () => {
|
||||
:loading="costCentresLoading"
|
||||
@click="openCostCentres"
|
||||
>Kostenstellen bearbeiten</UButton>
|
||||
<UButton
|
||||
v-if="canRegeneratePdf"
|
||||
icon="i-heroicons-document-arrow-down"
|
||||
variant="outline"
|
||||
@click="router.push(`/createDocument/edit/${itemInfo.id}?regeneratePdf=1`)"
|
||||
>PDF nacherzeugen</UButton>
|
||||
<!-- <UButton
|
||||
:to="dataStore.documents.find(i => i.createdDocument === itemInfo.id) ? dataStore.documents.find(i => i.createdDocument === itemInfo.id).url : ''"
|
||||
target="_blank"
|
||||
|
||||
Reference in New Issue
Block a user