Gutschrift: Sachwert ohne Betrag = keine Rechnung (kein ZUGFeRD)

Eine Sachwert-Gutschrift darf betragslos sein (Betrag leer/0): dann
findet keine Rechnungsstellung statt - der Kunde hat den Gegenstand
einfach als Subvention erhalten.

- Backend: leeres amount -> 0; Sachwert erlaubt 0, Geld verlangt > 0
  (400 sonst). vatRelevant bei 0 erzwungen-false.
- PDF: betragsloser Sachwert -> Titel 'Sachwert-Uebergabe', kein
  Betrags-/USt-Block (Hinweis keine Rechnungsstellung), KEIN ZUGFeRD-
  Embedding. Mit Betrag -> unveraendert ZUGFeRD.
- Frontend: Wert-Feld bei Sachwert optional; USt-Block ausgeblendet ohne
  Betrag; Liste zeigt 'Sachwert ohne Betrag (keine Rechnung)'.

Verifiziert: Sachwert 0 -> kein factur-x.xml; Geld 0 -> 400;
Sachwert 200 -> ZUGFeRD.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-09 13:22:13 +02:00
co-authored by Claude Opus 4.8
parent 4d14390b2a
commit 6f95005530
4 changed files with 131 additions and 73 deletions
+11 -2
View File
@@ -83,12 +83,21 @@ function validateAndNormalize(input: CreateCreditNoteInput) {
? input.amountBasis
: 'BRUTTO') as CreditNoteAmountBasis;
const amount = Number(input.amount);
// Leeres/fehlendes Betragsfeld = 0. Sachwerte dürfen betragslos sein
// (reine Übergabe des Gegenstands als Subvention → keine Rechnung, s.u.);
// Geld-Gutschriften brauchen dagegen einen echten Betrag.
const amount = input.amount === undefined || input.amount === null || (input.amount as unknown) === ''
? 0
: Number(input.amount);
if (!Number.isFinite(amount) || amount < 0) {
throw new ApiError(400, 'Ungültiger Betrag');
}
if (type === 'GELD' && amount <= 0) {
throw new ApiError(400, 'Bei Geld-Gutschriften bitte einen Betrag größer 0 angeben.');
}
const vatRelevant = !!input.vatRelevant;
// Ohne Betrag gibt es keine USt (nicht-monetärer Sachwert).
const vatRelevant = amount > 0 && !!input.vatRelevant;
const vatRate = Number.isFinite(Number(input.vatRate)) ? Number(input.vatRate) : 19;
if (vatRate < 0 || vatRate > 100) {
throw new ApiError(400, 'Ungültiger USt-Satz');