Gutschriften Phase 2b: Vertrags-UI + Beleg-Upload + Nummernkreis-Seite

Frontend:
- CreditNotesSection im Vertragsdetail (eigene Section wie Rechnungen):
  Liste + Anlegen/Bearbeiten (Modal). Geld/Sachwert mit passenden
  Feldern, USt-Block mit Live-Vorschau Netto/USt/Brutto, Datum, Ort,
  Unterschrift, 'Ware erhalten'. Loeschen mit Bestaetigung.
- Ueberweisungsbeleg-Upload/-Anzeige/-Entfernen (nur Geld-Gutschriften).
- Nummernkreis-Verwaltung als Settings-Seite mit Live-Vorschau der
  naechsten Nummer.
- Frontend-Typen (CreditNote etc.) + creditNoteApi.

Backend:
- Ueberweisungsbeleg-Upload-Route /upload/credit-notes/:id/receipt
  (+ DELETE), Portal geblockt, Ownership ueber Vertrag.
- fileDownload: Ownership-Aufloesung fuer credit-note-receipts +
  credit-notes (Vertrag) ergaenzt.

Als Section statt Tab-Balken, weil die Vertragsansicht kartenbasiert
ist (kein bestehender Tab-Balken); spaeter umbaubar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-06 13:15:02 +02:00
co-authored by Claude Opus 4.8
parent 3580c51cb1
commit 9e38cb32f0
10 changed files with 804 additions and 6 deletions
+50
View File
@@ -57,6 +57,56 @@ export interface CustomerReferrals {
recruited: ReferralEntry[];
}
// ==================== GUTSCHRIFTEN (CREDIT NOTES) ====================
export type CreditNoteType = 'GELD' | 'SACHWERT';
export type CreditNoteCustomerType = 'PRIVAT' | 'FIRMA';
export type CreditNoteAmountBasis = 'NETTO' | 'BRUTTO';
export interface CreditNote {
id: number;
contractId: number;
number: string;
type: CreditNoteType;
sachwertDescription?: string | null;
customerType: CreditNoteCustomerType;
vatRelevant: boolean;
amountBasis: CreditNoteAmountBasis;
vatRate: number;
amountNet: number;
amountVat: number;
amountGross: number;
currency: string;
creditDate: string;
place?: string | null;
signedAt?: string | null;
goodsReceived: boolean;
receiptPath?: string | null;
pdfPath?: string | null;
notes?: string | null;
createdBy?: string | null;
createdAt: string;
updatedAt: string;
}
export interface CreditNoteDefaults {
customerType: CreditNoteCustomerType;
vatRelevant: boolean;
nextNumber: string;
}
export interface CreditNoteNumberRange {
id: number;
prefix: string;
includeYear: boolean;
separator: string;
padding: number;
nextNumber: number;
resetYearly: boolean;
currentYear: number | null;
preview?: string;
}
export interface RepresentativeAuthorization {
id: number;
customerId: number;