diff --git a/application/controllers/Cronjob.php b/application/controllers/Cronjob.php index d162d68..3d1ba37 100644 --- a/application/controllers/Cronjob.php +++ b/application/controllers/Cronjob.php @@ -137,4 +137,220 @@ class Cronjob extends CI_Controller { 'period' => $period ]); } + + // ===================================================== + // CRONJOB UNTUK LIHAT KEHADIRAN SELAMA 1 BULAN + // ===================================================== + + // | Kriteria | Pengurangan | + // | ---------------------- | ------------------: | + // | Alpha | -20 poin / hari | + // | Terlambat | -2 poin / kejadian | + // | Izin (permit) | -1 poin / hari | + // | Akumulasi telat | -1 poin / 60 menit | + // | Akumulasi pulang cepat | -1 poin / 120 menit | + + public function generateMonthlyAttendance() + { + $month = date('Y-m-01'); + + $startDate = date('Y-m-01', strtotime($month)); + $endDate = date('Y-m-t', strtotime($month)); + + $employees = $this->db + ->where('is_active', 1) + ->get('k_employees') + ->result(); + + $processed = 0; + + $this->db->trans_begin(); + + try { + + foreach ($employees as $employee) { + + // Total Hari Kerja + $schedule = $this->db->query(" + SELECT + COUNT(*) AS total_hari_kerja + FROM k_employee_shift_schedules + WHERE employee_id = ? + AND status IN ('published','done') + AND schedule_date BETWEEN ? AND ? + ", array( + $employee->id, + $startDate, + $endDate + ))->row(); + + $total_hari_kerja = (int) $schedule->total_hari_kerja; + + // Rekap Absensi + $attendance = $this->db->query(" + SELECT + + COALESCE(SUM(attendance_status='present'),0) AS total_present, + COALESCE(SUM(attendance_status='late'),0) AS total_late, + COALESCE(SUM(attendance_status='alpha'),0) AS total_alpha, + COALESCE(SUM(attendance_status='sick'),0) AS total_sick, + COALESCE(SUM(attendance_status='permit'),0) AS total_permit, + COALESCE(SUM(attendance_status='annual'),0) AS total_annual, + + COALESCE(SUM(late_minutes),0) AS total_late_minutes, + COALESCE(SUM(early_leave_minutes),0) AS total_early_leave_minutes, + + COALESCE(SUM(work_hours),0) AS total_work_hours, + COALESCE(SUM(overtime_hours),0) AS total_overtime_hours + + FROM k_attendances + WHERE employee_id = ? + AND attendance_date BETWEEN ? AND ? + ", array( + $employee->id, + $startDate, + $endDate + ))->row(); + + $total_present = (int) $attendance->total_present; + $total_late = (int) $attendance->total_late; + $total_alpha = (int) $attendance->total_alpha; + $total_sick = (int) $attendance->total_sick; + $total_permit = (int) $attendance->total_permit; + $total_annual = (int) $attendance->total_annual; + + // Kehadiran + $total_hadir = $total_present + $total_late; + + $attendance_percentage = 0; + + if ($total_hari_kerja > 0) { + $attendance_percentage = round( + ($total_hadir / $total_hari_kerja) * 100, + 2 + ); + } + + // SCOR + $score = 100; + + // Alpha + $score -= ($total_alpha * 20); + + // Telat + $score -= ($total_late * 2); + + // Izin + $score -= ($total_permit * 1); + + // Total menit telat + $score -= floor( + ((int) $attendance->total_late_minutes) / 60 + ); + + // Total menit pulang cepat + $score -= floor( + ((int) $attendance->total_early_leave_minutes) / 120 + ); + + if ($score < 0) { + $score = 0; + } + + // LOGIKA STATUS + if ($score >= 90) { + $status = 'baik sekali'; + } elseif ($score >= 75) { + $status = 'baik'; + } elseif ($score >= 60) { + $status = 'kurang baik'; + } else { + $status = 'buruk'; + } + + // INSERT OR UPDATE TO k_attendance_monthly + $sql = " + INSERT INTO k_attendance_monthly ( + employee_id, month, + total_present, total_late, total_alpha, total_sick, total_permit, total_annual, + total_late_minutes, total_early_leave_minutes, + total_work_hours, total_overtime_hours, + total_hari_kerja, total_hadir, attendance_percentage, + score, status + ) + VALUES ( + ?, ?, + ?, ?, ?, ?, ?, ?, + ?, ?, + ?, ?, + ?, ?, ?, + ?, ? + ) + ON DUPLICATE KEY UPDATE + total_present = VALUES(total_present), + total_late = VALUES(total_late), + total_alpha = VALUES(total_alpha), + total_sick = VALUES(total_sick), + total_permit = VALUES(total_permit), + total_annual = VALUES(total_annual), + total_late_minutes = VALUES(total_late_minutes), + total_early_leave_minutes = VALUES(total_early_leave_minutes), + total_work_hours = VALUES(total_work_hours), + total_overtime_hours = VALUES(total_overtime_hours), + total_hari_kerja = VALUES(total_hari_kerja), + total_hadir = VALUES(total_hadir), + attendance_percentage = VALUES(attendance_percentage), + score = VALUES(score), + status = VALUES(status), + updated_at = CURRENT_TIMESTAMP + "; + + $this->db->query($sql, array( + $employee->id, + $month, + $total_present, + $total_late, + $total_alpha, + $total_sick, + $total_permit, + $total_annual, + (int)$attendance->total_late_minutes, + (int)$attendance->total_early_leave_minutes, + (float)$attendance->total_work_hours, + (float)$attendance->total_overtime_hours, + $total_hari_kerja, + $total_hadir, + $attendance_percentage, + $score, + $status + )); + + $processed++; + } + + if ($this->db->trans_status() === FALSE) { + throw new Exception('Transaction failed'); + } + + $this->db->trans_commit(); + + echo json_encode(array( + 'status' => true, + 'month' => $month, + 'processed' => $processed, + 'message' => 'Monthly attendance generated successfully' + )); + + } catch (Exception $e) { + + $this->db->trans_rollback(); + + echo json_encode(array( + 'status' => false, + 'month' => $month, + 'message' => $e->getMessage() + )); + } + } + } \ No newline at end of file