# Attendance workspace

Open **Attendance & roster** in the company sidebar. The monthly register is the default. Use the attendance section navigation for Overview, Live attendance, My attendance, Regularization, Break register, Shifts, Rosters, Devices, Locations, Reports and Settings.

## Everyday use

1. Choose the date range (up to 31 days), branch, department, shift or status. Search by employee name or number. More filters includes legal entity, team, employment type, source, geofence, request state and individual employee/device/location IDs. Filters, sorting and pagination run on the server. Saved presets belong to the signed-in user.
2. Switch between monthly, weekly, daily and employee views. Monthly/weekly registers scroll horizontally while the employee column and header stay visible. Employee view presents one employee's chronological ledger. Phones show compact employee cards with tappable days.
3. Click a day status for the punch timeline, hours, breaks, location outcome, remarks, requests, approval history, correction history and calculation snapshots. Escape closes the drawer; the full-record link supports ordinary navigation.
4. Export the filtered register or a report as CSV, Excel or PDF. Column visibility preferences stay in the browser for that tenant. Exports are bounded to 1,000 employees and 31 days; PDF is bounded to 1,000 rows. Raw biometric/audit reports are bounded to 10,000/5,000 records; use a narrower date range for large populations.
5. Authorized staff use **Add / adjust** for verified manual records or use a regularization request for independent approval. Bulk recalculation creates new calculation revisions and resets attendance verification. Bulk verification accepts complete recorded days only. Neither operation changes sealed payroll.

Status codes: P present, A absent, L late, H half day, LV approved leave, WO weekly off, PH public holiday, OD official duty, WFH work from home, MP missing punch, PR pending regularization, NC not calculated. NC does not mean confirmed absence. Original verified legacy statuses are retained even when a read-only calculation preview reveals additional late/early information.

## Employee self-service

The dashboard now includes **My attendance** quick actions for the signed-in employee: punch in/out and start/end break, following the current session. It requests a fresh browser location only after a punch action, never on page load or in the background. Browser permission and HTTPS (or genuine local loopback) are required for location. GPS evidence is encrypted and retained only under the configured company GPS policy; the dashboard explicitly indicates when GPS capture is off. If permission fails, nothing is submitted silently. A separate **Punch without location** button is available only when the existing company policy permits it; server-side validation remains authoritative. Unlinked accounts are prompted to ask HR to link their employee record.

The role workspace summaries and recent activity panels on the dashboard start collapsed. Expand their colored headings to see tasks, shortcuts and audit updates.

Employees see their own workday, hours, breaks, history, shifts, requests and period summaries. Punch time comes from the server; supplied client timestamps are ignored. Check-in, checkout, break start and break end enforce session order, one active break, method permissions, effective employment, roster, policy and locks. UUID action keys make safe retries idempotent. Multiple work sessions require the re-entry policy or a split shift.

The location button requests a single browser location fix with consent. Coordinates expire in the form after two minutes. No background or continuous location tracking is introduced. GPS is disabled by default unless a pre-existing shift geofence requires it. Hosted location attendance requires HTTPS; genuine loopback HTTP remains supported for local development. Browser GPS is untrusted evidence and does not prove physical presence.

## Effective policies and shifts

Settings are grouped and searchable. A saved policy appends an effective version. Precedence is company, branch, department, shift and employee; a shift's effective template rules apply at the shift level. Blank settings inherit the prior applicable value. Scope IDs must belong to the company. Existing raw events, break snapshots and calculation history are preserved.

Defaults include an eight-hour full-day target, four-hour half-day review threshold, five-minute late/early grace, 24-hour maximum session, two-hour early check-in window, six breaks, seven-day regularization submission window, five requests per calendar month and 48-hour approval reminder SLA. Overtime is recorded separately and never becomes payment or a deduction without approval. Default thresholds are configurable company policy, not jurisdiction-specific legal rules.

Fixed, flexible, overnight and split templates are versioned. Rotating rosters use a cycle of shift IDs and days per rotation step. Bulk assignment is limited to 500 employee-days and rejects existing attendance, conflicting leave and locked dates. Shift swaps require a linked employee in the same branch and department, partner confirmation and independent approval; changed underlying rosters invalidate a stale swap.

