$smarty->assign_by_ref('current_user', $current_user); $smarty->assign_by_ref('current_user_prefs', $current_user_prefs); if (!isset($skip_message_check)) { $profiler->startTimer("Interface.inc - Check for UNREAD messages..."); //CHeck for unread messages $mlf = new MessageListFactory(); $unread_messages = $mlf->getNewMessagesByUserId($current_user->getId()); Debug::text('UnRead Messages: ' . $unread_messages, __FILE__, __LINE__, __METHOD__, 10); $smarty->assign_by_ref('unread_messages', $unread_messages); if (isset($_COOKIE['newMailPopUp'])) { $smarty->assign_by_ref('newMailPopUp', $_COOKIE['newMailPopUp']); } unset($mlf); $profiler->stopTimer("Interface.inc - Check for UNREAD messages..."); $profiler->startTimer("Interface.inc - Check for Exceptions"); $elf = new ExceptionListFactory(); $elf->getFlaggedExceptionsByUserIdAndPayPeriodStatus($current_user->getId(), 10); $display_exception_flag = FALSE; if ($elf->getRecordCount() > 0) { foreach ($elf as $e_obj) { if ($e_obj->getColumn('severity_id') == 30) { $display_exception_flag = 'red'; } elseif ($e_obj->getColumn('severity_id') == 20) { $display_exception_flag = 'yellow'; } break; } } unset($elf, $e_obj); if (isset($display_exception_flag)) { Debug::text('Exception Flag to Display: ' . $display_exception_flag, __FILE__, __LINE__, __METHOD__, 10);
/** * Returns array of notifications message to be displayed to the user. * @param string $action Action that is being performed, possible values: 'login', 'preference', 'notification', 'pay_period' * @return array */ function getNotifications($action = FALSE) { global $config_vars, $disable_database_connection; $retarr = FALSE; //Skip this step if disable_database_connection is enabled or the user is going through the installer still switch (strtolower($action)) { case 'login': if ((!isset($disable_database_connection) or isset($disable_database_connection) and $disable_database_connection != TRUE) and (!isset($config_vars['other']['installer_enabled']) or isset($config_vars['other']['installer_enabled']) and $config_vars['other']['installer_enabled'] != TRUE)) { //Get all system settings, so they can be used even if the user isn't logged in, such as the login page. $sslf = new SystemSettingListFactory(); $system_settings = $sslf->getAllArray(); } unset($sslf); //Check license validity if ((DEPLOYMENT_ON_DEMAND == FALSE and $this->getCurrentCompanyObject()->getId() == 1 or isset($config_vars['other']['primary_company_id']) and $this->getCurrentCompanyObject()->getId() == $config_vars['other']['primary_company_id']) and getTTProductEdition() > 10) { if (!isset($system_settings['license'])) { $system_settings['license'] = NULL; } $license = new TTLicense(); $license_validate = $license->validateLicense($system_settings['license']); $license_message = $license->getFullErrorMessage($license_validate, TRUE); if ($license_message != '') { $destination_url = 'http://www.timetrex.com/r.php?id=899'; if ($license_validate === TRUE) { //License likely expires soon. $retarr[] = array('delay' => 0, 'bg_color' => '#FFFF00', 'message' => TTi18n::getText('WARNING: %1', $license_message), 'destination' => $destination_url); } else { //License error. $retarr[] = array('delay' => -1, 'bg_color' => '#FF0000', 'message' => TTi18n::getText('WARNING: %1', $license_message), 'destination' => $destination_url); } } unset($license, $license_validate, $license_message, $destination); } //System Requirements not being met. if (isset($system_settings['valid_install_requirements']) and DEPLOYMENT_ON_DEMAND == FALSE and (int) $system_settings['valid_install_requirements'] == 0) { $retarr[] = array('delay' => -1, 'bg_color' => '#FF0000', 'message' => TTi18n::getText('WARNING: %1 system requirement check has failed! Please contact your %1 administrator immediately to re-run the %1 installer to correct the issue.', APPLICATION_NAME), 'destination' => NULL); } //Check version mismatch if (isset($system_settings['system_version']) and DEPLOYMENT_ON_DEMAND == FALSE and APPLICATION_VERSION != $system_settings['system_version']) { $retarr[] = array('delay' => -1, 'bg_color' => '#FF0000', 'message' => TTi18n::getText('WARNING: %1 application version does not match database version. Please re-run the %1 installer to complete the upgrade process.', APPLICATION_NAME), 'destination' => NULL); } //Only display message to the primary company. if (time() - (int) APPLICATION_VERSION_DATE > 86400 * 475 and ($this->getCurrentCompanyObject()->getId() == 1 or isset($config_vars['other']['primary_company_id']) and $this->getCurrentCompanyObject()->getId() == $config_vars['other']['primary_company_id'])) { //~1yr and 3mths $retarr[] = array('delay' => -1, 'bg_color' => '#FF0000', 'message' => TTi18n::getText('WARNING: This %1 version (v%2) is severely out of date and may no longer be supported. Please upgrade to the latest version as soon as possible as invalid calculations may already be occurring.', array(APPLICATION_NAME, APPLICATION_VERSION)), 'destination' => NULL); } //New version available notification. if (DEMO_MODE == FALSE and (isset($system_settings['new_version']) and $system_settings['new_version'] == 1) and ($this->getCurrentCompanyObject()->getId() == 1 or isset($config_vars['other']['primary_company_id']) and $this->getCurrentCompanyObject()->getId() == $config_vars['other']['primary_company_id'])) { //Only display this every two weeks. $new_version_available_notification_arr = UserSettingFactory::getUserSetting($this->getCurrentUserObject()->getID(), 'new_version_available_notification'); if (!isset($new_version_available_notification_arr['value']) or isset($new_version_available_notification_arr['value']) and $new_version_available_notification_arr['value'] <= time() - 86400 * 14) { UserSettingFactory::setUserSetting($this->getCurrentUserObject()->getID(), 'new_version_available_notification', time()); $retarr[] = array('delay' => -1, 'bg_color' => '#FFFF00', 'message' => TTi18n::getText('NOTICE: A new version of %1 available, it is highly recommended that you upgrade as soon as possible. Click here to download the latest version.', array(APPLICATION_NAME)), 'destination' => getTTProductEdition() == TT_PRODUCT_COMMUNITY ? 'http://www.timetrex.com/r.php?id=19' : 'http://www.timetrex.com/r.php?id=9'); } unset($new_version_available_notification); } //Check for major new version. $new_version_notification_arr = UserSettingFactory::getUserSetting($this->getCurrentUserObject()->getID(), 'new_version_notification'); if (DEMO_MODE == FALSE and (!isset($config_vars['branding']['application_name']) or ($this->getCurrentCompanyObject()->getId() == 1 or isset($config_vars['other']['primary_company_id']) and $this->getCurrentCompanyObject()->getId() == $config_vars['other']['primary_company_id'])) and $this->getPermissionObject()->getLevel() >= 20 and $this->getCurrentUserObject()->getCreatedDate() <= APPLICATION_VERSION_DATE and (!isset($new_version_notification_arr['value']) or isset($new_version_notification_arr['value']) and Misc::MajorVersionCompare(APPLICATION_VERSION, $new_version_notification_arr['value'], '>'))) { UserSettingFactory::setUserSetting($this->getCurrentUserObject()->getID(), 'new_version_notification', APPLICATION_VERSION); $retarr[] = array('delay' => -1, 'bg_color' => '#FFFF00', 'message' => TTi18n::getText('NOTICE: Your instance of %1 has been upgraded to v%2, click here to see whats new.', array(APPLICATION_NAME, APPLICATION_VERSION)), 'destination' => 'http://www.timetrex.com/r.php?id=300'); } unset($new_version_notification); //Check installer enabled. if (isset($config_vars['other']['installer_enabled']) and $config_vars['other']['installer_enabled'] == 1) { $retarr[] = array('delay' => -1, 'bg_color' => '#FF0000', 'message' => TTi18n::getText('WARNING: %1 is currently in INSTALL MODE. Please go to your timetrex.ini.php file and set "installer_enabled" to "FALSE".', APPLICATION_NAME), 'destination' => NULL); } //Make sure CronJobs are running correctly. $cjlf = new CronJobListFactory(); $cjlf->getMostRecentlyRun(); if ($cjlf->getRecordCount() > 0) { //Is last run job more then 48hrs old? $cj_obj = $cjlf->getCurrent(); if (PRODUCTION == TRUE and DEMO_MODE == FALSE and $cj_obj->getLastRunDate() < time() - 172800 and $cj_obj->getCreatedDate() < time() - 172800) { $retarr[] = array('delay' => -1, 'bg_color' => '#FF0000', 'message' => TTi18n::getText('WARNING: Critical maintenance jobs have not run in the last 48hours. Please contact your %1 administrator immediately.', APPLICATION_NAME), 'destination' => NULL); } } unset($cjlf, $cj_obj); //Check if any pay periods are past their transaction date and not closed. if (DEMO_MODE == FALSE and $this->getPermissionObject()->Check('pay_period_schedule', 'enabled') and $this->getPermissionObject()->Check('pay_period_schedule', 'view')) { $pplf = TTnew('PayPeriodListFactory'); $pplf->getByCompanyIdAndStatusAndTransactionDate($this->getCurrentCompanyObject()->getId(), array(10, 30), TTDate::getBeginDayEpoch(time())); //Open or Post Adjustment pay periods. if ($pplf->getRecordCount() > 0) { foreach ($pplf as $pp_obj) { if ($pp_obj->getCreatedDate() < time() - 86400 * 40) { //Ignore pay period schedules newer than 40 days. They are automatically closed after 45 days. $retarr[] = array('delay' => 0, 'bg_color' => '#FF0000', 'message' => TTi18n::getText('WARNING: Pay periods past their transaction date have not been closed yet. It\'s critical that these pay periods are closed to prevent data loss, click here to close them now.'), 'destination' => array('menu_name' => 'Pay Periods')); break; } } } unset($pplf, $pp_obj); } //CHeck for unread messages $mclf = new MessageControlListFactory(); $unread_messages = $mclf->getNewMessagesByCompanyIdAndUserId($this->getCurrentCompanyObject()->getId(), $this->getCurrentUserObject()->getId()); Debug::text('UnRead Messages: ' . $unread_messages, __FILE__, __LINE__, __METHOD__, 10); if ($unread_messages > 0) { $retarr[] = array('delay' => 25, 'bg_color' => '#FFFF00', 'message' => TTi18n::getText('NOTICE: You have %1 new message(s) waiting, click here to read them now.', $unread_messages), 'destination' => array('menu_name' => 'Messages')); } unset($mclf, $unread_messages); if (DEMO_MODE == FALSE) { $elf = new ExceptionListFactory(); $elf->getFlaggedExceptionsByUserIdAndPayPeriodStatus($this->getCurrentUserObject()->getId(), 10); $display_exception_flag = FALSE; if ($elf->getRecordCount() > 0) { foreach ($elf as $e_obj) { if ($e_obj->getColumn('severity_id') == 30) { $display_exception_flag = 'red'; } break; } } if (isset($display_exception_flag) and $display_exception_flag !== FALSE) { Debug::Text('Exception Flag to Display: ' . $display_exception_flag, __FILE__, __LINE__, __METHOD__, 10); $retarr[] = array('delay' => 30, 'bg_color' => '#FFFF00', 'message' => TTi18n::getText('NOTICE: You have critical severity exceptions pending, click here to view them now.'), 'destination' => array('menu_name' => 'Exceptions')); } unset($elf, $e_obj, $display_exception_flag); } if (DEMO_MODE == FALSE and $this->getPermissionObject()->getLevel() >= 20 and ($this->getCurrentUserObject()->getWorkEmail() == '' and $this->getCurrentUserObject()->getHomeEmail() == '')) { $retarr[] = array('delay' => 30, 'bg_color' => '#FF0000', 'message' => TTi18n::getText('WARNING: Please click here and enter an email address for your account, this is required to receive important notices and prevent your account from being locked out.'), 'destination' => array('menu_name' => 'Contact Information')); } break; default: break; } //Check timezone is proper. $current_user_prefs = $this->getCurrentUserObject()->getUserPreferenceObject(); if ($current_user_prefs->setDateTimePreferences() == FALSE) { //Setting timezone failed, alert user to this fact. //WARNING: %1 was unable to set your time zone. Please contact your %1 administrator immediately.{/t} {if $permission->Check('company','enabled') AND $permission->Check('company','edit_own')}<a href="http://forums.timetrex.com/viewtopic.php?t=40">{t}For more information please click here.{/t}</a>{/if} if ($this->getPermissionObject()->Check('company', 'enabled') and $this->getPermissionObject()->Check('company', 'edit_own')) { $destination_url = 'http://www.timetrex.com/r.php?id=1010'; $sub_message = TTi18n::getText('For more information please click here.'); } else { $destination_url = NULL; $sub_message = NULL; } $retarr[] = array('delay' => -1, 'bg_color' => '#FF0000', 'message' => TTi18n::getText('WARNING: %1 was unable to set your time zone. Please contact your %1 administrator immediately.', APPLICATION_NAME) . ' ' . $sub_message, 'destination' => $destination_url); unset($destination_url, $sub_message); } return $retarr; }
//Get maximum shift time for each pay period schedule, so we know how far back //we have to recalculate days at the minimum. $ppslf = new PayPeriodScheduleListFactory(); $ppslf->getByCompanyId($c_obj->getId()); if ($ppslf->getRecordCount() > 0) { foreach ($ppslf as $pps_obj) { $tmp_start_date = TTDate::getMiddleDayEpoch($execution_time) - $pps_obj->getMaximumShiftTime(); if ($tmp_start_date < $start_date) { $start_date = $tmp_start_date; Debug::text(' Maximum Shift Time is greater then 48hrs, reducing Start Date to: ' . TTDate::getDate('DATE+TIME', $start_date), __FILE__, __LINE__, __METHOD__, 5); } } } unset($ppslf, $pps_obj, $tmp_start_date); //Get earliest pre_mature exception in a NON-closed pay period. $elf = new ExceptionListFactory(); $elf->getByCompanyIDAndTypeAndPayPeriodStatus($c_obj->getId(), 5, array(10, 12, 15, 30), 1, NULL, NULL, array('b.date_stamp' => 'asc')); //Limit 1 if ($elf->getRecordCount() > 0) { foreach ($elf as $e_obj) { $tmp_start_date = $e_obj->getUserDateObject()->getDateStamp(); if ($tmp_start_date < $start_date) { $start_date = $tmp_start_date; Debug::text(' Pre-Mature exceptions occur before start date, reducing to: ' . TTDate::getDate('DATE+TIME', $start_date) . '(' . $e_obj->getId() . ')', __FILE__, __LINE__, __METHOD__, 5); } } } unset($elf, $e_obj, $tmp_start_date); $udlf = new UserDateListFactory(); $udlf->getByCompanyIdAndStartDateAndEndDateAndPayPeriodStatus($c_obj->getId(), $start_date, $end_date, array(10, 12, 15, 30)); Debug::text(' Start Date: ' . TTDate::getDate('DATE+TIME', $start_date) . ' End Date: ' . TTDate::getDate('DATE+TIME', $end_date) . ' User Date Rows: ' . $udlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 5);
case 'search_form_clear': case 'search_form_search': Debug::Text('Action: ' . $action, __FILE__, __LINE__, __METHOD__, 10); $saved_search_id = UserGenericDataFactory::searchFormDataHandler($action, $filter_data, URLBuilder::getURL(NULL, 'UserExceptionList.php')); default: BreadCrumb::setCrumb($title); extract(UserGenericDataFactory::getSearchFormData($saved_search_id, $sort_column)); Debug::Text('Sort Column: ' . $sort_column, __FILE__, __LINE__, __METHOD__, 10); Debug::Text('Saved Search ID: ' . $saved_search_id, __FILE__, __LINE__, __METHOD__, 10); $sort_array = NULL; if ($sort_column != '') { $sort_array = array(Misc::trimSortPrefix($sort_column) => $sort_order); } URLBuilder::setURL($_SERVER['SCRIPT_NAME'], array('sort_column' => Misc::trimSortPrefix($sort_column), 'sort_order' => $sort_order, 'saved_search_id' => $saved_search_id, 'page' => $page)); $ulf = new UserListFactory(); $elf = new ExceptionListFactory(); $hlf = new HierarchyListFactory(); $permission_children_ids = $hlf->getHierarchyChildrenByCompanyIdAndUserIdAndObjectTypeID($current_company->getId(), $current_user->getId()); Debug::Arr($permission_children_ids, 'Permission Children Ids:', __FILE__, __LINE__, __METHOD__, 10); if ($permission->Check('punch', 'view') == FALSE) { if ($permission->Check('punch', 'view_child')) { $filter_data['permission_children_ids'] = $permission_children_ids; } if ($permission->Check('punch', 'view_own')) { $filter_data['permission_children_ids'][] = $current_user->getId(); } } $pplf = new PayPeriodListFactory(); $pplf->getByCompanyId($current_company->getId()); $pay_period_options = $pplf->getArrayByListFactory($pplf, FALSE, FALSE); $pay_period_ids = array_keys((array) $pay_period_options);
Debug::Text('Current Pay Period Status: ' . $pay_period_obj->getStatus(), __FILE__, __LINE__, __METHOD__, 10); $status_options = $pay_period_obj->getOptions('status'); if ($pay_period_obj->getStatus() == 20 or $pay_period_obj->getStatus() == 30) { //Once pay period is closed, do not allow it to re-open. $status_filter_arr = array(20, 30); } else { //Only allow to close pay period if AFTER end date. if (TTDate::getTime() >= $pay_period_obj->getEndDate()) { $status_filter_arr = array(10, 12, $pay_period_obj->getStatus(), 20); } else { $status_filter_arr = array(10, 12, $pay_period_obj->getStatus()); } } $status_options = Option::getByArray($status_filter_arr, $status_options); $smarty->assign_by_ref('status_options', $status_options); $elf = new ExceptionListFactory(); $elf->getSumExceptionsByPayPeriodIdAndBeforeDate($pay_period_obj->getId(), $pay_period_obj->getEndDate()); $exceptions = array('low' => 0, 'med' => 0, 'high' => 0); if ($elf->getRecordCount() > 0) { Debug::Text(' Found Exceptions: ' . $elf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); foreach ($elf as $e_obj) { if ($e_obj->getColumn('severity_id') == 10) { $exceptions['low'] = $e_obj->getColumn('count'); } if ($e_obj->getColumn('severity_id') == 20) { $exceptions['med'] = $e_obj->getColumn('count'); } if ($e_obj->getColumn('severity_id') == 30) { $exceptions['high'] = $e_obj->getColumn('count'); } }
if (isset($date_absence_total_group[$user_date_stamp][$date_data['absence_policy_id']])) { $prev_total_time = $date_absence_total_group[$user_date_stamp][$date_data['absence_policy_id']]['total_time']; } $date_data['total_time'] = $date_data['total_time'] + $prev_total_time; $date_absence_total_group[$user_date_stamp][$date_data['absence_policy_id']] = $date_data; } } $date_total_absence_ids = array_unique($date_total_absence_ids); sort($date_total_absence_ids); $date_absence_total_rows = TimeSheetFormatArrayByDate($date_absence_total_group, $date_total_absence_ids, $calendar_array, 'absence_policy'); //var_dump($date_absence_total_rows); } /* Get Exceptions */ $elf = new ExceptionListFactory(); $elf->getByCompanyIDAndUserIdAndStartDateAndEndDate($current_company->getID(), $user_id, $start_date, $end_date); $punch_exceptions = array(); if ($elf->getRecordCount() > 0) { Debug::text('Found exceptions!: ', __FILE__, __LINE__, __METHOD__, 10); foreach ($elf as $e_obj) { $user_date_stamp = TTDate::strtotime($e_obj->getColumn('user_date_stamp')); $exception_data_arr = array('type_id' => $e_obj->getType(), 'severity_id' => $e_obj->getColumn('severity_id'), 'exception_policy_type_id' => $e_obj->getColumn('exception_policy_type_id'), 'color' => $e_obj->getColor()); if ($e_obj->getPunchId() != '') { $punch_exceptions[$e_obj->getPunchId()][] = $exception_data_arr; } if ($e_obj->getPunchId() == '' and $e_obj->getPunchControlId() != '') { $punch_control_exceptions[$e_obj->getPunchControlId()][] = $exception_data_arr; } $date_exceptions[$user_date_stamp][] = $exception_data_arr; if (!isset($unique_exceptions[$e_obj->getColumn('exception_policy_type_id')]) or $unique_exceptions[$e_obj->getColumn('exception_policy_type_id')]['severity_id'] < $exception_data_arr['severity_id']) {
//Repeat broken out by branch/department as well } /* Exception History */ if (isset($columns['exception'])) { //Get exception types. $eplf = new ExceptionPolicyListFactory(); $eplf->getByCompanyId($current_company->getId()); if ($eplf->getRecordCount() > 0) { foreach ($eplf as $ep_obj) { $exception_policy_arr[$ep_obj->getId()] = array('type_id' => $ep_obj->getType(), 'name' => Option::getByKey($ep_obj->getType(), $ep_obj->getOptions('type')), 'severity_id' => $ep_obj->getSeverity()); } } //var_dump($exception_policy_arr); $elf = new ExceptionListFactory(); $elf->getReportByTimePeriodAndUserIdAndCompanyIdAndStartDateAndEndDate('week', $filter_data['user_ids'], $current_company->getId(), $filter_data['start_date'], $filter_data['end_date']); if ($elf->getRecordCount() > 0) { foreach ($elf as $e_obj) { $user_exception_rows[$e_obj->getColumn('user_id')][$e_obj->getColumn('exception_policy_id')]['week'] = array('exception_policy_id' => $e_obj->getColumn('exception_policy_id'), 'name' => $exception_policy_arr[$e_obj->getColumn('exception_policy_id')]['name'], 'code' => $exception_policy_arr[$e_obj->getColumn('exception_policy_id')]['type_id'], 'avg' => round($e_obj->getColumn('avg'), 2), 'min' => $e_obj->getColumn('min'), 'max' => $e_obj->getColumn('max'), 'total' => $e_obj->getColumn('total')); } } $elf->getReportByTimePeriodAndUserIdAndCompanyIdAndStartDateAndEndDate('month', $filter_data['user_ids'], $current_company->getId(), $filter_data['start_date'], $filter_data['end_date']); if ($elf->getRecordCount() > 0) { foreach ($elf as $e_obj) { $user_exception_rows[$e_obj->getColumn('user_id')][$e_obj->getColumn('exception_policy_id')]['month'] = array('exception_policy_id' => $e_obj->getColumn('exception_policy_id'), 'name' => $exception_policy_arr[$e_obj->getColumn('exception_policy_id')]['name'], 'code' => $exception_policy_arr[$e_obj->getColumn('exception_policy_id')]['type_id'], 'avg' => round($e_obj->getColumn('avg'), 2), 'min' => $e_obj->getColumn('min'), 'max' => $e_obj->getColumn('max'), 'total' => $e_obj->getColumn('total')); } } $elf->getDOWReportByUserIdAndCompanyIdAndStartDateAndEndDate($filter_data['user_ids'], $current_company->getId(), $filter_data['start_date'], $filter_data['end_date']); if ($elf->getRecordCount() > 0) { foreach ($elf as $e_obj) {
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(' 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(' 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(' 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(' 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(' 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(' 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(' 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(' 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(' 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(' 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(' 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(' 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(' User allowed on Job!', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text(' Job not found!', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text(' 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(' Job item allowed on job!', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text(' Job not found!', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text(' 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(' Job Not Completed!', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text(' Job not found!', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text(' 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; }