0

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.

  1. First iterate over a loop of Starting date and Ending date for which I want to see the working hours.
  2. Now first of all check if the employee logged in on a particular date, by finding a status 1 entry of that date.
  3. If the employee logged in on that date, then I fetch all attendance records for that date.
  4. 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;
}
  • 1
    Code please.... – Irvin Nov 28 '16 at 03:20
  • Sorry, now I have added some code with my question. – Kapil Sharma Nov 28 '16 at 03:40
  • If there's no status 2 for that day that means there's no log-out right? – Rav Nov 28 '16 at 05:50
  • This has something to do with a database, right? – Strawberry Nov 28 '16 at 08:28
  • Yes correct Ronald – Kapil Sharma Nov 28 '16 at 08:41
  • Yes Strawberry. – Kapil Sharma Nov 28 '16 at 08:41
  • You forgot to mention what should happen when there is no logout. If you have night shifts, you can just read the next (and previous) day in php too (or do it in the db), and start/end such days at 12pm if you sum per calender date. Without night shifts (e.g. the user simply forgot to log out), either treat it as "logged in to the end of day", if e.g. everybody leaves at 18pm or after 8 hours, or as no worktime (e.g. log out at the last logged time that day), so the user has an incentive to let it get corrected, otherwise someone has to remind them to reduce their logged hours... – Solarflare Nov 28 '16 at 12:07

0 Answers0