diff --git a/backend/src/services/creditNotePdf.service.ts b/backend/src/services/creditNotePdf.service.ts index 82041efa..234340d8 100644 --- a/backend/src/services/creditNotePdf.service.ts +++ b/backend/src/services/creditNotePdf.service.ts @@ -158,16 +158,21 @@ export async function generateCreditNotePdf(creditNoteId: number): Promise<{ buf } // ---- Unterschriftsblock ---- - doc.moveDown(3); - const y = doc.y; - const place = cn.place || company.city || ''; - doc.fontSize(10).fillColor('#000'); - doc.text('_______________________________', 50, y); - doc.text('_______________________________', 320, y); - doc.fontSize(8).fillColor('#666'); - doc.text(`Ort/Datum${place ? ` (${place})` : ''}`, 50, y + 14); - doc.text('Unterschrift', 320, y + 14); - doc.fillColor('#000'); + // Nur bei Sachwert: das Dokument wird vom Kunden unterschrieben. Bei einer + // Geld-Überweisung ist keine Unterschrift nötig – als Beleg dient die + // hochgeladene Überweisungsbestätigung. + if (cn.type === 'SACHWERT') { + doc.moveDown(3); + const y = doc.y; + const place = cn.place || company.city || ''; + doc.fontSize(10).fillColor('#000'); + doc.text('_______________________________', 50, y); + doc.text('_______________________________', 320, y); + doc.fontSize(8).fillColor('#666'); + doc.text(`Ort/Datum${place ? ` (${place})` : ''}`, 50, y + 14); + doc.text('Unterschrift', 320, y + 14); + doc.fillColor('#000'); + } // ---- Fußzeile (Firmendaten) ---- // Position aus der Seitengeometrie berechnen, damit die Fußzeile am diff --git a/docs/todo.md b/docs/todo.md index ce04fd98..710ce537 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -97,6 +97,15 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung ## ✅ Erledigt +- [x] **🧾 Gutschrift: Beleg-Upload auch für Sachwerte + kein Unterschriftsblock bei Geld** (2026-08-12) + - **Beleg-Upload jetzt für beide Arten:** bei Geld die Überweisungsbestätigung, + bei Sachwert das **unterschriebene Dokument**. `ReceiptControls` in der Liste + für Geld UND Sachwert (Label „Überweisungsbeleg" bzw. „Unterschr. Dokument"). + Endpoint `/upload/credit-notes/:id/receipt` war schon typ-agnostisch. + - **PDF-Unterschriftsblock nur noch bei Sachwert:** eine Geld-Überweisung wird + nicht unterschrieben (Beleg = hochgeladene Überweisungsbestätigung). Bei Geld + entfällt der Unterschrift/Ort-Block im PDF; im Formular sind „Ort" + + „Unterschrift am" bei Geld ausgeblendet. Verifiziert (beide PDFs 1 Seite). - [x] **📦 Lieferschein-Nummernkreis für betragslose Sachwerte (GoBD)** (2026-08-12) - Pentester-Hinweis R142: Beim Übergang Geld→betragsloser Sachwert wurde die schon vergebene Gutschriftsnummer auf null gesetzt → **Lücke** in der GS-Serie. diff --git a/frontend/src/components/contracts/CreditNotesSection.tsx b/frontend/src/components/contracts/CreditNotesSection.tsx index 2a6a1277..105a7d56 100644 --- a/frontend/src/components/contracts/CreditNotesSection.tsx +++ b/frontend/src/components/contracts/CreditNotesSection.tsx @@ -280,22 +280,25 @@ function CreditNoteFormModal({ value={form.creditDate} onChange={(e) => set('creditDate', e.target.value)} /> - set('place', e.target.value)} - placeholder="z.B. Oldenburg" - /> + {/* Ort/Unterschrift nur bei Sachwert – Überweisung wird nicht unterschrieben. */} + {isSachwert && ( + set('place', e.target.value)} + placeholder="z.B. Oldenburg" + /> + )} -
- Der Überweisungsbeleg kann nach dem Speichern in der Liste hochgeladen werden. + {isSachwert + ? 'Das unterschriebene Dokument kann nach dem Speichern in der Liste hochgeladen werden.' + : 'Der Überweisungsbeleg kann nach dem Speichern in der Liste hochgeladen werden.'}
)} @@ -336,7 +341,7 @@ function CreditNoteFormModal({ } // ---------- Beleg-Upload (nur GELD) ---------- -function ReceiptControls({ cn, canEdit, onChanged }: { cn: CreditNote; canEdit: boolean; onChanged: () => void }) { +function ReceiptControls({ cn, canEdit, onChanged, label = 'Beleg' }: { cn: CreditNote; canEdit: boolean; onChanged: () => void; label?: string }) { const fileRef = useRef