Tuesday, March 21, 2017

Matching user time logs to day shift in an attendance system

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;
        }
    }
}



via kazuo

Advertisement