Filing a VAT return used to mean an accountant pulling every invoice and bill for the period into a spreadsheet — days of work, one missed row away from being wrong.
The first fix was structural: a batch engine that claims every posted invoice, bill and reversal in the date window and locks each document to that one batch, so the same document can never be filed twice across two periods. Reversals are subtracted rather than trusted on sign alone, and the Excel export is laid out exactly like the official return form.
Across three GCC companies, the harder problem is the chain between periods. Credit carries forward from one return to the next, and an unnoticed gap or an overlapping period silently misstates a return that has already been filed.
So the system refuses to guess. Two batches can't share a period, and the rule lives in the model, so imports and scripts obey it too. Each batch finds the last submitted one for its company. When the periods are consecutive the credit carries forward automatically; when they aren't, the batch shows an explicit gap warning and a person decides.
Tax treatment follows the same idea. One category on each tax — standard, reduced, zero-rated, exempt, import/export or reverse charge — replaced detection logic scattered through the code, so a new treatment is a data change, not a code change in three places.
Read the case study: VAT across three GCC companies, with no silent filing gaps