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

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

{{ $generalsetting->alamat }}
{{ $generalsetting->telepon }}
@if(count($jenis_tunjangan) > 0) @endif @foreach ($jenis_tunjangan as $j) @endforeach @php $total_gaji_pokok = 0; foreach ($jenis_tunjangan as $j) { ${'total_tunjangan_' . $j->kode_jenis_tunjangan} = 0; } $total_bruto = 0; $total_all_denda = 0; $total_jumlah_potongan_jam = 0; $total_gaji_bersih = 0; $total_bpjs_kesehatan = 0; $total_bpjs_tenagakerja = 0; $total_all_potongan = 0; $total_upah_lembur = 0; $total_penambah = 0; $total_pengurang = 0; @endphp @foreach ($laporan_presensi as $d) @php $tanggal_presensi = $periode_dari; // Mapping jadwal untuk NIK ini dari berbagai sumber (sama seperti presensi_cetak) $mapJadwalByDate = $jadwal_bydate[$d['nik']] ?? []; $mapJadwalGrupByDate = $jadwal_grup_bydate[$d['nik']] ?? []; $mapJadwalByDay = $jadwal_byday[$d['nik']] ?? []; @endphp @php $total_tunjangan = 0; @endphp @foreach ($jenis_tunjangan as $j) @php $total_tunjangan += $d[$j->kode_jenis_tunjangan]; ${'total_tunjangan_' . $j->kode_jenis_tunjangan} += $d[$j->kode_jenis_tunjangan]; @endphp @endforeach @php $total_denda = 0; $total_potongan_jam = 0; $total_jam_lembur_aktual = 0; $total_jam_netto_lembur = 0; $total_nominal_lembur_snapshot = 0; $has_lembur_snapshot = false; $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_check = getHari($tanggal_presensi); if (isset($mapJadwalByDate[$tanggal_presensi])) $has_schedule = true; elseif (isset($mapJadwalGrupByDate[$tanggal_presensi])) $has_schedule = true; elseif (isset($mapJadwalByDay[$nama_hari_check])) $has_schedule = true; else { $keyDC = $d['kode_dept'] . '|' . $d['kode_cabang']; $mapD = $jadwal_bydept[$keyDC] ?? []; if (isset($mapD[$nama_hari_check])) $has_schedule = true; } $is_libur = !$has_schedule; } $tipe_hari = $is_libur ? 2 : 1; // 1: Kerja, 2: Libur/Off // Cek apakah data lembur sudah di-snapshot (dikunci) $lembur_key = $d['nik'] . '|' . $tanggal_presensi; $ceklembur_data = $datalembur_indexed[$lembur_key] ?? []; $snapshot_lembur = isset($d[$tanggal_presensi]) && $d[$tanggal_presensi]['jam_lembur_aktual'] !== null; if ($snapshot_lembur) { $has_lembur_snapshot = true; $jml_jam_lembur = $d[$tanggal_presensi]['jam_lembur_aktual']; $jam_netto_harian = $d[$tanggal_presensi]['jam_lembur_netto']; $total_nominal_lembur_snapshot += $d[$tanggal_presensi]['nominal_lembur'] ?? 0; } else { // O(1) indexed lookup instead of linear scan $lembur_aktual = hitungLembur($ceklembur_data); if ($lembur_aktual > 0) { $jml_jam_lembur = $lembur_aktual; $jam_netto_harian = hitungJamNetto($lembur_aktual, $tipe_hari); } else { $jml_jam_lembur = 0; $jam_netto_harian = 0; } } // O(1) libur lookup for display $libur_key = $d['nik'] . '|' . $tanggal_presensi; $ceklibur = $datalibur_indexed[$libur_key] ?? ($datalibur_by_tanggal[$tanggal_presensi] ?? []); @endphp @if (isset($d[$tanggal_presensi])) @if ($d[$tanggal_presensi]['status'] == 'h') @php $bgcolor = ''; $textcolor = ''; $jam_masuk = $tanggal_presensi . ' ' . $d[$tanggal_presensi]['jam_masuk']; $jam_in = !empty($d[$tanggal_presensi]['jam_in']) ? date('H:i', strtotime($d[$tanggal_presensi]['jam_in'])) : '✘'; $jam_out = !empty($d[$tanggal_presensi]['jam_out']) ? date('H:i', strtotime($d[$tanggal_presensi]['jam_out'])) : '✘'; $color_jam_in = !empty($d[$tanggal_presensi]['jam_in']) ? 'green' : 'red'; $color_jam_out = !empty($d[$tanggal_presensi]['jam_out']) ? 'green' : 'red'; $terlambat = hitungjamterlambat($d[$tanggal_presensi]['jam_in'], $jam_masuk); $color_terlambat = $terlambat != null ? $terlambat['color'] : ''; // Jika denda sudah dikunci di database, gunakan nilai tersebut $denda_dari_db = isset($d[$tanggal_presensi]['denda']) && $d[$tanggal_presensi]['denda'] !== null ? $d[$tanggal_presensi]['denda'] : null; if ($denda_dari_db !== null) { // Denda sudah dikunci, gunakan dari DB $denda = $denda_dari_db; // Potongan jam tetap dihitung dengan rumus if ($terlambat != null) { if ($terlambat['desimal_terlambat'] < 1) { $potongan_jam_terlambat = 0; } else { $potongan_jam_terlambat = $terlambat['desimal_terlambat'] > $d[$tanggal_presensi]['total_jam'] ? $d[$tanggal_presensi]['total_jam'] : $terlambat['desimal_terlambat']; } } else { $potongan_jam_terlambat = 0; } } else { // Belum dikunci → gunakan rumus hitungdenda seperti biasa if ($terlambat != null) { if ($terlambat['desimal_terlambat'] < 1) { $potongan_jam_terlambat = 0; $denda = hitungdenda($denda_list, $terlambat['menitterlambat']); } else { $potongan_jam_terlambat = $terlambat['desimal_terlambat'] > $d[$tanggal_presensi]['total_jam'] ? $d[$tanggal_presensi]['total_jam'] : $terlambat['desimal_terlambat']; $denda = 0; } } else { $potongan_jam_terlambat = 0; $denda = 0; } } $pulangcepat = hitungpulangcepat( $tanggal_presensi, $d[$tanggal_presensi]['jam_out'], $d[$tanggal_presensi]['jam_pulang'], $d[$tanggal_presensi]['istirahat'], $d[$tanggal_presensi]['jam_awal_istirahat'], $d[$tanggal_presensi]['jam_akhir_istirahat'], $d[$tanggal_presensi]['lintashari'], ); $pulangcepat = $pulangcepat > $d[$tanggal_presensi]['total_jam'] ? $d[$tanggal_presensi]['total_jam'] : $pulangcepat; $color_pulang_cepat = $pulangcepat != null ? 'red' : ''; $potongan_tidak_absen_masuk_atau_pulang = empty($d[$tanggal_presensi]['jam_out']) || empty($d[$tanggal_presensi]['jam_in']) ? $d[$tanggal_presensi]['total_jam'] : 0; $potongan_istirahat = hitungPotonganIstirahat( $d[$tanggal_presensi]['istirahat_out'], $d[$tanggal_presensi]['istirahat_in'], $d[$tanggal_presensi]['jam_awal_istirahat'], $d[$tanggal_presensi]['jam_akhir_istirahat'] ); $status_potongan_istirahat = $d[$tanggal_presensi]['status_potongan_istirahat'] ?? $generalsetting->potongan_istirahat; $potongan_jam = $potongan_tidak_absen_masuk_atau_pulang == 0 ? $pulangcepat + $potongan_jam_terlambat + ($status_potongan_istirahat == 1 ? $potongan_istirahat : 0) : $potongan_tidak_absen_masuk_atau_pulang; // $ket = // $ket_nama_jam_kerja . // $ket_jadwal_kerja . // $ket_presensi . // $ket_terlambat . // $ket_denda . // $ket_pulang_cepat . // $ket_potongan_jam; @endphp @elseif($d[$tanggal_presensi]['status'] == 'i') @php $bgcolor = '#dea51f'; $textcolor = 'white'; $potongan_jam = $d[$tanggal_presensi]['total_jam']; // Izin: jika denda sudah dikunci, ambil dari DB, jika tidak 0 $denda_dari_db = isset($d[$tanggal_presensi]['denda']) && $d[$tanggal_presensi]['denda'] !== null ? $d[$tanggal_presensi]['denda'] : null; $denda = $denda_dari_db !== null ? $denda_dari_db : 0; @endphp @elseif($d[$tanggal_presensi]['status'] == 's') @php $bgcolor = '#c8075b'; $textcolor = 'white'; // Sakit: jika denda sudah dikunci, ambil dari DB, jika tidak 0 $denda_dari_db = isset($d[$tanggal_presensi]['denda']) && $d[$tanggal_presensi]['denda'] !== null ? $d[$tanggal_presensi]['denda'] : null; $denda = $denda_dari_db !== null ? $denda_dari_db : 0; @endphp @elseif($d[$tanggal_presensi]['status'] == 'c') @php $bgcolor = '#0164b5'; $textcolor = 'white'; // Cuti: jika denda sudah dikunci, ambil dari DB, jika tidak 0 $denda_dari_db = isset($d[$tanggal_presensi]['denda']) && $d[$tanggal_presensi]['denda'] !== null ? $d[$tanggal_presensi]['denda'] : null; $denda = $denda_dari_db !== null ? $denda_dari_db : 0; @endphp @elseif($d[$tanggal_presensi]['status'] == 'a') @php $bgcolor = 'red'; $textcolor = 'white'; $potongan_jam = $d[$tanggal_presensi]['total_jam']; // Alpa: jika denda sudah dikunci, ambil dari DB, jika tidak 0 $denda_dari_db = isset($d[$tanggal_presensi]['denda']) && $d[$tanggal_presensi]['denda'] !== null ? $d[$tanggal_presensi]['denda'] : null; $denda = $denda_dari_db !== null ? $denda_dari_db : 0; @endphp @endif @else @php $bgcolor = 'red'; $textcolor = 'white'; $ket = ''; $potongan_jam = 0; // Jika hari ini libur khusus karyawan, tidak ada potongan jam if (!empty($ceklibur)) { $bgcolor = 'green'; $textcolor = 'white'; $ket = $ceklibur[0]['keterangan']; } else { // Bukan libur → cek jadwal berurutan (sama seperti presensi_cetak): // 1) Jadwal by-date per karyawan $totalJamJadwal = $mapJadwalByDate[$tanggal_presensi] ?? null; // 2) Kalau kosong, cek jadwal grup by-date if ($totalJamJadwal === null) { $totalJamJadwal = $mapJadwalGrupByDate[$tanggal_presensi] ?? null; } // 3) Kalau masih kosong, cek jadwal by-day per karyawan if ($totalJamJadwal === null) { $nama_hari = getHari($tanggal_presensi); $totalJamJadwal = $mapJadwalByDay[$nama_hari] ?? null; } // 4) Kalau masih kosong, cek jadwal by-day per departemen & cabang if ($totalJamJadwal === null) { $nama_hari = isset($nama_hari) ? $nama_hari : getHari($tanggal_presensi); $keyDeptCabang = $d['kode_dept'] . '|' . $d['kode_cabang']; $mapDept = $jadwal_bydept[$keyDeptCabang] ?? []; $totalJamJadwal = $mapDept[$nama_hari] ?? null; } // Jika ada jadwal tapi tidak ada presensi sama sekali → potongan jam = total_jam jadwal $is_future = strtotime($tanggal_presensi) > strtotime(date('Y-m-d')); if ($totalJamJadwal !== null && !$is_future) { $potongan_jam = is_array($totalJamJadwal) ? $totalJamJadwal['total_jam'] : $totalJamJadwal; } } @endphp @endif @php $status_potongan_harian = isset($d[$tanggal_presensi]['status_potongan']) ? $d[$tanggal_presensi]['status_potongan'] : $generalsetting->status_potongan_jam; if ($status_potongan_harian == 0) { $potongan_jam = 0; } $total_denda += $denda; $total_potongan_jam += $potongan_jam; $total_jam_lembur_aktual += $jml_jam_lembur; $total_jam_netto_lembur += $jam_netto_harian; @endphp {{-- --}} @php $tanggal_presensi = date('Y-m-d', strtotime('+1 day', strtotime($tanggal_presensi))); @endphp @endwhile @php if ($total_potongan_jam > $generalsetting->total_jam_bulan) { $total_potongan_jam = $generalsetting->total_jam_bulan; } $jumlah_potongan_jam = ROUND($upah_perjam) * $total_potongan_jam; $total_potongan = ROUND($jumlah_potongan_jam) + $total_denda + $d['bpjs_kesehatan'] + $d['bpjs_tenagakerja'] + ($d['cicilan_pinjaman'] ?? 0); $total_all_potongan += $total_potongan; // Hitung Upah Lembur if ($has_lembur_snapshot) { // Gunakan nominal yang sudah di-snapshot saat kunci laporan $upah_lembur = $total_nominal_lembur_snapshot; } else { // Hitung secara live (belum dikunci) // Gunakan $lemburKhusus yang sudah di-set di awal loop (pre-loaded) if ($lemburKhusus) { $upah_lembur = $lemburKhusus->upah_perjam * $total_jam_lembur_aktual; } else { $upah_perjam_lembur = ($d['gaji_pokok'] + $total_tunjangan) / ($generalsetting->total_jam_bulan ?: 173); $upah_lembur = ROUND($upah_perjam_lembur) * $total_jam_netto_lembur; } } $total_upah_lembur += $upah_lembur; $total_gaji_pokok += $d['gaji_pokok']; $total_bpjs_kesehatan += $d['bpjs_kesehatan']; $total_bpjs_tenagakerja += $d['bpjs_tenagakerja']; $total_penambah += $d['penambah']; $total_pengurang += $d['pengurang']; $total_bruto += $bruto; $total_all_denda += $total_denda; $total_jumlah_potongan_jam += $jumlah_potongan_jam; $gaji_bersih = $d['gaji_pokok'] + $total_tunjangan - $total_potongan + $d['penambah'] - $d['pengurang'] + $upah_lembur; $total_gaji_bersih += $gaji_bersih; @endphp @endforeach @foreach ($jenis_tunjangan as $d) @endforeach
No Nik Nama Karyawan Jabatan Dept Cabang Gaji PokokTunjanganΣ Bruto Σ Jam Kerja Upah/Jam Denda Pot. Jam BPJS Pinjaman Potongan Lembur Penyesuaian Gaji Bersih
{{ $j->jenis_tunjangan }}Jam Jumlah Kesehatan Tenaga Kerja Jam (A|N) Jumlah Penambah Pengurang
{{ $loop->iteration }} '{{ $d['nik_show'] ?? $d['nik'] }} {{ $d['nama_karyawan'] }} {{ $d['nama_jabatan'] }} {{ $d['kode_dept'] }} {{ $d['kode_cabang'] }} {{ formatAngka($d['gaji_pokok']) }}{{ formatAngka($d[$j->kode_jenis_tunjangan]) }} @php $bruto = $d['gaji_pokok'] + $total_tunjangan; @endphp {{ formatAngka($bruto) }} {{ $generalsetting->total_jam_bulan }} @php $upah_perjam = $d['gaji_pokok'] / $generalsetting->total_jam_bulan; @endphp {{ formatAngka($upah_perjam) }} {!! $ket !!} {{ formatAngka($total_denda) }} {{ formatAngkaDesimal($total_potongan_jam) }} {{ formatAngka($jumlah_potongan_jam) }} {{ formatAngka($d['bpjs_kesehatan']) }} {{ formatAngka($d['bpjs_tenagakerja']) }} {{ formatAngka($d['cicilan_pinjaman'] ?? 0) }} {{ formatAngka($total_potongan) }} @if ($lemburKhusus) {{ formatAngkaDesimal($total_jam_lembur_aktual) }} @else {{ formatAngkaDesimal($total_jam_netto_lembur) }} @endif {{ formatAngka($upah_lembur) }} {{ formatAngka($d['penambah']) }} {{ formatAngka($d['pengurang']) }} {{ formatAngka($gaji_bersih) }}
TOTAL {{ formatAngka($total_gaji_pokok) }} {{ formatAngka(${'total_tunjangan_' . $d->kode_jenis_tunjangan}) }}{{ formatAngka($total_bruto) }} {{ formatAngka($total_all_denda) }} {{ formatAngka($total_jumlah_potongan_jam) }} {{ formatAngka($total_bpjs_kesehatan) }} {{ formatAngka($total_bpjs_tenagakerja) }} {{ formatAngka($laporan_presensi->sum('cicilan_pinjaman')) }} {{ formatAngka($total_all_potongan) }} {{ formatAngka($total_upah_lembur) }} {{ formatAngka($total_penambah) }} {{ formatAngka($total_pengurang) }} {{ formatAngka($total_gaji_bersih) }}