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:
1 parent
79f230ea2c
commit
4b184f744f
4 files changed
+88
-12
No files matched your search
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user