static function smartReCalculate($user_id, $user_date_ids, $enable_exception = TRUE, $enable_premature_exceptions = FALSE, $enable_future_exceptions = TRUE) { if ($user_id == '') { return FALSE; } //Debug::Arr($user_date_ids, 'aUser Date IDs: ', __FILE__, __LINE__, __METHOD__, 10); if (!is_array($user_date_ids) and is_numeric($user_date_ids) and $user_date_ids > 0) { $user_date_ids = array($user_date_ids); } if (!is_array($user_date_ids)) { Debug::Text('Returning FALSE... User Date IDs not an array...', __FILE__, __LINE__, __METHOD__, 10); return FALSE; } $user_date_ids = array_unique($user_date_ids); //Debug::Arr($user_date_ids, 'bUser Date IDs: ', __FILE__, __LINE__, __METHOD__, 10); $start_week_day_id = 0; $ppslf = TTnew('PayPeriodScheduleListFactory'); $ppslf->getByUserId($user_id); if ($ppslf->getRecordCount() == 1) { $pps_obj = $ppslf->getCurrent(); $start_week_day_id = $pps_obj->getStartWeekDay(); } Debug::text('Start Week Day ID: ' . $start_week_day_id, __FILE__, __LINE__, __METHOD__, 10); //Get date stamps for all user_date_ids. $udlf = TTnew('UserDateListFactory'); $udlf->getByIds($user_date_ids, NULL, array('date_stamp' => 'asc')); //Order by date asc if ($udlf->getRecordCount() > 0) { //Order them, and get the one or more sets of date ranges that need to be recalculated. //Need to consider re-calculating multiple weeks at once. $i = 0; foreach ($udlf as $ud_obj) { $start_week_epoch = TTDate::getBeginWeekEpoch($ud_obj->getDateStamp(), $start_week_day_id); $end_week_epoch = TTDate::getEndWeekEpoch($ud_obj->getDateStamp(), $start_week_day_id); Debug::text('Current Date: ' . TTDate::getDate('DATE', $ud_obj->getDateStamp()) . ' Start Week: ' . TTDate::getDate('DATE', $start_week_epoch) . ' End Week: ' . TTDate::getDate('DATE', $end_week_epoch), __FILE__, __LINE__, __METHOD__, 10); if ($i == 0) { $range_arr[$start_week_epoch] = array('start_date' => $ud_obj->getDateStamp(), 'end_date' => $end_week_epoch); } else { //Loop through each range extending it if needed. foreach ($range_arr as $tmp_start_week_epoch => $tmp_range) { if ($ud_obj->getDateStamp() >= $tmp_range['start_date'] and $ud_obj->getDateStamp() <= $tmp_range['end_date']) { //Date falls within already existing range continue; } elseif ($ud_obj->getDateStamp() < $tmp_range['start_date'] and $ud_obj->getDateStamp() >= $tmp_start_week_epoch) { //Date falls within the same week, but before the current start date. $range_arr[$tmp_start_week_epoch]['start_date'] = $ud_obj->getDateStamp(); Debug::text('Pushing Start Date back...', __FILE__, __LINE__, __METHOD__, 10); } else { //Outside current range. Check to make sure it isn't within another range. if (isset($range_arr[$start_week_epoch])) { //Within another existing week, check to see if we need to extend it. if ($ud_obj->getDateStamp() < $range_arr[$start_week_epoch]['start_date']) { Debug::text('bPushing Start Date back...', __FILE__, __LINE__, __METHOD__, 10); $range_arr[$start_week_epoch]['start_date'] = $ud_obj->getDateStamp(); } } else { //Not within another existing week Debug::text('Adding new range...', __FILE__, __LINE__, __METHOD__, 10); $range_arr[$start_week_epoch] = array('start_date' => $ud_obj->getDateStamp(), 'end_date' => $end_week_epoch); } } } unset($tmp_range, $tmp_start_week_epoch); } $i++; } unset($start_week_epoch, $end_week_epoch, $udlf, $ud_obj); if (is_array($range_arr)) { ksort($range_arr); //Sort range by start week, so recalculating goes in date order. //Debug::Arr($range_arr, 'Range Array: ', __FILE__, __LINE__, __METHOD__, 10); foreach ($range_arr as $week_range) { $udlf = TTnew('UserDateListFactory'); $udlf->getByUserIdAndStartDateAndEndDate($user_id, $week_range['start_date'], $week_range['end_date']); if ($udlf->getRecordCount() > 0) { Debug::text('Found days to re-calculate: ' . $udlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); $udlf->StartTransaction(); $z = 1; $z_max = $udlf->getRecordCount(); foreach ($udlf as $ud_obj) { //We only need to re-calculate exceptions on the exact days specified by user_date_ids. //This was the case before we Over Weekly Time/Over Scheduled Weekly Time exceptions, //Now we have to enable calculating exceptions for the entire week. Debug::text('Re-calculating day with exceptions: ' . $ud_obj->getId(), __FILE__, __LINE__, __METHOD__, 10); if ($z == $z_max) { //Enable recalculating holidays at the end of each week. UserDateTotalFactory::reCalculateDay($ud_obj->getId(), $enable_exception, $enable_premature_exceptions, $enable_future_exceptions, TRUE); } else { UserDateTotalFactory::reCalculateDay($ud_obj->getId(), $enable_exception, $enable_premature_exceptions, $enable_future_exceptions); } $z++; } $udlf->CommitTransaction(); } } //Use the last date to base the future week calculation on. Make sure we don't unset $week_range['end_date'] //When BiWeekly overtime policies are calculated, it sets getEnableCalcFutureWeek() to TRUE. if (isset($week_range['end_date']) and UserDateTotalFactory::getEnableCalcFutureWeek() == TRUE) { $future_week_date = $week_range['end_date'] + 86400 * 7; Debug::text('Found Biweekly overtime policy, calculate one week into the future: ' . TTDate::getDate('DATE', $future_week_date), __FILE__, __LINE__, __METHOD__, 10); UserDateTotalFactory::reCalculateRange($user_id, TTDate::getBeginWeekEpoch($future_week_date, $start_week_day_id), TTDate::getEndWeekEpoch($future_week_date, $start_week_day_id)); UserDateTotalFactory::setEnableCalcFutureWeek(FALSE); //Return to FALSE so future weeks aren't calculate for other users. unset($future_week_date); } return TRUE; } } Debug::text('Returning FALSE!', __FILE__, __LINE__, __METHOD__, 10); return FALSE; }