| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Attendances (hr_attendance)
• Discuss (mail) • Employees (hr) |
| Community Apps Dependencies | Show |
| Lines of code | 4770 |
| Technical Name |
eh_hr_attendance_access_control |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
Door Access Control
When a face match succeeds at the kiosk, the right employee gets the door unlocked and the attempt lands in an audit trail, allowed or denied.
Why this module
Door Access Control
The match is the credential
The kiosk JS wraps the face-match call and, on a success response, fires the access trigger with the matched employee id. The server resolves the device's zone, checks the permission, calls the reader, and the door opens. No badge, no PIN, no second tap.
Per-employee, per-zone, time-boxed
Access is a permission row joining an employee to a zone, with optional valid-from and valid-to dates and an active flag. Outside the window or without a row, the trigger returns denied and still writes the attempt to the audit log. One permission per employee per zone is enforced at the database level.
One protocol, any hardware
The module speaks a single reader protocol: an HTTP POST of an unlock command to a webhook URL you configure. Relay boards, Wiegand readers, MQTT panels, and proprietary controllers sit behind a small bridge service you run that exposes that endpoint, so the Odoo side never ships a hardware driver.
Day in the life
A contractor reaches the side entrance
They look at the kiosk. The face match succeeds, the kiosk shows its usual success screen, and in the background the access trigger fires. The server finds the zone for that site, confirms the contractor has a live permission whose valid-to has not passed, and POSTs an unlock to the door's bridge with an auto-relock interval. The bridge releases the strike, the door opens, and an access event lands with outcome allowed, the reader's response, and the milliseconds it took. A week later their permission lapses; the next match returns denied, the door stays shut, and that denial is logged just as plainly.
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 kiosk at a site with no active zone records a no_zone event and returns cleanly instead of erroring. The match still succeeds for attendance.
If the zone has no active reader, the attempt is logged as no_reader. The permission check is decoupled from hardware reachability.
Network failures and timeouts are caught, the HTTP timeout is configurable per reader, and the attempt is recorded as reader_error with the exception text rather than crashing the request.
A 4xx from the bridge maps to reader_denied; 5xx and network errors map to reader_error. The reader's last status and last response are written back to the reader record for commissioning.
The trigger is fire-and-forget from the browser with keepalive; the audit row is created server-side regardless, so slow door hardware cannot slow the visible attendance flow.
The trigger endpoint requires a valid kiosk device token and is rate limited per token or client IP; missing token returns 401, an unknown or cross-company employee returns 404.
Zones, readers, permissions, and events all carry a company and are filtered by global record rules; zone codes are unique per company and the employee must belong to the device's company.
A daily cron prunes events older than each company's configured retention horizon, default 365 days, in capped batches so a large backlog does not run away in one pass.
What is inside
Built to do the job, end to end.
- Four models, one endpoint, one JS hook. Zone, reader, permission, and access event models; a public POST endpoint at /eh_hr/kiosk/access/trigger; and an asset that wraps the kiosk fetch to fire the trigger on a successful match. The employee form gains an access-permissions list.
- Reader configuration. Each reader holds a webhook URL, an optional bearer token visible only to admins, an auto-relock seconds value passed to the bridge, and a configurable HTTP timeout. A test-unlock button lets you verify the bridge is reachable during commissioning.
- Append-only audit events. Every attempt writes an event with employee, zone, reader, site, device, outcome, the reader's response text, and elapsed milliseconds. The access control lists grant no write rights and reserve delete for admins, so the trail is add-only in practice.
- Roles and retention. User, manager, admin, and auditor roles map onto the four models with sensible read, write, and delete splits. A daily retention sweep honours a per-company retention-days setting and works in bounded batches.
Honest about the edges
What this does not do, so nothing surprises you.
- Ships exactly one reader protocol: an HTTP webhook POST. Relay, Wiegand, MQTT, and proprietary boards require a small bridge service you run that exposes that HTTP endpoint. No hardware driver is included.
- The unlock fires on a successful face match only. This module extends the ERP Heritage face kiosk and depends on it; it is not a standalone badge or card reader.
- One zone per site is acted on: when a site maps to several zones the first match wins, and multi-zone-per-site selection is noted in the code as a future enhancement.
- There is no anti-passback, no occupancy counting, no schedule-based door auto-unlock, and no approval or escalation workflow. Permissions are a simple employee-zone row with an optional date window.
- Audit events are append-only by access rights, not cryptographically sealed; an admin retains delete rights and the retention cron removes aged rows by design.
- Each successful match fires its own trigger; there is no de-duplication or idempotency key, so a door configured with a short auto-relock is the intended way to bound repeated unlocks.
Odoo 16 door access control, Odoo attendance access control, biometric door unlock Odoo, face recognition door access, Wiegand bridge Odoo, relay door unlock webhook, per employee zone permission, access event audit trail, kiosk face match unlock, hr_attendance physical access, vendor neutral access reader, multi company access control 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.
Please log in to comment on this module