Twelve entities, twelve spreadsheets, one deadline — and the tax they needed was already sitting in the group.
New Zealand runs provisional tax on fixed dates. Miss one, or guess low, and Inland Revenue charges use-of-money interest and late payment penalties from the day you should have paid. Tax pooling is the legislated way out: a pool of tax already deposited with IRD on those dates, from which you can buy a backdated credit that IRD treats as paid on time.
Most of the country’s accountants use it for one client at a time. The interesting problem is a group — a parent and its subsidiaries, filing together, some having overpaid and some having underpaid on exactly the same dates. The money to fix the shortfall is frequently already sitting two rows down the same spreadsheet.
Getting it there meant building a spreadsheet per entity, working out by hand who was over and who was under, and then raising each transfer, purchase and sale as a separate transaction. Against a hard deadline. In the busiest fortnight of an accountant’s year.
My role
I led design at TMNZ, New Zealand’s original tax pooling provider. Group Optimiser was mine end to end: the discovery with tax agents, the flow, the interaction model for the netting table, the terminology, every state and every empty state, and the arguments with myself about how much of this to automate.
Stack
Figma with a component library and variables, ClickUp for the brief-in and real accountant sessions for validation.
The before
Here is the ritual, and I want to be fair about it — it worked. It was just enormously expensive, entirely manual, and wrong in a way nobody could see until the deadline had gone.
Every entity in the group needs its position worked out: what IRD says is due on each date, what has actually been paid, what is sitting in the pool. Then someone reconciles those by hand into a group view, decides which surpluses cover which shortfalls, and raises the transactions one at a time. Add an entity and the work doesn’t grow by one — it grows by one against every other entity and every tax date.
Three steps, in the order an accountant thinks
The whole design came down to sequencing. An accountant does not want a settings screen; they want to be asked the handful of questions that change the maths, see the answer, and then commit it deliberately. So: preferences, then the optimised position, then confirm.
The rule I held to across all three: nothing is created until step three. Steps one and two are a quote you can run twenty times on a Tuesday and walk away from. That single promise is what let me put a live-recalculating table in front of people handling other people’s tax money without anyone getting nervous.
Step one — the four questions that change the maths
Every preference on this screen exists because leaving it implicit would produce a technically correct answer that the accountant would then have to unpick. Should tax that’s currently listed for sale be pulled back into the group? Should surplus that the optimisation doesn’t need be sold? Should tax dates that haven’t happened yet be included, when the client may still intend to deposit on them?
Each one carries a plain-English consequence and, where there’s a defensible default, the word (Recommended) — earned, not decorative. A recommendation on a screen about someone else’s tax liability is a promise, so each one had to survive a sentence explaining why.
Step two — the netting table
This is the product. Every taxpayer in the group, their position at IRD, what they hold in the pool, and — the part that did not exist before — what the group can do for itself before anybody spends a dollar.
Include and exclude entities and the whole position recalculates in front of you: transfers out of the surplus entities, transfers into the short ones, the residual that genuinely has to be bought from the pool, and any excess that can be sold. Underneath it, the number the entire product exists to produce — the interest and penalties this group does not pay.
Two interaction decisions did most of the work. The table recalculates immediately, with no apply button, because an accountant tests a hypothesis by toggling — and an apply button turns eight hypotheses into eight round trips. And every derived figure carries its own explanation on hover, because “why is that number that number” is the only question that matters here, and a support call is a design failure.
The awkward cases, drawn
Financial tools are judged on their edges, and this one had three that mattered. A taxpayer past the IRD deadline for pooling that year, who cannot legally be included no matter what the table would prefer. Tax dates in the future, which may or may not belong in the calculation depending on whether the client plans to deposit on them. And entities the accountant simply has not finished — not started, or half-filled — sitting in a group that is otherwise ready to go.
None of these are errors. All three were being handled as errors, in red, at the point of failure. I moved every one of them upstream into a stated exclusion with a reason and a way back, because an accountant discovering at step three that four entities silently dropped out is an accountant who never trusts the tool again.
Step three — how you’d like to pay for it
The residual purchase still has to be paid for, and there are genuinely different products behind that: pay it down flexibly as cash allows, fix a fee up front and settle at a future date, or build an instalment arrangement. Three real choices, each with a different interest profile, presented as a comparison rather than a dropdown — because this is the one decision on the screen that is about the client’s cash flow rather than their tax position.
Then the AML confirmation, which is a legal requirement and reads like one. I fought to keep it in plain language and short, and lost about a third of that fight, which is roughly par for a compliance checkbox.
Where it lands afterwards
Group Optimiser doesn’t live alone. The dashboard has an Upcoming Deadlines tab where an agent tracks which clients are approaching which dates, and every entity carries a status: not started, incomplete, complete, pending approval, pending payment.
Running the optimiser is, by definition, doing the thing those statuses are tracking — so one of the step-one preferences quietly closes the loop and marks the optimised taxpayers complete. It’s the smallest feature in the project and the one agents mentioned most, because it removes the bit of admin that exists purely because two screens didn’t talk to each other.
Which is the version of automation I actually believe in: not a machine making the tax decision, but a machine refusing to make a human retype what it already knows.
And the paperwork
Accountants do not finish at the screen. They finish when the client, the file and sometimes the bank all have the same document. So the same optimised position exports as a report designed to be read on paper: a group page, a page per taxpayer, footed with who generated it and when, and a payment page with the banking details on it.
Results
What I learned
In financial products the edge cases are the product. The happy path took a fortnight. Past-deadline taxpayers, future dates, half-finished entities, groups where the optimisation nets to exactly zero, groups with nothing to buy at all — that took months, and it is the entire difference between a tool an accountant trusts in June and one they open once.
Recalculation is a trust mechanic, not a performance one. The reason the table updates instantly isn’t speed. It’s that watching a number move in response to your own decision is how a person builds a model of what the system is doing — and a model is the thing that lets them sign off on it.
And say what you excluded, before you exclude it. Every quiet, sensible, correct omission a system makes on someone’s behalf is a small withdrawal from the same account. Spend it once and you have a support ticket. Spend it twice and they go back to the spreadsheet, where at least the mistakes are theirs.