| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Employees (hr) • Attendances (hr_attendance) |
| Community Apps Dependencies | Show |
| Lines of code | 3587 |
| Technical Name |
eh_hr_visitor |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
Visitor Management
One reception tablet, two flows: the kiosk that runs attendance also signs visitors in, with NDA capture, host email, and an audit trail.
Why this module
Visitor Management
No second tablet to buy
Visitor sign-in is served on /eh_hr/visitor/<site_code> from the same kiosk device, paired with the same token the attendance kiosk uses. One reception tablet runs both flows.
The NDA you showed is the NDA on file
The exact NDA prose and photo-consent text shown at the kiosk are copied onto each visitor record at sign-in time, so a later audit reads what the visitor actually accepted rather than today's setting.
The kiosk never dumps your staff list
Host lookup is a throttled typeahead that needs two characters and returns at most ten names scoped to the device's company. The bootstrap call returns purposes and NDA text but never the employee directory.
Day in the life
A contractor and a courier arrive within the same minute
The courier taps Sign in, picks Delivery, types two letters of the host's name, selects them from the short list, and is in; the host gets an arrival email with the visit number. The contractor picks Contractor, which requires both NDA and photo: the site terms appear on screen, the contractor ticks accept, the consent line shows above the camera, they capture a photo, and sign in. Both records store the NDA and consent text exactly as displayed. At 6pm the hourly cron sees the contractor still on site, reads the company timezone, and auto-signs them out with a marker on the record. A year later the daily sweep deletes both rows, photo and NDA snapshot included, because retention lapsed.
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 auto sign-out cron evaluates each company independently against its own configured hour and its own partner timezone, so a 6pm cutoff fires at 6pm local for each company, not once globally in UTC.
Both crons cap work at batch_limit (500) per run and stop early when the budget is exhausted, so a backlog of overstays or expired rows is drained over successive runs rather than in one long transaction.
The daily sweep unlinks signed-out rows past the retention window; the photo binary and the NDA text snapshot are columns on that row, so deleting the row deletes the personal data with it. The privacy promise is executed, not just documented.
If the visit-number sequence has not seeded yet, create() falls back to a timestamp-based number so the very first sign-in still works instead of erroring.
NDA acceptance is enforced at the HTTP endpoint, again in action_sign_in, and once more by a model constraint, so a visit cannot reach signed-in state with an unaccepted required NDA through any path.
The sign-in endpoint rejects a host id that does not belong to the calling device's company, so a token cannot file a visitor against an employee in another company.
Signing in an already-signed-in record is a no-op, and sign-out only acts on records currently signed in, so duplicate kiosk taps do not corrupt timestamps or re-notify the host.
Bootstrap, host search, sign-in, and sign-out are all public routes, each throttled per token or IP through the shared rate-limit service, returning 429 when over budget.
What is inside
Built to do the job, end to end.
- Visitor record. eh.hr.visitor holds name, organisation, contact, host employee, purpose, sign-in and sign-out timestamps, computed duration, state, NDA flags and snapshot, optional photo, notes, kiosk site and device, and a unique visit number. Full chatter and tracking on the key fields.
- Configurable purposes. eh.hr.visitor.purpose is a sortable list (meeting, delivery, contractor, interview seeded) where each purpose carries its own require-NDA and require-photo toggles. Codes are validated URL-safe and unique per company.
- Kiosk shell and endpoints. A public QWeb shell drives a pair, sign-in, NDA, photo, result, and sign-out flow against four JSON endpoints: bootstrap, host_search, sign_in, sign_out. The device pairs with the same token mechanism as the attendance kiosk.
- Host arrival email. A seeded mail.template emails the host with the visitor name, organisation, purpose, visit number, and arrival time. If the host has no work email the module posts a note on the visitor chatter instead of failing silently.
- Two crons and settings. An hourly per-company auto sign-out and a daily retention sweep. Company settings expose the NDA text, photo-consent text, auto-checkout hour, on/off toggle, and retention days, surfaced in res.config.settings.
- Roles and isolation. Read for users and auditors, create and edit for managers, full control for admins, mapped to the attendance suite's groups. Global record rules scope visitors and purposes to the current company.
Honest about the edges
What this does not do, so nothing surprises you.
- Targets Odoo 16 Community and depends on the ERP Heritage attendance base, core, hr, and mail modules; it is not a standalone install and does not run on Enterprise-only stacks.
- Visitor sign-in authenticates the paired device, not the visitor; anyone at a paired kiosk can submit a sign-in, which suits a staffed or supervised reception, not an unattended public entrance.
- Host arrival notification is email only through the standard mail queue. There is no SMS, push, Slack, or Teams notification in this module.
- Photo capture relies on the browser getUserMedia API and a camera-equipped device; there is no badge printing, ID document scan, or barcode badge issuance.
- Sign-out is keyed on the visit number the visitor enters; there is no face match or automatic presence detection for departures.
- Retention deletion is permanent unlink with no archive or export-before-delete step, so set the retention window deliberately and keep external backups if you need long-term visitor history.
Odoo 16 visitor management, visitor sign in kiosk Odoo, front desk visitor log, reception sign in system, NDA capture visitor, contractor sign in Odoo, host notification visitor, visitor management Community, hr attendance visitor kiosk, visitor retention GDPR, self hosted visitor system, digital visitor book Odoo
Please log in to comment on this module