Initial commit

This commit is contained in:
root
2026-05-26 08:07:45 +00:00
commit a234e55e64
4263 changed files with 855927 additions and 0 deletions
+644
View File
@@ -0,0 +1,644 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Scheduler extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->database();
date_default_timezone_set('Asia/Jakarta');
}
// =====================================================
// PROCESS ATTENDANCE LOG
// =====================================================
public function process_attendance()
{
echo "PROCESS ATTENDANCE START\n";
// =============================================
// GET PENDING LOG
// =============================================
$logs = $this->db
->where('process_status','pending')
->order_by('check_time','ASC')
->limit(1000)
->get('k_attendance_logs')
->result();
foreach($logs as $log){
try{
// =====================================
// GET EMPLOYEE
// =====================================
$employee = $this->db
->where(
'fingerprint_user_id',
$log->user_id
)
->where('is_active',1)
->get('k_employees')
->row();
if(!$employee){
$this->updateLogStatus(
$log->id,
'failed'
);
echo "FAILED EMPLOYEE : {$log->user_id}\n";
continue;
}
// =====================================
// UPDATE EMPLOYEE ID
// =====================================
$this->db
->where('id',$log->id)
->update(
'k_attendance_logs',
[
'employee_id' => $employee->id
]
);
$logDateTime = date(
'Y-m-d H:i:s',
strtotime($log->check_time)
);
// =====================================
// FIND SCHEDULE
// SUPPORT SHIFT MALAM
// =====================================
$this->db->from(
'k_employee_shift_schedules'
);
$this->db->where(
'employee_id',
$employee->id
);
$this->db->where(
'status',
'published'
);
// =====================================
// RANGE SHIFT
// =====================================
$this->db->where("
'{$logDateTime}' BETWEEN
DATE_SUB(start_datetime, INTERVAL 3 HOUR)
AND
DATE_ADD(end_datetime, INTERVAL 6 HOUR)
", null, false);
$this->db->order_by(
'start_datetime',
'DESC'
);
$schedule = $this->db->get()->row();
// =====================================
// SCHEDULE NOT FOUND
// =====================================
if(!$schedule){
$this->updateLogStatus(
$log->id,
'failed'
);
echo "FAILED SCHEDULE : {$logDateTime}\n";
continue;
}
// =====================================
// GET SHIFT
// =====================================
$shift = $this->db
->where('id',$schedule->shift_id)
->get('k_shifts')
->row();
if(!$shift){
$this->updateLogStatus(
$log->id,
'failed'
);
echo "FAILED SHIFT : {$schedule->shift_id}\n";
continue;
}
// =====================================
// ATTENDANCE DATE
// =====================================
$attendance_date = date(
'Y-m-d',
strtotime($schedule->start_datetime)
);
// =====================================
// GET ATTENDANCE
// =====================================
$attendance = $this->db
->where(
'employee_id',
$employee->id
)
->where(
'attendance_date',
$attendance_date
)
->get('k_attendances')
->row();
// =====================================
// CHECK LATE
// =====================================
$late_minutes = 0;
$maxCheckin = strtotime(
$schedule->start_datetime
) + (
$shift->late_tolerance_minutes * 60
);
if(
strtotime($logDateTime)
>
$maxCheckin
){
$late_minutes = floor(
(
strtotime($logDateTime)
-
strtotime($schedule->start_datetime)
) / 60
);
if($late_minutes < 0){
$late_minutes = 0;
}
}
// =====================================
// INSERT CHECKIN
// =====================================
if(!$attendance){
$this->db->insert(
'k_attendances',
[
'employee_id' => $employee->id,
'attendance_date' => $attendance_date,
'checkin_time' => $logDateTime,
'late_minutes' => $late_minutes,
'attendance_status' => (
$late_minutes > 0
? 'late'
: 'present'
),
'shift_id' => $shift->id,
'attendance_log_in_id' => $log->id,
'created_at' => date('Y-m-d H:i:s')
]
);
echo "CHECKIN : {$employee->full_name}\n";
} else {
// =================================
// SUDAH ADA CHECKOUT
// =================================
if(!empty($attendance->checkout_time)){
$this->updateLogStatus(
$log->id,
'processed'
);
echo "SKIP LOG (SUDAH CHECKOUT)\n";
continue;
}
// =================================
// CEK SELISIH JAM
// =================================
$diffMinutes = floor(
(
strtotime($logDateTime)
-
strtotime($attendance->checkin_time)
) / 60
);
// =================================
// MINIMAL 2 JAM
// BARU DIANGGAP CHECKOUT
// =================================
if($diffMinutes < 120){
$this->updateLogStatus(
$log->id,
'processed'
);
echo "SKIP DUPLICATE LOG : {$employee->full_name}\n";
continue;
}
// =================================
// WORK HOURS
// =================================
$workHours = (
strtotime($logDateTime)
-
strtotime($attendance->checkin_time)
) / 3600;
if($workHours < 0){
$workHours = 0;
}
// =================================
// EARLY LEAVE
// =================================
$early_leave_minutes = 0;
if(
strtotime($logDateTime)
<
strtotime($schedule->end_datetime)
){
$early_leave_minutes = floor(
(
strtotime($schedule->end_datetime)
-
strtotime($logDateTime)
) / 60
);
if($early_leave_minutes < 0){
$early_leave_minutes = 0;
}
}
// =================================
// OVERTIME
// =================================
$overtime_hours = 0;
if(
strtotime($logDateTime)
>
strtotime($schedule->end_datetime)
){
$overtime_hours = round(
(
strtotime($logDateTime)
-
strtotime($schedule->end_datetime)
) / 3600,
2
);
if($overtime_hours < 0){
$overtime_hours = 0;
}
}
// =================================
// UPDATE CHECKOUT
// =================================
$this->db
->where(
'id',
$attendance->id
)
->update(
'k_attendances',
[
'checkout_time' => $logDateTime,
'attendance_log_out_id' => $log->id,
'work_hours' => round($workHours,2),
'early_leave_minutes' => $early_leave_minutes,
'overtime_hours' => $overtime_hours
]
);
echo "CHECKOUT : {$employee->full_name}\n";
}
// =====================================
// UPDATE LOG STATUS
// =====================================
$this->updateLogStatus(
$log->id,
'processed'
);
echo "SUCCESS LOG ID : {$log->id}\n";
} catch(Exception $e){
$this->updateLogStatus(
$log->id,
'failed'
);
echo "ERROR : " . $e->getMessage() . "\n";
}
}
echo "PROCESS ATTENDANCE DONE\n";
}
// =====================================================
// AUTO CLOSE ATTENDANCE
// =====================================================
public function auto_close_attendance()
{
echo "AUTO CLOSE START\n";
// =============================================
// AMBIL ATTENDANCE BELUM CHECKOUT
// =============================================
$attendances = $this->db
->where('checkout_time IS NULL', null, false)
->get('k_attendances')
->result();
foreach($attendances as $attendance){
// =========================================
// GET SCHEDULE
// =========================================
$schedule = $this->db
->where(
'employee_id',
$attendance->employee_id
)
->where(
'shift_id',
$attendance->shift_id
)
->where(
'DATE(start_datetime)',
$attendance->attendance_date
)
->get('k_employee_shift_schedules')
->row();
if(!$schedule){
continue;
}
// =========================================
// AUTO CLOSE
// END SHIFT + 4 JAM
// =========================================
$autoCloseTime = date(
'Y-m-d H:i:s',
strtotime(
$schedule->end_datetime . ' +4 hours'
)
);
// =========================================
// BELUM WAKTUNYA
// =========================================
if(
strtotime(date('Y-m-d H:i:s'))
<
strtotime($autoCloseTime)
){
continue;
}
// =========================================
// WORK HOURS
// =========================================
$workHours = (
strtotime($schedule->end_datetime)
-
strtotime($attendance->checkin_time)
) / 3600;
if($workHours < 0){
$workHours = 0;
}
// =========================================
// AUTO CHECKOUT
// =========================================
$this->db
->where('id',$attendance->id)
->update(
'k_attendances',
[
'checkout_time' => $schedule->end_datetime,
'work_hours' => round($workHours,2),
'notes' => 'Auto checkout by system'
]
);
echo "AUTO CLOSE EMPLOYEE : {$attendance->employee_id}\n";
}
echo "AUTO CLOSE DONE\n";
}
// =====================================================
// GENERATE DAILY ATTENDANCE
// =====================================================
public function generate_daily_attendance()
{
echo "GENERATE DAILY START\n";
// =============================================
// GENERATE HARI KEMARIN
// =============================================
$date = date(
'Y-m-d',
strtotime('-1 day')
);
// =============================================
// GET ALL SCHEDULE
// =============================================
$schedules = $this->db
->where('schedule_date', $date)
->where('status','published')
->get('k_employee_shift_schedules')
->result();
foreach($schedules as $schedule){
// =========================================
// CHECK ATTENDANCE EXIST
// =========================================
$attendance = $this->db
->where(
'employee_id',
$schedule->employee_id
)
->where(
'attendance_date',
$date
)
->get('k_attendances')
->row();
if($attendance){
continue;
}
// =========================================
// CHECK HOLIDAY
// =========================================
$holiday = $this->db
->where('holiday_date',$date)
->get('k_holidays')
->row();
if($holiday){
$this->db->insert(
'k_attendances',
[
'employee_id' => $schedule->employee_id,
'attendance_date' => $date,
'attendance_status' => 'holiday',
'is_holiday' => 1,
'shift_id' => $schedule->shift_id,
'notes' => $holiday->holiday_name
]
);
continue;
}
// =========================================
// CHECK LEAVE
// =========================================
$leave = $this->db
->where(
'employee_id',
$schedule->employee_id
)
->where(
'approval_status',
'approved'
)
->where('start_date <=',$date)
->where('end_date >=',$date)
->get('k_leave_requests')
->row();
if($leave){
$this->db->insert(
'k_attendances',
[
'employee_id' => $schedule->employee_id,
'attendance_date' => $date,
'attendance_status' => $leave->leave_type,
'shift_id' => $schedule->shift_id,
'notes' => $leave->reason
]
);
continue;
}
// =========================================
// DEFAULT ALPHA
// =========================================
$this->db->insert(
'k_attendances',
[
'employee_id' => $schedule->employee_id,
'attendance_date' => $date,
'attendance_status' => 'alpha',
'shift_id' => $schedule->shift_id,
'notes' => 'Tidak hadir'
]
);
echo "GENERATE EMPLOYEE : {$schedule->employee_id}\n";
}
echo "GENERATE DAILY DONE\n";
}
// =====================================================
// UPDATE LOG STATUS
// =====================================================
private function updateLogStatus(
$id,
$status
){
$this->db
->where('id',$id)
->update(
'k_attendance_logs',
[
'process_status' => $status
]
);
}
}