হিসাব তালিকা সমস্ত অ্যাকাউন্টিংয়ের ভিত্তি। ট্রাভেল-নির্দিষ্ট সাবট্রি: দায় (2011 BSP Payable, 2031-2035 Deferred Revenue), সম্পদ (1101 AR, 1109 Commission Receivable), আয় (4011 Air Commission, 4022 Tour Revenue, 4031 Service Fee), ব্যয় (5045 BSP Variance)।
Chapter 5.1 — Chart of Accounts
chapter: 05-accounting/01-chart-of-accounts
version: 1.0.0
status: stable
last_reviewed: 2026-05-26
owners: [accounting, platform-engineering]
1. Purpose
The Chart of Accounts (CoA) is the vocabulary of the partner's financial statements. Every journal entry, every report, every tax filing references account codes defined here. Getting this right is foundational; getting it wrong is expensive to retrofit.
2. Why this matters in modern travel accounting
Travel businesses have an unusually rich set of account types compared to a generic small business:
- Multiple receivable streams (B2C, B2B sub-agent, corporate accounts, IATA-net carriers).
- Multiple payable streams (BSP airlines, non-BSP airlines, hotel suppliers, GDS fees, payment processor fees).
- Several revenue categories that recognise on different triggers (commission earned at issuance, override commission earned at period close, markup earned at service date, service fees earned at issuance).
- Pass-through accounts for taxes the agency collects but does not own.
- Deferred revenue liabilities for tickets issued but not yet flown.
A generic accounting tool's CoA cannot capture this without customisation. travoBooks ships a travel-specific CoA template per country and a guided customiser.
3. Industry relevance
A correctly-structured CoA makes the following tasks trivial; an incorrectly-structured one makes them impossible:
- Quarterly commission earnings by airline.
- Net BSP exposure at any moment.
- Service-date-based revenue (the IFRS 15 requirement).
- Per-supplier ageing.
- ADM impact on the P&L.
- Tax filings broken out by jurisdiction.
4. Compliance considerations
| Standard | Implication for CoA |
|---|---|
| IFRS 15 (Revenue from Contracts with Customers) | Revenue cannot be recognised at ticket issuance unless control transfers then. CoA must distinguish recognised revenue from deferred. |
| IFRS 9 (Financial Instruments) | Receivables must be measurable for expected credit loss. AR accounts are subdivided by counterparty type. |
| IAS 21 (Effects of Changes in FX Rates) | Realised vs. unrealised FX gains/losses are separate accounts. |
| IFRS 16 (Leases) | If the partner has lease obligations (office, equipment), the CoA includes right-of-use assets and lease liabilities. |
| US-GAAP ASC 606 | Mirrors IFRS 15 for revenue recognition. |
| IATA BSP | A dedicated control account isolates "BSP Cash Payable" — money collected from customers that belongs to airlines via BSP. |
5. Business logic
5.1 Structure
The CoA is a hierarchical tree with a fixed top-level structure aligned to the five accounting elements, with travel-specific subtrees beneath.
1xxx ASSETS
10xx Current Assets
101x Cash & Equivalents
102x Accounts Receivable
103x Other Receivables
105x Prepayments
106x Inventory (vouchers, stock tickets)
15xx Non-Current Assets
151x Property, Plant & Equipment
155x Intangibles
158x Right-of-Use Assets (IFRS 16)
2xxx LIABILITIES
20xx Current Liabilities
201x Accounts Payable
2011 BSP Payable (control)
2012 Non-BSP Airline Payable
2013 Hotel Suppliers Payable
2014 GDS / Tech Vendor Payable
202x Tax Payable
2021 VAT/GST Output Payable
2022 Withholding Tax Payable
203x Deferred Revenue (Unearned)
205x Customer Advances / Deposits
206x Payroll Liabilities
25xx Non-Current Liabilities
251x Long-Term Loans
255x Lease Liabilities (IFRS 16)
3xxx EQUITY
301x Share Capital
302x Retained Earnings
303x Other Reserves
309x Current-Year P&L (system-managed)
4xxx REVENUE
401x Commission Revenue
4011 Air — Base Commission
4012 Air — Override Commission
4013 Hotel Commission
4014 Non-Air Commission
402x Markup Revenue
403x Service Fee Revenue
404x Cancellation/Change Fee Revenue
409x FX Gain — Realised
4099 FX Gain — Unrealised
5xxx COST OF SALES
501x Air Net Cost
502x Hotel Net Cost
503x Refund Cost Adjustments
504x ADM Net Impact
6xxx OPERATING EXPENSES
601x Salaries & Benefits
602x Office Rent (or 158x amortisation if IFRS 16)
603x GDS / Tech Subscriptions
604x Marketing & Advertising
605x Payment Processor Fees
606x Depreciation
609x FX Loss — Realised
6099 FX Loss — Unrealised
7xxx OTHER INCOME
8xxx OTHER EXPENSES
9xxx TAX
901x Income Tax Expense
5.2 Account anatomy
Each account row has:
| Field | Purpose |
|---|---|
code |
The numeric or alphanumeric code (e.g. 2011). Unique per partner. |
name |
Human-readable name. |
type |
One of: asset, liability, equity, revenue, expense, contra. |
subtype |
E.g. current_asset, current_liability, cost_of_sales. |
normal_balance |
debit or credit. Validates incoming postings. |
is_postable |
If false, the account is a header/rollup and cannot be posted to directly. |
is_control |
If true, posting is allowed only via auto-generated entries (e.g. AR control). |
parent_code |
The parent in the tree. |
currency_mode |
functional_only | any — whether the account holds only functional currency or accepts foreign-currency postings. |
tax_link |
Optional link to a tax profile (for output VAT/GST accounts). |
requires_dimension |
Required dimensions on a posting (e.g. supplier_id for supplier payable). |
is_active |
Soft disable; cannot delete an account that has ever been posted to. |
5.3 Control accounts
Certain accounts (AR, AP, BSP) are control accounts. The balance must equal the sum of the sub-ledger (per-customer, per-supplier). The system enforces this with:
- Postings to a control account are auto-generated only — never via manual JE.
- Sub-ledger and control reconcile on a nightly job; mismatch raises an alert.
5.4 Multi-currency accounts
Accounts marked currency_mode = any hold balances in any currency. The ledger row stores transaction_currency, transaction_amount, plus the functional-currency equivalents at posting time. Period-end revaluation produces unrealised FX gain/loss postings to 4099 / 6099. See Multi-Currency.
5.5 Versioning
Account definitions change rarely but they do change. travoBooks versions account metadata: when name changes, the historical name is preserved with effective dates. Reports run "as at" a date use the metadata in effect at that date.
6. Inputs → processing → outputs
6.1 Bootstrapping the CoA (on partner provisioning)
Input: country_code, business_type (B2B / B2C / Mixed), tax_regime (VAT / GST / None).
Processing: render a country-aware template; produce ~150 accounts seeded into chart_of_accounts.
Output: a complete usable CoA, with is_active = true for the common ones and is_active = false for jurisdiction-specific extras.
6.2 Adding / editing an account (input)
account:
code: "4015"
name: "Air — Group Booking Commission"
type: "revenue"
subtype: "operating_revenue"
normal_balance: "credit"
parent_code: "401"
is_postable: true
is_control: false
currency_mode: "any"
requires_dimension: []
6.3 Outputs
- New account available immediately.
- Permission
coa.edit.partnerrequired. - Audit log entry; emails to subscribed admins.
7. Module dependencies
| Reads from | Writes to | Read by |
|---|---|---|
| Country/tax reference | chart_of_accounts, chart_of_accounts_history, audit_logs |
Every accounting module: journals, invoicing, payments, reports |
8. Security & permissions
coa.read.partner— view CoA.coa.create.partner— add new accounts.coa.edit.partner— edit (name, parent, active flag).coa.deactivate.partner— toggleis_active.- 🔒 Account deletion is not exposed. Accounts with any posted ledger row cannot be removed; they are deactivated.
- 🔒
is_controlcannot be flipped on a populated account — would invalidate sub-ledger reconciliation.
Maker–checker: editing an account in active use (>0 ledger rows in current period) requires approver acknowledgement.
9. Validation rules
| Rule | Error |
|---|---|
code unique per partner |
COA_CODE_DUPLICATE |
code matches ^[A-Z0-9-]{2,16}$ |
COA_CODE_INVALID |
parent_code must exist and be is_postable=false |
COA_PARENT_INVALID |
normal_balance must match type (asset/expense = debit; liability/equity/revenue = credit; contra = opposite of its category) |
COA_NORMAL_BALANCE_MISMATCH |
| Cannot post to non-postable | COA_NOT_POSTABLE |
Cannot change type once any ledger row exists |
COA_TYPE_IMMUTABLE |
| Control account postings only from system | COA_CONTROL_DIRECT_POST |
| Required dimension missing on posting | JE_DIMENSION_REQUIRED |
10. Error handling
- A posting attempt to a deactivated account: 422 with
COA_INACTIVEand a hint to use the active equivalent. - A posting that violates
normal_balancedirection is allowed (a contra movement is legitimate) but flagged in the period anomaly report if the net movement contradicts the normal balance. - Bulk edits are transactional — if one row fails, none are applied.
11. Real-world example
Scenario. Innovate Travel (partner P-001, functional currency BDT) sells an international ticket on Emirates for a Dhaka–Dubai trip. Sell price BDT 80,000. Net cost BDT 72,000. Base commission BDT 6,000, override BDT 1,200 (estimated, recognised on quarter close). Service fee BDT 800. VAT 15% on service fee = BDT 120 (output tax payable, agency owes).
At issuance, the platform writes a single balanced journal entry that touches the following accounts:
| Account | Code | 🅓 Debit | 🅒 Credit |
|---|---|---|---|
| Customer A/R | 1021 | 80,920 | |
| BSP Payable | 2011 | 72,000 | |
| Air Base Commission Revenue | 4011 | 6,000 | |
| Service Fee Revenue | 4031 | 800 | |
| VAT Output Payable | 2021 | 120 | |
| Deferred Air Revenue | 2031 | 6,000 | |
| Air Base Commission Revenue (deferral reversal) | 4011 | 6,000 | |
| TOTAL | 86,920 | 86,920 |
Two things to note from the CoA's role here:
- The presence of a dedicated
Service Fee Revenue(4031) distinct from Commission Revenue (4011) is what later allows the partner to file VAT correctly — VAT applies to service fees, not to the airline ticket pass-through. - The deferral of the BDT 6,000 commission lives in
2031 (Deferred Air Revenue)because under IFRS 15 the airline's performance obligation (the flight) has not yet been satisfied. At service date, a second journal moves it: 🅓20316,000 / 🅒40116,000.
The override commission (BDT 1,200) is not posted at issuance because it is estimated; it accrues to 4012 Air Override Commission only when the airline confirms the achievement at quarter close.
12. Step-by-step workflow — customising the CoA
13. Database tables touched
chart_of_accounts— current state.chart_of_accounts_history— every edit, with effective dates.account_dimensions— required dimensions per account.tax_profiles— referenced viatax_link.
Full schema in 10-database/03-table-reference.md.
14. Future scalability
| Need | Approach |
|---|---|
| Multi-entity consolidation with different CoAs | Group-level mapping table maps partner-account → group-account at report time. |
| IFRS / Local-GAAP dual ledger | Each account can carry a local_gaap_code mapping; reports render via the chosen lens. |
| Industry-segment CoAs (e.g. corporate vs leisure) | cost_centre dimension on every posting; CoA stays unified. |
15. Common pitfalls
- ⚠️ Adding a new account in the middle of a fiscal period and posting historical entries to it. Period-comparison reports will spike. Use effective-date metadata or carry on with the existing account and re-categorise next period.
- ⚠️ Treating BSP Payable like a regular AP. It is a control account with airline-level sub-ledger; never journal it directly.
- ⚠️ Confusing markup revenue with commission revenue. They have different VAT treatment in most jurisdictions.
Next: 02-journals-and-ledger.md — how journal entries are constructed, validated, and posted to the GL.