@if ($generalsetting->logo && Storage::exists('public/logo/' . $generalsetting->logo)) Logo Perusahaan @else Logo Default @endif

LAPORAN PRESENSI (FORMAT 2)
{{ $generalsetting->nama_perusahaan }}
PERIODE {{ date('d-m-Y', strtotime($periode_dari)) }} - {{ date('d-m-Y', strtotime($periode_sampai)) }}

{{ $generalsetting->alamat }}
{{ $generalsetting->telepon }}
@php $tanggal_presensi = $periode_dari; @endphp @while (strtotime($tanggal_presensi) <= strtotime($periode_sampai)) @php $tanggal_presensi = date('Y-m-d', strtotime('+1 day', strtotime($tanggal_presensi))); @endphp @endwhile @php $tanggal_presensi = $periode_dari; @endphp @while (strtotime($tanggal_presensi) <= strtotime($periode_sampai)) @php $tanggal_presensi = date('Y-m-d', strtotime('+1 day', strtotime($tanggal_presensi))); @endphp @endwhile @php $tanggal_presensi = $periode_dari; @endphp @while (strtotime($tanggal_presensi) <= strtotime($periode_sampai)) @php $tanggal_presensi = date('Y-m-d', strtotime('+1 day', strtotime($tanggal_presensi))); @endphp @endwhile @foreach ($laporan_presensi as $d) @php $tanggal_presensi = $periode_dari; $mapJadwalByDate = $jadwal_bydate[$d['nik']] ?? []; $mapJadwalGrupByDate = $jadwal_grup_bydate[$d['nik']] ?? []; $mapJadwalByDay = $jadwal_byday[$d['nik']] ?? []; @endphp @php $total_denda = 0; $total_potongan_jam = 0; $total_jam_lembur = 0; $jml_hadir = 0; $jml_sakit = 0; $jml_izin = 0; $jml_cuti = 0; $jml_libur = 0; $jml_alfa = 0; $jml_terlambat = 0; $jml_pulangcepat = 0; $jml_tidakscanmasuk = 0; $jml_tidakscanpulang = 0; $lemburKhusus = $lembur_khusus_map[$d['nik']] ?? null; @endphp @while (strtotime($tanggal_presensi) <= strtotime($periode_sampai)) @php $denda = 0; $potongan_jam = 0; // Optimized: Check libur using pre-loaded data (no DB query) $is_libur_nasional = isset($libur_nasional_dates[$tanggal_presensi]); if ($is_libur_nasional) { $is_libur = true; } else { $has_schedule = false; $nama_hari = getHari($tanggal_presensi); if (isset($mapJadwalByDate[$tanggal_presensi])) $has_schedule = true; elseif (isset($mapJadwalGrupByDate[$tanggal_presensi])) $has_schedule = true; elseif (isset($mapJadwalByDay[$nama_hari])) $has_schedule = true; else { $keyDC = $d['kode_dept'] . '|' . $d['kode_cabang']; $mapD = $jadwal_bydept[$keyDC] ?? []; if (isset($mapD[$nama_hari])) $has_schedule = true; elseif (isset($jadwal_global[$nama_hari])) $has_schedule = true; } $is_libur = !$has_schedule; } // Cek apakah data lembur sudah di-snapshot (dikunci) $lembur_key = $d['nik'] . '|' . $tanggal_presensi; $ceklembur = $datalembur_indexed[$lembur_key] ?? []; $snapshot_lembur = isset($d[$tanggal_presensi]) && $d[$tanggal_presensi]['jam_lembur_aktual'] !== null; if ($snapshot_lembur) { $jam_netto_harian = $d[$tanggal_presensi]['is_lembur_khusus'] ? $d[$tanggal_presensi]['jam_lembur_aktual'] : $d[$tanggal_presensi]['jam_lembur_netto']; } else { // O(1) indexed lookup instead of linear search $lembur_aktual = !empty($ceklembur) ? hitungLembur($ceklembur) : 0; $tipe_hari = $is_libur ? 2 : 1; $jam_netto_harian = $lembur_aktual > 0 ? hitungJamNetto($lembur_aktual, $tipe_hari) : 0; // Jika ada lembur khusus, gunakan JAM AKTUAL (Gross) if ($lemburKhusus) { $jam_netto_harian = $lembur_aktual; } } $nama_hari = getHari($tanggal_presensi); // O(1) libur lookup for display $libur_key = $d['nik'] . '|' . $tanggal_presensi; $ceklibur = $datalibur_indexed[$libur_key] ?? ($datalibur_by_tanggal[$tanggal_presensi] ?? []); $col_data = ['jadwal' => '-', 'in' => '-', 'out' => '-', 'ist_o' => '-', 'ist_i' => '-', 'lbr' => '-', 'pj' => '-', 'dnd' => '-']; $bgcolor = ''; $textcolor = ''; @endphp @if (isset($d[$tanggal_presensi])) @php $row_p = $d[$tanggal_presensi]; @endphp @php $col_data['jadwal'] = $row_p['nama_jam_kerja'] . ' (' . date('H:i', strtotime($row_p['jam_masuk'])) . '-' . date('H:i', strtotime($row_p['jam_pulang'])) . ')'; @endphp @if ($row_p['status'] == 'h') @php $jml_hadir++; $jam_masuk_ref = $tanggal_presensi . ' ' . $row_p['jam_masuk']; $col_data['in'] = !empty($row_p['jam_in']) ? date('H:i', strtotime($row_p['jam_in'])) : 'X'; $col_data['out'] = !empty($row_p['jam_out']) ? date('H:i', strtotime($row_p['jam_out'])) : 'X'; $terlambat = hitungjamterlambat($row_p['jam_in'], $jam_masuk_ref); if ($terlambat && $terlambat['menitterlambat'] > 0) $jml_terlambat++; $denda_db = $row_p['denda'] ?? null; if ($denda_db !== null) { $denda = $denda_db; } else if ($terlambat) { $denda = $terlambat['desimal_terlambat'] < 1 ? hitungdenda($denda_list, $terlambat['menitterlambat']) : 0; } $pc = hitungpulangcepat($tanggal_presensi, $row_p['jam_out'], $row_p['jam_pulang'], $row_p['istirahat'], $row_p['jam_awal_istirahat'], $row_p['jam_akhir_istirahat'], $row_p['lintashari']); if ($pc) $jml_pulangcepat++; $ist_pot = hitungPotonganIstirahat($row_p['istirahat_out'], $row_p['istirahat_in'], $row_p['jam_awal_istirahat'], $row_p['jam_akhir_istirahat']); $no_abs_pot = (empty($row_p['jam_out']) || empty($row_p['jam_in'])) ? $row_p['total_jam'] : 0; $pj_ist_stat = $row_p['status_potongan_istirahat'] ?? $generalsetting->potongan_istirahat; $potongan_jam = $no_abs_pot == 0 ? ($pc + ($terlambat && $terlambat['desimal_terlambat'] >= 1 ? $terlambat['desimal_terlambat'] : 0) + ($pj_ist_stat == 1 ? $ist_pot : 0)) : $no_abs_pot; if (($row_p['status_potongan'] ?? $generalsetting->status_potongan_jam) == 0) $potongan_jam = 0; $col_data['ist_o'] = !empty($row_p['istirahat_out']) ? date('H:i', strtotime($row_p['istirahat_out'])) : '-'; $col_data['ist_i'] = !empty($row_p['istirahat_in']) ? date('H:i', strtotime($row_p['istirahat_in'])) : '-'; $col_data['lbr'] = $jam_netto_harian > 0 ? formatAngkaDesimal($jam_netto_harian) : '-'; $col_data['pj'] = $potongan_jam > 0 ? formatAngkaDesimal($potongan_jam) : '-'; $col_data['dnd'] = $denda > 0 ? formatAngka($denda) : '-'; if (empty($row_p['jam_in'])) $jml_tidakscanmasuk++; if (empty($row_p['jam_out'])) $jml_tidakscanpulang++; @endphp @else @php $status_map = ['i' => ['IZIN', '#dea51f', 'jml_izin'], 's' => ['SAKIT', '#c8075b', 'jml_sakit'], 'c' => ['CUTI', '#0164b5', 'jml_cuti'], 'a' => ['ALPA', 'red', 'jml_alfa']]; $st = $status_map[$row_p['status']]; $bgcolor = $st[1]; $textcolor = 'white'; ${$st[2]}++; $col_data['in'] = $st[0]; if ($row_p['status'] == 'a' || $row_p['status'] == 'i') { $potongan_jam = ($row_p['status_potongan'] ?? $generalsetting->status_potongan_jam) == 1 ? $row_p['total_jam'] : 0; $col_data['pj'] = $potongan_jam > 0 ? formatAngkaDesimal($potongan_jam) : '-'; } $denda = $row_p['denda'] ?? 0; $col_data['dnd'] = $denda > 0 ? formatAngka($denda) : '-'; @endphp @endif @else @php $is_future = strtotime($tanggal_presensi) > strtotime(date('Y-m-d')); if (!empty($ceklibur)) { $bgcolor = 'green'; $textcolor = 'white'; $jml_libur++; $col_data['in'] = 'LIBUR'; } else { $fallback = $mapJadwalByDate[$tanggal_presensi] ?? ($mapJadwalGrupByDate[$tanggal_presensi] ?? ($mapJadwalByDay[$nama_hari] ?? ($jadwal_bydept[$d['kode_dept'].'|'.$d['kode_cabang']][$nama_hari] ?? ($jadwal_global[$nama_hari] ?? null)))); if (is_array($fallback)) { $col_data['jadwal'] = $fallback['nama_jam_kerja'] . ' (' . date('H:i', strtotime($fallback['jam_masuk'])) . '-' . date('H:i', strtotime($fallback['jam_pulang'])) . ')'; $tJam = $fallback['total_jam']; } else { $tJam = null; } if ($tJam !== null && !$is_future) { $jml_alfa++; $bgcolor = 'red'; $textcolor = 'white'; $col_data['in'] = 'ALPA'; $potongan_jam = $generalsetting->status_potongan_jam == 1 ? $tJam : 0; $col_data['pj'] = $potongan_jam > 0 ? formatAngkaDesimal($potongan_jam) : '-'; } } if ($is_libur) { $bgcolor = 'orange'; $textcolor = 'white'; $col_data['in'] = 'LB-K'; } @endphp @endif @php $total_denda += $denda; $total_potongan_jam += $potongan_jam; $total_jam_lembur += $jam_netto_harian; $bgcolor = $is_libur ? 'orange' : $bgcolor; $cell_style = "background-color:$bgcolor; color:$textcolor;"; @endphp @php $tanggal_presensi = date('Y-m-d', strtotime('+1 day', strtotime($tanggal_presensi))); @endphp @endwhile @endforeach
No Nik Nama Karyawan Jabatan Dept Tanggal Denda (T) Pot. Jam (T) Lembur (T) Rekap
{{ getHari(date('Y-m-d', strtotime($tanggal_presensi))) }}Hadir Izin Sakit Alfa Libur Terlambat T.S.M T.S.P P.C
{{ date('d', strtotime($tanggal_presensi)) }}
Jadwal In Out Ist-O Ist-I Lbr PJ Dnd
{{ $loop->iteration }} '{{ $d['nik_show'] ?? $d['nik'] }} {{ $d['nama_karyawan'] }} {{ $d['nama_jabatan'] }} {{ $d['kode_dept'] }}{{ $col_data['jadwal'] }} {{ $col_data['in'] }} {{ $col_data['out'] }} {{ $col_data['ist_o'] }} {{ $col_data['ist_i'] }} @if($col_data['lbr'] != '-') {{ $col_data['lbr'] }} @else {{ $col_data['lbr'] }} @endif {{ $col_data['pj'] }} {{ $col_data['dnd'] }}{{ formatAngka($total_denda) }} {{ formatAngkaDesimal($total_potongan_jam) }} {{ formatAngkaDesimal($total_jam_lembur) }} @if ($lemburKhusus) @endif {{ $jml_hadir }} {{ $jml_izin }} {{ $jml_sakit }} {{ $jml_alfa }} {{ $jml_libur }} {{ $jml_terlambat }} {{ $jml_tidakscanmasuk }} {{ $jml_tidakscanpulang }} {{ $jml_pulangcepat }}