function roundTimeStamp($epoch) { $original_epoch = $epoch; Debug::text(' Rounding Timestamp: ' . TTDate::getDate('DATE+TIME', $epoch) . ' Status ID: ' . $this->getStatus() . ' Type ID: ' . $this->getType(), __FILE__, __LINE__, __METHOD__, 10); /* //Punch control is no longer used for rounding. if ( !is_object( $this->getPunchControlObject() ) ) { return FALSE; } */ //Check for rounding policies. $riplf = new RoundIntervalPolicyListFactory(); $type_id = $riplf->getPunchTypeFromPunchStatusAndType($this->getStatus(), $this->getType()); Debug::text(' Round Interval Punch Type: ' . $type_id . ' User: '******' Found Rounding Policy: ' . $round_policy_obj->getId() . ' Punch Type: ' . $round_policy_obj->getPunchType(), __FILE__, __LINE__, __METHOD__, 10); //FIXME: It will only do proper total rounding if they edit the Lunch Out punch. //We need to account for cases when they edit just the Lunch In Punch. if ($round_policy_obj->getPunchType() == 100) { Debug::text('Lunch Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); //On Lunch Punch In (back from lunch) do the total rounding. if ($this->getStatus() == 10 and $this->getType() == 20) { Debug::text('bLunch Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); //If strict is set, round to scheduled lunch time? //Find Lunch Punch In. $plf = new PunchListFactory(); //$plf->getPreviousPunchByUserDateIdAndStatusAndTypeAndEpoch( $this->getPunchControlObject()->getUserDateID(), 20, 20, $epoch ); $plf->getPreviousPunchByUserIdAndStatusAndTypeAndEpoch($this->getUser(), 20, 20, $epoch); if ($plf->getRecordCount() == 1) { Debug::text('Found Lunch Punch Out: ' . TTDate::getDate('DATE+TIME', $plf->getCurrent()->getTimeStamp()), __FILE__, __LINE__, __METHOD__, 10); $total_lunch_time = $epoch - $plf->getCurrent()->getTimeStamp(); Debug::text('Total Lunch Time: ' . $total_lunch_time, __FILE__, __LINE__, __METHOD__, 10); //Set the ScheduleID $has_schedule = $this->setScheduleID($this->findScheduleID($epoch)); if ($has_schedule == TRUE and $round_policy_obj->getGrace() > 0 and is_object($this->getScheduleObject()->getSchedulePolicyObject()) and is_object($this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject())) { Debug::text(' Applying Grace Period: ', __FILE__, __LINE__, __METHOD__, 10); $total_lunch_time = TTDate::graceTime($total_lunch_time, $round_policy_obj->getGrace(), $this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getAmount()); Debug::text('After Grace: ' . $total_lunch_time, __FILE__, __LINE__, __METHOD__, 10); } if ($round_policy_obj->getInterval() > 0) { Debug::Text(' Rounding to interval: ' . $round_policy_obj->getInterval(), __FILE__, __LINE__, __METHOD__, 10); $total_lunch_time = TTDate::roundTime($total_lunch_time, $round_policy_obj->getInterval(), $round_policy_obj->getRoundType(), $round_policy_obj->getGrace()); Debug::text('After Rounding: ' . $total_lunch_time, __FILE__, __LINE__, __METHOD__, 10); } if ($has_schedule == TRUE and $round_policy_obj->getStrict() == TRUE and is_object($this->getScheduleObject()->getSchedulePolicyObject()) and is_object($this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject())) { Debug::Text(' Snap Time: Round Type: ' . $round_policy_obj->getRoundType(), __FILE__, __LINE__, __METHOD__, 10); if ($round_policy_obj->getRoundType() == 10) { Debug::Text(' Snap Time DOWN ', __FILE__, __LINE__, __METHOD__, 10); $total_lunch_time = TTDate::snapTime($total_lunch_time, $this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getAmount(), 'DOWN'); } elseif ($round_policy_obj->getRoundType() == 30) { Debug::Text(' Snap Time UP', __FILE__, __LINE__, __METHOD__, 10); $total_lunch_time = TTDate::snapTime($total_lunch_time, $this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getAmount(), 'UP'); } else { Debug::Text(' Not Snaping Time', __FILE__, __LINE__, __METHOD__, 10); } } $epoch = $plf->getCurrent()->getTimeStamp() + $total_lunch_time; Debug::text('Epoch after total rounding is: ' . $epoch . ' - ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); } else { Debug::text('DID NOT Find Lunch Punch Out: ' . TTDate::getDate('DATE+TIME', $plf->getCurrent()->getTimeStamp()), __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text('Skipping Lunch Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); } } elseif ($round_policy_obj->getPunchType() == 110) { //Break Total Debug::text('break Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); //On break Punch In (back from break) do the total rounding. if ($this->getStatus() == 10 and $this->getType() == 30) { Debug::text('bbreak Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); //If strict is set, round to scheduled break time? //Find break Punch In. $plf = new PunchListFactory(); //$plf->getPreviousPunchByUserDateIdAndStatusAndTypeAndEpoch( $this->getPunchControlObject()->getUserDateID(), 20, 30, $epoch ); $plf->getPreviousPunchByUserIdAndStatusAndTypeAndEpoch($this->getUser(), 20, 30, $epoch); if ($plf->getRecordCount() == 1) { Debug::text('Found break Punch Out: ' . TTDate::getDate('DATE+TIME', $plf->getCurrent()->getTimeStamp()), __FILE__, __LINE__, __METHOD__, 10); $total_break_time = $epoch - $plf->getCurrent()->getTimeStamp(); Debug::text('Total break Time: ' . $total_break_time, __FILE__, __LINE__, __METHOD__, 10); //Set the ScheduleID $has_schedule = $this->setScheduleID($this->findScheduleID($epoch)); if ($has_schedule == TRUE and $round_policy_obj->getGrace() > 0 and is_object($this->getScheduleObject()->getSchedulePolicyObject()) and is_object($this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject())) { Debug::text(' Applying Grace Period: ', __FILE__, __LINE__, __METHOD__, 10); $total_break_time = TTDate::graceTime($total_break_time, $round_policy_obj->getGrace(), $this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getAmount()); Debug::text('After Grace: ' . $total_break_time, __FILE__, __LINE__, __METHOD__, 10); } if ($round_policy_obj->getInterval() > 0) { Debug::Text(' Rounding to interval: ' . $round_policy_obj->getInterval(), __FILE__, __LINE__, __METHOD__, 10); $total_break_time = TTDate::roundTime($total_break_time, $round_policy_obj->getInterval(), $round_policy_obj->getRoundType(), $round_policy_obj->getGrace()); Debug::text('After Rounding: ' . $total_break_time, __FILE__, __LINE__, __METHOD__, 10); } if ($has_schedule == TRUE and $round_policy_obj->getStrict() == TRUE and is_object($this->getScheduleObject()->getSchedulePolicyObject()) and is_object($this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject())) { Debug::Text(' Snap Time: Round Type: ' . $round_policy_obj->getRoundType(), __FILE__, __LINE__, __METHOD__, 10); if ($round_policy_obj->getRoundType() == 10) { Debug::Text(' Snap Time DOWN ', __FILE__, __LINE__, __METHOD__, 10); $total_break_time = TTDate::snapTime($total_break_time, $this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getAmount(), 'DOWN'); } elseif ($round_policy_obj->getRoundType() == 30) { Debug::Text(' Snap Time UP', __FILE__, __LINE__, __METHOD__, 10); $total_break_time = TTDate::snapTime($total_break_time, $this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getAmount(), 'UP'); } else { Debug::Text(' Not Snaping Time', __FILE__, __LINE__, __METHOD__, 10); } } $epoch = $plf->getCurrent()->getTimeStamp() + $total_break_time; Debug::text('Epoch after total rounding is: ' . $epoch . ' - ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); } else { Debug::text('DID NOT Find break Punch Out: ' . TTDate::getDate('DATE+TIME', $plf->getCurrent()->getTimeStamp()), __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text('Skipping break Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); } } elseif ($round_policy_obj->getPunchType() == 120) { //Day Total Rounding Debug::text('Day Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); if ($this->getStatus() == 20 and $this->getType() == 10) { //Out, Type Normal Debug::text('bDay Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); //If strict is set, round to scheduled time? $plf = new PunchListFactory(); $plf->getPreviousPunchByUserIdAndEpochAndNotPunchIDAndMaximumShiftTime($this->getUser(), $epoch, $this->getId()); if ($plf->getRecordCount() == 1) { Debug::text('Found Previous Punch In: ' . TTDate::getDate('DATE+TIME', $plf->getCurrent()->getTimeStamp()), __FILE__, __LINE__, __METHOD__, 10); //Get day total time prior to this punch control. $pclf = new PunchControlListFactory(); $pclf->getByUserDateId($plf->getCurrent()->getPunchControlObject()->getUserDateID()); if ($pclf->getRecordCount() > 0) { $day_total_time = $epoch - $plf->getCurrent()->getTimeStamp(); Debug::text('aDay Total Time: ' . $day_total_time . ' Current Punch Control ID: ' . $this->getPunchControlID(), __FILE__, __LINE__, __METHOD__, 10); foreach ($pclf as $pc_obj) { if ($plf->getCurrent()->getPunchControlID() != $pc_obj->getID()) { Debug::text('Punch Control Total Time: ' . $pc_obj->getTotalTime() . ' ID: ' . $pc_obj->getId(), __FILE__, __LINE__, __METHOD__, 10); $day_total_time += $pc_obj->getTotalTime(); } } Debug::text('bDay Total Time: ' . $day_total_time, __FILE__, __LINE__, __METHOD__, 10); $original_day_total_time = $day_total_time; if ($day_total_time > 0) { //Set the ScheduleID $has_schedule = $this->setScheduleID($this->findScheduleID($epoch)); if ($has_schedule == TRUE and $round_policy_obj->getGrace() > 0 and is_object($this->getScheduleObject()->getSchedulePolicyObject()) and is_object($this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject())) { Debug::text(' Applying Grace Period: ', __FILE__, __LINE__, __METHOD__, 10); $day_total_time = TTDate::graceTime($day_total_time, $round_policy_obj->getGrace(), $this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getAmount()); Debug::text('After Grace: ' . $day_total_time, __FILE__, __LINE__, __METHOD__, 10); } if ($round_policy_obj->getInterval() > 0) { Debug::Text(' Rounding to interval: ' . $round_policy_obj->getInterval(), __FILE__, __LINE__, __METHOD__, 10); $day_total_time = TTDate::roundTime($day_total_time, $round_policy_obj->getInterval(), $round_policy_obj->getRoundType(), $round_policy_obj->getGrace()); Debug::text('After Rounding: ' . $day_total_time, __FILE__, __LINE__, __METHOD__, 10); } if ($has_schedule == TRUE and $round_policy_obj->getStrict() == TRUE and is_object($this->getScheduleObject()->getSchedulePolicyObject()) and is_object($this->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject())) { Debug::Text(' Snap Time: Round Type: ' . $round_policy_obj->getRoundType(), __FILE__, __LINE__, __METHOD__, 10); if ($round_policy_obj->getRoundType() == 10) { Debug::Text(' Snap Time DOWN ', __FILE__, __LINE__, __METHOD__, 10); $day_total_time = TTDate::snapTime($day_total_time, $this->getScheduleObject()->getTotalTime(), 'DOWN'); } elseif ($round_policy_obj->getRoundType() == 30) { Debug::Text(' Snap Time UP', __FILE__, __LINE__, __METHOD__, 10); $day_total_time = TTDate::snapTime($day_total_time, $this->getScheduleObject()->getTotalTime(), 'UP'); } else { Debug::Text(' Not Snaping Time', __FILE__, __LINE__, __METHOD__, 10); } } Debug::text('cDay Total Time: ' . $day_total_time, __FILE__, __LINE__, __METHOD__, 10); $day_total_time_diff = $day_total_time - $original_day_total_time; Debug::text('Day Total Diff: ' . $day_total_time_diff, __FILE__, __LINE__, __METHOD__, 10); $epoch = $original_epoch + $day_total_time_diff; } } } else { Debug::text('DID NOT Find Normal Punch Out: ' . TTDate::getDate('DATE+TIME', $plf->getCurrent()->getTimeStamp()), __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text('Skipping Lunch Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text('NOT Total Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); if ($this->inScheduleStartStopWindow($epoch) and $round_policy_obj->getGrace() > 0) { Debug::text(' Applying Grace Period: ', __FILE__, __LINE__, __METHOD__, 10); $epoch = TTDate::graceTime($epoch, $round_policy_obj->getGrace(), $this->getScheduleWindowTime()); Debug::text('After Grace: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); } $grace_time = $round_policy_obj->getGrace(); //If strict scheduling is enabled, handle grace times differently. //Only apply them above if we are near the schedule start/stop time. //This allows for grace time to apply if an employee punches in late, //but afterwards not apply at all. if ($round_policy_obj->getStrict() == TRUE) { $grace_time = 0; } if ($round_policy_obj->getInterval() > 0) { Debug::Text(' Rounding to interval: ' . $round_policy_obj->getInterval(), __FILE__, __LINE__, __METHOD__, 10); $epoch = TTDate::roundTime($epoch, $round_policy_obj->getInterval(), $round_policy_obj->getRoundType(), $grace_time); Debug::text('After Rounding: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10); } //ONLY perform strict rounding on Normal punches, not break/lunch punches? //Modify the UI to restrict this as well perhaps? if ($round_policy_obj->getStrict() == TRUE and $this->getScheduleWindowTime() !== FALSE) { Debug::Text(' Snap Time: Round Type: ' . $round_policy_obj->getRoundType(), __FILE__, __LINE__, __METHOD__, 10); if ($round_policy_obj->getRoundType() == 10) { Debug::Text(' Snap Time DOWN ', __FILE__, __LINE__, __METHOD__, 10); $epoch = TTDate::snapTime($epoch, $this->getScheduleWindowTime(), 'DOWN'); } elseif ($round_policy_obj->getRoundType() == 30) { Debug::Text(' Snap Time UP', __FILE__, __LINE__, __METHOD__, 10); $epoch = TTDate::snapTime($epoch, $this->getScheduleWindowTime(), 'UP'); } else { //If its an In Punch, snap up, if its out punch, snap down? Debug::Text(' Average rounding type, automatically determining snap direction.', __FILE__, __LINE__, __METHOD__, 10); if ($this->getStatus() == 10) { Debug::Text(' Snap Time UP', __FILE__, __LINE__, __METHOD__, 10); $epoch = TTDate::snapTime($epoch, $this->getScheduleWindowTime(), 'UP'); } else { Debug::Text(' Snap Time DOWN ', __FILE__, __LINE__, __METHOD__, 10); $epoch = TTDate::snapTime($epoch, $this->getScheduleWindowTime(), 'DOWN'); } } } } } else { Debug::text(' NO Rounding Policy(s) Found', __FILE__, __LINE__, __METHOD__, 10); } Debug::text(' Rounded TimeStamp: ' . TTDate::getDate('DATE+TIME', $epoch) . ' Original TimeStamp: ' . TTDate::getDate('DATE+TIME', $original_epoch), __FILE__, __LINE__, __METHOD__, 10); return $epoch; }