Main page Georgio Hajj Boutros
All case studies

Case 05 · Accounting automation · anomaly detection · reconciliation matching

Journal entries that post themselves

Most of close is not judgement. It is preparing the same entries and matching the same items, by hand, from several systems, every month. This is the automation that takes the routine off accountants' desks without letting anything unusual reach the books unreviewed.

Role
Designed and owns
Scale
Recurring entries, every close
Systems
Python, AWS S3, Oracle GL
Status
In production
01 — The situation

What was actually happening

Recurring journal entries were assembled by hand each close: figures pulled from files in storage, from the ERPs and from outside services, calculated in spreadsheets, then keyed into the ledger. Reconciliations followed the same pattern, with people matching items line by line.

Much of that matching effort went into items that were not really exceptions at all: the same transaction written with a different reference format, a rounded amount, a trailing space in a name. The genuinely wrong items were in there too, but they were hard to see among the merely untidy ones.

Automation that posts to the ledger is only acceptable if every entry is explainable and nothing unusual reaches the books unreviewed.

02 — The constraint

Why the obvious fix does not work

Speed was never the hard requirement. The ledger is the record auditors, lenders and the board rely on, and an automated entry that nobody can explain is worse than a slow manual one.

So the constraint was twofold. Every posted entry had to be traceable back to the source data that produced it. And anything that looked unusual had to stop and wait for a person, rather than post and be found later.

03 — The approach

What I built

Python pulls the inputs from AWS S3, the ERPs and external services, performs the calculations and posts the resulting journal entries to the Oracle General Ledger. Each entry carries a reference to the batch of source data it came from.

Before anything posts, an anomaly gate compares it with what is expected for that account. Entries inside the expected range post automatically. Anything outside it is held, with the reason attached, for an accountant to approve or correct.

Reconciliation runs alongside. Exact matches clear first, then fuzzy matching pairs items that differ only in formatting or rounding. Confident matches clear automatically, borderline ones are proposed to a person, and only the true exceptions are left for investigation.

AWS S3 ERPs External services Python calculates each entry Anomaly gate inside expected range? every hold carries its reason yes · posts automatically Oracle General Ledger traceable to its source batch no · held Accountant approves or corrects RECONCILIATION Items to match Exact, then fuzzy match confidence tiers cleared automatically Reconciled true exceptions only Accountant
Two paths, one principle. Postings pass an anomaly gate before they reach the ledger, and reconciliation items clear automatically only when the match is certain. Everything else waits for a person, with the reason visible.
04 — Judgement

Decisions, and what each one cost

Every one of these had a defensible alternative. The trade-off is stated because the trade-off is the point.

Decision 01

Hold, do not post and flag

An unusual entry that posts and is flagged afterwards is already in the books. Holding it before posting keeps the ledger clean and puts the review at the only point where it can prevent an error.

Cost: some legitimate but unusual entries wait for a person, which adds a review step to close.

Decision 02

Every hold carries its reason

A held entry with no explanation just moves the investigation to the accountant. Attaching why it was held, in plain terms, turns review into a quick decision rather than a search.

Cost: the checks have to be simple enough to explain, which rules out some cleverer methods.

Decision 03

Confidence tiers for fuzzy matching

A single match threshold is either too strict to help or too loose to trust. Separating certain matches, probable matches and non-matches lets the machine clear the first group and a person confirm the second.

Cost: the tiers need tuning, and the middle band still asks for human time.

Decision 04

Traceable to the source batch

Every automated entry points back to the data that produced it, so any figure in the ledger can be explained to an auditor, and the same batch cannot be posted twice.

Cost: extra bookkeeping in the automation itself, which is invisible until the day it matters.

05 — Outcome

What changed

  • Routine entries post themselves, calculated from source data rather than keyed by hand.
  • Only true exceptions reach an accountant, each with the reason it was held or left unmatched.
  • Every automated entry is traceable back to the batch of source data that produced it.
  • Review time moved to judgement, away from preparing entries and matching untidy but correct items.
  • Python
  • AWS S3
  • Oracle General Ledger
  • Anomaly detection
  • Fuzzy matching
  • Reconciliation
06 — Retrospective

What I would do differently

Honestly assessed, with hindsight

I would log every accountant decision on a held entry from the first day. Each approval or correction is a label on whether the check was right, and that record is exactly what you need to tune the thresholds with evidence rather than instinct.

I would also agree the definition of an exception with the accountants before building the matching, not after. What counts as a formatting difference and what counts as a real discrepancy is an accounting judgement, and the automation is only as good as that agreement.

Figures on this page are illustrative. No employer data is reproduced.