Kontrolle: Anzahlung und Schlussrechnung nehmen das Zahlungsziel der AB
Ohne daysUntilDue gilt bei Anzahlung und Schluss auftrag.zahlungszielTage (Route und createProjectInvoice), sonst weiterhin 14 Tage; eine Angabe gilt vor der AB. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d96d09f589
commit
57d1ab82c6
4 files changed
+73
-6
No files matched your search
@@ -188,7 +188,6 @@ router.delete('/buchungen/:id/zuordnung', async (req, res) => {
|
||||
// --- Rechnungen (Stripe) ----------------------------------------------------------------------------------------
|
||||
|
||||
const INVOICE_FILTERS = new Set(['alle', 'offen', 'ueberfaellig', 'bezahlt', 'entwurf'])
|
||||
const DEFAULT_DAYS_UNTIL_DUE = 14
|
||||
const createdOf = (invoice) => invoice.createdDate ?? ''
|
||||
|
||||
router.get('/rechnungen', async (req, res) => {
|
||||
@@ -226,7 +225,8 @@ router.post('/rechnungen', async (req, res) => {
|
||||
anzahlung,
|
||||
zeilentexte,
|
||||
leistungszeitraum,
|
||||
daysUntilDue: daysUntilDue ?? DEFAULT_DAYS_UNTIL_DUE,
|
||||
// Ohne Angabe entscheidet createProjectInvoice (AB-Zahlungsziel bei Anzahlung und Schluss, sonst 14 Tage)
|
||||
daysUntilDue: daysUntilDue ?? undefined,
|
||||
memo,
|
||||
// Nur ein echtes Ja sendet sofort: alles andere bleibt ein Entwurf
|
||||
senden: senden === true || senden === 'true',
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createHash } from 'node:crypto'
|
||||
import { config } from '../../config.js'
|
||||
import { getStripe, getOrCreateStripeCustomer, stripeCustomerFields, subscriptionIdOfInvoice } from '../stripeBilling.js'
|
||||
import { addDays, berlinDate, daysBetween } from './dates.js'
|
||||
import { RECHNUNGS_ARTEN, sperreRechnung } from '../auftraege/konstanten.js'
|
||||
import { RECHNUNGS_ARTEN, AB_RECHNUNGS_ARTEN, sperreRechnung } from '../auftraege/konstanten.js'
|
||||
import { withLocks } from '../keyedLock.js'
|
||||
import { baueRechnung, ladeFestenKunden, buche, gibProjektRechnungFrei, setzeAbAbgerechnet } from '../auftraege/rechnungsbau.js'
|
||||
import { createProjektRechnung, updateProjektRechnung } from '../auftraege/projektRechnungenStore.js'
|
||||
@@ -336,13 +336,14 @@ export async function createProjectInvoice({
|
||||
anzahlung,
|
||||
zeilentexte,
|
||||
leistungszeitraum,
|
||||
daysUntilDue = DEFAULT_DAYS_UNTIL_DUE,
|
||||
daysUntilDue,
|
||||
memo = '',
|
||||
senden = false,
|
||||
idempotencyKey,
|
||||
createdBy,
|
||||
}) {
|
||||
if (!isWholeNumberBetween(daysUntilDue, 0, MAX_DAYS_UNTIL_DUE)) {
|
||||
// Ohne Angabe: bei Anzahlung und Schluss das Zahlungsziel der AB (siehe createInvoice), sonst 14 Tage
|
||||
if (daysUntilDue !== undefined && !isWholeNumberBetween(daysUntilDue, 0, MAX_DAYS_UNTIL_DUE)) {
|
||||
throw httpError(400, `Das Zahlungsziel muss eine ganze Zahl von 0 bis ${MAX_DAYS_UNTIL_DUE} Tagen sein.`)
|
||||
}
|
||||
const note = typeof memo === 'string' ? memo.trim() : ''
|
||||
@@ -379,8 +380,11 @@ export async function rechnungsVorschau(eingabe) {
|
||||
return { positionen, summeCents, leistungszeitraum, customFields }
|
||||
}
|
||||
|
||||
async function createInvoice({ eingabe, daysUntilDue, note, senden, key }) {
|
||||
async function createInvoice({ eingabe, daysUntilDue: angegeben, note, senden, key }) {
|
||||
const entwurf = await baueRechnung(eingabe)
|
||||
// Zahlungsziel: die Angabe des Aufrufers, sonst bei Anzahlung und Schluss das der AB, sonst 14 Tage
|
||||
const abZiel = AB_RECHNUNGS_ARTEN.includes(entwurf.art) ? entwurf.auftrag?.zahlungszielTage : undefined
|
||||
const daysUntilDue = angegeben ?? (isWholeNumberBetween(abZiel, 0, MAX_DAYS_UNTIL_DUE) ? abZiel : DEFAULT_DAYS_UNTIL_DUE)
|
||||
const customer = entwurf.kunde
|
||||
// Ohne Adresse lehnt Stripe das Senden erst nach dem Festschreiben ab: lieber vorab pruefen
|
||||
if (senden && !String(customer.email || '').trim()) throw httpError(400, NO_EMAIL_MESSAGE)
|
||||
|
||||
Reference in new issue
Block a user