feat(invoice): Stornorechnung und Rechnungskopie an Admin-Adresse
Rechnungskopie: unter Einstellungen > Firma > "Rechnungskopie an" laesst sich eine Adresse hinterlegen; jede Rechnung und Stornorechnung geht zusaetzlich als eigene Mail mit derselben E-Rechnung dorthin (lib/invoice-mail.ts). Stornorechnung: eine Rechnung wird nie geloescht. Bei Stornierung im Admin, erstatteter Retoure oder voller Erstattung bei Stripe entsteht genau eine Stornorechnung ST-JJJJ-NNNN (eigener lueckenloser Nummernkreis) mit allen Positionen und Bezug auf die Rechnung, als E-Rechnung (Gutschrift 381) an die Kundschaft und als Kopie. Gleichzeitige Ausloeser (Admin-Storno und Stripe-Webhook derselben Erstattung) enden bei einer Stornorechnung. Bestellungen mit Stornorechnung lassen sich nicht wieder oeffnen. ERP-Export: GET /api/erp/rechnungen?art=storno liefert Stornorechnungen mit Bezug (cancels), Rechnungen tragen cancelledBy; PDFs auch fuer ST-Nummern. Admin-Bestelldetail zeigt die Stornorechnung mit Download. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
508ff24aa7
commit
4d1bcbbdb7
22 files changed
+809
-16
No files matched your search
+37
-1
@@ -710,11 +710,47 @@ model Invoice {
|
||||
/// einem oeffentlich abrufbaren Pfad.
|
||||
pdfPath String?
|
||||
|
||||
order Order @relation(fields: [orderId], references: [id], onDelete: Cascade)
|
||||
order Order @relation(fields: [orderId], references: [id], onDelete: Cascade)
|
||||
cancellation CancellationInvoice?
|
||||
|
||||
@@map("invoices")
|
||||
}
|
||||
|
||||
/// Eigener fortlaufender Nummernkreis der Stornorechnungen (ST-JJJJ-NNNN),
|
||||
/// je Kalenderjahr — aus demselben Grund eine Zeile mit Sperre wie
|
||||
/// InvoiceCounter.
|
||||
model CancellationCounter {
|
||||
year Int @id
|
||||
lastNumber Int @default(0)
|
||||
|
||||
@@map("cancellation_counters")
|
||||
}
|
||||
|
||||
/// Stornorechnung: hebt eine Rechnung vollstaendig auf. Eine Rechnung wird
|
||||
/// nie geloescht oder geaendert (§ 14 UStG, GoBD); wird die Bestellung
|
||||
/// storniert oder voll erstattet, entsteht stattdessen dieser Gegenbeleg mit
|
||||
/// eigener Nummer und Bezug auf die Rechnung (lib/cancellation-invoice.ts).
|
||||
/// Hoechstens einer je Rechnung. ERPNext uebernimmt ihn als
|
||||
/// Rechnungskorrektur, die Ausgangsrechnung steht dort dann auf
|
||||
/// "Credit Note Issued".
|
||||
model CancellationInvoice {
|
||||
id String @id @default(cuid())
|
||||
invoiceId String @unique
|
||||
number String @unique
|
||||
issuedAt DateTime @default(now())
|
||||
/// Betrag der aufgehobenen Rechnung (brutto, positiv).
|
||||
totalCents Int
|
||||
/// STORNIERUNG (Admin), RETOURE (Retoure erstattet) oder ERSTATTUNG (volle Erstattung bei Stripe).
|
||||
reason String
|
||||
/// Wie Invoice.pdfPath, relativ zu INVOICE_DIR.
|
||||
pdfPath String?
|
||||
|
||||
invoice Invoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@index([issuedAt])
|
||||
@@map("cancellation_invoices")
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Marketing / Kontakt
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in new issue
Block a user