Functional Weave
Code in Python

finance.bank-reconcile-match@1.0.0

vectors.json

8,275 bytes · view raw

[
  {"name": "a receipt and a direct debit match; the stray line on each side is left over", "args": [[{"id": "B1", "date": "2026-03-02", "amount": {"minor": 12000, "currency": "GBP"}, "reference": "INV-1001 ACME"}, {"id": "B2", "date": "2026-03-03", "amount": {"minor": -4550, "currency": "GBP"}, "reference": "DD BRITISH GAS"}, {"id": "B3", "date": "2026-03-05", "amount": {"minor": 9999, "currency": "GBP"}, "reference": "unknown"}], [{"id": "L1", "date": "2026-03-01", "amount": {"minor": 12000, "currency": "GBP"}, "reference": "INV1001"}, {"id": "L2", "date": "2026-03-03", "amount": {"minor": -4550, "currency": "GBP"}, "reference": "British Gas"}, {"id": "L3", "date": "2026-03-20", "amount": {"minor": 9999, "currency": "GBP"}, "reference": "INV1003"}], 3, 0], "expect": {"matches": [{"bankId": "B1", "ledgerId": "L1", "dayDifference": 1, "similarity": 7500}, {"bankId": "B2", "ledgerId": "L2", "dayDifference": 0, "similarity": 9000}], "unmatchedBank": ["B3"], "unmatchedLedger": ["L3"]}},
  {"name": "two equal payments pair by reference, not by the order the ledger lists them", "args": [[{"id": "B1", "date": "2026-04-10", "amount": {"minor": 50000, "currency": "GBP"}, "reference": "INV2002"}, {"id": "B2", "date": "2026-04-10", "amount": {"minor": 50000, "currency": "GBP"}, "reference": "INV2001"}], [{"id": "L1", "date": "2026-04-09", "amount": {"minor": 50000, "currency": "GBP"}, "reference": "INV2001"}, {"id": "L2", "date": "2026-04-09", "amount": {"minor": 50000, "currency": "GBP"}, "reference": "INV2002"}], 3, 0], "expect": {"matches": [{"bankId": "B1", "ledgerId": "L2", "dayDifference": 1, "similarity": 10000}, {"bankId": "B2", "ledgerId": "L1", "dayDifference": 1, "similarity": 10000}], "unmatchedBank": [], "unmatchedLedger": []}},
  {"name": "the best pair overall is taken first, even when it is not the first bank line's nearest date", "args": [[{"id": "B1", "date": "2026-07-01", "amount": {"minor": 5000, "currency": "GBP"}, "reference": "REF A"}, {"id": "B2", "date": "2026-07-01", "amount": {"minor": 5000, "currency": "GBP"}, "reference": "PAYMENT 7788"}], [{"id": "L1", "date": "2026-07-01", "amount": {"minor": 5000, "currency": "GBP"}, "reference": "7788"}, {"id": "L2", "date": "2026-07-03", "amount": {"minor": 5000, "currency": "GBP"}, "reference": "refa"}], 3, 0], "expect": {"matches": [{"bankId": "B1", "ledgerId": "L2", "dayDifference": -2, "similarity": 10000}, {"bankId": "B2", "ledgerId": "L1", "dayDifference": 0, "similarity": 4615}], "unmatchedBank": [], "unmatchedLedger": []}},
  {"name": "equal similarity: the nearer date wins", "args": [[{"id": "B1", "date": "2026-05-05", "amount": {"minor": -1000, "currency": "GBP"}, "reference": ""}], [{"id": "L1", "date": "2026-05-02", "amount": {"minor": -1000, "currency": "GBP"}, "reference": ""}, {"id": "L2", "date": "2026-05-04", "amount": {"minor": -1000, "currency": "GBP"}, "reference": ""}], 3, 0], "expect": {"matches": [{"bankId": "B1", "ledgerId": "L2", "dayDifference": 1, "similarity": 0}], "unmatchedBank": [], "unmatchedLedger": ["L1"]}},
  {"name": "a complete tie goes to the earlier ledger entry", "args": [[{"id": "B1", "date": "2026-05-05", "amount": {"minor": -1000, "currency": "GBP"}, "reference": "X"}], [{"id": "L1", "date": "2026-05-04", "amount": {"minor": -1000, "currency": "GBP"}, "reference": ""}, {"id": "L2", "date": "2026-05-06", "amount": {"minor": -1000, "currency": "GBP"}, "reference": ""}], 3, 0], "expect": {"matches": [{"bankId": "B1", "ledgerId": "L1", "dayDifference": 1, "similarity": 0}], "unmatchedBank": [], "unmatchedLedger": ["L2"]}},
  {"name": "the date window is inclusive: 3 days matches, 4 does not", "args": [[{"id": "B1", "date": "2026-06-04", "amount": {"minor": 100, "currency": "GBP"}, "reference": "a"}, {"id": "B2", "date": "2026-06-05", "amount": {"minor": 200, "currency": "GBP"}, "reference": "b"}], [{"id": "L1", "date": "2026-06-01", "amount": {"minor": 100, "currency": "GBP"}, "reference": "a"}, {"id": "L2", "date": "2026-06-01", "amount": {"minor": 200, "currency": "GBP"}, "reference": "b"}], 3, 0], "expect": {"matches": [{"bankId": "B1", "ledgerId": "L1", "dayDifference": 3, "similarity": 10000}], "unmatchedBank": ["B2"], "unmatchedLedger": ["L2"]}},
  {"name": "a zero window needs the same date", "args": [[{"id": "B1", "date": "2026-06-02", "amount": {"minor": 100, "currency": "GBP"}, "reference": "a"}], [{"id": "L1", "date": "2026-06-01", "amount": {"minor": 100, "currency": "GBP"}, "reference": "a"}], 0, 0], "expect": {"matches": [], "unmatchedBank": ["B1"], "unmatchedLedger": ["L1"]}},
  {"name": "a reference below the minimum similarity does not match", "args": [[{"id": "B1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "ABC"}], [{"id": "L1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "XYZ"}], 3, 5000], "expect": {"matches": [], "unmatchedBank": ["B1"], "unmatchedLedger": ["L1"]}},
  {"name": "similarity counts repeated pairs once each: AAAA against AA is 5000", "args": [[{"id": "B1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "aaaa"}], [{"id": "L1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "AA"}], 3, 5000], "expect": {"matches": [{"bankId": "B1", "ledgerId": "L1", "dayDifference": 0, "similarity": 5000}], "unmatchedBank": [], "unmatchedLedger": []}},
  {"name": "ACME LTD against ACME is 6666, rounded down", "args": [[{"id": "B1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "ACME LTD"}], [{"id": "L1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "acme"}], 3, 0], "expect": {"matches": [{"bankId": "B1", "ledgerId": "L1", "dayDifference": 0, "similarity": 6666}], "unmatchedBank": [], "unmatchedLedger": []}},
  {"name": "INV1001 against INV1002 is 8333", "args": [[{"id": "B1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "INV1001"}], [{"id": "L1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "INV1002"}], 3, 0], "expect": {"matches": [{"bankId": "B1", "ledgerId": "L1", "dayDifference": 0, "similarity": 8333}], "unmatchedBank": [], "unmatchedLedger": []}},
  {"name": "the same amount in another currency is not a match", "args": [[{"id": "B1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "x"}], [{"id": "L1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "EUR"}, "reference": "x"}], 3, 0], "expect": {"matches": [], "unmatchedBank": ["B1"], "unmatchedLedger": ["L1"]}},
  {"name": "money out does not match money in", "args": [[{"id": "B1", "date": "2026-06-01", "amount": {"minor": -1000, "currency": "GBP"}, "reference": "x"}], [{"id": "L1", "date": "2026-06-01", "amount": {"minor": 1000, "currency": "GBP"}, "reference": "x"}], 3, 0], "expect": {"matches": [], "unmatchedBank": ["B1"], "unmatchedLedger": ["L1"]}},
  {"name": "nothing to match", "args": [[], [], 3, 0], "expect": {"matches": [], "unmatchedBank": [], "unmatchedLedger": []}},
  {"name": "a negative window is refused", "args": [[], [], -1, 0], "expectError": "dateWindowDays must be 0 or more"},
  {"name": "a similarity over 10000 is refused", "args": [[], [], 3, 10001], "expectError": "minSimilarity must be 0 to 10000"},
  {"name": "duplicate bank ids are refused", "args": [[{"id": "B1", "date": "2026-06-01", "amount": {"minor": 1, "currency": "GBP"}, "reference": ""}, {"id": "B1", "date": "2026-06-02", "amount": {"minor": 2, "currency": "GBP"}, "reference": ""}], [], 3, 0], "expectError": "duplicate bank line id \"B1\""},
  {"name": "duplicate ledger ids are refused", "args": [[], [{"id": "L1", "date": "2026-06-01", "amount": {"minor": 1, "currency": "GBP"}, "reference": ""}, {"id": "L1", "date": "2026-06-02", "amount": {"minor": 2, "currency": "GBP"}, "reference": ""}], 3, 0], "expectError": "duplicate ledger entry id \"L1\""},
  {"name": "an impossible date is refused", "args": [[{"id": "B1", "date": "2026-02-30", "amount": {"minor": 1, "currency": "GBP"}, "reference": ""}], [{"id": "L1", "date": "2026-03-01", "amount": {"minor": 1, "currency": "GBP"}, "reference": ""}], 3, 0], "expectError": "not a real calendar date"}
]