Omniscope Custom Blocks › Analytics/Reconciliation-Matcher

Reconciliation Matcher

Matches two ledgers one-to-one on amount, reference and date with tolerances, plus group matches, and lists the unmatched items on each side.

Analytics › Finance Python visokio-agents

Open the demo in Omniscope Download demo.ioz Sample data: bank-statement.csv Sample data: cash-book.csv Source on GitHub

Items tagged visokio-agents are community examples built by Visokio's agents, to extend Omniscope's core blocks and views with popular, specialist and more unusual use cases, and to show what anyone, people or agents, can build on Omniscope. They are tested by automated tests and were run on a real Omniscope server. They were not reviewed by Omniscope's core team, so they are not on a par with the core blocks and views, which have years of manual, functional and unit tests behind them. About

Omniscope custom block · Analytics

Match two ledgers one-to-one on amount, reference and date, with tolerances and group matches, and get the reconciling items on each side.

Python · pandas, numpy · nothing extra to install

The problem it solves

Bank reconciliations, supplier statement reconciliations and card settlement checks all come down to the same job: pair up the items on two lists and explain what is left. Exact joins miss items whose dates differ by a day or whose references are typed differently; manual ticking takes hours at every month end.

This block matches in passes, from exact to tolerant, always one-to-one and best match first, finds remittances that cover several invoices, and returns both lists with match IDs and rules, so the reconciling items are what is left to review.

How it works

What goes in

Input 1: bank statement

Invented October statement, 368 lines.

Statement Line Value Date Narrative Amount
1 2025-10-01 REF INV40226 584.83
2 2025-10-01 REF INV40295 1800.41
3 2025-10-01 BACS PO7732 -432.29
4 2025-10-02 INV-40133 1766.4
5 2025-10-02 INV-40143 672.51
6 2025-10-02 REF INV40234 728.91

368 rows in the sample file.

Input 2: cash book

Invented cash book, 379 journals.

Journal Type Posting Date Reference Amount (GBP)
J50000 Receipt 2025-10-01 INV-40133 1766.4
J50001 Receipt 2025-10-01 INV-40143 672.51
J50002 Receipt 2025-10-01 INV-40162 376.37
J50003 Receipt 2025-10-01 INV-40168 373.02
J50004 Receipt 2025-10-01 INV-40226 584.83
J50005 Receipt 2025-10-01 INV-40234 728.91

379 rows in the sample file.

The options

Option Demo setting What it does
Amount Amount Amount of each item in input 1.
Date (optional) Value Date Date of each item in input 1, for the date window.
Reference (optional) Narrative Reference or narrative in input 1, compared with input 2's.
Amount Amount (GBP) Amount of each item in input 2.
Date (optional) Posting Date Date of each item in input 2.
Reference (optional) Reference Reference in input 2.
Amount tolerance 0.01 For example 0.01 for rounding differences.
Date window (days) 3 Maximum days between matched items.
Input 2 amounts Same sign as input 1 Choose Opposite when one side records as negative what the other records as positive.
Match groups with the same reference On One item against several that add up to it.

What comes out

Matches (examples of each non-exact rule)

Match ID Rule Items In 1 Items In 2 Amount 1 Amount 2 Difference Date Difference (days) Reference 1 Reference 2
117 Amount and date 1 1 584.83 584.83 0 0 REF INV40226 INV-40226
118 Amount and date 1 1 1,800.41 1,800.41 0 0 REF INV40295 INV-40295
119 Amount and date 1 1 -432.29 -432.29 0 0 BACS PO7732 PO7732
363 Group (many to one) 2 1 1,800 1,800 0 -0.5 CASH DEP 1120 CASH-DEP-1120
362 Group (one to many) 1 3 2,500 2,500 0 -2 ACME REMIT 0931 ACME-REMIT-0931

Unmatched in the cash book (not yet on the statement)

Journal Type Posting Date Reference Amount (GBP) Match Status
J50022 Receipt 2025-10-02 INV-40253 815.40 Unmatched
J50070 Receipt 2025-10-06 INV-40105 330.85 Unmatched
J50158 Payment 2025-10-12 PO7722 -654.31 Unmatched
J50159 Payment 2025-10-12 PO7741 -156.27 Unmatched
J50204 Receipt 2025-10-16 INV-40142 213.95 Unmatched
J50210 Receipt 2025-10-16 INV-40327 862.89 Unmatched
J50227 Payment 2025-10-17 PO7760 -1,602.35 Unmatched
J50264 Payment 2025-10-20 PO7779 -1,857.24 Unmatched
J50305 Receipt 2025-10-23 INV-40290 104.16 Unmatched
J50338 Payment 2025-10-26 PO7703 -1,700.13 Unmatched
J50349 Receipt 2025-10-27 INV-40216 971.52 Unmatched
J50358 Receipt 2025-10-28 INV-40179 850.63 Unmatched
J50371 Payment 2025-10-28 PO7798 -1,406.48 Unmatched
J50378 Payment 2025-10-31 DD-LEASE -365 Unmatched

