worknova.manus/cron/generate_attendance.php
LAPTOP-V9RRD1TL\Michelle's Computer f8f8fcaf96 first commit
2025-07-21 21:38:17 +08:00

994 lines
56 KiB
PHP

<?php
// default config setting
$boolean_ssl_lock = true ;
include '../connect/cms-config.php' ;
include '../requires/function.php' ;
// defualt parameter
$get_type = $_GET['get_type'] ;
$get_date = $_GET['get_date'] ;
$get_staff_id = $_GET['get_staff_id'] ;
$status = '500' ;
$message = 'Failed' ;
if ( $get_type == 'custom' ){
// today is generate selected date report
$date_yesterday = $get_date ;
}else{
// today is generate yesterday report
$date_today = TODAYDATE ;
$date_yesterday = date('Y-m-d', strtotime($date_today . ' -1 day')) ;
}
$current_hour = date('H', time()) ;
$date_next = date('Y-m-d', strtotime($date_yesterday . ' +1 day')) ;
$yesterday_day = date('N', strtotime($date_yesterday)) ;
// check if is holiday
$boolean_holiday = false ;
$holiday_name = '' ;
$holiday_q = $mysqli->query("SELECT holiday_name FROM setting_holiday
WHERE deleted_at IS NULL AND holiday_date = '".$date_yesterday."' LIMIT 1") ;
if ( $holiday_q->num_rows ){
$boolean_holiday = true ;
$holiday = $holiday_q->fetch_assoc() ;
$holiday_name = $holiday['holiday_name'] ;
}
// loop all staff
if ( $get_type == 'custom' ){
$staffs_q = $mysqli->query("SELECT staff_id, staff_idno, staff_name, group_id, country_id, staff_settings, work_type_id FROM staff
WHERE deleted_at IS NULL AND staff_id = '".$get_staff_id."' LIMIT 1") ;
}else{
$staffs_q = $mysqli->query("SELECT staff_id, staff_idno, staff_name, group_id, country_id, staff_settings, work_type_id FROM staff
WHERE deleted_at IS NULL AND ( staff_date_resigned >= '".date("Y-m-d",time())."' OR staff_date_resigned = '0000-00-00' OR staff_date_resigned IS NULL )") ;
}
if ( $staffs_q->num_rows > 0 ){
$status = '210' ;
$message = 'No staff found.' ;
$staffs = [] ;
while ( $row = $staffs_q->fetch_assoc() ){
$staffs[] = $row ;
}
// get all staff deparment
$staff_department = [] ;
$get_department = $mysqli->query("SELECT staff_id, department_id FROM staff_department
WHERE deleted_at IS NULL ORDER BY department_id") ;
if ( $get_department->num_rows > 0 ){
while ( $row_department = $get_department->fetch_assoc() ){
$staff_department[$row_department['staff_id']][] = $row_department['department_id'] ;
}
}
// cut off attendance report
foreach ( $staffs as $key => $staff ){
$status = '201' ;
$message = 'Attendance list report was generated already.' ;
$staff_id = $staff['staff_id'] ;
$list_type = 'normal' ;
$list_type_remark = 'WD' ;
$list_remark = '' ;
$list_work_day = '0' ;
$list_ot_day = '0' ;
$list_work = '00:00:00' ;
$list_rest = '00:00:00' ;
$list_rest_more = '00:00:00' ;
$list_time_off = '00:00:00' ;
$list_rest2 = '00:00:00' ;
$list_rest_more2 = '00:00:00' ;
$list_time_off2 = '00:00:00' ;
$list_early = '00:00:00' ;
$list_early_out = '00:00:00' ;
$list_late = '00:00:00' ;
$list_ot_normal = '00:00:00' ;
$list_leave_day = 0 ;
$wrong_punch = [] ;
$array_abnormal = [] ;
// staff setting
$staff_settings = $staff['staff_settings'] ;
if ( $staff_settings != '' ){
$staff_settings = JsonEncodeDecode('decode', $staff_settings) ;
}else{
$staff_settings = [] ;
}
// check if not exists
$attendance_list_q = $mysqli->query("SELECT list_id FROM staff_attendance_list
WHERE deleted_at IS NULL AND staff_id = '".$staff_id."' AND list_date = '".$date_yesterday."' LIMIT 1") ;
if ( $attendance_list_q->num_rows == 0 ){
$status = '209' ;
$message = 'Selected staff no setting working hours.' ;
// check staff working time, if not exists create
$boolean_setting_working = false ;
$working_q = $mysqli->query("SELECT working_id, working_on, working_next_day, working_if_flexi, working_if_include_rest, working_if_ot, working_direct_day, working_if_fixed_work, working_day_calculation, working_period_from, working_period_to, working_period_before, working_from, working_to, working_to_include_ot, working_total_hours, working_total_rest_hours, working_rest_range_from, working_rest_range_to, working_rest_include_ot, working_rounding_ot, working_if_ot_morning, working_if_offduty, working_count_offduty, working_if_deduct_offduty, working_max_ot,working_total_rest_hours2,working_rest_range_from2,working_rest_range_to2 FROM staff_attendance_working
WHERE deleted_at IS NULL AND staff_id = '".$staff_id."' AND working_date = '".$date_yesterday."' LIMIT 1") ;
if ( $working_q->num_rows == 0 ){
// get staff working hours
$working_q2 = $mysqli->query("SELECT group_id, working_on, working_next_day, working_if_flexi, working_if_include_rest, working_if_ot, working_direct_day, working_if_fixed_work, working_day_calculation, working_morning_start as working_period_from, working_morning_end as working_period_to, working_period_before, working_break_start as working_from, working_break_end as working_to, working_break_end_include_ot as working_to_include_ot, working_total_hours, working_total_rest_hours, working_rest_range_from, working_rest_range_to, working_rest_include_ot, working_rounding_ot, working_if_ot_morning, working_if_offduty, working_count_offduty, working_if_deduct_offduty, working_max_ot,working_total_rest_hours2,working_rest_range_from2,working_rest_range_to2 FROM setting_working
WHERE deleted_at IS NULL AND group_id = '".$staff['group_id']."' AND working_day = '".$yesterday_day."' LIMIT 1") ;
// check if working setting got set
if ( $working_q2->num_rows > 0 ){
$boolean_setting_working = true ;
$working = $working_q2->fetch_assoc() ;
$mysqli->query("INSERT INTO staff_attendance_working
(staff_id, working_group_id, working_date, working_on, working_next_day, working_if_flexi, working_if_include_rest, working_if_ot, working_direct_day, working_if_fixed_work, working_day_calculation, working_period_from, working_period_to, working_period_before, working_from, working_to, working_to_include_ot, working_total_hours, working_total_rest_hours, working_rest_range_from, working_rest_range_to, working_rest_include_ot, working_rounding_ot, working_if_ot_morning, working_if_offduty, working_count_offduty, working_if_deduct_offduty, working_max_ot, created_at, updated_at,working_total_rest_hours2,working_rest_range_from2,working_rest_range_to2) VALUES
('".$staff_id."', '".$working['group_id']."', '".$date_yesterday."', '".$working['working_on']."', '".$working['working_next_day']."', '".$working['working_if_flexi']."', '".$working['working_if_include_rest']."', '".$working['working_if_ot']."', '".$working['working_direct_day']."', '".$working['working_if_fixed_work']."', '".$working['working_day_calculation']."', '".$working['working_period_from']."', '".$working['working_period_to']."', '".$working['working_period_before']."', '".$working['working_from']."', '".$working['working_to']."', '".$working['working_to_include_ot']."', '".$working['working_total_hours']."', '".$working['working_total_rest_hours']."', ".( $working['working_rest_range_from'] != '' ? "'".$working['working_rest_range_from']."'" : "NULL" ).", ".( $working['working_rest_range_to'] != '' ? "'".$working['working_rest_range_to']."'" : "NULL" ).", ".( $working['working_rest_include_ot'] != '' ? "'".$working['working_rest_include_ot']."'" : "NULL" ).", '".$working['working_rounding_ot']."', '".$working['working_if_ot_morning']."', '".$working['working_if_offduty']."', '".$working['working_count_offduty']."', '".$working['working_if_deduct_offduty']."', '".$working['working_max_ot']."', '".TODAYDATE."', '".TODAYDATE."','".$working['working_total_rest_hours2']."',".($working['working_rest_range_from2'] !='' ? "'".$working['working_rest_range_from2']."'" : "NULL" ).",".($working['working_rest_range_to2'] != '' ? "'".$working['working_rest_range_to2']."'": "NULL" ).")") ;
}
}else{
$boolean_setting_working = true ;
$working = $working_q->fetch_assoc() ;
}
if ( $boolean_setting_working ){
$status = '208' ;
$message = 'Selected staff cannot generate attendance report currently.' ;
// default parameter
$total_hours = $working['working_total_hours'] ;
$total_rest_hours = $working['working_total_rest_hours'] ;
$total_rest_hours2 = $working['working_total_rest_hours2'] ;
$boolean_rest_hours2 = ( $total_rest_hours2 != '' && $total_rest_hours2 != '00:00:00' ? 'yes' : 'no' ) ;
$array_atten_ls = [] ;
$array_atten = [] ;
$punchiscorrect = true ;
// check if allow to insert attendances
$check_current_datetime = $date_yesterday.' '.$working['working_period_from'] ;
$check_next_datetime = $date_next.' '.$working['working_period_to'] ;
if ( $working['working_to_include_ot'] > 0 ){
$check_next_datetime = date( 'Y-m-d H:i:s', strtotime('-'.$working['working_to_include_ot'].' hour', strtotime($check_next_datetime)) ) ;
}
// set running schedule time + 1 hours
$check_running_datetime = date( 'Y-m-d H:i:s', strtotime('+1 hour', strtotime($check_next_datetime)) ) ;
$after_rest1 = date( 'Y-m-d', strtotime( $check_current_datetime ) ) . ' ' . $working['working_rest_range_from'] ;
$after_rest2 = date( 'Y-m-d', strtotime( $check_current_datetime ) ) . ' ' . $working['working_rest_range_to'] ;
if ( TODAYDATE > $check_running_datetime ){
// check if today got apply leave
$check_leave_q = $mysqli->query("SELECT a.leave_type, a.leave_work_day, b.leave_reason FROM staff_leave_date a
LEFT JOIN staff_leave b ON ( a.leave_id = b.leave_id )
WHERE a.deleted_at IS NULL AND a.staff_id = '".$staff_id."' AND a.leave_date = '".$date_yesterday."' AND b.deleted_at IS NULL AND b.leave_status = 'confirmed' LIMIT 1") ;
if ( $check_leave_q->num_rows > 0 ){
$check_leave = $check_leave_q->fetch_assoc() ;
$list_type = 'leave' ;
$list_remark = $check_leave['leave_reason'] ;
$list_leave_day = $check_leave['leave_work_day'] ;
switch ( $check_leave['leave_type'] ){
case 'unpaid' :
$list_type_remark = 'UL' ;
break ;
case 'annual' :
$list_type_remark = 'AL' ;
break ;
case 'sick' :
$list_type_remark = 'MC' ;
break ;
}
}
// check today is holiday or weekend
if ( $working['working_on'] == 'no' ){
$list_type = 'weekend' ;
$list_type_remark = 'OD' ;
$list_remark = 'Off Day' ;
$list_work_day = '0' ;
}else{
// if is holiday
if ( $boolean_holiday ){
$list_type = 'holiday' ;
$list_type_remark = 'HL' ;
$list_remark = $holiday_name ;
$list_work_day = '0' ;
}
}
// filter between time period attendance
$attendance_q = $mysqli->query("SELECT attendance_id, created_at FROM staff_attendance
WHERE deleted_at IS NULL AND staff_id = '".$staff_id."' AND list_id = '0' AND created_at >= '".$check_current_datetime."' AND created_at <= '".$check_next_datetime."' ORDER BY created_at ASC") ;
if ( $attendance_q->num_rows > 0 ){
$total_atten = $attendance_q->num_rows ;
$last_atten = '' ;
$working_from = '00:00:00' ;
$first_in_time = '00:00:00' ;
$count_atten = 0 ;
// keep all attendance in array
while ( $attendance = $attendance_q->fetch_assoc() ){
$last_atten = $attendance['created_at'] ;
// check working to
$working_to = date('Y-m-d H:i:s', strtotime( date('Y-m-d', strtotime($last_atten)).' '.$working['working_to'] )) ;
if ( $working['working_if_flexi'] != 'yes' && $working['working_if_fixed_work'] == 'yes' ){
if ( $last_atten >= $working_to ){
$last_atten = $working_to ;
}
}
if ( $count_atten == 0 ){
if ( $working['working_if_flexi'] == 'yes' ){
$working_from = $last_atten ;
}else{
$working_from = date('Y-m-d H:i:s', strtotime( date('Y-m-d', strtotime($last_atten)).' '.$working['working_from'] )) ;
}
$first_in_time = $last_atten ;
if ( $working_from >= $last_atten ){
$last_atten = $working_from ;
}
}
$array_atten_ls[] = $attendance['attendance_id'] ;
$array_atten[] = $last_atten ;
$count_atten++ ;
}
// generate new attendance if attendance is odd
if ( $total_atten%2 == 1 ){
$array_atten[] = $last_atten ;
$punchiscorrect = false ;
}
if ( $array_atten['1'] >= $array_atten['0'] ){
// calculate work and rest and keep in array
$array_hours = [] ;
$array_abnormal = [] ;
$next_hours = '' ;
$rest_1_out = '' ;
$rest_1_in = '' ;
$rest_2_out = '' ;
$rest_2_in = '' ;
$count_rest = 0 ;
foreach ( $array_atten as $k => $v ){
if ( $next_hours != '' ){
$array_hours[] = subtractTime($v, $next_hours) ;
if ( $count_rest == 1 ){
$rest_1_out = $v ;
}
if ( $count_rest == 2 ){
$rest_1_in = $v ;
}
if ( $count_rest == 3 ){
$rest_2_out = $v ;
}
if ( $count_rest == 4 ){
$rest_2_in = $v ;
}
}
$next_hours = $v ;
$count_rest++ ;
}
// get total work & rest
foreach ( $array_hours as $k => $v ){
if ( $k%2 == 1 ){
if ( $k == 1 ){
$list_rest = addTime($list_rest, $v) ;
}else{
if ( $boolean_rest_hours2 == 'yes' ){
$list_rest2 = addTime($list_rest2, $v) ;
}else{
$list_rest = addTime($list_rest, $v) ;
}
}
}else{
$list_work = addTime($list_work, $v) ;
}
$prev_hours = $v ;
}
// check rest in & out if got time, and attendance time more than 2
// if range from and range to setting is empty do nothing
// check if under the range time, if yes do nothing, else checking total time off
$rest_array[] = [
'current_rest' => '1',
'boolean_rest_hours' => 'yes',
'array_atten_ls_1' => 1,
'array_atten_ls_2' => 2,
'total_rest_hours' => $total_rest_hours,
'list_rest' => $list_rest,
'list_rest_more' => $list_rest_more,
'list_time_off' => $list_time_off,
'rest_out' => $rest_1_out,
'rest_in' => $rest_1_in,
'count_rest' => 2,
'working_rest_range_from' => $working['working_rest_range_from'],
'working_rest_range_to' => $working['working_rest_range_to']
] ;
if ( $boolean_rest_hours2 ){
$rest_array[] = [
'current_rest' => '2',
'boolean_rest_hours' => $boolean_rest_hours2,
'array_atten_ls_1' => 3,
'array_atten_ls_2' => 4,
'total_rest_hours' => $total_rest_hours2,
'list_rest' => $list_rest2,
'list_rest_more' => $list_rest_more2,
'list_time_off' => $list_time_off2,
'rest_out' => $rest_2_out,
'rest_in' => $rest_2_in,
'count_rest' => 4,
'working_rest_range_from' => $working['working_rest_range_from2'],
'working_rest_range_to' => $working['working_rest_range_to2']
] ;
}
foreach ( $rest_array as $krest => $vrest ){
$temp_list_time_off = $vrest['list_time_off'] ;
$more_rest = '00:00:00' ;
if ( $vrest['boolean_rest_hours'] == 'yes' ){
if ( $working['working_if_flexi'] == 'no' && $vrest['rest_out'] != '' && $vrest['rest_in'] != '' && $count_rest > $vrest['count_rest'] ){
$rest_range_from = $vrest['working_rest_range_from'] ;
$rest_range_to = $vrest['working_rest_range_to'] ;
if ( ( $rest_range_from != '' && $rest_range_from != '00:00:00' ) &&
( $rest_range_to != '' && $rest_range_to != '00:00:00' ) ){
$rest_range_from = $date_yesterday . ' ' . $rest_range_from ;
$rest_range_to = $date_yesterday . ' ' . $rest_range_to ;
if ( $rest_range_from > $vrest['rest_out'] || $rest_range_to < $vrest['rest_out'] || $rest_range_from > $vrest['rest_in'] || $rest_range_to < $vrest['rest_in'] ){
// if situation 1 - early out
// else - late out
if ( $rest_range_from > $vrest['rest_out'] || $rest_range_to >= $vrest['rest_out'] ){
if ( $rest_range_from > $vrest['rest_in'] ){
$temp_list_time_off = subtractTime($rest_range_from, $vrest['rest_out']) ;
$array_abnormal[] = $array_atten_ls[$vrest['array_atten_ls_1']] ;
$array_abnormal[] = $array_atten_ls[$vrest['array_atten_ls_2']] ;
}else{
if ( $rest_range_from > $vrest['rest_out'] && $rest_range_to < $vrest['rest_in'] ){
$deduct_out = subtractTime($rest_range_from, $vrest['rest_out']) ;
$deduct_in = subtractTime($vrest['rest_in'], $rest_range_to) ;
$temp_list_time_off = addTime($deduct_out, $deduct_in) ;
$array_abnormal[] = $array_atten_ls[$vrest['array_atten_ls_1']] ;
$array_abnormal[] = $array_atten_ls[$vrest['array_atten_ls_2']] ;
}elseif ( $rest_range_from <= $vrest['rest_out'] && $rest_range_to < $vrest['rest_in'] ){
$temp_list_time_off = subtractTime($vrest['rest_in'], $rest_range_to) ;
$array_abnormal[] = $array_atten_ls[$vrest['array_atten_ls_2']] ;
}else{
$temp_list_time_off = subtractTime($rest_range_from, $vrest['rest_out']) ;
$array_abnormal[] = $array_atten_ls[$vrest['array_atten_ls_1']] ;
}
}
}else{
$temp_list_time_off = subtractTime($vrest['rest_in'], $vrest['rest_out']) ;
$array_abnormal[] = $array_atten_ls[$vrest['array_atten_ls_2']] ;
}
}
}
}
$boolean_rest = false ;
if ( $vrest['current_rest'] == '1' ){
$boolean_rest = true ;
}
if ( $vrest['current_rest'] == '2' ){
if ( $vrest['working_rest_range_from'] != '00:00:00' && $vrest['working_rest_range_to'] != '00:00:00' ){
$setting_rest2_time = date( 'Y-m-d', strtotime( $check_current_datetime ) ) . ' ' . $vrest['working_rest_range_to'] ;
}else{
$setting_rest2_time = date( 'Y-m-d', strtotime( $check_current_datetime ) ) . ' ' . $working['working_to'] ;
$setting_rest2_time = date( 'Y-m-d H:i:s', strtotime( $setting_rest2_time . ' +'.convertMinutes($vrest['total_rest_hours']).' minutes' ) ) ;
}
if ( $last_atten >= $working_to && $last_atten >= $setting_rest2_time ){
$check_atten_hours = subtractTime($last_atten, $working_to) ;
$boolean_rest = true ;
}else{
$list_rest2 = '00:00:00' ;
$list_rest_more2 = '00:00:00' ;
$list_time_off2 = '00:00:00' ;
}
}
// calculate rest
if ( $vrest['total_rest_hours'] != '00:00:00' && $vrest['total_rest_hours'] != '' ){
if ( $boolean_rest ){
if ( $vrest['total_rest_hours'] > $vrest['list_rest'] ){
$diff_rest = subtractTime($vrest['total_rest_hours'], $vrest['list_rest']) ;
if ( $list_work > '00:00:00' ){
$list_work = subtractTime($list_work, $diff_rest) ;
}
}
}
if ( $vrest['list_rest'] > $vrest['total_rest_hours'] ){
$more_rest = subtractTime($vrest['list_rest'], $vrest['total_rest_hours']) ;
if ( $boolean_rest ){
$list_work = addTime($list_work, $more_rest) ;
$array_abnormal[] = $array_atten_ls[$vrest['array_atten_ls_2']] ;
}
}
}
// if rest hour more than real rest hours within working hours
if ( $boolean_rest ){
if ( $vrest['total_rest_hours'] == '00:00:00' || $vrest['total_rest_hours'] == '' ){
if ( $temp_list_time_off != '00:00:00' && $temp_list_time_off != '' ){
if ( $temp_list_time_off > $vrest['total_rest_hours'] ){
$list_work = addTime($list_work, $vrest['total_rest_hours']) ;
$temp_list_time_off = subtractTime($temp_list_time_off, $vrest['total_rest_hours']) ;
}else{
$list_work = addTime($list_work, $temp_list_time_off) ;
$temp_list_time_off = '00:00:00' ;
}
}
}
}
// if ( $working['working_direct_day'] == 'no' ){
if ( $list_type_remark != 'OD' && $list_type_remark != 'HL' ){
switch ( $vrest['current_rest'] ){
case '1' :
$list_rest = $vrest['total_rest_hours'] ;
$list_rest_more = $more_rest ;
$list_time_off = $temp_list_time_off ;
break ;
case '2' :
$list_rest2 = $vrest['total_rest_hours'] ;
$list_rest_more2 = $more_rest ;
$list_time_off2 = $temp_list_time_off ;
break ;
}
}
}
}
// get early / late / ot
if ( $working_from > $first_in_time ){
$list_early = subtractTime($working_from, $first_in_time) ;
}
$new_first_in_time = $first_in_time ;
if ( $working['working_rest_range_from'] != '00:00:00' ){
$new_first_in_time = date( 'Y-m-d', strtotime( $first_in_time ) ) . ' ' . $working['working_rest_range_from'] ;
}
if ( $first_in_time >= $working_from && $working_from < $new_first_in_time ){
if ( $new_first_in_time >= $first_in_time ){
$list_late = subtractTime($first_in_time, $working_from) ;
}else{
$list_late = subtractTime($new_first_in_time, $working_from) ;
}
}
// echo $list_late ;
// exit ;
// check if OT is count as total work?
// add the late hours to the total work
$list_work_total = $list_work ;
// if ( $working['working_direct_day'] == 'yes' ){
if ( $list_type_remark == 'OD' || $list_type_remark == 'HL' ){
$total_hours = '00:00:00' ;
}else{
if ( $working['working_if_flexi'] != 'yes' ){
$list_work = addTime($list_work, $list_late) ;
}
}
// check if work enough hours
if ( $list_work >= $total_hours ){
// check if ot
if ( $working['working_if_ot'] == 'yes' ){
if ( $list_work > $total_hours ){
$list_ot_normal = subtractTime($list_work, $total_hours) ;
$list_work = subtractTime($list_work, $list_ot_normal) ;
}
// if off duty is yes
if ( $working['working_if_offduty'] == 'yes' ){
if ( $list_ot_normal >= $working['working_count_offduty'] ){
if ( $working['working_if_deduct_offduty'] == 'no' ){
$list_work = addTime($list_work, $working['working_count_offduty']) ;
$list_ot_normal = subtractTime($list_ot_normal, $working['working_count_offduty']) ;
}
}else{
$list_work = addTime($list_work, $list_ot_normal) ;
$list_ot_normal = '00:00:00' ;
}
}
// if ot rounding is greater than 1
if ( $working['working_rounding_ot'] > 1 ){
$working_rounding_ot = strPad(2, $working['working_rounding_ot']) ;
if ( $working_rounding_ot == '60' ){
$rounding_ot = '01:00:00' ;
}else{
$rounding_ot = '00:'.$working_rounding_ot.':00' ;
}
$reset_list_ot_normal = $list_ot_normal ;
$list_ot_normal = '00:00:00' ;
$boolean_ot = true ;
if ( $rounding_ot <= $reset_list_ot_normal ){
while ( $boolean_ot ){
$reset_list_ot_normal = subtractTime($reset_list_ot_normal, $rounding_ot) ;
$list_ot_normal = addTime($list_ot_normal, $rounding_ot) ;
if ( $rounding_ot > $reset_list_ot_normal ){
$boolean_ot = false ;
}
}
// check if morning is count as ot
if ( $working['working_if_ot_morning'] == 'yes' ){
if ( $list_early != '' && $list_early != '00:00:00' ){
$reset_list_ot_normal = $list_early ;
$boolean_ot = true ;
if ( $rounding_ot <= $reset_list_ot_normal ){
while ( $boolean_ot ){
$reset_list_ot_normal = subtractTime($reset_list_ot_normal, $rounding_ot) ;
$list_ot_normal = addTime($list_ot_normal, $rounding_ot) ;
if ( $rounding_ot > $reset_list_ot_normal ){
$boolean_ot = false ;
}
}
}
}
}
}
}
// check if OT is count as total work?
// delete back the total work hours
if ( $working['working_if_flexi'] != 'yes' ){
$list_work = subtractTime($list_work, $list_late) ;
}
// check max ot hours
$working_max_ot = $working['working_max_ot'] ;
if ( $working_max_ot != '' && $working_max_ot != '00:00:00' ){
if ( $list_ot_normal > $working_max_ot ){
$list_work = addTime( $list_work, subtractTime($working_max_ot, $list_ot_normal) ) ;
$list_ot_normal = $working_max_ot ;
}
}
}
}else{
$list_early_out = subtractTime($total_hours, $list_work_total) ;
if ( $list_late != '00:00:00' ){
$list_early_out = subtractTime($list_early_out, $list_late) ;
}
if ( $after_rest2 > $last_atten ){
// $rest_exclude_early_out = subtractTime($after_rest2, $last_atten) ;
// $list_early_out = subtractTime( $list_early_out, $rest_exclude_early_out ) ;
}
}
}
}else{
if ( $working['working_on'] == 'yes' && $list_type == 'normal' ){
$list_type_remark = 'AS' ;
$list_remark = 'Absent' ;
}
}
// inside into db
// start commit
$error = 0 ;
$mysqli->autocommit( false ) ;
try{
// check if normal working hours
if ( $list_work != '00:00:00' ){
// reset late
$count_total_less = 0 ;
$boolean_less = true ;
$rounding_less = $working['working_day_calculation'] ;
$get_list_early_out = $list_early_out ;
$reset_list_less = addTime($list_late, $get_list_early_out) ;
$reset_list_less = addTime($reset_list_less, $list_time_off) ;
if ( $list_leave_day == '0.5' ){
if ( $list_late > $list_early_out ){
$reset_list_less = subtractTime($reset_list_less, $total_rest_hours) ;
}
}
$reset_work = $working['working_total_hours'] ;
$reset_ot_normal = $list_ot_normal ;
if ( $reset_list_less != '00:00:00' && $reset_list_less > '00:01:00'){
$reset_list_less = subtractTime($reset_list_less, '00:01:00') ;
$rounding_less = ( $rounding_less != '00:00:00' ? $rounding_less : '00:01' ) ;
if ( $rounding_less <= $reset_list_less ){
while ( $boolean_less ){
$reset_list_less = subtractTime($reset_list_less, $rounding_less) ;
if ( $rounding_less > $reset_list_less ){
$boolean_less = false ;
}
$count_total_less++ ;
}
}
if ( $reset_list_less != '00:00:00' ){
$count_total_less++ ;
}
}
// check if local / oversea worker, 1 = local, else oversea
if ( $count_total_less > 0 ){
for ( $a = $count_total_less ; $a > 0 ; $a-- ){
// $deduct_from_day = true ;
// if ( $staff['country_id'] == '1' ){
// }else{
// if ( $working['working_if_ot'] == 'yes' && $reset_ot_normal != '00:00:00' ){
// $deduct_from_day = false ;
// }
// }
// // check if deduct from day or ot
// if ( $deduct_from_day ){
// }else{
// if ( $rounding_less > $reset_ot_normal ){
// $reset_ot_normal = '00:00:00' ;
// }else{
// $reset_ot_normal = subtractTime($reset_ot_normal, $rounding_less) ;
// }
// }
if ( $rounding_less > $reset_work ){
$reset_work = '00:00:00' ;
}else{
$reset_work = subtractTime($reset_work, $rounding_less) ;
}
}
}
// get working & ot day
if ( $reset_work != '00:00:00' ){
$reset_total_work = numberFormat( convertMinutes($working['working_total_hours']), 2 ) ;
$reset_work = numberFormat( convertMinutes($reset_work), 2 ) ;
$list_work_day += numberFormat( ( $reset_work / $reset_total_work ), 2 ) ;
$list_work_day = ( $list_leave_day == 0.5 ? 0.5 : ( $list_work_day > 0.5 ? 1 : ( $list_work_day > 0 ? 0.5 : 0 ) ) ) ;
}
if ( $reset_ot_normal != '00:00:00' ){
$explode_ot_normal = explode(':', $reset_ot_normal) ;
$list_ot_day = numberFormat ( ( $explode_ot_normal[0] . '.' . ( $explode_ot_normal[1] > 0 ? ( $explode_ot_normal[1] / 60 * 100 ) : '' ) ), 2 ) ;
}
}
// over x minutes just count as late
if ( $working['working_period_before'] > 0 ){
$count_late_minutes = convertToTimes($working['working_period_before']) ;
if ( $list_late != '00:00:00' ){
if ( $count_late_minutes > $list_late ){
$list_work = addTime($list_work, $list_late) ;
$list_late = '00:00:00' ;
}else{
$list_work = addTime($list_work, $count_late_minutes) ;
$list_late = subtractTime($list_late, $count_late_minutes) ;
}
}
}
// work_type_id == 3 mean part time job
if ( $list_type_remark == 'WD' && $staff['work_type_id'] == '3' ){
$list_type_remark = 'PT' ;
}
// check if abnormal attendance
if ( $list_late != '00:00:00' ){
$array_abnormal[] = $array_atten_ls[0] ;
}
if ( $list_early_out != '00:00:00' ){
$array_abnormal[] = end($array_atten_ls) ;
}
// if only work half day
$boolean_move_towork = false ;
if ( ( $list_work_day + $list_leave_day ) == '0.5' ){
if ( convertMinutes( $list_late ) > 0 ){
$list_work_day += 0.5 ;
if ( $working['working_rest_range_to'] != '00:00:00' ){
if ( $first_in_time >= $after_rest1 && $after_rest2 > $first_in_time && $list_late != '00:00:00' ){
$late_includerest = subtractTime( $after_rest2, $first_in_time ) ;
$list_late = subtractTime( $list_late, $late_includerest ) ;
}else{
$boolean_move_towork = true ;
}
}else{
$boolean_move_towork = true ;
}
}else{
$boolean_move_towork = true ;
}
}
if ( $boolean_move_towork ){
if ( $list_rest != '00:00:00' ){
$list_work = addTime($list_work, $list_rest) ;
}
$list_rest = '00:00:00' ;
$list_time_off = '00:00:00' ;
}
if ( $list_work_day == 0.5 && $list_leave_day == 0 ){
$list_work_day = 1 ;
}
// combine all working hours as ot
// if ( $working['working_direct_day'] == 'yes' ){
if ( $list_type_remark == 'OD' || $list_type_remark == 'HL' ){
$list_work_day = '0' ;
$list_ot_day = '0' ;
$list_work = '00:00:00' ;
$list_late = '00:00:00' ;
$list_early = '00:00:00' ;
$list_early_out = '00:00:00' ;
}
// if leave half day, then filter out late / early out
if ( $working['working_if_flexi'] == 'no' ){
if ( $list_type_remark == 'AL' || $list_type_remark == 'UL' || $list_type_remark == 'MC' ){
if ( $list_leave_day == '0.5' ){
$half_day_minutes = ( convertMinutes( $total_hours ) / 2 ) ;
$half_day_hours = convertToTimes( $half_day_minutes ) ;
if ( $list_late >= $half_day_hours ){
$list_late = subtractTime( $list_late, $half_day_hours ) ;
if ( $list_late >= $total_rest_hours ){
$list_late = subtractTime( $list_late, $total_rest_hours ) ;
}else{
$list_late = '00:00:00' ;
}
}else{
$list_late = '00:00:00' ;
}
if ( $list_early_out >= $half_day_hours ){
$list_early_out = subtractTime( $list_early_out, $half_day_hours ) ;
if ( $list_early_out >= $total_rest_hours ){
$list_early_out = subtractTime( $list_early_out, $total_rest_hours ) ;
}else{
$list_early_out = '00:00:00' ;
}
}else{
$list_early_out = '00:00:00' ;
}
}
}
}
if ( $working['working_rest_include_ot'] != '00:00:00' ){
if ( $list_rest != '00:00:00' ){
$temp_ot_rest = addTime( $list_ot_normal, $list_rest ) ;
if ( $working['working_rest_include_ot'] >= $temp_ot_rest ){
$list_ot_normal = $temp_ot_rest ;
$list_rest = '00:00:00' ;
}
}
}
if ( !$punchiscorrect ){
$list_work_day = 0 ;
$list_ot_day = 0 ;
$list_work = '00:00:00' ;
$list_rest = '00:00:00' ;
$list_rest_more = '00:00:00' ;
$list_time_off = '00:00:00' ;
$list_rest2 = '00:00:00' ;
$list_rest_more2 = '00:00:00' ;
$list_time_off2 = '00:00:00' ;
$list_early = '00:00:00' ;
$list_early_out = '00:00:00' ;
$list_late = '00:00:00' ;
$list_ot_normal = '00:00:00' ;
$array_abnormal = [] ;
}
// show log
echo 'staff : <br />' ;
foreach ( $staff as $kk => $vv ){
echo $kk . ' -> ' . $vv ;
echo '<br />' ;
}
echo '<br />' ;
echo '<br />' ;
echo 'array_atten : <br />' ;
foreach ( $array_atten as $kk => $vv ){
echo $kk . ' -> ' . $vv ;
echo '<br />' ;
}
echo '<br />' ;
echo '<br />' ;
echo 'array_abnormal : <br />' ;
foreach ( $array_abnormal as $kk => $vv ){
echo $kk . ' -> ' . $vv ;
echo '<br />' ;
}
echo '<br />' ;
echo '<br />' ;
echo 'working : <br />' ;
foreach ( $working as $kk => $vv ){
echo $kk . ' -> ' . $vv ;
echo '<br />' ;
}
echo '<br />' ;
echo '<br />' ;
echo 'staff_id -> ' . $staff_id ;
echo '<br />' ;
echo 'list_type -> ' . $list_type ;
echo '<br />' ;
echo 'list_date -> ' . $date_yesterday ;
echo '<br />' ;
echo 'list_work_day -> ' . $list_work_day ;
echo '<br />' ;
echo 'list_ot_day -> ' . $list_ot_day ;
echo '<br />' ;
echo 'list_leave_day -> ' . $list_leave_day ;
echo '<br />' ;
echo 'list_early -> ' . $list_early ;
echo '<br />' ;
echo 'list_early_out -> ' . $list_early_out ;
echo '<br />' ;
echo 'list_late -> ' . $list_late ;
echo '<br />' ;
echo 'list_rest -> ' . $list_rest ;
echo '<br />' ;
echo 'list_rest_more -> ' . $list_rest_more ;
echo '<br />' ;
echo 'list_time_off -> ' . $list_time_off ;
echo '<br />' ;
echo 'list_rest2 -> ' . $list_rest2 ;
echo '<br />' ;
echo 'list_rest_more2 -> ' . $list_rest_more2 ;
echo '<br />' ;
echo 'list_time_off2 -> ' . $list_time_off2 ;
echo '<br />' ;
echo 'list_type -> ' . $list_type ;
echo '<br />' ;
echo 'list_type_remark -> ' . $list_type_remark ;
echo '<br />' ;
echo 'list_remark -> ' . $list_remark ;
echo '<br />' ;
echo 'list_work -> ' . $list_work ;
echo '<br />' ;
echo 'list_ot_normal -> ' . $list_ot_normal ;
echo '<br />' ;
echo '<br />' ;
echo '<br />' ;
// exit ;
$list_insert = $mysqli->query("INSERT INTO staff_attendance_list
(staff_id, list_date, list_checkinout, created_at, updated_at, list_work_day, list_ot_day, list_leave_day, list_early, list_early_out, list_late, list_rest, list_rest_more, list_time_off, list_rest2, list_rest_more2, list_time_off2, list_type, list_type_remark, list_remark, list_work, list_ot_normal) VALUES
('".$staff_id."', '".$date_yesterday."', '".json_encode($array_atten)."', '".TODAYDATE."', '".TODAYDATE."', '".$list_work_day."', '".$list_ot_day."', '".$list_leave_day."', '".$list_early."', '".$list_early_out."', '".$list_late."', '".$list_rest."', '".$list_rest_more."', '".$list_time_off."', '".$list_rest2."', '".$list_rest_more2."', '".$list_time_off2."', '".$list_type."', '".$list_type_remark."', '".$list_remark."', '".$list_work."', '".$list_ot_normal."')") ;
if ( $mysqli->affected_rows > 0 ){
$last_insert = $mysqli->insert_id ;
if ( count($array_atten_ls) > 0 ){
foreach ( $array_atten_ls as $k_atten => $v_atten ){
$merge_insert = $mysqli->query("UPDATE staff_attendance SET
" . ( in_array($v_atten, $array_abnormal) ? "abnormal = 'yes'," : '' ) . "
list_id = '".$last_insert."',
check_group = '".$date_yesterday."'
WHERE attendance_id = '".$v_atten."' ") ;
if ( $mysqli->affected_rows > 0 ){ }else{
$error++ ;
}
}
}
}else{
$error++ ;
}
}catch( Exception $e ){
$error++;
}
if( $error == 0 ) {
// commit query
$mysqli->commit() ;
$status = '200' ;
$message = 'Success' ;
}else{
$mysqli->rollback() ;
$status = '300' ;
$message = 'Something error, please try again later.' ;
}
}
}
}
}
}
echo json_encode([
'status' => $status,
'message' => $message
]) ;
?>