Skip to content

Chart of accounts

Fexl Lite seeds a chart of accounts the first time a tenant boots — five top-level types (Asset, Liability, Equity, Revenue, Expense) and a fixed set of sub-accounts under each. Every flow in the app — POS, refunds, restocks, supplier payments — posts to one of these codes. Most operators never need to touch the chart; this page is the reference when you do.

Updated 4 May 2026·For v1.6.100·6 min read

How the chart is structured

Every account has a four-digit code, a human name (English + Arabic), a type (asset / liability / equity / revenue / expense), and an optional parent_id that nests it under a roll-up code. The leaves are where journal entries actually post — the parents are presentation-only on reports.

The number ranges follow a convention you’ll recognise from any standard accounting textbook:

  • 1xxx — Assets
  • 2xxx — Liabilities
  • 3xxx — Equity
  • 4xxx — Revenue
  • 5xxx — Cost of Goods Sold (a sub-flavour of expense)
  • 6xxx — Operating Expenses
  • 7xxx — Other income / expense

Within each range, the first slot (e.g. 1000 Assets) is the parent, and the rest of the codes nest under it.

Assets (1xxx)

Things you own. Debits increase, credits decrease.

CodeNameWhat posts here
1000Assets (parent)rolled-up only, no JE writes here
1010Cashparent of cash sub-accounts (1010-001, 1010-002, …)
1020Bankcard-machine settlements, bank-transfer payments
1030Mobile Moneywallet-style payment methods
1100Accounts Receivablepartial-payment / pay-later debt; opening balance on customers
1200Inventoryevery restock ingress; balance = Σ FIFO qty_remaining × cost
1300Advanced Paymentsprepaid expenses pending amortisation (rent, insurance)

The Balance Sheet derives the 1010 Cash number by summing every 1010-* sub-account, not by reading 1010 directly. Children sum to parent — see Balance Sheet.

Liabilities (2xxx)

What you owe. Credits increase, debits decrease.

CodeNameWhat posts here
2000Liabilities (parent)rolled-up only
2010Accounts Payablesupplier balances; PO receive (unpaid portion) credits this
2020VAT PayableVAT collected on sales, less VAT reclaimable on purchases
2030Commission Payableaccrued delegate commissions awaiting payout
2040Deferred Revenueinvoices paid in advance for goods not yet delivered
2100Customer Creditsstore credit owed to customers (refund-as-credit destination)

The customer-credit liability is 2100, not 2120 or any other near-miss. A store credit refund posts CR 2100; a credit withdrawal posts DR 2100. See Debt & credit for the full debt-vs-credit accounting model.

Equity (3xxx)

The owner’s stake. Credits increase, debits decrease.

CodeNameWhat posts here
3000Equity (parent)rolled-up only
3010Owner’s Equitydirect owner contributions; “no supplier” PO receives credit here
3020Retained Earningsaccumulated net profit at year-end

3010 is the catch-all when you receive stock without a supplier (the owner brought it from home, a sample arrived without paperwork). The PO receive flow checks for a supplier on the PO row — if there isn’t one, it credits 3010 instead of 2010.

Revenue (4xxx)

What customers pay you. Credits increase, debits decrease.

CodeNameWhat posts here
4000Revenue (parent)rolled-up only
4010Sales Revenueevery sold-product line on every invoice
4015Service Revenueservice-type invoice lines (no inventory move)
4020Sales Returnsrefunds (cash, card, or credit); shows as a contra on the P&L
4030Sales Discountsdiscounts taken at POS; contra to sales
4040Shipping Revenueshipping fee charged to the customer on an invoice

A refund debits 4020 (reducing net revenue) and credits whichever account took the refund: cash sub-account on a cash refund, card terminal on a card refund, 2100 on a store-credit refund. The amount lands at the gross refund value — VAT and shipping reversals are separate lines on the same JE.

Cost of Goods Sold (5xxx)

What it cost you to deliver the revenue. Debits increase, credits decrease.

CodeNameWhat posts here
5000Cost of Goods Sold (parent)rolled-up only
5010COGS — Productsnon-bonus units sold; FIFO unit cost × quantity
5020COGS — Bonus Itemsbonus / BOGO units; bonus-allocated cost × quantity

Splitting bonus from sold products on COGS is what lets the P&L answer “how much did the promotion actually cost me.” Without the split, the bonus cost would hide in the same bucket as regular COGS and the gross-margin line would lie. #40 v1.6.100 made the split correct on the defect-egress write too — so even returns of bonus items hit 5020 rather than 5010.

Operating Expenses (6xxx)

Running costs. Debits increase, credits decrease.

CodeNameWhat posts here
6000Operating Expenses (parent)rolled-up only
6010Rentrent expenses
6020Utilitieselectricity, water, internet
6030Transportlocal delivery, taxis
6040Fuelvehicle fuel
6050Office Suppliesstationery, consumables
6060Marketingads, promotions, signage
6070Commissionsdelegate commission payouts (cleared from 2030)
6080Shipping Expensesoutbound shipping cost paid to a carrier
6099Other Expensescatch-all for un-categorised expenses

Expenses can also be prepaid — you pay 12 months of rent upfront. The cash leg goes to 1300 Advanced Payments instead of 6010 directly, then a monthly amortisation entry moves 1/12 from 1300 to 6010 over the next year. See Prepaid expenses.

Other (7xxx)

Anything not core to the operating P&L.

CodeNameWhat posts here
7000Other Income (parent)rolled-up only
7050Cash Over/Shortmanual entries for accumulated drawer variance
7100Other Expenseone-off losses (broken inventory, theft write-off)

Cash Over/Short (7050) is where many operators settle accumulated shift variance at the end of a week or month. Sum the positive and negative variances across closed shifts, post one entry that nets them against 7050 and the appropriate cash sub-account, and the variance column starts fresh on the next batch of shifts.

Cash sub-accounts

Cash (1010) is the only top-level account that conventionally has children created at runtime: 1010-001, 1010-002, etc. — one per cashier or drawer. They’re seeded by EnsureCashSubAccounts for users who don’t have one yet, and they’re picked when you open a shift. Every cash leg from that shift posts to that specific sub-account.

The Balance Sheet’s Cash row sums every 1010-* sub-account behind the scenes, so the consolidated number is always correct, even on multi-drawer days. See Open & close a shift and Sales settings — Cash & Drawer.

Custom accounts

You can add your own accounts via POST /api/accounts (or eventually a Settings UI). The shape is the same: code, name, type, optional parent_id. A custom code becomes available to any handler that wants to reference it — but unless you also wire a flow to post to it, it’ll just sit there with a zero balance.

The chart-seed logic (SeedDefaultAccounts) checks whether any accounts exist for the tenant before seeding. If accounts already exist, the seed is a no-op — your custom additions are safe across server restarts and migrations.

Reading on a journal entry

Every JE line carries account_code directly, alongside the resolved account_id. Reports that aggregate by account use the ID; reports that filter by code (or the API caller asking for “show me 1100”) use the code. They stay in sync as long as the chart is seeded — and ResolveOrphanJELineAccountIDs runs on startup to fix any lines that posted before the chart was seeded.