| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Attendances (hr_attendance)
• Discuss (mail) • Employees (hr) |
| Community Apps Dependencies | Show |
| Lines of code | 2415 |
| Technical Name |
eh_hr_attendance_award_au |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
AU Award Engine for Attendance
Splits every shift into ordinary, penalty, and overtime hours against the employee's Modern Award, then writes the rate-weighted result straight back to the attendance row.
Why this module
AU Award Engine for Attendance
An interval engine, not a single rate per shift
A naive engine stamps one rate on a whole shift from the check-in weekday, so a shift that starts Friday 22:00 and ends Saturday 02:00 bills entirely as Friday ordinary. This engine splits the worked interval at every midnight and penalty-band edge, classifies each segment by its own date and clock time, then layers daily overtime, weekly overtime, and casual loading. The split is in the shipped code, not the roadmap.
The awarded numbers land on the attendance row
Ordinary, penalty, overtime tier 1, overtime tier 2, and effective pay hours are stored compute fields on hr.attendance with the right dependencies. Close an attendance, reassign an award, or add a public holiday that touches an existing row and the buckets recompute. The payroll exporter, list views, and reports all read the awarded values with no second pass.
Rates are data on the award, never hard-coded
Every cap, multiplier, penalty band, allowance, casual loading, and minimum engagement lives on the award record and is editable per company. A cited General Retail Industry Award MA000004 baseline ships configured so the engine applies real loadings out of the box. Copy it, edit the multipliers for your workforce, and verify each rate against the current Fair Work determination before payroll.
Day in the life
A retail manager closes a week with a Friday-night shift that runs past midnight.
A casual works Friday 18:00 to Saturday 02:00, then a separate Saturday afternoon period. The engine splits the overnight shift at midnight: the Friday evening hours after 18:00 pick up the weekday evening band, the post-midnight hours are classified as Saturday and take the Saturday penalty, and casual loading is added to every hour on top. Because two separated periods were worked on the Saturday, the day is flagged a broken shift and the broken-shift allowance is paid once, on the day's last period. Earlier ordinary hours in the same work week are summed, so the hours that tip past the 38-hour weekly cap fall into the overtime tiers on this later shift rather than retroactively on the ones already stored. Every result is written to the attendance rows, ready for the payroll exporter.
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 shift spanning midnight is split at 00:00 and each side is classified by its own date. The Friday evening segment keeps the weekday band; the post-midnight segment takes Saturday or public-holiday rates as the calendar dictates, not the check-in weekday.
Hours past the 38-hour weekly cap are tipped into the overtime tiers. The prior week's ordinary hours are keyed by check-in then record id, so the excess lands on the later shift and appending a new shift never retroactively moves overtime onto already-stored rows.
Adding or re-timing one attendance recomputes its siblings in the same work week, because weekly overtime and broken-shift detection are cross-record. The recompute is scoped to that one week, order-independent, and triggered on both create and the relevant writes.
Within any segment, public holiday beats Sunday beats Saturday beats an explicit time-of-day band beats ordinary. A holiday that also falls on a Sunday is paid at the holiday rate, never double-counted.
Two or more periods on one day separated by an unpaid gap of at least an hour flag the day as a broken shift. The flat allowance is paid exactly once, on the day's latest-starting period, so it is never duplicated across the periods worked.
Awards and the public-holiday calendar are isolated by a global per-company record rule, and a holiday with an empty company applies database-wide. The award attribution on each attendance resolves through the employee's company.
When the leave suite is installed, the award reads the canonical eh.hr.public.holiday calendar unioned with any award-local rows, so a holiday entered once is honoured by both leave and award interpretation instead of two unsynced calendars.
The award buckets recompute automatically through stored-compute dependencies, so no periodic sweep runs in the normal flow. A re-flush cron exists only for bulk updates that bypass the ORM (manual SQL, mass import) and ships disabled by default.
An attendance with no check-out, no assigned award, or an inverted or zero-length interval resolves to zero buckets rather than a partial or negative number, so an in-progress punch never pollutes the pay hours.
What is inside
Built to do the job, end to end.
- Interval interpretation engine. A pure-Python engine splits each shift at every midnight and penalty-band edge, classifies each segment by date and clock time, fills the daily ordinary cap, then spills into overtime tier 1 up to a configured cap and tier 2 beyond it. Casual loading is added per hour. Exposed as a static, DB-free function and as a record-bound wrapper, both covered by tests.
- Award and penalty-band configuration. Per-company award records carry daily and weekly ordinary caps, two overtime tiers and multipliers, Saturday, Sunday and public-holiday rates, casual loading percent, minimum engagement, and a broken-shift allowance. Penalty bands add time-of-day loadings by day type. Allowances apply per shift, per hour, or per day, optionally auto-applied. Positivity constraints guard the rate fields.
- Public-holiday calendar with regions. A per-company holiday model covers National plus the eight Australian states and territories, with a uniqueness constraint per date and company and an empty-company option for database-wide holidays. It unions with the canonical leave-suite calendar when present so a date entered once is honoured everywhere.
- Attendance write-back and views. Stored compute fields put ordinary, penalty, both overtime tiers, effective pay hours, the applied award, minimum-engagement top-up, broken-shift flag, and allowance amount on each attendance. List and form views surface them, and a default award can be set per company and overridden per employee.
- Security and seeded baseline. Four access tiers (user, manager, admin, auditor) gate the award, penalty, allowance, and holiday models, with global per-company record rules on the award and holiday calendars. A cited General Retail Industry Award MA000004 baseline and an evening penalty band are seeded on install as a working starting point.
Honest about the edges
What this does not do, so nothing surprises you.
- This is an interpretation and award-split layer over attendance, not a full payroll engine. It computes hours and a rate-weighted effective-hours figure plus allowance amounts; turning those into pay slips and money is the job of a payroll exporter that reads these fields.
- Rates ship as a cited baseline as at a recent determination. Modern Award rates change with each annual Fair Work determination and vary by employment type, so operators must verify every rate against the current determination before running payroll.
- Annualised-salary employees are intentionally left without an award; the engine assumes an hourly basis. Do not assign an award to staff whose pay is not hours-based.
- Penalty bands are configured by clock-time windows and day type. They are applied per segment, but the engine does not ship a pre-loaded national rate table for every Modern Award; you configure the bands for the awards your workforce sits under.
- Requires the eh_hr_attendance_base module and the standard hr_attendance app. Built and tested for Odoo 18 Community.
Odoo 18 Australian award, Modern Award Odoo attendance, Fair Work penalty rates Odoo, casual loading Odoo payroll, weekly overtime attendance, public holiday penalty Odoo, broken shift allowance, minimum engagement award, hr_attendance award interpretation, AU payroll hours Odoo 18, ordinary penalty overtime split, MA000004 retail award 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