Kontrolle: AB ohne Projekt im Rechnungsdialog für Anzahlung und Schluss wählbar

Der Server (rechnungsbau.js, baueAbRechnung) nimmt Anzahlung und Schlussrechnung ohne
Projekt an. Unter 'Ohne Projekt' lädt der Dialog die ABs des Kunden ohne Projekt und
ihre Rechnungen; frei bleibt die Vorgabe.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-07 15:19:35 +00:00
1 parent 79f230ea2c
commit 4b184f744f
4 files changed
+88 -12

No files matched your search

+19 -2
View File
@@ -118,13 +118,30 @@ export function abSummenText({ ab, rechnungen, stripeOk }) {
return `${summe} · bereits berechnet ${euro(berechnet)} · noch nicht berechnet ${euro(Math.max(0, (Number(ab?.summeCents) || 0) - berechnet))}`
}
/**
* Aufträge und Rechnungen für „Ohne Projekt“ aus der Auftragsliste des Kunden ({ auftraege }) und seiner Rechnungsliste
* ({ rechnungen }): nur ABs ohne Projekt und die Rechnungen, die zu ihnen gehören. -> { auftraege, rechnungen }
*/
export function ohneProjektAbDaten(auftragsAntwort, rechnungsAntwort) {
const abs = Array.isArray(auftragsAntwort?.auftraege) ? auftragsAntwort.auftraege.filter((a) => a && !a.projektId) : []
const ids = new Set(abs.map((a) => a.id))
const alle = Array.isArray(rechnungsAntwort?.rechnungen) ? rechnungsAntwort.rechnungen : []
return { auftraege: abs, rechnungen: alle.filter((r) => r && r.auftragId && ids.has(r.auftragId)) }
}
// --- Rechnungsarten -----------------------------------------------------------------------------------------
/** Wählbare Arten mit Sperrgrund: [{ key, label, enabled, hint }]. */
export function artOptionen({ projektId, auftraege, rechnungen, auftraegeAktiv }) {
if (projektId === null || projektId === undefined) return []
const option = (key, enabled, hint = '') => ({ key, label: ART_OPTION_LABEL[key], enabled, hint: enabled ? '' : hint })
if (projektId === '') return [option('frei', true)]
if (projektId === '') {
// Eine gültige Festpreis-AB ohne Projekt erlaubt Anzahlung und Schlussrechnung (der Server nimmt sie ohne Projekt an)
const ohne = auftraegeAktiv ? gueltigeFestpreisAbs(Array.isArray(auftraege) ? auftraege.filter((a) => a && !a.projektId) : []) : []
if (ohne.length === 0) return [option('frei', true)]
const ohneEntwurf = ohne.filter((a) => !hatEntwurfZurAuftrag(rechnungen, a.id))
return [option('frei', true), option('anzahlung', true), option('schluss', ohneEntwurf.length > 0, ENTWURF_HINWEIS)]
}
const abs = auftraegeAktiv ? gueltigeFestpreisAbs(auftraege) : []
const freie = abs.filter((a) => !hatEntwurfZurAuftrag(rechnungen, a.id))
const schlussHinweis = abs.length === 0 ? AB_HINWEIS : ENTWURF_HINWEIS
@@ -140,7 +157,7 @@ export function artOptionen({ projektId, auftraege, rechnungen, auftraegeAktiv }
export function standardArt(optionen, { auftraege, rechnungen, offeneMinuten, stripeOk = true }) {
const liste = Array.isArray(optionen) ? optionen : []
if (liste.length === 0) return ''
if (liste.length === 1 && liste[0].key === 'frei') return 'frei'
if (liste.some((o) => o.key === 'frei' && o.enabled)) return 'frei' // ohne Projekt
// Ist Stripe nicht erreichbar, sind die berechneten Beträge unbekannt: keine Art vorschlagen
if (stripeOk === false) return ''
const waehlbar = (key) => liste.some((o) => o.key === key && o.enabled)