Leave the general ledger alone
We’ll start with the thing we refuse to do. We don’t write general ledgers. ERPNext and Odoo already post balanced entries, handle multi-currency, close periods and produce a trial balance that ties. Rewriting any of that is a way to spend a lot of money on a future audit problem.
What does go wrong is everything around the ledger. Someone posts a manual journal to the receivables control account to make a balance look right. Shared rent gets split by gut feel. The branch P&L lives in a spreadsheet that’s rebuilt every month and argued over at every board meeting. Those are the problems a module can fix.
What belongs in a custom accounting module
Three kinds of thing, mostly.
Controls before posting. Rules about who can post what, when a reason is required and which accounts should only ever be touched by source documents like invoices and payments.
Entries drafted by rules. Allocations, recurring accruals and intercompany recharges, generated as drafts from a rule someone can read, then posted by a person.
Reports built for your structure. Branch, department or project P&L from cost centers in ERPNext or analytic accounts in Odoo, laid out the way your board pack wants.
On ERPNext, that becomes a Frappe app with hooks on Journal Entry, a rule DocType, a scheduled job and a Script Report. On Odoo, it’s an addon that guards account.move posting, reads account.analytic.account for distribution and runs allocations on an ir.cron. In both cases the code stays out of core, which is why the approach in our guide to keeping ERPNext customizations through upgrades applies here too.
Worked example: three branches, one rent bill
A group runs three branches from one leased building. Rent is $18,000 a month on a single supplier invoice. The branches occupy 1,000 m², 600 m² and 400 m².
On the first working day of the month, the module drafts a journal entry that moves rent out of the shared cost center: $9,000 to branch one, $5,400 to branch two and $3,600 to branch three. The draft includes the rule name and the floor areas used, in the remark. The finance manager glances at it and submits. If branch two takes an extra 100 m² in March, someone updates the rule once and April’s draft follows.
Separately, a junior accountant tries to post a $7,500 manual journal with no remark. The system asks for a reason. Later they try to credit the trade receivables account directly, which has been marked restricted. That’s blocked, with a message pointing them to a credit note or payment instead. An accounts manager can still post it when there’s a genuine reason, and the entry carries their name.
Notice what the module doesn’t do. It doesn’t decide whether the $7,500 journal is correct. It makes sure there’s a written reason attached, so when the auditor picks it out of a sample in eleven months’ time, the accountant who posted it doesn’t have to reconstruct the story from memory. Controls like this are less about stopping fraud and more about stopping the slow drift of entries that even their authors can’t explain a year later.
The snippet on this page is the journal guard. About 30 lines, and most of it is the error messages.
Controls we’d skip, or do differently
- Blocking backdated entries in custom code. Both platforms have period and lock date features. Use those. A second, homemade lock just confuses people about which one applies.
- Allocations that post automatically. A draft costs a finance manager thirty seconds. An automatic wrong posting costs a reversal, a note and a conversation.
- Approval on every journal entry. If every entry needs approval, approvers stop reading. Put the gate on restricted accounts and large amounts, and trust the rest.
- A parallel tax calculation. If tax is wrong, fix the tax configuration.
Where accounting meets the rest
The ledger is where the rest of your ERP ends up. Clean data from invoice management and expense claims makes month end shorter than any report can. If the control you need depends on how ERPNext is configured rather than on new code, start with our page on ERPNext customization. And if your finance processes are unusual enough that neither platform fits, custom ERP development is the alternative we’d look at.