Unmatched on the statement (bank-only items)

Statement Line Value Date Narrative Amount Match Status
158 2025-10-13 CARD CHARGES -118.42 Unmatched
241 2025-10-20 RETURNED ITEM -640 Unmatched
366 2025-10-31 ACCOUNT FEE -32.5 Unmatched
367 2025-10-31 INTEREST 4.17 Unmatched
The reconciliation statement built from the outputs: every difference between the two totals is accounted for by unmatched items and rounding.
The reconciliation statement built from the outputs: every difference between the two totals is accounted for by unmatched items and rounding.

The reconciliation statement built from the outputs: every difference between the two totals is accounted for by unmatched items and rounding.

Most items need the tolerant pass: references are typed differently and the bank clears one to three days later (illustrative data).
Most items need the tolerant pass: references are typed differently and the bank clears one to three days later (illustrative data).

Most items need the tolerant pass: references are typed differently and the bank clears one to three days later (illustrative data).

Where it pays off

Finance: Bank reconciliation

Statement against cash book every day or month end, with the unmatched items forming the reconciliation statement.

Accounts payable: Supplier statement reconciliation

A supplier's statement against the purchase ledger, finding missing invoices, credit notes and payments in transit.

Retail and hospitality: Card and cash settlements

Card processor settlements against till takings by site, with fees and chargebacks left as reconciling items.

Shared services: Intercompany matching

One entity's receivables against another's payables, with entity and currency fields that must agree.

Use cases describe typical scenarios and are illustrative.

Why do this in Omniscope

How it fits into an Omniscope workflow

Bank statement (file or bank API) → Cash book (ERP database) → Reconciliation Matcher → Report / Email output (unmatched items)

Load both sides on a schedule; Data Cleansing upstream can tidy narrative text, though the block already ignores spaces, punctuation and case in references.

Email the unmatched items to the finance team and keep the match output as the audit trail of what was matched and by which rule.

Both sides are loaded, cleaned and matched in the same workflow, and the unmatched items go to the finance team from that same run; the match rules are open to read in the block's source if an auditor asks how a pair was matched.

In one step

Tolerant one-to-one and group matching, with the rule behind each match recorded.

Try it

  1. Open the demo project (demo.iox on the demo server, or import demo.ioz from this folder): an invented October bank statement and cash book.
  2. The question: what is left to explain at month end?
  3. Open the block: amounts, dates and references on each side, 0.01 tolerance, 3-day window. Run it.
  4. Look at the summary: 363 matches, of which 116 on the Exact rule (same amount and reference, within the date window); the rest needed the amount-and-date or group passes.
  5. Look at the unmatched lists: 14 cash book items not yet cleared and 4 bank charges and items. Those are the reconciliation statement.

Running in Omniscope

Omniscope workflow
Omniscope workflow

The demo project's workflow: the sample data, the block, and a Validate data check on its output.

Language and libraries

Python. It uses pandas and numpy, plus the Python standard library (re).

pandas and numpy are part of Omniscope's Docker Python image, and the block was run in both host mode and Docker mode on an Omniscope server, with the same results. It needs nothing else installed.

Tested

The demo workflow completed without errors on an Omniscope server (368 records in Input 1 items, 379 in Input 2 items, 363 in Matches and 8 in Summary). Automated tests check normal data, empty input, wrong types and large input.

Reference

Fields it reads

NameTypeWhat it does
AmountFieldAmount of each item in input 1.
Date (optional)FieldDate of each item in input 1, for the date window.
Reference (optional)FieldReference or narrative in input 1, compared with input 2's.
AmountFieldAmount of each item in input 2.
Date (optional)FieldDate of each item in input 2.
Reference (optional)FieldReference in input 2.
Fields that must agree (optional)FieldsSame field names in both inputs, such as Account or Currency.

Options

NameTypeWhat it does
Amount toleranceNumberFor example 0.01 for rounding differences.
Date window (days)NumberMaximum days between matched items.
Input 2 amountsChoiceChoose Opposite when one side records as negative what the other records as positive.
Match groups with the same referenceYes / noOne item against several that add up to it.

Outputs

OutputWhat it holds
Items 1Input 1 with Match Status, Match ID and Match Rule.
Items 2Input 2 with Match Status, Match ID and Match Rule.
MatchesOne row per match: rule, items and amount on each side, difference, date difference, references.
SummaryMatched and unmatched items and amounts per side, and matches per rule.