CASE FILE 02/13CLASS: SAMPLE BUILDDATA: REALISTIC, NOT CLIENTTYPE: Bookkeeping & reconciliation

Sample build: realistic data, built to show how I'd handle this work. Not client work.

Sample buildBookkeeping & reconciliation

Xero clean-up and hire billing check for a full year, with an Airtable, Glide and Make asset app

2,524 Xero invoice lines re-coded for a year, and 60,258.70 of unbilled hire found by rebuilding the asset log

Sample build · realistic data, built to show how I'd handle this work · not client work · every figure is computed from the files in the appendix

  • 2,524invoice lines re-coded or queued
  • 98.2%coded by a rule
  • 60,258.70hire under-billed, found from the log
  • 29/29controls pass

01Summary

  1. In this scenario a fencing, scaffolding and roofing business has a year of Xero sales (2,538 lines) coded to two accounts, 153 contacts with duplicates, and hired equipment tracked on paper dockets.
  2. 2,478 of 2,524 lines (98.2%) are coded by 13 rules to four income accounts and a Service line tracking category; 46 go to a person, and 83 lines on the wrong tax rate are listed by BAS quarter.
  3. Rebuilding every 4-week hire cycle from the cleaned asset log shows 60 site-assets under-billed by 60,258.70 and 8 over-billed by 2,578.50; 29 of 29 formula controls pass.

2,478 of 2,524 lines (98.2%) are coded by 13 rules to four income accounts and a Service line tracking category; 46 go to a person, and 83 lines on the wrong tax rate are listed by BAS quarter.

Key point, computed from the sample files

02The scenario

In this scenario a fencing, scaffolding and roofing business codes all its income to 200 Sales or 260 Other Revenue, and 200 defaults to GST Free, so some sales go out with no GST. Contacts were keyed twice by different staff. Fence panels go out on paper dockets typed into a log later, and the 4-weekly hire invoices are raised from memory, so nobody knows what was on site against what was billed.

Exhibit 1: Current-state process map: 6 manual steps across 3 roles
Current-state swimlaneYardOfficeXeroPaper docket1Typed into a loglater2Bills from memory3All income to 2004200 defaults toGST Free5Contacts keyedagain6

Source: sample files

03Issues in the data

Exhibit 2: Issues in the scenario, counted from the sample data
2,524invoice lines in two catch-all income accounts
83lines on the wrong tax rate (net GST 3,317.29)
29duplicate contacts among 153
12returns written against the wrong site in the asset log

Source: sample files

04How I approached it

  • A rules engine (engine.py): 13 categorisation rules, contact matching by tax number then name and email domain, asset log clean-up, a rebuild of every hire cycle and a regression test.
  • A workbook with 25 tabs and 26,141 formulas: re-coded invoice lines, revenue by account and service line, 12 recode journals, tax review by BAS quarter, contacts, a chart-of-accounts fix map, the clean asset ledger, fleet reconciliation and the hire billing check.
  • An Airtable base, Glide screens and four Make scenarios, with a simulated July billing run (76 draft invoices) and a re-run that creates none.
  • A 29-control tab, a test log, a 19-page report and a one-page executive summary.
Exhibit 3: Target design for the scenario
Future-state architectureCAPTUREGlide app for the yardSite picked from alistDocket photoSTOREAirtable: sites,movementsHire periods with akeyINTEGRATEMake S1 to S4Draft invoices onlyNightly checksLEDGERXero: 4010-4040, 835Service line trackingContacts from Xeroonly

Source: my design and the sample files

05How this applies to your business

  1. Week 1: ledger fixesPost the 12 recode journals, fix 200's default tax, create the new accounts and tracking, merge contacts.
  2. Week 2: decisionsThe owner clears the review queue; the accountant advises on BAS corrections; credit notes for over-billing.
  3. Week 3: assetsYard recount, catch-up invoices for confirmed gaps, Airtable loaded from the clean ledger.
  4. Week 4 to 8: app liveGlide for the yard, Make in draft-only mode beside the office for one cycle, then the office approves drafts instead of keying.
Exhibit 4: Responsibilities (R responsible, A accountable, C consulted, I informed)
ActivityBusiness ownerSpecialist (me)Your team
Post journals and chart changesARI
Decide review linesRCI
Record movements in the appAIR
Approve Make draft invoicesACR
Change a rule or scenarioARC

Source: sample plan

06Controls and checks

