Most finance teams in India keep their statutory books in Tally and will keep doing so. The problem is not that Tally is the wrong place for the books — it is that the operational side ends up re-keyed into it, or worse, kept in a parallel spreadsheet that nobody reconciles.
So we import rather than replace. Two shapes come across: masters (groups, ledgers, stock items) and vouchers (the day book). Both arrive as XML, either from an export you make with Ctrl+E or straight over Tally's own HTTP gateway.
The sign convention will catch you out
Tally writes debits as negative amounts and credits as positive ones. Most systems, including ours, do the opposite. Getting this wrong does not throw an error — it silently inverts every balance sheet you produce afterwards.
<ALLLEDGERENTRIES.LIST>
<LEDGERNAME>Sharma Distributors</LEDGERNAME>
<ISDEEMEDPOSITIVE>Yes</ISDEEMEDPOSITIVE>
<AMOUNT>-11800.00</AMOUNT> <!-- negative = DEBIT in Tally -->
</ALLLEDGERENTRIES.LIST>We flip the sign exactly once, in the parser, so nothing downstream has to remember the rule. Everything past that boundary follows one convention: a positive amount debits the account, and a voucher is balanced when its entries sum to zero.
Identity, not heuristics
The naive way to avoid duplicate imports is to remember the date range you last pulled. That breaks the first time someone back-dates a voucher, which in accounting is most weeks.
Tally gives every voucher a GUID. We store it on the voucher with a unique index per organization. Re-importing an overlapping range then does exactly nothing to the vouchers you already have, and picks up the ones you do not — including the back-dated ones.
- GUID
- per voucher, unique per organization
- 2
- passes over groups, so children find their parents
- 0
- rows written before you accept the review
Everything is staged first
An import never writes on the way in. The file is parsed, every row is validated against your existing chart of accounts and catalogue, and the result is stored as a batch you review. Accepting it re-reads that stored batch under a row lock and applies it once — so a double click, a refreshed tab or a replayed request cannot post the day book twice.
What happens to the rows that do not fit
- A voucher naming a ledger you have not imported yet can be skipped, or parked in Suspense A/c so the rest of the day book still comes across.
- A rounding difference inside a Tally voucher goes to Suspense rather than being silently absorbed, so you can see it and fix it.
- Stock items that match nothing in your catalogue are reported, and optionally created as products in a category you choose.
- Cancelled and optional vouchers in Tally are skipped, and the review says so.
The review screen shows all of it before anything is written. That is the whole point: an import you cannot inspect is an import you cannot trust.