Raw events are stored in UTC with their source timezone; calculations assign them to a local workday, support multiple in/out pairs and use actual elapsed time across DST. Paid/unpaid breaks use the policy captured when the break started. Automatic unpaid deduction uses the greater of the shift allowance and actual unpaid breaks, avoiding double deduction. Incomplete/short/excess breaks remain visible as review flags.

Optional automatic checkout caps provisional hours at scheduled shift end and records an **estimate requiring approval**. It leaves the actual checkout missing, preserves the open session and never fabricates a raw punch or approves payroll. Correct the missing checkout through the normal approval workflow.

## Regularization and payroll safety

Requests support missed/incorrect punches, break corrections, late/early explanations, WFH, official duty, device failures and geofence exceptions. Supporting documents must belong to that employee and have passed the existing malware scanner. Evidence uses the existing private encrypted document vault; enabling attendance does not enable OCR.

Depending on the effective policy, manager and/or HR approvals are required. Requesters and swap beneficiaries cannot approve their own request. Manager and final HR approval must be independent. Explicit delegates require the attendance approval permission. Requests can be returned, clarified with revised times/events, resubmitted, rejected or withdrawn. Submission revisions and decisions remain visible.

Approval creates an adjustment overlay and a new calculated version; it never overwrites original raw events. If attendance or payroll is sealed, the approved request is marked **payroll adjustment required** and historical attendance/payroll stays unchanged. Payroll staff can enter a reviewed amount for a later month and generate the existing financial adjustment request. That request requires its own independent payroll approval. Replaying preparation returns the same linked adjustment.

## Devices and secure file imports

The device inventory records manufacturer, model, serial, branch, location, timezone, expected synchronization interval, status and adapter. Map each device user ID to an employee. Imports retain unmatched events; authorized matching appends an immutable link rather than changing the original event. Verified or sealed attendance is retained and flagged for a correction workflow.

The available adapter is **reviewed CSV/Excel file**. Its check action checks adapter capabilities, not a physical network connection. Endpoint/port fields are inventory information. A live ZKTeco/BioTime/other connector has deliberately not been invented: manufacturer, exact model/firmware, API/SDK/protocol, network and licensing documentation must be reviewed before implementing it. No fingerprints, face templates or biometric templates are accepted or stored.

Import header:

```csv
event_id,device_user_id,occurred_at,kind
device-event-001,42,2026-10-17T09:00:00+04:00,in
device-event-002,42,2026-10-17T12:30:00+04:00,break_out
device-event-003,42,2026-10-17T13:00:00+04:00,break_in
device-event-004,42,2026-10-17T18:00:00+04:00,out
```

Use ISO timestamps with an explicit offset or Z. Each file has at most 1,000 events and is at most 2 MB. Excel accepts one worksheet and four columns. The adapter rejects oversized ZIP contents, macros/embeddings, external relationships, DTD/entities and formulas; formulas are never evaluated. Replayed device event IDs must have exactly matching original timestamps, kinds and device user IDs. A conflicting replay rolls the import back and records a safe error. Re-importing unchanged events is harmless.

Optional scheduled private file imports need `ATTENDANCE_SCHEDULED_IMPORTS=true` and files under `storage/app/private/attendance-inbox/TENANT_ID/DEVICE_ID/`. This is an explicit server opt-in; the default remains false. Only the configured private root is read, symlinks/path escapes are rejected, processing is bounded and successfully imported file hashes are skipped. Source files remain for operator review. The existing maintenance cron observes the configured interval; it does not contact vendor endpoints.

## Locations and notifications

Locations support branch/department/employee assignment, effective dates, allowed methods, radius and maximum accuracy. Strict mode rejects invalid/outside fixes; warning mode records flagged exceptions; flexible mode follows the remote-work permission. GPS collection and radius enforcement can be configured separately. With automatic location selection, the nearest applicable location is used. Precise coordinates and location-validation snapshots are encrypted separately and deleted after the retention period (30 days by default); the original timestamp/source and validation outcome remain. Impossible travel is a human-review flag, never a fraud conclusion. Precise evidence is limited to the employee and attendance managers.

The existing notification delivery engine handles bell/email queues, deduplication, retry and logs. Attendance policies choose recipients and event categories. Successful punch notifications and attendance email are off by default. Late/early time, excess breaks, GPS exceptions, corrections, overtime approvals, shift changes, regularization, locks, missing checkout, stale devices and failed imports have relevant notifications. Scheduled reports send a permission-checked filtered report link to the owner's inbox; they do not email an unprotected attachment. Optional email also requires company SMTP activation. Local maintenance continues to pause outbound email.

