本文整理汇总了PHP中TTDate::doesRangeSpanMidnight方法的典型用法代码示例。如果您正苦于以下问题:PHP TTDate::doesRangeSpanMidnight方法的具体用法?PHP TTDate::doesRangeSpanMidnight怎么用?PHP TTDate::doesRangeSpanMidnight使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TTDate
的用法示例。
在下文中一共展示了TTDate::doesRangeSpanMidnight方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: getShiftData
//.........这里部分代码省略.........
$shift++;
}
}
if (!isset($shift_data[$shift]['total_time'])) {
$shift_data[$shift]['total_time'] = 0;
}
$punch_day_epoch = TTDate::getBeginDayEpoch($p_obj->getTimeStamp());
if (!isset($shift_data[$shift]['total_time_per_day'][$punch_day_epoch])) {
$shift_data[$shift]['total_time_per_day'][$punch_day_epoch] = 0;
}
//Determine which shift is closest to the given epoch.
$punch_difference_from_epoch = abs($epoch - $p_obj->getTimeStamp());
if ($nearest_punch_difference === FALSE or $punch_difference_from_epoch < $nearest_punch_difference) {
Debug::text('Nearest Shift Determined to be: ' . $shift . ' Nearest Punch Diff: ' . (int) $nearest_punch_difference . ' Punch Diff: ' . $punch_difference_from_epoch, __FILE__, __LINE__, __METHOD__, 10);
$nearest_shift_id = $shift;
$nearest_punch_difference = $punch_difference_from_epoch;
}
$punch_arr = array('id' => $p_obj->getId(), 'punch_control_id' => $p_obj->getPunchControlId(), 'user_date_id' => $punch_control_obj->getUserDateID(), 'time_stamp' => $p_obj->getTimeStamp(), 'status_id' => $p_obj->getStatus(), 'type_id' => $p_obj->getType());
$shift_data[$shift]['punches'][] = $punch_arr;
$shift_data[$shift]['punch_control_ids'][] = $p_obj->getPunchControlId();
if ($punch_control_obj->getUserDateID() != FALSE) {
$shift_data[$shift]['user_date_ids'][] = $punch_control_obj->getUserDateID();
}
$shift_data[$shift]['span_midnight'] = FALSE;
if (!isset($shift_data[$shift]['first_in']) and $p_obj->getStatus() == 10) {
//Debug::text('First In -- Punch ID: '. $p_obj->getID() .' Punch Control ID: '. $p_obj->getPunchControlID() .' TimeStamp: '. TTDate::getDate('DATE+TIME', $p_obj->getTimeStamp() ), __FILE__, __LINE__, __METHOD__, 10);
$shift_data[$shift]['first_in'] = $punch_arr;
} elseif ($p_obj->getStatus() == 20) {
//Debug::text('Last Out -- Punch ID: '. $p_obj->getID() .' Punch Control ID: '. $p_obj->getPunchControlID() .' TimeStamp: '. TTDate::getDate('DATE+TIME', $p_obj->getTimeStamp() ), __FILE__, __LINE__, __METHOD__, 10);
$shift_data[$shift]['last_out'] = $punch_arr;
//Debug::text('Total Time: '. $total_time, __FILE__, __LINE__, __METHOD__, 10);
$shift_data[$shift]['total_time'] += $total_time;
//Check to see if the previous punch was on a different day then the current punch.
if (isset($prev_punch_arr) and is_array($prev_punch_arr) and ($p_obj->getStatus() == 20 and $prev_punch_arr['status_id'] != 20) and TTDate::doesRangeSpanMidnight($prev_punch_arr['time_stamp'], $p_obj->getTimeStamp()) == TRUE) {
Debug::text('Punch pair DOES span midnight', __FILE__, __LINE__, __METHOD__, 10);
$shift_data[$shift]['span_midnight'] = TRUE;
$total_time_for_each_day_arr = TTDate::calculateTimeOnEachDayBetweenRange($prev_punch_arr['time_stamp'], $p_obj->getTimeStamp());
if (is_array($total_time_for_each_day_arr)) {
foreach ($total_time_for_each_day_arr as $begin_day_epoch => $day_total_time) {
if (!isset($shift_data[$shift]['total_time_per_day'][$begin_day_epoch])) {
$shift_data[$shift]['total_time_per_day'][$begin_day_epoch] = 0;
}
$shift_data[$shift]['total_time_per_day'][$begin_day_epoch] += $day_total_time;
}
}
unset($total_time_for_each_day_arr, $begin_day_epoch, $day_total_time, $prev_day_total_time);
} else {
$shift_data[$shift]['total_time_per_day'][$punch_day_epoch] += $total_time;
}
}
$prev_punch_arr = $punch_arr;
$i++;
}
//Debug::Arr($shift_data, 'aShift Data:', __FILE__, __LINE__, __METHOD__, 10);
if (isset($shift_data)) {
//Loop through each shift to determine the day with the most time.
foreach ($shift_data as $tmp_shift_key => $tmp_shift_data) {
krsort($shift_data[$tmp_shift_key]['total_time_per_day']);
//Sort by day first
arsort($shift_data[$tmp_shift_key]['total_time_per_day']);
//Sort by total time per day.
reset($shift_data[$tmp_shift_key]['total_time_per_day']);
$shift_data[$tmp_shift_key]['day_with_most_time'] = key($shift_data[$tmp_shift_key]['total_time_per_day']);
$shift_data[$tmp_shift_key]['punch_control_ids'] = array_unique($shift_data[$tmp_shift_key]['punch_control_ids']);
if (isset($shift_data[$tmp_shift_key]['user_date_ids'])) {
$shift_data[$tmp_shift_key]['user_date_ids'] = array_unique($shift_data[$tmp_shift_key]['user_date_ids']);
示例2: preSave
function preSave()
{
if ($this->isNew()) {
//Debug::text(' Setting Original TimeStamp: '. $this->getTimeStamp(), __FILE__, __LINE__, __METHOD__,10);
$this->setOriginalTimeStamp($this->getTimeStamp());
}
if ($this->getDeleted() == FALSE) {
if ($this->getTransfer() == TRUE and $this->getEnableAutoTransfer() == TRUE) {
Debug::text(' Transfer is Enabled, automatic punch out of last punch pair: ', __FILE__, __LINE__, __METHOD__, 10);
//Check to make sure there is an open punch pair.
$plf = new PunchListFactory();
$plf->getPreviousPunchByUserIdAndEpoch($this->getUser(), $this->getTimeStamp());
if ($plf->getRecordCount() > 0) {
$p_obj = $plf->getCurrent();
Debug::text(' Found Last Punch: ', __FILE__, __LINE__, __METHOD__, 10);
if ($p_obj->getStatus() == 10) {
Debug::text(' Last Punch was in. Auto Punch Out now: ', __FILE__, __LINE__, __METHOD__, 10);
//Make sure the current punch status is IN
$this->setStatus(10);
//In
$this->setType(10);
//Normal (can't transfer in/out of lunches?)
$pf = new PunchFactory();
$pf->setUser($this->getUser());
$pf->setEnableAutoTransfer(FALSE);
$pf->setPunchControlID($p_obj->getPunchControlID());
$pf->setTransfer(TRUE);
$pf->setType($p_obj->getNextType());
$pf->setStatus(20);
//Out
$pf->setTimeStamp($this->getTimeStamp(), FALSE);
//Disable rounding.
$pf->setActualTimeStamp($this->getTimeStamp());
$pf->setOriginalTimeStamp($this->getTimeStamp());
if ($pf->isValid()) {
if ($pf->Save(FALSE) == TRUE) {
$p_obj->getPunchControlObject()->setEnableCalcTotalTime(TRUE);
$p_obj->getPunchControlObject()->setEnableCalcSystemTotalTime(TRUE);
$p_obj->getPunchControlObject()->setEnableCalcUserDateTotal(TRUE);
$p_obj->getPunchControlObject()->setEnableCalcException(TRUE);
$p_obj->getPunchControlObject()->setEnablePreMatureException(TRUE);
if ($p_obj->getPunchControlObject()->isValid()) {
$p_obj->getPunchControlObject()->Save();
} else {
Debug::text(' aError saving auto out punch...', __FILE__, __LINE__, __METHOD__, 10);
}
} else {
Debug::text(' bError saving auto out punch...', __FILE__, __LINE__, __METHOD__, 10);
}
} else {
Debug::text(' cError saving auto out punch...', __FILE__, __LINE__, __METHOD__, 10);
}
} else {
Debug::text(' Last Punch was out. No Auto Punch ', __FILE__, __LINE__, __METHOD__, 10);
}
}
unset($plf, $p_obj, $pf);
}
//Split punch at midnight.
//This has to be an Out punch, and the previous punch has to be an in punch in order for the split to occur.
//Check to make sure there is an open punch pair.
//Make sure this punch isn't right at midnight either, as no point in splitting a punch at that time.
//FIXME: What happens if a supervisor edits a 11:30PM punch and makes it 5:00AM the next day?
// We can't split punches when editing, because we have to split punch_control_ids prior to saving etc...
if ($this->isNew() == TRUE and $this->getStatus() == 20 and $this->getEnableSplitAtMidnight() == TRUE and $this->getTimeStamp() != TTDate::getBeginDayEpoch($this->getTimeStamp()) and (is_object($this->getPunchControlObject()) and is_object($this->getPunchControlObject()->getPayPeriodScheduleObject()) and $this->getPunchControlObject()->getPayPeriodScheduleObject()->getShiftAssignedDay() == 40)) {
$plf = new PunchListFactory();
$plf->getPreviousPunchByUserIdAndEpoch($this->getUser(), $this->getTimeStamp());
if ($plf->getRecordCount() > 0) {
$p_obj = $plf->getCurrent();
Debug::text(' Found Last Punch: ', __FILE__, __LINE__, __METHOD__, 10);
if ($p_obj->getStatus() == 10 and TTDate::doesRangeSpanMidnight($this->getTimeStamp(), $p_obj->getTimeStamp())) {
Debug::text(' Last Punch was in and this is an out punch that spans midnight. Split Punch at midnight now: ', __FILE__, __LINE__, __METHOD__, 10);
//FIXME: This will fail if a shift spans multiple days!
//Make sure the current punch status is OUT
//But we can split LUNCH/Break punches, because someone could punch in at 8PM, then out for lunch at 1:00AM, this would need to be split.
$this->setStatus(20);
//Out
//Reduce the out punch by 60 seconds, and increase the current punch by 60seconds so no time is lost.
$this->setTimeStamp($this->getTimeStamp() + 60);
//FIXME: May need to use ActualTimeStamp here so we aren't double rounding.
//Get new punch control ID for the midnight punch and this one.
$new_punch_control_id = $this->getPunchControlObject()->getNextInsertId();
$this->setPunchControlID($new_punch_control_id);
Debug::text(' Split Punch: Punching out just before midnight yesterday...', __FILE__, __LINE__, __METHOD__, 10);
//
//Punch out just before midnight
//
$pf = new PunchFactory();
$pf->setUser($this->getUser());
$pf->setEnableSplitAtMidnight(FALSE);
$pf->setTransfer(FALSE);
$pf->setEnableAutoTransfer(FALSE);
$pf->setType(10);
//Normal
$pf->setStatus(20);
//Out
$before_midnight_timestamp = TTDate::getBeginDayEpoch($this->getTimeStamp()) - 60;
$pf->setTimeStamp($before_midnight_timestamp, FALSE);
//Disable rounding.
$pf->setActualTimeStamp($before_midnight_timestamp);
//.........这里部分代码省略.........
示例3: getShiftData
function getShiftData($user_date_id = NULL, $user_id = NULL, $epoch = NULL, $filter = NULL, $tmp_punch_control_obj = NULL, $maximum_shift_time = NULL, $new_shift_trigger_time = NULL, $plf = NULL)
{
global $profiler;
$profiler->startTimer('PayPeriodScheduleFactory::getShiftData()');
if (is_numeric($user_date_id) and $user_date_id > 0) {
$user_id = $epoch = NULL;
}
if ($user_date_id == '' and $user_id == '' and $epoch == '') {
return FALSE;
}
if ($maximum_shift_time === NULL) {
$maximum_shift_time = $this->getMaximumShiftTime();
}
//Debug::text('User Date ID: '. $user_date_id .' User ID: '. $user_id .' TimeStamp: '. TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10);
if ($new_shift_trigger_time === NULL) {
$new_shift_trigger_time = $this->getNewDayTriggerTime();
}
if (!is_object($plf)) {
$plf = TTnew('PunchListFactory');
if ($user_date_id != '') {
$plf->getByUserDateId($user_date_id);
} else {
//Get punches by time stamp.
$punch_control_id = 0;
if (is_object($tmp_punch_control_obj)) {
$punch_control_id = $tmp_punch_control_obj->getId();
}
//We need to double the maximum shift time when searching for punches.
//Assuming a maximum punch time of 14hrs:
// In: 10:00AM Out: 2:00PM
// In: 6:00PM Out: 6:00AM (next day)
// The above scenario when adding the last 6:00AM punch on the next day will only look back 14hrs and not find the first
// punch pair, therefore allowing more than 14hrs on the same day.
// So we need to extend the maximum shift time just when searching for punches and let getShiftData() sort out the proper maximum shift time itself.
$plf->getShiftPunchesByUserIDAndEpoch($user_id, $epoch, $punch_control_id, $maximum_shift_time * 2);
unset($punch_control_id);
}
}
Debug::text('Punch Rows: ' . $plf->getRecordCount() . ' UserID: ' . $user_id . ' Date: ' . TTDate::getDate('DATE+TIME', $epoch) . '(' . $epoch . ') MaximumShiftTime: ' . $maximum_shift_time . ' Filter: ' . $filter, __FILE__, __LINE__, __METHOD__, 10);
if ($plf->getRecordCount() > 0) {
$shift = 0;
$i = 0;
$nearest_shift_id = 0;
$nearest_punch_difference = FALSE;
$prev_punch_obj = FALSE;
foreach ($plf as $p_obj) {
//Debug::text('Shift: '. $shift .' Punch ID: '. $p_obj->getID() .' Punch Control ID: '. $p_obj->getPunchControlID() .' TimeStamp: '. TTDate::getDate('DATE+TIME', $p_obj->getTimeStamp() ), __FILE__, __LINE__, __METHOD__, 10);
//If we're editing a punch, we need to use the object passed to this function instead of the one
//from the database.
if ($epoch == NULL) {
//If user_date_id is passed without epoch, set epoch to the first punch we find.
$epoch = $p_obj->getTimeStamp();
}
if (isset($prev_punch_arr) and $p_obj->getTimeStamp() > $prev_punch_arr['time_stamp']) {
$shift_data[$shift]['previous_punch_key'] = $i - 1;
if ($shift_data[$shift]['previous_punch_key'] < 0) {
$shift_data[$shift]['previous_punch_key'] = NULL;
}
}
//Determine if a non-saved PunchControl object was passed, and if so, match the IDs to use that instead.
if (is_object($tmp_punch_control_obj) and $p_obj->getPunchControlID() == $tmp_punch_control_obj->getId()) {
Debug::text('Passed non-saved punch control object that matches, using that instead... Using ID: ' . (int) $tmp_punch_control_obj->getId(), __FILE__, __LINE__, __METHOD__, 10);
$punch_control_obj = $tmp_punch_control_obj;
} else {
$punch_control_obj = $p_obj->getPunchControlObject();
}
//Can't use PunchControl object total_time because the record may not be saved yet when editing
//an already existing punch.
//When editing, simply pass the existing PunchControl object to this function so we can
//use it instead of the one in the database perhaps?
$total_time = $punch_control_obj->getTotalTime();
//We can't skip records with total_time == 0, because then when deleting one of the two
//punches in a pair, the remaining punch is ignored and causing punches to jump around between days in some cases.
if ($i > 0 and isset($shift_data[$shift]['last_out']) and ($p_obj->getStatus() == 10 or $p_obj->getStatus() == $prev_punch_arr['status_id'])) {
Debug::text('Checking for new shift... This Control ID: ' . $p_obj->getPunchControlID() . ' Last Out Control ID: ' . $shift_data[$shift]['last_out']['punch_control_id'] . ' Last Out Time: ' . TTDate::getDate('DATE+TIME', $shift_data[$shift]['last_out']['time_stamp']), __FILE__, __LINE__, __METHOD__, 10);
//Assume that if two punches are assigned to the same punch_control_id are the same shift, even if the time between
//them exceeds the new_shift_trigger_time. This helps fix the bug where you could add a In punch then add a Out
//punch BEFORE the In punch as long as it was more than the Maximum Shift Time before the In Punch.
//ie: Add: In Punch 10-Dec-09 @ 8:00AM, Add: Out Punch 09-Dec-09 @ 5:00PM.
//Basically it just helps the validation checks to determine the error.
//
//It used to be that if shifts are split at midnight, new_shift_trigger_time must be 0, so the "split" punch can occur at midnight.
//However we have since added a check to see if punches span midnight and trigger a new shift based on that, regardless of the new shift trigger time.
//As the new_shift_trigger_time of 0 also affected lunch/break automatic detection by Punch Time, since an Out punch and a In punch of any time
//would trigger a new shift, and it wouldn't be detected as lunch/break.
//
//What happens when the employee takes lunch/break over midnight? Lunch out at 11:30PM Lunch IN at 12:30AM
// We need to split those into two lunches, or two breaks? But then that can affect those policies if they are only allowed one break.
// Or do we not split the shift at all when this occurs? Currently we don't split at all.
if ($p_obj->getPunchControlID() != $shift_data[$shift]['last_out']['punch_control_id'] and ($p_obj->getTimeStamp() - $shift_data[$shift]['last_out']['time_stamp'] >= $new_shift_trigger_time or $this->getShiftAssignedDay() == 40 and $p_obj->getType() == 10 and $shift_data[$shift]['last_out']['type_id'] == 10 and TTDate::doesRangeSpanMidnight($shift_data[$shift]['last_out']['time_stamp'], $p_obj->getTimeStamp(), TRUE) == TRUE)) {
$shift++;
}
} elseif ($i > 0 and isset($prev_punch_arr['time_stamp']) and $prev_punch_arr['punch_control_id'] != $p_obj->getPunchControlId() and abs($prev_punch_arr['time_stamp'] - $p_obj->getTimeStamp()) > $maximum_shift_time) {
//Debug::text(' New shift because two punch_control records exist and punch timestamp exceed maximum shift time.', __FILE__, __LINE__, __METHOD__, 10);
$shift++;
}
if (!isset($shift_data[$shift]['total_time'])) {
$shift_data[$shift]['total_time'] = 0;
}
$punch_day_epoch = TTDate::getBeginDayEpoch($p_obj->getTimeStamp());
//.........这里部分代码省略.........
示例4: calculateTimeOnEachDayBetweenRange
public static function calculateTimeOnEachDayBetweenRange($start_epoch, $end_epoch)
{
if (TTDate::doesRangeSpanMidnight($start_epoch, $end_epoch) == TRUE) {
$total_before_first_midnight = TTDate::getEndDayEpoch($start_epoch) + 1 - $start_epoch;
if ($total_before_first_midnight > 0) {
$retval[TTDate::getBeginDayEpoch($start_epoch)] = $total_before_first_midnight;
}
$loop_start = TTDate::getEndDayEpoch($start_epoch) + 1;
$loop_end = TTDate::getBeginDayEpoch($end_epoch);
for ($x = $loop_start; $x < $loop_end; $x += 86400) {
$retval[TTDate::getBeginDayEpoch($x)] = 86400;
}
$total_after_last_midnight = $end_epoch - TTDate::getBeginDayEpoch($end_epoch);
if ($total_after_last_midnight > 0) {
$retval[TTDate::getBeginDayEpoch($end_epoch)] = $total_after_last_midnight;
}
} else {
$retval = array(TTDate::getBeginDayEpoch($start_epoch) => $end_epoch - $start_epoch);
}
return $retval;
}
示例5: calcExceptions
static function calcExceptions($user_date_id, $enable_premature_exceptions = FALSE, $enable_future_exceptions = TRUE)
{
global $profiler;
$profiler->startTimer("ExceptionPolicy::calcExceptions()");
if ($user_date_id == '') {
return FALSE;
}
Debug::text(' User Date ID: ' . $user_date_id . ' PreMature: ' . (int) $enable_premature_exceptions, __FILE__, __LINE__, __METHOD__, 10);
$current_epoch = TTDate::getTime();
//Get user date info
$udlf = TTnew('UserDateListFactory');
$udlf->getById($user_date_id);
if ($udlf->getRecordCount() > 0) {
$user_date_obj = $udlf->getCurrent();
if ($enable_future_exceptions == FALSE and $user_date_obj->getDateStamp() > TTDate::getEndDayEpoch($current_epoch)) {
return FALSE;
}
} else {
return FALSE;
}
//16hrs... If punches are older then this time, its no longer premature.
//This should actually be the PayPeriod Schedule maximum shift time.
if (is_object($user_date_obj->getPayPeriodObject()) and is_object($user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject())) {
self::$premature_delay = $user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject()->getMaximumShiftTime();
Debug::text(' Setting preMature Exception delay to maximum shift time: ' . self::$premature_delay, __FILE__, __LINE__, __METHOD__, 10);
} else {
self::$premature_delay = 57600;
}
//Get list of existing exceptions, so we can determine if we need to delete any. We can't delete them all blindly and re-create them
//as this will send duplicate email notifications for every single punch.
$existing_exceptions = array();
$elf = TTnew('ExceptionListFactory');
$elf->getByUserDateID($user_date_id);
if ($elf->getRecordCount() > 0) {
foreach ($elf as $e_obj) {
$existing_exceptions[] = array('id' => $e_obj->getId(), 'user_date_id' => $e_obj->getUserDateID(), 'exception_policy_id' => $e_obj->getExceptionPolicyID(), 'type_id' => $e_obj->getType(), 'punch_id' => $e_obj->getPunchID(), 'punch_control_id' => $e_obj->getPunchControlID());
}
}
unset($elf, $e_obj);
//Get all Punches on this date for this user.
$plf = TTnew('PunchListFactory');
$plf->getByUserDateId($user_date_id);
if ($plf->getRecordCount() > 0) {
Debug::text(' Found Punches: ' . $plf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
}
$slf = TTnew('ScheduleListFactory');
$slf->getByUserDateIdAndStatusId($user_date_id, 10);
if ($slf->getRecordCount() > 0) {
Debug::text(' Found Schedule: ' . $slf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
}
$schedule_id_cache = NULL;
//Cache schedule IDs so we don't need to do a lookup for every exception.
$current_exceptions = array();
//Array holding current exception data.
//Get all active exceptions.
$eplf = TTnew('ExceptionPolicyListFactory');
$eplf->getByPolicyGroupUserIdAndActive($user_date_obj->getUser(), TRUE);
if ($eplf->getRecordCount() > 0) {
Debug::text(' Found Active Exceptions: ' . $eplf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
foreach ($eplf as $ep_obj) {
//Debug::text(' Found Exception Type: '. $ep_obj->getType() .' ID: '. $ep_obj->getID() .' Control ID: '. $ep_obj->getExceptionPolicyControl(), __FILE__, __LINE__, __METHOD__,10);
if ($enable_premature_exceptions == TRUE and self::isPreMature($ep_obj->getType()) == TRUE) {
//Debug::text(' Premature Exception: '. $ep_obj->getType() , __FILE__, __LINE__, __METHOD__,10);
$type_id = 5;
//Pre-Mature
} else {
//Debug::text(' NOT Premature Exception: '. $ep_obj->getType() , __FILE__, __LINE__, __METHOD__,10);
$type_id = 50;
//Active
}
switch (strtolower($ep_obj->getType())) {
case 's1':
//Unscheduled Absence... Anytime they are scheduled and have not punched in.
//Ignore these exceptions if the schedule is after today (not including today),
//so if a supervisors schedules an employee two days in advance they don't get a unscheduled
//absence appearing right away.
//Since we now trigger In Late/Out Late exceptions immediately after schedule time, only trigger this exception after
//the schedule end time has passed.
//**We also need to handle shifts that start at 11:00PM on one day, end at 8:00AM the next day, and they are assigned to the day where
//the most time is worked (ie: the next day).
//Handle split shifts too...
//- This has a side affect that if the schedule policy start/stop time is set to 0, it will trigger both a UnScheduled Absence
// and a Not Scheduled exception for the same schedule/punch.
//Loop through all schedules, then find punches to match.
if ($slf->getRecordCount() > 0) {
foreach ($slf as $s_obj) {
if ($s_obj->getStatus() == 10 and $current_epoch >= $s_obj->getEndTime()) {
$add_exception = TRUE;
//Debug::text(' Found Schedule: Start Time: '. TTDate::getDate('DATE+TIME', $s_obj->getStartTime() ), __FILE__, __LINE__, __METHOD__,10);
//Find punches that fall within this schedule time including start/stop window.
if (TTDate::doesRangeSpanMidnight($s_obj->getStartTime(), $s_obj->getEndTime()) and is_object($user_date_obj) and is_object($user_date_obj->getPayPeriodObject()) and is_object($user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject())) {
//Get punches from both days.
$plf_tmp = TTnew('PunchListFactory');
$plf_tmp->getShiftPunchesByUserIDAndEpoch($user_date_obj->getUser(), $s_obj->getStartTime(), 0, $user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject()->getMaximumShiftTime());
Debug::text(' Schedule spans midnight... Found rows from expanded search: ' . $plf_tmp->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
if ($plf_tmp->getRecordCount() > 0) {
foreach ($plf_tmp as $p_obj_tmp) {
if ($s_obj->inSchedule($p_obj_tmp->getTimeStamp())) {
Debug::text(' aFound punch for schedule...', __FILE__, __LINE__, __METHOD__, 10);
$add_exception = FALSE;
//.........这里部分代码省略.........
示例6: preSave
function preSave()
{
if ($this->isNew()) {
Debug::text(' Setting Original TimeStamp: ' . $this->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
$this->setOriginalTimeStamp($this->getTimeStamp());
}
if ($this->getDeleted() == FALSE) {
if ($this->isNew() and $this->getTransfer() == TRUE and $this->getEnableAutoTransfer() == TRUE) {
Debug::text(' Transfer is Enabled, automatic punch out of last punch pair...', __FILE__, __LINE__, __METHOD__, 10);
//Use actual time stamp, not rounded timestamp. This should only be called on new punches as well, otherwise Actual Time Stamp could be incorrect.
$p_obj = $this->getPreviousPunchObject($this->getActualTimeStamp());
if (is_object($p_obj)) {
Debug::text(' Found Last Punch: ', __FILE__, __LINE__, __METHOD__, 10);
if ($p_obj->getStatus() == 10) {
Debug::text(' Last Punch was in. Auto Punch Out now: ', __FILE__, __LINE__, __METHOD__, 10);
//Make sure the current punch status is IN
$this->setStatus(10);
//In
$this->setType(10);
//Normal (can't transfer in/out of lunches?)
$pf = TTnew('PunchFactory');
$pf->setUser($this->getUser());
$pf->setEnableAutoTransfer(FALSE);
$pf->setPunchControlID($p_obj->getPunchControlID());
$pf->setTransfer(TRUE);
$pf->setType($p_obj->getNextType());
$pf->setStatus(20);
//Out
$pf->setTimeStamp($this->getTimeStamp(), FALSE);
//Disable rounding.
$pf->setActualTimeStamp($this->getTimeStamp());
//$pf->setOriginalTimeStamp( $this->getTimeStamp() ); //set in preSave()
$pf->setLongitude($this->getLongitude());
$pf->setLatitude($this->getLatitude());
if ($pf->isValid()) {
if ($pf->Save(FALSE) == TRUE) {
$p_obj->getPunchControlObject()->setEnableCalcTotalTime(TRUE);
$p_obj->getPunchControlObject()->setEnableCalcSystemTotalTime(TRUE);
$p_obj->getPunchControlObject()->setEnableCalcUserDateTotal(TRUE);
$p_obj->getPunchControlObject()->setEnableCalcException(TRUE);
$p_obj->getPunchControlObject()->setEnablePreMatureException(TRUE);
if ($p_obj->getPunchControlObject()->isValid()) {
$p_obj->getPunchControlObject()->Save();
} else {
Debug::text(' aError saving auto out punch...', __FILE__, __LINE__, __METHOD__, 10);
}
} else {
Debug::text(' bError saving auto out punch...', __FILE__, __LINE__, __METHOD__, 10);
}
} else {
Debug::text(' cError saving auto out punch...', __FILE__, __LINE__, __METHOD__, 10);
}
} else {
Debug::text(' Last Punch was out. No Auto Punch out needed, removing transfer flag from this punch...', __FILE__, __LINE__, __METHOD__, 10);
$this->setTransfer(FALSE);
}
}
unset($p_obj, $pf);
}
//Split punch at midnight.
//This has to be an Out punch, and the previous punch has to be an in punch in order for the split to occur.
//Check to make sure there is an open punch pair.
//Make sure this punch isn't right at midnight either, as no point in splitting a punch at that time.
//FIXME: What happens if a supervisor edits a 11:30PM punch and makes it 5:00AM the next day?
// We can't split punches when editing existing punches, because we have to split punch_control_ids prior to saving etc...
// But we can split when supervisors are adding new punches.
//Debug::text('Split at Midnight Enabled: '. $this->getEnableSplitAtMidnight() .' IsNew: '. $this->isNew() .' Status: '. $this->getStatus() .' TimeStamp: '. $this->getTimeStamp() .' Punch Control ID: '. $this->getPunchControlID(), __FILE__, __LINE__, __METHOD__,10);
if ($this->isNew() == TRUE and $this->getStatus() == 20 and $this->getEnableSplitAtMidnight() == TRUE and $this->getTimeStamp() != TTDate::getBeginDayEpoch($this->getTimeStamp()) and (is_object($this->getPunchControlObject()) and is_object($this->getPunchControlObject()->getPayPeriodScheduleObject()) and $this->getPunchControlObject()->getPayPeriodScheduleObject()->getShiftAssignedDay() == 40)) {
$plf = TTnew('PunchListFactory');
$plf->getPreviousPunchByUserIdAndEpoch($this->getUser(), $this->getTimeStamp());
if ($plf->getRecordCount() > 0) {
$p_obj = $plf->getCurrent();
Debug::text(' Found Last Punch... ID: ' . $p_obj->getId() . ' Timestamp: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
if ($p_obj->getStatus() == 10 and TTDate::doesRangeSpanMidnight($this->getTimeStamp(), $p_obj->getTimeStamp())) {
Debug::text(' Last Punch was in and this is an out punch that spans midnight. Split Punch at midnight now: ', __FILE__, __LINE__, __METHOD__, 10);
//FIXME: This will fail if a shift spans multiple days!
//Make sure the current punch status is OUT
//But we can split LUNCH/Break punches, because someone could punch in at 8PM, then out for lunch at 1:00AM, this would need to be split.
$this->setStatus(20);
//Out
//Reduce the out punch by 60 seconds, and increase the current punch by 60seconds so no time is lost.
$this->setTimeStamp($this->getTimeStamp());
//FIXME: May need to use ActualTimeStamp here so we aren't double rounding.
//Get new punch control ID for the midnight punch and this one.
$new_punch_control_id = $this->getPunchControlObject()->getNextInsertId();
//Since we need to change the PunchControlID, copy the current punch_control object to work around getGenericObject() checking the
//IDs and not returning the object anymore.
$tmp_punch_control_obj = $this->getPunchControlObject();
$this->setPunchControlID($new_punch_control_id);
Debug::text(' Split Punch: Punching out just before midnight yesterday...', __FILE__, __LINE__, __METHOD__, 10);
//
//Punch out just before midnight
//The issue with this is that if rounding is enabled this will ignore it, and the shift for this day may total: 3.98hrs.
//when they want it to total 4.00hrs. Why don't we split shifts at exactly midnight with no gap at all?
//Split shifts right at midnight causes additional issues when editing those punches, TimeTrex will want to combine them on the same day again.
$pf = TTnew('PunchFactory');
$pf->setUser($this->getUser());
$pf->setEnableSplitAtMidnight(FALSE);
$pf->setTransfer(FALSE);
$pf->setEnableAutoTransfer(FALSE);
//.........这里部分代码省略.........