The order-details panel reads qty/description/amount from expense_metadata.line_items. A grocery shop is a receipt like any other, so it stores the same keys rather than name/quantity/line_total — otherwise the rows arrive complete and display blank, which is exactly the failure ING-8 names. unit and category are the two fields a grocery line has and a delivery line does not; nothing renders them yet and the category composition will.
This commit is contained in:
@@ -30,11 +30,17 @@ export type TenderLeg = {
|
||||
class?: "card" | "gift_card" | "cash" | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Same keys the order lane uses, because the panel that renders an itemised receipt reads
|
||||
* `qty`/`description`/`amount` and a grocery shop is a receipt like any other. `unit` and
|
||||
* `category` are the two things a grocery line has and a delivery line does not; nothing
|
||||
* renders them yet, and the intra-transaction category composition will.
|
||||
*/
|
||||
export type ReceiptLineItem = {
|
||||
name: string;
|
||||
quantity?: number | null;
|
||||
description: string;
|
||||
qty?: number | null;
|
||||
amount?: number | null;
|
||||
unit?: string | null;
|
||||
line_total?: number | null;
|
||||
category?: string | null;
|
||||
};
|
||||
|
||||
@@ -103,7 +109,7 @@ export function validateReceipt(receipt: ParsedReceipt): string[] {
|
||||
|
||||
// Lines are allowed to disagree: promotional rows are deliberately skipped during
|
||||
// extraction, so this flags rather than rejects. The money is the tender, not the lines.
|
||||
const lineSum = round2((receipt.line_items ?? []).reduce((total, line) => total + Number(line.line_total || 0), 0));
|
||||
const lineSum = round2((receipt.line_items ?? []).reduce((total, line) => total + Number(line.amount || 0), 0));
|
||||
if (receipt.line_items?.length && Math.abs(lineSum - round2(receipt.total)) > 0.02) flags.push(`line_items_sum_${lineSum.toFixed(2)}`);
|
||||
if (receipt.tender_legs.length > 1) flags.push("split_tender");
|
||||
if (receipt.tender_legs.some((leg) => !leg.class)) flags.push("unclassified_tender");
|
||||
|
||||
Reference in New Issue
Block a user