@php($fieldHelp=['timezone'=>'IANA timezone used to assign UTC punches to local workdays.','minimum_minutes'=>'Net minutes required for a full day; shorter complete days show Half day.','half_day_minutes'=>'Days below this threshold carry an additional review flag.','allowed_methods'=>'Choose methods allowed within this scope. Leave unselected to inherit.','allow_reentry'=>'Allow additional in/out sessions after a completed session. Split shifts also allow re-entry.','maximum_session_hours'=>'Limit a recorded session; longer sessions require correction.','early_checkin_minutes'=>'How early employees may check in before scheduled start.','grace_minutes'=>'Ignore this many minutes after scheduled start before marking late.','early_grace_minutes'=>'Ignore this many minutes before scheduled end before marking early.','missing_punch_hours'=>'Elapsed hours before a missing-checkout reminder.','auto_checkout'=>'Cap provisional hours at scheduled end. Keeps checkout missing and requires approval; no punch is invented.','automatic_break_deduction'=>'Deduct the greater of the shift break allowance and actual unpaid breaks, avoiding double deduction.','breaks_required'=>'Flag a completed workday if no break was recorded.','maximum_breaks'=>'Maximum break starts allowed per workday.','overtime_enabled'=>'Calculate excess time separately. Calculation alone never approves pay.','gps_enabled'=>'Collect action-only location when the employee consents. Legacy shift geofences still apply.','geofence_enabled'=>'Validate coordinates against an assigned location radius.','location_required'=>'Require coordinates for each GPS attendance action.','geofence_mode'=>'Strict rejects, warning permits with flags, flexible follows remote policy.','maximum_accuracy'=>'Largest acceptable reported GPS error, in metres.','remote_allowed'=>'Permit remote punches under flexible geofencing.','location_retention_days'=>'Delete encrypted coordinates after this many days; retain original punch and validation outcome.','regularization_days'=>'How many past days employees may submit for correction.','regularization_monthly_limit'=>'Maximum non-withdrawn requests submitted per calendar month.','attachment_required'=>'Require employee-owned supporting evidence that passed scanning.','approval_flow'=>'Manager and HR approvals use different people. Self-approval is never allowed.','delegated_approvers'=>'Tenant user IDs allowed to cover manager review; each needs attendance.approve.','approval_sla_hours'=>'Hours before an open request triggers a deduplicated overdue reminder.','auto_approve_explanations'=>'Accept unchanged late/early explanations only; never change time or payroll automatically.','notify_employee'=>'Send relevant attendance notifications to the employee.','notify_managers'=>'Send relevant attendance notifications to the assigned manager.','notify_hr'=>'Notify authorized HR recipients.','notify_successful_punch'=>'Optionally notify for successful check-in, checkout and break actions.','email_notifications'=>'Additionally queue email through the existing notification engine. SMTP and company delivery opt-in are required.']) @php($groups=['general'=>['General',['timezone','minimum_minutes','half_day_minutes']],'punch'=>['Punch rules',['allowed_methods','allow_reentry','maximum_session_hours','early_checkin_minutes','grace_minutes','early_grace_minutes','missing_punch_hours','auto_checkout']],'break'=>['Break rules',['automatic_break_deduction','breaks_required','maximum_breaks']],'shift'=>['Shift & overtime',['overtime_enabled']],'biometric'=>['Biometric',['allowed_methods']],'gps'=>['GPS & geofencing',['location_mode','location_required','geofence_mode','maximum_accuracy','remote_allowed','location_retention_days']],'regularization'=>['Regularization',['regularization_days','regularization_monthly_limit','attachment_required','approval_flow','delegated_approvers','approval_sla_hours','auto_approve_explanations']],'notifications'=>['Notifications',['notify_employee','notify_managers','notify_hr','notify_successful_punch','email_notifications','notify_late','notify_early','notify_excess_break','notify_geofence','notify_corrections','notify_locks','notify_overtime','notify_devices']],'permissions'=>['Permissions & locks',[]]])

