Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

mshs07's avatar

How to make faster.

I'm using a function to proccess 2500 employees 2 days attendance data. I run this function unisg Task Scheduling. it takes more than 90 min. How can I make this faster. My function is given bellow:

public function daily_attendance() {
    ini_set('max_execution_time', 0);  set_time_limit(0); ignore_user_abort(true);
    \DB::connection()->disableQueryLog();
    $ot_update = EmployeeAttendances::where('ot_update', 0)->first();
    $lock_months = LockSalary::lists('salary_month');
    $holiday_list = HolidayLists::latest()->lists('holiday_date'); 
    
    if(is_null($ot_update)){
        $attendance_date = EmployeeAttendances::where('ot_update', 1)->where('automatic', 1)->where('attendance_update', 0)->orderBy('attendance_date', 'desc')->groupBy('attendance_date')->select('attendance_date')->first();
        if(!is_null($attendance_date)) {
            $end_date = $attendance_date->attendance_date;
            $start_date = date('Y-m-d', strtotime($end_date .' -1 day'));
            
            $attend_days = $this->date_range($end_date, $start_date); 
            krsort($attend_days);
            $i = 0;
            \Storage::disk('local')->put('attendance.txt', 'Attendance Data is updating from '.$attend_days[0].' to '.$attend_days[1]);
            foreach($attend_days as $attend_day) {
                $start_month_date = date('Y-m-01', strtotime($attend_day));
                if(!in_array($start_month_date, $lock_months)) {
                    $employees = \DB::select(\DB::raw('SELECT emp_basic.id, emp_basic.employee_code, emp_basic.fullname, 
                        emp_official.weekly_holiday, emp_official.unit, emp_official.section, emp_official.joining_date, 
                        emp_official.separation_date, emp_official.overtime, emp_official.pm_absent 
                        FROM hrm_employee_basic_info as emp_basic
                        JOIN hrm_employee_official_info as emp_official ON emp_official.employee_id = emp_basic.id
                        WHERE ((DATE(emp_basic.deleted_at) IS NULL))
                        AND ((emp_official.separation_date IS NULL) OR (DATE(emp_official.separation_date) = "'.$attend_day.'") OR (DATE(emp_official.separation_date) > "'.$attend_day.'"))
                        AND (DATE(emp_official.joining_date) <= "'. $attend_day .'")
                        GROUP BY emp_basic.id ORDER BY emp_basic.id'));
                    
                    
                    foreach($employees as $employee) {
                        $employee_attendances = array();
                        $employee_office = $this->employee_office($employee->id, $attend_day);                            
                        $intime = EmployeeAttendances::where('employee_id', $employee->id)->where('attendance_date', $attend_day)->where('attendance_time', '>', $employee_office['in_time_margin'])->min('attendance_time');
                        $min_out = EmployeeAttendances::where('attendance_date', $attend_day)->where('employee_id', $employee->id)->where('attendance_time', '<', $employee_office['in_time_margin'])->max('attendance_time');
                        if($min_out < $employee_office['in_time_margin'] && $min_out != null){
                            $outtime = EmployeeAttendances::where('attendance_date', $attend_day)->where('employee_id', $employee->id)->where('attendance_time', '<', $employee_office['in_time_margin'])->max('attendance_time');
                        } else {
                            $outtime = EmployeeAttendances::where('attendance_date', $attend_day)->where('employee_id', $employee->id)->max('attendance_time');
                        }
                        
                        $leave_data = EmployeeLeaves::where('employee_id', $employee->id)->where('leave_days', $attend_day)->where('status', 'Approved')->first();
                        $late_data = EmployeeLates::where('employee_id', $employee->id)->where('late_date', $attend_day)->first();
                        $ot_time = EmployeeOts::where('employee_id', $employee->id)->where('ot_date', $attend_day)->first();
                                                
                        $alternate_holiday_today = AlternateHolidays::whereRaw('alternate_holiday = "'.$attend_day.'" AND (unit = "'.$employee->unit.'" OR unit IS NULL) AND (section = "'.$employee->section.'" OR section IS NULL) 
                                            AND (joining_date > "'.$employee->joining_date.'" OR joining_date IS NULL)')->lists('alternate_holiday');
                        $alternate_workday_today = AlternateHolidays::whereRaw('holiday = "'.$attend_day.'" AND (unit = "'.$employee->unit.'" OR unit IS NULL) AND (section = "'.$employee->section.'" OR section IS NULL) 
                                            AND (joining_date > "'.$employee->joining_date.'" OR joining_date IS NULL)')->lists('holiday');
                        $emp_holidays = EmployeeHolidays::where('new_holiday', $attend_day)->where('employee_id', $employee->id)->lists('new_holiday');
                        $emp_working = EmployeeHolidays::where('old_holiday', $attend_day)->where('employee_id', $employee->id)->lists('old_holiday');
                        
                        $working = array_unique(array_merge($emp_working, $alternate_workday_today));
                        
                        $employee_attendances['employee_id'] = $employee->id;
                        $employee_attendances['attend_date'] = $attend_day;
                        
                        if($employee->separation_date) {
                            $separation = $employee->separation_date;
                        } else {
                            $separation = '2150-12-31';
                        }
                             
                        if(empty($intime) && !empty($outtime)) {
                            $intime = $outtime;
                            $in_date = date('Y-m-d', strtotime($attend_day .' -1 day'));
                            $from_time = strtotime($in_date." ".$employee_office['in_time']);
                            $to_time = strtotime($attend_day." ".$outtime);
                            $total_time = round(abs($to_time - $from_time) / 60,0);
                                    
                            if($employee_office['shift_id'] == '4') {
                                $outtime = EmployeeAttendances::where('employee_id', $employee->id)->where('attendance_date', $attend_day)->where('attendance_time', '<', $employee_office['last_ot_time'])->max('attendance_time');
                            }
                                   
                            $data['employee_id'] = $employee->id;
                            $data['late_date'] = $attend_day;
                            $data['late'] = $total_time;
                            $data['user_id'] = '1';
                            
                            $late_data = EmployeeLates::create($data); 
                        }
                        $week_day = date("w", strtotime($attend_day));
                        if($week_day == 0){
                            $week_day = 7;
                        }
                        
                        if($intime && empty($late_data) && empty($leave_data) && $week_day != $employee->weekly_holiday && in_array($attend_day, $alternate_holiday_today)){
                            $employee_attendances['status'] = 'PH'; 
                        } elseif($intime && empty($late_data) && empty($leave_data) && $week_day != $employee->weekly_holiday && in_array($attend_day, $holiday_list)){
                            $employee_attendances['status'] = 'PH'; 
                        } elseif($intime && empty($late_data) && empty($leave_data) && $week_day == $employee->weekly_holiday && !in_array($attend_day, $working)){
                            $employee_attendances['status'] = 'PW';
                        } elseif($intime && empty($late_data) && empty($leave_data) && in_array($attend_day, $emp_holidays) && !in_array($attend_day, $working)){
                            $employee_attendances['status'] = 'PW'; 
                        } elseif($intime && empty($late_data) && empty($leave_data)) {
                            $employee_attendances['status'] = 'P'; 
                        } elseif($intime && !empty($late_data) && empty($leave_data) && $week_day != $employee->weekly_holiday && in_array($attend_day, $alternate_holiday_today)){
                            $employee_attendances['status'] = 'LH'; 
                        } elseif($intime && !empty($late_data) && empty($leave_data) && $week_day != $employee->weekly_holiday && in_array($attend_day, $holiday_list)){
                            $employee_attendances['status'] = 'LH'; 
                        } elseif($intime && !empty($late_data) && empty($leave_data) && $week_day == $employee->weekly_holiday && !in_array($attend_day, $working)){
                            $employee_attendances['status'] = 'LW'; 
                        } elseif($intime && !empty($late_data) && empty($leave_data) && in_array($attend_day, $emp_holidays) && !in_array($attend_day, $working)){
                            $employee_attendances['status'] = 'LW'; 
                        } elseif($intime && !empty($late_data) && empty($leave_data)) {
                            $employee_attendances['status'] = 'L';  
                        } elseif(!empty($leave_data)) {
                            if($leave_data->leave_type == 'Casual Leave') {
                                $employee_attendances['status'] = 'CL';
                            } elseif($leave_data->leave_type == 'Sick Leave') {
                                $employee_attendances['status'] = 'SL';
                            } elseif($leave_data->leave_type == 'Earned Leave') {
                                $employee_attendances['status'] = 'EL';
                            } elseif($leave_data->leave_type == 'Maternity Leave') {
                                $employee_attendances['status'] = 'MLV';
                            } elseif($leave_data->leave_type == 'Special Leave') {
                                $employee_attendances['status'] = 'SP';
                            } elseif($leave_data->leave_type == 'Without Payment Leave') {
                                $employee_attendances['status'] = 'LWP';
                            } elseif($leave_data->leave_type == 'Suspension') {
                                $employee_attendances['status'] = 'SUS';
                            } else {
                                $employee_attendances['status'] = 'LV';
                            }
                            EmployeeAttendances::where('employee_id', $employee->id)->where('attendance_date', $attend_day)->delete();
                            if(!empty($ot_time)) $ot_time->delete();
                            if(!empty($late_data)) $late_data->delete();
                        } elseif($week_day != $employee->weekly_holiday && in_array($attend_day, $alternate_holiday_today)) {
                            if(($separation >= $attend_day) && ($employee->joining_date <= $attend_day)) {
                                $employee_attendances['status'] = 'H';
                                if(!empty($ot_time)) $ot_time->delete();
                                if(!empty($late_data)) $late_data->delete();
                            } else {
                                $employee_attendances['status'] = NULL;
                            }
                        } elseif($week_day != $employee->weekly_holiday && in_array($attend_day, $holiday_list)) {
                            if(($separation >= $attend_day) && ($employee->joining_date <= $attend_day)) {
                                $employee_attendances['status'] = 'H';
                                if(!empty($ot_time)) $ot_time->delete();
                                if(!empty($late_data)) $late_data->delete();
                            } else {
                                $employee_attendances['status'] = NULL;
                            }
                        } elseif(in_array($attend_day, $emp_holidays) && !in_array($attend_day, $working)) {
                            if(($separation >= $attend_day) && ($employee->joining_date <= $attend_day)) {
                                $employee_attendances['status'] = 'W';
                                if(!empty($ot_time)) $ot_time->delete();
                                if(!empty($late_data)) $late_data->delete();
                            } else {
                                $employee_attendances['status'] = NULL;
                            }
                        }  elseif($week_day == $employee->weekly_holiday && !in_array($attend_day, $working)) {
                            if(($separation >= $attend_day) && ($employee->joining_date <= $attend_day)) {
                                $employee_attendances['status'] = 'W';
                                if(!empty($ot_time)) $ot_time->delete();
                                if(!empty($late_data)) $late_data->delete();
                            } else {
                                $employee_attendances['status'] = NULL;
                            }
                        } else {
                            $employee_attendances['status'] = 'A'; 
                            if(!empty($ot_time)) $ot_time->delete();
                            if(!empty($late_data)) $late_data->delete();
                        }
                        
                        if(!empty($intime) && empty($leave_data)) {
                            $employee_attendances['in_time'] = date('h:i A', strtotime($intime));
                        } else {
                            $employee_attendances['in_time'] = NULL;
                        }
                        
                        $remarks_data = null;
                        $in_time_remarks = EmployeeAttendances::where('attendance_date', $attend_day)->where('employee_id', $employee->id)->where('attendance_time', $intime)->first();
                        if(!is_null($in_time_remarks)) {
                            if($in_time_remarks->remarks != null) {
                                $remarks_data = $in_time_remarks->remarks.'<br/>';
                            }
                            $employee_attendances['in_time_status'] = $in_time_remarks->automatic;
                        }
                        if(!empty($outtime) && empty($leave_data) && date('h:i A', strtotime($outtime)) != date('h:i A', strtotime($intime))) {
                            $employee_attendances['out_time'] = date('h:i A', strtotime($outtime));
                        } else {
                            $employee_attendances['out_time'] = NULL;
                            if(!empty($ot_time)) $ot_time->delete();
                        }
                        $allowed_status = ['P', 'L'];    
                        if($employee_attendances['in_time'] != NULL && $employee_attendances['out_time'] == NULL && $employee->pm_absent != NULL && $attend_day != date('Y-m-d') &&  in_array($employee_attendances['status'], $allowed_status)) {
                            $employee_attendances['status'] = 'PM';
                        }
                        
                        
                        $out_time_remarks = EmployeeAttendances::where('attendance_date', $attend_day)->where('employee_id', $employee->id)->where('attendance_time', $outtime)->first();
                        if(!is_null($out_time_remarks)) {
                            if($out_time_remarks->remarks != null && $employee_attendances['out_time'] != NULL) {
                                $remarks_data .= $out_time_remarks->remarks;
                            }
                            $employee_attendances['out_time_status'] = $out_time_remarks->automatic;
                        }
                        if($employee->overtime != NULL){                     
                            if(!empty($ot_time) && empty($leave_data) && $employee_attendances['status'] != 'W' && $employee_attendances['status'] != 'H' && $employee_attendances['status'] != 'A' && $employee_attendances['out_time'] != NULL) {
                                $employee_attendances['ot_hours'] = $ot_time->ot_hours;
                            } else {
                                $employee_attendances['ot_hours'] = 0;
                            }
                        } else {
                            $employee_attendances['ot_hours'] = 0;
                        }
                        
                        if(!empty($late_data) && empty($leave_data) && $employee_attendances['status'] != 'W' && $employee_attendances['status'] != 'H' && $employee_attendances['status'] != 'A') {
                            $employee_attendances['late'] = $late_data->late;
                        } else {
                            $employee_attendances['late'] = 0;
                        }
                        
                        $employee_attendances['remarks'] = $remarks_data;
                        
                        
                        $attend_data = EmployeeDailyAttendances::where('employee_id', $employee->id)->where('attend_date', $attend_day)->first();
                        if(!is_null($attend_data)) {
                            $employee_attendances['monthly_attend_update'] = 0;
                            $employee_attendances['salary_update'] = 0;
                            $attend_data->update($employee_attendances);
                        } else {                            
                            EmployeeDailyAttendances::create($employee_attendances);
                        }
                        
                    }
                    $employee_attendance = EmployeeAttendances::where('attendance_date', $attend_day)->where('ot_update', 1)->update(['attendance_update' => '1']);
                } else {
                    $employee_attendance = EmployeeAttendances::where('attendance_date', $attend_day)->where('ot_update', 1)->update(['attendance_update' => '2']);
                }
            }  
            if(\Storage::exists('attendance.txt')) {
                \Storage::disk('local')->delete('attendance.txt');
            }
        }
    }
    
}
0 likes
3 replies
topvillas's avatar

Nobody's going to read that.

Do yourself a favour and split that colossal thing into smaller functions.

3 likes
MikeHopley's avatar

Nobody's going to read that.

I'd go one further and question whether anyone can read it (and understand it).

This is not the kind of code you want to come back to after six months. You will not remember how it works.

If you currently understand it then:

  1. Congratulations for having the intelligence to hold all that in your head!
  2. Take the time now to refactor it into something readable, before it's too late.
Jaytee's avatar

Yeah go format this into smaller chunks of code. It'll take us 90 minutes just to read that shit.

And for your scheduler to go through 2500 employees and do that everytime, i'm not surprised.

Please or to participate in this conversation.