/**
  * Get default recurring_schedule_control data for creating new recurring_schedule_controles.
  * @return array
  */
 function getRecurringScheduleControlDefaultData()
 {
     $company_obj = $this->getCurrentCompanyObject();
     Debug::Text('Getting recurring_schedule_control default data...', __FILE__, __LINE__, __METHOD__, 10);
     $data = array('company_id' => $company_obj->getId(), 'start_week' => 1, 'start_date' => TTDate::getAPIDate('DATE', TTDate::getBeginWeekEpoch(TTDate::getTime())), 'end_date' => NULL);
     return $this->returnHandler($data);
 }
 /**
  * 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;
 }
Exemple #3
0
 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;
 }
Exemple #4
0
 function testScheduleB()
 {
     global $dd;
     $this->createPayPeriodSchedule(10);
     $this->createPayPeriods();
     $this->getAllPayPeriods();
     $date_epoch = TTDate::getBeginWeekEpoch(time());
     //Use current year
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $date_epoch2 = TTDate::getBeginWeekEpoch(time()) + 86400;
     //Use current year
     $date_stamp2 = TTDate::getDate('DATE', $date_epoch2);
     $meal_policy_id = $this->createMealPolicy(10);
     //60min autodeduct
     $schedule_policy_id = $this->createSchedulePolicy($meal_policy_id);
     $schedule_id = $this->createSchedule($this->user_id, $date_epoch, array('schedule_policy_id' => $schedule_policy_id, 'start_time' => ' 11:00PM', 'end_time' => '8:00AM'));
     $slf = TTNew('ScheduleListFactory');
     $slf->getByID($schedule_id);
     if ($slf->getRecordCount() == 1) {
         $s_obj = $slf->getCurrent();
         $this->assertEquals($date_stamp, TTDate::getDate('DATE', $s_obj->getStartTime()));
         $this->assertEquals($date_stamp2, TTDate::getDate('DATE', $s_obj->getEndTime()));
         $this->assertEquals(8 * 3600, $s_obj->getTotalTime());
     } else {
         $this->assertEquals(TRUE, FALSE);
     }
     return TRUE;
 }
 function getShiftsByStartDateAndEndDate($start_date, $end_date)
 {
     //Make sure timezone isn't in the time format. Because recurring schedules
     //are timezone agnostic. 7:00AM in PST is also 7:00AM in EST.
     //This causes an issue where the previous users timezone carries over to the next
     //users timezone, causing errors.
     //TTDate::setTimeFormat('g:i A');
     if ($start_date == '') {
         return FALSE;
     }
     if ($end_date == '') {
         return FALSE;
     }
     if ($start_date < $this->getStartDate()) {
         $start_date = $this->getStartDate();
     }
     if ($this->getEndDate(TRUE) != NULL and $end_date > $this->getEndDate()) {
         $end_date = $this->getEndDate();
     }
     Debug::text('Start Date: ' . TTDate::getDate('DATE+TIME', $start_date) . '(' . $start_date . ') End Date: ' . TTDate::getDate('DATE+TIME', $end_date) . '(' . $end_date . ')', __FILE__, __LINE__, __METHOD__, 10);
     //Get week data
     $rstlf = TTnew('RecurringScheduleTemplateListFactory');
     $rstlf->getByRecurringScheduleTemplateControlId($this->getRecurringScheduleTemplateControl())->getCurrent();
     $max_week = 1;
     $weeks = array();
     if ($rstlf->getRecordCount() > 0) {
         foreach ($rstlf as $rst_obj) {
             //Debug::text('Week: '. $rst_obj->getWeek(), __FILE__, __LINE__, __METHOD__, 10);
             $template_week_rows[$rst_obj->getWeek()][] = $rst_obj->getObjectAsArray();
             $weeks[$rst_obj->getWeek()] = $rst_obj->getWeek();
             if ($rst_obj->getWeek() > $max_week) {
                 $max_week = $rst_obj->getWeek();
             }
         }
     }
     $weeks = $this->ReMapWeeks($weeks);
     //Get week of start_date
     $start_date_week = TTDate::getBeginWeekEpoch($this->getStartDate(), 0);
     //Start week on Sunday to match Recurring Schedule.
     //Debug::text('Week of Start Date: '. $start_date_week .' Date: '. TTDate::getDate('DATE+TIME', $this->getStartDate() ) ,__FILE__, __LINE__, __METHOD__, 10);
     //Since we add 43200 to each iteration (even though its removed right after), we need to add 43200 to the end_date as well so we loop the
     //proper amount of times, otherwise schedules may be added too late.
     for ($i = $start_date; $i <= $end_date + 43200; $i += 86400 + 43200) {
         //Handle DST by adding 12hrs to the date to get the mid-day epoch, then forcing it back to the beginning of the day.
         $i = TTDate::getBeginDayEpoch($i);
         //This needs to take into account weeks spanning January 1st of each year. Where the week goes from 53 to 1.
         //Rather then use the week of the year, calculate the weeks between the recurring schedule start date and now.
         $current_week = round((TTDate::getBeginWeekEpoch($i, 0) - $start_date_week) / 604800);
         //Find out which week we are on based on the recurring schedule start date. Use round due to DST the week might be 6.9 or 7.1, so we need to round to the nearest full week.
         //Debug::text('I: '. $i .' User ID: '. $this->getColumn('user_id') .' Current Date: '. TTDate::getDate('DATE+TIME', $i) .' Current Week: '. $current_week .' Start Week: '. $start_date_week,__FILE__, __LINE__, __METHOD__, 10);
         $template_week = $current_week % $max_week + 1;
         //Debug::text('Template Week: '. $template_week .' Max Week: '. $max_week,__FILE__, __LINE__, __METHOD__, 10);
         $day_of_week = strtolower(date('D', $i));
         //Debug::text('Day Of Week: '. $day_of_week,__FILE__, __LINE__, __METHOD__, 10);
         if (isset($weeks[$template_week])) {
             $mapped_template_week = $weeks[$template_week];
             //Debug::text('&nbsp;&nbsp;Mapped Template Week: '. $mapped_template_week,__FILE__, __LINE__, __METHOD__, 10);
             if (isset($template_week_rows[$mapped_template_week])) {
                 //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Starting Looping...!',__FILE__, __LINE__, __METHOD__, 10);
                 foreach ($template_week_rows[$mapped_template_week] as $template_week_arr) {
                     if ($template_week_arr['days'][$day_of_week] == TRUE) {
                         //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Found Scheduled Time: Start Time: '. TTDate::getDate('DATE+TIME', TTDate::getTimeLockedDate( $template_week_arr['start_time'], $i ) ),__FILE__, __LINE__, __METHOD__, 10);
                         $start_time = TTDate::getTimeLockedDate($template_week_arr['raw_start_time'], $i);
                         $end_time = TTDate::getTimeLockedDate($template_week_arr['raw_end_time'], $i);
                         if ($end_time < $start_time) {
                             //Spans the day boundary, add 86400 to end_time
                             $end_time = $end_time + 86400;
                             //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Schedule spans day boundary, bumping endtime to next day: ',__FILE__, __LINE__, __METHOD__, 10);
                         }
                         //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Start Date: '. TTDate::getDate('DATE+TIME', $start_time) .' End Date: '. TTDate::getDate('DATE+TIME', $end_time),__FILE__, __LINE__, __METHOD__, 10);
                         //$shifts[TTDate::getBeginDayEpoch($i)][] = array(
                         $shifts[TTDate::getISODateStamp($i)][] = array('status_id' => $template_week_arr['status_id'], 'start_time' => $start_time, 'raw_start_time' => TTDate::getDate('DATE+TIME', $start_time), 'end_time' => $end_time, 'raw_end_time' => TTDate::getDate('DATE+TIME', $end_time), 'total_time' => $template_week_arr['total_time'], 'schedule_policy_id' => $template_week_arr['schedule_policy_id'], 'branch_id' => $template_week_arr['branch_id'], 'department_id' => $template_week_arr['department_id'], 'job_id' => $template_week_arr['job_id'], 'job_item_id' => $template_week_arr['job_item_id']);
                         unset($start_time, $end_time);
                     } else {
                         //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aSkipping!',__FILE__, __LINE__, __METHOD__, 10);
                     }
                 }
             } else {
                 //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;bSkipping!',__FILE__, __LINE__, __METHOD__, 10);
             }
         } else {
             //Debug::text('&nbsp;&nbsp;cSkipping!',__FILE__, __LINE__, __METHOD__, 10);
         }
     }
     //var_dump($shifts);
     if (isset($shifts)) {
         return $shifts;
     }
     return FALSE;
 }
 function getShifts($start_date, $end_date, &$holiday_data = array(), &$branch_options = array(), &$department_options = array(), &$n, &$shifts = array(), &$shifts_index = array(), $open_shift_conflict_index = array(), $permission_children_ids = NULL)
 {
     //Debug::text('Start Date: '. TTDate::getDate('DATE+TIME', $start_date) .' End Date: '. TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10);
     $recurring_schedule_control_start_date = TTDate::strtotime($this->getColumn('recurring_schedule_control_start_date'));
     //Debug::text('Recurring Schedule Control Start Date: '. TTDate::getDate('DATE+TIME', $recurring_schedule_control_start_date),__FILE__, __LINE__, __METHOD__, 10);
     $current_template_week = $this->getColumn('remapped_week');
     $max_week = $this->getColumn('max_week');
     //Debug::text('Template Week: '. $current_template_week .' Max Week: '. $this->getColumn('max_week') .' ReMapped Week: '. $this->getColumn('remapped_week') ,__FILE__, __LINE__, __METHOD__, 10);
     if ($recurring_schedule_control_start_date == '') {
         return FALSE;
     }
     //Get week of start_date
     $start_date_week = TTDate::getBeginWeekEpoch($recurring_schedule_control_start_date, 0);
     //Start week on Sunday to match Recurring Schedule.
     //Debug::text('Week of Start Date: '. $start_date_week ,__FILE__, __LINE__, __METHOD__, 10);
     $apf = TTnew('AbsencePolicyFactory');
     $absence_policy_paid_type_options = $apf->getOptions('paid_type');
     for ($i = $start_date; $i <= $end_date; $i += 86400 + 43200) {
         //Handle DST by adding 12hrs to the date to get the mid-day epoch, then forcing it back to the beginning of the day.
         $i = TTDate::getBeginDayEpoch($i);
         if ($this->getColumn('hire_date') != '' and $i < $this->getColumn('hire_date') or $this->getColumn('termination_date') != '' and $i > $this->getColumn('termination_date')) {
             //Debug::text('Skipping due to Hire/Termination date: User ID: '. $this->getColumn('user_id') .' I: '. $i .' Hire Date: '. $this->getColumn('hire_date') .' Termination Date: '. $this->getColumn('termination_date') ,__FILE__, __LINE__, __METHOD__, 10);
             continue;
         }
         //This needs to take into account weeks spanning January 1st of each year. Where the week goes from 53 to 1.
         //Rather then use the week of the year, calculate the weeks between the recurring schedule start date and now.
         $current_week = round((TTDate::getBeginWeekEpoch($i, 0) - $start_date_week) / 604800);
         //Find out which week we are on based on the recurring schedule start date. Use round due to DST the week might be 6.9 or 7.1, so we need to round to the nearest full week.
         //Debug::text('I: '. $i .' User ID: '. $this->getColumn('user_id') .' Current Date: '. TTDate::getDate('DATE+TIME', $i) .' Current Week: '. $current_week .' Start Week: '. $start_date_week,__FILE__, __LINE__, __METHOD__, 10);
         $template_week = $current_week % $max_week + 1;
         //Debug::text('Template Week: '. $template_week .' Max Week: '. $max_week,__FILE__, __LINE__, __METHOD__, 10);
         if ($template_week == $current_template_week) {
             //Debug::text('Current Date: '. TTDate::getDate('DATE+TIME', $i) .' Current Week: '. $current_week,__FILE__, __LINE__, __METHOD__, 10);
             //Debug::text('&nbsp;Template Week: '. $template_week .' Max Week: '. $max_week,__FILE__, __LINE__, __METHOD__, 10);
             if ($this->isActiveShiftDay($i)) {
                 //Debug::text('&nbsp;&nbsp;Active Shift on this day...',__FILE__, __LINE__, __METHOD__, 10);
                 $start_time = TTDate::getTimeLockedDate($this->getStartTime(), $i);
                 $end_time = TTDate::getTimeLockedDate($this->getEndTime(), $i);
                 if ($end_time < $start_time) {
                     //Spans the day boundary, add 86400 to end_time
                     $end_time = $end_time + 86400;
                     //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Schedule spans day boundary, bumping endtime to next day: ',__FILE__, __LINE__, __METHOD__, 10);
                 }
                 $iso_date_stamp = TTDate::getISODateStamp(PayPeriodScheduleFactory::getShiftAssignedDate($start_time, $end_time, $this->getColumn('shift_assigned_day_id')));
                 //$iso_date_stamp = TTDate::getISODateStamp( $i );
                 $open_shift_multiplier = $this->getColumn('user_id') == 0 ? $this->getOpenShiftMultiplier() : 1;
                 //Debug::text('Open Shift Multiplier: '. $open_shift_multiplier,__FILE__, __LINE__, __METHOD__, 10);
                 for ($x = 0; $x < $open_shift_multiplier; $x++) {
                     //Check all non-OPEN shifts for conflicts.
                     if ($this->getColumn('user_id') > 0 and isset($shifts_index[$iso_date_stamp][$this->getColumn('user_id')])) {
                         //User has previous recurring schedule shifts, check for overlap.
                         //Loop over each employees shift for this day and check for conflicts
                         foreach ($shifts_index[$iso_date_stamp][$this->getColumn('user_id')] as $shift_key) {
                             if (isset($shifts[$iso_date_stamp][$shift_key])) {
                                 //Must use parseDateTime() when called from the API due to date formats that strtotime() fails on.
                                 if (TTDate::isTimeOverLap(defined('TIMETREX_API') ? TTDate::parseDateTime($shifts[$iso_date_stamp][$shift_key]['start_date']) : $shifts[$iso_date_stamp][$shift_key]['start_date'], defined('TIMETREX_API') ? TTDate::parseDateTime($shifts[$iso_date_stamp][$shift_key]['end_date']) : $shifts[$iso_date_stamp][$shift_key]['end_date'], $start_time, $end_time) == TRUE) {
                                     //Debug::text('&nbsp;&nbsp;Found overlapping recurring schedules! User ID: '. $this->getColumn('user_id') .' Start Time: '. $start_time,__FILE__, __LINE__, __METHOD__, 10);
                                     continue 2;
                                 }
                             }
                         }
                         unset($shift_key);
                     } elseif ($this->getColumn('user_id') == 0 and isset($shifts_index[$iso_date_stamp])) {
                         //Debug::text('    Checking OPEN shift conflicts... Date: '. $iso_date_stamp,__FILE__, __LINE__, __METHOD__, 10);
                         //Check all OPEN shifts for conflicts.
                         //This is special, since there can be multiple open shifts for the same branch,department,job,task, so we need to check if are conflicts with *any* employee.
                         //Do we allow conflicting shifts between committed and recurring OPEN shifts? For example what if there are two open shifts on the same day
                         //6AM-3PM (x2) and they want to override one of those shifts to 7AM-4PM? If we use this check:
                         //   ( $shifts[$iso_date_stamp][$shift_key]['user_id'] > 0 OR ( isset($shifts[$iso_date_stamp][$shift_key]['id']) AND $shifts[$iso_date_stamp][$shift_key]['id'] > 0 ) )
                         //That allows committed OPEN shifts to override recurring open shifts, which is great, but it prevents adding additional open shifts that may
                         //also overlap unless they override all recurring shifts first. I think this is the trade-off we have to make as its more likely that they
                         //will adjust an open shift time rather than add/remove specific shifts. Removing recurring OPEN shifts can be done by making them ABSENT.
                         //This will also affect when recurring OPEN shifts are committed by preventing the shifts from doubling up.
                         foreach ($shifts_index[$iso_date_stamp] as $tmp_index_user_id => $tmp_index_arr) {
                             foreach ($tmp_index_arr as $shift_key) {
                                 $tmp_start_date = defined('TIMETREX_API') ? TTDate::parseDateTime($shifts[$iso_date_stamp][$shift_key]['start_date']) : $shifts[$iso_date_stamp][$shift_key]['start_date'];
                                 $tmp_end_date = defined('TIMETREX_API') ? TTDate::parseDateTime($shifts[$iso_date_stamp][$shift_key]['end_date']) : $shifts[$iso_date_stamp][$shift_key]['end_date'];
                                 if (($shifts[$iso_date_stamp][$shift_key]['user_id'] > 0 or isset($shifts[$iso_date_stamp][$shift_key]['id']) and $shifts[$iso_date_stamp][$shift_key]['id'] > 0) and (!isset($open_shift_conflict_index['open'][$this->getID()][$shift_key]) and (isset($shifts[$iso_date_stamp][$shift_key]['id']) and !isset($open_shift_conflict_index['scheduled'][$shifts[$iso_date_stamp][$shift_key]['id']]))) and $this->getColumn('schedule_branch_id') == $shifts[$iso_date_stamp][$shift_key]['branch_id'] and $this->getColumn('schedule_department_id') == $shifts[$iso_date_stamp][$shift_key]['department_id'] and $this->getColumn('job_id') == $shifts[$iso_date_stamp][$shift_key]['job_id'] and $this->getColumn('job_item_id') == $shifts[$iso_date_stamp][$shift_key]['job_item_id'] and ($tmp_start_date == $start_time and $tmp_end_date == $end_time)) {
                                     //Debug::text('      Found OPEN shift conflict... Skipping...! Shift Key: '. $shift_key,__FILE__, __LINE__, __METHOD__, 10);
                                     //We need to track each shift_key that caused a conflict so it can't cause another conflict later on.
                                     //  Make sure we just track it on a per template basis though, otherwise the same $shift_key from a previous template can affect other templates.
                                     //  The above issue would show up as OPEN shifts not being overridden.
                                     //We also need to track which scheduled shift that caused a conflict so it can't cause another one later on.
                                     //  This prevents a single scheduled shift from overriding multiple OPEN shifts of different times.
                                     //However we need to be smarter about which shifts override which OPEN shifts...
                                     //  So if there are two open shifts, 10AM-4PM and 3:50PM-9PM, a 10AM-4PM scheduled shift overrides the OPEN shift that best fits it (10AM to 4PM, *not* 3:50-9PM)
                                     //  For now require an exact match to override an OPEN shift, if we start using partial schedules it gets much more complicated.
                                     //  Or we could introduce a hardcoded "fudge factor" setting (ie: 5 mins) that is always used instead.
                                     $open_shift_conflict_index['open'][$this->getID()][$shift_key] = TRUE;
                                     $open_shift_conflict_index['scheduled'][$shifts[$iso_date_stamp][$shift_key]['id']] = TRUE;
                                     continue 3;
                                 }
                                 unset($tmp_start_date, $tmp_end_date);
                             }
                         }
                         unset($tmp_index_user_id, $tmp_index_arr);
                     }
                     //This check has to occurr after the committed schedule check, otherwise no committed schedules will appear.
                     if ($this->getColumn('recurring_schedule_control_start_date') != '' and $i < TTDate::strtotime($this->getColumn('recurring_schedule_control_start_date')) or $this->getColumn('recurring_schedule_control_end_date') != '' and $i > TTDate::strtotime($this->getColumn('recurring_schedule_control_end_date'))) {
                         //Debug::text('Skipping due to Recurring Schedule Start/End date: ID: '. $this->getColumn('id') .' User ID: '. $this->getColumn('user_id') .' I: '. $i .' Start Date: '. $this->getColumn('recurring_schedule_control_start_date') .' ('. TTDate::strtotime( $this->getColumn('recurring_schedule_control_start_date') ) .') End Date: '. $this->getColumn('recurring_schedule_control_end_date') ,__FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Start Date: '. TTDate::getDate('DATE+TIME', $start_time) .' End Date: '. TTDate::getDate('DATE+TIME', $end_time),__FILE__, __LINE__, __METHOD__, 10);
                     $status_id = $this->getColumn('status_id');
                     $absence_policy_id = $this->getColumn('absence_policy_id');
                     $absence_policy_type_id = $this->getColumn('absence_policy_type_id');
                     $absence_policy = $this->getColumn('absence_policy') != '' ? $this->getColumn('absence_policy') : NULL;
                     //Must be NULL to be converted to N/A
                     if (isset($holiday_data[$iso_date_stamp])) {
                         //We have to assume they are eligible, because we really won't know
                         //if they will have worked enough days or not. We could assume they
                         //work whatever their schedule is, but chances are they will be eligible then anyways.
                         //Debug::text('&nbsp;&nbsp;Found Holiday on this day...',__FILE__, __LINE__, __METHOD__, 10);
                         $status_id = $holiday_data[$iso_date_stamp]['status_id'];
                         if (isset($holiday_data[$iso_date_stamp]['absence_policy_id'])) {
                             $absence_policy_id = $holiday_data[$iso_date_stamp]['absence_policy_id'];
                             $absence_policy_type_id = $holiday_data[$iso_date_stamp]['type_id'];
                             $absence_policy = $holiday_data[$iso_date_stamp]['absence_policy'];
                         }
                     }
                     $hourly_rate = Misc::MoneyFormat($this->getColumn('user_wage_hourly_rate'), FALSE);
                     if ($absence_policy_id > 0 and in_array($absence_policy_type_id, $absence_policy_paid_type_options) == FALSE) {
                         //UnPaid Absence.
                         $total_time_wage = Misc::MoneyFormat(0);
                     } else {
                         $total_time_wage = Misc::MoneyFormat(bcmul(TTDate::getHours($this->getTotalTime()), $hourly_rate), FALSE);
                     }
                     //Debug::text('I: '. $i .' N: '. $n .' User ID: '. $this->getColumn('user_id') .' Current Date: '. TTDate::getDate('DATE+TIME', $i) .' Current Week: '. $current_week .' Start Time: '. TTDate::getDate('DATE+TIME', $start_time ) .' Absence Policy: '. $absence_policy,__FILE__, __LINE__, __METHOD__, 10);
                     //$shifts[$iso_date_stamp][$this->getColumn('user_id').$start_time] = array(
                     $shifts[$iso_date_stamp][$n] = array('pay_period_id' => FALSE, 'user_id' => (int) $this->getColumn('user_id'), 'user_created_by' => $this->getColumn('user_created_by'), 'user_full_name' => $this->getColumn('user_id') > 0 ? Misc::getFullName($this->getColumn('first_name'), NULL, $this->getColumn('last_name'), FALSE, FALSE) : TTi18n::getText('OPEN'), 'first_name' => $this->getColumn('first_name'), 'last_name' => $this->getColumn('last_name'), 'title_id' => $this->getColumn('title_id'), 'title' => $this->getColumn('title'), 'group_id' => $this->getColumn('group_id'), 'group' => $this->getColumn('group'), 'default_branch_id' => $this->getColumn('default_branch_id'), 'default_branch' => $this->getColumn('default_branch'), 'default_department_id' => $this->getColumn('default_department_id'), 'default_department' => $this->getColumn('default_department'), 'job_id' => $this->getJob(), 'job' => $this->getColumn('job'), 'job_status_id' => $this->getColumn('job_status_id'), 'job_manual_id' => $this->getColumn('job_manual_id'), 'job_branch_id' => $this->getColumn('job_branch_id'), 'job_department_id' => $this->getColumn('job_department_id'), 'job_group_id' => $this->getColumn('job_group_id'), 'job_item_id' => $this->getJobItem(), 'job_item' => $this->getColumn('job_item'), 'type_id' => 20, 'status_id' => $status_id, 'date_stamp' => TTDate::getAPIDate('DATE', strtotime($iso_date_stamp)), 'start_date_stamp' => defined('TIMETREX_API') ? TTDate::getAPIDate('DATE', $start_time) : $start_time, 'start_date' => defined('TIMETREX_API') ? TTDate::getAPIDate('DATE+TIME', $start_time) : $start_time, 'end_date' => defined('TIMETREX_API') ? TTDate::getAPIDate('DATE+TIME', $end_time) : $end_time, 'start_time' => defined('TIMETREX_API') ? TTDate::getAPIDate('TIME', $start_time) : $start_time, 'end_time' => defined('TIMETREX_API') ? TTDate::getAPIDate('TIME', $end_time) : $end_time, 'start_time_stamp' => $start_time, 'end_time_stamp' => $end_time, 'total_time' => $this->getTotalTime(), 'hourly_rate' => $hourly_rate, 'total_time_wage' => $total_time_wage, 'note' => FALSE, 'schedule_policy_id' => $this->getSchedulePolicyID(), 'absence_policy_id' => $absence_policy_id, 'absence_policy' => $absence_policy, 'branch_id' => $this->getColumn('schedule_branch_id'), 'branch' => $this->getColumn('schedule_branch'), 'department_id' => $this->getColumn('schedule_department_id'), 'department' => $this->getColumn('schedule_department'), 'created_by_id' => $this->getColumn('recurring_schedule_control_created_by'), 'created_date' => $this->getCreatedDate(), 'updated_date' => $this->getUpdatedDate());
                     //Make sure we add in permission columns.
                     $this->getPermissionColumns($shifts[$iso_date_stamp][$n], (int) $this->getColumn('user_id'), $this->getColumn('recurring_schedule_control_created_by'), $permission_children_ids);
                     //$shifts_index[$iso_date_stamp][$this->getColumn('user_id')][] = $this->getColumn('user_id').$start_time;
                     $shifts_index[$iso_date_stamp][$this->getColumn('user_id')][] = $n;
                     $n++;
                 }
                 unset($open_shift_multiplier);
                 unset($start_time, $end_time);
             } else {
                 //Debug::text('&nbsp;&nbsp;NOT active shift on this day... ID: '. $this->getColumn('id') .' User ID: '. $this->getColumn('user_id') .' Start Time: '. TTDate::getDate('DATE+TIME', $i),__FILE__, __LINE__, __METHOD__, 10);
             }
         }
     }
     if (isset($shifts)) {
         //Debug::Arr($shifts, 'Template Shifts: ',__FILE__, __LINE__, __METHOD__, 10);
         return $shifts;
     }
     return FALSE;
 }
 function createPayPeriodSchedule()
 {
     $ppsf = new PayPeriodScheduleFactory();
     $ppsf->setCompany($this->company_id);
     //$ppsf->setName( 'Bi-Weekly'.rand(1000,9999) );
     $ppsf->setName('Bi-Weekly');
     $ppsf->setDescription('Pay every two weeks');
     $ppsf->setType(20);
     $ppsf->setStartWeekDay(0);
     $anchor_date = TTDate::getBeginWeekEpoch(TTDate::getBeginYearEpoch());
     //Start 6 weeks ago
     $ppsf->setAnchorDate($anchor_date);
     $ppsf->setStartDayOfWeek(TTDate::getDayOfWeek($anchor_date));
     $ppsf->setTransactionDate(7);
     $ppsf->setTransactionDateBusinessDay(TRUE);
     $ppsf->setDayStartTime(0);
     $ppsf->setNewDayTriggerTime(4 * 3600);
     $ppsf->setMaximumShiftTime(16 * 3600);
     $ppsf->setShiftAssignedDay(10);
     //$ppsf->setContinuousTime( (4*3600) );
     $ppsf->setEnableInitialPayPeriods(FALSE);
     if ($ppsf->isValid()) {
         $insert_id = $ppsf->Save(FALSE);
         Debug::Text('Pay Period Schedule ID: ' . $insert_id, __FILE__, __LINE__, __METHOD__, 10);
         $ppsf->setUser(array($this->user_id));
         $ppsf->Save();
         $this->pay_period_schedule_id = $insert_id;
         return $insert_id;
     }
     Debug::Text('Failed Creating Pay Period Schedule!', __FILE__, __LINE__, __METHOD__, 10);
     return FALSE;
 }
 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 createPayPeriods($start_date = NULL)
 {
     if ($start_date == '') {
         $start_date = TTDate::getBeginWeekEpoch(TTDate::getBeginYearEpoch(time()) - 86400 * (7 * 6));
     }
     $max_pay_periods = 192;
     //Make a lot of pay periods as we need to test 6 years worth of accruals for different milestones.
     $ppslf = new PayPeriodScheduleListFactory();
     $ppslf->getById($this->pay_period_schedule_id);
     if ($ppslf->getRecordCount() > 0) {
         $pps_obj = $ppslf->getCurrent();
         for ($i = 0; $i < $max_pay_periods; $i++) {
             if ($i == 0) {
                 //$end_date = TTDate::getBeginYearEpoch( strtotime('01-Jan-07') );
                 $end_date = $start_date;
             } else {
                 $end_date = $end_date + 86400 * 14;
             }
             Debug::Text('I: ' . $i . ' End Date: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10);
             $pps_obj->createNextPayPeriod($end_date, 86400 * 3600);
         }
     }
     return TRUE;
 }
 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;
 }
 function testAutoAddMultipleBreakPolicyE()
 {
     global $dd;
     $policy_ids['break'][] = $this->createBreakPolicy($this->company_id, 150);
     $policy_ids['break'][] = $this->createBreakPolicy($this->company_id, 152);
     $policy_ids['break'][] = $this->createBreakPolicy($this->company_id, 154);
     $policy_ids['break'][] = $this->createBreakPolicy($this->company_id, 156);
     //This one shouldn't apply
     //Create Policy Group
     $dd->createPolicyGroup($this->company_id, NULL, NULL, NULL, NULL, NULL, NULL, array($this->user_id), $policy_ids['break']);
     $date_epoch = TTDate::getBeginWeekEpoch(time());
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:00AM'), strtotime($date_stamp . ' 10:00AM'), array('in_type_id' => 10, 'out_type_id' => 30, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 10:06AM'), strtotime($date_stamp . ' 12:00PM'), array('in_type_id' => 30, 'out_type_id' => 30, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 12:06PM'), strtotime($date_stamp . ' 2:15PM'), array('in_type_id' => 30, 'out_type_id' => 30, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 2:21PM'), strtotime($date_stamp . ' 4:30PM'), array('in_type_id' => 30, 'out_type_id' => 30, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 4:36PM'), strtotime($date_stamp . ' 5:30PM'), array('in_type_id' => 30, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //print_r($udt_arr);
     //Total Time
     $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 9.5 * 3600);
     //Regular Time
     $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 20);
     $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 9.5 * 3600);
     return TRUE;
 }
     Redirect::Page(URLBuilder::getURL(array('filter_user_id' => $filter_data['user_id']), '../pay_stub_amendment/PayStubAmendmentList.php'));
     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;
             }
Exemple #13
0
 function testRoundingD()
 {
     global $dd;
     $this->createPayPeriodSchedule(10);
     $this->createPayPeriods();
     $this->getAllPayPeriods();
     $policy_ids['round'][] = $dd->createRoundingPolicy($this->company_id, 30);
     //Day Total
     $policy_ids['round'][] = $dd->createRoundingPolicy($this->company_id, 40);
     //Lunch Total
     $policy_ids['round'][] = $dd->createRoundingPolicy($this->company_id, 50);
     //Break Total
     //Create Policy Group
     $dd->createPolicyGroup($this->company_id, NULL, NULL, NULL, NULL, NULL, $policy_ids['round'], array($this->user_id));
     $date_epoch = TTDate::getBeginWeekEpoch(time());
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:03AM'), NULL, array('in_type_id' => 10, 'out_type_id' => 20, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $dd->createPunchPair($this->user_id, NULL, strtotime($date_stamp . ' 12:06PM'), array('in_type_id' => 10, 'out_type_id' => 30, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 1:12PM'), NULL, array('in_type_id' => 30, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $dd->createPunchPair($this->user_id, NULL, strtotime($date_stamp . ' 5:07PM'), array('in_type_id' => 20, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $punch_arr = $this->getPunchDataArray(TTDate::getBeginDayEpoch($date_epoch), TTDate::getEndDayEpoch($date_epoch));
     //print_r($punch_arr);
     $this->assertEquals(2, count($punch_arr[$date_epoch]));
     $this->assertEquals($punch_arr[$date_epoch][0]['shift_data']['punches'][0]['time_stamp'], strtotime($date_stamp . ' 8:03AM'));
     $this->assertEquals($punch_arr[$date_epoch][0]['shift_data']['punches'][1]['time_stamp'], strtotime($date_stamp . ' 12:06PM'));
     $this->assertEquals($punch_arr[$date_epoch][0]['shift_data']['punches'][2]['time_stamp'], strtotime($date_stamp . ' 1:06PM'));
     $this->assertEquals($punch_arr[$date_epoch][0]['shift_data']['punches'][3]['time_stamp'], strtotime($date_stamp . ' 5:03PM'));
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //Total Time
     $this->assertEquals(10, $udt_arr[$date_epoch][0]['status_id']);
     $this->assertEquals(10, $udt_arr[$date_epoch][0]['type_id']);
     $this->assertEquals(8 * 3600, $udt_arr[$date_epoch][0]['total_time']);
     return TRUE;
 }
Exemple #14
0
 function testMaximumShiftTimeD()
 {
     global $dd;
     $this->createPayPeriodSchedule(10);
     $this->createPayPeriods();
     $this->getAllPayPeriods();
     $date_epoch = TTDate::getBeginWeekEpoch(time());
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $date_epoch2 = TTDate::getBeginDayEpoch(TTDate::getBeginWeekEpoch(time()) + 86400 + 3600);
     $date_stamp2 = TTDate::getDate('DATE', $date_epoch2);
     //Create two punch pairs with LESS than the minimum time between shifts, so they both fall on the same day, but are considered ONE shift and therefore fails.
     //However the last punch must be more than 16hrs away from the previous OUT punch (2:30PM)
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 1:00AM'), strtotime($date_stamp . ' 2:30PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 6:15PM'), strtotime($date_stamp2 . ' 8:00AM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $punch_arr = $this->getPunchDataArray(TTDate::getBeginDayEpoch($date_epoch), TTDate::getEndDayEpoch($date_epoch2));
     //print_r($punch_arr);
     $this->assertEquals(2, count($punch_arr[$date_epoch][0]['shift_data']['punches']));
     $this->assertEquals(1, count($punch_arr[$date_epoch][0]['shift_data']['punch_control_ids']));
     //$this->assertEquals( $date_epoch, $punch_arr[$date_epoch][0]['date_stamp'] );
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch2);
     //Total Time
     $this->assertEquals(10, $udt_arr[$date_epoch][0]['status_id']);
     $this->assertEquals(10, $udt_arr[$date_epoch][0]['type_id']);
     $this->assertEquals(13.5 * 3600, $udt_arr[$date_epoch][0]['total_time']);
     return TRUE;
 }
 function calcExceptions($user_date_id, $enable_premature_exceptions = FALSE, $enable_future_exceptions = TRUE)
 {
     global $profiler;
     $profiler->startTimer("ExceptionPolicy::calcExceptions()");
     if ($user_date_id == '') {
         return FALSE;
     }
     Debug::text(' User Date ID: ' . $user_date_id . ' PreMature: ' . (int) $enable_premature_exceptions, __FILE__, __LINE__, __METHOD__, 10);
     //Get user date info
     $udlf = new UserDateListFactory();
     $udlf->getById($user_date_id);
     if ($udlf->getRecordCount() > 0) {
         $user_date_obj = $udlf->getCurrent();
         if ($enable_future_exceptions == FALSE and $user_date_obj->getDateStamp() > TTDate::getEndDayEpoch()) {
             return FALSE;
         }
     } else {
         return FALSE;
     }
     //Since we are not usng demerits yet, just always delete exceptions and re-calculate them
     $elf = new ExceptionListFactory();
     $elf->getByUserDateID($user_date_id);
     if ($elf->getRecordCount() > 0) {
         foreach ($elf as $e_obj) {
             Debug::text(' Deleting Exception: ' . $e_obj->getID(), __FILE__, __LINE__, __METHOD__, 10);
             $e_obj->Delete();
         }
     }
     //Get all Punches on this date for this user.
     $plf = new PunchListFactory();
     $plf->getByUserDateId($user_date_id);
     if ($plf->getRecordCount() > 0) {
         Debug::text(' Found Punches: ' . $plf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     }
     $slf = new ScheduleListFactory();
     $slf->getByUserDateIdAndStatusId($user_date_id, 10);
     if ($slf->getRecordCount() > 0) {
         Debug::text(' Found Schedule: ' . $slf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     }
     $schedule_id_cache = NULL;
     //Cache schedule IDs so we don't need to do a lookup for every exception.
     //Get all active exceptions.
     $eplf = new ExceptionPolicyListFactory();
     $eplf->getByPolicyGroupUserIdAndActive($user_date_obj->getUser(), TRUE);
     if ($eplf->getRecordCount() > 0) {
         Debug::text(' Found Active Exceptions: ' . $eplf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
         foreach ($eplf as $ep_obj) {
             //Debug::text(' Found Exception Type: '. $ep_obj->getType() .' ID: '. $ep_obj->getID() .' Control ID: '. $ep_obj->getExceptionPolicyControl(), __FILE__, __LINE__, __METHOD__,10);
             if ($enable_premature_exceptions == TRUE and self::isPreMature($ep_obj->getType()) == TRUE) {
                 //Debug::text(' Premature Exception: '. $ep_obj->getType() , __FILE__, __LINE__, __METHOD__,10);
                 $type_id = 5;
                 //Pre-Mature
             } else {
                 //Debug::text(' NOT Premature Exception: '. $ep_obj->getType() , __FILE__, __LINE__, __METHOD__,10);
                 $type_id = 50;
                 //Active
             }
             switch (strtolower($ep_obj->getType())) {
                 case 's1':
                     //Unscheduled Absence... Anytime they are scheduled and have not punched in.
                     //Ignore these exceptions if the schedule is after today (not including today),
                     //so if a supervisors schedules an employee two days in advance they don't get a unscheduled
                     //absence appearing right away.
                     if ($plf->getRecordCount() == 0) {
                         if ($slf->getRecordCount() > 0) {
                             foreach ($slf as $s_obj) {
                                 if ($s_obj->getStatus() == 10 and TTDate::getBeginDayEpoch($s_obj->getStartTime()) - TTDate::getBeginDayEpoch(TTDate::getTime()) <= 0) {
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 }
                             }
                         } else {
                             Debug::text(' NOT Scheduled', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 's2':
                     //Not Scheduled
                     $schedule_total_time = 0;
                     if ($slf->getRecordCount() == 0) {
                         if ($plf->getRecordCount() > 0) {
                             Debug::text(' Worked when wasnt scheduled', __FILE__, __LINE__, __METHOD__, 10);
                             $ef = new ExceptionFactory();
                             $ef->setUserDateID($user_date_id);
                             $ef->setExceptionPolicyID($ep_obj->getId());
                             $ef->setType($type_id);
                             $ef->setEnableDemerits(TRUE);
                             if ($ef->isValid()) {
                                 if ($enable_premature_exceptions == TRUE) {
                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                 }
                                 $ef->Save();
                             }
                         }
                     } else {
                         Debug::text(' IS Scheduled', __FILE__, __LINE__, __METHOD__, 10);
                     }
                     break;
                 case 's3':
                     //In Early
                     if ($plf->getRecordCount() > 0) {
                         //Loop through each punch, find out if they are scheduled, and if they are in early
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getType() == 10 and $p_obj->getStatus() == 10) {
                                 //Normal In
                                 if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                     $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                 }
                                 if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE) {
                                     if ($p_obj->getTimeStamp() < $p_obj->getScheduleObject()->getStartTime()) {
                                         if (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getStartTime(), $ep_obj->getGrace()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                         } elseif (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getStartTime(), $ep_obj->getWatchWindow()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setPunchID($p_obj->getID());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         }
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                     }
                     break;
                 case 's4':
                     //In Late
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getType() == 10 and $p_obj->getStatus() == 10) {
                                 //Normal In
                                 if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                     $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                 }
                                 if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE) {
                                     if ($p_obj->getTimeStamp() > $p_obj->getScheduleObject()->getStartTime()) {
                                         if (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getStartTime(), $ep_obj->getGrace()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                         } elseif (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getStartTime(), $ep_obj->getWatchWindow()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setPunchID($p_obj->getID());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         }
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                     }
                     break;
                 case 's5':
                     //Out Early
                     if ($plf->getRecordCount() > 0) {
                         //Loop through each punch, find out if they are scheduled, and if they are in early
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getType() == 10 and $p_obj->getStatus() == 20) {
                                 //Normal Out
                                 if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                     $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                 }
                                 if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE) {
                                     if ($p_obj->getTimeStamp() < $p_obj->getScheduleObject()->getEndTime()) {
                                         if (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getEndTime(), $ep_obj->getGrace()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                         } elseif (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getEndTime(), $ep_obj->getWatchWindow()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setPunchID($p_obj->getID());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         }
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                     }
                     break;
                 case 's6':
                     //Out Late
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getType() == 10 and $p_obj->getStatus() == 20) {
                                 //Normal Out
                                 if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                     $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                 }
                                 if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE) {
                                     if ($p_obj->getTimeStamp() > $p_obj->getScheduleObject()->getEndTime()) {
                                         if (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getEndTime(), $ep_obj->getGrace()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Within Grace time, IGNORE EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                         } elseif (TTDate::inWindow($p_obj->getTimeStamp(), $p_obj->getScheduleObject()->getEndTime(), $ep_obj->getWatchWindow()) == TRUE) {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NOT Within Grace time, SET EXCEPTION: ', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setPunchID($p_obj->getID());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         }
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;NO Schedule Found', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                     }
                     break;
                 case 'm1':
                     //Missing In Punch
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             //Debug::text(' Punch: Status: '. $p_obj->getStatus() .' Punch Control ID: '. $p_obj->getPunchControlID() .' Punch ID: '. $p_obj->getId() .' TimeStamp: '. $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__,10);
                             if ($type_id == 5 and $p_obj->getTimeStamp() < time() - self::$premature_delay) {
                                 $type_id = 50;
                             }
                             $punch_pairs[$p_obj->getPunchControlID()][] = array('status_id' => $p_obj->getStatus(), 'punch_control_id' => $p_obj->getPunchControlID(), 'punch_id' => $p_obj->getId());
                         }
                         if (isset($punch_pairs)) {
                             foreach ($punch_pairs as $punch_control_id => $punch_pair) {
                                 //Debug::Arr($punch_pair, 'Punch Pair for Control ID:'. $punch_control_id, __FILE__, __LINE__, __METHOD__,10);
                                 if (count($punch_pair) != 2) {
                                     Debug::text('aFound Missing Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                     if ($punch_pair[0]['status_id'] == 20) {
                                         //Missing In Punch
                                         Debug::text('bFound Missing In Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                         $ef = new ExceptionFactory();
                                         $ef->setUserDateID($user_date_id);
                                         $ef->setExceptionPolicyID($ep_obj->getId());
                                         $ef->setPunchControlID($punch_pair[0]['punch_control_id']);
                                         $ef->setType($type_id);
                                         $ef->setEnableDemerits(TRUE);
                                         if ($ef->isValid()) {
                                             if ($enable_premature_exceptions == TRUE) {
                                                 $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                             }
                                             $ef->Save();
                                         }
                                     }
                                 } else {
                                     Debug::text('No Missing Punches...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($punch_pairs, $punch_pair);
                     }
                     break;
                 case 'm2':
                     //Missing Out Punch
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             Debug::text(' Punch: Status: ' . $p_obj->getStatus() . ' Punch Control ID: ' . $p_obj->getPunchControlID() . ' Punch ID: ' . $p_obj->getId() . ' TimeStamp: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
                             if ($type_id == 5 and $p_obj->getTimeStamp() < time() - self::$premature_delay) {
                                 $type_id = 50;
                             }
                             $punch_pairs[$p_obj->getPunchControlID()][] = array('status_id' => $p_obj->getStatus(), 'punch_control_id' => $p_obj->getPunchControlID());
                         }
                         if (isset($punch_pairs)) {
                             foreach ($punch_pairs as $punch_control_id => $punch_pair) {
                                 if (count($punch_pair) != 2) {
                                     Debug::text('aFound Missing Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                     if ($punch_pair[0]['status_id'] == 10) {
                                         //Missing Out Punch
                                         Debug::text('bFound Missing Out Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                         $ef = new ExceptionFactory();
                                         $ef->setUserDateID($user_date_id);
                                         $ef->setExceptionPolicyID($ep_obj->getId());
                                         $ef->setPunchControlID($punch_pair[0]['punch_control_id']);
                                         $ef->setType($type_id);
                                         $ef->setEnableDemerits(TRUE);
                                         if ($ef->isValid()) {
                                             if ($enable_premature_exceptions == TRUE) {
                                                 $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                             }
                                             $ef->Save();
                                         }
                                     }
                                 } else {
                                     Debug::text('No Missing Punches...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($punch_pairs, $punch_pair);
                     }
                     break;
                 case 'm3':
                     //Missing Lunch In/Out punch
                     if ($plf->getRecordCount() > 0) {
                         //We need to account for cases where they may punch IN from lunch first, then Out.
                         //As well as just a Lunch In punch and nothing else.
                         foreach ($plf as $p_obj) {
                             if ($type_id == 5 and $p_obj->getTimeStamp() < time() - self::$premature_delay) {
                                 $type_id = 50;
                             }
                             $punches[] = $p_obj;
                         }
                         if (isset($punches) and is_array($punches)) {
                             foreach ($punches as $key => $p_obj) {
                                 if ($p_obj->getType() == 20) {
                                     //Lunch
                                     Debug::text(' Punch: Status: ' . $p_obj->getStatus() . ' Punch Control ID: ' . $p_obj->getPunchControlID() . ' TimeStamp: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
                                     if ($p_obj->getStatus() == 10) {
                                         //Make sure previous punch is Lunch/Out
                                         if (!isset($punches[$key - 1]) or isset($punches[$key - 1]) and is_object($punches[$key - 1]) and ($punches[$key - 1]->getType() != 20 or $punches[$key - 1]->getStatus() != 20)) {
                                             //Invalid punch
                                             $invalid_punches[] = array('punch_id' => $p_obj->getId());
                                         }
                                     } else {
                                         //Make sure next punch is Lunch/In
                                         if (!isset($punches[$key + 1]) or isset($punches[$key + 1]) and is_object($punches[$key + 1]) and ($punches[$key + 1]->getType() != 20 or $punches[$key + 1]->getStatus() != 10)) {
                                             //Invalid punch
                                             $invalid_punches[] = array('punch_id' => $p_obj->getId());
                                         }
                                     }
                                 }
                             }
                             unset($punches, $key, $p_obj);
                             if (isset($invalid_punches) and count($invalid_punches) > 0) {
                                 foreach ($invalid_punches as $invalid_punch_arr) {
                                     Debug::text('Found Missing Lunch In/Out Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     //$ef->setPunchControlID( $invalid_punch_arr['punch_id'] );
                                     $ef->setPunchID($invalid_punch_arr['punch_id']);
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 }
                                 unset($invalid_punch_arr);
                             } else {
                                 Debug::text('Lunch Punches match up.', __FILE__, __LINE__, __METHOD__, 10);
                             }
                             unset($invalid_punches);
                         }
                     }
                     break;
                 case 'm4':
                     //Missing Break In/Out punch
                     if ($plf->getRecordCount() > 0) {
                         //We need to account for cases where they may punch IN from break first, then Out.
                         //As well as just a break In punch and nothing else.
                         foreach ($plf as $p_obj) {
                             if ($type_id == 5 and $p_obj->getTimeStamp() < time() - self::$premature_delay) {
                                 $type_id = 50;
                             }
                             $punches[] = $p_obj;
                         }
                         if (isset($punches) and is_array($punches)) {
                             foreach ($punches as $key => $p_obj) {
                                 if ($p_obj->getType() == 30) {
                                     //Break
                                     Debug::text(' Punch: Status: ' . $p_obj->getStatus() . ' Type: ' . $p_obj->getType() . ' Punch Control ID: ' . $p_obj->getPunchControlID() . ' TimeStamp: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
                                     if ($p_obj->getStatus() == 10) {
                                         //Make sure previous punch is Break/Out
                                         if (!isset($punches[$key - 1]) or isset($punches[$key - 1]) and is_object($punches[$key - 1]) and ($punches[$key - 1]->getType() != 30 or $punches[$key - 1]->getStatus() != 20)) {
                                             //Invalid punch
                                             $invalid_punches[] = array('punch_id' => $p_obj->getId());
                                         }
                                     } else {
                                         //Make sure next punch is Break/In
                                         if (!isset($punches[$key + 1]) or isset($punches[$key + 1]) and is_object($punches[$key + 1]) and ($punches[$key + 1]->getType() != 30 or $punches[$key + 1]->getStatus() != 10)) {
                                             //Invalid punch
                                             $invalid_punches[] = array('punch_id' => $p_obj->getId());
                                         }
                                     }
                                 }
                             }
                             unset($punches, $key, $p_obj);
                             if (isset($invalid_punches) and count($invalid_punches) > 0) {
                                 foreach ($invalid_punches as $invalid_punch_arr) {
                                     Debug::text('Found Missing Break In/Out Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     //$ef->setPunchControlID( $invalid_punch_arr['punch_id'] );
                                     $ef->setPunchID($invalid_punch_arr['punch_id']);
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 }
                                 unset($invalid_punch_arr);
                             } else {
                                 Debug::text('Lunch Punches match up.', __FILE__, __LINE__, __METHOD__, 10);
                             }
                             unset($invalid_punches);
                         }
                     }
                     break;
                 case 's7':
                     //Over Scheduled Hours
                     if ($plf->getRecordCount() > 0) {
                         //This ONLY takes in to account WORKED hours, not paid absence hours.
                         $schedule_total_time = 0;
                         if ($slf->getRecordCount() > 0) {
                             //Check for schedule policy
                             foreach ($slf as $s_obj) {
                                 Debug::text(' Schedule Total Time: ' . $s_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                                 $schedule_total_time += $s_obj->getTotalTime();
                             }
                             $daily_total_time = 0;
                             if ($schedule_total_time > 0) {
                                 //Get daily total time.
                                 $udtlf = new UserDateTotalListFactory();
                                 //Take into account auto-deduct/add meal policies
                                 //$udtlf->getByUserDateIdAndStatus( $user_date_id, 20 );
                                 $udtlf->getByUserDateIdAndStatusAndType($user_date_id, 10, 10);
                                 if ($udtlf->getRecordCount() > 0) {
                                     foreach ($udtlf as $udt_obj) {
                                         $daily_total_time += $udt_obj->getTotalTime();
                                     }
                                 }
                                 Debug::text(' Daily Total Time: ' . $daily_total_time . ' Schedule Total Time: ' . $schedule_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                 if ($daily_total_time > 0 and $daily_total_time > $schedule_total_time + $ep_obj->getGrace()) {
                                     Debug::text(' Worked Over Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 } else {
                                     Debug::text(' DID NOT Work Over Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         } else {
                             Debug::text(' Not Scheduled', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 's8':
                     //Under Scheduled Hours
                     if ($plf->getRecordCount() > 0) {
                         //This ONLY takes in to account WORKED hours, not paid absence hours.
                         $schedule_total_time = 0;
                         if ($slf->getRecordCount() > 0) {
                             //Check for schedule policy
                             foreach ($slf as $s_obj) {
                                 Debug::text(' Schedule Total Time: ' . $s_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                                 $schedule_total_time += $s_obj->getTotalTime();
                             }
                             $daily_total_time = 0;
                             if ($schedule_total_time > 0) {
                                 //Get daily total time.
                                 $udtlf = new UserDateTotalListFactory();
                                 //Take into account auto-deduct/add meal policies
                                 //$udtlf->getByUserDateIdAndStatus( $user_date_id, 20 );
                                 $udtlf->getByUserDateIdAndStatusAndType($user_date_id, 10, 10);
                                 if ($udtlf->getRecordCount() > 0) {
                                     foreach ($udtlf as $udt_obj) {
                                         $daily_total_time += $udt_obj->getTotalTime();
                                     }
                                 }
                                 Debug::text(' Daily Total Time: ' . $daily_total_time . ' Schedule Total Time: ' . $schedule_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                 if ($daily_total_time < $schedule_total_time - $ep_obj->getGrace()) {
                                     Debug::text(' Worked Under Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                                     if ($type_id == 5 and $user_date_obj->getDateStamp() < TTDate::getBeginDayEpoch(time() - self::$premature_delay)) {
                                         $type_id = 50;
                                     }
                                     $ef = new ExceptionFactory();
                                     $ef->setUserDateID($user_date_id);
                                     $ef->setExceptionPolicyID($ep_obj->getId());
                                     $ef->setType($type_id);
                                     $ef->setEnableDemerits(TRUE);
                                     if ($ef->isValid()) {
                                         if ($enable_premature_exceptions == TRUE) {
                                             $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                         }
                                         $ef->Save();
                                     }
                                 } else {
                                     Debug::text(' DID NOT Work Under Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         } else {
                             Debug::text(' Not Scheduled', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'o1':
                     //Over Daily Time.
                     if ($plf->getRecordCount() > 0) {
                         //This ONLY takes in to account WORKED hours, not paid absence hours.
                         $daily_total_time = 0;
                         //Get daily total time.
                         $udtlf = new UserDateTotalListFactory();
                         //Take into account auto-deduct/add meal policies
                         $udtlf->getByUserDateIdAndStatusAndType($user_date_id, 10, 10);
                         if ($udtlf->getRecordCount() > 0) {
                             foreach ($udtlf as $udt_obj) {
                                 $daily_total_time += $udt_obj->getTotalTime();
                             }
                         }
                         Debug::text(' Daily Total Time: ' . $daily_total_time . ' Watch Window: ' . $ep_obj->getWatchWindow() . ' User Date ID: ' . $user_date_id, __FILE__, __LINE__, __METHOD__, 10);
                         if ($daily_total_time > 0 and $daily_total_time > $ep_obj->getWatchWindow()) {
                             Debug::text(' Worked Over Daily Hours', __FILE__, __LINE__, __METHOD__, 10);
                             $ef = new ExceptionFactory();
                             $ef->setUserDateID($user_date_id);
                             $ef->setExceptionPolicyID($ep_obj->getId());
                             $ef->setType($type_id);
                             $ef->setEnableDemerits(TRUE);
                             if ($ef->isValid()) {
                                 if ($enable_premature_exceptions == TRUE) {
                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                 }
                                 $ef->Save();
                             }
                         } else {
                             Debug::text(' DID NOT Work Over Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'o2':
                     //Over Weekly Time.
                 //Over Weekly Time.
                 case 's9':
                     //Over Weekly Scheduled Time.
                     if ($plf->getRecordCount() > 0) {
                         //Get Pay Period Schedule info
                         if (is_object($user_date_obj->getPayPeriodObject()) and is_object($user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject())) {
                             $start_week_day_id = $user_date_obj->getPayPeriodObject()->getPayPeriodScheduleObject()->getStartWeekDay();
                         } else {
                             $start_week_day_id = 0;
                         }
                         Debug::text('Start Week Day ID: ' . $start_week_day_id, __FILE__, __LINE__, __METHOD__, 10);
                         $weekly_scheduled_total_time = 0;
                         if (strtolower($ep_obj->getType()) == 's9') {
                             $tmp_slf = new ScheduleListFactory();
                             $tmp_slf->getByUserIdAndStartDateAndEndDate($user_date_obj->getUser(), TTDate::getBeginWeekEpoch($user_date_obj->getDateStamp(), $start_week_day_id), $user_date_obj->getDateStamp());
                             if ($tmp_slf->getRecordCount() > 0) {
                                 foreach ($tmp_slf as $s_obj) {
                                     $weekly_scheduled_total_time += $s_obj->getTotalTime();
                                 }
                             }
                             unset($tmp_slf, $s_obj);
                         }
                         //This ONLY takes in to account WORKED hours, not paid absence hours.
                         $weekly_total_time = 0;
                         //Get daily total time.
                         $udtlf = new UserDateTotalListFactory();
                         $weekly_total_time = $udtlf->getWorkedTimeSumByUserIDAndStartDateAndEndDate($user_date_obj->getUser(), TTDate::getBeginWeekEpoch($user_date_obj->getDateStamp(), $start_week_day_id), $user_date_obj->getDateStamp());
                         Debug::text(' Weekly Total Time: ' . $weekly_total_time . ' Weekly Scheduled Total Time: ' . $weekly_scheduled_total_time . ' Watch Window: ' . $ep_obj->getWatchWindow() . ' Grace: ' . $ep_obj->getGrace() . ' User Date ID: ' . $user_date_id, __FILE__, __LINE__, __METHOD__, 10);
                         if (strtolower($ep_obj->getType()) == 'o2' and $weekly_total_time > 0 and $weekly_total_time > $ep_obj->getWatchWindow() or strtolower($ep_obj->getType()) == 's9' and $weekly_total_time > 0 and $weekly_total_time > $weekly_scheduled_total_time + $ep_obj->getGrace()) {
                             Debug::text(' Worked Over Weekly Hours', __FILE__, __LINE__, __METHOD__, 10);
                             $ef = new ExceptionFactory();
                             $ef->setUserDateID($user_date_id);
                             $ef->setExceptionPolicyID($ep_obj->getId());
                             $ef->setType($type_id);
                             $ef->setEnableDemerits(TRUE);
                             if ($ef->isValid()) {
                                 if ($enable_premature_exceptions == TRUE) {
                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                 }
                                 $ef->Save();
                             }
                         } else {
                             Debug::text(' DID NOT Work Over Scheduled Hours', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'l1':
                     //Long Lunch
                 //Long Lunch
                 case 'l2':
                     //Short Lunch
                     if ($plf->getRecordCount() > 0) {
                         //Get all lunch punches.
                         $pair = 0;
                         $x = 0;
                         $out_for_lunch = FALSE;
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 20 and $p_obj->getType() == 20) {
                                 $lunch_out_timestamp = $p_obj->getTimeStamp();
                                 $lunch_punch_arr[$pair]['punch_id'] = $p_obj->getId();
                                 $out_for_lunch = TRUE;
                             } elseif ($out_for_lunch == TRUE and $p_obj->getStatus() == 10 and $p_obj->getType() == 20) {
                                 $lunch_punch_arr[$pair][20] = $lunch_out_timestamp;
                                 $lunch_punch_arr[$pair][10] = $p_obj->getTimeStamp();
                                 $out_for_lunch = FALSE;
                                 $pair++;
                                 unset($lunch_out_timestamp);
                             } else {
                                 $out_for_lunch = FALSE;
                             }
                         }
                         if (isset($lunch_punch_arr)) {
                             Debug::Arr($lunch_punch_arr, 'Lunch Punch Array: ', __FILE__, __LINE__, __METHOD__, 10);
                             foreach ($lunch_punch_arr as $pair => $time_stamp_arr) {
                                 if (isset($time_stamp_arr[10]) and isset($time_stamp_arr[20])) {
                                     $lunch_total_time = bcsub($time_stamp_arr[10], $time_stamp_arr[20]);
                                     Debug::text(' Lunch Total Time: ' . $lunch_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                     if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                         $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                     }
                                     //Check to see if they have a schedule policy
                                     if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE and is_object($p_obj->getScheduleObject()) == TRUE and is_object($p_obj->getScheduleObject()->getSchedulePolicyObject()) == TRUE) {
                                         $mp_obj = $p_obj->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject();
                                     } else {
                                         $mplf = new MealPolicyListFactory();
                                         $mplf->getByPolicyGroupUserId($user_date_obj->getUserObject()->getId());
                                         if ($mplf->getRecordCount() > 0) {
                                             Debug::text('Found Meal Policy to apply.', __FILE__, __LINE__, __METHOD__, 10);
                                             $mp_obj = $mplf->getCurrent();
                                         }
                                     }
                                     if (isset($mp_obj) and is_object($mp_obj)) {
                                         $meal_policy_lunch_time = $mp_obj->getAmount();
                                         Debug::text('Meal Policy Time: ' . $meal_policy_lunch_time, __FILE__, __LINE__, __METHOD__, 10);
                                         $add_exception = FALSE;
                                         if (strtolower($ep_obj->getType()) == 'l1' and $meal_policy_lunch_time > 0 and $lunch_total_time > 0 and $lunch_total_time > $meal_policy_lunch_time + $ep_obj->getGrace()) {
                                             $add_exception = TRUE;
                                         } elseif (strtolower($ep_obj->getType()) == 'l2' and $meal_policy_lunch_time > 0 and $lunch_total_time > 0 and $lunch_total_time < $meal_policy_lunch_time - $ep_obj->getGrace()) {
                                             $add_exception = TRUE;
                                         }
                                         if ($add_exception == TRUE) {
                                             Debug::text('Adding Exception!', __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             if (isset($time_stamp_arr['punch_id'])) {
                                                 $ef->setPunchID($time_stamp_arr['punch_id']);
                                             }
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('Not Adding Exception!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     }
                                 } else {
                                     Debug::text(' Lunch Punches not paired... Skipping!', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         } else {
                             Debug::text(' No Lunch Punches found, or none are paired.', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'l3':
                     //No Lunch
                     if ($plf->getRecordCount() > 0) {
                         //If they are scheduled or not, we can check for a meal policy and base our
                         //decision off that. We don't want a No Lunch exception on a 3hr shift though.
                         //Also ignore this exception if the lunch is auto-deduct.
                         $daily_total_time = 0;
                         $udtlf = new UserDateTotalListFactory();
                         $udtlf->getByUserDateIdAndStatus($user_date_id, 20);
                         if ($udtlf->getRecordCount() > 0) {
                             foreach ($udtlf as $udt_obj) {
                                 $daily_total_time += $udt_obj->getTotalTime();
                             }
                         }
                         Debug::text('Day Total Time: ' . $daily_total_time, __FILE__, __LINE__, __METHOD__, 10);
                         if ($daily_total_time > 0) {
                             //Check for lunch punch.
                             $lunch_punch = FALSE;
                             foreach ($plf as $p_obj) {
                                 if ($p_obj->getType() == 20) {
                                     Debug::text('Found Lunch Punch: ' . $p_obj->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
                                     $lunch_punch = TRUE;
                                     break;
                                 }
                             }
                             if ($lunch_punch == FALSE) {
                                 Debug::text('DID NOT Find Lunch Punch... Checking meal policies. ', __FILE__, __LINE__, __METHOD__, 10);
                                 //Use scheduled meal policy first.
                                 if ($slf->getRecordCount() > 0) {
                                     Debug::text('Schedule Found...', __FILE__, __LINE__, __METHOD__, 10);
                                     foreach ($slf as $s_obj) {
                                         if ($s_obj->getSchedulePolicyObject() !== FALSE and $s_obj->getSchedulePolicyObject()->getMealPolicyObject() !== FALSE and $s_obj->getSchedulePolicyObject()->getMealPolicyObject()->getType() != 10) {
                                             Debug::text('Found Schedule Meal Policy... Trigger Time: ' . $s_obj->getSchedulePolicyObject()->getMealPolicyObject()->getTriggerTime(), __FILE__, __LINE__, __METHOD__, 10);
                                             if ($daily_total_time > $s_obj->getSchedulePolicyObject()->getMealPolicyObject()->getTriggerTime()) {
                                                 Debug::text('Daily Total Time is After Schedule Meal Policy Trigger Time: ', __FILE__, __LINE__, __METHOD__, 10);
                                                 $ef = new ExceptionFactory();
                                                 $ef->setUserDateID($user_date_id);
                                                 $ef->setExceptionPolicyID($ep_obj->getId());
                                                 $ef->setType($type_id);
                                                 $ef->setEnableDemerits(TRUE);
                                                 if ($ef->isValid()) {
                                                     if ($enable_premature_exceptions == TRUE) {
                                                         $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                     }
                                                     $ef->Save();
                                                 }
                                             }
                                         } else {
                                             Debug::text('Schedule Meal Policy does not exist, or is auto-deduct?', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     }
                                 } else {
                                     Debug::text('No Schedule Found...', __FILE__, __LINE__, __METHOD__, 10);
                                     //Check if they have a meal policy, with no schedule.
                                     $mplf = new MealPolicyListFactory();
                                     $mplf->getByPolicyGroupUserId($user_date_obj->getUser());
                                     if ($mplf->getRecordCount() > 0) {
                                         Debug::text('Found UnScheduled Meal Policy...', __FILE__, __LINE__, __METHOD__, 10);
                                         $m_obj = $mplf->getCurrent();
                                         if ($daily_total_time > $m_obj->getTriggerTime() and $m_obj->getType() == 20) {
                                             Debug::text('Daily Total Time is After Schedule Meal Policy Trigger Time: ' . $m_obj->getTriggerTime(), __FILE__, __LINE__, __METHOD__, 10);
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setType($type_id);
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('Auto-deduct meal policy, ignorning this exception.', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         //There is no  meal policy or schedule policy with a meal policy assigned to it
                                         //With out this we could still apply No Lunch exceptions, but they will happen even on
                                         //a 2minute shift.
                                         Debug::text('No meal policy, applying No Lunch exception.', __FILE__, __LINE__, __METHOD__, 10);
                                         $ef = new ExceptionFactory();
                                         $ef->setUserDateID($user_date_id);
                                         $ef->setExceptionPolicyID($ep_obj->getId());
                                         $ef->setType($type_id);
                                         $ef->setEnableDemerits(TRUE);
                                         if ($ef->isValid()) {
                                             if ($enable_premature_exceptions == TRUE) {
                                                 $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                             }
                                             $ef->Save();
                                         }
                                     }
                                 }
                             } else {
                                 Debug::text('Found Lunch Punch... Ignoring this exception. ', __FILE__, __LINE__, __METHOD__, 10);
                             }
                         }
                     }
                     break;
                 case 'b1':
                     //Long Break
                 //Long Break
                 case 'b2':
                     //Short Break
                     if ($plf->getRecordCount() > 0) {
                         //Get all break punches.
                         $pair = 0;
                         $x = 0;
                         $out_for_break = FALSE;
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 20 and $p_obj->getType() == 30) {
                                 $break_out_timestamp = $p_obj->getTimeStamp();
                                 $break_punch_arr[$pair]['punch_id'] = $p_obj->getId();
                                 $out_for_break = TRUE;
                             } elseif ($out_for_break == TRUE and $p_obj->getStatus() == 10 and $p_obj->getType() == 30) {
                                 $break_punch_arr[$pair][20] = $break_out_timestamp;
                                 $break_punch_arr[$pair][10] = $p_obj->getTimeStamp();
                                 $out_for_break = FALSE;
                                 $pair++;
                                 unset($break_out_timestamp);
                             } else {
                                 $out_for_break = FALSE;
                             }
                         }
                         unset($pair);
                         if (isset($break_punch_arr)) {
                             Debug::Arr($break_punch_arr, 'Break Punch Array: ', __FILE__, __LINE__, __METHOD__, 10);
                             foreach ($break_punch_arr as $pair => $time_stamp_arr) {
                                 if (isset($time_stamp_arr[10]) and isset($time_stamp_arr[20])) {
                                     $break_total_time = bcsub($time_stamp_arr[10], $time_stamp_arr[20]);
                                     Debug::text(' Break Total Time: ' . $break_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                     if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                         $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                     }
                                     //Check to see if they have a schedule policy
                                     $bplf = new BreakPolicyListFactory();
                                     if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE and is_object($p_obj->getScheduleObject()) == TRUE and is_object($p_obj->getScheduleObject()->getSchedulePolicyObject()) == TRUE) {
                                         $break_policy_ids = $p_obj->getScheduleObject()->getSchedulePolicyObject()->getBreakPolicyObject();
                                         $bplf->getByIdAndCompanyId($break_policy_ids, $user_date_obj->getUserObject()->getCompany());
                                     } else {
                                         $bplf->getByPolicyGroupUserId($user_date_obj->getUser());
                                     }
                                     unset($break_policy_ids);
                                     if ($bplf->getRecordCount() > 0) {
                                         Debug::text('Found Break Policy(ies) to apply: ' . $bplf->getRecordCount() . ' Pair: ' . $pair, __FILE__, __LINE__, __METHOD__, 10);
                                         foreach ($bplf as $bp_obj) {
                                             $bp_objs[] = $bp_obj;
                                         }
                                         unset($bplf, $bp_obj);
                                         if (isset($bp_objs[$pair]) and is_object($bp_objs[$pair])) {
                                             $bp_obj = $bp_objs[$pair];
                                             $break_policy_break_time = $bp_obj->getAmount();
                                             Debug::text('Break Policy Time: ' . $break_policy_break_time . ' ID: ' . $bp_obj->getID(), __FILE__, __LINE__, __METHOD__, 10);
                                             $add_exception = FALSE;
                                             if (strtolower($ep_obj->getType()) == 'b1' and $break_policy_break_time > 0 and $break_total_time > 0 and $break_total_time > $break_policy_break_time + $ep_obj->getGrace()) {
                                                 $add_exception = TRUE;
                                             } elseif (strtolower($ep_obj->getType()) == 'b2' and $break_policy_break_time > 0 and $break_total_time > 0 and $break_total_time < $break_policy_break_time - $ep_obj->getGrace()) {
                                                 $add_exception = TRUE;
                                             }
                                             if ($add_exception == TRUE) {
                                                 Debug::text('Adding Exception! ' . $ep_obj->getType(), __FILE__, __LINE__, __METHOD__, 10);
                                                 $ef = new ExceptionFactory();
                                                 $ef->setUserDateID($user_date_id);
                                                 $ef->setExceptionPolicyID($ep_obj->getId());
                                                 if (isset($time_stamp_arr['punch_id'])) {
                                                     $ef->setPunchID($time_stamp_arr['punch_id']);
                                                 }
                                                 $ef->setType($type_id);
                                                 $ef->setEnableDemerits(TRUE);
                                                 if ($ef->isValid()) {
                                                     if ($enable_premature_exceptions == TRUE) {
                                                         $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                     }
                                                     $ef->Save();
                                                 }
                                             } else {
                                                 Debug::text('Not Adding Exception!', __FILE__, __LINE__, __METHOD__, 10);
                                             }
                                             unset($bp_obj);
                                         }
                                         unset($bp_objs);
                                     }
                                 } else {
                                     Debug::text(' Break Punches not paired... Skipping!', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         } else {
                             Debug::text(' No Break Punches found, or none are paired.', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     break;
                 case 'b3':
                     //Too Many Breaks
                 //Too Many Breaks
                 case 'b4':
                     //Too Few Breaks
                     if ($plf->getRecordCount() > 0) {
                         //Get all break punches.
                         $pair = 0;
                         $x = 0;
                         $out_for_break = FALSE;
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 20 and $p_obj->getType() == 30) {
                                 $break_out_timestamp = $p_obj->getTimeStamp();
                                 $break_punch_arr[$pair]['punch_id'] = $p_obj->getId();
                                 $out_for_break = TRUE;
                             } elseif ($out_for_break == TRUE and $p_obj->getStatus() == 10 and $p_obj->getType() == 30) {
                                 $break_punch_arr[$pair][20] = $break_out_timestamp;
                                 $break_punch_arr[$pair][10] = $p_obj->getTimeStamp();
                                 $out_for_break = FALSE;
                                 $pair++;
                                 unset($break_out_timestamp);
                             } else {
                                 $out_for_break = FALSE;
                             }
                         }
                         unset($pair);
                         if (isset($break_punch_arr)) {
                             $total_breaks = count($break_punch_arr);
                             Debug::Arr($break_punch_arr, 'Break Punch Array: ', __FILE__, __LINE__, __METHOD__, 10);
                             foreach ($break_punch_arr as $pair => $time_stamp_arr) {
                                 if (isset($time_stamp_arr[10]) and isset($time_stamp_arr[20])) {
                                     $break_total_time = bcsub($time_stamp_arr[10], $time_stamp_arr[20]);
                                     Debug::text(' Break Total Time: ' . $break_total_time, __FILE__, __LINE__, __METHOD__, 10);
                                     if (!isset($scheduled_id_cache[$p_obj->getID()])) {
                                         $scheduled_id_cache[$p_obj->getID()] = $p_obj->findScheduleID(NULL, $user_date_obj->getUser());
                                     }
                                     //Check to see if they have a schedule policy
                                     $bplf = new BreakPolicyListFactory();
                                     if ($p_obj->setScheduleID($scheduled_id_cache[$p_obj->getID()]) == TRUE and is_object($p_obj->getScheduleObject()) == TRUE and is_object($p_obj->getScheduleObject()->getSchedulePolicyObject()) == TRUE) {
                                         $break_policy_ids = $p_obj->getScheduleObject()->getSchedulePolicyObject()->getBreakPolicyObject();
                                         $bplf->getByIdAndCompanyId($break_policy_ids, $user_date_obj->getUserObject()->getCompany());
                                     } else {
                                         $bplf->getByPolicyGroupUserId($user_date_obj->getUser());
                                     }
                                     unset($break_policy_ids);
                                     $allowed_breaks = $bplf->getRecordCount();
                                     $add_exception = FALSE;
                                     if (strtolower($ep_obj->getType()) == 'b3' and $total_breaks > $allowed_breaks) {
                                         Debug::text(' Too many breaks taken...', __FILE__, __LINE__, __METHOD__, 10);
                                         $add_exception = TRUE;
                                     } elseif (strtolower($ep_obj->getType()) == 'b4' and $total_breaks < $allowed_breaks) {
                                         Debug::text(' Too few breaks taken...', __FILE__, __LINE__, __METHOD__, 10);
                                         $add_exception = TRUE;
                                     } else {
                                         Debug::text(' Proper number of breaks taken...', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                     if ($add_exception == TRUE and (strtolower($ep_obj->getType()) == 'b4' or strtolower($ep_obj->getType()) == 'b3' and $pair > $allowed_breaks - 1)) {
                                         Debug::text('Adding Exception! ' . $ep_obj->getType(), __FILE__, __LINE__, __METHOD__, 10);
                                         $ef = new ExceptionFactory();
                                         $ef->setUserDateID($user_date_id);
                                         $ef->setExceptionPolicyID($ep_obj->getId());
                                         if (isset($time_stamp_arr['punch_id']) and strtolower($ep_obj->getType()) == 'b3') {
                                             $ef->setPunchID($time_stamp_arr['punch_id']);
                                         }
                                         $ef->setType($type_id);
                                         $ef->setEnableDemerits(TRUE);
                                         if ($ef->isValid()) {
                                             if ($enable_premature_exceptions == TRUE) {
                                                 $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                             }
                                             $ef->Save();
                                         }
                                     } else {
                                         Debug::text('Not Adding Exception!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 }
                             }
                         }
                     }
                     break;
                 case 'j1':
                     //Not Allowed on Job
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 10) {
                                 //In punches
                                 if (is_object($p_obj->getPunchControlObject()) and $p_obj->getPunchControlObject()->getJob() > 0) {
                                     //Found job punch, check job settings.
                                     $jlf = new JobListFactory();
                                     $jlf->getById($p_obj->getPunchControlObject()->getJob());
                                     if ($jlf->getRecordCount() > 0) {
                                         $j_obj = $jlf->getCurrent();
                                         if ($j_obj->isAllowedUser($user_date_obj->getUser()) == FALSE) {
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setType($type_id);
                                             $ef->setPunchControlId($p_obj->getPunchControlId());
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;User allowed on Job!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job not found!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Not a Job Punch...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($j_obj);
                     }
                     break;
                 case 'j2':
                     //Not Allowed on Task
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 10) {
                                 //In punches
                                 if (is_object($p_obj->getPunchControlObject()) and $p_obj->getPunchControlObject()->getJob() > 0 and $p_obj->getPunchControlObject()->getJobItem() > 0) {
                                     //Found job punch, check job settings.
                                     $jlf = new JobListFactory();
                                     $jlf->getById($p_obj->getPunchControlObject()->getJob());
                                     if ($jlf->getRecordCount() > 0) {
                                         $j_obj = $jlf->getCurrent();
                                         if ($j_obj->isAllowedItem($p_obj->getPunchControlObject()->getJobItem()) == FALSE) {
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setType($type_id);
                                             $ef->setPunchControlId($p_obj->getPunchControlId());
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job item allowed on job!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job not found!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Not a Job Punch...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($j_obj);
                     }
                     break;
                 case 'j3':
                     //Job already completed
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             if ($p_obj->getStatus() == 10) {
                                 //In punches
                                 if (is_object($p_obj->getPunchControlObject()) and $p_obj->getPunchControlObject()->getJob() > 0) {
                                     //Found job punch, check job settings.
                                     $jlf = new JobListFactory();
                                     $jlf->getById($p_obj->getPunchControlObject()->getJob());
                                     if ($jlf->getRecordCount() > 0) {
                                         $j_obj = $jlf->getCurrent();
                                         //Status is completed and the User Date Stamp is greater then the job end date.
                                         //If no end date is set, ignore this.
                                         if ($j_obj->getStatus() == 30 and $j_obj->getEndDate() != FALSE and $user_date_obj->getDateStamp() > $j_obj->getEndDate()) {
                                             $ef = new ExceptionFactory();
                                             $ef->setUserDateID($user_date_id);
                                             $ef->setExceptionPolicyID($ep_obj->getId());
                                             $ef->setType($type_id);
                                             $ef->setPunchControlId($p_obj->getPunchControlId());
                                             $ef->setEnableDemerits(TRUE);
                                             if ($ef->isValid()) {
                                                 if ($enable_premature_exceptions == TRUE) {
                                                     $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                                 }
                                                 $ef->Save();
                                             }
                                         } else {
                                             Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job Not Completed!', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Job not found!', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;Not a Job Punch...', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                             }
                         }
                         unset($j_obj);
                     }
                     break;
                 case 'j4':
                     //No Job or Task
                     if ($plf->getRecordCount() > 0) {
                         foreach ($plf as $p_obj) {
                             //In punches only
                             if ($p_obj->getStatus() == 10 and is_object($p_obj->getPunchControlObject()) and ($p_obj->getPunchControlObject()->getJob() == '' or $p_obj->getPunchControlObject()->getJob() == 0 or $p_obj->getPunchControlObject()->getJob() == FALSE or $p_obj->getPunchControlObject()->getJobItem() == '' or $p_obj->getPunchControlObject()->getJobItem() == 0 or $p_obj->getPunchControlObject()->getJobItem() == FALSE)) {
                                 $ef = new ExceptionFactory();
                                 $ef->setUserDateID($user_date_id);
                                 $ef->setExceptionPolicyID($ep_obj->getId());
                                 $ef->setType($type_id);
                                 $ef->setPunchControlId($p_obj->getPunchControlId());
                                 $ef->setPunchId($p_obj->getId());
                                 $ef->setEnableDemerits(TRUE);
                                 if ($ef->isValid()) {
                                     if ($enable_premature_exceptions == TRUE) {
                                         $ef->emailException($user_date_obj->getUserObject(), $user_date_obj, $ep_obj);
                                     }
                                     $ef->Save();
                                 }
                             }
                         }
                     }
                     break;
                 default:
                     Debug::text('BAD, should never get here: ', __FILE__, __LINE__, __METHOD__, 10);
                     break;
             }
         }
     }
     $profiler->stopTimer("ExceptionPolicy::calcExceptions()");
     return TRUE;
 }
Exemple #16
0
    //Redirect
}
$smarty->assign('title', TTi18n::gettext($title = 'My Schedule'));
// See index.php
//BreadCrumb::setCrumb($title);
/*
 * Get FORM variables
 */
