Visitor Management
One reception tablet, two flows. Staff attendance and guest sign-in share the same kiosk, the same device pairing, and one audit trail.
Why this module
Visitor Management
Reuses the kiosk you already run
The reception tablet that runs employee attendance also runs visitor sign-in by browsing a different URL. Same device pairing, same device token, same kiosk site and terminal records. No second iPad, no second subscription, no second vendor holding your guest data in their cloud.
The retention promise is enforced, not written
The NDA text shown is snapshotted onto every record at sign-in, so an audit can prove what was accepted. A daily cron deletes signed-out rows past the company retention window, and the photo and NDA snapshot are deleted with the row. Photo capture is opt-in and shows consent text before the shutter is enabled.
Hosts resolve by typeahead, never bulk-pulled
The kiosk does not download the employee directory. A device token holder can only retrieve the few names a visitor actually types: host search needs two characters, returns at most ten matches scoped to the device company, and every public endpoint is rate limited by an atomic, restart-durable counter.
Day in the life
A contractor arrives at 9am for a site visit
They tap the reception tablet, pick Contractor as the purpose, and start typing their host's name. Two characters in, the typeahead returns the match. Because the Contractor purpose requires it, the NDA text appears and they tick accept, then the camera consent shows and they take a photo. They tap Sign in, get visit number V000142, and the host receives an email naming the visitor, their organisation, and the purpose. At 6pm they have left without signing out, so the end-of-day cron closes the record and marks it auto-signed-out. Twelve months later the retention sweep deletes the row, taking the photo and the NDA snapshot with it.
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 runs hourly and evaluates each company against its own configured cutoff hour in that company's timezone, so a guest still signed in past close is closed and flagged auto_signed_out for audit. Work is batched at 500 per run and reports progress through the cron framework.
A stolen device token cannot bulk-pull the directory or hammer sign-in. Every public endpoint passes through a fixed-window rate limiter whose counter is a single atomic SQL upsert, correct under concurrent workers and durable across restarts, returning HTTP 429 once the per-window budget is spent.
The NDA prose can change in settings over time, so the exact text shown is snapshotted onto each visitor record at sign-in rather than referenced live. A later audit reads what that specific visitor accepted, not today's wording.
Visitor and purpose records carry a company and are filtered by global record rules. Sign-out by visit number, host search, and the auto-checkout and retention crons all scope to the device or record company, so two companies on one database never see each other's guests.
If the visit-number sequence has not seeded yet, create falls back to a timestamp-based number so sign-in still works. If the host has no work email, notification falls back to a chatter post instead of silently failing.
Retention is enforced in code: the daily sweep deletes signed-out rows older than the company retention window, and because the photo and NDA snapshot live on the row, they are removed in the same unlink rather than left orphaned.
What is inside
Built to do the job, end to end.
- Visitor and purpose models. eh.hr.visitor holds name, organisation, contact, host employee, purpose, sign-in and sign-out timestamps, state, NDA flags and snapshot, optional photo, notes, and visit number, with mail.thread tracking. eh.hr.visitor.purpose is a configurable list with per-purpose Require NDA and Require photo toggles and a unique code per company.
- Public kiosk endpoints. A public shell at /eh_hr/visitor/<site_code>, plus bootstrap, host_search, sign_in, and sign_out routes authenticated by the kiosk device token issued through the base module pairing flow. The vanilla-JS shell walks the visitor through form, NDA, photo, and result screens with no Odoo web framework dependency.
- Host notification and audit log. Arrival emails go through a seeded mail.template and the standard mail queue, with a chatter fallback. Every sign-in and sign-out is also written to the suite's kiosk event log with the device, IP, and a reference back to the visitor record.
- Per-company configuration. Settings expose NDA text, photo consent text, auto check-out on or off, the cutoff hour, and retention days, all stored on res.company and editable from the standard Settings page. Four seed purposes (Meeting, Delivery, Contractor, Interview) ship ready to use.
- Roles and isolation. Access lines map to the suite's user, manager, admin, and auditor groups, with read-only user and auditor tiers. Global record rules keep visitor and purpose data scoped per company.
Honest about the edges
What this does not do, so nothing surprises you.
- The kiosk authenticates the device, not the individual visitor. The reception tablet is trusted via its pairing token; the guest signing in is not separately identified or verified.
- There is no pre-registration, invitation, or expected-guest list. Visitors sign in on arrival; the module does not pre-load bookings or send guest invites.
- No badge printing, no SMS, and no watchlist or blocklist screening are included.
- Public sign-out is by visit number only. A visitor who has lost their number needs the receptionist to look them up in the backend; there is no public name-based sign-out.
- Photo capture depends on a browser camera and getUserMedia. On a device without a camera or with camera access denied, the photo step is skipped and sign-in still completes.
- This module requires the ERP Heritage attendance base for its kiosk site, terminal, pairing, event log, and rate-limit infrastructure. It is not a standalone install.
- Evacuation reporting is limited to the live list of signed-in visitors; no dedicated muster or roll-call report is shipped.
Odoo 19 visitor management, visitor sign-in kiosk, front desk visitor log, NDA capture kiosk, contractor sign-in, reception guest check-in, host email notification, visitor management Community, Odoo HR attendance visitor, self-hosted visitor system, visitor photo capture consent, end of day auto sign-out, visitor data retention, kiosk device token, multi-company visitor log
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.
Modules teams pair with this one.
Premium ERP Heritage modules that extend the same stack, each built to the same engineering bar.
Sync Employment Hero ATS recruitment job openings into the standard Odoo Recruitment app, mapping each opening on...
The New Zealand country pack for the ERP Heritage Employment Hero integration
A reusable two way synchronisation engine that keeps Odoo in step with the people and payroll platform, idempoten...
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Employees (hr) • Attendances (hr_attendance) |
| Community Apps Dependencies | Show |
| Lines of code | 3648 |
| Technical Name |
eh_hr_visitor |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
Please log in to comment on this module