function calcPremiumPolicyTotalTime($udt_meal_policy_adjustment_arr, $udt_break_policy_adjustment_arr, $daily_total_time = FALSE)
 {
     global $profiler;
     $profiler->startTimer("UserDateTotal::calcPremiumPolicyTotalTime() - Part 1");
     if ($daily_total_time === FALSE) {
         $daily_total_time = $this->getDailyTotalTime();
     }
     $pplf = new PremiumPolicyListFactory();
     $pplf->getByPolicyGroupUserId($this->getUserDateObject()->getUser());
     if ($pplf->getRecordCount() > 0) {
         Debug::text('Found Premium Policies to apply.', __FILE__, __LINE__, __METHOD__, 10);
         foreach ($pplf as $pp_obj) {
             Debug::text('Found Premium Policy: ID: ' . $pp_obj->getId() . ' Type: ' . $pp_obj->getType(), __FILE__, __LINE__, __METHOD__, 10);
             //FIXME: Support manually setting a premium policy through the Edit Hours page?
             //In those cases, just skip auto-calculating it and accept it?
             switch ($pp_obj->getType()) {
                 case 10:
                     //Date/Time
                     Debug::text(' Date/Time Premium Policy...', __FILE__, __LINE__, __METHOD__, 10);
                     //Make sure this is a valid day
                     //Take into account shifts that span midnight though, where one half of the shift is eligilble for premium time.
                     //ie: Premium Policy starts 7AM to 7PM on Sat/Sun. Punches in at 9PM Friday and out at 9AM Sat, we need to check if both days are valid.
                     //FIXME: Handle shifts that are longer than 24hrs in length.
                     if ($pp_obj->isActive($this->getUserDateObject()->getDateStamp() - 86400, $this->getUserDateObject()->getDateStamp() + 86400)) {
                         Debug::text(' Premium Policy Is Active On OR Around This Day.', __FILE__, __LINE__, __METHOD__, 10);
                         $total_daily_time_used = 0;
                         $daily_trigger_time = 0;
                         $udtlf = new UserDateTotalListFactory();
                         if ($pp_obj->isHourRestricted() == TRUE) {
                             if ($pp_obj->getWeeklyTriggerTime() > 0) {
                                 //Get Pay Period Schedule info
                                 if (is_object($this->getUserDateObject()->getPayPeriodObject()) and is_object($this->getUserDateObject()->getPayPeriodObject()->getPayPeriodScheduleObject())) {
                                     $start_week_day_id = $this->getUserDateObject()->getPayPeriodObject()->getPayPeriodScheduleObject()->getStartWeekDay();
                                 } else {
                                     $start_week_day_id = 0;
                                 }
                                 Debug::text('Start Week Day ID: ' . $start_week_day_id, __FILE__, __LINE__, __METHOD__, 10);
                                 $weekly_total_time = $udtlf->getWeekRegularTimeSumByUserIDAndEpochAndStartWeekEpoch($this->getUserDateObject()->getUser(), $this->getUserDateObject()->getDateStamp(), TTDate::getBeginWeekEpoch($this->getUserDateObject()->getDateStamp(), $start_week_day_id));
                                 if ($weekly_total_time > $pp_obj->getWeeklyTriggerTime()) {
                                     $daily_trigger_time = 0;
                                 } else {
                                     $daily_trigger_time = $pp_obj->getWeeklyTriggerTime() - $weekly_total_time;
                                 }
                                 Debug::text(' Weekly Trigger Time: ' . $daily_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                             }
                             if ($pp_obj->getDailyTriggerTime() > 0 and $pp_obj->getDailyTriggerTime() > $daily_trigger_time) {
                                 $daily_trigger_time = $pp_obj->getDailyTriggerTime();
                             }
                         }
                         Debug::text(' Daily Trigger Time: ' . $daily_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                         //Loop through all worked (status: 20) UserDateTotalRows
                         $udtlf->getByUserDateIdAndStatus($this->getUserDateID(), 20);
                         $i = 1;
                         if ($udtlf->getRecordCount() > 0) {
                             Debug::text('Found Total Hours to attempt to apply premium policy... Record Count: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
                             foreach ($udtlf as $udt_obj) {
                                 Debug::text('UserDateTotal ID: ' . $udt_obj->getID() . ' Total Time: ' . $udt_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                                 //Ignore incomplete punches
                                 if ($udt_obj->getTotalTime() == 0) {
                                     continue;
                                 }
                                 //How do we handle actual shifts for premium time?
                                 //So if premium policy starts at 1PM for shifts, to not
                                 //include employees who return from lunch at 1:30PM.
                                 //Create a function that takes all punches for a day, and returns
                                 //the first in and last out time for a given shift when taking
                                 //into account minimum time between shifts, as well as the total time for that shift.
                                 //We can then use that time for ActiveTime on premium policies, and determine if a
                                 //punch falls within the active time, then we add it to the total.
                                 if ($pp_obj->isTimeRestricted() == TRUE and $udt_obj->getPunchControlID() != FALSE) {
                                     Debug::text('Time Restricted Premium Policy, lookup punches to get times.', __FILE__, __LINE__, __METHOD__, 10);
                                     if ($pp_obj->getIncludePartialPunch() == FALSE) {
                                         $shift_data = $this->getShiftDataByUserDateID($this->getUserDateID());
                                     }
                                     $plf = new PunchListFactory();
                                     $plf->getByPunchControlId($udt_obj->getPunchControlID());
                                     if ($plf->getRecordCount() > 0) {
                                         Debug::text('Found Punches: ' . $plf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
                                         foreach ($plf as $punch_obj) {
                                             if ($pp_obj->getIncludePartialPunch() == TRUE) {
                                                 //Debug::text('Including Partial Punches...', __FILE__, __LINE__, __METHOD__, 10);
                                                 if ($punch_obj->getStatus() == 10) {
                                                     $punch_times['in'] = $punch_obj->getTimeStamp();
                                                 } elseif ($punch_obj->getStatus() == 20) {
                                                     $punch_times['out'] = $punch_obj->getTimeStamp();
                                                 }
                                             } else {
                                                 if (isset($shift_data) and is_array($shift_data)) {
                                                     foreach ($shift_data as $shift) {
                                                         if ($punch_obj->getTimeStamp() >= $shift['first_in'] and $punch_obj->getTimeStamp() <= $shift['last_out']) {
                                                             //Debug::Arr($shift,'Shift Data...', __FILE__, __LINE__, __METHOD__, 10);
                                                             Debug::text('Punch (' . TTDate::getDate('DATE+TIME', $punch_obj->getTimeStamp()) . ') inside shift time...', __FILE__, __LINE__, __METHOD__, 10);
                                                             $punch_times['in'] = $shift['first_in'];
                                                             $punch_times['out'] = $shift['last_out'];
                                                             break;
                                                         } else {
                                                             Debug::text('Punch (' . TTDate::getDate('DATE+TIME', $punch_obj->getTimeStamp()) . ') outside shift time...', __FILE__, __LINE__, __METHOD__, 10);
                                                         }
                                                     }
                                                 }
                                             }
                                         }
                                         if (isset($punch_times) and count($punch_times) == 2 and $pp_obj->isActiveTime($punch_times['in'], $punch_times['out']) == TRUE) {
                                             //Debug::Arr($punch_times, 'Punch Times: ', __FILE__, __LINE__, __METHOD__, 10);
                                             $punch_total_time = $pp_obj->getPartialPunchTotalTime($punch_times['in'], $punch_times['out'], $udt_obj->getTotalTime());
                                             Debug::text('Valid Punch pair in active time, Partial Punch Total Time: ' . $punch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                         } else {
                                             Debug::text('InValid Punch Pair or outside Active Time...', __FILE__, __LINE__, __METHOD__, 10);
                                             $punch_total_time = 0;
                                         }
                                     }
                                 } elseif ($pp_obj->isActive($udt_obj->getUserDateObject()->getDateStamp()) == TRUE) {
                                     $punch_total_time = $udt_obj->getTotalTime();
                                 } else {
                                     $punch_total_time = 0;
                                 }
                                 Debug::text('aPunch Total Time: ' . $punch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                 //Apply meal policy adjustment as early as possible.
                                 if ($pp_obj->getIncludeMealPolicy() == TRUE and isset($udt_meal_policy_adjustment_arr[$udt_obj->getId()])) {
                                     Debug::text(' Meal Policy Adjustment Found: ' . $udt_meal_policy_adjustment_arr[$udt_obj->getId()], __FILE__, __LINE__, __METHOD__, 10);
                                     $punch_total_time = bcadd($punch_total_time, $udt_meal_policy_adjustment_arr[$udt_obj->getId()]);
                                     $tmp_punch_total_time = bcadd($udt_obj->getTotalTime(), $udt_meal_policy_adjustment_arr[$udt_obj->getId()]);
                                 } else {
                                     $tmp_punch_total_time = $udt_obj->getTotalTime();
                                 }
                                 Debug::text('bPunch Total Time: ' . $punch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                 //Apply break policy adjustment as early as possible.
                                 if ($pp_obj->getIncludeBreakPolicy() == TRUE and isset($udt_break_policy_adjustment_arr[$udt_obj->getId()])) {
                                     Debug::text(' Break Policy Adjustment Found: ' . $udt_break_policy_adjustment_arr[$udt_obj->getId()], __FILE__, __LINE__, __METHOD__, 10);
                                     $punch_total_time = bcadd($punch_total_time, $udt_break_policy_adjustment_arr[$udt_obj->getId()]);
                                     $tmp_punch_total_time = bcadd($udt_obj->getTotalTime(), $udt_break_policy_adjustment_arr[$udt_obj->getId()]);
                                 } else {
                                     $tmp_punch_total_time = $udt_obj->getTotalTime();
                                 }
                                 Debug::text('cPunch Total Time: ' . $punch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                 $total_daily_time_used += $tmp_punch_total_time;
                                 Debug::text('Daily Total Time Used: ' . $total_daily_time_used, __FILE__, __LINE__, __METHOD__, 10);
                                 //FIXME: Should the daily/weekly trigger time be >= instead of >.
                                 //That way if the policy is active after 7.5hrs, punch time of exactly 7.5hrs will still
                                 //activate the policy, rather then requiring 7.501hrs+
                                 if ($punch_total_time > 0 and $total_daily_time_used > $daily_trigger_time) {
                                     Debug::text('Past Trigger Time!!', __FILE__, __LINE__, __METHOD__, 10);
                                     //Calculate how far past trigger time we are.
                                     $past_trigger_time = $total_daily_time_used - $daily_trigger_time;
                                     if ($punch_total_time > $past_trigger_time) {
                                         $punch_total_time = $past_trigger_time;
                                         Debug::text('Using Past Trigger Time as punch total time: ' . $past_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                                     } else {
                                         Debug::text('NOT Using Past Trigger Time as punch total time: ' . $past_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                     $total_time = $punch_total_time;
                                     if ($pp_obj->getMinimumTime() > 0 or $pp_obj->getMaximumTime() > 0) {
                                         $premium_policy_daily_total_time = (int) $udtlf->getPremiumPolicySumByUserDateIDAndPremiumPolicyID($this->getUserDateID(), $pp_obj->getId());
                                         Debug::text(' Premium Policy Daily Total Time: ' . $premium_policy_daily_total_time . ' Minimum Time: ' . $pp_obj->getMinimumTime() . ' Maximum Time: ' . $pp_obj->getMaximumTime() . ' Total Time: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                         if ($pp_obj->getMinimumTime() > 0) {
                                             //FIXME: Split the minimum time up between all the punches somehow.
                                             //Apply the minimum time on the last punch, otherwise if there are two punch pairs of 15min each
                                             //and a 1hr minimum time, if the minimum time is applied to the first, it will be 1hr and 15min
                                             //for the day. If its applied to the last it will be just 1hr.
                                             //Min & Max time is based on the shift time, rather then per punch pair time.
                                             //FIXME: If there is a minimum time set to say 9hrs, and the punches go like this:
                                             // In: 7:00AM Out: 3:00:PM, Out: 3:30PM (missing 2nd In Punch), the minimum time won't be calculated due to the invalid punch pair.
                                             if ($i == $udtlf->getRecordCount() and bcadd($premium_policy_daily_total_time, $total_time) < $pp_obj->getMinimumTime()) {
                                                 $total_time = bcsub($pp_obj->getMinimumTime(), $premium_policy_daily_total_time);
                                             }
                                         }
                                         Debug::text(' Total Time After Minimum is applied: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                         if ($pp_obj->getMaximumTime() > 0) {
                                             //Min & Max time is based on the shift time, rather then per punch pair time.
                                             if (bcadd($premium_policy_daily_total_time, $total_time) > $pp_obj->getMaximumTime()) {
                                                 Debug::text(' bMore than Maximum Time...', __FILE__, __LINE__, __METHOD__, 10);
                                                 $total_time = bcsub($total_time, bcsub(bcadd($premium_policy_daily_total_time, $total_time), $pp_obj->getMaximumTime()));
                                             }
                                         }
                                     }
                                     Debug::text(' Premium Punch Total Time: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                     if ($total_time > 0) {
                                         Debug::text(' Applying  Premium Time!: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                         $udtf = new UserDateTotalFactory();
                                         $udtf->setUserDateID($this->getUserDateID());
                                         $udtf->setStatus(10);
                                         //System
                                         $udtf->setType(40);
                                         //Premium
                                         $udtf->setPremiumPolicyId($pp_obj->getId());
                                         $udtf->setBranch($udt_obj->getBranch());
                                         $udtf->setDepartment($udt_obj->getDepartment());
                                         $udtf->setJob($udt_obj->getJob());
                                         $udtf->setJobItem($udt_obj->getJobItem());
                                         $udtf->setQuantity($udt_obj->getQuantity());
                                         $udtf->setBadQuantity($udt_obj->getBadQuantity());
                                         $udtf->setTotalTime($total_time);
                                         $udtf->setEnableCalcSystemTotalTime(FALSE);
                                         if ($udtf->isValid() == TRUE) {
                                             $udtf->Save();
                                         }
                                         unset($udtf);
                                     } else {
                                         Debug::text(' Premium Punch Total Time is 0...', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::text('Not Past Trigger Time Yet or Punch Time is 0...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                                 $i++;
                             }
                         }
                     }
                     break;
                 case 20:
                     //Differential
                     Debug::text(' Differential Premium Policy...', __FILE__, __LINE__, __METHOD__, 10);
                     //Loop through all worked (status: 20) UserDateTotalRows
                     $udtlf = new UserDateTotalListFactory();
                     $udtlf->getByUserDateIdAndStatus($this->getUserDateID(), 20);
                     if ($udtlf->getRecordCount() > 0) {
                         Debug::text('Found Total Hours to attempt to apply premium policy... Record Count: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
                         foreach ($udtlf as $udt_obj) {
                             //Ignore incomplete punches
                             if ($udt_obj->getTotalTime() == 0) {
                                 continue;
                             }
                             if ($pp_obj->getBranchSelectionType() == 10 and ($pp_obj->getExcludeDefaultBranch() == FALSE or $pp_obj->getExcludeDefaultBranch() == TRUE and $udt_obj->getBranch() != $this->getUserDateObject()->getUserObject()->getDefaultBranch()) or $pp_obj->getBranchSelectionType() == 20 and in_array($udt_obj->getBranch(), (array) $pp_obj->getBranch()) and ($pp_obj->getExcludeDefaultBranch() == FALSE or $pp_obj->getExcludeDefaultBranch() == TRUE and $udt_obj->getBranch() != $this->getUserDateObject()->getUserObject()->getDefaultBranch()) or $pp_obj->getBranchSelectionType() == 30 and !in_array($udt_obj->getBranch(), (array) $pp_obj->getBranch()) and ($pp_obj->getExcludeDefaultBranch() == FALSE or $pp_obj->getExcludeDefaultBranch() == TRUE and $udt_obj->getBranch() != $this->getUserDateObject()->getUserObject()->getDefaultBranch())) {
                                 Debug::text(' Shift Differential... Meets Branch Criteria! Select Type: ' . $pp_obj->getBranchSelectionType() . ' Exclude Default Branch: ' . (int) $pp_obj->getExcludeDefaultBranch() . ' Default Branch: ' . $this->getUserDateObject()->getUserObject()->getDefaultBranch(), __FILE__, __LINE__, __METHOD__, 10);
                                 if ($pp_obj->getDepartmentSelectionType() == 10 and ($pp_obj->getExcludeDefaultDepartment() == FALSE or $pp_obj->getExcludeDefaultDepartment() == TRUE and $udt_obj->getDepartment() != $this->getUserDateObject()->getUserObject()->getDefaultDepartment()) or $pp_obj->getDepartmentSelectionType() == 20 and in_array($udt_obj->getDepartment(), (array) $pp_obj->getDepartment()) and ($pp_obj->getExcludeDefaultDepartment() == FALSE or $pp_obj->getExcludeDefaultDepartment() == TRUE and $udt_obj->getDepartment() != $this->getUserDateObject()->getUserObject()->getDefaultDepartment()) or $pp_obj->getDepartmentSelectionType() == 30 and !in_array($udt_obj->getDepartment(), (array) $pp_obj->getDepartment()) and ($pp_obj->getExcludeDefaultDepartment() == FALSE or $pp_obj->getExcludeDefaultDepartment() == TRUE and $udt_obj->getDepartment() != $this->getUserDateObject()->getUserObject()->getDefaultDepartment())) {
                                     Debug::text(' Shift Differential... Meets Department Criteria! Select Type: ' . $pp_obj->getDepartmentSelectionType() . ' Exclude Default Department: ' . (int) $pp_obj->getExcludeDefaultDepartment() . ' Default Department: ' . $this->getUserDateObject()->getUserObject()->getDefaultDepartment(), __FILE__, __LINE__, __METHOD__, 10);
                                     if ($pp_obj->getJobGroupSelectionType() == 10 or $pp_obj->getJobGroupSelectionType() == 20 and (is_object($udt_obj->getJobObject()) and in_array($udt_obj->getJobObject()->getGroup(), (array) $pp_obj->getJobGroup())) or $pp_obj->getJobGroupSelectionType() == 30 and (is_object($udt_obj->getJobObject()) and !in_array($udt_obj->getJobObject()->getGroup(), (array) $pp_obj->getJobGroup()))) {
                                         Debug::text(' Shift Differential... Meets Job Group Criteria! Select Type: ' . $pp_obj->getJobGroupSelectionType(), __FILE__, __LINE__, __METHOD__, 10);
                                         if ($pp_obj->getJobSelectionType() == 10 or $pp_obj->getJobSelectionType() == 20 and in_array($udt_obj->getJob(), (array) $pp_obj->getJob()) or $pp_obj->getJobSelectionType() == 30 and !in_array($udt_obj->getJob(), (array) $pp_obj->getJob())) {
                                             Debug::text(' Shift Differential... Meets Job Criteria! Select Type: ' . $pp_obj->getJobSelectionType(), __FILE__, __LINE__, __METHOD__, 10);
                                             if ($pp_obj->getJobItemGroupSelectionType() == 10 or $pp_obj->getJobItemGroupSelectionType() == 20 and (is_object($udt_obj->getJobItemObject()) and in_array($udt_obj->getJobItemObject()->getGroup(), (array) $pp_obj->getJobItemGroup())) or $pp_obj->getJobItemGroupSelectionType() == 30 and (is_object($udt_obj->getJobItemObject()) and !in_array($udt_obj->getJobItemObject()->getGroup(), (array) $pp_obj->getJobItemGroup()))) {
                                                 Debug::text(' Shift Differential... Meets Task Group Criteria! Select Type: ' . $pp_obj->getJobItemGroupSelectionType(), __FILE__, __LINE__, __METHOD__, 10);
                                                 if ($pp_obj->getJobItemSelectionType() == 10 or $pp_obj->getJobItemSelectionType() == 20 and in_array($udt_obj->getJobItem(), (array) $pp_obj->getJobItem()) or $pp_obj->getJobItemSelectionType() == 30 and !in_array($udt_obj->getJobItem(), (array) $pp_obj->getJobItem())) {
                                                     Debug::text(' Shift Differential... Meets Task Criteria! Select Type: ' . $pp_obj->getJobSelectionType(), __FILE__, __LINE__, __METHOD__, 10);
                                                     $premium_policy_daily_total_time = 0;
                                                     $punch_total_time = $udt_obj->getTotalTime();
                                                     $total_time = 0;
                                                     //Apply meal policy adjustment BEFORE min/max times
                                                     if ($pp_obj->getIncludeMealPolicy() == TRUE and isset($udt_meal_policy_adjustment_arr[$udt_obj->getId()])) {
                                                         Debug::text(' Meal Policy Adjustment Found: ' . $udt_meal_policy_adjustment_arr[$udt_obj->getId()], __FILE__, __LINE__, __METHOD__, 10);
                                                         $punch_total_time = bcadd($punch_total_time, $udt_meal_policy_adjustment_arr[$udt_obj->getId()]);
                                                     }
                                                     if ($pp_obj->getIncludeBreakPolicy() == TRUE and isset($udt_break_policy_adjustment_arr[$udt_obj->getId()])) {
                                                         Debug::text(' Break Policy Adjustment Found: ' . $udt_break_policy_adjustment_arr[$udt_obj->getId()], __FILE__, __LINE__, __METHOD__, 10);
                                                         $punch_total_time = bcadd($punch_total_time, $udt_break_policy_adjustment_arr[$udt_obj->getId()]);
                                                     }
                                                     if ($pp_obj->getMinimumTime() > 0 or $pp_obj->getMaximumTime() > 0) {
                                                         $premium_policy_daily_total_time = $udtlf->getPremiumPolicySumByUserDateIDAndPremiumPolicyID($this->getUserDateID(), $pp_obj->getId());
                                                         Debug::text(' Premium Policy Daily Total Time: ' . $premium_policy_daily_total_time . ' Minimum Time: ' . $pp_obj->getMinimumTime() . ' Maximum Time: ' . $pp_obj->getMaximumTime(), __FILE__, __LINE__, __METHOD__, 10);
                                                         if ($pp_obj->getMinimumTime() > 0) {
                                                             if ($daily_total_time < $pp_obj->getMinimumTime()) {
                                                                 //Split the minimum time up between all punches
                                                                 //We only get IN punches, so we don't need to divide $total_punches by 2.
                                                                 //This won't calculate the proper amount if punches aren't paired, but everything
                                                                 //is broken then anyways.
                                                                 $total_time = bcdiv($pp_obj->getMinimumTime(), $total_punches);
                                                                 Debug::text(' Daily Total Time is less the Minimum, using: ' . $total_time . ' Total Punches: ' . $total_punches, __FILE__, __LINE__, __METHOD__, 10);
                                                             } else {
                                                                 Debug::text(' Daily Total is more then minimum...', __FILE__, __LINE__, __METHOD__, 10);
                                                                 $total_time = $punch_total_time;
                                                             }
                                                         } else {
                                                             $total_time = $punch_total_time;
                                                         }
                                                         Debug::text(' Total Time After Minimum is applied: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                         if ($pp_obj->getMaximumTime() > 0) {
                                                             if ($total_time > $pp_obj->getMaximumTime()) {
                                                                 Debug::text(' aMore than Maximum Time...', __FILE__, __LINE__, __METHOD__, 10);
                                                                 $total_time = $pp_obj->getMaximumTime();
                                                             } elseif (bcadd($premium_policy_daily_total_time, $total_time) > $pp_obj->getMaximumTime()) {
                                                                 Debug::text(' bMore than Maximum Time...', __FILE__, __LINE__, __METHOD__, 10);
                                                                 $total_time = bcsub(bcadd($premium_policy_daily_total_time, $total_time), $pp_obj->getMaximumTime());
                                                             }
                                                         }
                                                     } else {
                                                         $total_time = $punch_total_time;
                                                     }
                                                     Debug::text(' Premium Punch Total Time: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                     if ($total_time > 0) {
                                                         Debug::text(' Applying  Premium Time!: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                         $udtf = new UserDateTotalFactory();
                                                         $udtf->setUserDateID($this->getUserDateID());
                                                         $udtf->setStatus(10);
                                                         //System
                                                         $udtf->setType(40);
                                                         //Premium
                                                         $udtf->setPremiumPolicyId($pp_obj->getId());
                                                         $udtf->setBranch($udt_obj->getBranch());
                                                         $udtf->setDepartment($udt_obj->getDepartment());
                                                         $udtf->setJob($udt_obj->getJob());
                                                         $udtf->setJobItem($udt_obj->getJobItem());
                                                         $udtf->setQuantity($udt_obj->getQuantity());
                                                         $udtf->setBadQuantity($udt_obj->getBadQuantity());
                                                         $udtf->setTotalTime($total_time);
                                                         $udtf->setEnableCalcSystemTotalTime(FALSE);
                                                         if ($udtf->isValid() == TRUE) {
                                                             $udtf->Save();
                                                         }
                                                         unset($udtf);
                                                     } else {
                                                         Debug::text(' Premium Punch Total Time is 0...', __FILE__, __LINE__, __METHOD__, 10);
                                                     }
                                                 } else {
                                                     Debug::text(' Shift Differential... DOES NOT Meet Task Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                                 }
                                             } else {
                                                 Debug::text(' Shift Differential... DOES NOT Meet Task Group Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                             }
                                         } else {
                                             Debug::text(' Shift Differential... DOES NOT Meet Job Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         Debug::text(' Shift Differential... DOES NOT Meet Job Group Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::text(' Shift Differential... DOES NOT Meet Department Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             } else {
                                 Debug::text(' Shift Differential... DOES NOT Meet Branch Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                             }
                         }
                     }
                     break;
                 case 30:
                     //Meal/Break
                     Debug::text(' Meal/Break Premium Policy...', __FILE__, __LINE__, __METHOD__, 10);
                     if ($pp_obj->getDailyTriggerTime() == 0 or $pp_obj->getDailyTriggerTime() > 0 and $daily_total_time >= $pp_obj->getDailyTriggerTime()) {
                         //Find maximum worked without a break.
                         $plf = new PunchListFactory();
                         $plf->getByUserDateId($this->getUserDateID());
                         //Get all punches for the day.
                         if ($plf->getRecordCount() > 0) {
                             Debug::text('Found Punches: ' . $plf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
                             foreach ($plf as $p_obj) {
                                 Debug::text('TimeStamp: ' . $p_obj->getTimeStamp() . ' Status: ' . $p_obj->getStatus(), __FILE__, __LINE__, __METHOD__, 10);
                                 $punch_pairs[$p_obj->getPunchControlID()][] = array('status_id' => $p_obj->getStatus(), 'punch_control_id' => $p_obj->getPunchControlID(), 'time_stamp' => $p_obj->getTimeStamp());
                             }
                             if (isset($punch_pairs)) {
                                 $prev_punch_timestamp = NULL;
                                 $maximum_time_worked_without_break = 0;
                                 foreach ($punch_pairs as $punch_pair) {
                                     if (count($punch_pair) > 1) {
                                         //Total Punch Time
                                         $total_punch_pair_time = $punch_pair[1]['time_stamp'] - $punch_pair[0]['time_stamp'];
                                         $maximum_time_worked_without_break += $total_punch_pair_time;
                                         Debug::text('Total Punch Pair Time: ' . $total_punch_pair_time . ' Maximum No Break Time: ' . $maximum_time_worked_without_break, __FILE__, __LINE__, __METHOD__, 10);
                                         if ($prev_punch_timestamp !== NULL) {
                                             $break_time = $punch_pair[0]['time_stamp'] - $prev_punch_timestamp;
                                             if ($break_time > $pp_obj->getMinimumBreakTime()) {
                                                 Debug::text('Exceeded Minimum Break Time: ' . $break_time . ' Minimum: ' . $pp_obj->getMinimumBreakTime(), __FILE__, __LINE__, __METHOD__, 10);
                                                 $maximum_time_worked_without_break = 0;
                                             }
                                         }
                                         if ($maximum_time_worked_without_break > $pp_obj->getMaximumNoBreakTime()) {
                                             Debug::text('Exceeded maximum no break time!', __FILE__, __LINE__, __METHOD__, 10);
                                             if ($pp_obj->getMaximumTime() > $pp_obj->getMinimumTime()) {
                                                 $total_time = $pp_obj->getMaximumTime();
                                             } else {
                                                 $total_time = $pp_obj->getMinimumTime();
                                             }
                                             if ($total_time > 0) {
                                                 Debug::text(' Applying Meal/Break Premium Time!: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                 //Get Punch Control obj.
                                                 $pclf = new PunchControlListFactory();
                                                 $pclf->getById($punch_pair[0]['punch_control_id']);
                                                 if ($pclf->getRecordCount() > 0) {
                                                     $pc_obj = $pclf->getCurrent();
                                                 }
                                                 $udtf = new UserDateTotalFactory();
                                                 $udtf->setUserDateID($this->getUserDateID());
                                                 $udtf->setStatus(10);
                                                 //System
                                                 $udtf->setType(40);
                                                 //Premium
                                                 $udtf->setPremiumPolicyId($pp_obj->getId());
                                                 if (isset($pc_obj) and is_object($pc_obj)) {
                                                     $udtf->setBranch($pc_obj->getBranch());
                                                     $udtf->setDepartment($pc_obj->getDepartment());
                                                     $udtf->setJob($pc_obj->getJob());
                                                     $udtf->setJobItem($pc_obj->getJobItem());
                                                 }
                                                 $udtf->setTotalTime($total_time);
                                                 $udtf->setEnableCalcSystemTotalTime(FALSE);
                                                 if ($udtf->isValid() == TRUE) {
                                                     $udtf->Save();
                                                 }
                                                 unset($udtf);
                                                 break;
                                                 //Stop looping through punches.
                                             }
                                         } else {
                                             Debug::text('Did not exceed maximum no break time yet...', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                         $prev_punch_timestamp = $punch_pair[1]['time_stamp'];
                                     } else {
                                         Debug::text('Found UnPaired Punch, Ignorning...', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 }
                                 unset($plf, $punch_pairs, $punch_pair, $prev_punch_timestamp, $maximum_time_worked_without_break, $total_time);
                             }
                         }
                     } else {
                         Debug::text(' Not within Daily Total Time: ' . $daily_total_time . ' Trigger Time: ' . $pp_obj->getDailyTriggerTime(), __FILE__, __LINE__, __METHOD__, 10);
                     }
                     break;
                 case 100:
                     //Advanced
                     Debug::text(' Advanced Premium Policy...', __FILE__, __LINE__, __METHOD__, 10);
                     //Make sure this is a valid day
                     if ($pp_obj->isActive($this->getUserDateObject()->getDateStamp() - 86400, $this->getUserDateObject()->getDateStamp() + 86400)) {
                         Debug::text(' Premium Policy Is Active On This Day.', __FILE__, __LINE__, __METHOD__, 10);
                         $total_daily_time_used = 0;
                         $daily_trigger_time = 0;
                         $udtlf = new UserDateTotalListFactory();
                         if ($pp_obj->isHourRestricted() == TRUE) {
                             if ($pp_obj->getWeeklyTriggerTime() > 0) {
                                 //Get Pay Period Schedule info
                                 if (is_object($this->getUserDateObject()->getPayPeriodObject()) and is_object($this->getUserDateObject()->getPayPeriodObject()->getPayPeriodScheduleObject())) {
                                     $start_week_day_id = $this->getUserDateObject()->getPayPeriodObject()->getPayPeriodScheduleObject()->getStartWeekDay();
                                 } else {
                                     $start_week_day_id = 0;
                                 }
                                 Debug::text('Start Week Day ID: ' . $start_week_day_id, __FILE__, __LINE__, __METHOD__, 10);
                                 $weekly_total_time = $udtlf->getWeekRegularTimeSumByUserIDAndEpochAndStartWeekEpoch($this->getUserDateObject()->getUser(), $this->getUserDateObject()->getDateStamp(), TTDate::getBeginWeekEpoch($this->getUserDateObject()->getDateStamp(), $start_week_day_id));
                                 if ($weekly_total_time > $pp_obj->getWeeklyTriggerTime()) {
                                     $daily_trigger_time = 0;
                                 } else {
                                     $daily_trigger_time = $pp_obj->getWeeklyTriggerTime() - $weekly_total_time;
                                 }
                                 Debug::text(' Weekly Trigger Time: ' . $daily_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                             }
                             if ($pp_obj->getDailyTriggerTime() > 0 and $pp_obj->getDailyTriggerTime() > $daily_trigger_time) {
                                 $daily_trigger_time = $pp_obj->getDailyTriggerTime();
                             }
                         }
                         Debug::text(' Daily Trigger Time: ' . $daily_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                         //Loop through all worked (status: 20) UserDateTotalRows
                         $udtlf->getByUserDateIdAndStatus($this->getUserDateID(), 20);
                         $i = 1;
                         if ($udtlf->getRecordCount() > 0) {
                             Debug::text('Found Total Hours to attempt to apply premium policy... Record Count: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
                             foreach ($udtlf as $udt_obj) {
                                 //Ignore incomplete punches
                                 if ($udt_obj->getTotalTime() == 0) {
                                     continue;
                                 }
                                 //Check Shift Differential criteria before calculatating daily/weekly time which
                                 //is more resource intensive.
                                 if ($pp_obj->getBranchSelectionType() == 10 and ($pp_obj->getExcludeDefaultBranch() == FALSE or $pp_obj->getExcludeDefaultBranch() == TRUE and $udt_obj->getBranch() != $this->getUserDateObject()->getUserObject()->getDefaultBranch()) or $pp_obj->getBranchSelectionType() == 20 and in_array($udt_obj->getBranch(), (array) $pp_obj->getBranch()) and ($pp_obj->getExcludeDefaultBranch() == FALSE or $pp_obj->getExcludeDefaultBranch() == TRUE and $udt_obj->getBranch() != $this->getUserDateObject()->getUserObject()->getDefaultBranch()) or $pp_obj->getBranchSelectionType() == 30 and !in_array($udt_obj->getBranch(), (array) $pp_obj->getBranch()) and ($pp_obj->getExcludeDefaultBranch() == FALSE or $pp_obj->getExcludeDefaultBranch() == TRUE and $udt_obj->getBranch() != $this->getUserDateObject()->getUserObject()->getDefaultBranch())) {
                                     Debug::text(' Shift Differential... Meets Branch Criteria! Select Type: ' . $pp_obj->getBranchSelectionType() . ' Exclude Default Branch: ' . (int) $pp_obj->getExcludeDefaultBranch() . ' Default Branch: ' . $this->getUserDateObject()->getUserObject()->getDefaultBranch(), __FILE__, __LINE__, __METHOD__, 10);
                                     if ($pp_obj->getDepartmentSelectionType() == 10 and ($pp_obj->getExcludeDefaultDepartment() == FALSE or $pp_obj->getExcludeDefaultDepartment() == TRUE and $udt_obj->getDepartment() != $this->getUserDateObject()->getUserObject()->getDefaultDepartment()) or $pp_obj->getDepartmentSelectionType() == 20 and in_array($udt_obj->getDepartment(), (array) $pp_obj->getDepartment()) and ($pp_obj->getExcludeDefaultDepartment() == FALSE or $pp_obj->getExcludeDefaultDepartment() == TRUE and $udt_obj->getDepartment() != $this->getUserDateObject()->getUserObject()->getDefaultDepartment()) or $pp_obj->getDepartmentSelectionType() == 30 and !in_array($udt_obj->getDepartment(), (array) $pp_obj->getDepartment()) and ($pp_obj->getExcludeDefaultDepartment() == FALSE or $pp_obj->getExcludeDefaultDepartment() == TRUE and $udt_obj->getDepartment() != $this->getUserDateObject()->getUserObject()->getDefaultDepartment())) {
                                         Debug::text(' Shift Differential... Meets Department Criteria! Select Type: ' . $pp_obj->getDepartmentSelectionType() . ' Exclude Default Department: ' . (int) $pp_obj->getExcludeDefaultDepartment() . ' Default Department: ' . $this->getUserDateObject()->getUserObject()->getDefaultDepartment(), __FILE__, __LINE__, __METHOD__, 10);
                                         if ($pp_obj->getJobGroupSelectionType() == 10 or $pp_obj->getJobGroupSelectionType() == 20 and is_object($udt_obj->getJobObject()) and in_array($udt_obj->getJobObject()->getGroup(), (array) $pp_obj->getJobGroup()) or $pp_obj->getJobGroupSelectionType() == 30 and is_object($udt_obj->getJobObject()) and !in_array($udt_obj->getJobObject()->getGroup(), (array) $pp_obj->getJobGroup())) {
                                             Debug::text(' Shift Differential... Meets Job Group Criteria! Select Type: ' . $pp_obj->getJobGroupSelectionType(), __FILE__, __LINE__, __METHOD__, 10);
                                             if ($pp_obj->getJobSelectionType() == 10 or $pp_obj->getJobSelectionType() == 20 and in_array($udt_obj->getJob(), (array) $pp_obj->getJob()) or $pp_obj->getJobSelectionType() == 30 and !in_array($udt_obj->getJob(), (array) $pp_obj->getJob())) {
                                                 Debug::text(' Shift Differential... Meets Job Criteria! Select Type: ' . $pp_obj->getJobSelectionType(), __FILE__, __LINE__, __METHOD__, 10);
                                                 if ($pp_obj->getJobItemGroupSelectionType() == 10 or $pp_obj->getJobItemGroupSelectionType() == 20 and is_object($udt_obj->getJobItemObject()) and in_array($udt_obj->getJobItemObject()->getGroup(), (array) $pp_obj->getJobItemGroup()) or $pp_obj->getJobItemGroupSelectionType() == 30 and is_object($udt_obj->getJobItemObject()) and !in_array($udt_obj->getJobItemObject()->getGroup(), (array) $pp_obj->getJobItemGroup())) {
                                                     Debug::text(' Shift Differential... Meets Task Group Criteria! Select Type: ' . $pp_obj->getJobItemGroupSelectionType(), __FILE__, __LINE__, __METHOD__, 10);
                                                     if ($pp_obj->getJobItemSelectionType() == 10 or $pp_obj->getJobItemSelectionType() == 20 and in_array($udt_obj->getJobItem(), (array) $pp_obj->getJobItem()) or $pp_obj->getJobItemSelectionType() == 30 and !in_array($udt_obj->getJobItem(), (array) $pp_obj->getJobItem())) {
                                                         Debug::text(' Shift Differential... Meets Task Criteria! Select Type: ' . $pp_obj->getJobSelectionType(), __FILE__, __LINE__, __METHOD__, 10);
                                                         if ($pp_obj->isTimeRestricted() == TRUE and $udt_obj->getPunchControlID() != FALSE) {
                                                             Debug::text('Time Restricted Premium Policy, lookup punches to get times.', __FILE__, __LINE__, __METHOD__, 10);
                                                             if ($pp_obj->getIncludePartialPunch() == FALSE) {
                                                                 $shift_data = $this->getShiftDataByUserDateID($this->getUserDateID());
                                                             }
                                                             $plf = new PunchListFactory();
                                                             $plf->getByPunchControlId($udt_obj->getPunchControlID());
                                                             if ($plf->getRecordCount() > 0) {
                                                                 Debug::text('Found Punches: ' . $plf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
                                                                 foreach ($plf as $punch_obj) {
                                                                     if ($pp_obj->getIncludePartialPunch() == TRUE) {
                                                                         //Debug::text('Including Partial Punches...', __FILE__, __LINE__, __METHOD__, 10);
                                                                         if ($punch_obj->getStatus() == 10) {
                                                                             $punch_times['in'] = $punch_obj->getTimeStamp();
                                                                         } elseif ($punch_obj->getStatus() == 20) {
                                                                             $punch_times['out'] = $punch_obj->getTimeStamp();
                                                                         }
                                                                     } else {
                                                                         if (isset($shift_data) and is_array($shift_data)) {
                                                                             foreach ($shift_data as $shift) {
                                                                                 if ($punch_obj->getTimeStamp() >= $shift['first_in'] and $punch_obj->getTimeStamp() <= $shift['last_out']) {
                                                                                     //Debug::Arr($shift,'Shift Data...', __FILE__, __LINE__, __METHOD__, 10);
                                                                                     Debug::text('Punch (' . TTDate::getDate('DATE+TIME', $punch_obj->getTimeStamp()) . ') inside shift time...', __FILE__, __LINE__, __METHOD__, 10);
                                                                                     $punch_times['in'] = $shift['first_in'];
                                                                                     $punch_times['out'] = $shift['last_out'];
                                                                                     break;
                                                                                 } else {
                                                                                     Debug::text('Punch (' . TTDate::getDate('DATE+TIME', $punch_obj->getTimeStamp()) . ') outside shift time...', __FILE__, __LINE__, __METHOD__, 10);
                                                                                 }
                                                                             }
                                                                         }
                                                                     }
                                                                 }
                                                                 if (isset($punch_times) and count($punch_times) == 2 and $pp_obj->isActiveTime($punch_times['in'], $punch_times['out']) == TRUE) {
                                                                     //Debug::Arr($punch_times, 'Punch Times: ', __FILE__, __LINE__, __METHOD__, 10);
                                                                     $punch_total_time = $pp_obj->getPartialPunchTotalTime($punch_times['in'], $punch_times['out'], $udt_obj->getTotalTime());
                                                                     Debug::text('Valid Punch pair in active time, Partial Punch Total Time: ' . $punch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                                 } else {
                                                                     Debug::text('InValid Punch Pair or outside Active Time...', __FILE__, __LINE__, __METHOD__, 10);
                                                                     $punch_total_time = 0;
                                                                 }
                                                             }
                                                         } elseif ($pp_obj->isActive($udt_obj->getUserDateObject()->getDateStamp()) == TRUE) {
                                                             $punch_total_time = $udt_obj->getTotalTime();
                                                         } else {
                                                             $punch_total_time = 0;
                                                         }
                                                         Debug::text('aPunch Total Time: ' . $punch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                         //Apply meal policy adjustment as early as possible.
                                                         if ($pp_obj->getIncludeMealPolicy() == TRUE and isset($udt_meal_policy_adjustment_arr[$udt_obj->getId()])) {
                                                             Debug::text(' Meal Policy Adjustment Found: ' . $udt_meal_policy_adjustment_arr[$udt_obj->getId()], __FILE__, __LINE__, __METHOD__, 10);
                                                             $punch_total_time = bcadd($punch_total_time, $udt_meal_policy_adjustment_arr[$udt_obj->getId()]);
                                                             $tmp_punch_total_time = bcadd($udt_obj->getTotalTime(), $udt_meal_policy_adjustment_arr[$udt_obj->getId()]);
                                                         } else {
                                                             $tmp_punch_total_time = $udt_obj->getTotalTime();
                                                         }
                                                         Debug::text('bPunch Total Time: ' . $punch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                         if ($pp_obj->getIncludeBreakPolicy() == TRUE and isset($udt_break_policy_adjustment_arr[$udt_obj->getId()])) {
                                                             Debug::text(' Break Policy Adjustment Found: ' . $udt_break_policy_adjustment_arr[$udt_obj->getId()], __FILE__, __LINE__, __METHOD__, 10);
                                                             $punch_total_time = bcadd($punch_total_time, $udt_break_policy_adjustment_arr[$udt_obj->getId()]);
                                                             $tmp_punch_total_time = bcadd($udt_obj->getTotalTime(), $udt_break_policy_adjustment_arr[$udt_obj->getId()]);
                                                         } else {
                                                             $tmp_punch_total_time = $udt_obj->getTotalTime();
                                                         }
                                                         Debug::text('cPunch Total Time: ' . $punch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                         $total_daily_time_used += $tmp_punch_total_time;
                                                         Debug::text('Daily Total Time Used: ' . $total_daily_time_used, __FILE__, __LINE__, __METHOD__, 10);
                                                         if ($punch_total_time > 0 and $total_daily_time_used > $daily_trigger_time) {
                                                             Debug::text('Past Trigger Time!!', __FILE__, __LINE__, __METHOD__, 10);
                                                             //Calculate how far past trigger time we are.
                                                             $past_trigger_time = $total_daily_time_used - $daily_trigger_time;
                                                             if ($punch_total_time > $past_trigger_time) {
                                                                 $punch_total_time = $past_trigger_time;
                                                                 Debug::text('Using Past Trigger Time as punch total time: ' . $past_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                                                             } else {
                                                                 Debug::text('NOT Using Past Trigger Time as punch total time: ' . $past_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                                                             }
                                                             $total_time = $punch_total_time;
                                                             if ($pp_obj->getMinimumTime() > 0 or $pp_obj->getMaximumTime() > 0) {
                                                                 $premium_policy_daily_total_time = (int) $udtlf->getPremiumPolicySumByUserDateIDAndPremiumPolicyID($this->getUserDateID(), $pp_obj->getId());
                                                                 Debug::text(' Premium Policy Daily Total Time: ' . $premium_policy_daily_total_time . ' Minimum Time: ' . $pp_obj->getMinimumTime() . ' Maximum Time: ' . $pp_obj->getMaximumTime(), __FILE__, __LINE__, __METHOD__, 10);
                                                                 if ($pp_obj->getMinimumTime() > 0) {
                                                                     //FIXME: Split the minimum time up between all the punches somehow.
                                                                     if ($i == $udtlf->getRecordCount() and bcadd($premium_policy_daily_total_time, $total_time) < $pp_obj->getMinimumTime()) {
                                                                         $total_time = bcsub($pp_obj->getMinimumTime(), $premium_policy_daily_total_time);
                                                                     }
                                                                 }
                                                                 Debug::text(' Total Time After Minimum is applied: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                                 if ($pp_obj->getMaximumTime() > 0) {
                                                                     if ($total_time > $pp_obj->getMaximumTime()) {
                                                                         Debug::text(' aMore than Maximum Time...', __FILE__, __LINE__, __METHOD__, 10);
                                                                         $total_time = $pp_obj->getMaximumTime();
                                                                     } elseif (bcadd($premium_policy_daily_total_time, $total_time) > $pp_obj->getMaximumTime()) {
                                                                         Debug::text(' bMore than Maximum Time...', __FILE__, __LINE__, __METHOD__, 10);
                                                                         //$total_time = bcsub( bcadd( $premium_policy_daily_total_time, $total_time ), $pp_obj->getMaximumTime() );
                                                                         $total_time = bcsub($total_time, bcsub(bcadd($premium_policy_daily_total_time, $total_time), $pp_obj->getMaximumTime()));
                                                                     }
                                                                 }
                                                             }
                                                             Debug::text(' Premium Punch Total Time: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                             if ($total_time > 0) {
                                                                 Debug::text(' Applying  Premium Time!: ' . $total_time, __FILE__, __LINE__, __METHOD__, 10);
                                                                 $udtf = new UserDateTotalFactory();
                                                                 $udtf->setUserDateID($this->getUserDateID());
                                                                 $udtf->setStatus(10);
                                                                 //System
                                                                 $udtf->setType(40);
                                                                 //Premium
                                                                 $udtf->setPremiumPolicyId($pp_obj->getId());
                                                                 $udtf->setBranch($udt_obj->getBranch());
                                                                 $udtf->setDepartment($udt_obj->getDepartment());
                                                                 $udtf->setJob($udt_obj->getJob());
                                                                 $udtf->setJobItem($udt_obj->getJobItem());
                                                                 $udtf->setQuantity($udt_obj->getQuantity());
                                                                 $udtf->setBadQuantity($udt_obj->getBadQuantity());
                                                                 $udtf->setTotalTime($total_time);
                                                                 $udtf->setEnableCalcSystemTotalTime(FALSE);
                                                                 if ($udtf->isValid() == TRUE) {
                                                                     $udtf->Save();
                                                                 }
                                                                 unset($udtf);
                                                             } else {
                                                                 Debug::text(' Premium Punch Total Time is 0...', __FILE__, __LINE__, __METHOD__, 10);
                                                             }
                                                         } else {
                                                             Debug::text('Not Past Trigger Time Yet or Punch Time is 0...', __FILE__, __LINE__, __METHOD__, 10);
                                                         }
                                                     } else {
                                                         Debug::text(' Shift Differential... DOES NOT Meet Task Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                                     }
                                                 } else {
                                                     Debug::text(' Shift Differential... DOES NOT Meet Task Group Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                                 }
                                             } else {
                                                 Debug::text(' Shift Differential... DOES NOT Meet Job Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                             }
                                         } else {
                                             Debug::text(' Shift Differential... DOES NOT Meet Job Group Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         Debug::text(' Shift Differential... DOES NOT Meet Department Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::text(' Shift Differential... DOES NOT Meet Branch Criteria!', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                                 $i++;
                             }
                         }
                     }
                     break;
             }
         }
     }
     $profiler->stopTimer("UserDateTotal::calcPremiumPolicyTotalTime() - Part 1");
     return TRUE;
 }
 function getShiftData($user_date_id = NULL, $user_id = NULL, $epoch = NULL, $filter = NULL, $tmp_punch_control_obj = 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;
     }
     //Debug::text('User Date ID: '. $user_date_id .' User ID: '. $user_id .' TimeStamp: '. TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10);
     $new_shift_trigger_time = $this->getNewDayTriggerTime();
     $plf = new 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();
         }
         $plf->getShiftPunchesByUserIDAndEpoch($user_id, $epoch, $punch_control_id, $this->getMaximumShiftTime());
         unset($punch_control_id);
     }
     Debug::text('Punch Rows: ' . $plf->getRecordCount() . ' UserID: ' . $user_id . ' Date: ' . TTDate::getDate('DATE+TIME', $epoch) . '(' . $epoch . ') MaximumShiftTime: ' . $this->getMaximumShiftTime(), __FILE__, __LINE__, __METHOD__, 10);
     //Debug::Arr($punches, ' Punches: ', __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 ( $total_time == 0 ) {
             					Debug::text('Total time is 0, skipping this punch control object...', __FILE__, __LINE__, __METHOD__, 10);
             					//continue;
             				}
             */
             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...', __FILE__, __LINE__, __METHOD__, 10);
                 if ($p_obj->getTimeStamp() - $shift_data[$shift]['last_out']['time_stamp'] > $new_shift_trigger_time) {
                     $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']);
                 }
             }
             unset($tmp_shift_key, $tmp_shift_data);
             if ($filter == 'first_shift') {
                 //Only return first shift.
                 $shift_data = $shift_data[0];
             } elseif ($filter == 'last_shift') {
                 //Only return last shift.
                 $shift_data = $shift_data[$shift];
             } elseif ($filter == 'nearest_shift') {
                 $shift_data = $shift_data[$nearest_shift_id];
                 //Check to make sure the nearest shift is within the new shift trigger time of EPOCH.
                 if (isset($shift_data['first_in']['time_stamp'])) {
                     $first_in = $shift_data['first_in']['time_stamp'];
                 } elseif (isset($shift_data['last_out']['time_stamp'])) {
                     $first_in = $shift_data['last_out']['time_stamp'];
                 }
                 if (isset($shift_data['last_out']['time_stamp'])) {
                     $last_out = $shift_data['last_out']['time_stamp'];
                 } elseif (isset($shift_data['first_in']['time_stamp'])) {
                     $last_out = $shift_data['first_in']['time_stamp'];
                 }
                 if (TTDate::isTimeOverLap($epoch, $epoch, $first_in - $new_shift_trigger_time, $last_out + $new_shift_trigger_time) == FALSE) {
                     Debug::Text('Nearest shift is outside the new shift trigger time... Epoch: ' . $epoch . ' First In: ' . $first_in . ' Last Out: ' . $last_out . ' New Shift Trigger: ' . $new_shift_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     return FALSE;
                 }
                 unset($first_in, $last_out);
             }
             $profiler->stopTimer('PayPeriodScheduleFactory::getShiftData()');
             //Debug::Arr($shift_data, 'bShift Data:', __FILE__, __LINE__, __METHOD__, 10);
             return $shift_data;
         }
     }
     $profiler->stopTimer('PayPeriodScheduleFactory::getShiftData()');
     return FALSE;
 }
 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);
     //Get user date info
     $udlf = new 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()) {
             return FALSE;
         }
     } else {
         return FALSE;
     }
     //Since we are not usng demerits yet, just always delete exceptions and re-calculate them
     $elf = new ExceptionListFactory();
     $elf->getByUserDateID($user_date_id);
     if ($elf->getRecordCount() > 0) {
         foreach ($elf as $e_obj) {
             Debug::text(' Deleting Exception: ' . $e_obj->getID(), __FILE__, __LINE__, __METHOD__, 10);
             $e_obj->Delete();
         }
     }
     //Get all Punches on this date for this user.
     $plf = new PunchListFactory();
     $plf->getByUserDateId($user_date_id);
     if ($plf->getRecordCount() > 0) {
         Debug::text(' Found Punches: ' . $plf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     }
     $slf = new 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.
     //Get all active exceptions.
     $eplf = new 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.
                     if ($plf->getRecordCount() == 0) {
                         if ($slf->getRecordCount() > 0) {
                             foreach ($slf as $s_obj) {
                                 if ($s_obj->getStatus() == 10 and TTDate::getBeginDayEpoch($s_obj->getStartTime()) - TTDate::getBeginDayEpoch(TTDate::getTime()) <= 0) {
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 }
                             }
                         } else {
                             Debug::text(' NOT Scheduled', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 's2':
                     //Not Scheduled
                     $schedule_total_time = 0;
                     if ($slf->getRecordCount() == 0) {
                         if ($plf->getRecordCount() > 0) {
                             Debug::text(' Worked when wasnt scheduled', __FILE__, __LINE__, __METHOD__, 10);
                             $ef = new ExceptionFactory();
                             $ef->setUserDateID($user_date_id);
                             $ef->setExceptionPolicyID($ep_obj->getId());
                             $ef->setType($type_id);
                             $ef->setEnableDemerits(TRUE);
                             if ($ef->isValid()) {
                                 if ($enable_premature_exceptions == TRUE) {
                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                 }
                                 $ef->Save();
                             }
                         }
                     } else {
                         Debug::text(' IS Scheduled', __FILE__, __LINE__, __METHOD__, 10);
                     }
                     break;
                 case 's3':
                     //In Early
                     if ($plf->getRecordCount() > 0) {
                         //Loop through each punch, find out if they are scheduled, and if they are in early
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getType() == 10 and $p_obj->getStatus() == 10) {
                                 //Normal In
                                 if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                     $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                 }
                                 if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE) {
                                     if ($p_obj->getTimeStamp() < $p_obj->getScheduleObject()->getStartTime()) {
                                         if (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getStartTime(), $ep_obj->getGrace()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                         } elseif (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getStartTime(), $ep_obj->getWatchWindow()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setPunchID($p_obj->getID());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         }
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                     }
                     break;
                 case 's4':
                     //In Late
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getType() == 10 and $p_obj->getStatus() == 10) {
                                 //Normal In
                                 if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                     $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                 }
                                 if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE) {
                                     if ($p_obj->getTimeStamp() > $p_obj->getScheduleObject()->getStartTime()) {
                                         if (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getStartTime(), $ep_obj->getGrace()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                         } elseif (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getStartTime(), $ep_obj->getWatchWindow()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setPunchID($p_obj->getID());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         }
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                     }
                     break;
                 case 's5':
                     //Out Early
                     if ($plf->getRecordCount() > 0) {
                         //Loop through each punch, find out if they are scheduled, and if they are in early
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getType() == 10 and $p_obj->getStatus() == 20) {
                                 //Normal Out
                                 if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                     $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                 }
                                 if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE) {
                                     if ($p_obj->getTimeStamp() < $p_obj->getScheduleObject()->getEndTime()) {
                                         if (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getEndTime(), $ep_obj->getGrace()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                         } elseif (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getEndTime(), $ep_obj->getWatchWindow()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setPunchID($p_obj->getID());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         }
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                     }
                     break;
                 case 's6':
                     //Out Late
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getType() == 10 and $p_obj->getStatus() == 20) {
                                 //Normal Out
                                 if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                     $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                 }
                                 if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE) {
                                     if ($p_obj->getTimeStamp() > $p_obj->getScheduleObject()->getEndTime()) {
                                         if (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getEndTime(), $ep_obj->getGrace()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                         } elseif (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getEndTime(), $ep_obj->getWatchWindow()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setPunchID($p_obj->getID());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         }
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                     }
                     break;
                 case 'm1':
                     //Missing In Punch
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             //Debug::text(' Punch: Status: '. $p_obj->getStatus() .' Punch Control ID: '. $p_obj->getPunchControlID() .' Punch ID: '. $p_obj->getId() .' TimeStamp: '. $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__,10);
                             if ($type_id == 5 and $p_obj->getTimeStamp() < time() - self::$premature_delay) {
                                 $type_id = 50;
                             }
                             $punch_pairs[$p_obj->getPunchControlID()][] = array('status_id' => $p_obj->getStatus(), 'punch_control_id' => $p_obj->getPunchControlID(), 'punch_id' => $p_obj->getId());
                         }
                         if (isset($punch_pairs)) {
                             foreach ($punch_pairs as $punch_control_id => $punch_pair) {
                                 //Debug::Arr($punch_pair, 'Punch Pair for Control ID:'. $punch_control_id, __FILE__, __LINE__, __METHOD__,10);
                                 if (count($punch_pair) != 2) {
                                     Debug::text('aFound Missing Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                     if ($punch_pair[0]['status_id'] == 20) {
                                         //Missing In Punch
                                         Debug::text('bFound Missing In Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                         $ef = new ExceptionFactory();
                                         $ef->setUserDateID($user_date_id);
                                         $ef->setExceptionPolicyID($ep_obj->getId());
                                         $ef->setPunchControlID($punch_pair[0]['punch_control_id']);
                                         $ef->setType($type_id);
                                         $ef->setEnableDemerits(TRUE);
                                         if ($ef->isValid()) {
                                             if ($enable_premature_exceptions == TRUE) {
                                                 $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                             }
                                             $ef->Save();
                                         }
                                     }
                                 } else {
                                     Debug::text('No Missing Punches...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($punch_pairs, $punch_pair);
                     }
                     break;
                 case 'm2':
                     //Missing Out Punch
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             Debug::text(' Punch: Status: ' . $p_obj->getStatus() . ' Punch Control ID: ' . $p_obj->getPunchControlID() . ' Punch ID: ' . $p_obj->getId() . ' TimeStamp: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
                             if ($type_id == 5 and $p_obj->getTimeStamp() < time() - self::$premature_delay) {
                                 $type_id = 50;
                             }
                             $punch_pairs[$p_obj->getPunchControlID()][] = array('status_id' => $p_obj->getStatus(), 'punch_control_id' => $p_obj->getPunchControlID());
                         }
                         if (isset($punch_pairs)) {
                             foreach ($punch_pairs as $punch_control_id => $punch_pair) {
                                 if (count($punch_pair) != 2) {
                                     Debug::text('aFound Missing Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                     if ($punch_pair[0]['status_id'] == 10) {
                                         //Missing Out Punch
                                         Debug::text('bFound Missing Out Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                         $ef = new ExceptionFactory();
                                         $ef->setUserDateID($user_date_id);
                                         $ef->setExceptionPolicyID($ep_obj->getId());
                                         $ef->setPunchControlID($punch_pair[0]['punch_control_id']);
                                         $ef->setType($type_id);
                                         $ef->setEnableDemerits(TRUE);
                                         if ($ef->isValid()) {
                                             if ($enable_premature_exceptions == TRUE) {
                                                 $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                             }
                                             $ef->Save();
                                         }
                                     }
                                 } else {
                                     Debug::text('No Missing Punches...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($punch_pairs, $punch_pair);
                     }
                     break;
                 case 'm3':
                     //Missing Lunch In/Out punch
                     if ($plf->getRecordCount() > 0) {
                         //We need to account for cases where they may punch IN from lunch first, then Out.
                         //As well as just a Lunch In punch and nothing else.
                         foreach ($plf as $p_obj) {
                             if ($type_id == 5 and $p_obj->getTimeStamp() < time() - self::$premature_delay) {
                                 $type_id = 50;
                             }
                             $punches[] = $p_obj;
                         }
                         if (isset($punches) and is_array($punches)) {
                             foreach ($punches as $key => $p_obj) {
                                 if ($p_obj->getType() == 20) {
                                     //Lunch
                                     Debug::text(' Punch: Status: ' . $p_obj->getStatus() . ' Punch Control ID: ' . $p_obj->getPunchControlID() . ' TimeStamp: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
                                     if ($p_obj->getStatus() == 10) {
                                         //Make sure previous punch is Lunch/Out
                                         if (!isset($punches[$key - 1]) or isset($punches[$key - 1]) and is_object($punches[$key - 1]) and ($punches[$key - 1]->getType() != 20 or $punches[$key - 1]->getStatus() != 20)) {
                                             //Invalid punch
                                             $invalid_punches[] = array('punch_id' => $p_obj->getId());
                                         }
                                     } else {
                                         //Make sure next punch is Lunch/In
                                         if (!isset($punches[$key + 1]) or isset($punches[$key + 1]) and is_object($punches[$key + 1]) and ($punches[$key + 1]->getType() != 20 or $punches[$key + 1]->getStatus() != 10)) {
                                             //Invalid punch
                                             $invalid_punches[] = array('punch_id' => $p_obj->getId());
                                         }
                                     }
                                 }
                             }
                             unset($punches, $key, $p_obj);
                             if (isset($invalid_punches) and count($invalid_punches) > 0) {
                                 foreach ($invalid_punches as $invalid_punch_arr) {
                                     Debug::text('Found Missing Lunch In/Out Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     //$ef->setPunchControlID( $invalid_punch_arr['punch_id'] );
                                     $ef->setPunchID($invalid_punch_arr['punch_id']);
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 }
                                 unset($invalid_punch_arr);
                             } else {
                                 Debug::text('Lunch Punches match up.', __FILE__, __LINE__, __METHOD__, 10);
                             }
                             unset($invalid_punches);
                         }
                     }
                     break;
                 case 'm4':
                     //Missing Break In/Out punch
                     if ($plf->getRecordCount() > 0) {
                         //We need to account for cases where they may punch IN from break first, then Out.
                         //As well as just a break In punch and nothing else.
                         foreach ($plf as $p_obj) {
                             if ($type_id == 5 and $p_obj->getTimeStamp() < time() - self::$premature_delay) {
                                 $type_id = 50;
                             }
                             $punches[] = $p_obj;
                         }
                         if (isset($punches) and is_array($punches)) {
                             foreach ($punches as $key => $p_obj) {
                                 if ($p_obj->getType() == 30) {
                                     //Break
                                     Debug::text(' Punch: Status: ' . $p_obj->getStatus() . ' Type: ' . $p_obj->getType() . ' Punch Control ID: ' . $p_obj->getPunchControlID() . ' TimeStamp: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
                                     if ($p_obj->getStatus() == 10) {
                                         //Make sure previous punch is Break/Out
                                         if (!isset($punches[$key - 1]) or isset($punches[$key - 1]) and is_object($punches[$key - 1]) and ($punches[$key - 1]->getType() != 30 or $punches[$key - 1]->getStatus() != 20)) {
                                             //Invalid punch
                                             $invalid_punches[] = array('punch_id' => $p_obj->getId());
                                         }
                                     } else {
                                         //Make sure next punch is Break/In
                                         if (!isset($punches[$key + 1]) or isset($punches[$key + 1]) and is_object($punches[$key + 1]) and ($punches[$key + 1]->getType() != 30 or $punches[$key + 1]->getStatus() != 10)) {
                                             //Invalid punch
                                             $invalid_punches[] = array('punch_id' => $p_obj->getId());
                                         }
                                     }
                                 }
                             }
                             unset($punches, $key, $p_obj);
                             if (isset($invalid_punches) and count($invalid_punches) > 0) {
                                 foreach ($invalid_punches as $invalid_punch_arr) {
                                     Debug::text('Found Missing Break In/Out Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     //$ef->setPunchControlID( $invalid_punch_arr['punch_id'] );
                                     $ef->setPunchID($invalid_punch_arr['punch_id']);
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 }
                                 unset($invalid_punch_arr);
                             } else {
                                 Debug::text('Lunch Punches match up.', __FILE__, __LINE__, __METHOD__, 10);
                             }
                             unset($invalid_punches);
                         }
                     }
                     break;
                 case 's7':
                     //Over Scheduled Hours
                     if ($plf->getRecordCount() > 0) {
                         //This ONLY takes in to account WORKED hours, not paid absence hours.
                         $schedule_total_time = 0;
                         if ($slf->getRecordCount() > 0) {
                             //Check for schedule policy
                             foreach ($slf as $s_obj) {
                                 Debug::text(' Schedule Total Time: ' . $s_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                                 $schedule_total_time += $s_obj->getTotalTime();
                             }
                             $daily_total_time = 0;
                             if ($schedule_total_time > 0) {
                                 //Get daily total time.
                                 $udtlf = new UserDateTotalListFactory();
                                 //Take into account auto-deduct/add meal policies
                                 //$udtlf->getByUserDateIdAndStatus( $user_date_id, 20 );
                                 $udtlf->getByUserDateIdAndStatusAndType($user_date_id, 10, 10);
                                 if ($udtlf->getRecordCount() > 0) {
                                     foreach ($udtlf as $udt_obj) {
                                         $daily_total_time += $udt_obj->getTotalTime();
                                     }
                                 }
                                 Debug::text(' Daily Total Time: ' . $daily_total_time . ' Schedule Total Time: ' . $schedule_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                 if ($daily_total_time > 0 and $daily_total_time > $schedule_total_time + $ep_obj->getGrace()) {
                                     Debug::text(' Worked Over Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 } else {
                                     Debug::text(' DID NOT Work Over Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         } else {
                             Debug::text(' Not Scheduled', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 's8':
                     //Under Scheduled Hours
                     if ($plf->getRecordCount() > 0) {
                         //This ONLY takes in to account WORKED hours, not paid absence hours.
                         $schedule_total_time = 0;
                         if ($slf->getRecordCount() > 0) {
                             //Check for schedule policy
                             foreach ($slf as $s_obj) {
                                 Debug::text(' Schedule Total Time: ' . $s_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                                 $schedule_total_time += $s_obj->getTotalTime();
                             }
                             $daily_total_time = 0;
                             if ($schedule_total_time > 0) {
                                 //Get daily total time.
                                 $udtlf = new UserDateTotalListFactory();
                                 //Take into account auto-deduct/add meal policies
                                 //$udtlf->getByUserDateIdAndStatus( $user_date_id, 20 );
                                 $udtlf->getByUserDateIdAndStatusAndType($user_date_id, 10, 10);
                                 if ($udtlf->getRecordCount() > 0) {
                                     foreach ($udtlf as $udt_obj) {
                                         $daily_total_time += $udt_obj->getTotalTime();
                                     }
                                 }
                                 Debug::text(' Daily Total Time: ' . $daily_total_time . ' Schedule Total Time: ' . $schedule_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                 if ($daily_total_time < $schedule_total_time - $ep_obj->getGrace()) {
                                     Debug::text(' Worked Under Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                                     if ($type_id == 5 and $user_date_obj->getDateStamp() < TTDate::getBeginDayEpoch(time() - self::$premature_delay)) {
                                         $type_id = 50;
                                     }
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 } else {
                                     Debug::text(' DID NOT Work Under Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         } else {
                             Debug::text(' Not Scheduled', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'o1':
                     //Over Daily Time.
                     if ($plf->getRecordCount() > 0) {
                         //This ONLY takes in to account WORKED hours, not paid absence hours.
                         $daily_total_time = 0;
                         //Get daily total time.
                         $udtlf = new UserDateTotalListFactory();
                         //Take into account auto-deduct/add meal policies
                         $udtlf->getByUserDateIdAndStatusAndType($user_date_id, 10, 10);
                         if ($udtlf->getRecordCount() > 0) {
                             foreach ($udtlf as $udt_obj) {
                                 $daily_total_time += $udt_obj->getTotalTime();
                             }
                         }
                         Debug::text(' Daily Total Time: ' . $daily_total_time . ' Watch Window: ' . $ep_obj->getWatchWindow() . ' User Date ID: ' . $user_date_id, __FILE__, __LINE__, __METHOD__, 10);
                         if ($daily_total_time > 0 and $daily_total_time > $ep_obj->getWatchWindow()) {
                             Debug::text(' Worked Over Daily Hours', __FILE__, __LINE__, __METHOD__, 10);
                             $ef = new ExceptionFactory();
                             $ef->setUserDateID($user_date_id);
                             $ef->setExceptionPolicyID($ep_obj->getId());
                             $ef->setType($type_id);
                             $ef->setEnableDemerits(TRUE);
                             if ($ef->isValid()) {
                                 if ($enable_premature_exceptions == TRUE) {
                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                 }
                                 $ef->Save();
                             }
                         } else {
                             Debug::text(' DID NOT Work Over Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'o2':
                     //Over Weekly Time.
                 //Over Weekly Time.
                 case 's9':
                     //Over Weekly Scheduled Time.
                     if ($plf->getRecordCount() > 0) {
                         //Get Pay Period Schedule info
                         if (is_object($user_date_obj->getPayPeriodObject()) and is_object($user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject())) {
                             $start_week_day_id = $user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject()->getStartWeekDay();
                         } else {
                             $start_week_day_id = 0;
                         }
                         Debug::text('Start Week Day ID: ' . $start_week_day_id, __FILE__, __LINE__, __METHOD__, 10);
                         $weekly_scheduled_total_time = 0;
                         if (strtolower($ep_obj->getType()) == 's9') {
                             $tmp_slf = new ScheduleListFactory();
                             $tmp_slf->getByUserIdAndStartDateAndEndDate($user_date_obj->getUser(), TTDate::getBeginWeekEpoch($user_date_obj->getDateStamp(), $start_week_day_id), $user_date_obj->getDateStamp());
                             if ($tmp_slf->getRecordCount() > 0) {
                                 foreach ($tmp_slf as $s_obj) {
                                     $weekly_scheduled_total_time += $s_obj->getTotalTime();
                                 }
                             }
                             unset($tmp_slf, $s_obj);
                         }
                         //This ONLY takes in to account WORKED hours, not paid absence hours.
                         $weekly_total_time = 0;
                         //Get daily total time.
                         $udtlf = new UserDateTotalListFactory();
                         $weekly_total_time = $udtlf->getWorkedTimeSumByUserIDAndStartDateAndEndDate($user_date_obj->getUser(), TTDate::getBeginWeekEpoch($user_date_obj->getDateStamp(), $start_week_day_id), $user_date_obj->getDateStamp());
                         Debug::text(' Weekly Total Time: ' . $weekly_total_time . ' Weekly Scheduled Total Time: ' . $weekly_scheduled_total_time . ' Watch Window: ' . $ep_obj->getWatchWindow() . ' Grace: ' . $ep_obj->getGrace() . ' User Date ID: ' . $user_date_id, __FILE__, __LINE__, __METHOD__, 10);
                         if (strtolower($ep_obj->getType()) == 'o2' and $weekly_total_time > 0 and $weekly_total_time > $ep_obj->getWatchWindow() or strtolower($ep_obj->getType()) == 's9' and $weekly_total_time > 0 and $weekly_total_time > $weekly_scheduled_total_time + $ep_obj->getGrace()) {
                             Debug::text(' Worked Over Weekly Hours', __FILE__, __LINE__, __METHOD__, 10);
                             $ef = new ExceptionFactory();
                             $ef->setUserDateID($user_date_id);
                             $ef->setExceptionPolicyID($ep_obj->getId());
                             $ef->setType($type_id);
                             $ef->setEnableDemerits(TRUE);
                             if ($ef->isValid()) {
                                 if ($enable_premature_exceptions == TRUE) {
                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                 }
                                 $ef->Save();
                             }
                         } else {
                             Debug::text(' DID NOT Work Over Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'l1':
                     //Long Lunch
                 //Long Lunch
                 case 'l2':
                     //Short Lunch
                     if ($plf->getRecordCount() > 0) {
                         //Get all lunch punches.
                         $pair = 0;
                         $x = 0;
                         $out_for_lunch = FALSE;
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 20 and $p_obj->getType() == 20) {
                                 $lunch_out_timestamp = $p_obj->getTimeStamp();
                                 $lunch_punch_arr[$pair]['punch_id'] = $p_obj->getId();
                                 $out_for_lunch = TRUE;
                             } elseif ($out_for_lunch == TRUE and $p_obj->getStatus() == 10 and $p_obj->getType() == 20) {
                                 $lunch_punch_arr[$pair][20] = $lunch_out_timestamp;
                                 $lunch_punch_arr[$pair][10] = $p_obj->getTimeStamp();
                                 $out_for_lunch = FALSE;
                                 $pair++;
                                 unset($lunch_out_timestamp);
                             } else {
                                 $out_for_lunch = FALSE;
                             }
                         }
                         if (isset($lunch_punch_arr)) {
                             Debug::Arr($lunch_punch_arr, 'Lunch Punch Array: ', __FILE__, __LINE__, __METHOD__, 10);
                             foreach ($lunch_punch_arr as $pair => $time_stamp_arr) {
                                 if (isset($time_stamp_arr[10]) and isset($time_stamp_arr[20])) {
                                     $lunch_total_time = bcsub($time_stamp_arr[10], $time_stamp_arr[20]);
                                     Debug::text(' Lunch Total Time: ' . $lunch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                     if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                         $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                     }
                                     //Check to see if they have a schedule policy
                                     if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE and is_object($p_obj->getScheduleObject()) == TRUE and is_object($p_obj->getScheduleObject()->getSchedulePolicyObject()) == TRUE) {
                                         $mp_obj = $p_obj->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject();
                                     } else {
                                         $mplf = new MealPolicyListFactory();
                                         $mplf->getByPolicyGroupUserId($user_date_obj->getUserObject()->getId());
                                         if ($mplf->getRecordCount() > 0) {
                                             Debug::text('Found Meal Policy to apply.', __FILE__, __LINE__, __METHOD__, 10);
                                             $mp_obj = $mplf->getCurrent();
                                         }
                                     }
                                     if (isset($mp_obj) and is_object($mp_obj)) {
                                         $meal_policy_lunch_time = $mp_obj->getAmount();
                                         Debug::text('Meal Policy Time: ' . $meal_policy_lunch_time, __FILE__, __LINE__, __METHOD__, 10);
                                         $add_exception = FALSE;
                                         if (strtolower($ep_obj->getType()) == 'l1' and $meal_policy_lunch_time > 0 and $lunch_total_time > 0 and $lunch_total_time > $meal_policy_lunch_time + $ep_obj->getGrace()) {
                                             $add_exception = TRUE;
                                         } elseif (strtolower($ep_obj->getType()) == 'l2' and $meal_policy_lunch_time > 0 and $lunch_total_time > 0 and $lunch_total_time < $meal_policy_lunch_time - $ep_obj->getGrace()) {
                                             $add_exception = TRUE;
                                         }
                                         if ($add_exception == TRUE) {
                                             Debug::text('Adding Exception!', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             if (isset($time_stamp_arr['punch_id'])) {
                                                 $ef->setPunchID($time_stamp_arr['punch_id']);
                                             }
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('Not Adding Exception!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     }
                                 } else {
                                     Debug::text(' Lunch Punches not paired... Skipping!', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         } else {
                             Debug::text(' No Lunch Punches found, or none are paired.', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'l3':
                     //No Lunch
                     if ($plf->getRecordCount() > 0) {
                         //If they are scheduled or not, we can check for a meal policy and base our
                         //decision off that. We don't want a No Lunch exception on a 3hr shift though.
                         //Also ignore this exception if the lunch is auto-deduct.
                         $daily_total_time = 0;
                         $udtlf = new UserDateTotalListFactory();
                         $udtlf->getByUserDateIdAndStatus($user_date_id, 20);
                         if ($udtlf->getRecordCount() > 0) {
                             foreach ($udtlf as $udt_obj) {
                                 $daily_total_time += $udt_obj->getTotalTime();
                             }
                         }
                         Debug::text('Day Total Time: ' . $daily_total_time, __FILE__, __LINE__, __METHOD__, 10);
                         if ($daily_total_time > 0) {
                             //Check for lunch punch.
                             $lunch_punch = FALSE;
                             foreach ($plf as $p_obj) {
                                 if ($p_obj->getType() == 20) {
                                     Debug::text('Found Lunch Punch: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
                                     $lunch_punch = TRUE;
                                     break;
                                 }
                             }
                             if ($lunch_punch == FALSE) {
                                 Debug::text('DID NOT Find Lunch Punch... Checking meal policies. ', __FILE__, __LINE__, __METHOD__, 10);
                                 //Use scheduled meal policy first.
                                 if ($slf->getRecordCount() > 0) {
                                     Debug::text('Schedule Found...', __FILE__, __LINE__, __METHOD__, 10);
                                     foreach ($slf as $s_obj) {
                                         if ($s_obj->getSchedulePolicyObject() !== FALSE and $s_obj->getSchedulePolicyObject()->getMealPolicyObject() !== FALSE and $s_obj->getSchedulePolicyObject()->getMealPolicyObject()->getType() != 10) {
                                             Debug::text('Found Schedule Meal Policy... Trigger Time: ' . $s_obj->getSchedulePolicyObject()->getMealPolicyObject()->getTriggerTime(), __FILE__, __LINE__, __METHOD__, 10);
                                             if ($daily_total_time > $s_obj->getSchedulePolicyObject()->getMealPolicyObject()->getTriggerTime()) {
                                                 Debug::text('Daily Total Time is After Schedule Meal Policy Trigger Time: ', __FILE__, __LINE__, __METHOD__, 10);
                                                 $ef = new ExceptionFactory();
                                                 $ef->setUserDateID($user_date_id);
                                                 $ef->setExceptionPolicyID($ep_obj->getId());
                                                 $ef->setType($type_id);
                                                 $ef->setEnableDemerits(TRUE);
                                                 if ($ef->isValid()) {
                                                     if ($enable_premature_exceptions == TRUE) {
                                                         $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                     }
                                                     $ef->Save();
                                                 }
                                             }
                                         } else {
                                             Debug::text('Schedule Meal Policy does not exist, or is auto-deduct?', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     }
                                 } else {
                                     Debug::text('No Schedule Found...', __FILE__, __LINE__, __METHOD__, 10);
                                     //Check if they have a meal policy, with no schedule.
                                     $mplf = new MealPolicyListFactory();
                                     $mplf->getByPolicyGroupUserId($user_date_obj->getUser());
                                     if ($mplf->getRecordCount() > 0) {
                                         Debug::text('Found UnScheduled Meal Policy...', __FILE__, __LINE__, __METHOD__, 10);
                                         $m_obj = $mplf->getCurrent();
                                         if ($daily_total_time > $m_obj->getTriggerTime() and $m_obj->getType() == 20) {
                                             Debug::text('Daily Total Time is After Schedule Meal Policy Trigger Time: ' . $m_obj->getTriggerTime(), __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('Auto-deduct meal policy, ignorning this exception.', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         //There is no  meal policy or schedule policy with a meal policy assigned to it
                                         //With out this we could still apply No Lunch exceptions, but they will happen even on
                                         //a 2minute shift.
                                         Debug::text('No meal policy, applying No Lunch exception.', __FILE__, __LINE__, __METHOD__, 10);
                                         $ef = new ExceptionFactory();
                                         $ef->setUserDateID($user_date_id);
                                         $ef->setExceptionPolicyID($ep_obj->getId());
                                         $ef->setType($type_id);
                                         $ef->setEnableDemerits(TRUE);
                                         if ($ef->isValid()) {
                                             if ($enable_premature_exceptions == TRUE) {
                                                 $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                             }
                                             $ef->Save();
                                         }
                                     }
                                 }
                             } else {
                                 Debug::text('Found Lunch Punch... Ignoring this exception. ', __FILE__, __LINE__, __METHOD__, 10);
                             }
                         }
                     }
                     break;
                 case 'b1':
                     //Long Break
                 //Long Break
                 case 'b2':
                     //Short Break
                     if ($plf->getRecordCount() > 0) {
                         //Get all break punches.
                         $pair = 0;
                         $x = 0;
                         $out_for_break = FALSE;
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 20 and $p_obj->getType() == 30) {
                                 $break_out_timestamp = $p_obj->getTimeStamp();
                                 $break_punch_arr[$pair]['punch_id'] = $p_obj->getId();
                                 $out_for_break = TRUE;
                             } elseif ($out_for_break == TRUE and $p_obj->getStatus() == 10 and $p_obj->getType() == 30) {
                                 $break_punch_arr[$pair][20] = $break_out_timestamp;
                                 $break_punch_arr[$pair][10] = $p_obj->getTimeStamp();
                                 $out_for_break = FALSE;
                                 $pair++;
                                 unset($break_out_timestamp);
                             } else {
                                 $out_for_break = FALSE;
                             }
                         }
                         unset($pair);
                         if (isset($break_punch_arr)) {
                             Debug::Arr($break_punch_arr, 'Break Punch Array: ', __FILE__, __LINE__, __METHOD__, 10);
                             foreach ($break_punch_arr as $pair => $time_stamp_arr) {
                                 if (isset($time_stamp_arr[10]) and isset($time_stamp_arr[20])) {
                                     $break_total_time = bcsub($time_stamp_arr[10], $time_stamp_arr[20]);
                                     Debug::text(' Break Total Time: ' . $break_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                     if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                         $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                     }
                                     //Check to see if they have a schedule policy
                                     $bplf = new BreakPolicyListFactory();
                                     if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE and is_object($p_obj->getScheduleObject()) == TRUE and is_object($p_obj->getScheduleObject()->getSchedulePolicyObject()) == TRUE) {
                                         $break_policy_ids = $p_obj->getScheduleObject()->getSchedulePolicyObject()->getBreakPolicyObject();
                                         $bplf->getByIdAndCompanyId($break_policy_ids, $user_date_obj->getUserObject()->getCompany());
                                     } else {
                                         $bplf->getByPolicyGroupUserId($user_date_obj->getUser());
                                     }
                                     unset($break_policy_ids);
                                     if ($bplf->getRecordCount() > 0) {
                                         Debug::text('Found Break Policy(ies) to apply: ' . $bplf->getRecordCount() . ' Pair: ' . $pair, __FILE__, __LINE__, __METHOD__, 10);
                                         foreach ($bplf as $bp_obj) {
                                             $bp_objs[] = $bp_obj;
                                         }
                                         unset($bplf, $bp_obj);
                                         if (isset($bp_objs[$pair]) and is_object($bp_objs[$pair])) {
                                             $bp_obj = $bp_objs[$pair];
                                             $break_policy_break_time = $bp_obj->getAmount();
                                             Debug::text('Break Policy Time: ' . $break_policy_break_time . ' ID: ' . $bp_obj->getID(), __FILE__, __LINE__, __METHOD__, 10);
                                             $add_exception = FALSE;
                                             if (strtolower($ep_obj->getType()) == 'b1' and $break_policy_break_time > 0 and $break_total_time > 0 and $break_total_time > $break_policy_break_time + $ep_obj->getGrace()) {
                                                 $add_exception = TRUE;
                                             } elseif (strtolower($ep_obj->getType()) == 'b2' and $break_policy_break_time > 0 and $break_total_time > 0 and $break_total_time < $break_policy_break_time - $ep_obj->getGrace()) {
                                                 $add_exception = TRUE;
                                             }
                                             if ($add_exception == TRUE) {
                                                 Debug::text('Adding Exception! ' . $ep_obj->getType(), __FILE__, __LINE__, __METHOD__, 10);
                                                 $ef = new ExceptionFactory();
                                                 $ef->setUserDateID($user_date_id);
                                                 $ef->setExceptionPolicyID($ep_obj->getId());
                                                 if (isset($time_stamp_arr['punch_id'])) {
                                                     $ef->setPunchID($time_stamp_arr['punch_id']);
                                                 }
                                                 $ef->setType($type_id);
                                                 $ef->setEnableDemerits(TRUE);
                                                 if ($ef->isValid()) {
                                                     if ($enable_premature_exceptions == TRUE) {
                                                         $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                     }
                                                     $ef->Save();
                                                 }
                                             } else {
                                                 Debug::text('Not Adding Exception!', __FILE__, __LINE__, __METHOD__, 10);
                                             }
                                             unset($bp_obj);
                                         }
                                         unset($bp_objs);
                                     }
                                 } else {
                                     Debug::text(' Break Punches not paired... Skipping!', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         } else {
                             Debug::text(' No Break Punches found, or none are paired.', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'b3':
                     //Too Many Breaks
                 //Too Many Breaks
                 case 'b4':
                     //Too Few Breaks
                     if ($plf->getRecordCount() > 0) {
                         //Get all break punches.
                         $pair = 0;
                         $x = 0;
                         $out_for_break = FALSE;
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 20 and $p_obj->getType() == 30) {
                                 $break_out_timestamp = $p_obj->getTimeStamp();
                                 $break_punch_arr[$pair]['punch_id'] = $p_obj->getId();
                                 $out_for_break = TRUE;
                             } elseif ($out_for_break == TRUE and $p_obj->getStatus() == 10 and $p_obj->getType() == 30) {
                                 $break_punch_arr[$pair][20] = $break_out_timestamp;
                                 $break_punch_arr[$pair][10] = $p_obj->getTimeStamp();
                                 $out_for_break = FALSE;
                                 $pair++;
                                 unset($break_out_timestamp);
                             } else {
                                 $out_for_break = FALSE;
                             }
                         }
                         unset($pair);
                         if (isset($break_punch_arr)) {
                             $total_breaks = count($break_punch_arr);
                             Debug::Arr($break_punch_arr, 'Break Punch Array: ', __FILE__, __LINE__, __METHOD__, 10);
                             foreach ($break_punch_arr as $pair => $time_stamp_arr) {
                                 if (isset($time_stamp_arr[10]) and isset($time_stamp_arr[20])) {
                                     $break_total_time = bcsub($time_stamp_arr[10], $time_stamp_arr[20]);
                                     Debug::text(' Break Total Time: ' . $break_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                     if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                         $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                     }
                                     //Check to see if they have a schedule policy
                                     $bplf = new BreakPolicyListFactory();
                                     if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE and is_object($p_obj->getScheduleObject()) == TRUE and is_object($p_obj->getScheduleObject()->getSchedulePolicyObject()) == TRUE) {
                                         $break_policy_ids = $p_obj->getScheduleObject()->getSchedulePolicyObject()->getBreakPolicyObject();
                                         $bplf->getByIdAndCompanyId($break_policy_ids, $user_date_obj->getUserObject()->getCompany());
                                     } else {
                                         $bplf->getByPolicyGroupUserId($user_date_obj->getUser());
                                     }
                                     unset($break_policy_ids);
                                     $allowed_breaks = $bplf->getRecordCount();
                                     $add_exception = FALSE;
                                     if (strtolower($ep_obj->getType()) == 'b3' and $total_breaks > $allowed_breaks) {
                                         Debug::text(' Too many breaks taken...', __FILE__, __LINE__, __METHOD__, 10);
                                         $add_exception = TRUE;
                                     } elseif (strtolower($ep_obj->getType()) == 'b4' and $total_breaks < $allowed_breaks) {
                                         Debug::text(' Too few breaks taken...', __FILE__, __LINE__, __METHOD__, 10);
                                         $add_exception = TRUE;
                                     } else {
                                         Debug::text(' Proper number of breaks taken...', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                     if ($add_exception == TRUE and (strtolower($ep_obj->getType()) == 'b4' or strtolower($ep_obj->getType()) == 'b3' and $pair > $allowed_breaks - 1)) {
                                         Debug::text('Adding Exception! ' . $ep_obj->getType(), __FILE__, __LINE__, __METHOD__, 10);
                                         $ef = new ExceptionFactory();
                                         $ef->setUserDateID($user_date_id);
                                         $ef->setExceptionPolicyID($ep_obj->getId());
                                         if (isset($time_stamp_arr['punch_id']) and strtolower($ep_obj->getType()) == 'b3') {
                                             $ef->setPunchID($time_stamp_arr['punch_id']);
                                         }
                                         $ef->setType($type_id);
                                         $ef->setEnableDemerits(TRUE);
                                         if ($ef->isValid()) {
                                             if ($enable_premature_exceptions == TRUE) {
                                                 $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                             }
                                             $ef->Save();
                                         }
                                     } else {
                                         Debug::text('Not Adding Exception!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 }
                             }
                         }
                     }
                     break;
                 case 'j1':
                     //Not Allowed on Job
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 10) {
                                 //In punches
                                 if (is_object($p_obj->getPunchControlObject()) and $p_obj->getPunchControlObject()->getJob() > 0) {
                                     //Found job punch, check job settings.
                                     $jlf = new JobListFactory();
                                     $jlf->getById($p_obj->getPunchControlObject()->getJob());
                                     if ($jlf->getRecordCount() > 0) {
                                         $j_obj = $jlf->getCurrent();
                                         if ($j_obj->isAllowedUser($user_date_obj->getUser()) == FALSE) {
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setType($type_id);
                                             $ef->setPunchControlId($p_obj->getPunchControlId());
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;User allowed on Job!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job not found!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Not a Job Punch...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($j_obj);
                     }
                     break;
                 case 'j2':
                     //Not Allowed on Task
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 10) {
                                 //In punches
                                 if (is_object($p_obj->getPunchControlObject()) and $p_obj->getPunchControlObject()->getJob() > 0 and $p_obj->getPunchControlObject()->getJobItem() > 0) {
                                     //Found job punch, check job settings.
                                     $jlf = new JobListFactory();
                                     $jlf->getById($p_obj->getPunchControlObject()->getJob());
                                     if ($jlf->getRecordCount() > 0) {
                                         $j_obj = $jlf->getCurrent();
                                         if ($j_obj->isAllowedItem($p_obj->getPunchControlObject()->getJobItem()) == FALSE) {
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setType($type_id);
                                             $ef->setPunchControlId($p_obj->getPunchControlId());
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job item allowed on job!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job not found!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Not a Job Punch...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($j_obj);
                     }
                     break;
                 case 'j3':
                     //Job already completed
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 10) {
                                 //In punches
                                 if (is_object($p_obj->getPunchControlObject()) and $p_obj->getPunchControlObject()->getJob() > 0) {
                                     //Found job punch, check job settings.
                                     $jlf = new JobListFactory();
                                     $jlf->getById($p_obj->getPunchControlObject()->getJob());
                                     if ($jlf->getRecordCount() > 0) {
                                         $j_obj = $jlf->getCurrent();
                                         //Status is completed and the User Date Stamp is greater then the job end date.
                                         //If no end date is set, ignore this.
                                         if ($j_obj->getStatus() == 30 and $j_obj->getEndDate() != FALSE and $user_date_obj->getDateStamp() > $j_obj->getEndDate()) {
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setType($type_id);
                                             $ef->setPunchControlId($p_obj->getPunchControlId());
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job Not Completed!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job not found!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Not a Job Punch...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($j_obj);
                     }
                     break;
                 case 'j4':
                     //No Job or Task
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             //In punches only
                             if ($p_obj->getStatus() == 10 and is_object($p_obj->getPunchControlObject()) and ($p_obj->getPunchControlObject()->getJob() == '' or $p_obj->getPunchControlObject()->getJob() == 0 or $p_obj->getPunchControlObject()->getJob() == FALSE or $p_obj->getPunchControlObject()->getJobItem() == '' or $p_obj->getPunchControlObject()->getJobItem() == 0 or $p_obj->getPunchControlObject()->getJobItem() == FALSE)) {
                                 $ef = new ExceptionFactory();
                                 $ef->setUserDateID($user_date_id);
                                 $ef->setExceptionPolicyID($ep_obj->getId());
                                 $ef->setType($type_id);
                                 $ef->setPunchControlId($p_obj->getPunchControlId());
                                 $ef->setPunchId($p_obj->getId());
                                 $ef->setEnableDemerits(TRUE);
                                 if ($ef->isValid()) {
                                     if ($enable_premature_exceptions == TRUE) {
                                         $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                     }
                                     $ef->Save();
                                 }
                             }
                         }
                     }
                     break;
                 default:
                     Debug::text('BAD, should never get here: ', __FILE__, __LINE__, __METHOD__, 10);
                     break;
             }
         }
     }
     $profiler->stopTimer("ExceptionPolicy::calcExceptions()");
     return TRUE;
 }