extract(FormVariables::GetVariables(array('action', 'page', 'sort_column', 'sort_order', 'filter_data', 'serialize_filter_data')));
URLBuilder::setURL($_SERVER['SCRIPT_NAME'], array('sort_column' => $sort_column, 'sort_order' => $sort_order, 'page' => $page));
//Data is coming in serialized from Schedule Month.
$serialize_filter_data = unserialize(base64_decode(urldecode($serialize_filter_data)));
if (isset($filter_data['start_date']) and $filter_data['start_date'] != '') {
    $filter_data['start_date'] = TTDate::parseDateTime($filter_data['start_date']);
} else {
    $filter_data['start_date'] = TTDate::getBeginWeekEpoch(time());
}
$filter_data = array_merge($serialize_filter_data, $filter_data);
//Get Permission Hierarchy Children first, as this can be used for viewing, or editing.
$hlf = TTnew('HierarchyListFactory');
$permission_children_ids = $hlf->getHierarchyChildrenByCompanyIdAndUserIdAndObjectTypeID($current_company->getId(), $current_user->getId());
if ($permission->Check('schedule', 'view') == FALSE) {
    if ($permission->Check('schedule', 'view_child') == FALSE) {
        $permission_children_ids = array();
    }
    if ($permission->Check('schedule', 'view_own')) {
        $permission_children_ids[] = $current_user->getId();
    }
    $filter_data['permission_children_ids'] = $permission_children_ids;
}
$action = Misc::findSubmitButton();
 function testHolidayAndDailyOverTimePolicyA()
 {
     global $dd;
     $date_epoch = TTDate::getBeginWeekEpoch(time());
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     //Holiday
     $policy_ids['holiday'][] = $this->createHolidayPolicy($this->company_id, 10);
     $this->createHoliday($this->company_id, 10, $date_epoch, $policy_ids['holiday'][0]);
     //Daily
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 100);
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 110);
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 120);
     //Holiday overtime policy
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 510);
     //Create Policy Group
     $dd->createPolicyGroup($this->company_id, NULL, NULL, $policy_ids['holiday'], $policy_ids['overtime'], NULL, NULL, array($this->user_id));
     //
     //Day of Week: 1
     //
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:00AM'), strtotime($date_stamp . ' 8:00PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //print_r($udt_arr);
     //Total Time
     $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 12 * 3600);
     //Holiday Time
     $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 12 * 3600);
     return TRUE;
 }
