072aedeaf9
* fix: prevent credit notes from entering payment flow * fix: persist and display customer personal numbers * feat: configure automatic invoice reminder days * fix: issue credit notes through send flow * chore: add repository agent guidance * feat(mcp): route tools across user companies * fix(articles): delete unused register entries * feat(invoices): improve issued invoice actions * feat(supplier-invoices): retain uploaded source documents * docs: record implementation decisions * feat: enhance customer personal number handling and validation - Updated CustomerForm to allow personal numbers in the format of "********-1234" for individual customers. - Added validation to ensure personal numbers are only accepted for individual customers in CreateCustomerSchema. - Implemented masking and encryption for personal numbers to enhance data protection. - Introduced new utility functions for masking and encrypting personal numbers. - Added database migration to enforce unique constraints on credit note relationships and prevent duplicate entries. - Enhanced error handling and logging for credit note issuance and invoice processing. - Updated tests to cover new credit note creation guards and personal number handling. * test: enhance list companies test with supabase query mocks
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
/**
|
|
* A draft invoice (or proforma / delivery note) is editable in place: header
|
|
* fields AND line items: only while it has no committed verifikat. A journal
|
|
* entry is created when the invoice is sent (mark-sent / send) or, for
|
|
* kontantmetoden, at payment; once one exists, BFL immutability applies and the
|
|
* invoice must be corrected with a credit note instead. A self-billed invoice we
|
|
* received is the counterparty's document: never editable here. Credit-note
|
|
* drafts mirror an issued invoice and must not be changed into a different
|
|
* correction after creation.
|
|
*
|
|
* This is the single source of truth for that predicate. The PATCH route
|
|
* (app/api/invoices/[id]/route.ts) enforces it server-side; the detail and edit
|
|
* pages call it only to avoid opening a dead form: they are UX hints, not the
|
|
* trust boundary. Keeping all three on one function stops the rule from drifting.
|
|
*/
|
|
export function isEditableInvoiceDraft(invoice: {
|
|
status: string
|
|
journal_entry_id?: string | null
|
|
is_self_billed?: boolean | null
|
|
credited_invoice_id?: string | null
|
|
}): boolean {
|
|
return (
|
|
invoice.status === 'draft' &&
|
|
!invoice.journal_entry_id &&
|
|
!invoice.is_self_billed &&
|
|
!invoice.credited_invoice_id
|
|
)
|
|
}
|