$slf = new ScheduleListFactory();
 //$slf->getReportByPayPeriodIdAndUserId($filter_data['pay_period_ids'], $filter_data['user_ids']);
 $slf->getReportByCompanyIdAndArrayCriteria($current_company->getId(), $filter_data);
 if ($slf->getRecordCount() > 0) {
     foreach ($slf as $s_obj) {
         $user_id = $s_obj->getColumn('user_id');
         $pay_period_id = $s_obj->getColumn('pay_period_id');
         $status_id = $s_obj->getColumn('status_id');
         $status = strtolower(Option::getByKey($status_id, $s_obj->getOptions('status')));
         $schedule_rows[$user_id][$pay_period_id][$status] = $s_obj->getColumn('total_time');
         unset($user_id, $pay_period_id, $status_id, $status);
     }
 }
 //var_dump($schedule_rows);
 $pay_period_ids = array();
 $udtlf = new UserDateTotalListFactory();
 //$udtlf->getReportByPayPeriodIDListAndUserIdList($filter_data['pay_period_ids'], $filter_data['user_ids'], array($filter_data['primary_sort'] => 'asc') );
 $udtlf->getReportByCompanyIdAndArrayCriteria($current_company->getId(), $filter_data);
 foreach ($udtlf as $udt_obj) {
     $user_id = $udt_obj->getColumn('id');
     $pay_period_id = $udt_obj->getColumn('pay_period_id');
     $pay_period_ids[$pay_period_id] = NULL;
     //Keep list of all pay periods for timesheet verify.
     $status_id = $udt_obj->getColumn('status_id');
     $type_id = $udt_obj->getColumn('type_id');
     if ($status_id == 10 and $type_id == 10) {
         $column = 'paid_time';
     } elseif ($status_id == 10 and $type_id == 20) {
         $column = 'regular_time';
     } elseif ($status_id == 10 and $type_id == 30) {
         $column = 'over_time_policy-' . $udt_obj->getColumn('over_time_policy_id');
                     $udt_obj->setEnableCalcSystemTotalTime(TRUE);
                 }
                 $udt_obj->Save();
             }
             $i++;
         }
     }
     Redirect::Page(URLBuilder::getURL(array('user_id' => $user_id, 'filter_date' => $filter_date), 'UserDateTotalList.php'));
     break;
 default:
     if ((!isset($user_date_id) or isset($user_date_id) and $user_date_id == '') and $user_id != '' and $filter_date != '') {
         Debug::Text('User Date ID not passed, inserting one.', __FILE__, __LINE__, __METHOD__, 10);
         $user_date_id = UserDateFactory::findOrInsertUserDate($user_id, $filter_date);
     }
     if ($user_date_id != '') {
         $udtlf = new UserDateTotalListFactory();
         $udtlf->getByUserDateIDAndStatusAndType($user_date_id, array(10, 20, 30), array(10, 20, 30, 40, 100), $current_user_prefs->getItemsPerPage(), $page, NULL, $sort_array);
         $pager = new Pager($udtlf);
         $blf = new BranchListFactory();
         $branch_options = $blf->getByCompanyIdArray($current_company->getId());
         $dlf = new DepartmentListFactory();
         $department_options = $dlf->getByCompanyIdArray($current_company->getId());
         //Absence policies
         $otplf = new AbsencePolicyListFactory();
         $absence_policy_options = $otplf->getByCompanyIDArray($current_company->getId(), TRUE);
         //Overtime policies
         $otplf = new OverTimePolicyListFactory();
         $over_time_policy_options = $otplf->getByCompanyIDArray($current_company->getId(), TRUE);
         //Premium policies
         $pplf = new PremiumPolicyListFactory();
         $premium_policy_options = $pplf->getByCompanyIDArray($current_company->getId(), TRUE);
 function postSave()
 {
     $this->removeCache($this->getId());
     Debug::Text('Post Save... Deleted: ' . (int) $this->getDeleted(), __FILE__, __LINE__, __METHOD__, 10);
     //Delete punch control/schedules assigned to this.
     if ($this->getDeleted() == TRUE) {
         //Delete schedules assigned to this user date.
         //Turn off any re-calc's
         $slf = new ScheduleListFactory();
         $slf->getByUserDateID($this->getId());
         if ($slf->getRecordCount() > 0) {
             foreach ($slf as $schedule_obj) {
                 $schedule_obj->setDeleted(TRUE);
                 $schedule_obj->Save();
             }
         }
         $pclf = new PunchControlListFactory();
         $pclf->getByUserDateID($this->getId());
         if ($pclf->getRecordCount() > 0) {
             foreach ($pclf as $pc_obj) {
                 $pc_obj->setDeleted(TRUE);
                 $pc_obj->Save();
             }
         }
         //Delete user_date_total rows too
         $udtlf = new UserDateTotalListFactory();
         $udtlf->getByUserDateID($this->getId());
         if ($udtlf->getRecordCount() > 0) {
             foreach ($udtlf as $udt_obj) {
                 $udt_obj->setDeleted(TRUE);
                 $udt_obj->Save();
             }
         }
     }
     return TRUE;
 }
 function calcUserDateTotal()
 {
     if ($this->getEnableCalcUserDateTotal() == TRUE) {
         Debug::Text(' Calculating User Date Total...', __FILE__, __LINE__, __METHOD__, 10);
         //Add a row to the user date total table, as "worked" hours.
         //Edit if it already exists and is not set as override.
         $udtlf = new UserDateTotalListFactory();
         $udtlf->getByUserDateIdAndPunchControlId($this->getUserDateID(), $this->getId());
         Debug::text(' Checking for Conflicting User Date Total Records, count: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
         if ($udtlf->getRecordCount() > 0) {
             Debug::text(' Found Conflicting User Date Total Records, removing them before re-calc', __FILE__, __LINE__, __METHOD__, 10);
             foreach ($udtlf as $udt_obj) {
                 if ($udt_obj->getOverride() == FALSE) {
                     Debug::text(' bFound Conflicting User Date Total Records, removing them before re-calc', __FILE__, __LINE__, __METHOD__, 10);
                     $udt_obj->Delete();
                 }
             }
         }
         Debug::text(' cFound Conflicting User Date Total Records, removing them before re-calc: PreMature: ' . (int) $this->getEnablePreMatureException(), __FILE__, __LINE__, __METHOD__, 10);
         if ($this->getDeleted() == FALSE) {
             Debug::text(' Calculating Total Time for day. Punch Control ID: ' . $this->getId(), __FILE__, __LINE__, __METHOD__, 10);
             $udtf = new UserDateTotalFactory();
             $udtf->setUserDateID($this->getUserDateID());
             $udtf->setPunchControlID($this->getId());
             $udtf->setStatus(20);
             //Worked
             $udtf->setType(10);
             //Total
             $udtf->setBranch($this->getBranch());
             $udtf->setDepartment($this->getDepartment());
             $udtf->setJob($this->getJob());
             $udtf->setJobItem($this->getJobItem());
             $udtf->setQuantity($this->getQuantity());
             $udtf->setBadQuantity($this->getBadQuantity());
             $udtf->setTotalTime($this->getTotalTime());
             $udtf->setActualTotalTime($this->getActualTotalTime());
             //Let smartReCalculate handle calculating totals/exceptions.
             if ($udtf->isValid()) {
                 $udtf->Save();
             }
         }
     }
     return FALSE;
 }
 function reCalculate()
 {
     //Re-generate final pay stub
     //get current pay period based off their last day of work
     $pplf = new PayPeriodListFactory();
     $pay_period_id = $pplf->getByUserIdAndEndDate($this->getUser(), $this->getLastDate())->getCurrent()->getId();
     Debug::Text('Pay Period ID: ' . $pay_period_id, __FILE__, __LINE__, __METHOD__, 10);
     if (is_numeric($pay_period_id) == FALSE) {
         UserGenericStatusFactory::queueGenericStatus($this->getUserObject()->getFullName(TRUE) . ' - ' . TTi18n::gettext('Pay Stub'), 10, TTi18n::gettext('Pay Period is invalid!'), NULL);
         return FALSE;
     }
     if ($this->getEnableGeneratePayStub() == TRUE) {
         //Find out if a pay stub is already generated for the pay period we are currently in.
         //If it is, delete it so we can start from fresh
         $pslf = new PayStubListFactory();
         $pslf->getByUserIdAndPayPeriodId($this->getUser(), $pay_period_id);
         foreach ($pslf as $pay_stub) {
             Debug::Text('Found Pay Stub ID: ' . $pay_stub->getId(), __FILE__, __LINE__, __METHOD__, 10);
             //Do not delete PAID pay stubs!
             if ($pay_stub->getStatus() == 10) {
                 Debug::Text('Last Pay Stub Exists: ' . $pay_stub->getId(), __FILE__, __LINE__, __METHOD__, 10);
                 $pay_stub->setDeleted(TRUE);
                 $pay_stub->Save();
             }
         }
         //FIXME: Make sure user isn't already in-active! Otherwise pay stub won't generate.
         //Check if pay stub is already generated as well, if it is, and marked paid, then
         //we can't re-generate it, we need to skip this step.
         Debug::Text('Calculating Pay Stub...', __FILE__, __LINE__, __METHOD__, 10);
         $cps = new CalculatePayStub();
         $cps->setUser($this->getUser());
         $cps->setPayPeriod($pay_period_id);
         $cps->calculate();
         Debug::Text('Done Calculating Pay Stub', __FILE__, __LINE__, __METHOD__, 10);
     } else {
         UserGenericStatusFactory::queueGenericStatus($this->getUserObject()->getFullName(TRUE), 20, TTi18n::gettext('Not generating final pay stub!'), NULL);
     }
     //FIXME: Alert the user if they don't have enough information in TimeTrex to get accurate values.
     //Get insurable hours, earnings, and vacation pay now that the final pay stub is generated
     $ugdlf = new UserGenericDataListFactory();
     $ugdlf->getByCompanyIdAndScriptAndDefault($this->getUserObject()->getCompany(), $this->getTable());
     if ($ugdlf->getRecordCount() > 0) {
         Debug::Text('Found Company Form Setup!', __FILE__, __LINE__, __METHOD__, 10);
         $ugd_obj = $ugdlf->getCurrent();
         $setup_data = $ugd_obj->getData();
     }
     unset($ugd_obj);
     if (isset($setup_data)) {
         //var_dump($setup_data);
         if (isset($setup_data['insurable_earnings_psea_ids'])) {
             $insurable_earnings_psea_ids = $setup_data['insurable_earnings_psea_ids'];
         } else {
             //Fall back to Total Gross.
             $insurable_earnings_psea_ids = $this->getPayStubEntryAccountLinkObject()->getTotalGross();
         }
     }
     //Find out the date of how far back we have to go to get insurable values.
     //Insurable Hours
     $insurable_hours_start_date = $this->getInsurablePayPeriodStartDate($this->getInsurableHoursReportPayPeriods());
     //Insurable hours dont include stats!Just get total signed in hours.
     //If someone has just a negative bank time balance, those are NOT insurable.
     $udtlf = new UserDateTotalListFactory();
     $worked_total_time = $udtlf->getWorkedTimeSumByUserIDAndStartDateAndEndDate($this->getUser(), $insurable_hours_start_date, $this->getLastDate());
     Debug::text('Worked Total Time: ' . $worked_total_time, __FILE__, __LINE__, __METHOD__, 10);
     $total_hours = Misc::MoneyFormat(TTDate::getHours($worked_total_time), FALSE);
     Debug::Text('Total Insurable Hours: ' . $total_hours, __FILE__, __LINE__, __METHOD__, 10);
     $insurable_earnings_start_date = $this->getInsurablePayPeriodStartDate($this->getInsurableEarningsReportPayPeriods());
     $pself = new PayStubEntryListFactory();
     $total_earnings = $this->getTotalInsurableEarnings();
     //$total_earnings = $pself->getAmountSumByUserIdAndEntryNameIdAndStartDateAndEndDate( $this->getUser(), $insurable_earnings_psea_ids, $insurable_earnings_start_date, $this->getLastDate(), 0 );
     //$total_earnings = $total_earnings['amount'];
     //Note, this includes the current pay stub we just generated
     Debug::Text('Total Insurable Earnings: ' . $total_earnings, __FILE__, __LINE__, __METHOD__, 10);
     UserGenericStatusFactory::queueGenericStatus($this->getUserObject()->getFullName(TRUE) . ' - ' . TTi18n::gettext('Record of Employment'), 30, TTi18n::gettext('Insurable Hours:') . ' ' . $total_hours . ' ' . TTi18n::gettext('Insurable Earnings:') . ' ' . $total_earnings, NULL);
     //ReSave these
     if ($this->getId() != '') {
         $rlf = new ROEListFactory();
         $rlf->getById($this->getId());
         if ($rlf->getRecordCount() > 0) {
             $roe_obj = $rlf->getCurrent();
             $roe_obj->setInsurableHours($total_hours);
             $roe_obj->setInsurableEarnings($total_earnings);
             if ($roe_obj->isValid()) {
                 $roe_obj->Save();
             }
         }
     }
     return TRUE;
 }
 function Validate()
 {
     if ($this->getDeleted() == TRUE) {
         //Check to make sure there are no hours using this OT policy.
         $udtlf = new UserDateTotalListFactory();
         $udtlf->getByAbsencePolicyId($this->getId());
         if ($udtlf->getRecordCount() > 0) {
             $this->Validator->isTRUE('in_use', FALSE, TTi18n::gettext('This absence policy is in use'));
         }
     }
     return TRUE;
 }
         $udtf->setOverride(TRUE);
     } else {
         $udtf->setOverride(FALSE);
     }
     if ($udtf->isValid()) {
         $udtf->setEnableCalcSystemTotalTime(TRUE);
         $udtf->setEnableCalcWeeklySystemTotalTime(TRUE);
         $udtf->setEnableCalcException(TRUE);
         $udtf->Save();
         Redirect::Page(URLBuilder::getURL(array('refresh' => TRUE), '../CloseWindow.php'));
         break;
     }
 default:
     if ($id != '') {
         Debug::Text(' ID was passed: ' . $id, __FILE__, __LINE__, __METHOD__, 10);
         $udtlf = new UserDateTotalListFactory();
         $udtlf->getById($id);
         foreach ($udtlf as $udt_obj) {
             //Debug::Arr($station,'Department', __FILE__, __LINE__, __METHOD__,10);
             $udt_data = array('id' => $udt_obj->getId(), 'user_date_id' => $udt_obj->getUserDateId(), 'date_stamp' => $udt_obj->getUserDateObject()->getDateStamp(), 'user_id' => $udt_obj->getUserDateObject()->getUser(), 'user_full_name' => $udt_obj->getUserDateObject()->getUserObject()->getFullName(), 'status_id' => $udt_obj->getStatus(), 'type_id' => $udt_obj->getType(), 'total_time' => $udt_obj->getTotalTime(), 'branch_id' => $udt_obj->getBranch(), 'department_id' => $udt_obj->getDepartment(), 'job_id' => $udt_obj->getJob(), 'job_item_id' => $udt_obj->getJobItem(), 'quantity' => $udt_obj->getQuantity(), 'bad_quantity' => $udt_obj->getBadQuantity(), 'punch_control_id' => $udt_obj->getPunchControlID(), 'absence_policy_id' => $udt_obj->getAbsencePolicyID(), 'over_time_policy_id' => $udt_obj->getOverTimePolicyID(), 'premium_policy_id' => $udt_obj->getPremiumPolicyID(), 'meal_policy_id' => $udt_obj->getMealPolicyID(), 'override' => $udt_obj->getOverride(), 'created_date' => $udt_obj->getCreatedDate(), 'created_by' => $udt_obj->getCreatedBy(), 'updated_date' => $udt_obj->getUpdatedDate(), 'updated_by' => $udt_obj->getUpdatedBy(), 'deleted_date' => $udt_obj->getDeletedDate(), 'deleted_by' => $udt_obj->getDeletedBy(), 'override' => $udt_obj->getOverride());
         }
     } elseif ($action != 'submit') {
         Debug::Text(' ID was NOT passed: ' . $id, __FILE__, __LINE__, __METHOD__, 10);
         //UserID has to be set at minimum
         if ($user_date_id != '') {
             $udlf = new UserDateListFactory();
             $udlf->getById($user_date_id);
             if ($udlf->getRecordCount() > 0) {
                 $udt_obj = $udlf->getCurrent();
                 $udt_data = array('user_date_id' => $user_date_id, 'date_stamp' => $udt_obj->getDateStamp(), 'user_id' => $udt_obj->getUser(), 'user_full_name' => $udt_obj->getUserObject()->getFullName(), 'branch_id' => $udt_obj->getUserObject()->getDefaultBranch(), 'department_id' => $udt_obj->getUserObject()->getDefaultDepartment(), 'total_time' => 0, 'status_id' => 20, 'quantity' => 0, 'bad_quantity' => 0, 'punch_control_id' => 0, 'override' => FALSE);
             }
 function Validate()
 {
     //Make sure status/type combinations are correct.
     if (!in_array($this->getType(), $this->getOptions('status_type', $this->getStatus()))) {
         Debug::text('Type doesnt match status: Type: ' . $this->getType() . ' Status: ' . $this->getStatus(), __FILE__, __LINE__, __METHOD__, 10);
         $this->Validator->isTRUE('type', FALSE, TTi18n::gettext('Incorrect Type'));
     }
     //Check to make sure if this is an absence row, the absence policy is actually set.
     if ($this->getStatus() == 30 and $this->getAbsencePolicyID() == FALSE) {
         $this->Validator->isTRUE('absence_policy', FALSE, TTi18n::gettext('Invalid Absence Policy'));
     }
     //Check to make sure if this is an overtime row, the overtime policy is actually set.
     if ($this->getStatus() == 10 and $this->getType() == 30 and $this->getOverTimePolicyID() == FALSE) {
         $this->Validator->isTRUE('over_time_policy', FALSE, TTi18n::gettext('Invalid Overtime Policy'));
     }
     //Check to make sure if this is an premium row, the premium policy is actually set.
     if ($this->getStatus() == 10 and $this->getType() == 40 and $this->getPremiumPolicyID() == FALSE) {
         $this->Validator->isTRUE('premium_policy', FALSE, TTi18n::gettext('Invalid Premium Policy'));
     }
     //Check to make sure if this is an meal row, the meal policy is actually set.
     if ($this->getStatus() == 10 and $this->getType() == 100 and $this->getMealPolicyID() == FALSE) {
         $this->Validator->isTRUE('meal_policy', FALSE, TTi18n::gettext('Invalid Meal Policy'));
     }
     //Make sure that we aren't trying to overwrite an already overridden entry made by the user for some special purpose.
     if ($this->getDeleted() == FALSE and $this->isNew() == TRUE and in_array($this->getStatus(), array(10, 20, 30))) {
         Debug::text('Checking over already existing overridden entries ... User Date ID: ' . $this->getUserDateID() . ' Status ID: ' . $this->getStatus() . ' Type ID: ' . $this->getType(), __FILE__, __LINE__, __METHOD__, 10);
         $udtlf = new UserDateTotalListFactory();
         if ($this->getStatus() == 20 and $this->getPunchControlID() > 0) {
             $udtlf->getByUserDateIdAndStatusAndTypeAndPunchControlIdAndOverride($this->getUserDateID(), $this->getStatus(), $this->getType(), $this->getPunchControlID(), TRUE);
         } elseif ($this->getStatus() == 30) {
             $udtlf->getByUserDateIdAndStatusAndTypeAndAbsencePolicyIDAndOverride($this->getUserDateID(), $this->getStatus(), $this->getType(), $this->getAbsencePolicyID(), TRUE);
         } elseif ($this->getStatus() == 10 and $this->getType() == 30) {
             $udtlf->getByUserDateIdAndStatusAndTypeAndOvertimePolicyIDAndOverride($this->getUserDateID(), $this->getStatus(), $this->getType(), $this->getOverTimePolicyID(), TRUE);
         } elseif ($this->getStatus() == 10 and $this->getType() == 40) {
             $udtlf->getByUserDateIdAndStatusAndTypeAndPremiumPolicyIDAndOverride($this->getUserDateID(), $this->getStatus(), $this->getType(), $this->getPremiumPolicyID(), TRUE);
         } elseif ($this->getStatus() == 10 and $this->getType() == 100) {
             $udtlf->getByUserDateIdAndStatusAndTypeAndMealPolicyIDAndOverride($this->getUserDateID(), $this->getStatus(), $this->getType(), $this->getMealPolicyID(), TRUE);
         } elseif ($this->getStatus() == 10 and ($this->getType() == 10 or $this->getType() == 20 and $this->getPunchControlID() > 0)) {
             $udtlf->getByUserDateIdAndStatusAndTypeAndPunchControlIdAndOverride($this->getUserDateID(), $this->getStatus(), $this->getType(), $this->getPunchControlID(), TRUE);
         }
         Debug::text('Record Count: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
         if ($udtlf->getRecordCount() > 0) {
             Debug::text('Found an overridden row... NOT SAVING: ' . $udtlf->getCurrent()->getId(), __FILE__, __LINE__, __METHOD__, 10);
             $this->Validator->isTRUE('override', FALSE, TTi18n::gettext('Similar entry already exists, not overriding'));
         }
     }
     return TRUE;
 }
             //Get verified timesheets
             $pptsvlf = new PayPeriodTimeSheetVerifyListFactory();
             $pptsvlf->getByPayPeriodIdAndCompanyId($pay_period_obj->getId(), $current_company->getId());
             $verified_time_sheets = 0;
             $pending_time_sheets = 0;
             if ($pptsvlf->getRecordCount() > 0) {
                 foreach ($pptsvlf as $pptsv_obj) {
                     if ($pptsv_obj->getAuthorized() == TRUE) {
                         $verified_time_sheets++;
                     } elseif ($pptsv_obj->getStatus() == 30) {
                         $pending_time_sheets++;
                     }
                 }
             }
             //Get total employees with time for this pay period.
             $udtlf = new UserDateTotalListFactory();
             $total_worked_users = $udtlf->getWorkedUsersByPayPeriodId($pay_period_obj->getId());
             //Count how many pay stubs for each pay period.
             $pslf = new PayStubListFactory();
             $total_pay_stubs = $pslf->getByPayPeriodId($pay_period_obj->getId())->getRecordCount();
             if ($pay_period_obj->getStatus() != 20) {
                 $open_pay_periods = TRUE;
             }
             $pay_periods[] = array('id' => $pay_period_obj->getId(), 'company_id' => $pay_period_obj->getCompany(), 'pay_period_schedule_id' => $pay_period_obj->getPayPeriodSchedule(), 'name' => $pay_period_schedule->getName(), 'type' => Option::getByKey($pay_period_schedule->getType(), $pay_period_schedule->getOptions('type')), 'status' => Option::getByKey($pay_period_obj->getStatus(), $pay_period_obj->getOptions('status')), 'start_date' => TTDate::getDate('DATE+TIME', $pay_period_obj->getStartDate()), 'end_date' => TTDate::getDate('DATE+TIME', $pay_period_obj->getEndDate()), 'transaction_date' => TTDate::getDate('DATE+TIME', $pay_period_obj->getTransactionDate()), 'low_severity_exceptions' => $low_severity_exceptions, 'med_severity_exceptions' => $med_severity_exceptions, 'high_severity_exceptions' => $high_severity_exceptions, 'pending_requests' => $pending_requests, 'verified_time_sheets' => $verified_time_sheets, 'pending_time_sheets' => $pending_time_sheets, 'total_worked_users' => $total_worked_users, 'total_ps_amendments' => $total_ps_amendments, 'total_pay_stubs' => $total_pay_stubs, 'deleted' => $pay_period_obj->getDeleted());
         }
         unset($total_shifts, $total_ps_amendments, $total_pay_stubs, $verified_time_sheets, $total_worked_users);
     }
 } else {
     Debug::Text('No pay periods pending transaction ', __FILE__, __LINE__, __METHOD__, 10);
 }
 $smarty->assign_by_ref('open_pay_periods', $open_pay_periods);
 function isEligible($user_id)
 {
     if ($user_id == '') {
         return FALSE;
     }
     //$this->getHolidayPolicyObject();
     $ulf = new UserListFactory();
     $user_obj = $ulf->getById($user_id)->getCurrent();
     $slf = new ScheduleListFactory();
     $udtlf = new UserDateTotalListFactory();
     //Make sure the employee has been employed long enough according to labor standards
     //Also make sure that the employee hasn't been terminated on or before the holiday.
     if ($user_obj->getHireDate() <= $this->getDateStamp() - $this->getHolidayPolicyObject()->getMinimumEmployedDays() * 86400 and ($user_obj->getTerminationDate() == '' or $user_obj->getTerminationDate() != '' and $user_obj->getTerminationDate() > $this->getDateStamp())) {
         Debug::text('Employee has been employed long enough!', __FILE__, __LINE__, __METHOD__, 10);
         if ($this->getHolidayPolicyObject()->getType() == 20 or $this->getHolidayPolicyObject()->getType() == 30) {
             if ($this->getHolidayPolicyObject()->getWorkedScheduledDays() == TRUE and $this->getHolidayPolicyObject()->getMinimumWorkedDays() > 0 and $this->getHolidayPolicyObject()->getMinimumWorkedPeriodDays() > 0) {
                 Debug::text('aUsing scheduled days!', __FILE__, __LINE__, __METHOD__, 10);
                 $slf->getByUserIdAndTypeAndDirectionFromDate($user_obj->getId(), 10, 'before', $this->getDateStamp(), $this->getHolidayPolicyObject()->getMinimumWorkedPeriodDays());
                 if ($slf->getRecordCount() > 0) {
                     //Get user_date_ids
                     foreach ($slf as $s_obj) {
                         $scheduled_user_date_ids_before[] = $s_obj->getUserDateID();
                     }
                     //Debug::Arr($scheduled_user_date_ids_before, 'Scheduled UserDateIDs Before: ', __FILE__, __LINE__, __METHOD__,10);
                 }
             } else {
                 Debug::text('aUsing calendar days, NOT scheduled days!', __FILE__, __LINE__, __METHOD__, 10);
             }
             if ($this->getHolidayPolicyObject()->getWorkedAfterScheduledDays() == TRUE and $this->getHolidayPolicyObject()->getMinimumWorkedAfterDays() > 0 and $this->getHolidayPolicyObject()->getMinimumWorkedAfterPeriodDays() > 0) {
                 $slf->getByUserIdAndTypeAndDirectionFromDate($user_obj->getId(), 10, 'after', $this->getDateStamp(), $this->getHolidayPolicyObject()->getMinimumWorkedAfterPeriodDays());
                 Debug::text('bUsing scheduled days!', __FILE__, __LINE__, __METHOD__, 10);
                 if ($slf->getRecordCount() > 0) {
                     //Get user_date_ids
                     foreach ($slf as $s_obj) {
                         $scheduled_user_date_ids_after[] = $s_obj->getUserDateID();
                     }
                     //Debug::Arr($scheduled_user_date_ids_after, 'Scheduled UserDateIDs After: ', __FILE__, __LINE__, __METHOD__,10);
                 }
             } else {
                 Debug::text('bUsing calendar days, NOT scheduled days!', __FILE__, __LINE__, __METHOD__, 10);
             }
             $worked_before_days_count = 0;
             if ($this->getHolidayPolicyObject()->getMinimumWorkedDays() > 0 and $this->getHolidayPolicyObject()->getMinimumWorkedPeriodDays() > 0) {
                 if (isset($scheduled_user_date_ids_before) and $this->getHolidayPolicyObject()->getWorkedScheduledDays() == TRUE) {
                     $worked_before_days_count = $udtlf->getDaysWorkedByUserIDAndUserDateIDs($user_obj->getId(), $scheduled_user_date_ids_before);
                 } else {
                     $worked_before_days_count = $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($user_obj->getId(), $this->getDateStamp() - $this->getHolidayPolicyObject()->getMinimumWorkedPeriodDays() * 86400, $this->getDateStamp() - 86400);
                 }
             }
             Debug::text('Employee has worked the prior: ' . $worked_before_days_count . ' days (Must be at least: ' . $this->getHolidayPolicyObject()->getMinimumWorkedDays() . ')', __FILE__, __LINE__, __METHOD__, 10);
             $worked_after_days_count = 0;
             if ($this->getHolidayPolicyObject()->getMinimumWorkedAfterDays() > 0 and $this->getHolidayPolicyObject()->getMinimumWorkedAfterPeriodDays() > 0) {
                 if (isset($scheduled_user_date_ids_after) and $this->getHolidayPolicyObject()->getWorkedAfterScheduledDays() == TRUE) {
                     $worked_after_days_count = $udtlf->getDaysWorkedByUserIDAndUserDateIDs($user_obj->getId(), $scheduled_user_date_ids_after);
                 } else {
                     $worked_after_days_count = $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($user_obj->getId(), $this->getDateStamp() + 86400, $this->getDateStamp() + $this->getHolidayPolicyObject()->getMinimumWorkedAfterPeriodDays() * 86400);
                 }
             }
             Debug::text('Employee has worked the following: ' . $worked_after_days_count . ' days (Must be at least: ' . $this->getHolidayPolicyObject()->getMinimumWorkedAfterDays() . ')', __FILE__, __LINE__, __METHOD__, 10);
             //Make sure employee has worked for a portion of those days.
             if ($worked_before_days_count >= $this->getHolidayPolicyObject()->getMinimumWorkedDays() and $worked_after_days_count >= $this->getHolidayPolicyObject()->getMinimumWorkedAfterDays()) {
                 Debug::text('Employee has worked enough prior and following days!', __FILE__, __LINE__, __METHOD__, 10);
                 return TRUE;
             } else {
                 Debug::text('Employee has NOT worked enough days prior or following the holiday!', __FILE__, __LINE__, __METHOD__, 10);
             }
         } else {
             Debug::text('Standard Holiday Policy type, returning TRUE', __FILE__, __LINE__, __METHOD__, 10);
             return TRUE;
         }
     } else {
         Debug::text('Employee has NOT been employed long enough!', __FILE__, __LINE__, __METHOD__, 10);
     }
     return FALSE;
 }
                     $is_previous_time_sheet_verified = TRUE;
                 }
             }
         }
     } else {
         $is_previous_time_sheet_verified = TRUE;
         //There is no previous pay period
     }
     unset($previous_pay_period_obj, $pptsvlf, $pptsv_obj, $pplf);
 }
 //Get pay period totals
 //Sum all Worked Hours
 //Sum all Paid Absences
 //Sum all Dock Absences
 //Sum all Regular/OverTime hours
 $udtlf = new UserDateTotalListFactory();
 $worked_total_time = (int) $udtlf->getWorkedTimeSumByUserIDAndPayPeriodId($user_id, $pay_period_id);
 Debug::text('Worked Total Time: ' . $worked_total_time, __FILE__, __LINE__, __METHOD__, 10);
 $paid_absence_total_time = $udtlf->getPaidAbsenceTimeSumByUserIDAndPayPeriodId($user_id, $pay_period_id);
 Debug::text('Paid Absence Total Time: ' . $paid_absence_total_time, __FILE__, __LINE__, __METHOD__, 10);
 $dock_absence_total_time = $udtlf->getDockAbsenceTimeSumByUserIDAndPayPeriodId($user_id, $pay_period_id);
 Debug::text('Dock Absence Total Time: ' . $dock_absence_total_time, __FILE__, __LINE__, __METHOD__, 10);
 $udtlf->getRegularAndOverTimeSumByUserIDAndPayPeriodId($user_id, $pay_period_id);
 if ($udtlf->getRecordCount() > 0) {
     //Get overtime policy names
     $otplf = new OverTimePolicyListFactory();
     $over_time_policy_options = $otplf->getByCompanyIdArray($current_company->getId(), FALSE);
     foreach ($udtlf as $udt_obj) {
         Debug::text('Type ID: ' . $udt_obj->getColumn('type_id') . ' OverTime Policy ID: ' . $udt_obj->getColumn('over_time_policy_id') . ' Total Time: ' . $udt_obj->getColumn('total_time'), __FILE__, __LINE__, __METHOD__, 10);
         if ($udt_obj->getColumn('type_id') == 20) {
             $name = TTi18n::gettext('Regular Time');
Beispiel #12
0
 $udlf = new UserDateListFactory();
 $udlf->getDaysWorkedByTimePeriodAndUserIdAndCompanyIdAndStartDateAndEndDate('month', $filter_data['user_ids'], $current_company->getId(), $filter_data['start_date'], $filter_data['end_date']);
 if ($udlf->getRecordCount() > 0) {
     foreach ($udlf as $ud_obj) {
         //$user_days_worked[$ud_obj->getUser()]['month']
         $user_attendance_rows[$ud_obj->getUser()]['days_worked']['month'] = array('avg' => round($ud_obj->getColumn('avg'), 2), 'min' => $ud_obj->getColumn('min'), 'max' => $ud_obj->getColumn('max'));
     }
 }
 $udlf->getDaysWorkedByTimePeriodAndUserIdAndCompanyIdAndStartDateAndEndDate('week', $filter_data['user_ids'], $current_company->getId(), $filter_data['start_date'], $filter_data['end_date']);
 if ($udlf->getRecordCount() > 0) {
     foreach ($udlf as $ud_obj) {
         $user_attendance_rows[$ud_obj->getUser()]['days_worked']['week'] = array('avg' => round($ud_obj->getColumn('avg'), 2), 'min' => $ud_obj->getColumn('min'), 'max' => $ud_obj->getColumn('max'));
     }
 }
 //var_dump($user_days_worked);
 $udtlf = new UserDateTotalListFactory();
 $udtlf->getReportHoursByTimePeriodAndUserIdAndCompanyIdAndStartDateAndEndDate('day', $filter_data['user_ids'], $current_company->getId(), $filter_data['start_date'], $filter_data['end_date']);
 if ($udtlf->getRecordCount() > 0) {
     foreach ($udtlf as $udt_obj) {
         if ($udt_obj->getStatus() == 10 and $udt_obj->getType() == 20) {
             $type = 'regular';
             $policy_id = 0;
             $policy_name = 'regular';
         } elseif ($udt_obj->getStatus() == 10 and $udt_obj->getType() == 30 and $udt_obj->getOverTimePolicyId() != 0) {
             $type = 'over_time';
             $policy_id = $udt_obj->getOverTimePolicyId();
             $policy_name = $over_time_policy_arr[$udt_obj->getOverTimePolicyId()];
         } elseif ($udt_obj->getStatus() == 10 and $udt_obj->getType() == 40 and $udt_obj->getPremiumPolicyId() != 0) {
             $type = 'premium';
             $policy_id = $udt_obj->getPremiumPolicyId();
             $policy_name = $premium_policy_arr[$udt_obj->getPremiumPolicyId()];
 function setUserDateTotalID($id)
 {
     $id = trim($id);
     $udtlf = new UserDateTotalListFactory();
     if ($id == 0 or $this->Validator->isResultSetWithRows('user_date_total', $udtlf->getByID($id), TTi18n::gettext('User Date Total ID is invalid'))) {
         $this->data['user_date_total_id'] = $id;
         return TRUE;
     }
     return FALSE;
 }
 function getUserDateTotalArray($start_date, $end_date)
 {
     $udtlf = new UserDateTotalListFactory();
     $date_totals = array();
     //Get only system totals.
     //$udtlf->getByCompanyIDAndUserIdAndStatusAndStartDateAndEndDate( $this->company_id, $this->user_id, 10, $start_date, $end_date);
     $udtlf->getByCompanyIDAndUserIdAndStatusAndTypeAndStartDateAndEndDate($this->company_id, $this->user_id, 10, array(10, 20, 40), $start_date, $end_date);
     if ($udtlf->getRecordCount() > 0) {
         foreach ($udtlf as $udt_obj) {
             $user_date_stamp = TTDate::strtotime($udt_obj->getColumn('user_date_stamp'));
             $type_and_policy_id = $udt_obj->getType() . (int) $udt_obj->getOverTimePolicyID();
             $date_totals[$user_date_stamp][] = array('date_stamp' => $udt_obj->getColumn('user_date_stamp'), 'id' => $udt_obj->getId(), 'user_date_id' => $udt_obj->getUserDateId(), 'status_id' => $udt_obj->getStatus(), 'type_id' => $udt_obj->getType(), 'over_time_policy_id' => $udt_obj->getOverTimePolicyID(), 'premium_policy_id' => $udt_obj->getPremiumPolicyID(), 'type_and_policy_id' => $type_and_policy_id, 'branch_id' => (int) $udt_obj->getBranch(), 'department_id' => $udt_obj->getDepartment(), 'total_time' => $udt_obj->getTotalTime(), 'name' => $udt_obj->getName(), 'tmp_override' => $udt_obj->getOverride());
         }
     }
     return $date_totals;
 }
Beispiel #15
0
 function setUserDateTotalArray()
 {
     //Loop through unique UserDateTotal rows... Adding entries to pay stubs.
     $udtlf = new UserDateTotalListFactory();
     $udtlf->getByUserIdAndPayPeriodIdAndEndDate($this->getUser(), $this->getPayPeriod(), $this->getPayPeriodObject()->getEndDate());
     $dock_absence_time = 0;
     $paid_absence_time = 0;
     $dock_absence_amount = 0;
     $paid_absence_amount = 0;
     $prev_wage_effective_date = 0;
     if ($udtlf->getRecordCount() > 0) {
         foreach ($udtlf as $udt_obj) {
             Debug::text('User Total Row... Type: ' . $udt_obj->getType() . ' OverTime Policy ID: ' . $udt_obj->getOverTimePolicyID() . ' User Wage ID: ' . $udt_obj->getColumn('user_wage_id'), __FILE__, __LINE__, __METHOD__, 10);
             if ($udt_obj->getStatus() == 10 and $udt_obj->getType() == 20) {
                 //Regular Time
                 Debug::text('User Total Row... Regular Time: ' . $udt_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                 //Check if they are a salary user...
                 //Use WORKED time to calculate regular time. Not just regular time.
                 if (is_object($this->getUserWageObject($udt_obj->getColumn('user_wage_id'))) and $this->getUserWageObject($udt_obj->getColumn('user_wage_id'))->getType() != 10) {
                     //Salary
                     Debug::text('Strict Salary Wage: Reduce Regular Pay By: Dock Time: ' . $dock_absence_time . ' and Paid Absence: ' . $paid_absence_time, __FILE__, __LINE__, __METHOD__, 10);
                     if (isset($dock_absence_amount_arr[$udt_obj->getColumn('user_wage_id')])) {
                         $dock_absence_wage = $dock_absence_amount_arr[$udt_obj->getColumn('user_wage_id')];
                     } else {
                         $dock_absence_wage = 0;
                     }
                     if (isset($reduce_salary_absence_amount_arr[$udt_obj->getColumn('user_wage_id')])) {
                         $paid_absence_wage = $reduce_salary_absence_amount_arr[$udt_obj->getColumn('user_wage_id')];
                     } else {
                         $paid_absence_wage = 0;
                     }
                     Debug::text('Wage ID: ' . $udt_obj->getColumn('user_wage_id') . ' Dock Absence Wage: ' . $dock_absence_wage . ' Paid Absence Wage: ' . $paid_absence_wage, __FILE__, __LINE__, __METHOD__, 10);
                     $maximum_wage_salary = UserWageFactory::proRateSalary($this->getMaximumPayPeriodWage($udt_obj->getColumn('user_wage_id')), $this->getUserWageObject($udt_obj->getColumn('user_wage_id'))->getEffectiveDate(), $prev_wage_effective_date, $this->getPayPeriodObject()->getStartDate(), $this->getPayPeriodObject()->getEndDate());
                     $prev_wage_effective_date = $this->getUserWageObject($udt_obj->getColumn('user_wage_id'))->getEffectiveDate();
                     $amount = bcsub($maximum_wage_salary, bcadd($dock_absence_wage, $paid_absence_wage));
                     $total_time = $udt_obj->getTotalTime();
                     //Dont minus dock/paid absence time. Because its already not included.
                     $rate = NULL;
                     $pay_stub_entry = $this->getPayStubEntryAccountLinkObject()->getRegularTime();
                     unset($dock_absence_wage, $paid_absence_wage);
                 } else {
                     //Hourly
                     Debug::text('Hourly or Hourly + Bonus Wage', __FILE__, __LINE__, __METHOD__, 10);
                     $pay_stub_entry = $this->getPayStubEntryAccountLinkObject()->getRegularTime();
                     $total_time = $udt_obj->getTotalTime();
                     $rate = $this->getHourlyRate($udt_obj->getColumn('user_wage_id'));
                     $amount = $this->getWage($udt_obj->getTotalTime(), $rate);
                 }
                 Debug::text('aPay Stub Entry Account ID: ' . $pay_stub_entry . ' Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
             } elseif ($udt_obj->getStatus() == 10 and $udt_obj->getType() == 30) {
                 //Overtime
                 Debug::text('User Total Row... Overtime Time: ' . $udt_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                 //Get overtime policy info. Allow negative rates so they withdraw from pay stub accounts.
                 if ($udt_obj->getOverTimePolicyObject()->getRate() != 0) {
                     Debug::text('Paid Overtime Time Policy... Rate: ' . $udt_obj->getOverTimePolicyObject()->getRate(), __FILE__, __LINE__, __METHOD__, 10);
                     $pay_stub_entry = $udt_obj->getOverTimePolicyObject()->getPayStubEntryAccountId();
                     $total_time = $udt_obj->getTotalTime();
                     $rate = bcmul($this->getHourlyRate($udt_obj->getColumn('over_time_policy_wage_id')), $udt_obj->getOverTimePolicyObject()->getRate());
                     $amount = $this->getWage($udt_obj->getTotalTime(), $rate);
                     Debug::text('bPay Stub Entry Account ID: ' . $pay_stub_entry . ' Amount: ' . $amount . ' Rate: ' . $rate, __FILE__, __LINE__, __METHOD__, 10);
                 } else {
                     Debug::text('NOT Paid Overtime Time Policy: ', __FILE__, __LINE__, __METHOD__, 10);
                 }
             } elseif ($udt_obj->getStatus() == 30 and $udt_obj->getType() == 10) {
                 //Absence
                 Debug::text('User Total Row... Absence Time: ' . $udt_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                 if (is_object($udt_obj->getAbsencePolicyObject()) and ($udt_obj->getAbsencePolicyObject()->getType() == 10 or $udt_obj->getAbsencePolicyObject()->getType() == 12) and $udt_obj->getAbsencePolicyObject()->getPayStubEntryAccountID() != '') {
                     //Paid
                     Debug::text('Paid Absence Time: ' . $udt_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                     $pay_stub_entry = (int) $udt_obj->getAbsencePolicyObject()->getPayStubEntryAccountID();
                     $total_time = $udt_obj->getTotalTime();
                     $rate = bcmul($this->getHourlyRate($udt_obj->getColumn('absence_policy_wage_id')), $udt_obj->getAbsencePolicyObject()->getRate());
                     $amount = $this->getWage($udt_obj->getTotalTime(), $rate);
                     //$rate = $this->getHourlyRate( $udt_obj->getColumn('absence_policy_wage_id') );
                     //$amount = $this->getWage( $udt_obj->getTotalTime(), $this->getHourlyRate( $udt_obj->getColumn('absence_policy_wage_id') ) );
                     //Debug::text('Paid Absence Info: '. $udt_obj->getTotalTime() , __FILE__, __LINE__, __METHOD__,10);
                     Debug::text('cPay Stub Entry Account ID: ' . $pay_stub_entry . ' Amount: ' . $amount . ' Rate: ' . $rate, __FILE__, __LINE__, __METHOD__, 10);
                     $paid_absence_time = bcadd($paid_absence_time, $udt_obj->getTotalTime());
                     $paid_absence_amount = bcadd($paid_absence_amount, $amount);
                     //Make sure we add the amount below. Incase there are two or more
                     //entries for a paid absence in the same user_wage_id on one pay stub.
                     if (!isset($paid_absence_amount_arr[$udt_obj->getColumn('absence_policy_wage_id')])) {
                         $paid_absence_amount_arr[$udt_obj->getColumn('absence_policy_wage_id')] = 0;
                     }
                     $paid_absence_amount_arr[$udt_obj->getColumn('absence_policy_wage_id')] = bcadd($paid_absence_amount_arr[$udt_obj->getColumn('absence_policy_wage_id')], $amount);
                     //Some paid absences are over and above employees salary, so we need to track them separately.
                     //So we only reduce the salary of the amount of regular paid absences, not "Paid (Above Salary)" absences.
                     if (!isset($reduce_salary_absence_amount_arr[$udt_obj->getColumn('absence_policy_wage_id')])) {
                         $reduce_salary_absence_amount_arr[$udt_obj->getColumn('absence_policy_wage_id')] = 0;
                     }
                     if ($udt_obj->getAbsencePolicyObject()->getType() == 10) {
                         $reduce_salary_absence_amount_arr[$udt_obj->getColumn('absence_policy_wage_id')] = bcadd($reduce_salary_absence_amount_arr[$udt_obj->getColumn('absence_policy_wage_id')], $amount);
                     }
                 } elseif (is_object($udt_obj->getAbsencePolicyObject()) and $udt_obj->getAbsencePolicyObject()->getType() == 30) {
                     $dock_absence_time = bcadd($dock_absence_time, $udt_obj->getTotalTime());
                     $rate = bcmul($this->getHourlyRate($udt_obj->getColumn('absence_policy_wage_id')), $udt_obj->getAbsencePolicyObject()->getRate());
                     $amount = $this->getWage($udt_obj->getTotalTime(), $rate);
                     //$amount = $this->getWage( $udt_obj->getTotalTime(), $this->getHourlyRate( $udt_obj->getColumn('absence_policy_wage_id') ) );
                     $dock_absence_amount = bcadd($dock_absence_amount, $amount);
                     $dock_absence_amount_arr[$udt_obj->getColumn('absence_policy_wage_id')] = $amount;
                     Debug::text('DOCK Absence Time.. Adding: ' . $udt_obj->getTotalTime() . ' Total: ' . $dock_absence_time . ' Rate: ' . $rate, __FILE__, __LINE__, __METHOD__, 10);
                     unset($rate);
                 }
             } elseif ($udt_obj->getStatus() == 10 and $udt_obj->getType() == 40) {
                 //Premium
                 Debug::text('User Total Row... Premium Time: ' . $udt_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                 //Get premium policy info.
                 if (is_object($udt_obj->getPremiumPolicyObject()) and $udt_obj->getPremiumPolicyObject()->getRate() != 0) {
                     Debug::text('Paid Premium Time Policy... Rate: ' . $udt_obj->getPremiumPolicyObject()->getRate(), __FILE__, __LINE__, __METHOD__, 10);
                     switch ($udt_obj->getPremiumPolicyObject()->getPayType()) {
                         case 10:
                             //Pay Factor
                             //Since they are already paid for this time with regular or OT, minus 1 from the rate
                             $rate = bcmul($this->getHourlyRate($udt_obj->getColumn('premium_policy_wage_id')), bcsub($udt_obj->getPremiumPolicyObject()->getRate(), 1));
                             break;
                         case 20:
                             //Pay Plus Premium
                             $rate = $udt_obj->getPremiumPolicyObject()->getRate();
                             break;
                         case 30:
                             //Flat Hourly Rate
                             //Get the difference between the employees current wage and the premium wage.
                             $rate = bcsub($udt_obj->getPremiumPolicyObject()->getRate(), $this->getHourlyRate($udt_obj->getColumn('premium_policy_wage_id')));
                             break;
                     }
                     $pay_stub_entry = $udt_obj->getPremiumPolicyObject()->getPayStubEntryAccountId();
                     $total_time = $udt_obj->getTotalTime();
                     $amount = $this->getWage($udt_obj->getTotalTime(), $rate);
                     Debug::text('dPay Stub Entry Account ID: ' . $pay_stub_entry . ' Amount: ' . $amount . ' Rate: ' . $rate, __FILE__, __LINE__, __METHOD__, 10);
                 } else {
                     Debug::text('NOT Paid Premium Time Policy: ', __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
             if (isset($pay_stub_entry) and $pay_stub_entry != '') {
                 Debug::text('zPay Stub Entry Account ID: ' . $pay_stub_entry . ' Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                 $ret_arr['entries'][] = array('user_wage_id' => $udt_obj->getColumn('user_wage_id'), 'pay_stub_entry' => $pay_stub_entry, 'total_time' => $total_time, 'amount' => $amount, 'rate' => $rate);
             }
             unset($pay_stub_entry, $amount, $total_time, $rate);
         }
     } else {
         Debug::text('NO UserDate Total entries found.', __FILE__, __LINE__, __METHOD__, 10);
     }
     $ret_arr['other']['paid_absence_time'] = $paid_absence_time;
     $ret_arr['other']['dock_absence_time'] = $dock_absence_time;
     $ret_arr['other']['paid_absence_amount'] = $paid_absence_amount;
     $ret_arr['other']['dock_absence_amount'] = $dock_absence_amount;
     if (isset($ret_arr)) {
         Debug::Arr($ret_arr, 'UserDateTotal Array', __FILE__, __LINE__, __METHOD__, 10);
         return $this->user_date_total_arr = $ret_arr;
     }
     return FALSE;
 }
 function getWorkedTimeByUserIdAndEndDate($user_id, $end_date = NULL)
 {
     if ($user_id == '') {
         return FALSE;
     }
     if ($end_date == '') {
         return FALSE;
     }
     $udtlf = new UserDateTotalListFactory();
     $retval = $udtlf->getWorkedTimeSumByUserIDAndStartDateAndEndDate($user_id, 1, $end_date);
     Debug::Text('Worked Seconds: ' . (int) $retval . ' Before: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10);
     return $retval;
 }
 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;
 }