fix(dn): a combined line saves even when the supplier rule cannot be remembered
Co-Authored-By: MiniMax (Pinchy)
This commit is contained in:
parent
3ca3021d33
commit
9db3b2fb6c
2 changed files with 38 additions and 10 deletions
|
|
@ -5,6 +5,8 @@ import type { LineEdit } from "./line-rows";
|
|||
|
||||
const MESH_ITEM = "meshitem1234567";
|
||||
const BAILING_ITEM = "bailingitem12345";
|
||||
/** An order line the slip sells in metres. */
|
||||
const KERB_ITEM = "kerbitem12345678";
|
||||
/** An order line from another purchase order. */
|
||||
const FOREIGN_ITEM = "foreignitem12345";
|
||||
|
||||
|
|
@ -15,6 +17,7 @@ const context = (): PreviewContext => ({
|
|||
po: { id: "poabcdefghijklm", purchase_order_number: "MEGCPO9448", total_value: 11748.7 },
|
||||
poItems: [
|
||||
{ id: MESH_ITEM, description: "MESH DIAMOND 600 x 2.5 ROLL", unit: "m", qty: 2, rate: 1124.35, disc_percent: 0, vat_percent: 15 },
|
||||
{ id: KERB_ITEM, description: "KERB 150", unit: "m", qty: 100, rate: 150, disc_percent: 0, vat_percent: 15 },
|
||||
{ id: BAILING_ITEM, description: "1.6mm Bailing Wire", unit: "ea", qty: 100, rate: 95, disc_percent: 0, vat_percent: 15 },
|
||||
],
|
||||
lines: [
|
||||
|
|
@ -85,8 +88,25 @@ describe("saveLineEdits", () => {
|
|||
expect(rules.some((rule) => rule.receiving_match?.factor === 30)).toBe(true);
|
||||
});
|
||||
|
||||
it("saves nothing when one edit in the batch fails", () => {
|
||||
it("keeps a combined line even when the supplier rule cannot be remembered", () => {
|
||||
const c = context();
|
||||
// Two kerb lines on one order line, sold in metres: there is no single
|
||||
// product to scope a supplier rule to, so the rule is skipped — but the
|
||||
// edit itself has to stand.
|
||||
const result = saveLineEdits(c, preview(c), [edit({
|
||||
lines: [1, 2],
|
||||
poItemId: KERB_ITEM,
|
||||
slipQty: 4,
|
||||
slipUnit: "ea",
|
||||
factor: 15,
|
||||
reason: "One kerb is 15 m.",
|
||||
})], "operator");
|
||||
expect(result.remembered).toBeNull();
|
||||
expect(result.preview.allocations.some((allocation) =>
|
||||
allocation.purchaseOrderItemId === KERB_ITEM && allocation.sourceLineIds.length === 2)).toBe(true);
|
||||
});
|
||||
|
||||
it("saves nothing when one edit in the batch fails", () => { const c = context();
|
||||
const before = preview(c);
|
||||
const untouched = structuredClone(before);
|
||||
expect(() => saveLineEdits(c, before, [
|
||||
|
|
|
|||
|
|
@ -101,15 +101,23 @@ export function saveLineEdits(
|
|||
const item = edit.poItemId ? working.poItems.find((candidate) => candidate.id === edit.poItemId) : null;
|
||||
const targetUnit = item && typeof item.unit === "string" ? item.unit : null;
|
||||
if (targetUnit && edit.factor !== null && edit.factor !== 1 && edit.slipUnit.trim().toLowerCase() !== targetUnit.trim().toLowerCase()) {
|
||||
const guidance = rememberConnection(
|
||||
{ ...working, supplier: { ...working.supplier, reconciliation_rules: remembered ?? working.supplier.reconciliation_rules } },
|
||||
current,
|
||||
current.allocations.findIndex((allocation) => sameLines(allocation.sourceLineIds, sourceLineIds)),
|
||||
actor,
|
||||
);
|
||||
remembered = guidance;
|
||||
working = { ...working, supplier: { ...working.supplier, reconciliation_rules: guidance } };
|
||||
current = { ...current, snapshotHash: snapshotHash(working) };
|
||||
try {
|
||||
const guidance = rememberConnection(
|
||||
{ ...working, supplier: { ...working.supplier, reconciliation_rules: remembered ?? working.supplier.reconciliation_rules } },
|
||||
current,
|
||||
current.allocations.findIndex((allocation) => sameLines(allocation.sourceLineIds, sourceLineIds)),
|
||||
actor,
|
||||
);
|
||||
remembered = guidance;
|
||||
working = { ...working, supplier: { ...working.supplier, reconciliation_rules: guidance } };
|
||||
current = { ...current, snapshotHash: snapshotHash(working) };
|
||||
} catch (error) {
|
||||
// A rule that cannot be written must not lose the edit: a combined
|
||||
// line has no single product to scope the rule to. The line still
|
||||
// books and the office still sees it — the supplier rule is simply
|
||||
// not remembered this time.
|
||||
if (!(error instanceof Error) || !/can be remembered/i.test(error.message)) throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue