Chart of Accounts

The Chart of Accounts (CoA) is the list of GL accounts a company posts to. It is the vocabulary of the financial statements. Every posting in the entire ERP eventually lands on one.

Account types

Type Balance sheet or P&L Normal balance Resets at year end?
Asset BS Debit No — carries forward
Liability BS Credit No
Equity BS Credit No
Revenue / Income P&L Credit Yes — closed to retained earnings
Expense / Cost P&L Debit Yes

The accounting equation, which the ERP enforces at all times:

Assets = Liabilities + Equity
       where Equity includes (Revenue − Expenses)

The numbering convention

Most charts follow a block structure. A very common shape:

1xxxxx  Assets
  10xxxx  Cash and bank
  11xxxx  Accounts receivable
  12xxxx  Inventory
  13xxxx  Prepaid expenses
  15xxxx  Fixed assets (cost)
  16xxxx  Accumulated depreciation (contra-asset)
2xxxxx  Liabilities
  20xxxx  Accounts payable
  21xxxx  Accrued liabilities
  22xxxx  Tax payable
  23xxxx  GR/IR clearing
  25xxxx  Loans
3xxxxx  Equity
  30xxxx  Share capital
  32xxxx  Retained earnings
  33xxxx  Current year result
4xxxxx  Revenue
  40xxxx  Product sales
  41xxxx  Service revenue
  45xxxx  Sales returns and discounts (contra-revenue)
5xxxxx  Cost of goods sold
6xxxxx  Operating expenses
7xxxxx  Other income/expense
8xxxxx  Financial income/expense
9xxxxx  Tax and extraordinary

Learn to read an account number at a glance — 4 means revenue, 23 means a clearing account. This is how finance people talk.

Special account categories developers must know

Reconciliation accounts

AR and AP balances are not posted directly. You post to a customer or vendor (a subledger), and the system automatically posts to a reconciliation account in the GL.

Invoice customer ACME for 1,000
  Subledger:  Customer ACME     Dr 1,000
  GL:         113000 Trade AR   Dr 1,000  ← automatic, from the customer master
              400000 Revenue    Cr 1,000

You can never post manually to a reconciliation account. The subledger and GL must always agree; manual posting breaks that. This trips up every developer once.

Clearing accounts

Temporary holding accounts that should net to zero over time. The most important:

  • GR/IR (Goods Receipt / Invoice Receipt) — sits between receiving goods and receiving the supplier’s invoice. Debited on receipt, credited on invoice. A non-zero aged GR/IR balance means missing invoices or missing receipts, and auditors always look at it.
  • Bank clearing — between payment issued and bank statement confirmed
  • Payroll clearing — between payroll calculation and payment
  • Inter-company clearing — between paired entities

Clearing accounts are managed with open item management: each posting is an open item, cleared when matched against its counterpart.

Contra accounts

Accounts that sit against another and carry the opposite normal balance:

  • Accumulated depreciation (contra to fixed assets)
  • Allowance for doubtful accounts (contra to AR)
  • Sales returns and allowances (contra to revenue)

Statistical / memo accounts

Non-financial quantities used for reporting (headcount, square metres, units produced) so allocations can be driven by them.

Multiple charts of accounts

Large groups run more than one:

Chart Purpose
Operating / Group chart The one everybody posts to, used for group consolidated reporting
Country / Local chart Legally mandated local structure (France’s PCG, Bangladesh’s, China’s, Germany’s SKR)
Group chart Mapping target for consolidation

Postings hit the operating chart; an alternative account number on each account maps to the local chart for statutory reporting. Countries with prescribed charts (France, Belgium, Spain, China, Russia) make this mandatory, not optional.

Account determination — the key developer concept

Business users do not choose GL accounts. The system derives them from configuration. This is called account determination (or posting profiles / posting setup).

Example: goods issue for a sales delivery.

Inputs:  Chart of accounts + Valuation area + Valuation class of material
         + Account modifier + Movement type
Output:  Debit 500000 COGS, Credit 120000 Inventory

Every ERP has dozens of these determination tables:

Process Determination
Goods movements Movement type + valuation class → inventory/expense/COGS accounts
Sales billing Condition type + account key + customer/material account group → revenue, discount, freight accounts
Purchasing invoice Account assignment category → expense/asset/GR-IR accounts
Fixed assets Asset class → APC, accumulated depreciation, depreciation expense
Payroll Wage type → expense and liability accounts
Tax Tax code → input/output tax accounts
Bank House bank + payment method → bank and clearing accounts
FX Valuation method → realised/unrealised gain and loss accounts

When someone reports “the posting went to the wrong account”, 95% of the time the fix is in an account determination table, not in code. Learn where these tables live in your product; it will make you look like a wizard.

Field status and validation

Each account controls which fields are required, optional, or suppressed on a posting:

  • A cost account may require a cost centre
  • A bank account may suppress the cost centre
  • A revenue account may require a profit centre

This is field status group in SAP, posting profiles/financial dimensions rules elsewhere. It’s the mechanism that stops incomplete postings.

Designing a chart of accounts (if you’re building one)

  1. Keep it small. 300–800 accounts is healthy for a mid-size company. Charts with 5,000 accounts are almost always misusing accounts as dimensions.
  2. Do not encode dimensions in the account number. 600100 Salaries – Dhaka – Sales is wrong. Use 600100 Salaries + cost centre + profit centre. Otherwise the chart multiplies with every new location.
  3. One account = one meaning, forever. Never repurpose.
  4. Leave gaps in numbering for future insertions.
  5. Mark open-item-managed accounts deliberately — only clearing-style accounts.
  6. Decide P&L by nature or by function early (nature: “salaries, rent, depreciation”; function: “cost of sales, admin, distribution”). IFRS allows either; the choice reshapes the whole expense block.

Table shape if you’re building it

CREATE TABLE gl_account (
  id                BIGSERIAL PRIMARY KEY,
  chart_id          BIGINT NOT NULL REFERENCES chart_of_accounts(id),
  account_number    VARCHAR(20) NOT NULL,
  name              VARCHAR(255) NOT NULL,
  account_type      account_type_enum NOT NULL,  -- ASSET|LIABILITY|EQUITY|REVENUE|EXPENSE
  is_reconciliation BOOLEAN NOT NULL DEFAULT FALSE,
  recon_subledger   subledger_enum,              -- AR|AP|ASSET when reconciliation
  open_item_managed BOOLEAN NOT NULL DEFAULT FALSE,
  currency_code     CHAR(3),                     -- NULL = any currency
  blocked_for_posting BOOLEAN NOT NULL DEFAULT FALSE,
  alternative_account VARCHAR(20),               -- local chart mapping
  valid_from        DATE NOT NULL,
  valid_to          DATE,
  UNIQUE (chart_id, account_number)
);

Note: no balance column. Balances are derived from journal lines. See General Ledger.

Next