Kontrolle: Storno einer Anzahlung bei bestehendem Schluss-Entwurf der AB abgewiesen

409 'Erst den Entwurf der Schlussrechnung löschen.'; das Storno einer Anzahlung laeuft
unter der Kundensperre.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-07 15:18:46 +00:00
1 parent e3ae152f12
commit 1bb172ad91
3 files changed
+38 -7

No files matched your search

+15 -7
View File
@@ -4,7 +4,7 @@ import { getStripe, getOrCreateStripeCustomer, stripeCustomerFields, subscriptio
import { addDays, berlinDate, daysBetween } from './dates.js'
import { RECHNUNGS_ARTEN, AB_RECHNUNGS_ARTEN, sperreRechnung } from '../auftraege/konstanten.js'
import { withLocks } from '../keyedLock.js'
import { baueRechnung, ladeFestenKunden, buche, gibProjektRechnungFrei, setzeAbAbgerechnet, pruefeVorSenden } from '../auftraege/rechnungsbau.js'
import { baueRechnung, ladeFestenKunden, buche, gibProjektRechnungFrei, setzeAbAbgerechnet, pruefeVorSenden, hatSchlussEntwurf } from '../auftraege/rechnungsbau.js'
import { createProjektRechnung, updateProjektRechnung } from '../auftraege/projektRechnungenStore.js'
import { getSettings } from './settings.js'
@@ -507,13 +507,21 @@ export async function voidInvoice(invoiceId) {
const invoice = await readInvoice(invoiceId)
if (invoice.source !== 'projekt') throw httpError(409, ABO_MESSAGE)
if (invoice.status !== 'offen' && invoice.status !== 'ueberfaellig') throw httpError(409, 'Nur offene Rechnungen können storniert werden.')
try {
await getStripe().invoices.voidInvoice(invoice.id)
await bucheStorniert(invoice.id, invoice.art)
return await readInvoice(invoice.id)
} finally {
invalidateFinanceCache()
const stornieren = async () => {
// Der Schluss-Entwurf enthaelt die Minuszeile dieser Anzahlung: wuerde sie storniert, ginge er zu niedrig hinaus
if (invoice.art === 'anzahlung' && (await hatSchlussEntwurf({ invoiceId: invoice.id, auftragIdMetadaten: invoice.auftragId }))) {
throw httpError(409, 'Erst den Entwurf der Schlussrechnung löschen.')
}
try {
await getStripe().invoices.voidInvoice(invoice.id)
await bucheStorniert(invoice.id, invoice.art)
return await readInvoice(invoice.id)
} finally {
invalidateFinanceCache()
}
}
// Eine Anzahlung unter der Sperre des Kunden: das Anlegen und Senden einer Schlussrechnung laeuft nie zwischen Pruefung und Storno
return invoice.art === 'anzahlung' && invoice.webklarCustomerId ? withLocks(sperreRechnung(invoice.webklarCustomerId), stornieren) : stornieren()
}
/** Projekt-Entwurf bei Stripe loeschen, sonst status 409 (nur Entwuerfe lassen sich loeschen). */