I am looking for some basic attendance logic. What I have done so far is that employees can click on two different kinds of buttons and mark themselves as Signed In, Signed Out (status 1 and 2) using one button and Break Start, Break Over (status 3 and 4) using the other button.
Now when I calculate employee's total Sign In hours and total Break hours for a particular date I do something like below.
- First iterate over a loop of Starting date and Ending date for which I want to see the working hours.
- Now first of all check if the employee logged in on a particular date, by finding a status 1 entry of that date.
- If the employee logged in on that date, then I fetch all attendance records for that date.
- Now I iterate over this date's attendance records add up the time differences starting from first status 1 (i.e. Login) to next status and from next status (which can be either a break start 3 or a log out 2) till the next status (which can be either break over 4 or log in 1).
This is working good and my working hours' calculations are coming fine.
There is however one logical part that I am not able to understand i.e. if the employee does not logout on the same date for which I have fetched out the records, then the time span from last login or break start till the logout are not getting calculated. Because the final logged out status does not fall on the same date for which I fetched the records.
So, I need some help in understanding any suggestions how this can be managed and how can I calculate the working hours if the employee's logout status falls on a different date than login date.
Thanks in advance.
Here is some code.
public function getEmployeeAttendance($company_uid , $emp_uid)
{
for($m=1; $m<=12; $m++)
{
$mon = strtotime(date('Y-' . $m . '-00'));
$first = date("Y-m-01", $mon); // First Date Of cuRRENT mONTH
$last = date("Y-m-t", $mon); // Last Date Of cuRRENT mONTH
$date[] = range_date($first, $last);
}
$atten = array();
//echo "<pre>";
foreach($date as $dt)
{
foreach($dt as $d)
{
// A function to check if there was a status 1 on this date
$myAttendance = $this->Attendance_Model->myAttendance($company_uid , $emp_uid, $d);
# If Employee Signed In on This Date (i.e. Status was 1)
if(count($myAttendance) >0)
{
# Calculate Working Hours
$attenRec = $this->Attendance_Model->getAttendanceRecords($company_uid , $emp_uid, $d);
$signInHrs = 0;
$breakHrs = 0;
$workingHrs = 0;
for($i=0; $i<count($attenRec); $i++)
{
// Get this record's status
$status = $attenRec[$i]['status'];
// Get next record's status
if(!empty($attenRec[$i + 1]))
{
if($status == '1' || $status == '4') // Sign In or Break Over
{
$thisTime = strtotime($attenRec[$i]['atten_time']);
$nextTime = strtotime($attenRec[$i + 1]['atten_time']);
$diff = round(($nextTime - $thisTime) / 3600, 2);
$signInHrs += $diff;
}
if($status == '3') // Break Start
{
$thisTime = strtotime($attenRec[$i]['atten_time']);
$nextTime = strtotime($attenRec[$i + 1]['atten_time']);
$diff = round(($nextTime - $thisTime) / 3600, 2);
$signInHrs += $diff;
$breakHrs += $diff;
}
}
}
$onlySignInHrs = floor($signInHrs);
$remainingSignInHrs = $signInHrs - $onlySignInHrs;
$signInMinutes = round($remainingSignInHrs * 60);
$myAttendance['signInHrs'] = $onlySignInHrs . " Hrs : " . $signInMinutes . " Min";
$onlyBreakHrs = floor($breakHrs);
$remainingBreakHrs = $breakHrs - $onlyBreakHrs;
$breakMinutes = round($remainingBreakHrs * 60);
$myAttendance['breakHrs'] = $onlyBreakHrs . " Hrs : " . $breakMinutes . " Min";
$workingHrs = $signInHrs - $breakHrs;
$onlyWorkingHrs = floor($workingHrs);
$remainingWorkingHrs = $workingHrs - $onlyWorkingHrs;
$workingMinutes = round($remainingWorkingHrs * 60);
$myAttendance['workingHrs'] = $onlyWorkingHrs . " Hrs : " . $workingMinutes . " Min";
}
# Save This Date's Attendance
$atten[] = $myAttendance;
}
}
return $atten;
}