Я пытаюсь сформировать сумму посещаемости сотрудника. Данные из двух таблиц ниже.
Schedule /* This is the shift schedule of employee */
ID Name Schedule
1 Paul 11:00PM - 8:00AM
2 Juan 11:00PM - 8:00AM
3 Elise 11:00PM - 8:00AM
Attendance /* This is the logs of employee, it is name fp_logs */
ID EmployeeID Type Datetime
1 1 0 2015-07-25 22:00:00
2 2 0 2015-07-25 22:48:00
3 3 0 2015-07-25 20:48:00
1 1 1 2015-07-25 08:00:00
2 2 1 2015-07-25 08:44:00
3 3 1 2015-07-25 08:00:00
Как видно из таблицы посещаемости, у нас есть столбец с именем «тип», где 0 — логин, а 1 — выход.
Мой скрипт для генерации отчета
$strSQL = "SELECT * FROM employees";
$employees = $DB->getRecords($strSQL);
$from = strtotime("07/01/2015"); // Add post from date here
$to = strtotime("07/31/2015"); // Add post to date here
$total = array(
array('fullname'=> '', 'days' => 0, 'inc' => 0, 'late' => 0, 'undertime' => 0, 'absent' => 0, 'nightdiff' => 0)
);
foreach($employees as $key => $emp){
$empId = $emp['id'];
$curDate = $from;
while($curDate <= $to) {
$sched = $DB->getRecord("select * from schedules where empid='$empId' and date(scheddate) = '".date('Y/m/d', $curDate)."'");
$log = array(
'workingday' => @$sched['workingday'],
'day' => date('l', $curDate),
'login' => '',
'logout' => '',
);
$ltnow = date('Y/m/d', $curDate) < date('Y/m/d', NOW); //less than now
if($ltnow) {
if(@$sched['workingday']) {
$log_range = array(
'shift_before' => "datetime between date_add('".date('Y/m/d H:i:s', strtotime($sched['datefrom']))."',interval -6 hour) and '".date('Y/m/d H:i:s', strtotime($sched['datefrom']))."'",
'shift' => "datetime between '".date('Y/m/d H:i:s', strtotime($sched['datefrom']))."' and '".date('Y/m/d H:i:s',strtotime($sched['dateto']))."'",
'shift_after' => "datetime between '".date('Y/m/d H:i:s', strtotime($sched['dateto']))."' and date_add('".date('Y/m/d H:i:s',strtotime($sched['dateto']))."',interval +6 hour)");
$login = $DB->getRecord("select * from fp_logs where fp_id='$emp[fp_id]' and fp_id!='' and type='0' and $log_range[shift_before] limit 1");
$login_shift = $DB->getRecord("select * from fp_logs where fp_id='$emp[fp_id]' and fp_id!='' and type='0' and $log_range[shift] limit 1");
$logout_shift = $DB->getRecord("select * from fp_logs where fp_id='$emp[fp_id]' and fp_id!='' and type='1' and $log_range[shift] order by datetime desc limit 1");
$logout = $DB->getRecord("select * from fp_logs where fp_id='$emp[fp_id]' and fp_id!='' and type='1' and $log_range[shift_after] order by datetime desc limit 1");
$log['login'] = !empty($login['datetime'])?$login['datetime']:$login_shift['datetime'];
$log['logout'] = !empty($logout['datetime'])?$logout['datetime']:$logout_shift['datetime'];
$total[$key]['fullname'] = $emp['lname'] . ', ' .$emp['fname'];
if(empty($log['login']) && empty($log['logout'])) {
$total[$key]['absent']++;
} else {
if(empty($log['login']) || empty($log['logout'])) {
$total[$key]['absent']++;
$total[$key]['inc']++;
} else {
if((date('H:i:00', strtotime($sched['datefrom'])) == '07:00:00' && date('H:i:00', strtotime($sched['dateto'])) == '11:00:00') ||
(date('H:i:00', strtotime($sched['datefrom'])) == '06:00:00' && date('H:i:00', strtotime($sched['dateto'])) == '10:00:00'))
$total[$key]['days']+= .5;
else
$total[$key]['days']++;
$total[$key]['late'] += getLate($sched['datefrom'], $log['login']);
$total[$key]['undertime'] += getUnderTime($sched['dateto'], $log['logout']);
$nd = getNightDiff($sched['datefrom'], $sched['dateto'], $log['login'], $log['logout']);
$nd = $nd<0?0:$nd;
$total[$key]['nightdiff'] += $nd;
}
}
} else {
if(@$sched['schedtitle'] == 'Suspended') {
$total[$key]['absent']++;
}
}
}
$curDate = strtotime(date('Y/m/d H:i:s', $curDate)." +1 day");
}
}
В настоящее время он работает сейчас, проблема в том, что для создания 118 записей сотрудников требуется 1 час. Если только 1 запись, это займет 30 секунд. Есть ли способ сделать скрипт быстрее? Мне нужно вычислить общее опоздание, отсутствие, неполный рабочий день, неполное, ночное смещение каждого сотрудника. Отчет о посещаемости генерируется следующим образом.
Attendance Report
Name Days Late Absent Undertime NightDiff Incomplete
Paul 22 1 1 0 123 0
Juan 22 0 0 0 231 0
Elise 22 0 0 0 223 0
Задача ещё не решена.
Других решений пока нет …