Finanzen: Offen zeigt auch Ueberfaellige, Rechnungsliste laedt nach Zuordnen neu

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-01 15:12:18 +00:00
1 parent 1feeb18c08
commit 24a3cc41ef
6 files changed
+149 -29

No files matched your search

+4 -3
View File
@@ -21,11 +21,12 @@ const NOTE_MAX = 500
* weicht ab, 502 nicht gespeichert …) stehen im Dialog, der offen bleibt. Eine bestehende Zuordnung (außer Rechnung)
* lässt sich mit „Zuordnung lösen“ aufheben.
*
* invoices = offene und überfällige Rechnungen (invoicesLoading / invoicesError für den Ladezustand).
* invoices = offene und überfällige Rechnungen (invoicesLoading / invoicesError für den Ladezustand; invoicesLoaded =
* frisch und ohne Fehler geladen, dann sind Vorschläge zu nicht mehr offenen Rechnungen gesperrt).
* onDone(buchung) nach Erfolg (Aufrufer lädt neu und schließt); onClose({ refresh }) bei Abbruch, refresh = ein
* Fehler trat auf, der Stand kann sich geändert haben.
*/
export default function AssignDialog({ transaction, invoices = [], invoicesLoading = false, invoicesError = '', onClose, onDone }) {
export default function AssignDialog({ transaction, invoices = [], invoicesLoading = false, invoicesError = '', invoicesLoaded = false, onClose, onDone }) {
const tx = transaction || {}
const row = useMemo(() => transactionRows([tx])[0], [tx])
const [fixed, setFixed] = useState({ list: [], loading: false, error: '' })
@@ -69,7 +70,7 @@ export default function AssignDialog({ transaction, invoices = [], invoicesLoadi
}
}, [outgoing, unassigned])
const model = useMemo(() => assignModel(tx, { invoices, fixedCosts: fixed.list }), [tx, invoices, fixed.list])
const model = useMemo(() => assignModel(tx, { invoices, fixedCosts: fixed.list, invoicesLoaded }), [tx, invoices, fixed.list, invoicesLoaded])
const option = model.byKey[selected] || null
function close() {
+10 -5
View File
@@ -12,10 +12,12 @@ import {
ageGroupCells,
finalizedFilter,
invoiceConfirmText,
invoiceFilterStatuses,
invoiceDoneMessage,
invoiceFailureMessage,
invoiceRows,
isFinalizedNotSent,
mergeInvoiceLists,
} from '../../lib/financeView'
const PAGE_SIZE = 50
@@ -31,8 +33,11 @@ const CALLS = { send: sendInvoice, resend: resendInvoice, void: voidInvoice, del
* customerId filtert auf einen Kunden; `customer` (Appwrite-Dokument) legt zusätzlich den Kunden im Dialog fest
* (Kundenansicht). onChanged() meldet jede Änderung (Übersicht neu laden). Schmal (Karte bis 700 px) wird jede
* Zeile ein Raster: Nummer und Status / Kunde / Datum, Fällig / Betrag, Offen / Aktionen.
*
* „Offen“ zeigt offene und überfällige Rechnungen (zwei Abrufe, zusammengeführt, neueste zuerst). Ändert sich
* `refreshToken` (die Seite lädt nach Zuordnen, Bankabruf usw. alles neu), lädt auch die Liste neu.
*/
export default function InvoiceTable({ altersgruppen = null, customerId = null, customer = null, onChanged }) {
export default function InvoiceTable({ altersgruppen = null, customerId = null, customer = null, refreshToken = 0, onChanged }) {
const filterCustomer = customerId || customer?.$id || null
const [status, setStatus] = useState(DEFAULT_INVOICE_FILTER)
const [reloadKey, setReloadKey] = useState(0)
@@ -59,17 +64,17 @@ export default function InvoiceTable({ altersgruppen = null, customerId = null,
useEffect(() => {
// Nur die jüngste Anfrage zählt (Filterwechsel während des Ladens)
const mine = ++seqRef.current
getInvoices({ status, kunde: filterCustomer })
.then((data) => {
Promise.all(invoiceFilterStatuses(status).map((s) => getInvoices({ status: s, kunde: filterCustomer })))
.then((results) => {
if (!aliveRef.current || mine !== seqRef.current) return
setResult({ key, list: Array.isArray(data?.rechnungen) ? data.rechnungen : [] })
setResult({ key, list: mergeInvoiceLists(results.map((r) => r?.rechnungen)) })
setError(null)
})
.catch((err) => {
if (!aliveRef.current || mine !== seqRef.current) return
setError({ key, message: err?.message || 'Die Rechnungen konnten nicht geladen werden.' })
})
}, [status, filterCustomer, key, reloadKey])
}, [status, filterCustomer, key, reloadKey, refreshToken])
const reload = () => setReloadKey((k) => k + 1)
const changed = () => {