| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Attendances (hr_attendance)
• Discuss (mail) • Employees (hr) |
| Community Apps Dependencies | Show |
| Lines of code | 3205 |
| Technical Name |
eh_hr_attendance_geofence |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
Mobile Geofence Clock-in
Field and remote staff clock in from their own phone, and the server only accepts the punch when GPS puts them inside one of your work sites.
Why this module
Mobile Geofence Clock-in
The fence is on the server
Distance is computed server-side with the haversine formula against every active geofence-enabled site in the employee company, then compared to each site radius. The phone cannot grant itself an in-fence result; an out-of-range punch is refused and logged, never quietly accepted.
Pair once, opaque token after
A manager issues a six-digit PIN that is one-shot and expires in five minutes. Redeeming it issues a long random token bound to that one employee. The PIN row is claimed atomically, so a race cannot pair the same PIN to two devices, and it is stored in the database so pairing survives a restart and works across workers.
Hours assurance, not anti-fraud
Browser geolocation is reasonably hard to fake on a stock phone but is possible with developer tools or rooted hardware. This module anchors hours and flags out-of-fence attempts; it does not claim tamper-proof location, and it deliberately keeps no face or biometric capture on mobile.
Day in the life
A site supervisor pairs a new labourer and the punches start flowing
The supervisor opens the labourer employee record and clicks Issue mobile pairing PIN. A sticky notification shows a six-digit code valid for five minutes. The labourer opens the mobile page on their phone, types the PIN, and the server binds a device token to them. At the depot gate next morning they tap Clock in; the phone asks for location once, sends the coordinates, and the server measures the distance to each fenced site. They are eleven metres inside the yard, so the punch posts as a check-in and a geofence_pass event lands in the audit trail. That afternoon the same tap from the car park two hundred metres away is refused with you are not inside any of your work sites, a geofence_fail event is logged, and an attendance exception is raised for the manager to review. A field technician flagged as not geofence-required can still clock from a client site; their location is recorded for audit but does not block the punch.
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.
The pairing PIN is claimed atomically and marked used before the token is returned, so a second redeem of the same PIN fails. Issuing a new PIN expires any prior active one, and a daily cron expires lapsed PINs and purges terminal rows older than a day.
Pairing PINs and rate-limit counters live in database rows, not a process dictionary, so they are correct across multiple gunicorn workers and survive a restart. The rate-limit increment is a single atomic SQL upsert with no Python lock.
A punch passes if the phone is inside the radius of any one active geofence-enabled site in the employee company. Each site can carry its own radius; if it does not, the company default radius applies. The closest-site distance is recorded on a miss so a manager can see how far out the attempt was.
When an employee is marked not geofence-required, the clock posts even with no location, and the coordinates are still stored for audit. When it is required and the browser returns no location, the punch is refused with geofence_required rather than posted blind.
Device records carry the employee company and are isolated by record rules: a normal user sees only their own paired devices, a manager sees the company set. Geofence checks only ever consider sites belonging to the employee own company.
The public pair, clock, and whoami routes are throttled per IP or per token in fixed one-minute windows. The pair budget is deliberately tight because a six-digit PIN is otherwise brute-forceable online; over-budget callers get a 429.
Device pairing, every geofence pass and fail, and every check-in and check-out are written to the shared attendance audit trail with IP, user agent, and the site or distance. Out-of-fence attempts also raise a typed attendance exception.
A device token is a long random server-issued string with a uniqueness guard. A manager can rotate the token or revoke the device, after which the old token is rejected and the phone is dropped back to the pairing screen.
What is inside
Built to do the job, end to end.
- Mobile shell and clock endpoints. A vanilla-JavaScript mobile page served at /eh_hr/mobile with large touch targets and a dark mint theme, backed by public pair, clock, and whoami endpoints. No Odoo web framework dependency, so it runs on locked-down corporate browsers and basic Android and iOS WebViews.
- Registered device model. eh.hr.mobile.device stores the opaque token, paired employee, related company, registered-on and last-seen timestamps, last IP, user agent, and last coordinates, with manager actions to rotate the token or revoke the device.
- One-shot pairing PIN model. eh.hr.mobile.pairing issues a six-digit, five-minute, one-shot PIN per employee, with atomic redeem, automatic expiry of prior PINs, and a daily garbage-collection cron.
- Per-employee controls and settings. The employee form gains an Issue mobile pairing PIN button, a paired-device count, a View paired devices action, and a Require mobile geofence toggle. A company setting sets the default mobile geofence radius used when a site declares none.
Honest about the edges
What this does not do, so nothing surprises you.
- Location comes from the device browser geolocation API. It is reasonably hard to fake on a stock phone but can be spoofed with developer tools or rooted hardware, so treat this as hours assurance, not tamper-proof anti-fraud location.
- There is no on-device face match or biometric on mobile. Device pairing is the identity binding; if a phone is shared or handed over, punches are attributed to the paired employee.
- Location is read only at the moment of clock-in and clock-out. There is no background or continuous tracking, and no breadcrumb trail between punches.
- Geofences are circular, defined by a site latitude, longitude, and radius. Arbitrary polygon boundaries are not supported.
- Geofence-enabled work sites are defined in the attendance base module, which this module requires. With no fenced sites configured, a geofence-required employee cannot clock in.
- A formal geolocation consent record is not created automatically by the page. The browser shows its own permission prompt; capturing a stored consent record is a manual manager step on the employee.
Odoo 19 mobile attendance, GPS clock in, geofence attendance, field worker attendance, remote clock in, home based attendance, mobile clock in out, location based attendance, Odoo Community attendance, PIN device pairing, off site time tracking, geofenced check in
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