Exemple #18
0
 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;
 }
 function testBreakPunchTimeWindowD()
 {
     global $dd;
     $policy_ids['break'][] = $this->createBreakPolicy($this->company_id, 110);
     //Create Policy Group
     $dd->createPolicyGroup($this->company_id, NULL, NULL, NULL, NULL, NULL, NULL, array($this->user_id), $policy_ids['break']);
     $date_epoch = TTDate::getBeginWeekEpoch(time());
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $dd->createPunch($this->user_id, 10, 10, strtotime($date_stamp . ' 8:00AM'), array('branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $punch_time = strtotime($date_stamp . ' 10:00AM');
     $prev_punch_obj = $this->getPreviousPunch($punch_time);
     $punch_type_id = $prev_punch_obj->getNextType($punch_time);
     $punch_status_id = $prev_punch_obj->getNextStatus();
     $this->assertEquals($punch_type_id, 10);
     //Normal - Because when using punch time it can't be detected on the first out punch.
     $this->assertEquals($punch_status_id, 20);
     //Out
     $dd->createPunch($this->user_id, $punch_type_id, $punch_status_id, $punch_time, array('branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $punch_time = strtotime($date_stamp . ' 10:15AM');
     $prev_punch_obj = $this->getPreviousPunch($punch_time);
     $punch_type_id = $prev_punch_obj->getNextType($punch_time);
     $punch_status_id = $prev_punch_obj->getNextStatus();
     $this->assertEquals($punch_type_id, 30);
     //Break
     $this->assertEquals($punch_status_id, 10);
     //In
     $dd->createPunch($this->user_id, $punch_type_id, $punch_status_id, $punch_time, array('branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $punch_time = strtotime($date_stamp . ' 2:00PM');
     $prev_punch_obj = $this->getPreviousPunch($punch_time);
     $punch_type_id = $prev_punch_obj->getNextType($punch_time);
     $punch_status_id = $prev_punch_obj->getNextStatus();
     $this->assertEquals($punch_type_id, 10);
     //Normal - Because when using punch time it can't be detected on the first out punch.
     $this->assertEquals($punch_status_id, 20);
     //Out
     $dd->createPunch($this->user_id, $punch_type_id, $punch_status_id, $punch_time, array('branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $punch_time = strtotime($date_stamp . ' 2:15PM');
     $prev_punch_obj = $this->getPreviousPunch($punch_time);
     $punch_type_id = $prev_punch_obj->getNextType($punch_time);
     $punch_status_id = $prev_punch_obj->getNextStatus();
     $this->assertEquals($punch_type_id, 30);
     //Break
     $this->assertEquals($punch_status_id, 10);
     //In
     $dd->createPunch($this->user_id, $punch_type_id, $punch_status_id, $punch_time, array('branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $punch_time = strtotime($date_stamp . ' 5:00PM');
     $prev_punch_obj = $this->getPreviousPunch($punch_time);
     $punch_type_id = $prev_punch_obj->getNextType($punch_time);
     $punch_status_id = $prev_punch_obj->getNextStatus();
     $this->assertEquals($punch_type_id, 10);
     //Normal
     $this->assertEquals($punch_status_id, 20);
     //Out
     $dd->createPunch($this->user_id, $punch_type_id, $punch_status_id, $punch_time, array('branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $punch_arr = $this->getPunchDataArray(TTDate::getBeginDayEpoch($date_epoch), TTDate::getEndDayEpoch($date_epoch));
     //print_r($punch_arr);
     $this->assertEquals(3, count($punch_arr[$date_epoch]));
     $this->assertEquals($date_epoch, $punch_arr[$date_epoch][0]['date_stamp']);
     $this->assertEquals(6, count($punch_arr[$date_epoch][0]['shift_data']['punches']));
     $this->assertEquals(10, $punch_arr[$date_epoch][0]['shift_data']['punches'][0]['type_id']);
     $this->assertEquals(10, $punch_arr[$date_epoch][0]['shift_data']['punches'][0]['status_id']);
     $this->assertEquals(30, $punch_arr[$date_epoch][0]['shift_data']['punches'][1]['type_id']);
     $this->assertEquals(20, $punch_arr[$date_epoch][0]['shift_data']['punches'][1]['status_id']);
     $this->assertEquals(30, $punch_arr[$date_epoch][0]['shift_data']['punches'][2]['type_id']);
     $this->assertEquals(10, $punch_arr[$date_epoch][0]['shift_data']['punches'][2]['status_id']);
     $this->assertEquals(30, $punch_arr[$date_epoch][0]['shift_data']['punches'][3]['type_id']);
     $this->assertEquals(20, $punch_arr[$date_epoch][0]['shift_data']['punches'][3]['status_id']);
     $this->assertEquals(30, $punch_arr[$date_epoch][0]['shift_data']['punches'][4]['type_id']);
     $this->assertEquals(10, $punch_arr[$date_epoch][0]['shift_data']['punches'][4]['status_id']);
     $this->assertEquals(10, $punch_arr[$date_epoch][0]['shift_data']['punches'][5]['type_id']);
     $this->assertEquals(20, $punch_arr[$date_epoch][0]['shift_data']['punches'][5]['status_id']);
     return TRUE;
 }
             Redirect::Page(URLBuilder::getURL(NULL, 'RecurringScheduleControlList.php'));
             break;
         }
     }
 default:
     if (isset($id)) {
         BreadCrumb::setCrumb($title);
         $rsclf = new RecurringScheduleControlListFactory();
         $rsclf->getByIdAndCompanyId($id, $current_company->getID());
         foreach ($rsclf as $rsc_obj) {
             //Debug::Arr($station,'Department', __FILE__, __LINE__, __METHOD__,10);
             $data = array('id' => $rsc_obj->getId(), 'template_id' => $rsc_obj->getRecurringScheduleTemplateControl(), 'start_week' => $rsc_obj->getStartWeek(), 'start_date' => $rsc_obj->getStartDate(), 'end_date' => $rsc_obj->getEndDate(), 'auto_fill' => $rsc_obj->getAutoFill(), 'user_ids' => $rsc_obj->getUser(), 'created_date' => $rsc_obj->getCreatedDate(), 'created_by' => $rsc_obj->getCreatedBy(), 'updated_date' => $rsc_obj->getUpdatedDate(), 'updated_by' => $rsc_obj->getUpdatedBy(), 'deleted_date' => $rsc_obj->getDeletedDate(), 'deleted_by' => $rsc_obj->getDeletedBy());
         }
     } elseif ($action != 'submit') {
         Debug::Text('New Schedule', __FILE__, __LINE__, __METHOD__, 10);
         $data = array('start_week' => 1, 'start_date' => TTDate::getBeginWeekEpoch(TTDate::getTime()), 'end_date' => NULL);
     }
     //Select box options;
     $ulf = new UserListFactory();
     $ulf->getSearchByCompanyIdAndArrayCriteria($current_company->getId(), $filter_data);
     $user_options = UserListFactory::getArrayByListFactory($ulf, FALSE, TRUE);
     //$user_options = $ulf->getByCompanyIDArray( $current_company->getId(), TRUE );
     $rstclf = new RecurringScheduleTemplateControlListFactory();
     $template_options = $rstclf->getByCompanyIdArray($current_company->getId());
     //Select box options;
     $data['template_options'] = $template_options;
     $data['user_options'] = $user_options;
     if (isset($data['user_ids']) and is_array($data['user_ids'])) {
         $tmp_user_options = $user_options;
         foreach ($data['user_ids'] as $user_id) {
             if (isset($tmp_user_options[$user_id])) {
 function testHolidayAndDailyAndWeeklyOverTimePolicyA()
 {
     global $dd;
     $date_epoch = TTDate::getBeginWeekEpoch(time());
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     //Holiday
     $policy_ids['holiday'][] = $this->createHolidayPolicy($this->company_id, 10);
     $this->createHoliday($this->company_id, 10, $date_epoch, $policy_ids['holiday'][0]);
     //Daily
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 100);
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 110);
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 120);
     //Weekly
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 230);
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 240);
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 250);
     //Holiday overtime policy
     $policy_ids['overtime'][] = $this->createOverTimePolicy($this->company_id, 500);
     //Create Policy Group
     $dd->createPolicyGroup($this->company_id, NULL, NULL, $policy_ids['holiday'], $policy_ids['overtime'], NULL, NULL, array($this->user_id));
     //
     //Day of Week: 1
     //
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:00AM'), strtotime($date_stamp . ' 8:00PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //Total Time
     $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 12 * 3600);
     //Holiday Time
     $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 8 * 3600);
     //Overtime 1
     $this->assertEquals($udt_arr[$date_epoch][4]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][4]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][4]['over_time_policy_id'], $policy_ids['overtime'][0]);
     $this->assertEquals($udt_arr[$date_epoch][4]['total_time'], 1 * 3600);
     //Overtime 2
     $this->assertEquals($udt_arr[$date_epoch][3]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][3]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][3]['over_time_policy_id'], $policy_ids['overtime'][1]);
     $this->assertEquals($udt_arr[$date_epoch][3]['total_time'], 1 * 3600);
     //Overtime 3
     $this->assertEquals($udt_arr[$date_epoch][2]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][2]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][2]['over_time_policy_id'], $policy_ids['overtime'][2]);
     $this->assertEquals($udt_arr[$date_epoch][2]['total_time'], 2 * 3600);
     //
     //Day of Week: 2
     //
     $date_epoch = TTDate::getBeginDayEpoch(TTDate::getBeginWeekEpoch(time()) + (1 * 86400 + 3601));
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:00AM'), strtotime($date_stamp . ' 8:00PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //Total Time
     $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 12 * 3600);
     //Regular Time
     $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 20);
     $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 8 * 3600);
     //Overtime 1
     $this->assertEquals($udt_arr[$date_epoch][4]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][4]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][4]['over_time_policy_id'], $policy_ids['overtime'][0]);
     $this->assertEquals($udt_arr[$date_epoch][4]['total_time'], 1 * 3600);
     //Overtime 2
     $this->assertEquals($udt_arr[$date_epoch][3]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][3]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][3]['over_time_policy_id'], $policy_ids['overtime'][1]);
     $this->assertEquals($udt_arr[$date_epoch][3]['total_time'], 1 * 3600);
     //Overtime 3
     $this->assertEquals($udt_arr[$date_epoch][2]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][2]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][2]['over_time_policy_id'], $policy_ids['overtime'][2]);
     $this->assertEquals($udt_arr[$date_epoch][2]['total_time'], 2 * 3600);
     //
     //Day of Week: 3
     //
     $date_epoch = TTDate::getBeginDayEpoch(TTDate::getBeginWeekEpoch(time()) + (2 * 86400 + 3601));
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:00AM'), strtotime($date_stamp . ' 8:00PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //Total Time
     $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 12 * 3600);
     //Regular Time
     $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 20);
     $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 8 * 3600);
     //Overtime 1
     $this->assertEquals($udt_arr[$date_epoch][4]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][4]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][4]['over_time_policy_id'], $policy_ids['overtime'][0]);
     $this->assertEquals($udt_arr[$date_epoch][4]['total_time'], 1 * 3600);
     //Overtime 2
     $this->assertEquals($udt_arr[$date_epoch][3]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][3]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][3]['over_time_policy_id'], $policy_ids['overtime'][1]);
     $this->assertEquals($udt_arr[$date_epoch][3]['total_time'], 1 * 3600);
     //Overtime 3
     $this->assertEquals($udt_arr[$date_epoch][2]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][2]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][2]['over_time_policy_id'], $policy_ids['overtime'][2]);
     $this->assertEquals($udt_arr[$date_epoch][2]['total_time'], 2 * 3600);
     //
     //Day of Week: 4
     //
     $date_epoch = TTDate::getBeginDayEpoch(TTDate::getBeginWeekEpoch(time()) + (3 * 86400 + 3601));
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:00AM'), strtotime($date_stamp . ' 8:00PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //print_r($udt_arr);
     //Total Time
     $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 12 * 3600);
     //Regular Time
     $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 20);
     $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 8 * 3600);
     //Overtime 1
     $this->assertEquals($udt_arr[$date_epoch][4]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][4]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][4]['over_time_policy_id'], $policy_ids['overtime'][0]);
     $this->assertEquals($udt_arr[$date_epoch][4]['total_time'], 1 * 3600);
     //Overtime 2
     $this->assertEquals($udt_arr[$date_epoch][3]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][3]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][3]['over_time_policy_id'], $policy_ids['overtime'][1]);
     $this->assertEquals($udt_arr[$date_epoch][3]['total_time'], 1 * 3600);
     //Overtime 3
     $this->assertEquals($udt_arr[$date_epoch][2]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][2]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][2]['over_time_policy_id'], $policy_ids['overtime'][2]);
     $this->assertEquals($udt_arr[$date_epoch][2]['total_time'], 2 * 3600);
     //
     //Day of Week: 5
     //
     $date_epoch = TTDate::getBeginDayEpoch(TTDate::getBeginWeekEpoch(time()) + (4 * 86400 + 3601));
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:00AM'), strtotime($date_stamp . ' 8:00PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //print_r($udt_arr);
     //Total Time
     $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 12 * 3600);
     //Regular Time
     $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 20);
     $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 7 * 3600);
     //Weekly Overtime 1
     $this->assertEquals($udt_arr[$date_epoch][2]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][2]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][2]['over_time_policy_id'], $policy_ids['overtime'][3]);
     $this->assertEquals($udt_arr[$date_epoch][2]['total_time'], 1 * 3600);
     //Overtime 1
     $this->assertEquals($udt_arr[$date_epoch][5]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][5]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][5]['over_time_policy_id'], $policy_ids['overtime'][0]);
     $this->assertEquals($udt_arr[$date_epoch][5]['total_time'], 1 * 3600);
     //Overtime 2
     $this->assertEquals($udt_arr[$date_epoch][4]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][4]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][4]['over_time_policy_id'], $policy_ids['overtime'][1]);
     $this->assertEquals($udt_arr[$date_epoch][4]['total_time'], 1 * 3600);
     //Overtime 3
     $this->assertEquals($udt_arr[$date_epoch][3]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][3]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][3]['over_time_policy_id'], $policy_ids['overtime'][2]);
     $this->assertEquals($udt_arr[$date_epoch][3]['total_time'], 2 * 3600);
     //
     //Day of Week: 6
     //
     $date_epoch = TTDate::getBeginDayEpoch(TTDate::getBeginWeekEpoch(time()) + (5 * 86400 + 3601));
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:00AM'), strtotime($date_stamp . ' 8:00PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //print_r($udt_arr);
     //Total Time
     $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 12 * 3600);
     //Weekly Overtime 1
     $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][1]['over_time_policy_id'], $policy_ids['overtime'][4]);
     $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 1 * 3600);
     //Weekly Overtime 2
     $this->assertEquals($udt_arr[$date_epoch][2]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][2]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][2]['over_time_policy_id'], $policy_ids['overtime'][3]);
     $this->assertEquals($udt_arr[$date_epoch][2]['total_time'], 7 * 3600);
     //Overtime 1
     $this->assertEquals($udt_arr[$date_epoch][5]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][5]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][5]['over_time_policy_id'], $policy_ids['overtime'][0]);
     $this->assertEquals($udt_arr[$date_epoch][5]['total_time'], 1 * 3600);
     //Overtime 2
     $this->assertEquals($udt_arr[$date_epoch][4]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][4]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][4]['over_time_policy_id'], $policy_ids['overtime'][1]);
     $this->assertEquals($udt_arr[$date_epoch][4]['total_time'], 1 * 3600);
     //Overtime 3
     $this->assertEquals($udt_arr[$date_epoch][3]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][3]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][3]['over_time_policy_id'], $policy_ids['overtime'][2]);
     $this->assertEquals($udt_arr[$date_epoch][3]['total_time'], 2 * 3600);
     //
     //Day of Week: 7
     //
     $date_epoch = TTDate::getBeginDayEpoch(TTDate::getBeginWeekEpoch(time()) + (6 * 86400 + 3601));
     $date_stamp = TTDate::getDate('DATE', $date_epoch);
     $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 8:00AM'), strtotime($date_stamp . ' 8:00PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE);
     $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch);
     //print_r($udt_arr);
     //Total Time
     $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 12 * 3600);
     //Weekly Overtime 2
     $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][1]['over_time_policy_id'], $policy_ids['overtime'][5]);
     $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 1 * 3600);
     //Weekly Overtime 3
     $this->assertEquals($udt_arr[$date_epoch][2]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][2]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][2]['over_time_policy_id'], $policy_ids['overtime'][4]);
     $this->assertEquals($udt_arr[$date_epoch][2]['total_time'], 7 * 3600);
     //Overtime 1
     $this->assertEquals($udt_arr[$date_epoch][5]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][5]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][5]['over_time_policy_id'], $policy_ids['overtime'][0]);
     $this->assertEquals($udt_arr[$date_epoch][5]['total_time'], 1 * 3600);
     //Overtime 2
     $this->assertEquals($udt_arr[$date_epoch][4]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][4]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][4]['over_time_policy_id'], $policy_ids['overtime'][1]);
     $this->assertEquals($udt_arr[$date_epoch][4]['total_time'], 1 * 3600);
     //Overtime 3
     $this->assertEquals($udt_arr[$date_epoch][3]['status_id'], 10);
     $this->assertEquals($udt_arr[$date_epoch][3]['type_id'], 30);
     $this->assertEquals($udt_arr[$date_epoch][3]['over_time_policy_id'], $policy_ids['overtime'][2]);
     $this->assertEquals($udt_arr[$date_epoch][3]['total_time'], 2 * 3600);
     return TRUE;
 }
 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;
 }
 /**
  * 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 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;
 }
 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;
 }
             $end_date = $start_date + 86400 * 90;
         }
     }
 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();
    }
    if ($permission->Check('schedule', 'view_own')) {
        $permission_children_ids[] = $current_user->getId();
    }
    $filter_data['permission_children_ids'] = $permission_children_ids;
}
$do = Misc::findSubmitButton('do');
switch ($do) {
    case 'view_schedule':
    default:
        $user_ids = array();
        if ($filter_data['start_date'] != '' and $filter_data['show_days'] != '') {
            $start_date = $filter_data['start_date'] = TTDate::getBeginDayEpoch(TTDate::parseDateTime($filter_data['start_date']));
            $end_date = $filter_data['end_date'] = $start_date + ($filter_data['show_days'] * 86400 - 3601);
        } else {
            $start_date = $filter_data['start_date'] = TTDate::getBeginWeekEpoch(TTDate::getTime(), $current_user_prefs->getStartWeekDay());
            $end_date = $filter_data['end_date'] = $start_date + $filter_data['show_days'] * (86400 - 3601);
        }
        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');
        $raw_schedule_shifts = $sf->getScheduleArray($filter_data);
        if (is_array($raw_schedule_shifts)) {
            foreach ($raw_schedule_shifts as $day_epoch => $day_schedule_shifts) {
                foreach ($day_schedule_shifts as $day_schedule_shift) {
                    $user_ids[] = $day_schedule_shift['user_id'];
                    $day_schedule_shift['is_owner'] = $permission->isOwner($day_schedule_shift['user_created_by'], $day_schedule_shift['user_id']);
                    $day_schedule_shift['is_child'] = $permission->isChild($day_schedule_shift['user_id'], $permission_children_ids);
                    $tmp_schedule_shifts[$day_epoch][$day_schedule_shift['branch']][$day_schedule_shift['department']][] = $day_schedule_shift;
                    if ($day_schedule_shift['status_id'] == 10) {
                        //Working
                        if (isset($schedule_shift_totals[$day_epoch]['total_time'])) {
Exemple #28
0
 /**
  * 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.
 }