reconcile queue: offer a foreign row's exact native twin regardless of provisional AUD
ci / lint-test (push) Successful in 1m4s
ci / lint-test (push) Successful in 1m4s
Wallet INR taps were priced at a provisional 0.0180 AUD/INR; CommBank charged ~0.0149, so every rupee twin sat ~20% outside the picker's +-5% band. The auto-matcher pairs on the native figure but refuses ambiguity (INR 112 twice in three days, INR 175 three times), which left those rows offered nothing at all.
This commit is contained in:
@@ -66,4 +66,21 @@ describe("getPendingReconciliations", () => {
|
|||||||
expect(offered).toContain(live);
|
expect(offered).toContain(live);
|
||||||
expect(offered).not.toContain(dupe);
|
expect(offered).not.toContain(dupe);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("offers the exact native twin of a foreign row even when its provisional AUD is far off", async () => {
|
||||||
|
// Live shape, 2026-10-09: wallet INR 112 at a provisional A$2.01; CommBank
|
||||||
|
// charged A$1.68 -- 16% under, outside the +-5% band.
|
||||||
|
const manual = await insertTransaction(pool, ownerId, { description: "SWIGGY LIMITED", amount: 2.01, transaction_date: "2026-10-04" });
|
||||||
|
await pool.query(`UPDATE transactions SET foreign_currency_code = 'INR', foreign_currency_amount = 112 WHERE id = $1`, [manual]);
|
||||||
|
const twin = await statementLine(1.68, "2026-10-04", "Swiggy Limited Bengaluru");
|
||||||
|
const otherRupees = await statementLine(1.68, "2026-10-04", "Swiggy Limited Bengaluru");
|
||||||
|
await pool.query(`UPDATE transactions SET foreign_currency_code = 'INR', foreign_currency_amount = 112 WHERE id = $1`, [twin]);
|
||||||
|
await pool.query(`UPDATE transactions SET foreign_currency_code = 'INR', foreign_currency_amount = 113 WHERE id = $1`, [otherRupees]);
|
||||||
|
|
||||||
|
const [row] = (await getPendingReconciliations(ownerId)).filter((r) => r.id === manual);
|
||||||
|
const offered = row.matches.map((m) => m.id);
|
||||||
|
expect(offered).toContain(twin);
|
||||||
|
// A different native figure at the same AUD is not admitted by this path.
|
||||||
|
expect(offered).not.toContain(otherRupees);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
+11
-1
@@ -903,7 +903,17 @@ export async function getPendingReconciliations(ownerId: number): Promise<Manual
|
|||||||
-- the rn window and ordered by amount closeness; a looser band changes
|
-- the rn window and ordered by amount closeness; a looser band changes
|
||||||
-- which five appear, never how many, and a person confirms each one.
|
-- which five appear, never how many, and a person confirms each one.
|
||||||
-- The AUTO-matcher stays exact on purpose; see findAutoMatches().
|
-- The AUTO-matcher stays exact on purpose; see findAutoMatches().
|
||||||
AND t.amount BETWEEN m.amount * 0.95 AND m.amount * 1.05
|
AND (t.amount BETWEEN m.amount * 0.95 AND m.amount * 1.05
|
||||||
|
-- Or the exact native pair, whatever the AUD figures say. A
|
||||||
|
-- wallet row's AUD is provisional: in Oct 2026 it priced INR at
|
||||||
|
-- 0.0180 while CommBank charged ~0.0149, 20% under, so the band
|
||||||
|
-- excluded every rupee twin. findAutoMatches() matches on this
|
||||||
|
-- pair already, but refuses when two lines share it inside its
|
||||||
|
-- window (INR 112 on 10/4 and again on 10/7) -- and those are
|
||||||
|
-- exactly the rows that land here for a person to choose.
|
||||||
|
OR (m.foreign_currency_code IS NOT NULL
|
||||||
|
AND t.foreign_currency_code = m.foreign_currency_code
|
||||||
|
AND t.foreign_currency_amount = m.foreign_currency_amount))
|
||||||
JOIN statements s ON s.id = t.statement_id
|
JOIN statements s ON s.id = t.statement_id
|
||||||
LEFT JOIN transaction_overrides o ON o.transaction_id = t.id
|
LEFT JOIN transaction_overrides o ON o.transaction_id = t.id
|
||||||
WHERE m.statement_id IS NULL
|
WHERE m.statement_id IS NULL
|
||||||
|
|||||||
Reference in New Issue
Block a user