EH HR Salary Advance
Advances requested, approved, paid and recovered, on a role-gated workflow with a hash-chained audit trail.
Why this module
EH HR Salary Advance
Approval that is enforced, not decorative
Submit, approve, pay, recover and reject are workflow transitions, each gated to a role. An employee submits their own request, a manager approves or rejects, an officer pays and recovers. A transition from the wrong state, or by a user without the right group, is refused in code, not just hidden in the form.
One deduction or a monthly schedule
Set the number of installments and the recovery month, and the schedule splits the advance into equal monthly rows. The final row absorbs any rounding remainder so the lines always sum back to the advance amount. A stored balance shows what is still outstanding, and the advance flips to recovered on its own once every row is ticked paid.
A record you can defend
State, employee, amount, recovery month and installment count are written to an append-only, hash-chained log on every change. Each row carries the sha256 of the one before it, so any after-the-fact edit breaks the chain and is caught on verification. The history is yours, on your own server, with no data leaving your database.
Day in the life
An officer recovers an advance over three pay runs.
An employee submits a 500 advance for an emergency car repair. Their manager approves it, and an HR officer marks it paid. The officer sets three installments starting in the recovery month and generates the schedule: three monthly rows that sum exactly back to 500. Each pay run, the officer ticks that month's installment paid; the running balance falls from 500 to 333.34 to 166.67. When the final row is marked paid, the advance closes itself to recovered with a zero balance. Every transition and amount is on the hash-chained audit log, so the whole advance can be traced end to end.
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.
When an advance is split into installments, each row is rounded to two digits and the final row is computed as the amount less everything already allocated. The schedule therefore always sums back to the exact advance amount, with no stray cent left over or double-counted.
Marking an installment paid re-checks the parent advance. If it is in the paid state and every installment is now recovered, the advance auto-transitions to recovered. A partly paid schedule leaves the advance in paid, so the close only fires when recovery is genuinely complete.
Each workflow move is validated against the current state and the user's groups. A move from the wrong state, or by a user outside the transition's allowed role, raises and is rejected. Approve and reject are manager-only, pay and recover are officer-only, and submit is the employee's own.
A database CHECK constraint forbids a negative amount on both the advance and each installment line. A negative figure is refused at the database level, not merely warned about in the form, so the data cannot be coerced into an invalid state.
The audit log is append-only and hash-chained: each row stores the sha256 of the previous row plus its own fields, and chain appends are serialized by an advisory lock. An edit that does not recompute the entire downstream chain is caught when the chain is verified.
Each advance is numbered from a company-agnostic sequence on create, with a year-prefixed ADV reference, and falls back to a safe default if the sequence is missing. The reference is read-only and not copied, so duplicating a record never reuses a number.
What is inside
Built to do the job, end to end.
- Models this module adds. Two: eh.hr.salary.advance (the request, with amount, reason, recovery month, installment count, recovered total and outstanding balance) and eh.hr.salary.advance.line (one installment row, with due date, amount, paid flag and paid date).
- How it is wired. The advance inherits the workflow, audited and company-aware mixins plus mail threading. Its five states and six transitions are loaded as workflow data, its reference sequence and access rules ship in the module, and the form exposes the status bar, schedule generator and per-row Mark Paid action.
- Built on. eh_hr_core, eh_hr_compat and eh_hr_engine_workflow, plus standard Odoo hr. The state machine, audit log and company scoping come from the shared platform engines, so this module stays small and behaves like every other module beside it.
Honest about the edges
What this does not do, so nothing surprises you.
- This module does not post advances or recoveries to accounting or payroll journals. Marking an installment paid is a manual action that records the recovery on the advance; it does not create a payslip deduction or a journal entry. Posting to journals is a future seam.
- There is no interest, fee or amortization calculation. Installments are equal monthly portions of the principal, with the last row absorbing rounding only. For interest-bearing or fully amortized lending, a dedicated loan module is the right fit.
- The recovery month is a plain date, not a link to a payroll period record, and the schedule is driven by the officer ticking each installment rather than by an automated payroll run.
- Reference numbering is global rather than per company; the sequence is company-agnostic by design, so advances across companies draw from one running series.
- Approval here is a single manager step in the workflow, not a configurable multi-step or amount-threshold approval chain.
salary advance odoo, employee salary advance, payroll advance management, salary advance odoo 16, advance recovery schedule, employee cash advance, salary advance installments, hr advance approval workflow, salary advance repayment, odoo community hr advance, staff advance request, wage advance odoo
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