kovakmedya 37777a71f9 feat(invoices): auto income entry on 'paid' status
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.
2026-04-30 06:14:31 +03:00
S
Description
No description provided
5.2 MiB
Languages
TypeScript 99.5%
CSS 0.5%