Exhibit 5: Control framework: 29 checks, status read from the files
CheckWhat it catchesStatus
Lines counted + voided = lines in the exportNothing dropped or double countedPASS
Income by rule (Category Rules) = income in the exportEvery line falls under exactly one rule or the no-rule bucketPASS
Lines by rule = counted linesSame, by countPASS
Revenue by Service total = income in the exportThe new view loses nothingPASS
Before (200 + 260) = after (Revenue by Service)Re-coding moves income, it does not create itPASS
Recode journals: debits = creditsJournals balancePASS
Recode journals: months out of balanceEach monthly journal balances on its ownPASS
Recode journals: net credit to 4010-4040 and 835 = rule-coded incomeJournals match the line-level codingPASS
Rule-coded lines with no accountEvery rule gives an accountPASS
Review queue = counted lines needing a personNothing needing a decision is hiddenPASS
Tax Review lines = counted lines with the wrong tax rateEvery tax error is listedPASS
GST effect: Tax Review = Invoice LinesTwo independent calculations agreePASS
Contacts whose master is missing or merged againOne level of merge, no chainsPASS
Contacts kept separate (similar name, different tax number) that were mergedNo false mergesPASS
Invoice lines by contact = lines in the exportEvery line belongs to a known contactPASS
Duplicate dockets left in the clean logEach docket counted oncePASS
Duplicate dockets removed = DUPLICATE issuesEvery removal is on the issues listPASS
Sites below zero at 30 JuneWrong-site returns all resolvedPASS
Asset Position total = net units in the log to 30 JunePosition is completePASS
Fleet: should own - yard - on hire - not returned - varianceFleet adds upPASS
Stocktake variance = STOCKTAKE VARIANCE issuesVariance is raised, not absorbedPASS
Billable unit-weeks: Billing Check = Hire Cycles in FY26Billing check is completePASS
Invoiced hire unit-weeks: Billing Check = Invoice LinesEvery hire line is matched to a sitePASS
Hire credits: Billing Check = Invoice LinesCredit notes are countedPASS
Make July run: repeated idempotency keysA re-run cannot double billPASS
Make July run: amount = unit-weeks x rateDraft amounts are rightPASS
Exceptions: billing rows = pairs not agreeingEvery billing gap is on the registerPASS
Exceptions: open asset issuesEvery open asset issue is on the registerPASS
Engine regression: line coding disagreementsEngine matches the answer key on every linePASS

Source: sample files (Checks / Controls tab, test output or run log)

07What the files show

Exhibit 6: What the sample files show
  • 2,524invoice lines re-coded or queued
  • 98.2%coded by a rule
  • 60,258.70hire under-billed, found from the log
  • 29/29controls pass

Source: sample files, measured by script. Sample data, not a client result.

  • Income before (200 and 260) equals income after (4010 to 4040, 835 and the review queue): 1,758,394.15.
  • Each of the 12 monthly recode journals balances, and together they equal the line-level coding.
  • No site is below zero after the clean-up, and the fleet adds up: register, purchases and losses against yard, on hire and not returned.
  • The engine agrees with the answer key on all 2,538 lines, 29 duplicate contacts, 83 tax errors and 408 hire site-assets.

08Risks and how the build handles them

Exhibit 7: Risks and mitigations
RiskMitigation built in
Re-coding changes reported incomeControls: before (200 + 260) equals after, and each monthly journal balances
Two different businesses are mergedTax numbers are never ignored: 6 look-alikes are kept apart, and the test counts 0 false merges
A wrong-site fix moves the wrong docketEach fix needs a single candidate and is listed with its reason; anything ambiguous stays open for the yard
Make bills a cycle twiceIdempotency key Site|Asset|Cycle start: the simulated re-run created 0 new drafts

Source: sample design

09Appendix: files

A. Screenshots of the deliverable

Dashboard tab: income, tax, contacts, assets, billing and controls, every figure a formula

Exhibit 8: Dashboard tab: income, tax, contacts, assets, billing and controls, every figure a formula

Source: sample files

Invoice Lines tab: each Xero line with its rule, category, new account, service line and expected tax

Exhibit 9: Invoice Lines tab: each Xero line with its rule, category, new account, service line and expected tax

Source: sample files

Hire Billing Check tab: billable unit-weeks rebuilt from the asset log against unit-weeks invoiced, per site and asset

Exhibit 10: Hire Billing Check tab: billable unit-weeks rebuilt from the asset log against unit-weeks invoiced, per site and asset

Source: sample files

Make scenarios tab: S1 to S4 module by module, with the idempotency check and error handling

Exhibit 11: Make scenarios tab: S1 to S4 module by module, with the idempotency check and error handling

Source: sample files

Airtable schema tab: tables and fields for sites, customers, assets, movements, hire periods, billing runs and exceptions

Exhibit 12: Airtable schema tab: tables and fields for sites, customers, assets, movements, hire periods, billing runs and exceptions

Source: sample files

Controls tab: 29 formula controls, all PASS

Exhibit 13: Controls tab: 29 formula controls, all PASS

Source: sample files

Report page: target process from docket to paid invoice across the yard, Glide and Airtable, Make, Xero and the office

Exhibit 14: Report page: target process from docket to paid invoice across the yard, Glide and Airtable, Make, Xero and the office

Source: sample files

Overview of the Xero hire billing sample build: invoice lines coded by rule, review queue, GST to correct, hire under- and over-billing and the July draft run

Exhibit 15: Overview of the Xero hire billing sample build: invoice lines coded by rule, review queue, GST to correct, hire under- and over-billing and the July draft run

Source: sample files

B. Downloadable files

FileWhat it isSize
Xero-Hire-Billing-Cleanup-FY26.xlsxWorkbook: re-coded invoice lines, revenue by service line, recode journals, tax review, contacts, chart fix map, asset ledger, fleet reconciliation, hire billing check, Airtable/Glide/Make design, controls and test log707.7 KB
Xero-Hire-Billing-Report.pdfReport (19 pages): data profile, findings, options, target design, results, controls, tests, cutover, RACI, risks, SOP753.8 KB
Executive-Summary.pdfOne-page executive summary139.5 KB
engine.pyEngine: categorisation rules, contact matching, asset log clean-up, hire cycle rebuild, Make run simulation and the regression test23 KB
gen.pyBuilds the input data set: Xero exports, the transcribed asset log, fleet register and stocktake26 KB
Xero-Hire-Billing-FY26-data-and-code.zipInputs as exported (CSV), engine output, and the scripts that rebuild the workbook and the report214.4 KB

Sample build: realistic data, built to show how I'd handle this work. Names are placeholders and no client data is used.

Have a similar problem in your business?

Hire me on Upwork (opens in a new tab)