fix(invoicing): guard the QuickBooks send against an all-excluded group
Review follow-up to the non-invoiceable-extras work. Task 6 of the plan called for the billable-subset guard on `sendToQuickBooks` as well as in the modals; it landed in the modals only. `rows.length === 0` counts excluded rows, which ride along for the n8n status flip but never bill. A group where every row is excluded passes that check and ships an empty `items` array, so QuickBooks would create a zero-line invoice while n8n still flipped every row to `invoiced`. Not reachable through the current UI — both live modals disable submit on this case. This is defence-in-depth for the callers that bypass them: the (currently unrendered) bulk modal and any legacy call passing `overrides: undefined`, which falls back to every row in the group. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
7a1239a187
commit
9996923bf3
1 changed files with 15 additions and 0 deletions
|
|
@ -23,6 +23,7 @@ import {
|
|||
buildDeliveryNotePrintGroups,
|
||||
buildTodayUnprintedDeliveryNoteGroups,
|
||||
buildQbInvoicePayload,
|
||||
billableRows,
|
||||
nameSimilarity,
|
||||
buildOrderInvoiceCards,
|
||||
buildRecentInvoiceRange,
|
||||
|
|
@ -2048,6 +2049,20 @@ export default function InvoicingPage() {
|
|||
toast.error("Pick at least one item before sending to QuickBooks.");
|
||||
return false;
|
||||
}
|
||||
// Task 6 of the non-invoiceable-order-extras plan. `rows.length`
|
||||
// above counts excluded rows, which ride along for the n8n
|
||||
// status flip but never bill. If every row in the group is
|
||||
// excluded the payload's `items` array would be empty and
|
||||
// QuickBooks would receive a zero-line invoice.
|
||||
//
|
||||
// Both live modals disable submit on this case, so this is
|
||||
// defence-in-depth for the callers that bypass them: the
|
||||
// (currently unrendered) bulk modal and any legacy call that
|
||||
// passes `overrides: undefined` and falls back to every row.
|
||||
if (billableRows(rows).length === 0) {
|
||||
toast.error("This order has no billable lines.");
|
||||
return false;
|
||||
}
|
||||
const first = rows[0];
|
||||
const similarity = nameSimilarity(customer.name, first.companyName ?? "");
|
||||
if (similarity < 0.35) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue