Skip to content

PDF-Handling

Die PDF-Generierung für Kundenansicht und Finalisierung basiert auf useCustomerPdfPreview() und einer workerbasierten Generierungspipeline. Der persistente Signaturzustand liegt separat in useCustomerSignatureSession().

Signatur-Session

app/composables/media/pdf/useCustomerSignatureSession.ts verwaltet den persistenten Signaturzustand für die Kundenansicht.

Aufgaben:

  • persistiert Signaturdaten über signatureStore
  • verwaltet setTenantSignature, setLandlordSignature, setBillingProviderSignature und setPartnerSignature
  • kapselt useManualSignature getrennt von der PDF-Erzeugung

PDF-Preview-Ebene

app/composables/media/pdf/useCustomerPdfPreview.ts erzeugt die Vorschau- und Finalize-PDFs. Der Composable liest Signaturen über useCustomerSignatureSession(), enthält aber keine Signatur-Setter mehr.

Der eigentliche Aufbau von SectionData liegt zentral in app/utils/pdf/section-data.ts; useCustomerPdfPreview.ts liefert nur noch geladene Stores und vorbereitete Sonderdaten wie Zählerbilder, Raumdetail-Bilder, Handschrift und Raum-Namensauflösung an diesen Helper.

Aufgaben:

  • verwaltet pdfBlobUrl, activeVariant und isGenerating
  • lädt bei Bedarf vor der Generierung Setup- und Acceptance-Daten
  • ruft den zentralen SectionData-Builder auf
  • lädt Zähler- und Raumdetail-Bilder aus IndexedDB
  • bereitet Bilder, Logos, Handschrift und Signaturen für PDF-sichere Raster-Ausgabe auf

Generierungspfad

Varianten

Unterstützte Varianten:

  • extern
  • intern

Die Variantenauswahl beeinflusst die Sichtbarkeit von Sektionen über die zusammengeführte Setup-Konfiguration:

  • showExtern
  • showIntern

Dokumentdefinition

app/utils/pdf/protocol-main.ts erstellt die pdfmake-Definition.

Das generierte Dokument enthält:

  • Metadaten-Headerblock
  • Mieter- und Wohnungsinformationen
  • Sektionsausgabe aus der Sektions-Registry
  • Signaturseite
  • optionale Proxy-Nachweise direkt nach der Signaturseite
  • serialisierte Metadaten für dynamische Header- und Footer-Renderfunktionen im Worker

Sektions-Registry

app/utils/pdf/section-generators.ts ordnet Generatorfunktionen logischen Sektions-Descriptoren zu. app/utils/pdf/section-registry.ts expandiert daraus die Runtime-Schlüssel und Aliase über die gemeinsamen Section-Metadaten.

Die Registry ist verantwortlich für:

  • die Auswahl des Generators pro Sektion über SECTION_PDF_GENERATORS
  • die Wiederverwendung kanonischer Keys und Alias-Keys ohne doppelte Handpflege
  • das Umhüllen generierter Inhalte mit pdfTextTop und pdfTextBottom aus der Setup-Konfiguration

SectionData-Builder

app/utils/pdf/section-data.ts hält die zentrale Zuordnung zwischen PDF-relevanten Stores und den Feldern von SectionData.

Der Builder ist verantwortlich für:

  • die Ableitung der PDF-Daten aus der bestehenden Store-Registry statt aus einem handgeschriebenen Objektblock im Session-Composable
  • die Bündelung von Sonderfällen wie meterImages, roomDetailImages, vorbereiteten otherRemarks und tenantConfirmationFields
  • einen einzelnen Wartungspunkt, wenn eine PDF-Sektion neue oder geänderte Daten benötigt

Bildgalerien innerhalb von Tabellen werden über app/utils/pdf/imageTableRows.ts erzeugt, damit Zählerbilder, Raumdetail-Bilder und spätere bildbasierte Sektionen dieselbe Tabellen-Galerie verwenden. Das Layout liest die globalen PDF-Bildeinstellungen aus SectionData.pdfImageSettings: automatische oder feste Spaltenzahl, maximale Bildhöhe und die optionale Ausgabe von Bildbeschriftungen.

Einzelne Bilder können im Upload-Panel über pdfSinglePage als eigene PDF-Seite markiert werden. useCustomerPdfPreview.ts sammelt diese Bilder über buildPdfImagesForEntries(...) aus app/utils/pdf/singlePageImages.ts, entfernt sie aus der normalen Bildertabelle, rendert vorhandene Bildeditor-Annotationen in das Bild und übergibt sie als singlePageImages an generateProtocolPdf(). Die erzeugte Seite folgt demselben Seitenaufbau wie der Bevollmächtigten-Nachweis: eigener Seitenumbruch, fachlicher Kontext, Editor-Daten und Bildbeschreibung.

Beim Erweitern einer Sektion mit Bildanhängen ist buildPdfImagesForEntries(...) der Einstiegspunkt: Eintragliste, Upload-Loader, Inline-Mapping und Kontextzeilen reichen aus. Standalone-Bilder wie der Bevollmächtigten-Nachweis verwenden createUploadPdfPageImage(...), damit sie dieselbe PdfPageImage-Form nutzen.

Die generische Vorschau in Einstellungen > Global > PDF > Bilder nutzt app/utils/pdf/image-preview.ts und denselben Tabellen-Generator wie die Kunden-PDF. Sie ist bewusst abgespeckt, muss aber Spalten, Bildhöhe, Beschriftungen und Seitenwechsel so abbilden wie die echte pdfmake-Ausgabe.

Worker-Generierung

app/composables/media/pdf/usePDFGeneration.ts sendet serialisierbare Definitionen an app/workers/pdf-generator.worker.ts.

Der Worker:

  • rekonstruiert Header- und Footer-Funktionen aus serialisierten Metadaten
  • verhindert verwaiste Sektionsüberschriften, indem eine Sektion auf die nächste Seite verschoben wird, wenn unter der Überschrift kein Inhalt mehr auf derselben Seite steht
  • verwendet benutzerdefinierte Tabellenlayouts inklusive Layouts für Signaturboxen
  • gibt die PDF-Bytes als Uint8Array zurück

Vorschau-Rendering

Die Seiten der Kundenansicht rendern das generierte PDF über PdfPageCanvas.vue. Die Komponente lädt das Dokument mit useVuePdfEmbed(...), rendert einzelne Seiten in Canvas-Elemente und stellt diese als Object-URLs dar.

Dieser Rendering-Schritt ist getrennt von der PDF-Generierung. usePDFGeneration() erstellt die PDF-Datei, PdfPageCanvas.vue stellt sie dar.

Dateierzeugung für Finalize

app/composables/protocol/finalizePdfFile.ts verwendet die Vorschau-Generierung erneut, um die finalen Upload-Dateien zu erzeugen.

Generiertes Dateinamenformat:

  • {acceptanceId}_{typeId}_{variant}.pdf