37777a71f9b8b5411b33b69be63eb634d5b890e4
Marking an invoice as paid now creates a finance_entry (type=income) for
the customer with amount = invoice.total, linked via invoiceId. Reverting
status removes the entry. Idempotent: re-saving while already paid keeps
the existing entry (resyncs amount if invoice total changed in the
meantime).
- syncPaymentEntry(tenantId, userId, invoice) helper:
* status === 'paid': create entry if none exists; otherwise update
amount to match current invoice.total.
* status !== 'paid': delete any income entries linked to the invoice.
* Best-effort — failures are swallowed so the invoice mutation always
succeeds even if Appwrite hiccups on the finance write.
* Each create/delete writes an audit row tagged auto: 'invoice_paid' /
'invoice_unpaid' so we can trace later.
- updateInvoiceAction now calls syncPaymentEntry after persisting.
- recomputeTotals (run on every item add/update/delete) also re-syncs
the linked entry's amount when the invoice is currently paid.
- deleteInvoiceAction now cascade-deletes any linked finance_entries in
addition to items.
- /invoices and /invoices/[id] both revalidate /finance after writes.
UI:
- Invoice form shows a hint under the status select explaining the
finance side effect.
- Finance table tags rows with a 'Faturadan' badge when invoiceId is
set, so users can tell auto-generated entries apart from manual ones.
Description
No description provided
Languages
TypeScript
99.5%
CSS
0.5%