diff --git a/src/components/auftraege/RechnungDialog.jsx b/src/components/auftraege/RechnungDialog.jsx
index d02bd79..ee9fecb 100644
--- a/src/components/auftraege/RechnungDialog.jsx
+++ b/src/components/auftraege/RechnungDialog.jsx
@@ -17,7 +17,7 @@ import {
useWeitereBlaetter,
} from '../../hooks/useRechnungDaten'
import { createInvoice } from '../../lib/financeApi'
-import { canInvoice, euro } from '../../lib/financeFormat'
+import { canInvoice } from '../../lib/financeFormat'
import {
ADDRESS_INCOMPLETE_TEXT,
INVOICE_LIMITS,
@@ -33,8 +33,8 @@ import {
abLabel,
anzahlungStandard,
artOptionen,
+ abSummenText,
aufwandAuftrag,
- berechnetFuerAuftrag,
gueltigeFestpreisAbs,
projektOptionen,
standardArt,
@@ -129,9 +129,10 @@ function RechnungFormular({ onClose, onCreated, projektId, auftraegeAktiv, onSho
if (projekt === '') optionen = artOptionen({ projektId: '', auftraege: [], rechnungen: [], auftraegeAktiv: aktiv })
else if (projekt && detail.data) optionen = artOptionen({ projektId: projekt, auftraege, rechnungen, auftraegeAktiv: aktiv })
+ const stripeOk = detail.data?.stripeOk
const art = optionen.some((o) => o.key === state.art && o.enabled)
? state.art
- : standardArt(optionen, { auftraege, rechnungen, offeneMinuten: detail.data?.konto?.zeit?.offeneMinuten || 0 })
+ : standardArt(optionen, { auftraege, rechnungen, offeneMinuten: detail.data?.konto?.zeit?.offeneMinuten || 0, stripeOk })
const festpreisAbs = gueltigeFestpreisAbs(auftraege)
const auftragId =
@@ -268,7 +269,6 @@ function RechnungFormular({ onClose, onCreated, projektId, auftraegeAktiv, onSho
const abBlock = () => {
if (!ab) return null
- const berechnet = berechnetFuerAuftrag(rechnungen, ab.id)
return (
{festpreisAbs.length > 1 ? (
@@ -284,9 +284,7 @@ function RechnungFormular({ onClose, onCreated, projektId, auftraegeAktiv, onSho
) : (
{abLabel(ab)}
)}
-
- Auftragssumme {euro(ab.summeCents)} · bereits berechnet {euro(berechnet)} · noch nicht berechnet {euro(Math.max(0, ab.summeCents - berechnet))}
-
+
{abSummenText({ ab, rechnungen, stripeOk })}
)
}
diff --git a/src/lib/rechnungDialogView.js b/src/lib/rechnungDialogView.js
index 771f736..91c2618 100644
--- a/src/lib/rechnungDialogView.js
+++ b/src/lib/rechnungDialogView.js
@@ -18,6 +18,7 @@ export const ART_OPTION_LABEL = {
export const AB_HINWEIS = 'Anzahlung und Schlussrechnung brauchen eine Auftragsbestätigung.'
export const ENTWURF_HINWEIS = 'Zu dieser Auftragsbestätigung gibt es noch einen Entwurf. Erst senden oder löschen.'
export const OHNE_PROJEKT = 'Ohne Projekt'
+export const STRIPE_UNBEKANNT = 'Stripe nicht erreichbar – Beträge unbekannt'
export const STEUERNUMMER_RECHNUNG_HINWEIS =
'Die Steuernummer fehlt noch – sie gehört auf jede Rechnung (§ 34a UStDV). Eintragen unter Finanzen → Einstellungen.'
@@ -109,6 +110,14 @@ export function hatEntwurfZurAuftrag(rechnungen, auftragId) {
return Array.isArray(rechnungen) && rechnungen.some((r) => r && r.auftragId === auftragId && r.status === 'entwurf')
}
+/** Zeile unter der AB-Wahl. Ist Stripe nicht erreichbar, sind die berechneten Beträge unbekannt (nicht 0,00 €). */
+export function abSummenText({ ab, rechnungen, stripeOk }) {
+ const summe = `Auftragssumme ${euro(ab?.summeCents)}`
+ if (stripeOk === false) return `${summe} · ${STRIPE_UNBEKANNT}`
+ const berechnet = berechnetFuerAuftrag(rechnungen, ab?.id)
+ return `${summe} · bereits berechnet ${euro(berechnet)} · noch nicht berechnet ${euro(Math.max(0, (Number(ab?.summeCents) || 0) - berechnet))}`
+}
+
// --- Rechnungsarten -----------------------------------------------------------------------------------------
/** Wählbare Arten mit Sperrgrund: [{ key, label, enabled, hint }]. */
@@ -127,11 +136,13 @@ export function artOptionen({ projektId, auftraege, rechnungen, auftraegeAktiv }
]
}
-/** Vorbelegte Art: Anzahlung, Schlussrechnung, Aufwand oder Festbetrag je nach Lage ('' ohne Wahl). */
-export function standardArt(optionen, { auftraege, rechnungen, offeneMinuten }) {
+/** Vorbelegte Art: Anzahlung, Schlussrechnung, Aufwand oder Festbetrag je nach Lage ('' ohne Wahl, auch bei Stripe-Ausfall). */
+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'
+ // 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)
const jung = gueltigeFestpreisAbs(auftraege)[0]
if (
diff --git a/tests/unit/rechnungDialogView.test.mjs b/tests/unit/rechnungDialogView.test.mjs
index 98aa954..1bece4e 100644
--- a/tests/unit/rechnungDialogView.test.mjs
+++ b/tests/unit/rechnungDialogView.test.mjs
@@ -9,6 +9,7 @@ const {
artOptionen, standardArt, standardAuftrag, anzahlungStandard,
ausgewaehlteIds, blaetterSumme, blattAusAppwrite, ticketOptionen, zahlungszielVorschlag,
STEUERNUMMER_RECHNUNG_HINWEIS, steuernummerHinweis,
+ STRIPE_UNBEKANNT, abSummenText,
} = await loadModule('src/lib/rechnungDialogView.js')
const ab = (over = {}) => ({
@@ -248,3 +249,26 @@ test('steuernummerHinweis: nicht sperrender Hinweis, solange die Steuernummer in
assert.equal(steuernummerHinweis(null), '')
assert.equal(steuernummerHinweis([]), '')
})
+
+test('abSummenText: Auftragssumme, berechnet und noch offen; bei Stripe-Ausfall „Beträge unbekannt“ statt 0,00 €', () => {
+ assert.equal(
+ abSummenText({ ab: ab(), rechnungen: [rk()], stripeOk: true }),
+ 'Auftragssumme 800,00 € · bereits berechnet 400,00 € · noch nicht berechnet 400,00 €'
+ )
+ assert.equal(abSummenText({ ab: ab(), rechnungen: [], stripeOk: undefined }), 'Auftragssumme 800,00 € · bereits berechnet 0,00 € · noch nicht berechnet 800,00 €')
+ assert.equal(STRIPE_UNBEKANNT, 'Stripe nicht erreichbar – Beträge unbekannt')
+ const aus = abSummenText({ ab: ab(), rechnungen: [], stripeOk: false })
+ assert.equal(aus, 'Auftragssumme 800,00 € · Stripe nicht erreichbar – Beträge unbekannt')
+ assert.ok(!aus.includes('bereits berechnet'))
+})
+
+test('standardArt: bei Stripe-Ausfall wird keine Art vorgeschlagen (Beträge unbekannt)', () => {
+ const lage = { auftraege: [ab()], rechnungen: [], offeneMinuten: 90 }
+ const o = optionen({ auftraege: [ab()] })
+ assert.equal(standardArt(o, lage), 'anzahlung')
+ assert.equal(standardArt(o, { ...lage, stripeOk: true }), 'anzahlung')
+ assert.equal(standardArt(o, { ...lage, stripeOk: false }), '')
+ // ohne Projekt gibt es nichts zu raten: die freie Rechnung bleibt die Vorgabe
+ const frei = artOptionen({ projektId: '', auftraege: [], rechnungen: [], auftraegeAktiv: true })
+ assert.equal(standardArt(frei, { ...lage, stripeOk: false }), 'frei')
+})