Case studies / Tigg Accounting · Jun – Sep 2025
The account decides the currency
Multi-currency accounting breaks when the currency can be changed in the wrong place. I built the rules that tie currency to the account, and a quick-approve for bank reconciliation that is one click only when it's safe.
Role
Timeline
Team
Platform
Not mine
Measured outcome
the key decision
Currency follows the account, and leaving NPR empties the rate, so a rate of 1 can't slip into a foreign payment.
how deep do you want to go?
A number that passes every check and is still wrong
In the summer of 2025 Tigg Accounting needed to handle more than one currency properly. Most Nepali businesses keep their books only in rupees, but some pay foreign suppliers, bill clients in dollars, or hold a foreign-currency bank account. For them, every payment, receipt and bank line carries two facts: a currency, and a rate to NPR.
Walking through the money forms, I found the failure that worried me most. A form opened in NPR, where the exchange rate is 1 and the field is disabled. If the user then switched the currency to USD, the 1 stayed. Saving worked, because 1 is a present and positive number. The ledger then recorded a USD 1,250.00 payment as NPR 1,250.00 instead of roughly NPR 1,66,750.
An empty field gets noticed; a wrong number that looks right does not. That idea shaped the rest of the work: a default is a claim, and the form should only make claims that are true in the current context.
Context and how I worked
I was the only UI/UX designer at Tigg, and at that point I was moving from my internship into a frontend role. The trigger was the product's move to real multi-currency support. I didn't find a Figma file for these surfaces because I designed them directly in code. I changed the live forms, tested each rule against the forms that used it, and the senior frontend engineer reviewed every change before it was merged.
My research was a surface audit. I went through every place in the accounting app where an amount or a currency control appears and noted what it showed and what it let people do:
- the dashboard bank cards, the bank overview and its charts;
- bank statements, the reconciliation report and the matching drawers;
- customer and supplier payments, quick receipt, quick payment, cash transfer;
- the sales documents (quotation, sales order, invoice, credit note);
- the journal voucher used for forex adjustments.
Some context applied everywhere. NPR is the base currency, so every rate is written "to NPR" and NPR is listed first. A revaluation gain or loss is booked in NPR. Many businesses run more than one branch, and a branch changes which documents apply.
Three rules for the forms
The audit came down to three rules. Each one answers a question the forms had left open.
1. An amount always carries its currency
Dashboard balances, charts, statements and the reconciliation drawers now show the currency code or symbol next to the number, with the minus sign in the right place. The code is smaller and lighter than the amount: it gives context without adding clutter.
2. The account decides the currency
A payment from a USD bank account can only move USD. When someone picks a foreign-currency account in a payment, receipt or transfer, the form sets the currency to match and locks the selector. The rate stays editable, because the rate is still the user's decision.
My first version locked the currency for every account, NPR accounts included. Two days later I limited the lock to foreign accounts. Looking back, locking an NPR account added friction without preventing any real mistake. The risky case was always a foreign account posted in the wrong currency.
3. Leaving NPR clears the rate
Choosing NPR sets the rate to 1 and disables the field. Leaving NPR for a foreign currency empties the field and makes it required, so saving is blocked with "Exchange Rate is required" until someone types a rate. The forex-adjustment journal always opens in NPR with the currency fixed, because revaluation is recorded in the base currency.
Asset to add
Screenshot, test company with multi-currency on: New Supplier Payment after choosing a USD bank account in 'Paid From'. Show the currency set to USD and locked, and the empty, required 'Exchange Rate to NPR' field with its error.
One click, only when one click is enough
The same principle carried over to bank reconciliation. Before this work, every unmatched bank line needed "Find Match" or a full drawer to create a receipt or payment, even when the answer was obvious: a monthly fee, or a regular customer paying again. The backend could already suggest an account for a line, but the table didn't use the suggestions.
I designed and built a suggested account and an approve tick on every pending row, in the Bank Statement tab and in the bank overview's list of recent unmatched transactions. The first suggestion is filled in. If it's wrong, the user can search for any account, or clear the field. A cleared row stays empty, because clearing a suggestion is a decision and the table shouldn't quietly fill it again.
The hard question was when the tick is allowed to post straight away. A one-click post can't guess an exchange rate or a branch. So the tick checks three things in order: whether the organisation uses billing locations (branches), whether the line is in a foreign currency, and whether the bank account is. If any answer is yes, nothing is posted. The full drawer opens with the chosen account already filled in, and it asks only for what's missing.
I also removed the match percentage from the suggestion label. The score behind it came on different scales in different responses, so any number I showed would look more precise than the data really was. Now the label shows only the account name.
Asset to add
Screenshot, test company: Bank account → Bank Statement tab with one Reconciled line (showing linked document codes) and three Pending lines — a suggested account, a cleared selector, and a line with no suggestion.
What shipped
The work ran from late June to early September 2025 in three stages, each merged to production after review:
- Jun – Jul 2025Currency visible and bound to the accountCurrency on every money surface, the account lock, and the rate that clears when leaving NPR. Merged to production in July.
- Jul 2025Currency in the reconciliation drawerThe add-payment drawer follows the bank's currency, and it still works when multi-currency is switched off.
- Aug – Sep 2025Suggestions and quick approveSuggested accounts, search, clearing, the guard, and links from a reconciled line to its records. Merged to production in early September.
Quick approve is used in the product today. Measured outcome: none. I have no figures for error reduction, reconciliation time or how often suggestions are accepted, so I don't claim any.
A small sign that the rule held up: in March 2026 another engineer built a new document form and reused the same "clear the rate when leaving NPR" behaviour.
If I were measuring this, I'd track four things: how often the tick is used, how often people change or clear the suggestion, how often the guard sends a line to the full form and for which reason, and how many one-click posts are reversed within a week. That last number is the real safety signal.
What I learned
A default is a claim. "1" is only true for NPR. A pre-filled number is more dangerous than an empty field because it passes validation. I learned this twice: two weeks after fixing the forms, I briefly let the reconciliation drawer fill an empty rate with 1 for convenience, and replaced it with an empty, required field the same day.
Constrain only what can go wrong. Locking NPR accounts protected nobody. A constraint should match a real risk, not just look careful.
Speed should depend on context. One click promises that nothing else is needed. When a branch or a rate is involved, the honest response is the full form, already filled in, rather than a guess or an error.
The rule sheet and the row states
The currency pair, as a table
This is the sheet I used to check each form by hand. The codebase had no automated tests, so every rule had to be simple enough to check this way during review.
| Before | Action | Account currency | Currency after | Rate after | Selector |
|---|---|---|---|---|---|
| (new form) | form opens | none | NPR (listed first) | 1, disabled | free |
| NPR | choose USD | none | USD | empty, required | free |
| USD | choose NPR | none | NPR | 1, disabled | free |
| any | choose account | USD | USD | empty until typed | locked |
| any | choose account | NPR | NPR | 1, disabled | free |
| none | open reconciliation drawer | bank in USD | USD | the line's rate, or empty | locked |
| none | forex adjustment | none | NPR | 1, disabled | fixed |
With multi-currency switched off for the organisation, the currency controls don't appear at all, and documents are saved in NPR at 1.
A pending bank line
| State | What the row shows | What the tick does |
|---|---|---|
| Suggested | the first suggestion, filled in | posts, or opens the drawer if the guard says so |
| Chosen | another suggestion, or any searched account | same as above |
| Cleared | an empty selector that stays empty | nothing until an account is chosen |
| No suggestion | "Select account"; the list loads when opened | nothing until an account is chosen |
| Reconciled | "Reconciled" with up to two linked records and "+N more" | none; the links open the records |
When a line posts directly, the kind of record follows from the line and the account. Money in from a customer becomes a customer payment and money out to a supplier becomes a supplier payment. Anything else becomes a quick receipt or a quick payment. A failure shows the server's message, or "Transaction Failed", and leaves the row as it was.
Asset to add
Screenshot, test company with billing locations on and a USD bank account: the reconciliation drawer opened by pressing the tick on a USD line — account pre-filled from the row, currency locked to USD, rate and location still to fill.
Iterations and notes on sources
How the lock found its place
| When | Version | What happened |
|---|---|---|
| Early July 2025 | Lock for every account | Built, then limited two days later |
| Early July 2025 | Work out the currency by watching the account field afterwards | Didn't work reliably; I reverted it the next day and passed the currency along with the user's choice instead |
| Same week | Lock inside the shared currency field | Replaced within hours: the field couldn't know why the currency was foreign |
| Same week | Each form decides and tells the field | Kept. A review round also simplified the shared field, removing options I had added to it |
| A few days later | Fix for blank forms | New, empty forms showed the selector locked by mistake. Fixed with an NPR default |
Where these facts come from
No ticket, design file or chat record exists for this 2025 work. Dates and behaviour come from the product and its version history, which I've read again for this write-up. Where I give a reason for a change, it's my reading of the change looking back, not a note I wrote at the time. The screens above are placeholders for screenshots from a test company. The diagrams are redrawn, and all amounts are fictional.