/** * Get all necessary dates for building the TimeSheet in a single call, this is mainly as a performance optimization. * @param array $data filter data * @return array */ function getTimeSheetDates($base_date) { $epoch = TTDate::parseDateTime($base_date); if ($epoch == '') { $epoch = TTDate::getTime(); } $start_date = TTDate::getBeginWeekEpoch($epoch, $this->getCurrentUserPreferenceObject()->getStartWeekDay()); $end_date = TTDate::getEndWeekEpoch($epoch, $this->getCurrentUserPreferenceObject()->getStartWeekDay()); $retarr = array('base_date' => $epoch, 'start_date' => $start_date, 'end_date' => $end_date, 'base_display_date' => TTDate::getAPIDate('DATE', $epoch), 'start_display_date' => TTDate::getAPIDate('DATE', $start_date), 'end_display_date' => TTDate::getAPIDate('DATE', $end_date)); return $retarr; }
function generateData() { global $current_company, $current_user; TTDate::setTimeZone('PST8PDT'); $current_epoch = time(); $cf = new CompanyFactory(); $cf->StartTransaction(); $company_id = $this->createCompany(); $clf = new CompanyListFactory(); $clf->getById($company_id); $current_company = $clf->getCurrent(); if ($company_id !== FALSE) { Debug::Text('Company Created Successfully!', __FILE__, __LINE__, __METHOD__, 10); $this->createPermissionGroups($company_id); //Create currency $currency_ids[] = $this->createCurrency($company_id, 10); //USD $currency_ids[] = $this->createCurrency($company_id, 20); //CAD //Create branch $branch_ids[] = $this->createBranch($company_id, 10); //NY $branch_ids[] = $this->createBranch($company_id, 20); //WA //Create departments $department_ids[] = $this->createDepartment($company_id, 10); $department_ids[] = $this->createDepartment($company_id, 20); //Create stations $station_id = $this->createStation($company_id); //Create pay stub accounts. $this->createPayStubAccount($company_id); //Link pay stub accounts. $this->createPayStubAccountLink($company_id); //Company Deductions $this->createCompanyDeduction($company_id); //Wage Groups $wage_group_ids[] = $this->createUserWageGroups($company_id); //User Groups $user_group_ids[] = $this->createUserGroup($company_id, 10, 0); $user_group_ids[] = $this->createUserGroup($company_id, 20, $user_group_ids[0]); $user_group_ids[] = $this->createUserGroup($company_id, 30, $user_group_ids[0]); $user_group_ids[] = $this->createUserGroup($company_id, 40, 0); $user_group_ids[] = $this->createUserGroup($company_id, 50, $user_group_ids[3]); //Users $user_ids[] = $this->createUser($company_id, 10, 0, $branch_ids[0], $department_ids[0], $currency_ids[0], $user_group_ids[0]); $user_ids[] = $this->createUser($company_id, 11, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[0]); $user_ids[] = $this->createUser($company_id, 12, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[0]); $user_ids[] = $this->createUser($company_id, 13, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[0]); $user_ids[] = $this->createUser($company_id, 14, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[1]); $user_ids[] = $this->createUser($company_id, 15, 0, $branch_ids[0], $department_ids[0], $currency_ids[0], $user_group_ids[1]); $user_ids[] = $this->createUser($company_id, 16, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[1]); $user_ids[] = $this->createUser($company_id, 17, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[1]); $user_ids[] = $this->createUser($company_id, 18, 0, $branch_ids[0], $department_ids[0], $currency_ids[0], $user_group_ids[2]); $user_ids[] = $this->createUser($company_id, 19, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[2]); $user_ids[] = $this->createUser($company_id, 20, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[2]); $user_ids[] = $this->createUser($company_id, 21, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[3]); $user_ids[] = $this->createUser($company_id, 22, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[3]); $user_ids[] = $this->createUser($company_id, 23, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[3]); $user_ids[] = $this->createUser($company_id, 24, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[3]); $user_ids[] = $this->createUser($company_id, 25, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[4]); $user_ids[] = $this->createUser($company_id, 26, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[4]); $user_ids[] = $this->createUser($company_id, 27, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[4]); $user_ids[] = $this->createUser($company_id, 28, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[4]); $user_ids[] = $this->createUser($company_id, 29, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[4]); $user_ids[] = $this->createUser($company_id, 30, 0, $branch_ids[1], $department_ids[0], $currency_ids[0], $user_group_ids[4]); $user_ids[] = $this->createUser($company_id, 40, 0, $branch_ids[1], $department_ids[0], $currency_ids[0], $user_group_ids[4]); $current_user_id = $user_ids[] = $this->createUser($company_id, 100, 0, $branch_ids[0], $department_ids[0], $currency_ids[0], $user_group_ids[1]); //Create random users. for ($i = 0; $i <= $this->getMaxRandomUsers(); $i++) { $tmp_user_id = $this->createUser($company_id, 999, 0, $branch_ids[$i % 2], $department_ids[$i % 2], $currency_ids[0], $user_group_ids[$i % 5]); if ($tmp_user_id != FALSE) { $user_ids[] = $tmp_user_id; } } Debug::Arr($user_ids, 'All User IDs:', __FILE__, __LINE__, __METHOD__, 10); $ulf = new UserListFactory(); $ulf->getById($current_user_id); $current_user = $ulf->getCurrent(); unset($current_user_id); //Create policies $policy_ids['round'][] = $this->createRoundingPolicy($company_id, 10); //In $policy_ids['round'][] = $this->createRoundingPolicy($company_id, 20); //Out $policy_ids['accrual'][] = $this->createAccrualPolicy($company_id, 10); //Bank Time $policy_ids['accrual'][] = $this->createAccrualPolicy($company_id, 20); //Vacaction $policy_ids['accrual'][] = $this->createAccrualPolicy($company_id, 30); //Sick $policy_ids['overtime'][] = $this->createOverTimePolicy($company_id, 10); $policy_ids['overtime'][] = $this->createOverTimePolicy($company_id, 20, $policy_ids['accrual'][0]); $policy_ids['premium'][] = $this->createPremiumPolicy($company_id, 10); $policy_ids['absence'][] = $this->createAbsencePolicy($company_id, 10, $policy_ids['accrual'][1]); $policy_ids['absence'][] = $this->createAbsencePolicy($company_id, 20, $policy_ids['accrual'][0]); $policy_ids['absence'][] = $this->createAbsencePolicy($company_id, 30, $policy_ids['accrual'][2]); $policy_ids['meal_1'] = $this->createMealPolicy($company_id); $policy_ids['schedule_1'] = $this->createSchedulePolicy($company_id, $policy_ids['meal_1']); $policy_ids['exception_1'] = $this->createExceptionPolicy($company_id); $hierarchy_user_ids = $user_ids; $root_user_id = array_pop($hierarchy_user_ids); unset($hierarchy_user_ids[0], $hierarchy_user_ids[1]); //Create authorization hierarchy $hierarchy_control_id = $this->createAuthorizationHierarchyControl($company_id, $hierarchy_user_ids); if ($root_user_id == FALSE) { Debug::Text('Administrator wasn\'t created! Duplicate username perhaps? Are we appending a random number?', __FILE__, __LINE__, __METHOD__, 10); } //Admin user at the top $this->createAuthorizationHierarchyLevel($company_id, $hierarchy_control_id, $root_user_id, 1); $this->createAuthorizationHierarchyLevel($company_id, $hierarchy_control_id, $user_ids[0], 2); $this->createAuthorizationHierarchyLevel($company_id, $hierarchy_control_id, $user_ids[1], 3); unset($hierarchy_user_ids, $root_user_id); //Pay Period Schedule $this->createPayPeriodSchedule($company_id, $user_ids); //Create Policy Group $this->createPolicyGroup($company_id, $policy_ids['meal_1'], $policy_ids['exception_1'], NULL, $policy_ids['overtime'], $policy_ids['premium'], $policy_ids['round'], $user_ids); if (getTTProductEdition() == TT_PRODUCT_PROFESSIONAL) { //Task Groups $task_group_ids[] = $this->createTaskGroup($company_id, 10, 0); $task_group_ids[] = $this->createTaskGroup($company_id, 20, $task_group_ids[0]); $task_group_ids[] = $this->createTaskGroup($company_id, 30, $task_group_ids[0]); $task_group_ids[] = $this->createTaskGroup($company_id, 40, 0); $task_group_ids[] = $this->createTaskGroup($company_id, 50, $task_group_ids[3]); $task_group_ids[] = $this->createTaskGroup($company_id, 60, $task_group_ids[3]); //Job Tasks $default_task_id = $this->createTask($company_id, 10, $task_group_ids[2]); $task_ids[] = $this->createTask($company_id, 20, $task_group_ids[1]); $task_ids[] = $this->createTask($company_id, 30, $task_group_ids[1]); $task_ids[] = $this->createTask($company_id, 40, $task_group_ids[2]); $task_ids[] = $this->createTask($company_id, 50, $task_group_ids[4]); $task_ids[] = $this->createTask($company_id, 60, $task_group_ids[4]); $task_ids[] = $this->createTask($company_id, 70, $task_group_ids[5]); //Job Groups $job_group_ids[] = $this->createJobGroup($company_id, 10, 0); $job_group_ids[] = $this->createJobGroup($company_id, 20, $job_group_ids[0]); $job_group_ids[] = $this->createJobGroup($company_id, 30, $job_group_ids[0]); $job_group_ids[] = $this->createJobGroup($company_id, 40, 0); $job_group_ids[] = $this->createJobGroup($company_id, 50, $job_group_ids[3]); $job_group_ids[] = $this->createJobGroup($company_id, 60, $job_group_ids[3]); //Jobs $job_ids[] = $this->createJob($company_id, 10, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 11, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 12, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 13, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 14, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 15, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 16, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 17, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 18, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 19, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 20, $default_task_id, $job_group_ids[4], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 21, $default_task_id, $job_group_ids[4], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 22, $default_task_id, $job_group_ids[4], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 23, $default_task_id, $job_group_ids[5], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 24, $default_task_id, $job_group_ids[5], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 25, $default_task_id, $job_group_ids[5], $branch_ids[1], $department_ids[1]); } else { $task_ids[] = 0; $job_ids[] = 0; } //Create Accrual balances foreach ($user_ids as $user_id) { foreach ($policy_ids['accrual'] as $accrual_policy_id) { $this->createAccrualBalance($user_id, $accrual_policy_id); } unset($accrual_policy_id); } //Create recurring schedule templates $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 10, $policy_ids['schedule_1']); //Morning shift $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 20, $policy_ids['schedule_1']); //Afternoon shift $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 30, $policy_ids['schedule_1']); //Evening shift $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 40); //Split Shift $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 50, $policy_ids['schedule_1']); //Full rotation $recurring_schedule_start_date = TTDate::getBeginWeekEpoch($current_epoch + 86400 * 7.5); $this->createRecurringSchedule($company_id, $recurring_schedule_ids[0], $recurring_schedule_start_date, '', array($user_ids[0], $user_ids[1], $user_ids[2], $user_ids[3], $user_ids[4])); $this->createRecurringSchedule($company_id, $recurring_schedule_ids[1], $recurring_schedule_start_date, '', array($user_ids[5], $user_ids[6], $user_ids[7], $user_ids[8], $user_ids[9])); $this->createRecurringSchedule($company_id, $recurring_schedule_ids[2], $recurring_schedule_start_date, '', array($user_ids[10], $user_ids[11], $user_ids[12], $user_ids[13], $user_ids[14])); //Create schedule for each employee. foreach ($user_ids as $user_id) { //Create schedule starting 6 weeks ago, up to the end of the week. $schedule_options_arr = array('status_id' => 10, 'start_time' => '08:00AM', 'end_time' => '05:00PM', 'schedule_policy_id' => $policy_ids['schedule_1']); //$schedule_date = ($current_epoch-(86400*42)); $schedule_date = $current_epoch - 86400 * 14; $schedule_end_date = TTDate::getEndWeekEpoch($current_epoch); //$schedule_date = ($current_epoch-(86400*14)); //$schedule_end_date = ($current_epoch+(86400*28)); while ($schedule_date <= $schedule_end_date) { //Random departments/branches $schedule_options_arr['branch_id'] = $branch_ids[rand(0, count($branch_ids) - 1)]; $schedule_options_arr['department_id'] = $department_ids[rand(0, count($department_ids) - 1)]; //Skip weekends. if (date('w', $schedule_date) != 0 and date('w', $schedule_date) != 6) { $this->createSchedule($user_id, $schedule_date, $schedule_options_arr); } $schedule_date += 86400; } //break; unset($schedule_options_arr, $schedule_date, $schedule_end_date, $user_id); } //Punch users in/out randomly. foreach ($user_ids as $user_id) { //Pick random jobs/tasks that are used for the entire date range. //So one employee isn't punching into 15 jobs. $user_random_job_ids = array_rand($job_ids, 2); $user_random_task_ids = array_rand($job_ids, 3); //Create punches starting 6 weeks ago, up to the end of the week. //$start_date = $punch_date = ($current_epoch-(86400*42)); $start_date = $punch_date = $current_epoch - 86400 * 14; $end_date = TTDate::getEndWeekEpoch($current_epoch); //$start_date = $punch_date = ($current_epoch-(86400*14)); //$end_date = ($current_epoch+(86400*28)); $i = 0; while ($punch_date <= $end_date) { $date_stamp = TTDate::getDate('DATE', $punch_date); //$punch_full_time_stamp = strtotime($pc_data['date_stamp'].' '.$pc_data['time_stamp']); $exception_cutoff_date = $current_epoch - 86400 * 14; if (date('w', $punch_date) != 0 and date('w', $punch_date) != 6) { if ($punch_date >= $exception_cutoff_date and $i % 4 == 0) { $first_punch_in = rand(7, 8) . ':' . str_pad(rand(0, 30), 2, '0', STR_PAD_LEFT) . 'AM'; $last_punch_out = strtotime($date_stamp . ' ' . rand(4, 5) . ':' . str_pad(rand(0, 30), 2, '0', STR_PAD_LEFT) . 'PM'); if ($punch_date >= $exception_cutoff_date and rand(0, 20) == 0) { //Create request $this->createRequest(20, $user_id, $date_stamp); } if ($punch_date >= $exception_cutoff_date and rand(0, 16) == 0) { //Create request $this->createRequest(20, $user_id, $date_stamp); } } else { $first_punch_in = '08:00AM'; if ($punch_date >= $exception_cutoff_date and $i % 10 == 0) { //Don't punch out to generate exception. $last_punch_out = NULL; //Forgot to punch out request $this->createRequest(30, $user_id, $date_stamp); } else { $last_punch_out = strtotime($date_stamp . ' 5:00PM'); } } //Weekdays $this->createPunchPair($user_id, strtotime($date_stamp . ' ' . $first_punch_in), strtotime($date_stamp . ' 11:00AM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => $branch_ids[rand(0, count($branch_ids) - 1)], 'department_id' => $department_ids[rand(0, count($department_ids) - 1)], 'job_id' => $job_ids[array_rand($user_random_job_ids)], 'job_item_id' => $task_ids[array_rand($user_random_task_ids)]), TRUE); $this->createPunchPair($user_id, strtotime($date_stamp . ' 11:00AM'), strtotime($date_stamp . ' 1:00PM'), array('in_type_id' => 10, 'out_type_id' => 20, 'branch_id' => $branch_ids[rand(0, count($branch_ids) - 1)], 'department_id' => $department_ids[rand(0, count($department_ids) - 1)], 'job_id' => $job_ids[array_rand($user_random_job_ids)], 'job_item_id' => $task_ids[array_rand($user_random_task_ids)]), TRUE); //Calc total time on last punch pair only. $this->createPunchPair($user_id, strtotime($date_stamp . ' 2:00PM'), $last_punch_out, array('in_type_id' => 20, 'out_type_id' => 10, 'branch_id' => $branch_ids[rand(0, count($branch_ids) - 1)], 'department_id' => $department_ids[rand(0, count($department_ids) - 1)], 'job_id' => $job_ids[array_rand($user_random_job_ids)], 'job_item_id' => $task_ids[array_rand($user_random_task_ids)]), TRUE); } elseif ($punch_date > $exception_cutoff_date and date('w', $punch_date) == 6 and $i % 10 == 0) { //Sat. $this->createPunchPair($user_id, strtotime($date_stamp . ' 10:00AM'), strtotime($date_stamp . ' 2:30PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => $branch_ids[rand(0, count($branch_ids) - 1)], 'department_id' => $department_ids[rand(0, count($department_ids) - 1)], 'job_id' => $job_ids[array_rand($user_random_job_ids)], 'job_item_id' => $task_ids[array_rand($user_random_task_ids)]), TRUE); } //Recalculate entire day. Performance optimization. //UserDateTotalFactory::reCalculateRange( $user_id, $start_date, $end_date ); $punch_date += 86400; $i++; } unset($punch_options_arr, $punch_date, $user_id); } //Generate pay stubs for each pay period $pplf = new PayPeriodListFactory(); $pplf->getByCompanyId($company_id); if ($pplf->getRecordCount() > 0) { foreach ($pplf as $pp_obj) { foreach ($user_ids as $user_id) { $cps = new CalculatePayStub(); $cps->setUser($user_id); $cps->setPayPeriod($pp_obj->getId()); $cps->calculate(); } } } unset($pplf, $pp_obj, $user_id); } //$cf->FailTransaction(); $cf->CommitTransaction(); return FALSE; }
/** * Get all necessary dates for building the schedule in a single call, this is mainly as a performance optimization. * @param array $data filter data * @return array */ function getScheduleDates($base_date, $type, $strict = TRUE) { $epoch = TTDate::parseDateTime($base_date); if ($epoch == '') { $epoch = TTDate::getTime(); } if ($type == '') { $type = 'week'; } switch (strtolower($type)) { case 'day': if ($strict == TRUE) { $start_date = TTDate::getBeginDayEpoch($epoch); $end_date = TTDate::getEndDayEpoch($epoch); } else { $start_date = TTDate::getBeginDayEpoch($epoch); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); } break; case 'week': if ($strict == TRUE) { $start_date = TTDate::getBeginWeekEpoch($epoch, $this->getCurrentUserPreferenceObject()->getStartWeekDay()); $end_date = TTDate::getEndWeekEpoch($epoch, $this->getCurrentUserPreferenceObject()->getStartWeekDay()); } else { $start_date = TTDate::getBeginDayEpoch($epoch); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 7 * 86400); } break; case 'month': if ($strict == TRUE) { $start_date = TTDate::getBeginWeekEpoch(TTDate::getBeginMonthEpoch($epoch), $this->getCurrentUserPreferenceObject()->getStartWeekDay()); $end_date = TTDate::getEndWeekEpoch(TTDate::getEndMonthEpoch($epoch), $this->getCurrentUserPreferenceObject()->getStartWeekDay()); } else { $start_date = TTDate::getBeginDayEpoch($epoch); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 30 * 86400); } break; case 'year': if ($strict == TRUE) { $start_date = TTDate::getBeginWeekEpoch(TTDate::getBeginMonthEpoch($epoch), $this->getCurrentUserPreferenceObject()->getStartWeekDay()); $end_date = TTDate::getEndWeekEpoch(TTDate::getEndMonthEpoch(TTDate::getEndMonthEpoch($epoch) + 86400 * 2), $this->getCurrentUserPreferenceObject()->getStartWeekDay()); } else { $start_date = TTDate::getBeginDayEpoch($epoch); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 62 * 86400); } break; } $retarr = array('base_date' => $epoch, 'start_date' => $start_date, 'end_date' => $end_date, 'base_display_date' => TTDate::getAPIDate('DATE', $epoch), 'start_display_date' => TTDate::getAPIDate('DATE', $start_date), 'end_display_date' => TTDate::getAPIDate('DATE', $end_date)); Debug::Arr($retarr, 'Schedule Dates: Base Date: ' . $base_date . ' Type: ' . $type . ' Strict: ' . (int) $strict, __FILE__, __LINE__, __METHOD__, 10); return $retarr; }
function createPayStubAmendments($epoch = NULL) { //Get all recurring pay stub amendments and generate single pay stub amendments if appropriate. if ($epoch == '') { $epoch = TTDate::getTime(); } $ulf = TTnew('UserListFactory'); Debug::text('Recurring PS Amendment ID: ' . $this->getId() . ' Frequency: ' . $this->getFrequency(), __FILE__, __LINE__, __METHOD__, 10); $this->StartTransaction(); $tmp_user_ids = $this->getUser(); if ($tmp_user_ids[0] == -1) { $ulf->getByCompanyIdAndStatus($this->getCompany(), 10); foreach ($ulf as $user_obj) { $user_ids[] = $user_obj->getId(); } unset($user_obj); } else { $user_ids = $this->getUser(); } unset($tmp_user_ids); Debug::text('Total User IDs: ' . count($user_ids), __FILE__, __LINE__, __METHOD__, 10); if (is_array($user_ids) and count($user_ids) > 0) { //Make the PS amendment duplicate check start/end date separate //Make the PS amendment effective date separate. switch ($this->getFrequency()) { case 10: //Get all open pay periods $pplf = TTnew('PayPeriodListFactory'); //FIXME: Get all non-closed pay periods AFTER the start date. $pplf->getByUserIdListAndNotStatusAndStartDateAndEndDate($user_ids, 20, $this->getStartDate(), $this->getEndDate()); //All non-closed pay periods Debug::text('Found Open Pay Periods: ' . $pplf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); foreach ($pplf as $pay_period_obj) { Debug::text('Working on Pay Period: ' . $pay_period_obj->getId(), __FILE__, __LINE__, __METHOD__, 10); //If near the end of a pay period, or a pay period is already ended, add PS amendment if //it does not already exist. if ($epoch >= $pay_period_obj->getEndDate() and $this->checkTimeFrame($epoch)) { Debug::text('After end of pay period. Start Date: ' . TTDate::getDate('DATE+TIME', $pay_period_obj->getStartDate()) . ' End Date: ' . TTDate::getDate('DATE+TIME', $pay_period_obj->getEndDate()), __FILE__, __LINE__, __METHOD__, 10); $psalf = TTnew('PayStubAmendmentListFactory'); //Loop through each user of this Pay Period Schedule adding PS amendments if they don't already exist. $pay_period_schedule_users = $pay_period_obj->getPayPeriodScheduleObject()->getUser(); Debug::text(' Pay Period Schedule Users: ' . count($pay_period_schedule_users), __FILE__, __LINE__, __METHOD__, 10); foreach ($pay_period_schedule_users as $user_id) { //Make sure schedule user is in the PS amendment user list and user is active. Debug::text(' Pay Period Schedule User: '******' Recurring PS Amendment Selected Users: ', __FILE__, __LINE__, __METHOD__,10); if ($ulf->getById($user_id)->getCurrent()->getStatus() == 10 and in_array($user_id, $user_ids)) { //Check to see if the amendment was added already. if ($psalf->getByUserIdAndRecurringPayStubAmendmentIdAndStartDateAndEndDate($user_id, $this->getId(), $pay_period_obj->getStartDate(), $pay_period_obj->getEndDate())->getRecordCount() == 0) { //No amendment, good to insert one Debug::text('Inserting Recurring PS Amendment for User: '******'PayStubAmendmentFactory'); $psaf->setUser($user_id); $psaf->setStatus(50); $psaf->setType($this->getType()); $psaf->setRecurringPayStubAmendmentId($this->getId()); $psaf->setPayStubEntryNameId($this->getPayStubEntryNameId()); if ($this->getType() == 10) { $psaf->setRate($this->getRate()); $psaf->setUnits($this->getUnits()); $psaf->setAmount($this->getAmount()); } else { $psaf->setPercentAmount($this->getPercentAmount()); $psaf->setPercentAmountEntryNameID($this->getPercentAmountEntryNameId()); } $psaf->setDescription($this->getPayStubAmendmentDescription()); $psaf->setEffectiveDate(TTDate::getBeginDayEpoch($pay_period_obj->getEndDate())); if ($psaf->isValid()) { $psaf->Save(); } } else { //Amendment already inserted! Debug::text('Recurring PS Amendment already inserted for User: '******'Skipping User because they are INACTIVE or are not on the Recurring PS Amendment User List - ID: ' . $user_id, __FILE__, __LINE__, __METHOD__, 10); //continue; } } } else { Debug::text('Not in TimeFrame, not inserting amendments: Epoch: ' . $epoch . ' Pay Period End Date: ' . $pay_period_obj->getEndDate(), __FILE__, __LINE__, __METHOD__, 10); } } break; case 30: //Weekly //Weekly case 40: //Monthly //Monthly case 70: //Annually switch ($this->getFrequency()) { case 30: $trigger_date = TTDate::getDateOfNextDayOfWeek(TTDate::getBeginWeekEpoch($epoch), $this->getStartDate()); $start_date = TTDate::getBeginWeekEpoch($epoch); $end_date = TTDate::getEndWeekEpoch($epoch); break; case 40: $trigger_date = TTDate::getDateOfNextDayOfMonth(TTDate::getBeginMonthEpoch($epoch), $this->getStartDate()); //$monthly_date = TTDate::getDateOfNextDayOfMonth( TTDate::getBeginMonthEpoch($epoch), $this->getStartDate() ); $start_date = TTDate::getBeginMonthEpoch($epoch); $end_date = TTDate::getEndMonthEpoch($epoch); break; case 70: $trigger_date = TTDate::getDateOfNextYear($this->getStartDate(), $epoch); //$start_date = TTDate::getBeginYearEpoch($epoch); //$end_date = TTDate::getEndYearEpoch($epoch); $start_date = TTDate::getBeginDayEpoch($epoch - 86400 * 365); $end_date = TTDate::getEndDayEpoch($epoch); break; } Debug::text('Trigger Date: ' . TTDate::getDate('DATE', $trigger_date), __FILE__, __LINE__, __METHOD__, 10); if ($epoch >= $trigger_date and $this->checkTimeFrame($epoch)) { Debug::text('Within timeframe... Start Date: ' . TTDate::getDate('DATE+TIME', $start_date) . ' End Date: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10); foreach ($user_ids as $user_id) { //Make sure schedule user is in the PS amendment user list and user is active. if ($ulf->getById($user_id)->getCurrent()->getStatus() != 10 and !in_array($user_id, $user_ids)) { Debug::text('Skipping User because they are INACTIVE or are not on the Recurring PS Amendment User List - ID: ' . $user_id, __FILE__, __LINE__, __METHOD__, 10); continue; } $psalf = TTnew('PayStubAmendmentListFactory'); if ($psalf->getByUserIdAndRecurringPayStubAmendmentIdAndStartDateAndEndDate($user_id, $this->getId(), $start_date, $end_date)->getRecordCount() == 0) { //No amendment, good to insert one Debug::text('Inserting Recurring PS Amendment for User: '******'PayStubAmendmentFactory'); $psaf->setUser($user_id); $psaf->setStatus(50); $psaf->setType($this->getType()); $psaf->setRecurringPayStubAmendmentId($this->getId()); $psaf->setPayStubEntryNameId($this->getPayStubEntryNameId()); if ($this->getType() == 10) { $psaf->setRate($this->getRate()); $psaf->setUnits($this->getUnits()); $psaf->setAmount($this->getAmount()); } else { $psaf->setPercentAmount($this->getPercentAmount()); $psaf->setPercentAmountEntryNameID($this->getPercentAmountEntryNameId()); } $psaf->setDescription($this->getDescription()); $psaf->setEffectiveDate(TTDate::getBeginDayEpoch($trigger_date)); if ($psaf->isValid()) { $psaf->Save(); } } else { //Amendment already inserted! Debug::text('Recurring PS Amendment already inserted for User: ' . $user_id, __FILE__, __LINE__, __METHOD__, 10); } } } break; } } //$this->FailTransaction(); $this->CommitTransaction(); return TRUE; }
function generateData() { global $current_company, $current_user; TTDate::setTimeZone('PST8PDT'); $current_epoch = time(); $cf = TTnew('CompanyFactory'); $cf->StartTransaction(); $company_id = $this->createCompany(); $clf = TTnew('CompanyListFactory'); $clf->getById($company_id); $current_company = $clf->getCurrent(); if ($company_id !== FALSE) { Debug::Text('Company Created Successfully!', __FILE__, __LINE__, __METHOD__, 10); $this->createPermissionGroups($company_id); //Create currency $currency_ids[] = $this->createCurrency($company_id, 10); //USD $currency_ids[] = $this->createCurrency($company_id, 20); //CAD $currency_ids[] = $this->createCurrency($company_id, 30); //EUR //Create branch $branch_ids[] = $this->createBranch($company_id, 10); //NY $branch_ids[] = $this->createBranch($company_id, 20); //WA //Create departments $department_ids[] = $this->createDepartment($company_id, 10); $department_ids[] = $this->createDepartment($company_id, 20); $department_ids[] = $this->createDepartment($company_id, 30); $department_ids[] = $this->createDepartment($company_id, 40); //Create stations $station_id = $this->createStation($company_id); //Create pay stub accounts. $this->createPayStubAccount($company_id); //Link pay stub accounts. $this->createPayStubAccountLink($company_id); //Company Deductions $this->createCompanyDeduction($company_id); //Wage Groups $wage_group_ids[] = $this->createUserWageGroups($company_id); //User Groups $user_group_ids[] = $this->createUserGroup($company_id, 10, 0); $user_group_ids[] = $this->createUserGroup($company_id, 20, $user_group_ids[0]); $user_group_ids[] = $this->createUserGroup($company_id, 30, $user_group_ids[0]); $user_group_ids[] = $this->createUserGroup($company_id, 40, 0); $user_group_ids[] = $this->createUserGroup($company_id, 50, $user_group_ids[3]); //User Title $user_title_ids[] = $this->createUserTitle($company_id, 10); $user_title_ids[] = $this->createUserTitle($company_id, 20); $user_title_ids[] = $this->createUserTitle($company_id, 30); $user_title_ids[] = $this->createUserTitle($company_id, 40); $user_title_ids[] = $this->createUserTitle($company_id, 50); $user_title_ids[] = $this->createUserTitle($company_id, 60); $user_title_ids[] = $this->createUserTitle($company_id, 70); $user_title_ids[] = $this->createUserTitle($company_id, 80); $user_title_ids[] = $this->createUserTitle($company_id, 90); //Ethnic Group $ethnic_group_ids[] = $this->createEthnicGroup($company_id, 10); $ethnic_group_ids[] = $this->createEthnicGroup($company_id, 20); $ethnic_group_ids[] = $this->createEthnicGroup($company_id, 30); $ethnic_group_ids[] = $this->createEthnicGroup($company_id, 40); $ethnic_group_ids[] = $this->createEthnicGroup($company_id, 50); //Users $user_ids[] = $this->createUser($company_id, 10, 0, $branch_ids[0], $department_ids[0], $currency_ids[0], $user_group_ids[0], $user_title_ids[0], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 11, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[0], $user_title_ids[0], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 12, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[0], $user_title_ids[0], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 13, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[0], $user_title_ids[0], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 14, 0, $branch_ids[0], $department_ids[1], $currency_ids[1], $user_group_ids[1], $user_title_ids[1], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 15, 0, $branch_ids[0], $department_ids[0], $currency_ids[1], $user_group_ids[1], $user_title_ids[1], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 16, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[1], $user_title_ids[1], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 17, 0, $branch_ids[0], $department_ids[1], $currency_ids[0], $user_group_ids[1], $user_title_ids[1], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 18, 0, $branch_ids[0], $department_ids[0], $currency_ids[0], $user_group_ids[2], $user_title_ids[2], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 19, 0, $branch_ids[0], $department_ids[1], $currency_ids[2], $user_group_ids[2], $user_title_ids[2], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 20, 0, $branch_ids[0], $department_ids[1], $currency_ids[2], $user_group_ids[2], $user_title_ids[2], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 21, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[3], $user_title_ids[3], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 22, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[3], $user_title_ids[3], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 23, 0, $branch_ids[1], $department_ids[2], $currency_ids[0], $user_group_ids[3], $user_title_ids[3], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 24, 0, $branch_ids[1], $department_ids[2], $currency_ids[0], $user_group_ids[3], $user_title_ids[3], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 25, 0, $branch_ids[1], $department_ids[2], $currency_ids[0], $user_group_ids[4], $user_title_ids[4], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 26, 0, $branch_ids[1], $department_ids[1], $currency_ids[0], $user_group_ids[4], $user_title_ids[4], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 27, 0, $branch_ids[1], $department_ids[3], $currency_ids[0], $user_group_ids[4], $user_title_ids[4], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 28, 0, $branch_ids[1], $department_ids[3], $currency_ids[0], $user_group_ids[4], $user_title_ids[4], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 29, 0, $branch_ids[1], $department_ids[3], $currency_ids[0], $user_group_ids[4], $user_title_ids[4], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 30, 0, $branch_ids[1], $department_ids[0], $currency_ids[0], $user_group_ids[4], $user_title_ids[4], $ethnic_group_ids); $user_ids[] = $this->createUser($company_id, 40, 0, $branch_ids[1], $department_ids[0], $currency_ids[0], $user_group_ids[4], $user_title_ids[4], $ethnic_group_ids); $current_user_id = $user_ids[] = $this->createUser($company_id, 100, 0, $branch_ids[0], $department_ids[0], $currency_ids[0], $user_group_ids[4], $user_title_ids[0], $ethnic_group_ids); //Create random users. for ($i = 0; $i <= $this->getMaxRandomUsers(); $i++) { $tmp_user_id = $this->createUser($company_id, 999, 0, $branch_ids[$i % 2], $department_ids[$i % 4], $currency_ids[0], $user_group_ids[$i % 5], $user_title_ids[$i % 9], $ethnic_group_ids); if ($tmp_user_id != FALSE) { $user_ids[] = $tmp_user_id; } } Debug::Arr($user_ids, 'All User IDs:', __FILE__, __LINE__, __METHOD__, 10); $ulf = TTnew('UserListFactory'); $ulf->getById($current_user_id); $current_user = $ulf->getCurrent(); if ($current_user_id === FALSE) { Debug::Text('Administrator user wasn\'t created! Duplicate username perhaps? Are we appending a random number?', __FILE__, __LINE__, __METHOD__, 10); return FALSE; } unset($current_user_id); //Create policies $policy_ids['round'][] = $this->createRoundingPolicy($company_id, 10); //In $policy_ids['round'][] = $this->createRoundingPolicy($company_id, 20); //Out $policy_ids['accrual'][] = $this->createAccrualPolicy($company_id, 10); //Bank Time $policy_ids['accrual'][] = $this->createAccrualPolicy($company_id, 20); //Vacaction $policy_ids['accrual'][] = $this->createAccrualPolicy($company_id, 30); //Sick $policy_ids['overtime'][] = $this->createOverTimePolicy($company_id, 10); $policy_ids['overtime'][] = $this->createOverTimePolicy($company_id, 20, $policy_ids['accrual'][0]); if (getTTProductEdition() >= TT_PRODUCT_ENTERPRISE) { $policy_ids['expense'][] = $this->createExpensePolicy($company_id, 100); // Tax(Percent) - HST $policy_ids['expense'][] = $this->createExpensePolicy($company_id, 110); // Tax(Percent) - VAT $policy_ids['expense'][] = $this->createExpensePolicy($company_id, 120); // Tax(Flat Amount) - Improvement Fee $policy_ids['expense'][] = $this->createExpensePolicy($company_id, 10, array($policy_ids['expense'][1])); // Flat Amount $policy_ids['expense'][] = $this->createExpensePolicy($company_id, 20, array($policy_ids['expense'][0], $policy_ids['expense'][1])); // Percent $policy_ids['expense'][] = $this->createExpensePolicy($company_id, 30); // Per Unit - No Tax $policy_ids['expense'][] = $this->createExpensePolicy($company_id, 40, array($policy_ids['expense'][0], $policy_ids['expense'][2])); // Flat Amount } $policy_ids['premium'][] = $this->createPremiumPolicy($company_id, 10); $policy_ids['absence'][] = $this->createAbsencePolicy($company_id, 10, $policy_ids['accrual'][1]); $policy_ids['absence'][] = $this->createAbsencePolicy($company_id, 20, $policy_ids['accrual'][0]); $policy_ids['absence'][] = $this->createAbsencePolicy($company_id, 30, $policy_ids['accrual'][2]); $policy_ids['meal_1'] = $this->createMealPolicy($company_id); $policy_ids['schedule_1'] = $this->createSchedulePolicy($company_id, $policy_ids['meal_1']); $policy_ids['exception_1'] = $this->createExceptionPolicy($company_id); $hierarchy_user_ids = $user_ids; $root_user_id = array_pop($hierarchy_user_ids); unset($hierarchy_user_ids[0], $hierarchy_user_ids[1]); //Create authorization hierarchy $hierarchy_control_id = $this->createAuthorizationHierarchyControl($company_id, $hierarchy_user_ids); if ($root_user_id == FALSE) { Debug::Text('Administrator wasn\'t created! Duplicate username perhaps? Are we appending a random number?', __FILE__, __LINE__, __METHOD__, 10); return FALSE; } //Admin user at the top $this->createAuthorizationHierarchyLevel($company_id, $hierarchy_control_id, $root_user_id, 1); $this->createAuthorizationHierarchyLevel($company_id, $hierarchy_control_id, $user_ids[0], 2); $this->createAuthorizationHierarchyLevel($company_id, $hierarchy_control_id, $user_ids[1], 3); unset($hierarchy_user_ids, $root_user_id); //Pay Period Schedule $this->createPayPeriodSchedule($company_id, $user_ids); //Create Policy Group $this->createPolicyGroup($company_id, $policy_ids['meal_1'], $policy_ids['exception_1'], NULL, $policy_ids['overtime'], $policy_ids['premium'], $policy_ids['round'], $user_ids, NULL, NULL, $policy_ids['expense'], $policy_ids['absence']); if (getTTProductEdition() >= TT_PRODUCT_CORPORATE) { //Client Groups $client_group_ids[] = $this->createClientGroup($company_id, 10, 0); $client_group_ids[] = $this->createClientGroup($company_id, 20, $client_group_ids[0]); $client_group_ids[] = $this->createClientGroup($company_id, 30, $client_group_ids[0]); $client_group_ids[] = $this->createClientGroup($company_id, 40, 0); $client_group_ids[] = $this->createClientGroup($company_id, 50, $client_group_ids[3]); $product_group_ids[] = $this->createProductGroup($company_id, 10, 0); $product_group_ids[] = $this->createProductGroup($company_id, 20, 0); $product_group_ids[] = $this->createProductGroup($company_id, 30, $product_group_ids[1]); $product_group_ids[] = $this->createProductGroup($company_id, 40, $product_group_ids[2]); $product_group_ids[] = $this->createProductGroup($company_id, 50, $product_group_ids[1]); //Create at least 10 Clients $client_ids[] = $this->createClient($company_id, 10, $user_ids, $client_group_ids); $client_ids[] = $this->createClient($company_id, 20, $user_ids, $client_group_ids); $client_ids[] = $this->createClient($company_id, 30, $user_ids, $client_group_ids); $client_ids[] = $this->createClient($company_id, 40, $user_ids, $client_group_ids); $client_ids[] = $this->createClient($company_id, 50, $user_ids, $client_group_ids); $client_ids[] = $this->createClient($company_id, 60, $user_ids, $client_group_ids); $client_ids[] = $this->createClient($company_id, 70, $user_ids, $client_group_ids); $client_ids[] = $this->createClient($company_id, 80, $user_ids, $client_group_ids); //Create Invoice District $invoice_district_ids[] = $this->createInvoiceDistrict($company_id, 10); //US $invoice_district_ids[] = $this->createInvoiceDistrict($company_id, 20); //US $invoice_district_ids[] = $this->createInvoiceDistrict($company_id, 30); //CA $invoice_district_ids[] = $this->createInvoiceDistrict($company_id, 40); //CA //Create Client Contact, Each client should have at least two client contacts. foreach ($client_ids as $client_id) { $client_contact_ids[] = $this->createClientContact($client_id, 10, $invoice_district_ids, $currency_ids[0]); $client_contact_ids[] = $this->createClientContact($client_id, 20, $invoice_district_ids, $currency_ids[0]); } $product_ids[10][] = $this->createProduct($company_id, $product_group_ids, 10, $currency_ids[0]); $product_ids[10][] = $this->createProduct($company_id, $product_group_ids, 20, $currency_ids[0]); $product_ids[10][] = $this->createProduct($company_id, $product_group_ids, 30, $currency_ids[0]); $product_ids[10][] = $this->createProduct($company_id, $product_group_ids, 40, $currency_ids[0]); $product_ids[10][] = $this->createProduct($company_id, $product_group_ids, 50, $currency_ids[0]); $product_ids[20][] = $this->createProduct($company_id, $product_group_ids, 60, $currency_ids[0]); $product_ids[30][] = $this->createProduct($company_id, $product_group_ids, 70, $currency_ids[0]); $product_ids[40][] = $this->createProduct($company_id, $product_group_ids, 80, $currency_ids[0]); $product_ids[50][] = $this->createProduct($company_id, $product_group_ids, 90, $currency_ids[0]); $area_policy_ids[] = $this->createAreaPolicy($company_id, 20, array($invoice_district_ids[0], $invoice_district_ids[1])); $area_policy_ids[] = $this->createAreaPolicy($company_id, 10, array($invoice_district_ids[2], $invoice_district_ids[3])); $tax_policy_ids[] = $this->createTaxPolicy($company_id, $product_ids[30][0], $area_policy_ids); //Create Shipping Policy $shipping_policy_ids[] = $this->createShippingPolicy($company_id, $product_ids[40][0], 10, $currency_ids[0], $area_policy_ids); $shipping_policy_ids[] = $this->createShippingPolicy($company_id, $product_ids[40][0], 20, $currency_ids[0], $area_policy_ids); //Create Invoice foreach ($client_ids as $client_id) { $invoice_ids[] = $this->createInvoice($company_id, $client_id, $currency_ids[0], $product_ids[20][0], 100, array(), $user_ids, $shipping_policy_ids); $invoice_ids[] = $this->createInvoice($company_id, $client_id, $currency_ids[0], array($product_ids[10][0], $product_ids[10][1], $product_ids[10][2], $product_ids[10][3], $product_ids[10][4], $product_ids[20][0]), 40, NULL, $user_ids, $shipping_policy_ids); $invoice_ids[] = $this->createInvoice($company_id, $client_id, $currency_ids[0], array($product_ids[10][1], $product_ids[10][2], $product_ids[10][3]), 40, NULL, $user_ids, $shipping_policy_ids); $invoice_ids[] = $this->createInvoice($company_id, $client_id, $currency_ids[0], array($product_ids[10][0], $product_ids[10][4], $product_ids[20][0]), 100, array(), $user_ids, $shipping_policy_ids); $invoice_ids[] = $this->createInvoice($company_id, $client_id, $currency_ids[0], array($product_ids[10][3], $product_ids[10][4]), 100, array(), $user_ids, $shipping_policy_ids); } } else { $client_group_ids[] = 0; $product_group_ids[] = 0; $client_ids[] = 0; $invoice_district_ids[] = 0; $client_contact_ids[] = 0; $product_ids[10] = 0; $product_ids[20] = 0; $product_ids[30] = 0; $product_ids[40] = 0; $product_ids[50] = 0; $area_policy_ids[] = 0; $tax_policy_ids[] = 0; $shipping_policy_ids[] = 0; $invoice_ids[] = 0; } if (getTTProductEdition() >= TT_PRODUCT_CORPORATE) { //Task Groups $task_group_ids[] = $this->createTaskGroup($company_id, 10, 0); $task_group_ids[] = $this->createTaskGroup($company_id, 20, $task_group_ids[0]); $task_group_ids[] = $this->createTaskGroup($company_id, 30, $task_group_ids[0]); $task_group_ids[] = $this->createTaskGroup($company_id, 40, 0); $task_group_ids[] = $this->createTaskGroup($company_id, 50, $task_group_ids[3]); $task_group_ids[] = $this->createTaskGroup($company_id, 60, $task_group_ids[3]); //Job Tasks $default_task_id = $this->createTask($company_id, 10, $task_group_ids[2]); $task_ids[] = $this->createTask($company_id, 20, $task_group_ids[1]); $task_ids[] = $this->createTask($company_id, 30, $task_group_ids[1]); $task_ids[] = $this->createTask($company_id, 40, $task_group_ids[2]); $task_ids[] = $this->createTask($company_id, 50, $task_group_ids[4]); $task_ids[] = $this->createTask($company_id, 60, $task_group_ids[4]); $task_ids[] = $this->createTask($company_id, 70, $task_group_ids[5]); //Job Groups $job_group_ids[] = $this->createJobGroup($company_id, 10, 0); $job_group_ids[] = $this->createJobGroup($company_id, 20, $job_group_ids[0]); $job_group_ids[] = $this->createJobGroup($company_id, 30, $job_group_ids[0]); $job_group_ids[] = $this->createJobGroup($company_id, 40, 0); $job_group_ids[] = $this->createJobGroup($company_id, 50, $job_group_ids[3]); $job_group_ids[] = $this->createJobGroup($company_id, 60, $job_group_ids[3]); //Jobs $job_ids[] = $this->createJob($company_id, 10, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 11, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 12, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 13, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 14, $default_task_id, $job_group_ids[1], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 15, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 16, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 17, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 18, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 19, $default_task_id, $job_group_ids[2], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 20, $default_task_id, $job_group_ids[4], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 21, $default_task_id, $job_group_ids[4], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 22, $default_task_id, $job_group_ids[4], $branch_ids[0], $department_ids[0]); $job_ids[] = $this->createJob($company_id, 23, $default_task_id, $job_group_ids[5], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 24, $default_task_id, $job_group_ids[5], $branch_ids[1], $department_ids[1]); $job_ids[] = $this->createJob($company_id, 25, $default_task_id, $job_group_ids[5], $branch_ids[1], $department_ids[1]); } else { $task_ids[] = 0; $job_ids[] = 0; } if (getTTProductEdition() >= TT_PRODUCT_ENTERPRISE) { $user_expense_ids[] = $this->createUserExpense($user_ids[0], $policy_ids['expense'][3], $branch_ids[0], $department_ids[1], $currency_ids[0], $job_ids[1], $task_ids[1]); $user_expense_ids[] = $this->createUserExpense($user_ids[3], $policy_ids['expense'][3], $branch_ids[0], $department_ids[2], $currency_ids[1], $job_ids[1], $task_ids[0]); $user_expense_ids[] = $this->createUserExpense($user_ids[4], $policy_ids['expense'][3], $branch_ids[0], $department_ids[0], $currency_ids[0], $job_ids[1], $task_ids[2]); $user_expense_ids[] = $this->createUserExpense($user_ids[5], $policy_ids['expense'][3], $branch_ids[0], $department_ids[0], $currency_ids[0], $job_ids[2], $task_ids[2]); $user_expense_ids[] = $this->createUserExpense($user_ids[6], $policy_ids['expense'][3], $branch_ids[0], $department_ids[0], $currency_ids[0], $job_ids[2], $task_ids[2]); $user_expense_ids[] = $this->createUserExpense($user_ids[7], $policy_ids['expense'][3], $branch_ids[0], $department_ids[0], $currency_ids[0], $job_ids[2], $task_ids[2]); $user_expense_ids[] = $this->createUserExpense($user_ids[8], $policy_ids['expense'][3], $branch_ids[0], $department_ids[0], $currency_ids[0], $job_ids[3], $task_ids[1]); $user_expense_ids[] = $this->createUserExpense($user_ids[9], $policy_ids['expense'][3], $branch_ids[1], $department_ids[0], $currency_ids[0], $job_ids[4], $task_ids[1]); $user_expense_ids[] = $this->createUserExpense($user_ids[10], $policy_ids['expense'][3], $branch_ids[1], $department_ids[1], $currency_ids[0], $job_ids[4], $task_ids[1]); $user_expense_ids[] = $this->createUserExpense($user_ids[11], $policy_ids['expense'][3], $branch_ids[1], $department_ids[1], $currency_ids[0], $job_ids[5], $task_ids[0]); $user_expense_ids[] = $this->createUserExpense($user_ids[12], $policy_ids['expense'][4], $branch_ids[1], $department_ids[1], $currency_ids[0], $job_ids[6], $task_ids[0]); $user_expense_ids[] = $this->createUserExpense($user_ids[13], $policy_ids['expense'][4], $branch_ids[1], $department_ids[2], $currency_ids[0], $job_ids[7], $task_ids[0]); $user_expense_ids[] = $this->createUserExpense($user_ids[14], $policy_ids['expense'][4], $branch_ids[1], $department_ids[2], $currency_ids[0], $job_ids[7], $task_ids[4]); $user_expense_ids[] = $this->createUserExpense($user_ids[15], $policy_ids['expense'][4], $branch_ids[1], $department_ids[2], $currency_ids[0], $job_ids[8], $task_ids[4]); $user_expense_ids[] = $this->createUserExpense($user_ids[16], $policy_ids['expense'][4], $branch_ids[1], $department_ids[3], $currency_ids[0], $job_ids[8], $task_ids[4], NULL, 50); $user_expense_ids[] = $this->createUserExpense($user_ids[17], $policy_ids['expense'][4], $branch_ids[1], $department_ids[3], $currency_ids[0], $job_ids[9], $task_ids[1], NULL, 50); $user_expense_ids[] = $this->createUserExpense($user_ids[18], $policy_ids['expense'][4], $branch_ids[1], $department_ids[3], $currency_ids[0], $job_ids[10], $task_ids[3], NULL, 50); $user_expense_ids[] = $this->createUserExpense($user_ids[19], $policy_ids['expense'][4], $branch_ids[1], $department_ids[3], $currency_ids[0], $job_ids[0], $task_ids[3], NULL, 50); $user_expense_ids[] = $this->createUserExpense($user_ids[20], $policy_ids['expense'][4], $branch_ids[1], $department_ids[3], $currency_ids[0], $job_ids[0], $task_ids[3], NULL, 50); } else { $user_expense_ids[] = 0; } //Create Qualification $qualification_group_ids[] = $this->createQualificationGroup($company_id, 10, 0); $qualification_group_ids[] = $this->createQualificationGroup($company_id, 20, 0); $qualification_group_ids[] = $this->createQualificationGroup($company_id, 30, 0); $qualification_group_ids[] = $this->createQualificationGroup($company_id, 40, 0); $qualification_group_ids[] = $this->createQualificationGroup($company_id, 50, 0); //Create Accrual balances foreach ($user_ids as $user_id) { foreach ($policy_ids['accrual'] as $accrual_policy_id) { $this->createAccrualBalance($user_id, $accrual_policy_id); } unset($accrual_policy_id); } // Create Qualification $qualification_ids['skill'][] = $this->createQualification($company_id, 10, $qualification_group_ids[0]); $qualification_ids['skill'][] = $this->createQualification($company_id, 20, $qualification_group_ids[1]); $qualification_ids['skill'][] = $this->createQualification($company_id, 40, $qualification_group_ids[2]); $qualification_ids['skill'][] = $this->createQualification($company_id, 50, $qualification_group_ids[3]); $qualification_ids['skill'][] = $this->createQualification($company_id, 60, $qualification_group_ids[0]); $qualification_ids['license'][] = $this->createQualification($company_id, 200, $qualification_group_ids[0]); $qualification_ids['license'][] = $this->createQualification($company_id, 210, $qualification_group_ids[1]); $qualification_ids['license'][] = $this->createQualification($company_id, 220, $qualification_group_ids[1]); $qualification_ids['license'][] = $this->createQualification($company_id, 230, $qualification_group_ids[2]); $qualification_ids['license'][] = $this->createQualification($company_id, 240, $qualification_group_ids[4]); $qualification_ids['education'][] = $this->createQualification($company_id, 310, $qualification_group_ids[4]); $qualification_ids['education'][] = $this->createQualification($company_id, 320, $qualification_group_ids[2]); $qualification_ids['education'][] = $this->createQualification($company_id, 330, $qualification_group_ids[3]); $qualification_ids['education'][] = $this->createQualification($company_id, 340, $qualification_group_ids[2]); $qualification_ids['education'][] = $this->createQualification($company_id, 350, $qualification_group_ids[1]); $qualification_ids['language'][] = $this->createQualification($company_id, 400, $qualification_group_ids[0]); $qualification_ids['language'][] = $this->createQualification($company_id, 410, $qualification_group_ids[1]); $qualification_ids['language'][] = $this->createQualification($company_id, 420, $qualification_group_ids[3]); $qualification_ids['membership'][] = $this->createQualification($company_id, 500, $qualification_group_ids[0]); $qualification_ids['membership'][] = $this->createQualification($company_id, 510, $qualification_group_ids[1]); $qualification_ids['membership'][] = $this->createQualification($company_id, 520, $qualification_group_ids[2]); $qualification_ids['membership'][] = $this->createQualification($company_id, 530, $qualification_group_ids[3]); $kpi_group_ids[] = $this->createKPIGroup($company_id, 10, 0); $kpi_group_ids[] = $this->createKPIGroup($company_id, 20, 0); $kpi_group_ids[] = $this->createKPIGroup($company_id, 30, 0); $kpi_group_ids[] = $this->createKPIGroup($company_id, 40, 0); $kpi_group_ids[] = $this->createKPIGroup($company_id, 50, 0); $kpi_all_ids[]['10'] = $this->createKPI($company_id, 10, 10, array(-1)); $kpi_all_ids[]['10'] = $this->createKPI($company_id, 20, 10, array(-1)); $kpi_all_ids[]['20'] = $this->createKPI($company_id, 30, 20, array(-1)); $kpi_group1_ids[]['20'] = $this->createKPI($company_id, 40, 20, array($kpi_group_ids[0])); $kpi_group1_ids[]['10'] = $this->createKPI($company_id, 50, 10, array($kpi_group_ids[0])); $kpi_group2_ids[]['30'] = $this->createKPI($company_id, 60, 30, array($kpi_group_ids[1])); $kpi_group2_ids[]['30'] = $this->createKPI($company_id, 70, 30, array($kpi_group_ids[1])); foreach ($user_ids as $code => $user_id) { $reviewer_user_ids = $user_ids; unset($reviewer_user_ids[$code]); $reviewer_user_ids = array_values($reviewer_user_ids); $reviewer_user_random_ids = array_rand($reviewer_user_ids, 3); $user_review_control_id = $this->createUserReviewControl($user_id, $reviewer_user_ids[array_rand($reviewer_user_random_ids)]); if ($user_review_control_id != '') { foreach ($kpi_all_ids as $kpi_all_id) { foreach ($kpi_all_id as $code => $kpi_id) { $this->createUserReview($user_review_control_id, $code, $kpi_id); } } $group_id = rand(1, 2); switch ($group_id) { case 1: foreach ($kpi_group1_ids as $kpi_group1_id) { foreach ($kpi_group1_id as $code => $kpi_id) { $this->createUserReview($user_review_control_id, $code, $kpi_id); } } break; case 2: foreach ($kpi_group2_ids as $kpi_group2_id) { foreach ($kpi_group2_id as $code => $kpi_id) { $this->createUserReview($user_review_control_id, $code, $kpi_id); } } break; } } } //Create Qualification , Skills , Education ,Language , Lencense , Membership $x = 1; foreach ($user_ids as $user_id) { $type = $x * 10; $rand_arr_ids = array(1, 2, 3, 4, 5); $rand_ids = array_rand($rand_arr_ids, rand(3, 5)); foreach ($rand_ids as $rand_id) { switch ($rand_arr_ids[$rand_id]) { case 1: $this->createUserSkill($user_id, $type, $qualification_ids['skill'][rand(0, count($qualification_ids['skill']) - 1)]); break; case 2: $this->createUserEducation($user_id, $qualification_ids['education'][rand(0, count($qualification_ids['education']) - 1)]); break; case 3: $this->createUserLicense($user_id, $qualification_ids['license'][rand(0, count($qualification_ids['license']) - 1)]); break; case 4: $this->createUserLanguage($user_id, $type, $qualification_ids['language'][rand(0, count($qualification_ids['language']) - 1)]); break; case 5: $this->createUserMembership($user_id, $type, $qualification_ids['membership'][rand(0, count($qualification_ids['membership']) - 1)]); break; } } $x++; } foreach ($user_ids as $user_id) { $x = 1; while ($x <= 5) { $this->createUserContact($user_id); $x++; } } if (getTTProductEdition() >= TT_PRODUCT_ENTERPRISE) { $x = 1; while ($x <= 9) { $interviewer_random_user_ids = array_rand($user_ids, 3); $user_id = $user_ids[array_rand($interviewer_random_user_ids)]; $job_vacancy_id = $this->createJobVacancy($company_id, $user_id, $user_title_ids[rand(0, count($user_title_ids) - 1)], $branch_ids[rand(0, count($branch_ids) - 1)], $department_ids[rand(0, count($department_ids) - 1)]); if ($job_vacancy_id != '') { $job_applicant_id = $this->createJobApplicant($company_id); $y = 1; while ($y <= rand(75, 150)) { $this->createJobApplication($job_applicant_id, $job_vacancy_id, $user_id); $y++; } $n = 1; while ($n <= rand(2, 5)) { $this->createJobApplicantLocation($job_applicant_id); $this->createJobApplicantEmployment($job_applicant_id, $n * 10); $this->createJobApplicantReference($job_applicant_id); $this->createJobApplicantSkill($job_applicant_id, $qualification_ids['skill'][rand(0, count($qualification_ids['skill']) - 1)]); $this->createJobApplicantEducation($job_applicant_id, $qualification_ids['education'][rand(0, count($qualification_ids['education']) - 1)]); $this->createJobApplicantLicense($job_applicant_id, $qualification_ids['license'][rand(0, count($qualification_ids['license']) - 1)]); $this->createJobApplicantLanguage($job_applicant_id, $qualification_ids['language'][rand(0, count($qualification_ids['language']) - 1)]); $this->createJobApplicantMembership($job_applicant_id, $qualification_ids['membership'][rand(0, count($qualification_ids['membership']) - 1)], $currency_ids[0]); $n++; } } $x++; } } //Create recurring schedule templates $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 10, $policy_ids['schedule_1']); //Morning shift $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 20, $policy_ids['schedule_1']); //Afternoon shift $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 30, $policy_ids['schedule_1']); //Evening shift $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 40); //Split Shift $recurring_schedule_ids[] = $this->createRecurringScheduleTemplate($company_id, 50, $policy_ids['schedule_1']); //Full rotation $recurring_schedule_start_date = TTDate::getBeginWeekEpoch($current_epoch + 86400 * 7.5); $this->createRecurringSchedule($company_id, $recurring_schedule_ids[0], $recurring_schedule_start_date, '', array($user_ids[0], $user_ids[1], $user_ids[2], $user_ids[3], $user_ids[4])); $this->createRecurringSchedule($company_id, $recurring_schedule_ids[1], $recurring_schedule_start_date, '', array($user_ids[5], $user_ids[6], $user_ids[7], $user_ids[8], $user_ids[9])); $this->createRecurringSchedule($company_id, $recurring_schedule_ids[2], $recurring_schedule_start_date, '', array($user_ids[10], $user_ids[11], $user_ids[12], $user_ids[13], $user_ids[14])); //Create different schedule shifts. $schedule_options_arr = array(array('status_id' => 10, 'start_time' => '06:00AM', 'end_time' => '03:00PM', 'schedule_policy_id' => $policy_ids['schedule_1']), array('status_id' => 10, 'start_time' => '10:00AM', 'end_time' => '07:00PM', 'schedule_policy_id' => $policy_ids['schedule_1']), array('status_id' => 10, 'start_time' => '2:00PM', 'end_time' => '11:00PM', 'schedule_policy_id' => $policy_ids['schedule_1']), array('status_id' => 10, 'start_time' => '08:00AM', 'end_time' => '05:00PM', 'schedule_policy_id' => $policy_ids['schedule_1'])); //Create schedule for each employee. $x = 0; foreach ($user_ids as $user_id) { //Create schedule starting 6 weeks ago, up to the end of the week. Debug::Text('Creating schedule for User ID: ' . $user_id, __FILE__, __LINE__, __METHOD__, 10); //$schedule_date = ($current_epoch-(86400*42)); $schedule_date = $current_epoch - 86400 * 14; $schedule_end_date = TTDate::getEndWeekEpoch($current_epoch); //$schedule_date = ($current_epoch-(86400*14)); //$schedule_end_date = ($current_epoch+(86400*28)); while ($schedule_date <= $schedule_end_date) { if ($x % 5 == 0) { $schedule_options_key = 3; //Common shift } else { $schedule_options_key = array_rand($schedule_options_arr); } Debug::Text(' Schedule Date: ' . $schedule_date . ' Schedule Options Key: ' . $schedule_options_key, __FILE__, __LINE__, __METHOD__, 10); //Random departments/branches $schedule_options_arr[$schedule_options_key]['branch_id'] = $branch_ids[rand(0, count($branch_ids) - 1)]; $schedule_options_arr[$schedule_options_key]['department_id'] = $department_ids[rand(0, count($department_ids) - 1)]; //Schedule just weekdays for users 1-4, then weekends and not mon/tue for user 5. if ($x % 5 != 0 and date('w', $schedule_date) != 0 and date('w', $schedule_date) != 6 or $x % 5 == 0 and date('w', $schedule_date) != 1 and date('w', $schedule_date) != 2) { $this->createSchedule($company_id, $user_id, $schedule_date, $schedule_options_arr[$schedule_options_key]); } $schedule_date += 86400; } //break; unset($schedule_date, $schedule_end_date, $user_id); $x++; } unset($schedule_options_arr, $schedule_options_key); //Punch users in/out randomly. foreach ($user_ids as $user_id) { //Pick random jobs/tasks that are used for the entire date range. //So one employee isn't punching into 15 jobs. $user_random_job_ids = array_rand($job_ids, 2); $user_random_task_ids = array_rand($job_ids, 3); //Create punches starting 6 weeks ago, up to the end of the week. //$start_date = $punch_date = ($current_epoch-(86400*42)); $start_date = $punch_date = $current_epoch - 86400 * 14; $end_date = TTDate::getEndWeekEpoch($current_epoch); //$start_date = $punch_date = ($current_epoch-(86400*14)); //$end_date = ($current_epoch+(86400*28)); $i = 0; while ($punch_date <= $end_date) { $date_stamp = TTDate::getDate('DATE', $punch_date); //$punch_full_time_stamp = strtotime($pc_data['date_stamp'].' '.$pc_data['time_stamp']); $exception_cutoff_date = $current_epoch - 86400 * 14; if (date('w', $punch_date) != 0 and date('w', $punch_date) != 6) { if ($punch_date >= $exception_cutoff_date and $i % 4 == 0) { $first_punch_in = rand(7, 8) . ':' . str_pad(rand(0, 30), 2, '0', STR_PAD_LEFT) . 'AM'; $last_punch_out = strtotime($date_stamp . ' ' . rand(4, 5) . ':' . str_pad(rand(0, 30), 2, '0', STR_PAD_LEFT) . 'PM'); if ($punch_date >= $exception_cutoff_date and rand(0, 20) == 0) { //Create request $this->createRequest(20, $user_id, $date_stamp); } if ($punch_date >= $exception_cutoff_date and rand(0, 16) == 0) { //Create request $this->createRequest(20, $user_id, $date_stamp); } } else { $first_punch_in = '08:00AM'; if ($punch_date >= $exception_cutoff_date and $i % 10 == 0) { //Don't punch out to generate exception. $last_punch_out = NULL; //Forgot to punch out request $this->createRequest(30, $user_id, $date_stamp); } else { $last_punch_out = strtotime($date_stamp . ' 5:00PM'); } } //Weekdays $this->createPunchPair($user_id, strtotime($date_stamp . ' ' . $first_punch_in), strtotime($date_stamp . ' 11:00AM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => $branch_ids[rand(0, count($branch_ids) - 1)], 'department_id' => $department_ids[rand(0, count($department_ids) - 1)], 'job_id' => $job_ids[array_rand($user_random_job_ids)], 'job_item_id' => $task_ids[array_rand($user_random_task_ids)]), TRUE); $this->createPunchPair($user_id, strtotime($date_stamp . ' 11:00AM'), strtotime($date_stamp . ' 1:00PM'), array('in_type_id' => 10, 'out_type_id' => 20, 'branch_id' => $branch_ids[rand(0, count($branch_ids) - 1)], 'department_id' => $department_ids[rand(0, count($department_ids) - 1)], 'job_id' => $job_ids[array_rand($user_random_job_ids)], 'job_item_id' => $task_ids[array_rand($user_random_task_ids)]), TRUE); //Calc total time on last punch pair only. $this->createPunchPair($user_id, strtotime($date_stamp . ' 2:00PM'), $last_punch_out, array('in_type_id' => 20, 'out_type_id' => 10, 'branch_id' => $branch_ids[rand(0, count($branch_ids) - 1)], 'department_id' => $department_ids[rand(0, count($department_ids) - 1)], 'job_id' => $job_ids[array_rand($user_random_job_ids)], 'job_item_id' => $task_ids[array_rand($user_random_task_ids)]), TRUE); } elseif ($punch_date > $exception_cutoff_date and date('w', $punch_date) == 6 and $i % 10 == 0) { //Sat. $this->createPunchPair($user_id, strtotime($date_stamp . ' 10:00AM'), strtotime($date_stamp . ' 2:30PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => $branch_ids[rand(0, count($branch_ids) - 1)], 'department_id' => $department_ids[rand(0, count($department_ids) - 1)], 'job_id' => $job_ids[array_rand($user_random_job_ids)], 'job_item_id' => $task_ids[array_rand($user_random_task_ids)]), TRUE); } //Recalculate entire day. Performance optimization. //UserDateTotalFactory::reCalculateRange( $user_id, $start_date, $end_date ); $punch_date += 86400; $i++; } unset($punch_options_arr, $punch_date, $user_id); } //Generate pay stubs for each pay period $pplf = TTnew('PayPeriodListFactory'); $pplf->getByCompanyId($company_id); if ($pplf->getRecordCount() > 0) { foreach ($pplf as $pp_obj) { foreach ($user_ids as $user_id) { $cps = new CalculatePayStub(); $cps->setUser($user_id); $cps->setPayPeriod($pp_obj->getId()); $cps->calculate(); } } } unset($pplf, $pp_obj, $user_id); $this->createReportCustomColumn($company_id, 'UserSummaryReport', 10); $this->createReportCustomColumn($company_id, 'UserSummaryReport', 20); $this->createReportCustomColumn($company_id, 'UserSummaryReport', 100); $this->createReportCustomColumn($company_id, 'UserSummaryReport', 200); $this->createReportCustomColumn($company_id, 'UserSummaryReport', 270); $this->createReportCustomColumn($company_id, 'UserSummaryReport', 400); $this->createReportCustomColumn($company_id, 'UserSummaryReport', 405); $this->createReportCustomColumn($company_id, 'TimesheetSummaryReport', 10); $this->createReportCustomColumn($company_id, 'TimesheetSummaryReport', 20); $this->createReportCustomColumn($company_id, 'TimesheetSummaryReport', 200); $this->createReportCustomColumn($company_id, 'TimesheetDetailReport', 10); $this->createReportCustomColumn($company_id, 'TimesheetDetailReport', 20); $this->createReportCustomColumn($company_id, 'TimesheetDetailReport', 200); if (getTTProductEdition() >= TT_PRODUCT_CORPORATE) { // Attach document to employee foreach ($user_ids as $user_id) { $x = 1; while ($x <= rand(2, 4)) { $type = $x * 10; $document_id = $this->createDocument($company_id, 100, $type); $rand_arr = array(1, 2, 3, 4, 5, 6); $rand_ids = array_rand($rand_arr, rand(2, 5)); foreach ($rand_ids as $rand_id) { $document_revision_id = $this->createDocumentRevision($document_id, $rand_arr[$rand_id] * 10); $this->createDocumentFilesByObjectType($company_id, 100, $type, $document_revision_id, $document_id); } $this->createDocumentAttachment($document_id, 100, $user_id); $x++; } } // Attach document to Jobs foreach ($job_ids as $job_id) { $x = 1; while ($x <= rand(2, 3)) { $type = $x * 10; $document_id = $this->createDocument($company_id, 60, $type); $rand_arr = array(1, 2, 3, 4, 5, 6); $rand_ids = array_rand($rand_arr, rand(2, 5)); foreach ($rand_ids as $rand_id) { $document_revision_id = $this->createDocumentRevision($document_id, $rand_arr[$rand_id] * 10); $this->createDocumentFilesByObjectType($company_id, 60, $type, $document_revision_id, $document_id); } $this->createDocumentAttachment($document_id, 60, $job_id); $x++; } } // Attach document to clients foreach ($client_ids as $client_id) { $x = 1; while ($x <= rand(2, 4)) { $type = $x * 10; $document_id = $this->createDocument($company_id, 80, $type); $rand_arr = array(1, 2, 3, 4, 5, 6); $rand_ids = array_rand($rand_arr, rand(2, 5)); foreach ($rand_ids as $rand_id) { $document_revision_id = $this->createDocumentRevision($document_id, $rand_arr[$rand_id] * 10); $this->createDocumentFilesByObjectType($company_id, 80, $type, $document_revision_id, $document_id); } $this->createDocumentAttachment($document_id, 80, $client_id); $x++; } } // Attach document to client contacts foreach ($client_contact_ids as $client_contact_id) { $x = 1; while ($x <= 2) { $type = $x * 10; $document_id = $this->createDocument($company_id, 85, $type); $rand_arr = array(1, 2, 3, 4, 5, 6); $rand_ids = array_rand($rand_arr, rand(2, 5)); foreach ($rand_ids as $rand_id) { $document_revision_id = $this->createDocumentRevision($document_id, $rand_arr[$rand_id] * 10); $this->createDocumentFilesByObjectType($company_id, 85, $type, $document_revision_id, $document_id); } $this->createDocumentAttachment($document_id, 85, $client_contact_id); $x++; } } } } //$cf->FailTransaction(); $cf->CommitTransaction(); return FALSE; }
} } default: if ($permission->Check('schedule', 'view')) { Debug::text('Viewing all users schedule', __FILE__, __LINE__, __METHOD__, 10); if ($filter_user_id != '') { $user_id = $filter_user_id; } else { $user_id = $current_user->getId(); } } else { $user_id = $current_user->getId(); } if ($filter_start_date == '' or $filter_end_date == '') { $start_date = $filter_start_date = TTDate::getBeginWeekEpoch(TTDate::getTime() - 86400, $current_user_prefs->getStartWeekDay()); $end_date = $filter_end_date = TTDate::getEndWeekEpoch(TTDate::getTime() + 86400 * 28, $current_user_prefs->getStartWeekDay()); } //$start_date = $filter_start_date = TTDate::getBeginWeekEpoch( $start_date, 'mon'); //$end_date = $filter_end_date = TTDate::getEndWeekEpoch( $end_date, 'mon' ); Debug::text(' Start Date: ' . TTDate::getDate('DATE+TIME', $start_date) . ' End Date: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10); $sf = TTnew('ScheduleFactory'); $default_schedule_shifts = $sf->getScheduleArray($user_id, $start_date, $end_date); //var_dump($default_schedule_shifts); $calendar_array = TTDate::getCalendarArray($start_date, $end_date, $current_user_prefs->getStartWeekDay()); $smarty->assign_by_ref('calendar_array', $calendar_array); //$smarty->assign_by_ref('pay_period_locked_rows', $pay_period_locked_rows); $ulf = TTnew('UserListFactory'); $user_obj = $ulf->getById($user_id)->getCurrent(); /* $holiday = new Holiday(); $holiday->GetByCountryAndProvince($user_obj->getCountry(), $user_obj->getProvince() );
function getCalendarArray($start_date, $end_date, $start_day_of_week = 0, $force_weeks = TRUE) { if ($start_date == '' or $end_date == '') { return FALSE; } //Which day begins the week, Mon or Sun? //0 = Sun 1 = Mon /* if ( strtolower($start_day_of_week) == 'mon' OR $start_day_of_week == 1) { $start_day_of_week = 1; } else { $start_day_of_week = 0; } */ Debug::text(' Start Day Of Week: ' . $start_day_of_week, __FILE__, __LINE__, __METHOD__, 10); Debug::text(' Raw Start Date: ' . TTDate::getDate('DATE+TIME', $start_date) . ' Raw End Date: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10); if ($force_weeks == TRUE) { $cal_start_date = TTDate::getBeginWeekEpoch($start_date, $start_day_of_week); //$cal_end_date = TTDate::getEndWeekEpoch($end_date, $start_day_of_week); $cal_end_date = TTDate::getEndWeekEpoch($end_date, $start_day_of_week); } else { $cal_start_date = $start_date; $cal_end_date = $end_date; } Debug::text(' Cal Start Date: ' . TTDate::getDate('DATE+TIME', $cal_start_date) . ' Cal End Date: ' . TTDate::getDate('DATE+TIME', $cal_end_date), __FILE__, __LINE__, __METHOD__, 10); $prev_month = NULL; //$prev_week=NULL; $x = 0; //Gotta add more then 86400 because of day light savings time. //Causes infinite loop without it. //Don't add 7200 to Cal End Date because that could cause more then one //week to be displayed. //for($i=$cal_start_date; $i <= $cal_end_date; $i+=86400) { //for($i=$cal_start_date; $i <= ($cal_end_date+7200); $i+=93600) { for ($i = $cal_start_date; $i <= $cal_end_date; $i += 93600) { if ($x > 200) { break; } $i = TTDate::getBeginDayEpoch($i); $current_month = date('n', $i); //$current_week = date('W', $i); $current_day_of_week = date('w', $i); if ($current_month != $prev_month and $i >= $start_date) { $isNewMonth = TRUE; } else { $isNewMonth = FALSE; } //if ( $current_week != $prev_week ) { if ($current_day_of_week == $start_day_of_week) { $isNewWeek = TRUE; } else { $isNewWeek = FALSE; } //Display only blank boxes if the date is before the filter start date, or after. if ($i >= $start_date and $i <= $end_date) { $day_of_week = TTi18n::gettext(date('D', $i)); // i18n: these short day strings may not be in .po file. $day_of_month = date('j', $i); $month_name = TTi18n::gettext(date('F', $i)); // i18n: these short month strings may not be defined in .po file. } else { //Always have the day of the week at least. //$day_of_week = TTi18n::gettext( date('D', $i) ); // i18n: these short day strings may not be in .po file. $day_of_week = NULL; $day_of_month = NULL; $month_name = NULL; } $retarr[] = array('epoch' => $i, 'date_stamp' => TTDate::getISODateStamp($i), 'start_day_of_week' => $start_day_of_week, 'day_of_week' => $day_of_week, 'day_of_month' => $day_of_month, 'month_name' => $month_name, 'month_short_name' => substr($month_name, 0, 3), 'month' => $current_month, 'isNewMonth' => $isNewMonth, 'isNewWeek' => $isNewWeek); $prev_month = $current_month; //$prev_week = $current_week; //Debug::text('i: '. $i .' Date: '. TTDate::getDate('DATE+TIME', $i), __FILE__, __LINE__, __METHOD__,10); $x++; } return $retarr; }
static function smartReCalculate($user_id, $user_date_ids, $enable_exception = TRUE, $enable_premature_exceptions = FALSE, $enable_future_exceptions = TRUE) { if ($user_id == '') { return FALSE; } //Debug::Arr($user_date_ids, 'aUser Date IDs: ', __FILE__, __LINE__, __METHOD__, 10); if (!is_array($user_date_ids) and is_numeric($user_date_ids) and $user_date_ids > 0) { $user_date_ids = array($user_date_ids); } if (!is_array($user_date_ids)) { Debug::Text('Returning FALSE... User Date IDs not an array...', __FILE__, __LINE__, __METHOD__, 10); return FALSE; } $user_date_ids = array_unique($user_date_ids); //Debug::Arr($user_date_ids, 'bUser Date IDs: ', __FILE__, __LINE__, __METHOD__, 10); $start_week_day_id = 0; $ppslf = TTnew('PayPeriodScheduleListFactory'); $ppslf->getByUserId($user_id); if ($ppslf->getRecordCount() == 1) { $pps_obj = $ppslf->getCurrent(); $start_week_day_id = $pps_obj->getStartWeekDay(); } Debug::text('Start Week Day ID: ' . $start_week_day_id, __FILE__, __LINE__, __METHOD__, 10); //Get date stamps for all user_date_ids. $udlf = TTnew('UserDateListFactory'); $udlf->getByIds($user_date_ids, NULL, array('date_stamp' => 'asc')); //Order by date asc if ($udlf->getRecordCount() > 0) { //Order them, and get the one or more sets of date ranges that need to be recalculated. //Need to consider re-calculating multiple weeks at once. $i = 0; foreach ($udlf as $ud_obj) { $start_week_epoch = TTDate::getBeginWeekEpoch($ud_obj->getDateStamp(), $start_week_day_id); $end_week_epoch = TTDate::getEndWeekEpoch($ud_obj->getDateStamp(), $start_week_day_id); Debug::text('Current Date: ' . TTDate::getDate('DATE', $ud_obj->getDateStamp()) . ' Start Week: ' . TTDate::getDate('DATE', $start_week_epoch) . ' End Week: ' . TTDate::getDate('DATE', $end_week_epoch), __FILE__, __LINE__, __METHOD__, 10); if ($i == 0) { $range_arr[$start_week_epoch] = array('start_date' => $ud_obj->getDateStamp(), 'end_date' => $end_week_epoch); } else { //Loop through each range extending it if needed. foreach ($range_arr as $tmp_start_week_epoch => $tmp_range) { if ($ud_obj->getDateStamp() >= $tmp_range['start_date'] and $ud_obj->getDateStamp() <= $tmp_range['end_date']) { //Date falls within already existing range continue; } elseif ($ud_obj->getDateStamp() < $tmp_range['start_date'] and $ud_obj->getDateStamp() >= $tmp_start_week_epoch) { //Date falls within the same week, but before the current start date. $range_arr[$tmp_start_week_epoch]['start_date'] = $ud_obj->getDateStamp(); Debug::text('Pushing Start Date back...', __FILE__, __LINE__, __METHOD__, 10); } else { //Outside current range. Check to make sure it isn't within another range. if (isset($range_arr[$start_week_epoch])) { //Within another existing week, check to see if we need to extend it. if ($ud_obj->getDateStamp() < $range_arr[$start_week_epoch]['start_date']) { Debug::text('bPushing Start Date back...', __FILE__, __LINE__, __METHOD__, 10); $range_arr[$start_week_epoch]['start_date'] = $ud_obj->getDateStamp(); } } else { //Not within another existing week Debug::text('Adding new range...', __FILE__, __LINE__, __METHOD__, 10); $range_arr[$start_week_epoch] = array('start_date' => $ud_obj->getDateStamp(), 'end_date' => $end_week_epoch); } } } unset($tmp_range, $tmp_start_week_epoch); } $i++; } unset($start_week_epoch, $end_week_epoch, $udlf, $ud_obj); if (is_array($range_arr)) { ksort($range_arr); //Sort range by start week, so recalculating goes in date order. //Debug::Arr($range_arr, 'Range Array: ', __FILE__, __LINE__, __METHOD__, 10); foreach ($range_arr as $week_range) { $udlf = TTnew('UserDateListFactory'); $udlf->getByUserIdAndStartDateAndEndDate($user_id, $week_range['start_date'], $week_range['end_date']); if ($udlf->getRecordCount() > 0) { Debug::text('Found days to re-calculate: ' . $udlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); $udlf->StartTransaction(); $z = 1; $z_max = $udlf->getRecordCount(); foreach ($udlf as $ud_obj) { //We only need to re-calculate exceptions on the exact days specified by user_date_ids. //This was the case before we Over Weekly Time/Over Scheduled Weekly Time exceptions, //Now we have to enable calculating exceptions for the entire week. Debug::text('Re-calculating day with exceptions: ' . $ud_obj->getId(), __FILE__, __LINE__, __METHOD__, 10); if ($z == $z_max) { //Enable recalculating holidays at the end of each week. UserDateTotalFactory::reCalculateDay($ud_obj->getId(), $enable_exception, $enable_premature_exceptions, $enable_future_exceptions, TRUE); } else { UserDateTotalFactory::reCalculateDay($ud_obj->getId(), $enable_exception, $enable_premature_exceptions, $enable_future_exceptions); } $z++; } $udlf->CommitTransaction(); } } //Use the last date to base the future week calculation on. Make sure we don't unset $week_range['end_date'] //When BiWeekly overtime policies are calculated, it sets getEnableCalcFutureWeek() to TRUE. if (isset($week_range['end_date']) and UserDateTotalFactory::getEnableCalcFutureWeek() == TRUE) { $future_week_date = $week_range['end_date'] + 86400 * 7; Debug::text('Found Biweekly overtime policy, calculate one week into the future: ' . TTDate::getDate('DATE', $future_week_date), __FILE__, __LINE__, __METHOD__, 10); UserDateTotalFactory::reCalculateRange($user_id, TTDate::getBeginWeekEpoch($future_week_date, $start_week_day_id), TTDate::getEndWeekEpoch($future_week_date, $start_week_day_id)); UserDateTotalFactory::setEnableCalcFutureWeek(FALSE); //Return to FALSE so future weeks aren't calculate for other users. unset($future_week_date); } return TRUE; } } Debug::text('Returning FALSE!', __FILE__, __LINE__, __METHOD__, 10); return FALSE; }
public static function getTimePeriodDates($time_period, $epoch = NULL, $user_obj = NULL, $params = NULL) { $time_period = Misc::trimSortPrefix($time_period); if ($epoch == NULL or $epoch == '' or !is_numeric($epoch)) { $epoch = self::getTime(); } $start_week_day = 0; if (is_object($user_obj)) { $user_prefs = $user_obj->getUserPreferenceObject(); if (is_object($user_prefs)) { $start_week_day = $user_prefs->getStartWeekDay(); } } switch ($time_period) { case 'custom_date': //Params must pass start_date/end_date if (isset($params['start_date'])) { $start_date = TTDate::getBeginDayEpoch($params['start_date']); } if (isset($params['end_date'])) { $end_date = TTDate::getEndDayEpoch($params['end_date']); } break; case 'custom_time': //Params must pass start_date/end_date if (isset($params['start_date'])) { $start_date = $params['start_date']; } if (isset($params['end_date'])) { $end_date = $params['end_date']; } break; case 'custom_pay_period': //Params must pass pay_period_ids if (isset($params['pay_period_id'])) { $pay_period_ids = (array) $params['pay_period_id']; } break; case 'today': $start_date = TTDate::getBeginDayEpoch($epoch); $end_date = TTDate::getEndDayEpoch($epoch); break; case 'yesterday': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); break; case 'last_24_hours': $start_date = $epoch - 86400; $end_date = $epoch; break; case 'last_48_hours': $start_date = $epoch - 86400 * 2; $end_date = $epoch; break; case 'last_72_hours': $start_date = $epoch - 86400 * 3; $end_date = $epoch; break; case 'this_week': $start_date = TTDate::getBeginWeekEpoch($epoch, $start_week_day); $end_date = TTDate::getEndWeekEpoch($epoch, $start_week_day); break; case 'last_week': $start_date = TTDate::getBeginWeekEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 7, $start_week_day); $end_date = TTDate::getEndWeekEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 7, $start_week_day); break; case 'last_2_weeks': $start_date = TTDate::getBeginWeekEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 14, $start_week_day); $end_date = TTDate::getEndWeekEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 7, $start_week_day); break; case 'last_7_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 7); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); break; case 'last_14_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 14); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); break; //Params must be passed if more than one pay period schedule exists. //Params must be passed if more than one pay period schedule exists. case 'no_pay_period': case 'this_pay_period': case 'last_pay_period': Debug::text('Time Period for Pay Period Schedule selected...', __FILE__, __LINE__, __METHOD__, 10); //Make sure user_obj is set. if (!is_object($user_obj)) { Debug::text('User Object was not passsed...', __FILE__, __LINE__, __METHOD__, 10); break; } if (!isset($params['pay_period_schedule_id'])) { $params['pay_period_schedule_id'] = NULL; } $pay_period_ids = array(); //Since we allow multiple pay_period schedules to be selected, we have to return pay_period_ids, not start/end dates. if ($time_period == 'this_pay_period') { Debug::text('this_pay_period', __FILE__, __LINE__, __METHOD__, 10); $pplf = TTnew('PayPeriodListFactory'); $pplf->getThisPayPeriodByCompanyIdAndPayPeriodScheduleIdAndDate($user_obj->getCompany(), $params['pay_period_schedule_id'], time()); if ($pplf->getRecordCount() > 0) { foreach ($pplf as $pp_obj) { $pay_period_ids[] = $pp_obj->getId(); } } } elseif ($time_period == 'last_pay_period') { Debug::text('last_pay_period', __FILE__, __LINE__, __METHOD__, 10); $pplf = TTnew('PayPeriodListFactory'); $pplf->getLastPayPeriodByCompanyIdAndPayPeriodScheduleIdAndDate($user_obj->getCompany(), $params['pay_period_schedule_id'], time()); if ($pplf->getRecordCount() > 0) { foreach ($pplf as $pp_obj) { $pay_period_ids[] = $pp_obj->getId(); } } } else { Debug::text('no_pay_period', __FILE__, __LINE__, __METHOD__, 10); } Debug::Arr($pay_period_ids, 'Pay Period IDs: ', __FILE__, __LINE__, __METHOD__, 10); if (count($pay_period_ids) == 0) { unset($pay_period_ids); } break; case 'this_month': $start_date = TTDate::getBeginMonthEpoch($epoch); $end_date = TTDate::getEndMonthEpoch($epoch); break; case 'last_month': $start_date = TTDate::getBeginMonthEpoch(TTDate::getBeginMonthEpoch($epoch) - 86400); $end_date = TTDate::getEndMonthEpoch(TTDate::getBeginMonthEpoch($epoch) - 86400); break; case 'last_2_months': $start_date = TTDate::getBeginMonthEpoch(TTDate::getBeginMonthEpoch($epoch) - 86400 * 32); $end_date = TTDate::getEndMonthEpoch(TTDate::getBeginMonthEpoch($epoch) - 86400); break; case 'last_30_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 30); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); break; case 'last_45_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 45); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); break; case 'last_60_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 60); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); break; case 'this_quarter': $quarter = TTDate::getYearQuarter($epoch); $quarter_dates = TTDate::getYearQuarters($epoch, $quarter); //Debug::Arr($quarter_dates, 'Quarter Dates: Quarter: '. $quarter, __FILE__, __LINE__, __METHOD__,10); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'last_quarter': $quarter = TTDate::getYearQuarter($epoch) - 1; if ($quarter == 0) { $quarter = 4; $epoch = TTDate::getBeginYearEpoch() - 86400; //Need to jump back into the previous year. } $quarter_dates = TTDate::getYearQuarters($epoch, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'last_90_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 90); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); break; case 'this_year_1st_quarter': $quarter = 1; $quarter_dates = TTDate::getYearQuarters($epoch, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'this_year_2nd_quarter': $quarter = 2; $quarter_dates = TTDate::getYearQuarters($epoch, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'this_year_3rd_quarter': $quarter = 3; $quarter_dates = TTDate::getYearQuarters($epoch, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'this_year_4th_quarter': $quarter = 4; $quarter_dates = TTDate::getYearQuarters($epoch, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'last_year_1st_quarter': $quarter = 1; $quarter_dates = TTDate::getYearQuarters(TTDate::getBeginYearEpoch($epoch) - 86400, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'last_year_2nd_quarter': $quarter = 2; $quarter_dates = TTDate::getYearQuarters(TTDate::getBeginYearEpoch($epoch) - 86400, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'last_year_3rd_quarter': $quarter = 3; $quarter_dates = TTDate::getYearQuarters(TTDate::getBeginYearEpoch($epoch) - 86400, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'last_year_4th_quarter': $quarter = 4; $quarter_dates = TTDate::getYearQuarters(TTDate::getBeginYearEpoch($epoch) - 86400, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'last_3_months': $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); $start_date = mktime(0, 0, 0, TTDate::getMonth($end_date) - 3, TTDate::getDayOfMonth($end_date), TTDate::getYear($end_date)); break; case 'last_6_months': $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); $start_date = mktime(0, 0, 0, TTDate::getMonth($end_date) - 6, TTDate::getDayOfMonth($end_date), TTDate::getYear($end_date)); break; case 'last_9_months': $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); $start_date = mktime(0, 0, 0, TTDate::getMonth($end_date) - 9, TTDate::getDayOfMonth($end_date), TTDate::getYear($end_date)); break; case 'last_12_months': $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); $start_date = mktime(0, 0, 0, TTDate::getMonth($end_date), TTDate::getDayOfMonth($end_date), TTDate::getYear($end_date) - 1); break; case 'last_18_months': $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); $start_date = mktime(0, 0, 0, TTDate::getMonth($end_date) - 18, TTDate::getDayOfMonth($end_date), TTDate::getYear($end_date)); break; case 'last_24_months': $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400); $start_date = mktime(0, 0, 0, TTDate::getMonth($end_date) - 24, TTDate::getDayOfMonth($end_date), TTDate::getYear($end_date)); break; case 'this_year': $start_date = TTDate::getBeginYearEpoch($epoch); $end_date = TTDate::getEndYearEpoch($epoch); break; case 'last_year': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch($epoch) - 86400); $end_date = TTDate::getEndYearEpoch(TTDate::getBeginYearEpoch($epoch) - 86400); break; case 'last_2_years': $end_date = TTDate::getEndYearEpoch(TTDate::getBeginYearEpoch($epoch) - 86400); $start_date = mktime(0, 0, 0, TTDate::getMonth($end_date), TTDate::getDayOfMonth($end_date), TTDate::getYear($end_date) - 2); break; case 'last_3_years': $end_date = TTDate::getEndYearEpoch(TTDate::getBeginYearEpoch($epoch) - 86400); $start_date = mktime(0, 0, 0, TTDate::getMonth($end_date), TTDate::getDayOfMonth($end_date), TTDate::getYear($end_date) - 3); break; case 'last_5_years': $end_date = TTDate::getEndYearEpoch(TTDate::getBeginYearEpoch($epoch) - 86400); $start_date = mktime(0, 0, 0, TTDate::getMonth($end_date), TTDate::getDayOfMonth($end_date), TTDate::getYear($end_date) - 5); break; case 'to_yesterday': //"Up To" means we need to use the end time of the day we go up to. $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400) - 1; break; case 'to_today': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch)) - 1; break; case 'to_this_week': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginWeekEpoch($epoch, $start_week_day) - 1; break; case 'to_last_week': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginWeekEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 7, $start_week_day) - 1; break; case 'to_7_days': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 7) - 1; break; case 'to_14_days': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 14) - 1; break; case 'to_last_pay_period': case 'to_this_pay_period': Debug::text('Time Period for Pay Period Schedule selected...', __FILE__, __LINE__, __METHOD__, 10); //Make sure user_obj is set. if (!is_object($user_obj)) { Debug::text('User Object was not passsed...', __FILE__, __LINE__, __METHOD__, 10); break; } if (!isset($params['pay_period_schedule_id'])) { $params['pay_period_schedule_id'] = NULL; } $end_date = FALSE; //Since we allow multiple pay_period schedules to be selected, we have to return pay_period_ids, not start/end dates. if ($time_period == 'to_this_pay_period') { Debug::text('to_this_pay_period', __FILE__, __LINE__, __METHOD__, 10); $pplf = TTnew('PayPeriodListFactory'); $pplf->getThisPayPeriodByCompanyIdAndPayPeriodScheduleIdAndDate($user_obj->getCompany(), $params['pay_period_schedule_id'], time()); if ($pplf->getRecordCount() > 0) { foreach ($pplf as $pp_obj) { if ($end_date == FALSE or $pp_obj->getStartDate() < $end_date) { $end_date = $pp_obj->getStartDate(); } } } } elseif ($time_period == 'to_last_pay_period') { Debug::text('to_last_pay_period', __FILE__, __LINE__, __METHOD__, 10); $pplf = TTnew('PayPeriodListFactory'); $pplf->getLastPayPeriodByCompanyIdAndPayPeriodScheduleIdAndDate($user_obj->getCompany(), $params['pay_period_schedule_id'], time()); if ($pplf->getRecordCount() > 0) { foreach ($pplf as $pp_obj) { if ($end_date == FALSE or $pp_obj->getStartDate() < $end_date) { $end_date = $pp_obj->getStartDate(); } } } } $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = $end_date - 1; break; case 'to_last_month': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginMonthEpoch(TTDate::getBeginMonthEpoch($epoch) - 86400) - 1; break; case 'to_this_month': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginMonthEpoch($epoch) - 1; break; case 'to_30_days': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 30) - 1; break; case 'to_45_days': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 45) - 1; break; case 'to_60_days': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 60) - 1; break; case 'to_last_quarter': $quarter = TTDate::getYearQuarter($epoch) - 1; if ($quarter == 0) { $quarter = 4; $epoch = TTDate::getBeginYearEpoch() - 86400; //Need to jump back into the previous year. } $quarter_dates = TTDate::getYearQuarters($epoch, $quarter); $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = $quarter_dates['start'] - 1; break; case 'to_this_quarter': $quarter = TTDate::getYearQuarter($epoch); $quarter_dates = TTDate::getYearQuarters($epoch, $quarter); $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = $quarter_dates['start'] - 1; break; case 'to_90_days': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) - 86400 * 90) - 1; break; case 'to_this_year': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginYearEpoch($epoch) - 1; break; case 'to_last_year': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch($epoch) - 86400) - 1; break; case 'tomorrow': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); break; case 'next_24_hours': $start_date = $epoch; $end_date = $epoch + 86400; break; case 'next_48_hours': $start_date = $epoch; $end_date = $epoch + 86400 * 2; break; case 'next_72_hours': $start_date = $epoch; $end_date = $epoch + 86400 * 3; break; case 'next_week': $start_date = TTDate::getBeginWeekEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 7, $start_week_day); $end_date = TTDate::getEndWeekEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 7, $start_week_day); break; case 'next_2_weeks': $start_date = TTDate::getBeginWeekEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 7, $start_week_day); $end_date = TTDate::getEndWeekEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 14, $start_week_day); break; case 'next_7_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 7); break; case 'next_14_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 14); break; case 'next_month': $start_date = TTDate::getBeginMonthEpoch(TTDate::getEndMonthEpoch($epoch) + 86400); $end_date = TTDate::getEndMonthEpoch(TTDate::getEndMonthEpoch($epoch) + 86400); break; case 'next_2_months': $start_date = TTDate::getBeginMonthEpoch(TTDate::getEndMonthEpoch($epoch) + 86400); $end_date = TTDate::getEndMonthEpoch(TTDate::getEndMonthEpoch($epoch) + 86400 * 32); break; case 'next_30_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 30); break; case 'next_45_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 45); break; case 'next_60_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 60); break; case 'next_quarter': $quarter = TTDate::getYearQuarter($epoch) + 1; if ($quarter == 5) { $quarter = 1; $epoch = TTDate::getEndYearEpoch() + 86400; //Need to jump back into the previous year. } $quarter_dates = TTDate::getYearQuarters($epoch, $quarter); $start_date = $quarter_dates['start']; $end_date = $quarter_dates['end']; break; case 'next_90_days': $start_date = TTDate::getBeginDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400 * 90); break; case 'next_3_months': $start_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = mktime(0, 0, 0, TTDate::getMonth($start_date) + 3, TTDate::getDayOfMonth($start_date), TTDate::getYear($start_date)); break; case 'next_6_months': $start_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = mktime(0, 0, 0, TTDate::getMonth($start_date) + 6, TTDate::getDayOfMonth($start_date), TTDate::getYear($start_date)); break; case 'next_9_months': $start_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = mktime(0, 0, 0, TTDate::getMonth($start_date) + 9, TTDate::getDayOfMonth($start_date), TTDate::getYear($start_date)); break; case 'next_12_months': $start_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = mktime(0, 0, 0, TTDate::getMonth($start_date) + 12, TTDate::getDayOfMonth($start_date), TTDate::getYear($start_date)); break; case 'next_18_months': $start_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = mktime(0, 0, 0, TTDate::getMonth($start_date) + 18, TTDate::getDayOfMonth($start_date), TTDate::getYear($start_date)); break; case 'next_24_months': $start_date = TTDate::getEndDayEpoch(TTDate::getMiddleDayEpoch($epoch) + 86400); $end_date = mktime(0, 0, 0, TTDate::getMonth($start_date) + 24, TTDate::getDayOfMonth($start_date), TTDate::getYear($start_date)); break; case 'next_year': $start_date = TTDate::getBeginYearEpoch(TTDate::getEndYearEpoch($epoch) + 86400); $end_date = TTDate::getEndYearEpoch(TTDate::getEndYearEpoch($epoch) + 86400); break; case 'next_2_years': $start_date = TTDate::getEndYearEpoch(TTDate::getEndYearEpoch($epoch) + 86400); $end_date = mktime(0, 0, 0, TTDate::getMonth($start_date), TTDate::getDayOfMonth($start_date), TTDate::getYear($start_date) + 2); break; case 'next_3_years': $start_date = TTDate::getEndYearEpoch(TTDate::getEndYearEpoch($epoch) + 86400); $end_date = mktime(0, 0, 0, TTDate::getMonth($start_date), TTDate::getDayOfMonth($start_date), TTDate::getYear($start_date) + 3); break; case 'next_5_years': $start_date = TTDate::getEndYearEpoch(TTDate::getEndYearEpoch($epoch) + 86400); $end_date = mktime(0, 0, 0, TTDate::getMonth($start_date), TTDate::getDayOfMonth($start_date), TTDate::getYear($start_date) + 5); break; case 'all_years': $start_date = TTDate::getBeginYearEpoch(TTDate::getBeginYearEpoch(31564800) - 86400); $end_date = TTDate::getEndYearEpoch(time() + 86400 * (365 * 2)); break; default: break; } if (isset($start_date) and isset($end_date)) { //Debug::text('Period: '. $time_period .' Start: '. TTDate::getDate('DATE+TIME', $start_date ) .'('.$start_date.') End: '. TTDate::getDate('DATE+TIME', $end_date ) .'('.$end_date.')', __FILE__, __LINE__, __METHOD__,10); return array('start_date' => $start_date, 'end_date' => $end_date); } elseif (isset($pay_period_ids)) { //Debug::text('Period: '. $time_period .' returning just pay_period_ids...', __FILE__, __LINE__, __METHOD__,10); return array('pay_period_id' => $pay_period_ids); } return FALSE; }
static function calcExceptions($user_date_id, $enable_premature_exceptions = FALSE, $enable_future_exceptions = TRUE) { global $profiler; $profiler->startTimer("ExceptionPolicy::calcExceptions()"); if ($user_date_id == '') { return FALSE; } Debug::text(' User Date ID: ' . $user_date_id . ' PreMature: ' . (int) $enable_premature_exceptions, __FILE__, __LINE__, __METHOD__, 10); $current_epoch = TTDate::getTime(); //Get user date info $udlf = TTnew('UserDateListFactory'); $udlf->getById($user_date_id); if ($udlf->getRecordCount() > 0) { $user_date_obj = $udlf->getCurrent(); if ($enable_future_exceptions == FALSE and $user_date_obj->getDateStamp() > TTDate::getEndDayEpoch($current_epoch)) { return FALSE; } } else { return FALSE; } //16hrs... If punches are older then this time, its no longer premature. //This should actually be the PayPeriod Schedule maximum shift time. if (is_object($user_date_obj->getPayPeriodObject()) and is_object($user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject())) { self::$premature_delay = $user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject()->getMaximumShiftTime(); Debug::text(' Setting preMature Exception delay to maximum shift time: ' . self::$premature_delay, __FILE__, __LINE__, __METHOD__, 10); } else { self::$premature_delay = 57600; } //Get list of existing exceptions, so we can determine if we need to delete any. We can't delete them all blindly and re-create them //as this will send duplicate email notifications for every single punch. $existing_exceptions = array(); $elf = TTnew('ExceptionListFactory'); $elf->getByUserDateID($user_date_id); if ($elf->getRecordCount() > 0) { foreach ($elf as $e_obj) { $existing_exceptions[] = array('id' => $e_obj->getId(), 'user_date_id' => $e_obj->getUserDateID(), 'exception_policy_id' => $e_obj->getExceptionPolicyID(), 'type_id' => $e_obj->getType(), 'punch_id' => $e_obj->getPunchID(), 'punch_control_id' => $e_obj->getPunchControlID()); } } unset($elf, $e_obj); //Get all Punches on this date for this user. $plf = TTnew('PunchListFactory'); $plf->getByUserDateId($user_date_id); if ($plf->getRecordCount() > 0) { Debug::text(' Found Punches: ' . $plf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); } $slf = TTnew('ScheduleListFactory'); $slf->getByUserDateIdAndStatusId($user_date_id, 10); if ($slf->getRecordCount() > 0) { Debug::text(' Found Schedule: ' . $slf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); } $schedule_id_cache = NULL; //Cache schedule IDs so we don't need to do a lookup for every exception. $current_exceptions = array(); //Array holding current exception data. //Get all active exceptions. $eplf = TTnew('ExceptionPolicyListFactory'); $eplf->getByPolicyGroupUserIdAndActive($user_date_obj->getUser(), TRUE); if ($eplf->getRecordCount() > 0) { Debug::text(' Found Active Exceptions: ' . $eplf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); foreach ($eplf as $ep_obj) { //Debug::text(' Found Exception Type: '. $ep_obj->getType() .' ID: '. $ep_obj->getID() .' Control ID: '. $ep_obj->getExceptionPolicyControl(), __FILE__, __LINE__, __METHOD__,10); if ($enable_premature_exceptions == TRUE and self::isPreMature($ep_obj->getType()) == TRUE) { //Debug::text(' Premature Exception: '. $ep_obj->getType() , __FILE__, __LINE__, __METHOD__,10); $type_id = 5; //Pre-Mature } else { //Debug::text(' NOT Premature Exception: '. $ep_obj->getType() , __FILE__, __LINE__, __METHOD__,10); $type_id = 50; //Active } switch (strtolower($ep_obj->getType())) { case 's1': //Unscheduled Absence... Anytime they are scheduled and have not punched in. //Ignore these exceptions if the schedule is after today (not including today), //so if a supervisors schedules an employee two days in advance they don't get a unscheduled //absence appearing right away. //Since we now trigger In Late/Out Late exceptions immediately after schedule time, only trigger this exception after //the schedule end time has passed. //**We also need to handle shifts that start at 11:00PM on one day, end at 8:00AM the next day, and they are assigned to the day where //the most time is worked (ie: the next day). //Handle split shifts too... //- This has a side affect that if the schedule policy start/stop time is set to 0, it will trigger both a UnScheduled Absence // and a Not Scheduled exception for the same schedule/punch. //Loop through all schedules, then find punches to match. if ($slf->getRecordCount() > 0) { foreach ($slf as $s_obj) { if ($s_obj->getStatus() == 10 and $current_epoch >= $s_obj->getEndTime()) { $add_exception = TRUE; //Debug::text(' Found Schedule: Start Time: '. TTDate::getDate('DATE+TIME', $s_obj->getStartTime() ), __FILE__, __LINE__, __METHOD__,10); //Find punches that fall within this schedule time including start/stop window. if (TTDate::doesRangeSpanMidnight($s_obj->getStartTime(), $s_obj->getEndTime()) and is_object($user_date_obj) and is_object($user_date_obj->getPayPeriodObject()) and is_object($user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject())) { //Get punches from both days. $plf_tmp = TTnew('PunchListFactory'); $plf_tmp->getShiftPunchesByUserIDAndEpoch($user_date_obj->getUser(), $s_obj->getStartTime(), 0, $user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject()->getMaximumShiftTime()); Debug::text(' Schedule spans midnight... Found rows from expanded search: ' . $plf_tmp->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); if ($plf_tmp->getRecordCount() > 0) { foreach ($plf_tmp as $p_obj_tmp) { if ($s_obj->inSchedule($p_obj_tmp->getTimeStamp())) { Debug::text(' aFound punch for schedule...', __FILE__, __LINE__, __METHOD__, 10); $add_exception = FALSE; break; } } } unset($plf_tmp, $p_obj_tmp); } else { //Get punches from just this day. foreach ($plf as $p_obj) { if ($s_obj->inSchedule($p_obj->getTimeStamp())) { //Debug::text(' bFound punch for schedule...', __FILE__, __LINE__, __METHOD__,10); $add_exception = FALSE; break; } } } if ($add_exception == TRUE) { //Debug::text(' Adding S1 exception...', __FILE__, __LINE__, __METHOD__,10); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => FALSE, 'schedule_obj' => $s_obj); } } } } unset($s_obj, $add_exception); break; case 's2': //Not Scheduled //**We also need to handle shifts that start at 11:00PM on one day, end at 8:00AM the next day, and they are assigned to the day where //the most time is worked (ie: the next day). //Handle split shifts too... if ($plf->getRecordCount() > 1) { //Make sure at least two punche exist. //Loop through each punch, find out if they are scheduled, and if they are in early $prev_punch_time_stamp = FALSE; foreach ($plf as $p_obj) { //Ignore punches that have the exact same timestamp, as they are likely transfer punches. if ($prev_punch_time_stamp != $p_obj->getTimeStamp() and $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()); } //Check if no schedule exists, or an absent schedule exists. If they work when not scheduled (no schedule) or schedule absent, both should trigger this. if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == FALSE or is_object($p_obj->getScheduleObject()) and $p_obj->getScheduleObject()->getStatus() == 20) { //Debug::text(' Worked when wasnt scheduled', __FILE__, __LINE__, __METHOD__,10); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $p_obj->getID(), 'punch_control_id' => FALSE); } else { Debug::text(' Schedule Found', __FILE__, __LINE__, __METHOD__, 10); } } $prev_punch_time_stamp = $p_obj->getTimeStamp(); } } unset($scheduled_id_cache, $prev_punch_time_stamp, $p_obj); 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 $prev_punch_time_stamp = FALSE; foreach ($plf as $p_obj) { //Ignore punches that have the exact same timestamp, as they are likely transfer punches. if ($prev_punch_time_stamp != $p_obj->getTimeStamp() and $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); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $p_obj->getID(), 'punch_control_id' => FALSE, 'punch_obj' => $p_obj, 'schedule_obj' => $p_obj->getScheduleObject()); } } } else { Debug::text(' NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10); } } $prev_punch_time_stamp = $p_obj->getTimeStamp(); } } break; case 's4': //In Late if ($plf->getRecordCount() > 0) { $prev_punch_time_stamp = FALSE; foreach ($plf as $p_obj) { Debug::text(' In Late. Punch: ' . TTDate::getDate('DATE+TIME', $p_obj->getTimeStamp()), __FILE__, __LINE__, __METHOD__, 10); //Ignore punches that have the exact same timestamp and/or punches with the transfer flag, as they are likely transfer punches. if ($prev_punch_time_stamp != $p_obj->getTimeStamp() and $p_obj->getTransfer() == FALSE and $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); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $p_obj->getID(), 'punch_control_id' => FALSE, 'punch_obj' => $p_obj, 'schedule_obj' => $p_obj->getScheduleObject()); } } } else { Debug::text(' NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10); } } $prev_punch_time_stamp = $p_obj->getTimeStamp(); } } unset($scheduled_id_cache); //Late Starting their shift, with no punch yet, trigger exception if: // - Schedule is found // - Current time is after schedule start time and before schedule end time. // - Current time is after exception grace time //Make sure we take into account split shifts. Debug::text(' Checking Late Starting Shift exception... Current time: ' . TTDate::getDate('DATE+TIME', $current_epoch), __FILE__, __LINE__, __METHOD__, 10); if ($slf->getRecordCount() > 0) { foreach ($slf as $s_obj) { if ($s_obj->getStatus() == 10 and ($current_epoch >= $s_obj->getStartTime() and $current_epoch <= $s_obj->getEndTime())) { if (TTDate::inWindow($current_epoch, $s_obj->getStartTime(), $ep_obj->getGrace()) == TRUE) { Debug::text(' Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10); } else { //See if we can find a punch within the schedule time, if so assume we already created the exception above. //Make sure we take into account the schedule policy start/stop window. //However in the case where a single schedule shift and just one punch exists, if an employee comes in really //early (1AM) before the schedule start/stop window it will trigger an In Late exception. //This could still be correct though if they only come in for an hour, then come in late for their shift later. //Schedule start/stop time needs to be correct. //Also need to take into account shifts that span midnight, ie: 10:30PM to 6:00AM, as its important the schedules/punches match up properly. $add_exception = TRUE; Debug::text(' Found Schedule: Start Time: ' . TTDate::getDate('DATE+TIME', $s_obj->getStartTime()), __FILE__, __LINE__, __METHOD__, 10); //Find punches that fall within this schedule time including start/stop window. if (TTDate::doesRangeSpanMidnight($s_obj->getStartTime(), $s_obj->getEndTime()) and is_object($user_date_obj) and is_object($user_date_obj->getPayPeriodObject()) and is_object($user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject())) { //Get punches from both days. $plf_tmp = TTnew('PunchListFactory'); $plf_tmp->getShiftPunchesByUserIDAndEpoch($user_date_obj->getUser(), $s_obj->getStartTime(), 0, $user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject()->getMaximumShiftTime()); Debug::text(' Schedule spans midnight... Found rows from expanded search: ' . $plf_tmp->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); if ($plf_tmp->getRecordCount() > 0) { foreach ($plf_tmp as $p_obj_tmp) { if ($s_obj->inSchedule($p_obj_tmp->getTimeStamp())) { Debug::text(' Found punch for this schedule, skipping schedule...', __FILE__, __LINE__, __METHOD__, 10); $add_exception = FALSE; continue 2; //Skip to next schedule without creating exception. } } } unset($plf_tmp, $p_obj_tmp); } else { //Get punches from just this day. foreach ($plf as $p_obj) { if ($s_obj->inSchedule($p_obj->getTimeStamp())) { Debug::text(' bFound punch for schedule...', __FILE__, __LINE__, __METHOD__, 10); $add_exception = FALSE; break; } } } if ($add_exception == TRUE) { Debug::text(' NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => FALSE, 'schedule_obj' => $s_obj); } } } } } 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 $prev_punch_time_stamp = FALSE; $total_punches = $plf->getRecordCount(); $x = 1; foreach ($plf as $p_obj) { //Ignore punches that have the exact same timestamp and/or punches with the transfer flag, as they are likely transfer punches. //For Out Early, we have to wait until we are at the last punch, or there is a subsequent punch // to see if it matches the exact same time (transfer) //Therefore we need a two step confirmation before this exception can be triggered. Current punch, then next punch if it exists. if ($p_obj->getTransfer() == FALSE and $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); $tmp_exception = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $p_obj->getID(), 'punch_control_id' => FALSE, 'punch_obj' => $p_obj, 'schedule_obj' => $p_obj->getScheduleObject()); if ($x == $total_punches) { //Trigger exception if we're the last punch. $current_exceptions[] = $tmp_exception; } else { //Save exception to be triggered if the next punch doesn't match the same time. } } } } else { Debug::text(' NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10); } } elseif ($p_obj->getType() == 10 and $p_obj->getStatus() == 10) { //Normal In //This comes after an OUT punch, so we need to check if there are two punches //in a row with the same timestamp, if so ignore the exception. if (isset($tmp_exception) and $p_obj->getTimeStamp() == $prev_punch_time_stamp) { unset($tmp_exception); } elseif (isset($tmp_exception)) { $current_exceptions[] = $tmp_exception; //Set exception. } } $prev_punch_time_stamp = $p_obj->getTimeStamp(); $x++; } } unset($tmp_exception, $x, $prev_punch_time_stamp); break; case 's6': //Out Late if ($plf->getRecordCount() > 0) { $prev_punch_time_stamp = FALSE; foreach ($plf as $p_obj) { $punch_pairs[$p_obj->getPunchControlID()][] = array('status_id' => $p_obj->getStatus(), 'punch_control_id' => $p_obj->getPunchControlID(), 'time_stamp' => $p_obj->getTimeStamp()); if ($prev_punch_time_stamp != $p_obj->getTimeStamp() and $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); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $p_obj->getID(), 'punch_control_id' => FALSE, 'punch_obj' => $p_obj, 'schedule_obj' => $p_obj->getScheduleObject()); } } } else { Debug::text(' NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10); } } $prev_punch_time_stamp = $p_obj->getTimeStamp(); } //Trigger exception if no out punch and we have passed schedule out time. // - Schedule is found // - Make sure the user is missing an OUT punch. // - Current time is after schedule end time // - Current time is after exception grace time // - Current time is before schedule end time + maximum shift time. if (isset($punch_pairs) and $slf->getRecordCount() > 0) { 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); foreach ($slf as $s_obj) { Debug::text('Punch: ' . TTDate::getDate('DATE+TIME', $punch_pair[0]['time_stamp']) . ' Schedule Start Time: ' . TTDate::getDate('DATE+TIME', $s_obj->getStartTime()) . ' End Time: ' . TTDate::getDate('DATE+TIME', $s_obj->getEndTime()), __FILE__, __LINE__, __METHOD__, 10); //Because this is just an IN punch, make sure the IN punch is before the schedule end time //So we can eliminate split shift schedules. if ($punch_pair[0]['time_stamp'] <= $s_obj->getEndTime() and $current_epoch >= $s_obj->getEndTime() and $current_epoch <= $s_obj->getEndTime() + self::$premature_delay) { if (TTDate::inWindow($current_epoch, $s_obj->getEndTime(), $ep_obj->getGrace()) == TRUE) { Debug::text(' Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10); } else { Debug::text(' NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => $punch_pair[0]['punch_control_id'], 'schedule_obj' => $s_obj); } } } } } else { Debug::text('No Missing Punches...', __FILE__, __LINE__, __METHOD__, 10); } } } unset($punch_pairs, $punch_pair); } 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() < $current_epoch - 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('a1Found Missing Punch: ', __FILE__, __LINE__, __METHOD__, 10); if ($punch_pair[0]['status_id'] == 20) { //Missing In Punch Debug::text('b1Found Missing In Punch: ', __FILE__, __LINE__, __METHOD__, 10); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => $punch_pair[0]['punch_control_id']); } } 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); //This causes the exception to trigger if the first punch pair is more than the Maximum Shift time away from the current punch, //ie: In: 1:00AM, Out: 2:00AM, In 3:00PM (Maximum Shift Time less than 12hrs). The missing punch exception will be triggered immediately upon the 3:00PM punch. //if ( $type_id == 5 AND $p_obj->getTimeStamp() < ($current_epoch-self::$premature_delay) ) { // $type_id = 50; //} $punch_pairs[$p_obj->getPunchControlID()][] = array('status_id' => $p_obj->getStatus(), 'punch_control_id' => $p_obj->getPunchControlID(), 'time_stamp' => $p_obj->getTimeStamp()); } if (isset($punch_pairs)) { foreach ($punch_pairs as $punch_control_id => $punch_pair) { if (count($punch_pair) != 2) { Debug::text('a2Found Missing Punch: ', __FILE__, __LINE__, __METHOD__, 10); if ($punch_pair[0]['status_id'] == 10) { //Missing Out Punch Debug::text('b2Found Missing Out Punch: ', __FILE__, __LINE__, __METHOD__, 10); //Make sure we are at least MaximumShift Time from the matching In punch before trigging this exception. //Even when an supervisor is entering punches for today, make missing out punch pre-mature if the maximum shift time isn't exceeded. //This will prevent timesheet recalculations from having missing punches for everyone today. //if ( $type_id == 5 AND $punch_pair[0]['time_stamp'] < ($current_epoch-self::$premature_delay) ) { if ($punch_pair[0]['time_stamp'] < $current_epoch - self::$premature_delay) { $type_id = 50; } else { $type_id = 5; } $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => $punch_pair[0]['punch_control_id']); } } 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() < $current_epoch - 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); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $invalid_punch_arr['punch_id'], 'punch_control_id' => FALSE); } 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() < $current_epoch - 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); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $invalid_punch_arr['punch_id'], 'punch_control_id' => FALSE); } unset($invalid_punch_arr); } else { Debug::text('Lunch Punches match up.', __FILE__, __LINE__, __METHOD__, 10); } unset($invalid_punches); } } break; case 'c1': //Missed Check-in //Use grace period and make sure the employee punches within that period of time (usually a transfer punch, but break/lunch should work too) if ($plf->getRecordCount() > 0 and $ep_obj->getGrace() > 0) { $prev_punch_time_stamp = FALSE; $prev_punch_obj = FALSE; $x = 1; foreach ($plf as $p_obj) { Debug::text(' Missed Check-In Punch: ' . TTDate::getDate('DATE+TIME', $p_obj->getTimeStamp()) . ' Delay: ' . self::$premature_delay . ' Current Epoch: ' . $current_epoch, __FILE__, __LINE__, __METHOD__, 10); //Handle punch pairs below. Only trigger on OUT punches. if (is_object($prev_punch_obj) and $prev_punch_obj->getStatus() == 10 and $p_obj->getStatus() == 20 and $p_obj->getTimeStamp() - $prev_punch_time_stamp > $ep_obj->getGrace()) { //Only check OUT punches when paired. Debug::text(' Triggering excepetion as employee missed check-in within: ' . ($p_obj->getTimeStamp() - $prev_punch_time_stamp), __FILE__, __LINE__, __METHOD__, 10); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $p_obj->getID(), 'punch_control_id' => FALSE, 'punch_obj' => $p_obj, 'schedule_obj' => $p_obj->getScheduleObject()); } elseif ($prev_punch_time_stamp !== FALSE) { Debug::text(' Employee Checked-In within: ' . ($p_obj->getTimeStamp() - $prev_punch_time_stamp), __FILE__, __LINE__, __METHOD__, 10); } //Handle cases where there is a IN punch but no OUT punch yet. //However ignore cases where there is a OUT punch but no IN punch. if ($x == $plf->getRecordCount() and $p_obj->getStatus() == 10 and $current_epoch - $p_obj->getTimeStamp() > $ep_obj->getGrace() and $p_obj->getTimeStamp() > $current_epoch - self::$premature_delay) { Debug::text(' Triggering excepetion as employee hasnt checked in yet, within: ' . ($current_epoch - $prev_punch_time_stamp), __FILE__, __LINE__, __METHOD__, 10); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => $p_obj->getPunchControlID(), 'punch_obj' => $p_obj, 'schedule_obj' => $p_obj->getScheduleObject()); } $prev_punch_time_stamp = $p_obj->getTimeStamp(); $prev_punch_obj = $p_obj; $x++; } } unset($prev_punch_obj, $prev_punch_time_stamp, $x); break; case 'd1': //No Branch or Department $add_exception = FALSE; foreach ($plf as $p_obj) { //In punches only if ($p_obj->getStatus() == 10 and is_object($p_obj->getPunchControlObject())) { //If no Tasks are setup, ignore checking them. if ($p_obj->getPunchControlObject()->getBranch() == '' or $p_obj->getPunchControlObject()->getBranch() == 0 or $p_obj->getPunchControlObject()->getBranch() == FALSE) { $add_exception = TRUE; } if ($p_obj->getPunchControlObject()->getDepartment() == '' or $p_obj->getPunchControlObject()->getDepartment() == 0 or $p_obj->getPunchControlObject()->getDepartment() == FALSE) { //Make sure at least one task exists before triggering exception. $dlf = TTNew('DepartmentListFactory'); $dlf->getByCompanyID($user_date_obj->getUserObject()->getCompany(), 1); //Limit to just 1 record. if ($dlf->getRecordCount() > 0) { $add_exception = TRUE; } } if ($add_exception === TRUE) { $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $p_obj->getId(), 'punch_control_id' => $p_obj->getPunchControlId()); } } } break; case 's7': //Over Scheduled Hours if ($plf->getRecordCount() > 0) { //FIXME: Assign this exception to the last punch of the day, so it can be related back to a punch branch/department? //This ONLY takes in to account WORKED hours, not paid absence hours. //FIXME: Do we want to trigger this before their last out punch? $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 = TTnew('UserDateTotalListFactory'); //Take into account auto-deduct/add meal policies, but not paid absences. //$udtlf->getByUserDateIdAndStatusAndType( $user_date_id, 10, 10 ); $udtlf->getByUserDateId($user_date_id); if ($udtlf->getRecordCount() > 0) { foreach ($udtlf as $udt_obj) { if ($udt_obj->getTimeCategory() == 'worked_time') { $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); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => FALSE); } 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) { //FIXME: Assign this exception to the last punch of the day, so it can be related back to a punch branch/department? //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 = TTnew('UserDateTotalListFactory'); //Take into account auto-deduct/add meal policies //$udtlf->getByUserDateIdAndStatusAndType( $user_date_id, 10, 10 ); $udtlf->getByUserDateId($user_date_id); if ($udtlf->getRecordCount() > 0) { foreach ($udtlf as $udt_obj) { if ($udt_obj->getTimeCategory() == 'worked_time') { $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($current_epoch - self::$premature_delay)) { $type_id = 50; } $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => FALSE); } 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) { //FIXME: Assign this exception to the last punch of the day, so it can be related back to a punch branch/department? //This ONLY takes in to account WORKED hours, not paid absence hours. //FIXME: Do we want to trigger this before their last out punch? $daily_total_time = 0; //Get daily total time. $udtlf = TTnew('UserDateTotalListFactory'); //Take into account auto-deduct/add meal policies //$udtlf->getByUserDateIdAndStatusAndType( $user_date_id, 10, 10 ); $udtlf->getByUserDateId($user_date_id); if ($udtlf->getRecordCount() > 0) { foreach ($udtlf as $udt_obj) { if ($udt_obj->getTimeCategory() == 'worked_time') { $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); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => FALSE); } 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) { //FIXME: Assign this exception to the last punch of the day, so it can be related back to a punch branch/department? //Get Pay Period Schedule info //FIXME: Do we want to trigger this before their last out punch? 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; //Currently we only consider committed scheduled shifts. We may need to change this to take into account //recurring scheduled shifts that haven't been committed yet as well. //In either case though we should take into account the entires week worth of scheduled time even if we are only partially through //the week, that way we won't be triggering s9 exceptions on a Wed and a Fri or something, it will only occur on the last days of the week. if (strtolower($ep_obj->getType()) == 's9') { $tmp_slf = TTnew('ScheduleListFactory'); $tmp_slf->getByUserIdAndStartDateAndEndDate($user_date_obj->getUser(), TTDate::getBeginWeekEpoch($user_date_obj->getDateStamp(), $start_week_day_id), TTDate::getEndWeekEpoch($user_date_obj->getDateStamp(), $start_week_day_id)); if ($tmp_slf->getRecordCount() > 0) { foreach ($tmp_slf as $s_obj) { if ($s_obj->getStatus() == 10) { //Only working shifts. $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 = TTnew('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); //Don't trigger either of these exceptions unless both the worked and scheduled time is greater than 0. If they aren't scheduled at all //it should trigger a Unscheduled Absence exception instead of a over weekly scheduled time exception. 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_scheduled_total_time > 0 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); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => FALSE); } 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 = TTnew('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); if (isset($time_stamp_arr['punch_id'])) { $punch_id = $time_stamp_arr['punch_id']; } else { $punch_id = FALSE; } $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $punch_id, 'punch_control_id' => FALSE); unset($punch_id); } 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 short shift though. //Also ignore this exception if the lunch is auto-deduct. //**Try to assign this exception to a specific punch control id, so we can do searches based on punch branch. //Find meal policy //Use scheduled meal policy first. $meal_policy_obj = NULL; 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); $meal_policy_obj = $s_obj->getSchedulePolicyObject()->getMealPolicyObject(); } 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 = TTnew('MealPolicyListFactory'); $mplf->getByPolicyGroupUserId($user_date_obj->getUser()); if ($mplf->getRecordCount() > 0) { foreach ($mplf as $mp_obj) { if ($mp_obj->getType() != 10) { Debug::text('Found UnScheduled meal Policy... Trigger Time: ' . $mp_obj->getTriggerTime(), __FILE__, __LINE__, __METHOD__, 10); $meal_policy_obj = $mp_obj; } } unset($mplf, $mp_obj); } else { //There is no meal policy or schedule policy with a meal policy assigned to it //With out this we could still apply No meal exceptions, but they will happen even on //a 2minute shift. Debug::text('No Lunch policy, applying No meal exception.', __FILE__, __LINE__, __METHOD__, 10); $meal_policy_obj = TRUE; } } if (is_object($meal_policy_obj) or $meal_policy_obj === TRUE) { $punch_control_id = FALSE; $daily_total_time = 0; $udtlf = TTnew('UserDateTotalListFactory'); $udtlf->getByUserDateIdAndStatus($user_date_id, 20); if ($udtlf->getRecordCount() > 0) { foreach ($udtlf as $udt_obj) { $daily_total_time += $udt_obj->getTotalTime(); $punch_control_total_time[$udt_obj->getPunchControlID()] = $udt_obj->getTotalTime(); } } Debug::text('Day Total Time: ' . $daily_total_time, __FILE__, __LINE__, __METHOD__, 10); //Debug::Arr($punch_control_total_time, 'Punch Control Total Time: ', __FILE__, __LINE__, __METHOD__,10); if ($daily_total_time > 0 and ($meal_policy_obj === TRUE or $daily_total_time > $meal_policy_obj->getTriggerTime())) { //Check for meal punch. $meal_punch = FALSE; $tmp_punch_total_time = 0; $tmp_punch_control_ids = array(); foreach ($plf as $p_obj) { if ($p_obj->getType() == 20) { //20 = Lunch Debug::text('Found meal Punch: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10); $meal_punch = TRUE; break; } if (isset($punch_control_total_time[$p_obj->getPunchControlID()]) and !isset($tmp_punch_control_ids[$p_obj->getPunchControlID()])) { $tmp_punch_total_time += $punch_control_total_time[$p_obj->getPunchControlID()]; if ($punch_control_id === FALSE and ($meal_policy_obj === TRUE or $tmp_punch_total_time > $meal_policy_obj->getTriggerTime())) { Debug::text('Found punch control for exception: ' . $p_obj->getPunchControlID() . ' Total Time: ' . $tmp_punch_total_time, __FILE__, __LINE__, __METHOD__, 10); $punch_control_id = $p_obj->getPunchControlID(); //Don't meal the loop here, as we have to continue on and check for other meals. } } $tmp_punch_control_ids[$p_obj->getPunchControlID()] = TRUE; } unset($tmp_punch_total_time, $tmp_punch_control_ids); if ($meal_punch == FALSE) { Debug::text('Triggering No Lunch exception!', __FILE__, __LINE__, __METHOD__, 10); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => $punch_control_id); } } } } 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 = TTnew('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()->getBreakPolicy(); $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); if (isset($time_stamp_arr['punch_id'])) { $punch_id = $time_stamp_arr['punch_id']; } else { $punch_id = FALSE; } $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $punch_id, 'punch_control_id' => FALSE); unset($punch_id); } 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); //Get daily total time. $daily_total_time = 0; $udtlf = TTnew('UserDateTotalListFactory'); //$udtlf->getByUserDateIdAndStatusAndType( $user_date_id, 10, 10 ); $udtlf->getByUserDateId($user_date_id); if ($udtlf->getRecordCount() > 0) { foreach ($udtlf as $udt_obj) { if ($udt_obj->getTimeCategory() == 'worked_time') { $daily_total_time += $udt_obj->getTotalTime(); } } } Debug::text(' Daily Total Time: ' . $daily_total_time . ' User Date ID: ' . $user_date_id, __FILE__, __LINE__, __METHOD__, 10); //Make sure we take into account how long they have currently worked, so we don't //say too few breaks for 3hr shift that they employee took one break on. //Trigger this exception if the employee doesn't take a break at all? 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 = TTnew('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()->getBreakPolicy(); $bplf->getByIdAndCompanyId($break_policy_ids, $user_date_obj->getUserObject()->getCompany()); } else { //$bplf->getByPolicyGroupUserId( $user_date_obj->getUser() ); $bplf->getByPolicyGroupUserIdAndDayTotalTime($user_date_obj->getUser(), $daily_total_time); } 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); if (isset($time_stamp_arr['punch_id']) and strtolower($ep_obj->getType()) == 'b3') { $punch_id = $time_stamp_arr['punch_id']; } else { $punch_id = FALSE; } $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $punch_id, 'punch_control_id' => FALSE); unset($punch_id); } else { Debug::text('Not Adding Exception!', __FILE__, __LINE__, __METHOD__, 10); } } } } } break; case 'b5': //No Break if ($plf->getRecordCount() > 0) { //If they are scheduled or not, we can check for a break policy and base our //decision off that. We don't want a No Break exception on a 3hr short shift though. //Also ignore this exception if the break is auto-deduct. //**Try to assign this exception to a specific punch control id, so we can do searches based on punch branch. //Find break policy //Use scheduled break policy first. $break_policy_obj = NULL; if ($slf->getRecordCount() > 0) { Debug::text('Schedule Found...', __FILE__, __LINE__, __METHOD__, 10); foreach ($slf as $s_obj) { if ($s_obj->getSchedulePolicyObject() !== FALSE) { $break_policy_ids = $s_obj->getSchedulePolicyObject()->getBreakPolicy(); if (is_array($break_policy_ids)) { $bplf = TTNew('BreakPolicyListFactory'); $bplf->getByIdAndCompanyId($break_policy_ids, $user_date_obj->getUserObject()->getCompany()); if ($bplf->getRecordCount() > 0) { foreach ($bplf as $bp_obj) { if ($bp_obj->getType() != 10) { $break_policy_obj = $bp_obj; break; } } } } } unset($s_obj, $break_policy_ids, $bplf, $bp_obj); } } else { Debug::text('No Schedule Found...', __FILE__, __LINE__, __METHOD__, 10); //Check if they have a break policy, with no schedule. $bplf = TTnew('BreakPolicyListFactory'); $bplf->getByPolicyGroupUserId($user_date_obj->getUser()); if ($bplf->getRecordCount() > 0) { Debug::text('Found UnScheduled Break Policy...', __FILE__, __LINE__, __METHOD__, 10); foreach ($bplf as $bp_obj) { if ($bp_obj->getType() != 10) { $break_policy_obj = $bp_obj; break; } } unset($bplf, $bp_obj); } else { //There is no break policy or schedule policy with a break policy assigned to it //With out this we could still apply No Break exceptions, but they will happen even on //a 2minute shift. Debug::text('No break policy, applying No break exception.', __FILE__, __LINE__, __METHOD__, 10); $break_policy_obj = TRUE; } } if (is_object($break_policy_obj) or $break_policy_obj === TRUE) { $punch_control_id = FALSE; $daily_total_time = 0; $udtlf = TTnew('UserDateTotalListFactory'); $udtlf->getByUserDateIdAndStatus($user_date_id, 20); if ($udtlf->getRecordCount() > 0) { foreach ($udtlf as $udt_obj) { $daily_total_time += $udt_obj->getTotalTime(); $punch_control_total_time[$udt_obj->getPunchControlID()] = $udt_obj->getTotalTime(); } } Debug::text('Day Total Time: ' . $daily_total_time, __FILE__, __LINE__, __METHOD__, 10); //Debug::Arr($punch_control_total_time, 'Punch Control Total Time: ', __FILE__, __LINE__, __METHOD__,10); if ($daily_total_time > 0 and ($break_policy_obj === TRUE or $daily_total_time > $break_policy_obj->getTriggerTime())) { //Check for break punch. $break_punch = FALSE; $tmp_punch_total_time = 0; $tmp_punch_control_ids = array(); foreach ($plf as $p_obj) { if ($p_obj->getType() == 30) { //30 = Break Debug::text('Found break Punch: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10); $break_punch = TRUE; break; } if (isset($punch_control_total_time[$p_obj->getPunchControlID()]) and !isset($tmp_punch_control_ids[$p_obj->getPunchControlID()])) { $tmp_punch_total_time += $punch_control_total_time[$p_obj->getPunchControlID()]; if ($punch_control_id === FALSE and ($break_policy_obj === TRUE or $tmp_punch_total_time > $break_policy_obj->getTriggerTime())) { Debug::text('Found punch control for exception: ' . $p_obj->getPunchControlID(), __FILE__, __LINE__, __METHOD__, 10); $punch_control_id = $p_obj->getPunchControlID(); //Don't break the loop here, as we have to continue on and check for other breaks. } } $tmp_punch_control_ids[$p_obj->getPunchControlID()] = TRUE; } unset($tmp_punch_total_time, $tmp_punch_control_ids); if ($break_punch == FALSE) { Debug::text('Triggering No Break exception!', __FILE__, __LINE__, __METHOD__, 10); $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => $punch_control_id); } } } } break; case 'v1': //TimeSheet Not Verified //Get pay period schedule data, determine if timesheet verification is even enabled. if (is_object($user_date_obj->getPayPeriodObject()) and is_object($user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject()) and $user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject()->getTimeSheetVerifyType() > 10) { Debug::text('Verification enabled... Window Start: ' . TTDate::getDate('DATE+TIME', $user_date_obj->getPayPeriodObject()->getTimeSheetVerifyWindowStartDate()) . ' Grace Time: ' . $ep_obj->getGrace(), __FILE__, __LINE__, __METHOD__, 10); //*Only* trigger this exception on the last day of the pay period, because when the pay period is verified it has to force the last day to be recalculated. //Ignore timesheets without any time, (worked and absence). Or we could use the Watch Window to specify the minimum time required on //a timesheet to trigger this instead? //Make sure we are after the timesheet window start date + the grace period. if ($user_date_obj->getPayPeriodObject()->getStatus() != 50 and $current_epoch >= $user_date_obj->getPayPeriodObject()->getTimeSheetVerifyWindowStartDate() + $ep_obj->getGrace() and TTDate::getBeginDayEpoch($user_date_obj->getDateStamp()) == TTDate::getBeginDayEpoch($user_date_obj->getPayPeriodObject()->getEndDate())) { //Get pay period total time, include worked and paid absence time. $udtlf = TTnew('UserDateTotalListFactory'); $total_time = $udtlf->getTimeSumByUserIDAndPayPeriodId($user_date_obj->getUser(), $user_date_obj->getPayPeriodObject()->getID()); if ($total_time > 0) { //Check to see if pay period has been verified or not yet. $pptsvlf = TTnew('PayPeriodTimeSheetVerifyListFactory'); $pptsvlf->getByPayPeriodIdAndUserId($user_date_obj->getPayPeriodObject()->getId(), $user_date_obj->getUser()); $pay_period_verified = FALSE; if ($pptsvlf->getRecordCount() > 0) { $pay_period_verified = $pptsvlf->getCurrent()->getAuthorized(); } if ($pay_period_verified == FALSE) { //Always allow for emailing this exception because it can be triggered after a punch is modified and //any supervisor would need to be notified to verify the timesheet again. $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => FALSE, 'enable_email_notification' => TRUE); } else { Debug::text('TimeSheet has already been authorized!', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text('Timesheet does not have any worked or paid absence time...', __FILE__, __LINE__, __METHOD__, 10); } unset($udtlf, $total_time); } else { Debug::text('Not within timesheet verification window, or not after grace time.', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text('No Pay Period Schedule or TimeSheet Verificiation disabled...', __FILE__, __LINE__, __METHOD__, 10); } break; case 'j1': //Not Allowed on Job if (getTTProductEdition() >= TT_PRODUCT_CORPORATE and $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 = TTnew('JobListFactory'); $jlf->getById($p_obj->getPunchControlObject()->getJob()); if ($jlf->getRecordCount() > 0) { $j_obj = $jlf->getCurrent(); if ($j_obj->isAllowedUser($user_date_obj->getUser()) == FALSE) { $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => $p_obj->getPunchControlId()); } 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 (getTTProductEdition() >= TT_PRODUCT_CORPORATE and $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 = TTnew('JobListFactory'); $jlf->getById($p_obj->getPunchControlObject()->getJob()); if ($jlf->getRecordCount() > 0) { $j_obj = $jlf->getCurrent(); if ($j_obj->isAllowedItem($p_obj->getPunchControlObject()->getJobItem()) == FALSE) { $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => $p_obj->getPunchControlId()); } 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 (getTTProductEdition() >= TT_PRODUCT_CORPORATE and $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 = TTnew('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()) { $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => FALSE, 'punch_control_id' => $p_obj->getPunchControlId()); } 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 (getTTProductEdition() >= TT_PRODUCT_CORPORATE and $plf->getRecordCount() > 0) { foreach ($plf as $p_obj) { $add_exception = FALSE; //In punches only if ($p_obj->getStatus() == 10 and is_object($p_obj->getPunchControlObject())) { //If no Tasks are setup, ignore checking them. if ($p_obj->getPunchControlObject()->getJob() == '' or $p_obj->getPunchControlObject()->getJob() == 0 or $p_obj->getPunchControlObject()->getJob() == FALSE) { $add_exception = TRUE; } if ($p_obj->getPunchControlObject()->getJobItem() == '' or $p_obj->getPunchControlObject()->getJobItem() == 0 or $p_obj->getPunchControlObject()->getJobItem() == FALSE) { //Make sure at least one task exists before triggering exception. $jilf = TTNew('JobItemListFactory'); $jilf->getByCompanyID($user_date_obj->getUserObject()->getCompany(), 1); //Limit to just 1 record. if ($jilf->getRecordCount() > 0) { $add_exception = TRUE; } } if ($add_exception === TRUE) { $current_exceptions[] = array('user_date_id' => $user_date_id, 'exception_policy_id' => $ep_obj->getId(), 'type_id' => $type_id, 'punch_id' => $p_obj->getId(), 'punch_control_id' => $p_obj->getPunchControlId()); } } } } break; default: Debug::text('BAD, should never get here: ', __FILE__, __LINE__, __METHOD__, 10); break; } } } unset($ep_obj); $exceptions = self::diffExistingAndCurrentExceptions($existing_exceptions, $current_exceptions); if (is_array($exceptions)) { if (isset($exceptions['create_exceptions']) and is_array($exceptions['create_exceptions']) and count($exceptions['create_exceptions']) > 0) { Debug::text('Creating new exceptions... Total: ' . count($exceptions['create_exceptions']), __FILE__, __LINE__, __METHOD__, 10); foreach ($exceptions['create_exceptions'] as $tmp_exception) { $ef = TTnew('ExceptionFactory'); $ef->setUserDateID($tmp_exception['user_date_id']); $ef->setExceptionPolicyID($tmp_exception['exception_policy_id']); $ef->setType($tmp_exception['type_id']); if (isset($tmp_exception['punch_control_id']) and $tmp_exception['punch_control_id'] != '') { $ef->setPunchControlId($tmp_exception['punch_control_id']); } if (isset($tmp_exception['punch_id']) and $tmp_exception['punch_id'] != '') { $ef->setPunchId($tmp_exception['punch_id']); } $ef->setEnableDemerits(TRUE); if ($ef->isValid()) { $ef->Save(FALSE); //Save exception prior to emailing it, otherwise we can't save audit logs. if ($enable_premature_exceptions == TRUE or isset($tmp_exception['enable_email_notification']) and $tmp_exception['enable_email_notification'] == TRUE) { $eplf = TTnew('ExceptionPolicyListFactory'); $eplf->getById($tmp_exception['exception_policy_id']); if ($eplf->getRecordCount() == 1) { $ep_obj = $eplf->getCurrent(); $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, isset($tmp_exception['punch_obj']) ? $tmp_exception['punch_obj'] : NULL, isset($tmp_exception['schedule_obj']) ? $tmp_exception['schedule_obj'] : NULL, $ep_obj); } } else { Debug::text('Not emailing new exception: User Date ID: ' . $tmp_exception['user_date_id'] . ' Type ID: ' . $tmp_exception['type_id'] . ' Enable PreMature: ' . (int) $enable_premature_exceptions, __FILE__, __LINE__, __METHOD__, 10); } } unset($ef); } } if (isset($exceptions['delete_exceptions']) and is_array($exceptions['delete_exceptions']) and count($exceptions['delete_exceptions']) > 0) { Debug::Text('Deleting no longer valid exceptions... Total: ' . count($exceptions['delete_exceptions']), __FILE__, __LINE__, __METHOD__, 10); $ef = TTnew('ExceptionFactory'); $ef->bulkDelete($exceptions['delete_exceptions']); } } $profiler->stopTimer("ExceptionPolicy::calcExceptions()"); return TRUE; }
break; case 'recalculate_company': Debug::Text('Recalculating company timesheet!', __FILE__, __LINE__, __METHOD__, 10); //Redirect::Page( URLBuilder::getURL( array('action' => 'recalculate_company', 'pay_period_ids' => $pay_period_id, 'next_page' => urlencode( URLBuilder::getURL( array('filter_date' => $filter_date ), '../timesheet/ViewUserTimeSheet.php') ) ), '../progress_bar/ProgressBarControl.php') ); Redirect::Page(URLBuilder::getURL(array('action' => 'recalculate_company', 'pay_period_ids' => $pay_period_id, 'next_page' => urlencode(URLBuilder::getURL(NULL, '../timesheet/ViewUserTimeSheet.php'))), '../progress_bar/ProgressBarControl.php'), FALSE); break; case 'recalculate_employee': Debug::Text('Recalculating employee timesheet!', __FILE__, __LINE__, __METHOD__, 10); Redirect::Page(URLBuilder::getURL(array('action' => 'recalculate_employee', 'pay_period_ids' => $pay_period_id, 'filter_user_id' => $filter_data['user_id'], 'next_page' => urlencode(URLBuilder::getURL(NULL, '../timesheet/ViewUserTimeSheet.php'))), '../progress_bar/ProgressBarControl.php'), FALSE); break; case 'submit': default: BreadCrumb::setCrumb($title); Debug::Text('Default Action: ' . $action, __FILE__, __LINE__, __METHOD__, 10); $start_date = TTDate::getBeginWeekEpoch($filter_data['date'], $current_user_prefs->getStartWeekDay()); $end_date = TTDate::getEndWeekEpoch($filter_data['date'], $current_user_prefs->getStartWeekDay()); Debug::Text('Start Date: ' . TTDate::getDate('DATE+TIME', $start_date) . ' End Date: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10); $calendar_array = TTDate::getCalendarArray($start_date, $end_date, $current_user_prefs->getStartWeekDay()); //var_dump($calendar_array); //Get all punches, put in array by date epoch. $plf = TTnew('PunchListFactory'); $plf->getByCompanyIDAndUserIdAndStartDateAndEndDate($current_company->getId(), $user_id, $start_date, $end_date); if ($plf->getRecordCount() > 0) { foreach ($plf as $punch_obj) { $user_date_stamp = TTDate::strtotime($punch_obj->getColumn('user_date_stamp')); if ($punch_obj->getColumn('note') != '') { $has_note = TRUE; } else { $has_note = FALSE; } $punches[$user_date_stamp][] = array('date_stamp' => $punch_obj->getColumn('user_date_stamp'), 'id' => $punch_obj->getId(), 'punch_control_id' => $punch_obj->getPunchControlId(), 'time_stamp' => $punch_obj->getTimeStamp(), 'status_id' => $punch_obj->getStatus(), 'type_id' => $punch_obj->getType(), 'type_code' => $punch_obj->getTypeCode(), 'has_note' => $has_note);
/** * Get punch data for one or more punches. * @param array $data filter data * @return array */ function getPunch($data = NULL, $disable_paging = FALSE) { if (!$this->getPermissionObject()->Check('punch', 'enabled') or !($this->getPermissionObject()->Check('punch', 'view') or $this->getPermissionObject()->Check('punch', 'view_own') or $this->getPermissionObject()->Check('punch', 'view_child'))) { return $this->getPermissionObject()->PermissionDenied(); } $data = $this->initializeFilterAndPager($data, $disable_paging); $data['filter_data']['permission_children_ids'] = $this->getPermissionObject()->getPermissionChildren('punch', 'view'); //As a performance optimization to prevent the API from having to do additional date lookups, accept a single "date" field, that converts //into start/end dates. if (isset($data['filter_data']['date']) and $data['filter_data']['date'] != '') { $data['filter_data']['start_date'] = TTDate::getBeginWeekEpoch($data['filter_data']['date'], $this->getCurrentUserPreferenceObject()->getStartWeekDay()); $data['filter_data']['end_date'] = TTDate::getEndWeekEpoch($data['filter_data']['date'], $this->getCurrentUserPreferenceObject()->getStartWeekDay()); } //No filter data, restrict to last pay period as a performance optimization when hundreds of thousands of punches exist. //The issue with this though is that the API doesn't know what the filter criteria is, so it can't display this to the user. if (count($data['filter_data']) == 1 and !isset($data['filter_data']['pay_period_ids'])) { Debug::Text('Adding default filter data...', __FILE__, __LINE__, __METHOD__, 10); $pplf = TTnew('PayPeriodListFactory'); $pplf->getByCompanyId($this->getCurrentCompanyObject()->getId()); $pay_period_ids = array_keys((array) $pplf->getArrayByListFactory($pplf, FALSE, FALSE)); if (isset($pay_period_ids[0]) and isset($pay_period_ids[1])) { $data['filter_data']['pay_period_ids'] = array($pay_period_ids[0], $pay_period_ids[1]); } unset($pplf, $pay_period_ids); } $blf = TTnew('PunchListFactory'); $blf->getAPISearchByCompanyIdAndArrayCriteria($this->getCurrentCompanyObject()->getId(), $data['filter_data'], $data['filter_items_per_page'], $data['filter_page'], NULL, $data['filter_sort']); Debug::Text('Record Count: ' . $blf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); if ($blf->getRecordCount() > 0) { $this->getProgressBarObject()->start($this->getAMFMessageID(), $blf->getRecordCount()); $this->setPagerObject($blf); foreach ($blf as $b_obj) { $retarr[] = $b_obj->getObjectAsArray($data['filter_columns'], $data['filter_data']['permission_children_ids']); $this->getProgressBarObject()->set($this->getAMFMessageID(), $blf->getCurrentRow()); } $this->getProgressBarObject()->stop($this->getAMFMessageID()); return $this->returnHandler($retarr); } return $this->returnHandler(TRUE); //No records returned. }