Health Screen for Face Kiosk
A configurable health declaration that runs at the attendance kiosk before face capture, blocks entry on flagged answers, and keeps an immutable audit trail of every declaration.
Why this module
Health Screen for Face Kiosk
Blocks before the face match
The declaration runs after the kiosk pairs and before face capture starts. A yes on any deny-flagged question records a denied declaration, logs a kiosk event, and stops the kiosk from advancing, so the person never reaches the face match step for that session.
A snapshot that cannot rot
Each declaration stores the question text and answer as a JSON snapshot captured at submission. Reword or retire a question later and the historical rows are untouched. Declaration views are create-disabled and edit-disabled, and most roles have no write or unlink right.
Yours to keep
LGPL-3 source on disk. No activation key, no phone-home, no recurring licence. Operators write the prose for every question, set deny-on-yes per question, and choose the per-company retention horizon. Free today, free at renewal, because there is no renewal.
Day in the life
A reception tablet screens the morning shift.
The shift arrives at the kiosk. After the tablet pairs, the health screen intercepts the welcome screen and shows the company's active questions. A worker taps No down the list, taps Submit, and the kiosk records an allowed declaration and moves on to face capture. The next worker answers Yes to the unwell question, which is flagged deny-on-yes. The server records the declaration as denied, writes a kiosk event for the audit log, and returns a deny result, so the kiosk shows the entry-not-permitted screen and never starts face capture. With cadence set to once per local day, the first allowed answer is remembered on that device for the rest of the calendar day, so a worker stepping back to the tablet is not asked again. At day end the retention cron deletes declarations older than the company horizon in capped batches.
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 answer row stores the question text at submission time, not a foreign key to the live question. Rewording or deactivating a question afterward never rewrites or corrupts an existing declaration.
The daily retention sweep walks each company at its own horizon, caps the run at a batch limit so a large backlog cannot run unbounded, and reports progress through the cron progress hook for safe resumption.
Questions with no company apply database-wide, while company-set questions stay scoped. Global record rules constrain both questions and declarations to the user's allowed companies.
The questions and submit endpoints authenticate by kiosk device token and are rate limited per token or client IP, returning 429 when over budget and 401 when the token is missing or revoked.
Submit rejects a non-array body, skips malformed entries and unknown question ids, and re-derives the deny decision server-side from each question's own deny-on-yes flag rather than trusting the client.
A question can be recorded for audit without blocking. A yes on a question that is not deny-flagged is stored in the snapshot but still returns allowed, so informational questions do not stop entry.
What is inside
Built to do the job, end to end.
- Health question model. eh.hr.health.question holds yes or no prose, a sequence, a deny-on-yes flag, an active flag, and an optional company. Empty company means the question applies to every company. Four default questions ship seeded inactive for the operator to activate and edit.
- Health declaration model. eh.hr.health.declaration is the read-only audit row: decision allowed or denied, the JSON answer snapshot, the kiosk site and device, a notes field, company, and a computed reference. List, form, and search views are create-disabled and edit-disabled.
- Kiosk endpoints. A questions endpoint returns the active questions and cadence for the device's company, and a submit endpoint takes an array of yes or no answers and returns allowed or denied. Both reuse the kiosk device token and are rate limited.
- Kiosk hook and settings. A JS hook injected into the face kiosk shell shows the declaration before face capture and remembers an allowed result for the day when cadence is once per local day. Company settings expose the enable toggle, cadence, and retention horizon, plus a daily retention cron.
Honest about the edges
What this does not do, so nothing surprises you.
- This is an add-on to the ERP Heritage face attendance kiosk and depends on eh_hr_attendance_base, eh_hr_face_kiosk, and eh_hr_core. It is not a standalone kiosk.
- On a denial the module records a denied declaration, logs a kiosk event, and prevents the kiosk from advancing to face capture. It does not create or post a separate attendance-exception record.
- The kiosk declaration is recorded before face identification, so the live kiosk row is not attributed to a specific employee. The employee link on the audit row is populated only when a declaration is created with an employee through the model.
- Once-per-day cadence in the running kiosk is remembered client-side on the device. A server method to find a prior same-day allowed declaration exists and is tested but is not wired into the live kiosk flow.
- Questions are yes or no only. There is no free-text answer, scoring, conditional branching, temperature capture, or document upload.
- The deny screen instructs the person to speak with a manager. There is no built-in notification, escalation, or approval workflow to a supervisor.
Odoo 16 health screen, attendance kiosk health declaration, COVID screening Odoo, fitness for work questionnaire, deny entry attendance, workplace health screening, kiosk pre-clock-in questions, hr_attendance health check, employee health declaration audit, face kiosk health screen
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