| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Invoicing (account)
• Employees (hr) • Discuss (mail) |
| Community Apps Dependencies | Show |
| Lines of code | 2319 |
| Technical Name |
eh_hr_payroll_account |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
EH HR Payroll Accounting
Turn confirmed payslips into balanced, posted journal entries, with a per-rule account map and an automatic reversal when a slip is cancelled.
Why this module
EH HR Payroll Accounting
Every entry balances by construction
Each mapped salary rule emits a matched debit and credit for the absolute line total, so each pair is internally balanced and the whole entry nets to zero. When no rule carries accounts, the bridge falls back to a single net expense debit and payable credit. Either way the move balances before it posts.
One bad slip cannot block the run
Each payslip posts inside its own savepoint. A locked period or a move validation error rolls that one slip back and clears its move link so it stays retryable, without aborting the rest of the batch. A move_id guard makes a second posting attempt by any path a no-op.
Install only if you run accounting
The automatic path skips payslips that have no journal or accounts configured, so turning on the bridge never makes confirming a payslip fail. The explicit Post to journal button is the strict path: it raises if the journal or accounts are missing, because the user asked for it.
Day in the life
A payroll officer confirms a pay run and ties it to the ledger.
The salary rules already carry debit and credit accounts, so confirming the run posts one balanced entry per slip straight to the payroll journal: basic wage debits salary expense and credits net payable, the tax deduction debits payable and credits the PAYG liability. Each slip posts inside its own savepoint, so a slip that hits a locked period rolls back alone and stays retryable while the rest of the run posts cleanly. One slip was confirmed before its accounts were set, so it skips silently at confirm and posts later from the Post to journal button. When a correction is needed, cancelling the slip posts a mirror-image reversal that points back at the original entry, so the ledger nets to zero with a clean audit trail.
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.
Each payslip posts within its own database savepoint. A locked period or an account.move validation error rolls that single slip's half-built move back and clears its move_id, leaving it in a clean retryable state, so a batch of confirmations is never aborted by one failing entry.
A move_id link, checked by every posting path before it runs, is the double-post guard. Re-confirming, re-paying, or pressing Post to journal again on a slip that already posted is a no-op: no second move is ever created, as the no-double-post test asserts.
If salary rules carry both a debit and a credit account, the entry is built per rule. If they do not, the bridge falls back to a single net expense debit and payable credit pair, so it produces a balanced move whether or not the rules are mapped to accounts.
Cancelling a slip whose move is already posted books a mirror-image reversal that points back at the original entry, so the cancellation reaches the ledger. A move that was still in draft is simply cancelled instead of reversed.
The automatic path at confirm and pay skips unconfigured slips silently so payroll never breaks. The manual Post to journal button raises a clear error if the journal or the expense and payable accounts are missing, because the user asked for it explicitly.
What is inside
Built to do the job, end to end.
- Per-rule account mapping. Adds a debit account and a credit account to every salary rule, plus an Accounting page on the rule form. When set, the payslip entry is broken out per rule, with one balanced debit and credit line per rule whose total is non-zero.
- Payslip posting fields. Adds a general journal, a fallback salary expense account, a fallback salary payable account, the posted journal entry link, and the reversal entry link to the payslip, all surfaced on the payslip form alongside the net amount.
- Post on confirm, post on pay. Confirming a payslip creates and posts the move, not a draft. Paying acts as a safety net for slips confirmed before accounting was configured. Both paths are idempotent through the move_id guard.
- Manual Post to journal button. A header button, visible on paid slips that have no move yet, posts the entry on demand and raises a clear UserError if the journal or the accounts are not set.
- Test coverage. Ships tests for the balanced net fallback, the per-category breakdown, the journal-required guard, posting on confirm, the reversal on cancel, and the no-double-post guarantee.
Honest about the edges
What this does not do, so nothing surprises you.
- This is a bridge, not a chart of accounts: it posts entries but does not create accounts, journals, or tax mappings for you. You configure those.
- It depends on the EH HR payroll platform and the Odoo account module. It is not a standalone payroll engine and does not compute payslips.
- There is no payment, bank reconciliation, or analytic distribution logic here. It books the salary expense and payable; settling the payable is a separate step.
- Posting is triggered on confirm and pay, despite the legacy summary wording about paying. There is no scheduled or cron-driven posting in this module.
- There is no approval ladder, no multi-company scoping logic, and no advisory locking beyond the per-slip savepoint. Those live elsewhere if you need them.
odoo 16 payroll accounting, payslip journal entry odoo, post payroll to general ledger, salary expense payable journal, hr payroll account bridge, odoo community payroll posting, per rule debit credit account, payroll reversal on cancel, balanced payroll journal entry, erp heritage hr platform
Please log in to comment on this module