A 65-person consulting firm. Three data sources, a 14-tab Excel file, a close that took three days and caught revenue timing errors only at the quarterly review. Here is what we connected, the six tiles we built, and the three outcomes in the first quarter, including a budget overrun caught before it happened.
This is a case study from a build we completed in early 2026. The client is a 65-person management consulting firm based in the Netherlands. We have anonymised the company name. The numbers are as close to real as we are able to share.
Before: a three-day close nobody trusted
The finance controller ran the month-end close with one analyst. The process was not complicated, it was just slow, because the data they needed lived in three places that did not speak to each other.
The ERP (Exact Online) held revenue, invoices, and cost by department. The project management and time-tracking tool (Teamwork) held billable and non-billable hours by project and consultant. A Google Sheet maintained by account managers held the approved budget per project and any change orders that had been agreed verbally but not yet invoiced. All three were correct in their own system. None of them agreed with the others without manual work.
The close routine was: export from Exact, export from Teamwork, open the budget sheet, and reconcile them in Excel. The Excel file had fourteen tabs, grew by a few hundred rows each month, and was passed between the controller and the analyst by email with version numbers in the filename. On bad months, the filename reached v7 or v8 before the numbers were signed off. The close consistently took three working days.
Three things went wrong regularly enough to have become expected:
Consultants entered hours late, sometimes two or three days after the month closed, which meant the Teamwork export was always an undercount at the time the controller needed it. The controller knew this and applied a mental adjustment that was never written down.
Account managers updated the budget sheet during the close without telling finance. The controller discovered changes when the reconciliation did not balance. Tracking down which line had changed, and why, added half a day to a close that was already running long.
Revenue recognition timing was inconsistent across projects. Exact recorded revenue when an invoice was raised. Teamwork recorded completion when the project was marked done. The two events often happened in different months. Without a systematic check, revenue sometimes landed in the wrong period and was only caught in the quarterly review, too late to correct cleanly.
None of this was a crisis. It was a slow drain: senior finance time spent on reconciliation instead of analysis, and a monthly number that the leadership team had learned to treat with mild scepticism until the controller confirmed it was final.
What we built
The brief from the discovery call was clear: the controller wanted to close the month in a single day, with confidence in the number, and without spending the first half of that day hunting for discrepancies.
We connected three sources: Exact Online (via the REST API), Teamwork (via the API, pulling hours with a 24-hour lag tolerance), and the Google Sheet (read-only via the Sheets API, refreshed every 30 minutes). The board has six tiles:
Revenue recognised vs contracted. By project, from Exact. Shows the gap between what has been invoiced and what the contract value is, the controller's first question every close.
Hours by project: billable vs non-billable. From Teamwork, month-to-date and prior month for comparison. Includes a flag for projects where non-billable hours exceed 15% of total, the threshold the firm uses internally to trigger a conversation with the account manager.
Unbilled hours at risk. Projects where cumulative hours logged are within 20% of the approved budget ceiling, sorted by proximity to the ceiling. Pulls from both Teamwork (hours) and the Google Sheet (approved budget). The tile the controller said she wished had existed two years earlier.
Open WIP. Hours logged but not yet invoiced, by client and project. Exact and Teamwork combined, the invoice hasn't been raised yet but the work has been done. Quantifies unbilled exposure in euros at the standard day rate.
Cost by department. From Exact cost centre data, current month vs prior month and vs budget. One number per department, updated nightly.
Revenue timing check. Projects where the Teamwork completion date and the Exact invoice date fall in different months. Flags the recognition timing mismatches the controller had previously caught only in the quarterly review.
Build time was seven days. Day one: discovery and data mapping, the Google Sheet structure had evolved over three years and needed careful documentation before we could treat it as a reliable source. Days two and three: Exact and Teamwork integrations, validation of the revenue and hours tiles. Days four and five: the budget ceiling logic for the unbilled risk tile, and the timing check. Day six: review with the controller and the analyst, two adjustments to the WIP calculation. Day seven: live, with a two-hour handover.
After: four hours, one version
The first close after go-live took four hours. The controller described the difference as going from assembling the picture to reading it. The board had already done the reconciliation overnight. Her job on close day was to review the flags, make judgment calls on anything unusual, and sign off. The Excel file was not opened.
Three outcomes that were measurable within the first quarter:
A budget overrun caught before it happened. In the second week of the following month, the unbilled hours at risk tile showed one project at 91% of its approved budget with three weeks of the engagement remaining. The controller raised it with the account manager that morning. A change order was agreed before the project ran over. Under the old process, the overage would have appeared in the next month-end export, after the work was done and the client already surprised.
Revenue recognition errors eliminated in the first close.The timing check tile surfaced four projects where Exact and Teamwork completion dates fell in different months. Two were legitimate, invoiced early against milestone agreements. Two were errors: work completed in February, invoiced in March because the account manager sent the approval late. Both were corrected before the February close was filed.
The budget sheet stopped being a source of surprises. The Google Sheet is still maintained by account managers. The controller still does not control it. But because the dashboard refreshes it every 30 minutes and flags changes that affect open WIP calculations, mid-close updates now surface as a notification rather than an unexplained discrepancy. The half-day hunting exercise did not occur in the first three closes after go-live.
The analyst's role changed. She had spent most of close week on reconciliation mechanics. After go-live, she spent it on the things the dashboard flagged, calling account managers about budget ceilings, chasing late hour entries, preparing the commentary for the leadership pack. The controller described it as the difference between her analyst doing the close and doing the work that comes after the close.
What made it work
The Google Sheet was the interesting problem. It was informal infrastructure, built by account managers, not finance, to track something that the ERP did not capture well. It was not a reliable data source by conventional standards. But it was the only place the approved budget per project lived. Connecting it as a read-only feed, with a refresh cadence and change logging, turned an informal spreadsheet into a structured source without asking account managers to change how they worked.
The revenue timing tile was the one the controller had not thought to ask for. We proposed it during discovery when she described the quarterly review catch, a symptom that pointed to a systematic timing mismatch rather than isolated errors. It turned out to be the tile she checks first on close morning.