The existing `zentrik:local-maintenance` cron includes attendance monitoring, request overdue reminders, coordinate retention, scheduled reports and optional inbox imports. `php artisan zentrik:attendance:maintain` runs only attendance maintenance. Do not run a second delivery worker merely for attendance.

## Permissions and upgrades

| Permission | Capability |
| --- | --- |
| attendance.view | Company register, reports and day details |
| attendance.manage | Manual verification/corrections, shifts and rosters |
| attendance.approve | Independent HR decisions and period locks |
| attendance.devices | Devices, mappings, reviewed imports and matching |
| attendance.settings | Policy and work-location configuration |
| attendance.export | Downloads and own report schedules |
| employees.self | Own attendance, punches, requests and swaps |
| manager.approve | Assigned request review, including the affected day |
| payroll.manage / payroll.approve | Prepare / independently decide financial adjustments |

Every query/export is tenant scoped. Branch module disablement is respected. Company-wide selectors are excluded from ESS responses. Team filtering follows the existing organizational model's parent department; this app does not invent separate employee team membership.

For an existing installation, back up first and run:

```sh
php artisan migrate --force
php artisan zentrik:attendance:upgrade
php artisan zentrik:storage:verify
php artisan view:cache
```

The additive migration uses InnoDB for every new table. The upgrade command idempotently appends original legacy punches and initial calculation snapshots without recalculation or changes to existing attendance, rosters, approvals or payroll. New attendance permissions are added to the existing Company Admin/HR roles; custom roles remain explicitly managed. Do not run `migrate:fresh` on existing data. Restart a long-running local maintenance process after an upgrade so it loads the new code.

Hosting remains native Laravel/PHP/MySQL with the existing cron: no Docker, cloud, Redis or Cloudflare is required. CSV/Excel/PDF use PhpSpreadsheet and Dompdf locally on the server. PHP zip/XML/DOM/GD/mbstring support must be available. Tesseract and every tenant OCR switch remain disabled unless separately enabled by an authorized Super Admin.

## GPS capture and approximate place names

Zentrik Demo has a company policy effective **18 October 2026 (Asia/Dubai)** enabling GPS capture and requiring location. Geofence enforcement is off: saving the reported location does not restrict employees to an office boundary. Other clients keep their own policies. Configure a company policy under Attendance → Settings → GPS/location with GPS enabled, location required, strict missing-location handling, and geofence enforcement off for capture-only use. Existing location/geofence policies and role controls still apply. Existing historical entries are not assigned invented coordinates.

Dashboard quick actions and My attendance obtain a fresh browser fix at each punch when GPS capture is enabled. Permission denial or inaccurate/missing GPS prevents a required-location punch. There is no silent fallback. Devices/browsers need location services and permission; public hosting needs HTTPS, while genuine localhost remains supported. Browser GPS can be manipulated and is evidence for review, not proof of presence.

New location evidence stores coordinates, accuracy, an approximate name and its source inside the existing encrypted evidence field, with the same expiration and permission boundaries. Dashboard labels show the signed-in employee's latest unexpired location. Attendance day details show place names only to the same users who may view GPS evidence. Expired labels are hidden with their coordinates.

Naming uses native PHP/Laravel code and bundled **GeoNames CC BY 4.0** data, not a geocoding API. No employee GPS coordinates or identifiers are sent to a third party. Within a configured work site's radius, its saved name/address is used; otherwise a nearby populated-place point within 50 km is labeled “Near …”. This is an approximate area/town/neighbourhood, not an exact street address. Worldwide city/admin-seat coverage is supplemented with UAE neighbourhoods. Outside coverage, GPS is still saved and the name is explicitly unavailable. See [data attribution and coverage](../resources/data/NOTICE.md).

An operator can refresh the public data manually with `python scripts/build-place-data.py`. The generated dataset is bundled in source/cPanel releases, so Python, an API key, a geocoding server and extra runtime configuration are not needed on hosting. Runtime lookup remains offline and adds no database tables or Composer packages. Configured site street addresses can be maintained in Attendance → Locations.
