| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Attendances (hr_attendance)
• Discuss (mail) • Employees (hr) |
| Community Apps Dependencies | Show |
| Lines of code | 2642 |
| Technical Name |
eh_hr_attendance_roster |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
Attendance Roster
Template-driven shift rostering that generates per-employee schedules, then drives planned-versus-actual lateness and overtime from the real shift window.
Why this module
Attendance Roster
Templates become real shifts
A weekly day-of-week pattern (start, end, break) on each employee's default template materialises into concrete dated shifts up to a configurable horizon, default 28 days. The daily cron is timezone-aware per company and idempotent on employee plus start, so a re-run never duplicates a row.
The roster actually drives the numbers
Generated shifts are not inert. The planned window resets the lateness cutoff to the shift start plus grace, and attendance overtime is measured against the rostered hours: minutes beyond the window are daily overtime, ordinary hours over the weekly or fortnightly cap are period overtime.
Yours to keep
LGPL-3 source on disk. No activation key, no phone-home, no recurring licence. A Community Edition team gets a complete roster plus attendance plus exception loop without an Enterprise planning subscription. Read it, extend it, fork it if you need to.
Day in the life
A roster coordinator plans next month and lets the cron do the rest.
Each barista is given a default shift template: Monday to Friday, 9 to 5, thirty-minute break, anchored by day of week. Overnight the generation cron reads every active employee's template and materialises concrete dated shifts up to the 28-day horizon, in each company's own timezone, skipping anything already on the calendar so a second run adds nothing. One Saturday slot has no owner, so it is left open. A staff member opens it and claims it; the system blocks the claim only if they already have a shift starting at that exact moment. When someone needs Friday off, they raise a swap to a colleague; a manager approves it, and the shift is reassigned, unless the colleague already has a clashing start. The next morning, when people check in, the late-detection pass measures each arrival against that person's planned shift start plus the company grace, not a blanket office time, so a rostered late-shift worker is not wrongly flagged. Hours worked beyond the rostered window land as overtime automatically.
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.
Shift generation is idempotent on (employee, start). A database UNIQUE constraint plus a pre-create existence check means re-running the daily cron, or running it twice in a day, never creates a duplicate shift for the same employee and moment.
When the optional AU award module is installed and actually applies to the employee, the roster still links the covering shift but reports zero overtime, deferring entirely to the award so the same attendance is never counted twice. An employee with no award still gets roster-driven overtime, so nothing is lost.
Weekly or fortnightly overtime lands on the shift that actually tips the employee over the ordinary cap. Adding or editing a later attendance recomputes the period siblings, so the excess moves to the correct day instead of being frozen on whichever row was saved first.
Approving a shift swap reassigns the shift only if the target has no shift starting at the same moment. The clash is caught with a clear message before the roster's UNIQUE(employee, start) would otherwise raise a cryptic database error, and a swap to the same employee is rejected outright.
When the roster is installed, its late-detection override owns the whole pass rather than delegating to the base report, so a worker who arrives early for their rostered late shift is not double-flagged against the company-wide default check-in time.
Generation, late detection and overtime windows are all computed in each company's own partner timezone, and global record rules scope shift templates and shifts to company_ids, so a multi-company database keeps rosters cleanly separated.
Each cron run is bounded by a batch limit so a large horizon or a big headcount cannot generate an unbounded number of rows in a single pass, and overnight midnight-spanning shifts (end hour of 24) roll the end into the next day correctly.
What is inside
Built to do the job, end to end.
- Shift templates with weekly patterns. Each template carries a line per active day of week with a start hour, end hour and break minutes. At least one day line is enforced, on the constraint and again on create so an empty template cannot slip through. Templates are tracked on the chatter and scoped per company.
- Per-employee default template and daily generation. Set a default shift template on an employee and the daily cron materialises their concrete dated shifts up to the company horizon (default 28 days), in the company timezone, idempotently. Generation skips inactive employees and inactive templates.
- Scheduled shifts with calendar, list and status. A weekly calendar coloured by employee, plus a list and form with status badges for planned, completed, missed and cancelled. Filters for planned, today, next seven days and open shifts, grouped by employee, status or day.
- Open shifts and self-service claim. A shift with no employee is flagged open and can be claimed by the current user's linked employee from the form. The claim is blocked if the shift is already taken, the user has no employee record, or they already have a shift starting at the same moment.
- Manager-approved shift swaps. An employee asks to hand a scheduled shift to a colleague with a reason. Request, approve and reject move the state; approve is gated to the manager group and reassigns the shift, with a guard against a same-employee target and against a clashing start on the receiving side.
- Roster-driven lateness and overtime. When a planned shift exists, the late cutoff becomes the shift start plus company grace instead of the blanket office time. Attendance overtime is measured against the rostered net window for the day, plus the share of ordinary hours over the weekly or fortnightly ordinary cap (default 38 or 76 hours).
Honest about the edges
What this does not do, so nothing surprises you.
- Rostering is template and cron driven. There is no drag-and-drop visual roster builder; planning is by setting templates and editing the generated calendar, list and form shifts.
- Generation works from each employee's single default shift template. There is no demand forecasting, coverage or skills optimisation, or rotating multi-week pattern engine.
- Shift swaps use a single manager-approval step, not a multi-tier escalation ladder. The approve action is gated to the manager group and guarded against same-employee and clashing-start swaps.
- Roster-driven overtime defers to the AU award only when that separate award module is installed and applies to the employee; on its own the roster computes daily and weekly or fortnightly overtime from the company caps.
- This module extends the ERP Heritage attendance base and reports modules and Odoo hr_attendance; it is not a standalone payroll engine and does not post pay runs.
Odoo 19 Community roster, shift planning Odoo Community, weekly shift template, scheduled shift generation cron, open shift claim, shift swap approval, hr_attendance roster, rostered overtime weekly fortnightly, late check-in detection by shift, planned versus actual attendance, work schedule Odoo, Community Edition planning alternative, multi-company roster, employee default shift template, attendance exception lateness
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