EH HR Payroll Accounting
Post payslips to the ledger as balanced, reversible entries.
Why this module
EH HR Payroll Accounting
Every entry balances by construction
Each mapped salary rule emits its own debit and credit pair, so the line is balanced before it ever reaches the journal and the whole entry nets to zero. No rule accounts? It falls back to a single net expense and payable pair. The bridge works whether or not your rules are mapped to accounts.
It refuses to post into a closed period
Odoo 19 can quietly shift a move date forward to the next open period and post payroll into the wrong month. This bridge reads the company hard and fiscal-year lock dates directly and refuses instead, leaving the slip retryable once the period reopens. Posting is wrong-in-silence by default; here it is not.
Yours, self-hosted, no subscription
Permissive LGPL-3 on your own server. No per-user fee, no usage cap, and no payroll data leaving your database. One authored source runs on Odoo 16, 17, 18 and 19 Community, with the platform test suite green on every series, so you upgrade on your schedule.
Day in the life
A payroll officer closes the month and the ledger keeps up.
Payslips are computed and confirmed for the period. Because the salary rules carry debit and credit accounts, each slip posts a balanced entry the instant it is confirmed: basic wage debits salary expense and credits net payable, while the tax rule moves its amount from payable to PAYG payable, all in one move. One slip was confirmed before its journal was set, so it posts later on payment instead, no entry lost. A slip dated into a period that finance has already locked refuses to post and stays retryable rather than landing in the wrong month. A correction is needed on one employee, so the slip is cancelled: its entry is reversed first, the reversal points back at the original, and the two net to zero on the ledger. Nothing was re-keyed, nothing posted twice, and the auditor can trace every payroll number back to the slip that produced it.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
A move_id link on the slip is the double-post guard. Once a payslip has posted its entry, the manual button, the auto-post on confirm and the safety-net post on pay are all no-ops. No path can produce a second move for the same slip.
The slip's date is checked against the company hard lock and fiscal-year lock dates before posting. A locked period raises on the manual button, is skipped silently on the automatic path, and posts on retry once the period reopens, instead of being shifted forward and booked into the wrong month.
Each slip posts and reverses inside its own database savepoint. A locked period, a validation error or a genuine database error rolls back only that slip's half-built move and clears its link, so one bad slip never aborts the batch or poisons the transaction for the rest.
If account.move.action_post returns a wizard and leaves the move in draft (an abnormal-amount review step), the bridge does not record move_id against an unposted move. The savepoint rolls the draft back, so the slip stays retryable rather than linking to an entry that never posted.
Cancelling reverses the posted move before the workflow transition runs, so a reversal that fails on a locked period raises before the slip is moved to cancelled. The slip is left fully retryable, and the reversal entry points back at the original so the pair nets to zero.
When no salary rule carries both a debit and a credit account, the entry falls back to a single net expense and payable pair from the slip's fallback accounts. The bridge posts correctly whether your rules are fully mapped, partially mapped, or not mapped at all.
What is inside
Built to do the job, end to end.
- Account mapping on salary rules. Adds a Debit account and Credit account to each EH HR salary rule. Map them to get a per-category entry where each rule contributes its own balanced debit and credit line, so salary expense, net payable and tax payable land on the accounts you choose.
- Journal and fallback accounts on the payslip. Adds a general journal selector plus fallback salary expense and salary payable accounts to the payslip, and read-only links to the posted journal entry and its reversal. The fallback pair is used whenever rules are not mapped to accounts.
- Auto-post on confirm, manual button when needed. Confirming a configured slip creates and posts its balanced entry automatically. A Post to journal button on paid slips covers the case where accounting was configured after confirmation, so a slip is never left without its entry.
- Reversal on cancel. Cancelling a slip reverses its posted entry (or cancels a still-draft one), records the reversal against the slip, and links it back to the original move, so the cancellation reaches the ledger cleanly.
- Stands on the platform engines. No models of its own: it extends the existing payslip and salary rule, and depends only on eh_hr_payroll and Odoo account. Install it alongside the platform or on its own from the Apps menu.
Honest about the edges
What this does not do, so nothing surprises you.
- This is a bridge, not a payroll tax engine. It posts what the salary rules compute; it does not derive PAYG, superannuation or statutory amounts itself. Those live in eh_hr_payroll and its localizations.
- Entries post in the company currency of the slip. There is no foreign-currency payroll retranslation or multi-currency revaluation in this module.
- Posting is one journal entry per payslip. There is no payslip-run roll-up into a single batch entry; a run of slips produces one entry each.
- The fallback path books a single net expense and payable pair. Per-rule splitting into separate expense, tax and deduction accounts requires mapping the debit and credit accounts on the salary rules.
- There is no automated payment reconciliation. The bridge records the salary expense and payable; settling the payable against the bank payment is handled in standard Odoo accounting.
- Journal entries are not analytic-tagged or cost-center split by this module. Add analytic distribution through standard Odoo accounting if you need it.
Odoo Community payroll accounting, payslip journal entry Odoo, salary expense payable posting, payroll to general ledger bridge, balanced double entry payroll, salary rule account mapping debit credit, payslip reversal on cancel, locked period payroll posting, idempotent payroll journal entry, HR payroll account move, post payslip to accounting journal, Odoo 19 Community HR payroll, net salary payable account, payroll expense accrual entry, self-hosted Odoo payroll bridge
Need this fitted to the way you work?
ERP Heritage delivers end to end Odoo work: Odoo Implementation, Customization and Development, Integration, Migration, Consultation, Support and Training. We help teams put this module into production, shape it to their process, and keep it running.
We work with businesses across Australia (Melbourne, Sydney, Brisbane, Perth, Adelaide, Canberra) and the Middle East (Dubai, Abu Dhabi, Riyadh, Jeddah, Doha, Kuwait City, Muscat). Start a conversation at erpheritage.com.au or email info@erpheritage.com.au.
Languages
Available in 19 languages
The interface ships translated out of the box. Switch language in Odoo and the fields, menus, and messages follow.
Please log in to comment on this module