Create an effective policy version

Company defaults apply first, followed by branch, department, shift and employee overrides. Saving appends a version; historical snapshots stay unchanged.

@csrf

Enter values only for rules this version should override. Existing rules remain in force for blank fields.

@foreach($groups as $key=>[$label,$fields])
{{ $label }}
@foreach($fields as $field)@if($key!=='biometric')@if($field==='location_mode')@elseif($field==='timezone')
Leave unselected to keep the inherited timezone.
@else@endif @endif @endforeach @if($key==='gps')

Office boundaries use device coordinates, which can be inaccurate or altered. They support attendance review and do not prove physical presence. Configure offices in Work locations. Street lookup: {{ config('attendance.geocoding.enabled')?'Configured by platform administrator':'Off — private office addresses and offline area names only' }}.

@elseif($key==='biometric')

The reviewed file adapter accepts punch events only. Manage devices and mappings in Biometric devices. Scheduled inbox imports require an explicit server opt-in; endpoint fields do not make network connections.

@elseif($key==='permissions')

attendance.view: register and details · attendance.manage: shifts, rosters and corrections · attendance.approve: independent HR decisions and locks · attendance.devices: device configuration · attendance.settings: policies and locations · attendance.export: downloads and schedules · employees.self: own records and punches. Manage role grants in Admin settings.

@elseif($key==='shift')

Create effective shift versions and rotating assignments in Shift management. Overtime is calculated separately and requires approval. Automatic checkout caps the provisional hours at scheduled end and flags the estimate for approval. Missing checkout stays an exception; original evidence is never fabricated.

@endif
@endforeach

Break type policies

@foreach($breakTypes as $type)
{{ $type['name'] }} · {{ $type['paid']?'Paid':'Unpaid' }} · {{ $type['active']?'Active':'Disabled' }}
@csrf@foreach(['minimum_minutes'=>'Minimum minutes','maximum_minutes'=>'Maximum minutes','maximum_count'=>'Maximum per day','fixed_minutes'=>'Fixed deduction minutes (optional)'] as $field=>$label)@endforeach
@endforeach

Each new break captures its policy. Later policy changes do not rewrite existing break evidence.

Immutable policy history

@forelse($policies as $policy)
#{{ $policy->id }} · {{ $policy->name }} · {{ $policy->scope_type }} #{{ $policy->scope_id }} · {{ $policy->effective_on->toDateString() }}
{{ json_encode($policy->rules,JSON_PRETTY_PRINT) }}
@empty

Default policy is active. No overrides saved.

@endforelse{{ $policies->links() }}
@can('attendance.approve')

Attendance period locks

@csrf
@foreach($locks as $lock)

{{ $lock->period }} · {{ $lock->reopened_at?'Reopened':'Locked' }} · {{ $lock->reason }}

@if(!$lock->reopened_at)
@csrf
@endif
@endforeach{{ $locks->links() }}
@endcan

My scheduled reports

@forelse($schedules as $schedule)
@csrf{{ $schedule->name }} · {{ $schedule->frequency }} · {{ $schedule->enabled?'Enabled':'Paused' }} · last {{ $schedule->last_sent_on??'Not yet sent' }}
@empty

Create a schedule from Attendance reports.

@endforelse{{ $schedules->links() }}

Time & location diagnostics

Company timezone
{{ \App\Domain\Operations\Operations::timezone() }}
Current UTC time
{{ now()->utc()->format('Y-m-d H:i:s') }}
Company local time
{{ now()->timezone(\App\Domain\Operations\Operations::timezone())->format('d M Y g:i:s A') }}
Secure connection
{{ request()->isSecure()?'HTTPS active':'HTTPS required on hosting' }}

Employee attendance uses the effective policy timezone, which may override the company default. Punch timestamps use the host clock. Ask the hosting provider to keep NTP/time synchronization enabled; this page cannot verify synchronization independently. Browser location needs HTTPS and permission. Exact street names depend on location accuracy and address-data coverage.