@can('attendance.export')
Export
@foreach(['csv'=>'CSV','xlsx'=>'Excel','pdf'=>'PDF'] as $format=>$label){{ $label }}@endforeach
@endcan
Columns
@foreach(['present'=>'Present','absent'=>'Absent','late'=>'Late','leave'=>'Leave','weekly_off'=>'Weekly off','minutes'=>'Hours','overtime'=>'Overtime'] as $key=>$label)@endforeach
@include('attendance.filters') @if(isset($presets))
Saved filter presets
@foreach($presets as $preset){{ $preset->name }}@endforeach
@csrf@foreach($filters as $key=>$value)@if(is_scalar($value))@endif @endforeach
@endif @if($filters['view']==='employee' && empty($filters['employee_id']))
Search for an employee or enter their internal ID in More filters to focus this view.
@endif

Attendance register

{{ \Carbon\CarbonImmutable::parse($filters['from'])->format('d M') }} – {{ \Carbon\CarbonImmutable::parse($filters['to'])->format('d M Y') }}
{{ $employees->total() }} employees · click a status for details
@csrf @can('attendance.manage')
0 selectedUp to 500 employee-days. Recalculation resets verification; payroll locks are respected.
@endcan
@if($filters['view']==='employee') @include('attendance.employee-register') @else @can('attendance.manage')@endcan @if($filters['view']==='daily') @else @foreach($dates as $date)@php($day=\Carbon\CarbonImmutable::parse($date))@endforeach @foreach(['present'=>'Present','absent'=>'Absent','late'=>'Late','leave'=>'Leave','weekly_off'=>'WO','minutes'=>'Hours','overtime'=>'OT'] as $key=>$label)@endforeach @endif @forelse($rows as $row) @can('attendance.manage')@endcan @if($filters['view']==='daily') @php($day=reset($row['days'])) @php($m=$day['metrics']) @else @foreach($row['days'] as $date=>$day)@endforeach @foreach(['present','absent','late','leave','weekly_off','minutes','overtime'] as $key)@endforeach @endif @empty@endforelse
EmployeeBranch / departmentShiftScheduledCheck in / outBreakGrossNet hoursLate / earlyOvertimeStatusSource / locationRegularization{{ $day->format('d') }}{{ $day->format('D') }}{{ $label }}Action
{{ mb_substr($row['employee']->first_name,0,1).mb_substr($row['employee']->last_name,0,1) }}{{ $row['employee']->full_name }}{{ $row['employee']->employee_number }} · {{ $row['designation'] }}
{{ $row['branch'] }}{{ $row['department'] }}{{ $day['shift']?->name??'Unassigned' }}{{ $day['shift']?->starts_at }}{{ $day['shift']?->ends_at }}{{ $day['entry']?->clock_in?->timezone($m['timezone']??\App\Domain\Operations\Operations::timezone())->format('H:i')??'—' }}{{ $day['entry']?->clock_out?->timezone($m['timezone']??\App\Domain\Operations\Operations::timezone())->format('H:i')??'—' }}{{ \App\Domain\Operations\AttendanceRegister::hours($m['break_minutes']??0) }}{{ \App\Domain\Operations\AttendanceRegister::hours($m['gross_minutes']??0) }}{{ \App\Domain\Operations\AttendanceRegister::hours($day['minutes']) }}{{ $m['late_minutes']??0 }} / {{ $m['early_minutes']??0 }}m{{ \App\Domain\Operations\AttendanceRegister::hours($day['overtime']) }}{{ $day['code'] }}{{ $day['entry']?->source??'—' }}{{ str_replace('_',' ',$m['geofence_status']??'not_requested') }}{{ $day['request']?->status??'—' }}{{ $day['code'] }}{{ in_array($key,['minutes','overtime'])?\App\Domain\Operations\AttendanceRegister::hours($row['totals'][$key]):$row['totals'][$key] }}View
No employees match these filters.
@endif
@foreach($rows as $row)
{{ mb_substr($row['employee']->first_name,0,1) }}{{ $row['employee']->full_name }}{{ $row['employee']->employee_number }} · {{ $row['designation'] }}
@foreach($row['days'] as $date=>$day){{ substr($date,8,2) }}{{ $day['code'] }}@endforeach
{{ $row['totals']['present'] }} present · {{ $row['totals']['absent'] }} absent{{ \App\Domain\Operations\AttendanceRegister::hours($row['totals']['minutes']) }} hours
@endforeach
@foreach($codes as $code=>$label){{ $code }}{{ $label }}@endforeach

Uncalculated days are not confirmed absences. Hours and status do not authorize overtime payments or deductions. Payroll uses separately verified records.