Feature · General ledger · Written for ControllerAdvisory demo

The department is in the account number, because there was nowhere else to put it

It starts reasonably. Sales needs to be split by region, so the account code gets a region on the end. Then by product line, so it gets another piece. Then the new office opens and every account that carries a region has to be cloned for it. Nothing is broken, the ledger balances, the reports run, but the chart of accounts is now a filing scheme with three ideas encoded into one string, and reading it means parsing it. The cost is not the length of the list. It is that a new way of looking at the business, one nobody planned for when the coding convention was written, requires either a migration of the chart or another spreadsheet that maps codes to meanings.

The deferred account is verified before anything posts. Nothing hits the ledger until you approve.

01
The capability

What you get with general ledger

One chart of accounts, structured rather than encoded. Accounts, account groups and account tags are first-class objects, installed ready-made from a country localisation rather than typed by hand, the US chart comes seeded, with 232 country localisations available out of the box. The reporting dimensions come off the code and onto the journal line, so one line can carry region and product line and cost centre at once without any of them becoming part of the account number. Splits you make repeatedly become reusable percentage templates by department or location, applied when the entry is written rather than re-derived every month.

Every journal line carries its own currency amount alongside the company's, and the company holds the exchange journal and the FX gain and loss accounts, so a foreign-currency transaction is one entry rather than a manual re-expression. Underneath sits the full tax engine the localisations configure, taxes, tax groups and fiscal positions.

Entries you want posted on a schedule post themselves: a journal entry can be marked for auto-posting up to a date, and the system posts it when the date arrives. And a closed month can be sealed, posted entries are hash-chained, so a period that has been reported on cannot be quietly rewritten afterwards.

Two edges worth stating plainly: the reporting dimensions are tags on the journal line, not segments the ledger balances across, and exchange rates are entered rather than fetched. The FAQ below takes the first of those apart in full.

02
The capability

Where general ledger comes from

Three places, and the difference is worth knowing before you sign anything.

The ledger itself is Odoo Community. The chart of accounts, the reporting dimensions, multi-currency, the tax engine, auto-posting and the audit seal are all built in, no module to add, no tier to reach, no per-seat fee, and the deployment is one you own. NetSuite bills a ledger like this as a module and a per-seat renewal; in Odoo it is already included, and that difference is the product.

Two things sit outside it, and they are not the same kind of outside. Budgets, an object to hold a planned figure so actuals can be compared against it, do not exist in stock Community at all; the module that provides them is account_budget_oca, published free by the Odoo Community Association on the 18.0 branch, and we install it. That one arrives whole: the capability is the module.

Bank statement file import is a narrower thing than that, and worth stating narrowly. The rules engine that matches a statement line against an invoice is already in Community and already yours; what the stock image does not carry is the reader that turns a particular bank's file into statement lines, and account_statement_import_camt, from the Odoo Community Association's bank-statement-import repository on the 18.0 branch, supplies CAMT and generic file import. That module lifts a limit on something the ledger already does, it is not a capability we were missing. And it is file import: a live multi-institution feed is Odoo Enterprise, and Enterprise is licensed per user for the whole system, never per app.

One thing comes from nowhere, and we would rather you heard it here. Multiple books, posting one transaction simultaneously into a primary and a secondary set of books under different accounting standards, with mapped charts and book-specific functional currencies, has no module in either Odoo edition and none from the Community Association. We looked: a journal entry belongs to exactly one company and there is no second book to post it to. The nearest available shape is separate companies with their own charts, reconciled after the fact, which is a different thing and we will say so on the call rather than after the migration. If simultaneous multi-GAAP posting is a requirement rather than a preference, that is a real constraint on this stack.

The account carries the account; the line carries the rest
The account carries the account; the line carries the rest — today versus del.ai on Region, product line, cost centre, A new region and 4 more

The account carries the account; the line carries the rest

FAQ

What is a chart of accounts?

A chart of accounts is the complete list of accounts a business posts to, organised so that every transaction has exactly one place to land. Each account has a code, a name and a type, asset, liability, equity, income or expense, and the type is what tells the system whether a balance belongs on the balance sheet or in the profit and loss. Accounts are usually grouped into ranges by type, so codes beginning 1 are assets, 4 are income, and so on, which makes a reader able to guess what an unfamiliar code is. The chart is a structure decision rather than a data-entry one: it is easy to add an account and hard to change what an existing account means once a year of history has been posted to it, because every comparison to a prior period depends on the account having meant the same thing then. The common failure is to encode extra dimensions, region, department, product, into the account code itself, which works until one of those dimensions changes and every account carrying it has to be cloned or migrated. The alternative is to keep the account list about accounts and carry the other dimensions as attributes on the transaction line.

What does a general journal entry look like?

A general journal entry is a dated record with at least two lines, where the debits equal the credits and each line names one account. It is the raw form of every accounting transaction, and the entries people call journal entries in practice are usually the ones with no source document behind them, accruals, reclassifications, depreciation, corrections, because everything else is generated by an invoice or a payment. A typical accrual for an invoice that has not yet arrived: ``` 31 Jan Professional fees (expense) Dr 4,000 Accrued liabilities Cr 4,000 Legal work performed in January, invoice not yet received ``` Three things make it a valid entry rather than a note. It balances, so the ledger stays in agreement with itself. It carries a date, which decides the period the cost belongs to, and that is the entire point of the accrual, the work happened in January whether or not the paper did. And it carries a narration, because in twelve months the only person who can explain the entry will be whoever wrote the narration. In a real ledger the entry would also carry the dimensions the business reports on, such as which department the legal work was for, on the lines rather than in the account codes. Should a reporting dimension be part of the account code, or a tag on the line? A tag on the line, in almost every case, and the exception is when a regulator or a parent company dictates the code structure. The argument for encoding a dimension into the account number is that it makes every existing report work without change, and that is true on the day it is done. The cost arrives later and compounds: dimensions encoded in a code multiply against each other, so three regions and four product lines and two channels is not nine additions to the chart but twenty-four, and a fourth dimension nobody anticipated cannot be added at all without restructuring the chart and breaking comparison with prior years. A dimension carried as an attribute of the journal line does not multiply, can be added later without touching history, and can be reported in any combination. Oracle argues the encoded case is a problem worth solving too, on NetSuite's own general ledger page: "Eliminate the need to capture operational details for reporting while still supporting unlimited accounts and sub accounts." The distinction to check with any vendor is what their dimension actually is, a tag used for reporting and analysis, or a segment the ledger balances independently, meaning it will refuse an entry that leaves a sub-ledger unbalanced across that dimension. Both are useful and they are not the same guarantee, and the answer decides whether a segment-level trial balance is something the system enforces or something you produce. Can one accounting system keep two sets of books under different accounting standards at the same time? Some can and many cannot, and it is worth establishing which before a migration rather than after. The capability being asked about is a parallel ledger: one transaction posted simultaneously into a primary book and a secondary book that uses a different chart, different recognition rules and possibly a different functional currency, so a group can report under two standards without re-entering anything. NetSuite markets it as multi-book accounting and describes "prebuilt mapping capabilities linking primary and secondary charts of accounts and book-specific functional currencies." Odoo does not have this construct in either edition, and no community module supplies it, an entry belongs to one company and there is no second book dimension to post it to. What exists instead is separate legal entities, each with its own chart, reconciled after the fact, which covers a group reporting under one standard with local statutory filings underneath it but does not cover simultaneous dual-GAAP posting on a single transaction. If dual-GAAP is a hard requirement, it is a genuine constraint and the honest answer is that it needs to be designed around rather than configured.