EH HR Payroll New Zealand
A ready New Zealand salary structure on the EH payroll engine: PAYE on progressive marginal brackets, ACC earner levy, and KiwiSaver employer contribution.
Why this module
EH HR Payroll New Zealand
PAYE the way IRD does it
The period gross is annualised, taxed slice by slice across the IRD bands at each band's marginal rate, then divided back to the pay period. This is the progressive marginal method, distinct from a flat coefficient. A test asserts the engine reproduces the published IRD figure of NZD 13,220.50 of income tax on 70,000 annual, not a rate the test sets.
Brackets and rates are data
The five IRD bands ship as records on eh.hr.paye.bracket, seeded from the 2025-26 tax year and editable in an admin-only tree view. The ACC levy rate, ACC maximum liable income, and KiwiSaver employer rate are company fields. Inland Revenue and ACC revise these, so the method stays fixed while you update the numbers each tax year.
Salary rules in a sandbox
PAYE, ACC, and KiwiSaver are salary rules in a New Zealand standard structure that call helpers exposed through the engine seam. Rules run in a closed namespace where the payslip and employee are read-only proxies, no raw recordset is reachable from a formula, and each rule can read the running category totals computed before it.
Day in the life
A monthly run, computed correctly
You confirm this year's IRD bands, the ACC rate and cap, and the KiwiSaver rate on the company. An employee on the New Zealand standard structure gets a monthly payslip. The engine infers twelve pay periods from the period span, annualises the gross, taxes it bracket by bracket on the seeded IRD bands, and divides PAYE back to the month. ACC takes its flat percent of liable earnings up to the annual cap, also divided back. KiwiSaver adds the employer contribution as a gross-based employer line. Net is gross minus PAYE and ACC; KiwiSaver sits employer-side and does not reduce take-home.
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.
New Zealand taxes from the first dollar, so the lowest band starts at zero with no exempt amount. The bracket walk begins at a lower bound of zero and the data carries no tax-free slice, matching IRD.
The highest bracket uses a very large upper bound so all income above the last threshold is taxed at the top marginal rate, with no overflow above the table.
The earner levy applies only up to the maximum liable income. The annualised gross is clamped to the cap before the levy is applied, then the result is divided back to the period, so high earners stop accruing ACC above the ceiling.
Pay periods per year are inferred from the period span (52 weekly, 26 fortnightly, 12 monthly), so the same brackets annualise correctly whatever the cadence. Annualise, tax, divide back keeps a weekly and a monthly slip consistent for the same annual income.
The KiwiSaver line is an employer contribution on the employer category, computed on gross. It does not reduce net pay, and net is gross minus the PAYE and ACC deductions only.
PAYE and ACC return zero for a non-positive period gross rather than producing a negative deduction, so a nil or corrected slip does not generate a spurious refund line.
What is inside
Built to do the job, end to end.
- PAYE marginal engine. eh.hr.paye.bracket with compute_annual_paye (slice-by-slice marginal walk) and compute_period_paye (annualise, tax, divide back). Five IRD bands seeded as noupdate data with the published 2025-26 thresholds and rates.
- ACC and KiwiSaver helpers. An acc() helper applies the flat levy to liable earnings capped at the maximum liable income; the KiwiSaver rate feeds an employer-side rule on gross. Both are wired through the engine's _get_rule_helpers seam.
- New Zealand standard structure. A seeded salary structure with BASIC, GROSS, KIWISAVER, PAYE, ACC, and NET rules in sequence, each reading the category totals computed before it.
- Company settings and view. res.company fields for the ACC levy rate, ACC maximum liable income, and KiwiSaver employer rate. An admin-only PAYE Brackets tree view under the payroll menu for editing the bands each tax year.
- Access and tests. Bracket access for HR admin (read, write, create, delete), HR officer (read, write, create), and self-service employee (read). Tests assert PAYE against the published IRD figure and a full PAYE, ACC, KiwiSaver, and net payslip.
Honest about the edges
What this does not do, so nothing surprises you.
- The seeded brackets, ACC rate, ACC cap, and KiwiSaver rate are a template from the 2025-26 figures. You must verify and update them against the current Inland Revenue and ACC published values each tax year before relying on a run.
- The progressive marginal method is fixed in code; it does not implement secondary tax codes, the M or ME tax code thresholds, special tax codes, or tailored tax rates.
- No ESCT on employer KiwiSaver, no employee KiwiSaver deduction, no student loan repayments, and no child support deductions are modelled.
- No IRD payday filing, EI or ED file generation, or any electronic submission to Inland Revenue is included.
- No leave, holiday pay under the Holidays Act, or public holiday calculations are part of this module.
- Payslips read the period basic wage rather than a full employment contract; richer contract handling would come from the engine or a separate module.
- Savepoint isolation, audit field capture, and the rule sandbox are provided by the parent eh_hr_payroll engine, not added by this localization.
NZ payroll Odoo 16, New Zealand payroll Odoo, PAYE Odoo, ACC earner levy Odoo, KiwiSaver Odoo payroll, IRD income tax rates Odoo, New Zealand salary structure, progressive marginal PAYE, Odoo 16 Community payroll localization, eh_hr_payroll New Zealand
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.
Modules teams pair with this one.
Premium ERP Heritage modules that extend the same stack, each built to the same engineering bar.
Inbound webhook receiver for the Employment Hero people and payroll platform on Odoo 16 Community
Real-time fiscalisation of customer invoices and credit notes with the Mauritius Revenue Authority e-Invoicing (E...
The Canada country pack for the ERP Heritage Employment Hero integration
Imports finalised pay run journals from the Employment Hero payroll platform (KeyPay) into Odoo Community account...
Please log in to comment on this module