Fix/supp ag fb (#1023)
* 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
This commit is contained in:
@@ -905,6 +905,9 @@ async function commitMarkInvoicePaid(
|
||||
.single()
|
||||
|
||||
if (invoiceError || !invoice) return { error: 'Invoice not found', status: 404 }
|
||||
if (invoice.credited_invoice_id) {
|
||||
return { error: 'Kreditfakturor kan inte markeras som betalda.', status: 409 }
|
||||
}
|
||||
if (invoice.status !== 'sent' && invoice.status !== 'overdue') {
|
||||
return { error: 'Invoice can only be marked as paid when status is "sent" or "overdue"', status: 409 }
|
||||
}
|
||||
@@ -1143,6 +1146,12 @@ async function commitSendInvoice(
|
||||
.single()
|
||||
|
||||
if (invoiceError || !invoice) return { error: 'Invoice not found', status: 404 }
|
||||
if (invoice.credited_invoice_id) {
|
||||
return {
|
||||
error: 'Credit notes must be issued through the invoice send flow',
|
||||
status: 409,
|
||||
}
|
||||
}
|
||||
// partially_paid/credited imply the invoice was already issued too: the
|
||||
// status flip below would regress them to 'sent' (PR #666 review, ASVS V2.3).
|
||||
if (['sent', 'paid', 'overdue', 'partially_paid', 'credited'].includes(invoice.status)) {
|
||||
@@ -1312,6 +1321,12 @@ async function commitMarkInvoiceSent(
|
||||
.single()
|
||||
|
||||
if (invoiceError || !invoice) return { error: 'Invoice not found', status: 404 }
|
||||
if (invoice.credited_invoice_id) {
|
||||
return {
|
||||
error: 'Credit notes must be issued through the invoice send flow',
|
||||
status: 409,
|
||||
}
|
||||
}
|
||||
if (invoice.status !== 'draft') return { error: 'Only draft invoices can be marked as sent', status: 409 }
|
||||
|
||||
try {
|
||||
@@ -1374,6 +1389,9 @@ async function commitMatchTransactionInvoice(
|
||||
.single()
|
||||
|
||||
if (invError || !invoice) return { error: 'Invoice not found', status: 404 }
|
||||
if (invoice.credited_invoice_id) {
|
||||
return { error: 'Kreditfakturor kan inte registreras som betalda.', status: 409 }
|
||||
}
|
||||
if (!['sent', 'overdue', 'partially_paid'].includes(invoice.status)) {
|
||||
return { error: 'Invoice is not in a matchable state', status: 409 }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user