0

I'm trying to create a simple attendance application with Laravel. I'm just a little stuck with the logic side. What I'm trying to do is to match up the time logs of users to the correct schedule.

So in our office, we could have from 2 to 3 breaks, so a typical work shift will look like this:

Time In     - 06:00 AM
Break Out 1 - 07:15 AM
Break In 1  - 07:30 AM
Break Out 2 - 11:30 AM
Break In 2  - 12:00 PM
Time Out    - 03:00 PM

Now a user typically just uses the biometric device and selects "in" or "out".

My problem is given something like this:

05:58 AM, in
07:17 AM, out
07:31 AM, in
05:58 AM, out

How can the system tell which time log (07:17 AM) belongs to which time slot (Break Out 1)?

Thank you so much for the help, and if my question is unclear, I'm sorry.

Here's a sample code of what I've done so far. It works but I think it's really messy:

$day_shift = [
    "time_in" => date('H:i:s', strtotime("06:00 AM")),
    "break_out_1" => date('H:i:s', strtotime("07:15 AM")),
    "break_in_1" => date('H:i:s', strtotime("07:30 AM")),
    "break_out_2" => date('H:i:s', strtotime("11:30 AM")),
    "break_in_2" =>  date('H:i:s', strtotime("12:00 PM")),
    "break_out_3" => '',
    "break_in_3" => '',
    "time_out" =>  date('H:i:s', strtotime("03:00 pM")),
];


foreach ($day_shift as $key => $userScheduleTime) {
    if ($userScheduleTime !== "") {
        $time = $logDate->date." ".$userScheduleTime;
    } else {
        $time = "";
    }
    $schedules[] = array('time' => $time, 'type' => $types[$i%2],'name'=>$key);
    $i++;
}

// logTimes is a collection of time logs

foreach ($logTimes as $logTime) {
    $logs[] =  $logTime->toArray();
}
$cloneLogs = $logs;
$lastlog = end($cloneLogs);
if ($lastlog["log_type"] == "login") {
    $dayOut = "";
} else {
    $dayOut = $lastlog["log_time"];
}
$lastout = null;
$size = count($logs);
do {
    if ($logs[$size-1]['log_type'] == 'logout') {
        $lastout = $logs[$size-1];
        break;
    }
    $size--;
} while ($size > 0);

$lastlog = null;

for ($i = 0; $i < count($schedules); $i++) {
    $logTime = current($logs);
    if ($lastlog == $logTime['log_type']) {
        next($logs);
    }
    // checks the first log, calculates how late the person is
    if ($i == 0) {
        if ($logTime['log_type'] == "login") {
            $timein = $schedules[0]['time'];

            if (strtotime(date("Y-m-d H:i", strtotime($logTime['log_time']))) >
                strtotime(date("Y-m-d H:i", strtotime($timein)))) {
                $lates[$logTime['log_time']] = true;
                $lates["totallate"] += getDifferenceInMinutes($logTime['log_time'], $timein);
            }
            $lastlog = $logTime["log_type"];
            next($logs);
        }
    }

    if ($schedules[$i]['type']==$logTime['log_type'] && $i!=0 && $lastlog !== $logTime["log_type"]) {
        $nextSched = isset($schedules[$i+1])?$schedules[$i+1]:$schedules[$i];
        $j = 1;
        while ($nextSched['time']=="" && ($i+$j)<=count($schedules)) {
            $nextSched = $schedules[$i+$j];
            $j++;
        }

        if (strtotime($nextSched['time'])>strtotime($logTime['log_time']) && $logTime["log_time"] != $dayOut) {

            // checks and calculates if the user has undertime        
            if (strtotime($nextSched['time']) > strtotime($logTime['log_time']) && $nextSched['type']=='login') {
                if (strtotime($logTime['log_time']) < strtotime($schedules[$i]['time'])) {
                    $lates[$logTime['log_time']] = true;
                    $lates["totalunder"] += getDifferenceInMinutes($logTime['log_time'], $schedules[$i]['time']);
                }
            }

            // checks and calculates if the user has overbreaks
            if (date('H:i', strtotime($schedules[$i]['time'])) <
                date('H:i', strtotime($logTime['log_time'])) &&
                $logTime['log_type'] == 'login') {
                $lates[$logTime['log_time']] = true;
                $lates["totalover"] += getDifferenceInMinutes($schedules[$i]['time'], $logTime['log_time']);
            }
            $lastlog = $logTime["log_type"];
            next($logs);
        }


        if ($i+1==count($schedules)) {
            next($logs);
        }

        if ($logTime["log_time"] == $dayOut && $dayOut !== null) {
            $timeOut = $schedules[count($schedules)-1]["time"];
            if (strtotime(date("Y-m-d H:i", strtotime($logTime["log_time"]))) <
                strtotime(date("Y-m-d H:i", strtotime($timeOut)))) {
                $lates[$logTime["log_time"]] = true;
                $lates["totalunder"] += getDifferenceInMinutes($logTime['log_time'], $timeOut);
                $lastlog = $logTime["log_type"];
            }
            break;
        }
    }
}
kazuo
  • 297
  • 1
  • 6
  • 15
  • Based on what I understood I think you you should check for user first checkIn per day and make it TimeIn and then any In and Out after that time you can schedule it as breakOut and breakIn and any out after 3 will be TimeOut – Ahmad Rezk Mar 21 '17 at 09:34
  • Yes, that's what this code does already. But there will be cases where users skip the first break but time out and in for the second break, which means just sequentially adding the schedule won't work. – kazuo Mar 21 '17 at 15:42
  • I think you should put another constraint like count number of hours that employee has worked to specify in which period he is, then decide Is he in a break or timed out – Ahmad Rezk Mar 21 '17 at 20:09

0 Answers0