Building ERPSav: Taxed Twice on the Same Invoice Is a Rules Collision, Not a Data Entry Error. What Worked, What Broke
Most billing errors look like someone typed the wrong number. This one looked like everyone did their job correctly, and the business still paid tax twice on the same purchase. The supplier added sales tax on the invoic
Most billing errors look like someone typed the wrong number. This one looked like everyone did their job correctly, and the business still paid tax twice on the same purchase.
The supplier added sales tax on the invoice, as it should. Accounts payable paid the invoice in full, as it should. Then at month end the tax process self assessed use tax on the same document, because the purchase category was flagged as taxable and the rule assumed no tax had been charged yet. Two correct looking processes met on one invoice, and neither one could see what the other had already done.
That pattern is the interesting part for builders. It is not a typo problem. It is a rules collision problem, and collisions like it show up anywhere two independent automations act on the same record without checking each other's output first.
How the collision actually happens
It tends to appear on equipment, fixtures and supplies bought across state or national lines, where tax treatment is already less obvious. The supplier charges tax based on where the goods were delivered. The internal accrual runs from a category rule in the accounting system.
The break point is field coding. If the invoice tax line gets coded into the purchase cost instead of a separate tax field, the accrual rule has nothing to check against. From the rule's point of view, the tax field is empty, so the assumption that no tax was paid looks true, and the accrual fires. The data was present on the invoice the whole time. It was just stored where the second process never looked.
Refunds rarely unwind this on their own. Tax authorities generally expect the buyer to claim the overpaid portion with proof that tax was already paid, and suppliers rarely reverse a charge months later without documentation. The longer the pattern runs, the more invoices need to be matched one by one before anyone can file anything.
What worked
Compare three fields, on the same document number. The check that surfaced duplicates fastest was deliberately narrow: tax charged on the supplier invoice, tax coded in the ledger, and any use tax accrued, all pulled for the same document number. Where all three appear together, the duplicate is usually visible in minutes. No broad audit was needed to prove the pattern exists. The ten largest taxable purchases from the last quarter were enough.
Fix the rule, not just the invoices. Recovering money on the invoices already hit matters, but it leaves the cause in place. The durable fix was an exclusion in the accrual logic: if supplier tax was paid on a document, that document leaves the use tax population entirely. One rule change stopped the next quarter from quietly recreating the same list.
Keep the tax line in its own field, always. This sounds like bookkeeping hygiene, and it is, but it is also interface design between processes. A separate tax field is the contract that lets the second process make a correct decision. Folding tax into cost broke that contract, even though the totals still balanced.
Work the open period first. Recovery windows close. Starting with the period still open for claims, and filing with the invoice level proof already matched, turned a messy historical review into a sequence that could actually finish.
What broke
Category flags were trusted too far. A category marked taxable describes what usually happens, not what happened on a specific invoice. Early versions of the check treated the flag as ground truth and only sampled exceptions. That inverted the useful order. The invoice is the ground truth. The flag is only a prior.
Totals balancing gave false confidence. Because the invoice total was paid correctly and the ledger balanced, nothing looked wrong in summary reports. The overpayment lived in composition, not in totals: the right amount paid once, plus an extra accrual posted separately. Checks that only reconcile totals cannot see a duplication that arrives through a second posting path.
The first sweep was too wide. Scanning every purchase in a year produced a long, low confidence queue and slowed review. Narrowing to the largest taxable purchases first produced a short queue where each item could be confirmed quickly, and the confirmed pattern then justified widening the sweep with the rule already understood.
The takeaway
A lot of finance automation fails this way: not because a single rule is wrong, but because two reasonable rules were written at different times, by different teams, against different assumptions about the same fields. Testing each rule in isolation passes. The collision only appears when both run against the same real document.
That is why the tax check in ERPSav, a CloudVerg product, sits alongside its other recovery checks rather than inside a tax module alone. The product side lives at https://erpsav.com, where rules based engines scan for duplicate supplier payments, lease overcharges, utility and telecom errors, card fees, warranty claims and sales tax overcharges, so a fix in one area does not leave the same collision pattern running in another.
For builders wiring independent automations over shared records: where do your processes check what another process has already posted, and where do they still just assume?
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.