Пример #1
0
 function getSchedule($filter_data, $start_week_day = 0, $group_schedule = FALSE)
 {
     global $current_user, $current_user_prefs;
     //Individual is one schedule per employee, or all on one schedule.
     if (!is_array($filter_data)) {
         return FALSE;
     }
     $current_epoch = time();
     //Debug::Text('Start Date: '. TTDate::getDate('DATE', $start_date) .' End Date: '. TTDate::getDate('DATE', $end_date) , __FILE__, __LINE__, __METHOD__,10);
     Debug::text(' Start Date: ' . TTDate::getDate('DATE+TIME', $filter_data['start_date']) . ' End Date: ' . TTDate::getDate('DATE+TIME', $filter_data['end_date']) . ' Start Week Day: ' . $start_week_day, __FILE__, __LINE__, __METHOD__, 10);
     $pdf = new TTPDF('L', 'pt', 'Letter');
     $left_margin = 20;
     $top_margin = 20;
     $pdf->setMargins($left_margin, $top_margin);
     $pdf->SetAutoPageBreak(TRUE, 30);
     //$pdf->SetAutoPageBreak(FALSE);
     $pdf->SetFont('freesans', '', 10);
     $border = 0;
     $adjust_x = 0;
     $adjust_y = 0;
     if ($group_schedule == FALSE) {
         $valid_schedules = 0;
         $sf = TTnew('ScheduleFactory');
         $tmp_schedule_shifts = $sf->getScheduleArray($filter_data);
         //Re-arrange array by user_id->date
         if (is_array($tmp_schedule_shifts)) {
             foreach ($tmp_schedule_shifts as $day_epoch => $day_schedule_shifts) {
                 foreach ($day_schedule_shifts as $day_schedule_shift) {
                     $raw_schedule_shifts[$day_schedule_shift['user_id']][$day_epoch][] = $day_schedule_shift;
                 }
             }
         }
         unset($tmp_schedule_shifts);
         //Debug::Arr($raw_schedule_shifts, 'Raw Schedule Shifts: ', __FILE__, __LINE__, __METHOD__,10);
         if (isset($raw_schedule_shifts) and is_array($raw_schedule_shifts)) {
             foreach ($raw_schedule_shifts as $user_id => $day_schedule_shifts) {
                 foreach ($day_schedule_shifts as $day_epoch => $day_schedule_shifts) {
                     foreach ($day_schedule_shifts as $day_schedule_shift) {
                         //Debug::Arr($day_schedule_shift, 'aDay Schedule Shift: ', __FILE__, __LINE__, __METHOD__,10);
                         $tmp_schedule_shifts[$day_epoch][$day_schedule_shift['branch']][$day_schedule_shift['department']][] = $day_schedule_shift;
                         if (isset($schedule_shift_totals[$day_epoch]['total_shifts'])) {
                             $schedule_shift_totals[$day_epoch]['total_shifts']++;
                         } else {
                             $schedule_shift_totals[$day_epoch]['total_shifts'] = 1;
                         }
                         //$week_of_year = TTDate::getWeek( strtotime($day_epoch) );
                         $week_of_year = TTDate::getWeek(strtotime($day_epoch), $start_week_day);
                         if (!isset($schedule_shift_totals[$day_epoch]['labels'])) {
                             $schedule_shift_totals[$day_epoch]['labels'] = 0;
                         }
                         if ($day_schedule_shift['branch'] != '--' and !isset($schedule_shift_totals[$day_epoch]['branch'][$day_schedule_shift['branch']])) {
                             $schedule_shift_totals[$day_epoch]['branch'][$day_schedule_shift['branch']] = TRUE;
                             $schedule_shift_totals[$day_epoch]['labels']++;
                         }
                         if ($day_schedule_shift['department'] != '--' and !isset($schedule_shift_totals[$day_epoch]['department'][$day_schedule_shift['branch']][$day_schedule_shift['department']])) {
                             $schedule_shift_totals[$day_epoch]['department'][$day_schedule_shift['branch']][$day_schedule_shift['department']] = TRUE;
                             $schedule_shift_totals[$day_epoch]['labels']++;
                         }
                         if (!isset($max_week_data[$week_of_year]['shift'])) {
                             Debug::text('Date: ' . $day_epoch . ' Week: ' . $week_of_year . ' Setting Max Week shift to 0', __FILE__, __LINE__, __METHOD__, 10);
                             $max_week_data[$week_of_year]['shift'] = 1;
                             $max_week_data[$week_of_year]['labels'] = 0;
                         }
                         if (isset($max_week_data[$week_of_year]['shift']) and $schedule_shift_totals[$day_epoch]['total_shifts'] + $schedule_shift_totals[$day_epoch]['labels'] > $max_week_data[$week_of_year]['shift'] + $max_week_data[$week_of_year]['labels']) {
                             Debug::text('Date: ' . $day_epoch . ' Week: ' . $week_of_year . ' Setting Max Week shift to: ' . $schedule_shift_totals[$day_epoch]['total_shifts'] . ' Labels: ' . $schedule_shift_totals[$day_epoch]['labels'], __FILE__, __LINE__, __METHOD__, 10);
                             $max_week_data[$week_of_year]['shift'] = $schedule_shift_totals[$day_epoch]['total_shifts'];
                             $max_week_data[$week_of_year]['labels'] = $schedule_shift_totals[$day_epoch]['labels'];
                         }
                         //Debug::Arr($schedule_shift_totals, ' Schedule Shift Totals: ', __FILE__, __LINE__, __METHOD__,10);
                         //Debug::Arr($max_week_data, ' zMaxWeekData: ', __FILE__, __LINE__, __METHOD__,10);
                     }
                 }
                 if (isset($tmp_schedule_shifts)) {
                     //Sort Branches/Departments first
                     foreach ($tmp_schedule_shifts as $day_epoch => $day_tmp_schedule_shift) {
                         ksort($day_tmp_schedule_shift);
                         $tmp_schedule_shifts[$day_epoch] = $day_tmp_schedule_shift;
                         foreach ($day_tmp_schedule_shift as $branch => $department_schedule_shifts) {
                             ksort($tmp_schedule_shifts[$day_epoch][$branch]);
                         }
                     }
                     //Sort each department by start time.
                     foreach ($tmp_schedule_shifts as $day_epoch => $day_tmp_schedule_shift) {
                         foreach ($day_tmp_schedule_shift as $branch => $department_schedule_shifts) {
                             foreach ($department_schedule_shifts as $department => $department_schedule_shift) {
                                 $department_schedule_shift = Sort::multiSort($department_schedule_shift, 'start_time');
                                 $this->schedule_shifts[$day_epoch][$branch][$department] = $department_schedule_shift;
                             }
                         }
                     }
                 }
                 unset($day_tmp_schedule_shift, $department_schedule_shifts, $department_schedule_shift, $tmp_schedule_shifts, $branch, $department);
                 $calendar_array = TTDate::getCalendarArray($filter_data['start_date'], $filter_data['end_date'], $start_week_day);
                 //var_dump($calendar_array);
                 if (!is_array($calendar_array) or !isset($this->schedule_shifts) or !is_array($this->schedule_shifts)) {
                     continue;
                     //Skip to next user.
                 }
                 $ulf = TTnew('UserListFactory');
                 $ulf->getByIdAndCompanyId($user_id, $current_user->getCompany());
                 if ($ulf->getRecordCount() != 1) {
                     continue;
                 } else {
                     $user_obj = $ulf->getCurrent();
                     $pdf->AddPage();
                     $pdf->setXY(670, $top_margin);
                     $pdf->SetFont('freesans', '', 10);
                     $pdf->Cell(100, 15, TTDate::getDate('DATE+TIME', $current_epoch), $border, 0, 'R');
                     $pdf->setXY($left_margin, $top_margin);
                     $pdf->SetFont('freesans', 'B', 25);
                     $pdf->Cell(0, 25, $user_obj->getFullName() . ' - ' . TTi18n::getText('Schedule'), $border, 0, 'C');
                     $pdf->Ln();
                 }
                 $pdf->SetFont('freesans', 'B', 16);
                 $pdf->Cell(0, 15, TTDate::getDate('DATE', $filter_data['start_date']) . ' - ' . TTDate::getDate('DATE', $filter_data['end_date']), $border, 0, 'C');
                 //$pdf->Ln();
                 $pdf->Ln();
                 $pdf->Ln();
                 $pdf->SetFont('freesans', '', 8);
                 $cell_width = floor(($pdf->GetPageWidth() - $left_margin * 2) / 7);
                 $cell_height = 100;
                 $i = 0;
                 $total_days = count($calendar_array) - 1;
                 $boader = 1;
                 foreach ($calendar_array as $calendar) {
                     if ($i == 0) {
                         //Calendar Header
                         $pdf->SetFont('freesans', 'B', 8);
                         $calendar_header = TTDate::getDayOfWeekArrayByStartWeekDay($start_week_day);
                         foreach ($calendar_header as $header_name) {
                             $pdf->Cell($cell_width, 15, $header_name, 1, 0, 'C');
                         }
                         $pdf->Ln();
                         unset($calendar_header, $header_name);
                     }
                     $month_name = NULL;
                     if ($i == 0 or $calendar['isNewMonth'] == TRUE) {
                         $month_name = $calendar['month_name'];
                     }
                     if ($i > 0 and $i % 7 == 0) {
                         $this->writeWeekSchedule($pdf, $cell_width, $week_date_stamps, $max_week_data, $left_margin, $group_schedule, $start_week_day);
                         unset($week_date_stamps);
                     }
                     $pdf->SetFont('freesans', 'B', 8);
                     $pdf->Cell($cell_width / 2, 15, $month_name, 'LT', 0, 'L');
                     $pdf->Cell($cell_width / 2, 15, $calendar['day_of_month'], 'RT', 0, 'R');
                     $week_date_stamps[] = $calendar['date_stamp'];
                     $i++;
                 }
                 $this->writeWeekSchedule($pdf, $cell_width, $week_date_stamps, $max_week_data, $left_margin, $group_schedule, $start_week_day, TRUE);
                 $valid_schedules++;
                 unset($this->schedule_shifts, $calendar_array, $week_date_stamps, $max_week_data, $day_epoch, $day_schedule_shifts, $day_schedule_shift, $schedule_shift_totals);
             }
         }
         unset($raw_schedule_shifts);
     } else {
         $valid_schedules = 1;
         $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) {
                     //Debug::Arr($day_schedule_shift, 'bDay Schedule Shift: ', __FILE__, __LINE__, __METHOD__,10);
                     $tmp_schedule_shifts[$day_epoch][$day_schedule_shift['branch']][$day_schedule_shift['department']][] = $day_schedule_shift;
                     if (isset($schedule_shift_totals[$day_epoch]['total_shifts'])) {
                         $schedule_shift_totals[$day_epoch]['total_shifts']++;
                     } else {
                         $schedule_shift_totals[$day_epoch]['total_shifts'] = 1;
                     }
                     //$week_of_year = TTDate::getWeek( strtotime($day_epoch) );
                     $week_of_year = TTDate::getWeek(strtotime($day_epoch), $start_week_day);
                     Debug::text(' Date: ' . TTDate::getDate('DATE', strtotime($day_epoch)) . ' Week: ' . $week_of_year . ' TMP: ' . TTDate::getWeek(strtotime('20070721'), $start_week_day), __FILE__, __LINE__, __METHOD__, 10);
                     if (!isset($schedule_shift_totals[$day_epoch]['labels'])) {
                         $schedule_shift_totals[$day_epoch]['labels'] = 0;
                     }
                     if ($day_schedule_shift['branch'] != '--' and !isset($schedule_shift_totals[$day_epoch]['branch'][$day_schedule_shift['branch']])) {
                         $schedule_shift_totals[$day_epoch]['branch'][$day_schedule_shift['branch']] = TRUE;
                         $schedule_shift_totals[$day_epoch]['labels']++;
                     }
                     if ($day_schedule_shift['department'] != '--' and !isset($schedule_shift_totals[$day_epoch]['department'][$day_schedule_shift['branch']][$day_schedule_shift['department']])) {
                         $schedule_shift_totals[$day_epoch]['department'][$day_schedule_shift['branch']][$day_schedule_shift['department']] = TRUE;
                         $schedule_shift_totals[$day_epoch]['labels']++;
                     }
                     if (!isset($max_week_data[$week_of_year]['shift'])) {
                         Debug::text('Date: ' . $day_epoch . ' Week: ' . $week_of_year . ' Setting Max Week shift to 0', __FILE__, __LINE__, __METHOD__, 10);
                         $max_week_data[$week_of_year]['shift'] = 1;
                         $max_week_data[$week_of_year]['labels'] = 0;
                     }
                     if (isset($max_week_data[$week_of_year]['shift']) and $schedule_shift_totals[$day_epoch]['total_shifts'] + $schedule_shift_totals[$day_epoch]['labels'] > $max_week_data[$week_of_year]['shift'] + $max_week_data[$week_of_year]['labels']) {
                         Debug::text('Date: ' . $day_epoch . ' Week: ' . $week_of_year . ' Setting Max Week shift to: ' . $schedule_shift_totals[$day_epoch]['total_shifts'] . ' Labels: ' . $schedule_shift_totals[$day_epoch]['labels'], __FILE__, __LINE__, __METHOD__, 10);
                         $max_week_data[$week_of_year]['shift'] = $schedule_shift_totals[$day_epoch]['total_shifts'];
                         $max_week_data[$week_of_year]['labels'] = $schedule_shift_totals[$day_epoch]['labels'];
                     }
                 }
             }
         }
         //print_r($tmp_schedule_shifts);
         //print_r($max_week_data);
         if (isset($tmp_schedule_shifts)) {
             //Sort Branches/Departments first
             foreach ($tmp_schedule_shifts as $day_epoch => $day_tmp_schedule_shift) {
                 ksort($day_tmp_schedule_shift);
                 $tmp_schedule_shifts[$day_epoch] = $day_tmp_schedule_shift;
                 foreach ($day_tmp_schedule_shift as $branch => $department_schedule_shifts) {
                     ksort($tmp_schedule_shifts[$day_epoch][$branch]);
                 }
             }
             //Sort each department by start time.
             foreach ($tmp_schedule_shifts as $day_epoch => $day_tmp_schedule_shift) {
                 foreach ($day_tmp_schedule_shift as $branch => $department_schedule_shifts) {
                     foreach ($department_schedule_shifts as $department => $department_schedule_shift) {
                         $department_schedule_shift = Sort::multiSort($department_schedule_shift, 'last_name');
                         $this->schedule_shifts[$day_epoch][$branch][$department] = $department_schedule_shift;
                     }
                 }
             }
         }
         //Debug::Arr($this->schedule_shifts, 'Schedule Shifts: ', __FILE__, __LINE__, __METHOD__,10);
         $calendar_array = TTDate::getCalendarArray($filter_data['start_date'], $filter_data['end_date'], $start_week_day);
         //var_dump($calendar_array);
         if (!is_array($calendar_array) or !isset($this->schedule_shifts) or !is_array($this->schedule_shifts)) {
             return FALSE;
         }
         $pdf->AddPage();
         $pdf->setXY(670, $top_margin);
         $pdf->SetFont('freesans', '', 10);
         $pdf->Cell(100, 15, TTDate::getDate('DATE+TIME', $current_epoch), $border, 0, 'R');
         $pdf->setXY($left_margin, $top_margin);
         $pdf->SetFont('freesans', 'B', 25);
         $pdf->Cell(0, 25, 'Employee Schedule', $border, 0, 'C');
         $pdf->Ln();
         $pdf->SetFont('freesans', 'B', 10);
         $pdf->Cell(0, 15, TTDate::getDate('DATE', $filter_data['start_date']) . ' - ' . TTDate::getDate('DATE', $filter_data['end_date']), $border, 0, 'C');
         $pdf->Ln();
         $pdf->Ln();
         $pdf->SetFont('freesans', '', 8);
         $cell_width = floor(($pdf->GetPageWidth() - $left_margin * 2) / 7);
         $cell_height = 100;
         $i = 0;
         $total_days = count($calendar_array) - 1;
         $boader = 1;
         foreach ($calendar_array as $calendar) {
             if ($i == 0) {
                 //Calendar Header
                 $pdf->SetFont('freesans', 'B', 8);
                 $calendar_header = TTDate::getDayOfWeekArrayByStartWeekDay($start_week_day);
                 foreach ($calendar_header as $header_name) {
                     $pdf->Cell($cell_width, 15, $header_name, 1, 0, 'C');
                 }
                 $pdf->Ln();
                 unset($calendar_header, $header_name);
             }
             $month_name = NULL;
             if ($i == 0 or $calendar['isNewMonth'] == TRUE) {
                 $month_name = $calendar['month_name'];
             }
             if ($i > 0 and $i % 7 == 0) {
                 $this->writeWeekSchedule($pdf, $cell_width, $week_date_stamps, $max_week_data, $left_margin, $group_schedule, $start_week_day);
                 unset($week_date_stamps);
             }
             $pdf->SetFont('freesans', 'B', 8);
             $pdf->Cell($cell_width / 2, 15, $month_name, 'LT', 0, 'L');
             $pdf->Cell($cell_width / 2, 15, $calendar['day_of_month'], 'RT', 0, 'R');
             $week_date_stamps[] = $calendar['date_stamp'];
             $i++;
         }
         $this->writeWeekSchedule($pdf, $cell_width, $week_date_stamps, $max_week_data, $left_margin, $group_schedule, $start_week_day, TRUE);
     }
     if ($valid_schedules > 0) {
         $output = $pdf->Output('', 'S');
         return $output;
     }
     return FALSE;
 }
 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) . ' End Date: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10);
     //Get week data
     $rstlf = new 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::getWeek($this->getStartDate(), 0);
     //Start week on Sunday to match Recurring Schedule.
     Debug::text('Week of Start Date: ' . $start_date_week, __FILE__, __LINE__, __METHOD__, 10);
     for ($i = $start_date; $i <= $end_date; $i += 86400) {
         $current_week = TTDate::getWeek($i, 0);
         //Start week on Sunday to match Recurring Schedule.
         //Debug::text('Current Date: '. TTDate::getDate('DATE+TIME', $i) .' Current Week: '. $current_week,__FILE__, __LINE__, __METHOD__, 10);
         $template_week = abs($current_week - $start_date_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['start_time'], $i);
                         $end_time = TTDate::getTimeLockedDate($template_week_arr['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;
 }
Пример #3
0
 function test_getWeek()
 {
     //Match up with PHP's function
     $date1 = strtotime('01-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 44);
     $this->assertEquals(TTDate::getWeek($date1, 1), 44);
     $date1 = strtotime('02-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('03-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('08-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('09-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 46);
     $this->assertEquals(TTDate::getWeek($date1, 1), 46);
     //Test with Sunday as start day of week.
     $date1 = strtotime('01-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('02-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('03-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('08-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 46);
     $date1 = strtotime('09-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 46);
     //Test with Tuesday as start day of week.
     $date1 = strtotime('01-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 44);
     $date1 = strtotime('02-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 44);
     $date1 = strtotime('03-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('08-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('09-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('10-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 46);
     $date1 = strtotime('11-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 46);
     //Test with Wed as start day of week.
     $date1 = strtotime('03-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 3), 44);
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 3), 45);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 3), 45);
     //Test with Thu as start day of week.
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 4), 44);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 4), 45);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 4), 45);
     //Test with Fri as start day of week.
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 5), 44);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 5), 45);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 5), 45);
     //Test with Sat as start day of week.
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 6), 44);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 6), 45);
     $date1 = strtotime('08-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 6), 45);
     //Test with different years
     $date1 = strtotime('31-Dec-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 1), 53);
     $date1 = strtotime('01-Jan-10 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 1), 53);
     $date1 = strtotime('04-Jan-10 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 1), 1);
     $date1 = strtotime('03-Jan-10 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 1);
     $date1 = strtotime('09-Jan-10 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 6), 1);
     //Start on Monday as thats what PHP uses.
     for ($i = strtotime('07-Jan-13'); $i < strtotime('06-Jan-13'); $i += 86400 * 7) {
         $this->assertEquals(TTDate::getWeek($i, 1), date('W', $i));
     }
     //Start on Sunday.
     $this->assertEquals(TTDate::getWeek(strtotime('29-Dec-12'), 0), 52);
     $this->assertEquals(TTDate::getWeek(strtotime('30-Dec-12'), 0), 1);
     $this->assertEquals(TTDate::getWeek(strtotime('31-Dec-12'), 0), 1);
     $this->assertEquals(TTDate::getWeek(strtotime('01-Jan-12'), 0), 1);
     $this->assertEquals(TTDate::getWeek(strtotime('02-Jan-12'), 0), 1);
     $this->assertEquals(TTDate::getWeek(strtotime('03-Jan-12'), 0), 1);
     $this->assertEquals(TTDate::getWeek(strtotime('04-Jan-12'), 0), 1);
     $this->assertEquals(TTDate::getWeek(strtotime('05-Jan-12'), 0), 1);
     $this->assertEquals(TTDate::getWeek(strtotime('06-Jan-13'), 0), 2);
     $this->assertEquals(TTDate::getWeek(strtotime('09-Apr-13'), 0), 15);
     $this->assertEquals(TTDate::getWeek(strtotime('28-Jun-13'), 0), 26);
     //Start on every other day of the week
     $this->assertEquals(TTDate::getWeek(strtotime('28-Jun-13'), 6), 25);
     $this->assertEquals(TTDate::getWeek(strtotime('27-Jun-13'), 5), 25);
     $this->assertEquals(TTDate::getWeek(strtotime('26-Jun-13'), 4), 25);
     $this->assertEquals(TTDate::getWeek(strtotime('25-Jun-13'), 3), 25);
     $this->assertEquals(TTDate::getWeek(strtotime('24-Jun-13'), 2), 25);
     $this->assertEquals(TTDate::getWeek(strtotime('23-Jun-13'), 1), 25);
     $this->assertEquals(TTDate::getWeek(strtotime('22-Jun-13'), 0), 25);
 }
 function calcOverTimePolicyTotalTime($udt_meal_policy_adjustment_arr, $udt_break_policy_adjustment_arr)
 {
     global $profiler;
     $profiler->startTimer('UserDateTotal::calcOverTimePolicyTotalTime() - Part 1');
     //If this user is scheduled, get schedule overtime policy id.
     $schedule_total_time = 0;
     $schedule_over_time_policy_id = 0;
     $slf = TTnew('ScheduleListFactory');
     $slf->getByUserDateIdAndStatusId($this->getUserDateID(), 10);
     //FIXME: Allow overtime policies to be specified on absence shifts too, like premium policies?
     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();
             if (is_object($s_obj->getSchedulePolicyObject()) and $s_obj->getSchedulePolicyObject()->getOverTimePolicyID() != FALSE) {
                 $schedule_over_time_policy_id = $s_obj->getSchedulePolicyObject()->getOverTimePolicyID();
                 Debug::text('Found New Schedule Overtime Policies to apply: ' . $schedule_over_time_policy_id, __FILE__, __LINE__, __METHOD__, 10);
             }
         }
     } else {
         //If they are not scheduled, we use the PolicyGroup list to get a Over Schedule / No Schedule overtime policy.
         //We could check for an active recurring schedule, but there could be multiple, and which
         //one do we use?
     }
     //Apply policies for OverTime hours
     $otplf = TTnew('OverTimePolicyListFactory');
     $otp_calculation_order = $otplf->getOptions('calculation_order');
     $otplf->getByPolicyGroupUserIdOrId($this->getUserDateObject()->getUser(), $schedule_over_time_policy_id);
     if ($otplf->getRecordCount() > 0) {
         Debug::text('Found Overtime Policies to apply.', __FILE__, __LINE__, __METHOD__, 10);
         //Get Pay Period Schedule info
         if (is_object($this->getUserDateObject()->getPayPeriodObject()) and is_object($this->getUserDateObject()->getPayPeriodObject()->getPayPeriodScheduleObject())) {
             $start_week_day_id = $this->getUserDateObject()->getPayPeriodObject()->getPayPeriodScheduleObject()->getStartWeekDay();
         } else {
             $start_week_day_id = 0;
         }
         Debug::text('Start Week Day ID: ' . $start_week_day_id, __FILE__, __LINE__, __METHOD__, 10);
         //Convert all OT policies to daily before applying.
         //For instance, 40+hrs/week policy if they are currently at 35hrs is a 5hr daily policy.
         //For weekly OT policies, they MUST include regular time + other WEEKLY over time rules.
         $udtlf = TTnew('UserDateTotalListFactory');
         $weekly_total = $udtlf->getWeekRegularTimeSumByUserIDAndEpochAndStartWeekEpoch($this->getUserDateObject()->getUser(), $this->getUserDateObject()->getDateStamp(), TTDate::getBeginWeekEpoch($this->getUserDateObject()->getDateStamp(), $start_week_day_id));
         Debug::text('Weekly Total: ' . (int) $weekly_total, __FILE__, __LINE__, __METHOD__, 10);
         //Daily policy always takes precedence, then Weekly, Bi-Weekly, Day Of Week etc...
         //So unless the next policy in the list has a lower trigger time then the previous policy
         //We ignore it.
         //ie: if Daily OT is after 8hrs, and Day Of Week is after 10. Day of week will be ignored.
         //	If Daily OT is after 8hrs, and Weekly is after 40, and they worked 35 up to yesterday,
         //	and 12 hrs today, from 5hrs to 8hrs will be weekly, then anything after that is daily.
         //FIXME: Take rate into account, so for example if we have a daily OT policy after 8hrs at 1.5x
         //  and a Holiday OT policy after 0hrs at 2.0x. If the employee works 10hrs on the holiday we want all 10hrs to be Holiday time.
         //  We shouldn't go back to a lesser rate of 1.5x for the Daily OT policy. However if we do this we also need to take into account accrual rates, as time could be banked.
         //  Combine Rate and Accrual rate to use for sorting, as some 2.0x rate overtime policies might accrual/bank it all (Rate: 0 Accrual Rate: 2.0), but it should still be considered a 2.0x rate.
         //  *The work around for this currently is to have multiple holiday policies that match the daily overtime policies so they take priority.
         $tmp_trigger_time_arr = array();
         foreach ($otplf as $otp_obj) {
             Debug::text('  Checking Against Policy: ' . $otp_obj->getName() . ' Trigger Time: ' . $otp_obj->getTriggerTime(), __FILE__, __LINE__, __METHOD__, 10);
             $trigger_time = NULL;
             switch ($otp_obj->getType()) {
                 case 10:
                     //Daily
                     $trigger_time = $otp_obj->getTriggerTime();
                     Debug::text(' Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     break;
                 case 20:
                     //Weekly
                     $trigger_time = $otp_obj->getTriggerTime();
                     Debug::text(' Weekly Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     break;
                 case 30:
                     //Bi-Weekly
                     //Convert biweekly into a weekly policy by taking the hours worked in the
                     //first of the two week period and reducing the trigger time by that amount.
                     //When does the bi-weekly cutoff start though? It must have a hard date that it can be based on so we don't count the same week twice.
                     //Try to synchronize it with the week of the first pay period? Just figure out if we are odd or even weeks.
                     //FIXME: Set flag that tells smartRecalculate to calculate the next week or not.
                     $week_modifier = 0;
                     //0=Even, 1=Odd
                     if (is_object($this->getUserDateObject()->getPayPeriodObject())) {
                         $week_modifier = TTDate::getWeek($this->getUserDateObject()->getPayPeriodObject()->getStartDate(), $start_week_day_id) % 2;
                     }
                     $current_week_modifier = TTDate::getWeek($this->getUserDateObject()->getDateStamp(), $start_week_day_id) % 2;
                     Debug::text(' Current Week: ' . $current_week_modifier . ' Week Modifier: ' . $week_modifier, __FILE__, __LINE__, __METHOD__, 10);
                     $first_week_total = 0;
                     if ($current_week_modifier != $week_modifier) {
                         //$udtlf->getWeekRegularTimeSumByUserIDAndEpochAndStartWeekEpoch() uses "< $epoch" so the current day is ignored, but in this
                         //case we want to include the last day of the week, so we need to add one day to this argument.
                         $first_week_total = $udtlf->getWeekRegularTimeSumByUserIDAndEpochAndStartWeekEpoch($this->getUserDateObject()->getUser(), TTDate::getEndWeekEpoch(TTDate::getMiddleDayEpoch($this->getUserDateObject()->getDateStamp()) - 86400 * 7, $start_week_day_id) + 86400, TTDate::getBeginWeekEpoch(TTDate::getMiddleDayEpoch($this->getUserDateObject()->getDateStamp()) - 86400 * 7, $start_week_day_id));
                         Debug::text(' Week modifiers differ, calculate total time for the first week: ' . $first_week_total, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         UserDateTotalFactory::setEnableCalcFutureWeek(TRUE);
                     }
                     $trigger_time = $otp_obj->getTriggerTime() - $first_week_total;
                     if ($trigger_time < 0) {
                         $trigger_time = 0;
                     }
                     Debug::text('Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     unset($first_week_total, $week_modifier, $current_week_modifier);
                     break;
                 case 40:
                     //Sunday
                     if (date('w', $this->getUserDateObject()->getDateStamp()) == 0) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' DayOfWeek OT for Sat ... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT DayOfWeek OT for Sat...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     break;
                 case 50:
                     //Monday
                     if (date('w', $this->getUserDateObject()->getDateStamp()) == 1) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' DayOfWeek OT for Sat ... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT DayOfWeek OT for Sat...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     break;
                 case 60:
                     //Tuesday
                     if (date('w', $this->getUserDateObject()->getDateStamp()) == 2) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' DayOfWeek OT for Sat ... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT DayOfWeek OT for Sat...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     break;
                 case 70:
                     //Wed
                     if (date('w', $this->getUserDateObject()->getDateStamp()) == 3) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' DayOfWeek OT for Sat ... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT DayOfWeek OT for Sat...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     break;
                 case 80:
                     //Thu
                     if (date('w', $this->getUserDateObject()->getDateStamp()) == 4) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' DayOfWeek OT for Sat ... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT DayOfWeek OT for Sat...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     break;
                 case 90:
                     //Fri
                     if (date('w', $this->getUserDateObject()->getDateStamp()) == 5) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' DayOfWeek OT for Sat ... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT DayOfWeek OT for Sat...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     break;
                 case 100:
                     //Sat
                     if (date('w', $this->getUserDateObject()->getDateStamp()) == 6) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' DayOfWeek OT for Sat ... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT DayOfWeek OT for Sat...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     break;
                 case 150:
                     //2-day/week Consecutive
                 //2-day/week Consecutive
                 case 151:
                     //3-day/week Consecutive
                 //3-day/week Consecutive
                 case 152:
                     //4-day/week Consecutive
                 //4-day/week Consecutive
                 case 153:
                     //5-day/week Consecutive
                 //5-day/week Consecutive
                 case 154:
                     //6-day/week Consecutive
                 //6-day/week Consecutive
                 case 155:
                     //7-day/week Consecutive
                     switch ($otp_obj->getType()) {
                         case 150:
                             $minimum_days_worked = 2;
                             break;
                         case 151:
                             $minimum_days_worked = 3;
                             break;
                         case 152:
                             $minimum_days_worked = 4;
                             break;
                         case 153:
                             $minimum_days_worked = 5;
                             break;
                         case 154:
                             $minimum_days_worked = 6;
                             break;
                         case 155:
                             $minimum_days_worked = 7;
                             break;
                     }
                     //Should these be reset on the week boundary or should any consecutive days worked apply? Or should we offer both options?
                     //We should probably break this out to just a general "consecutive days worked" and add a field to specify any number of days
                     //and a field to specify if its only per week, or any timeframe.
                     //Will probably want to include a flag to consider scheduled days only too.
                     $days_worked_arr = (array) $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($this->getUserDateObject()->getUser(), TTDate::getBeginWeekEpoch($this->getUserDateObject()->getDateStamp(), $start_week_day_id), $this->getUserDateObject()->getDateStamp());
                     $weekly_days_worked = count($days_worked_arr);
                     Debug::text(' Weekly Days Worked: ' . $weekly_days_worked . ' Minimum Required: ' . $minimum_days_worked, __FILE__, __LINE__, __METHOD__, 10);
                     if ($weekly_days_worked >= $minimum_days_worked and TTDate::isConsecutiveDays($days_worked_arr) == TRUE) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' After Days Consecutive... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT After Days Consecutive Worked...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     unset($days_worked_arr, $weekly_days_worked, $minimum_days_worked);
                     break;
                 case 300:
                     //2-day Consecutive
                 //2-day Consecutive
                 case 301:
                     //3-day Consecutive
                 //3-day Consecutive
                 case 302:
                     //4-day Consecutive
                 //4-day Consecutive
                 case 303:
                     //5-day Consecutive
                 //5-day Consecutive
                 case 304:
                     //6-day Consecutive
                 //6-day Consecutive
                 case 305:
                     //7-day Consecutive
                     switch ($otp_obj->getType()) {
                         case 300:
                             $minimum_days_worked = 2;
                             break;
                         case 301:
                             $minimum_days_worked = 3;
                             break;
                         case 302:
                             $minimum_days_worked = 4;
                             break;
                         case 303:
                             $minimum_days_worked = 5;
                             break;
                         case 304:
                             $minimum_days_worked = 6;
                             break;
                         case 305:
                             $minimum_days_worked = 7;
                             break;
                     }
                     //This does not reset on the week boundary.
                     $days_worked_arr = (array) $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($this->getUserDateObject()->getUser(), $this->getUserDateObject()->getDateStamp() - 86400 * $minimum_days_worked, $this->getUserDateObject()->getDateStamp());
                     $weekly_days_worked = count($days_worked_arr);
                     Debug::text(' Weekly Days Worked: ' . $weekly_days_worked . ' Minimum Required: ' . $minimum_days_worked, __FILE__, __LINE__, __METHOD__, 10);
                     //Since these can span overtime weeks, we need to calculate the future week as well.
                     UserDateTotalFactory::setEnableCalcFutureWeek(TRUE);
                     if ($weekly_days_worked >= $minimum_days_worked and TTDate::isConsecutiveDays($days_worked_arr) == TRUE) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' After Days Consecutive... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT After Days Consecutive Worked...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     unset($days_worked_arr, $weekly_days_worked, $minimum_days_worked);
                     break;
                 case 350:
                     //2nd Consecutive Day
                 //2nd Consecutive Day
                 case 351:
                     //3rd Consecutive Day
                 //3rd Consecutive Day
                 case 352:
                     //4th Consecutive Day
                 //4th Consecutive Day
                 case 353:
                     //5th Consecutive Day
                 //5th Consecutive Day
                 case 354:
                     //6th Consecutive Day
                 //6th Consecutive Day
                 case 355:
                     //7th Consecutive Day
                     switch ($otp_obj->getType()) {
                         case 350:
                             $minimum_days_worked = 2;
                             break;
                         case 351:
                             $minimum_days_worked = 3;
                             break;
                         case 352:
                             $minimum_days_worked = 4;
                             break;
                         case 353:
                             $minimum_days_worked = 5;
                             break;
                         case 354:
                             $minimum_days_worked = 6;
                             break;
                         case 355:
                             $minimum_days_worked = 7;
                             break;
                     }
                     $range_start_date = TTDate::getMiddleDayEpoch($this->getUserDateObject()->getDateStamp()) - 86400 * $minimum_days_worked;
                     $previous_day_with_overtime_result = $udtlf->getPreviousDayByUserIdAndStartDateAndEndDateAndOverTimePolicyId($this->getUserDateObject()->getUser(), $range_start_date, $this->getUserDateObject()->getDateStamp(), $otp_obj->getId());
                     if ($previous_day_with_overtime_result !== FALSE) {
                         $previous_day_with_overtime = TTDate::getMiddleDayEpoch(TTDate::strtotime($previous_day_with_overtime_result));
                         Debug::text(' Previous Day with OT: ' . TTDate::getDate('DATE', $previous_day_with_overtime) . ' Start Date: ' . TTDate::getDate('DATE', $range_start_date) . ' End Date: ' . TTDate::getDate('DATE', $this->getUserDateObject()->getDateStamp()), __FILE__, __LINE__, __METHOD__, 10);
                     }
                     if (isset($previous_day_with_overtime) and $previous_day_with_overtime >= $range_start_date) {
                         $range_start_date = TTDate::getMiddleDayEpoch($previous_day_with_overtime) + 86400;
                         Debug::text(' bPrevious Day with OT: ' . TTDate::getDate('DATE', $previous_day_with_overtime) . ' Start Date: ' . TTDate::getDate('DATE', $range_start_date) . ' End Date: ' . TTDate::getDate('DATE', $this->getUserDateObject()->getDateStamp()), __FILE__, __LINE__, __METHOD__, 10);
                     }
                     //This does not reset on the week boundary.
                     $days_worked_arr = (array) $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($this->getUserDateObject()->getUser(), $range_start_date, $this->getUserDateObject()->getDateStamp());
                     sort($days_worked_arr);
                     $weekly_days_worked = count($days_worked_arr);
                     Debug::text(' Weekly Days Worked: ' . $weekly_days_worked . ' Minimum Required: ' . $minimum_days_worked, __FILE__, __LINE__, __METHOD__, 10);
                     //Since these can span overtime weeks, we need to calculate the future week as well.
                     UserDateTotalFactory::setEnableCalcFutureWeek(TRUE);
                     $days_worked_arr_key = $minimum_days_worked - 1;
                     if ($weekly_days_worked >= $minimum_days_worked and TTDate::isConsecutiveDays($days_worked_arr) == TRUE and isset($days_worked_arr[$days_worked_arr_key]) and TTDate::getMiddleDayEpoch(TTDate::strtotime($days_worked_arr[$days_worked_arr_key])) == TTDate::getMiddleDayEpoch($this->getUserDateObject()->getDateStamp())) {
                         $trigger_time = $otp_obj->getTriggerTime();
                         Debug::text(' After Days Consecutive... Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NOT After Days Consecutive Worked...', __FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     unset($range_start_date, $previous_day_with_overtime, $previous_day_with_overtime, $days_worked_arr, $weekly_days_worked, $minimum_days_worked);
                     break;
                 case 180:
                     //Holiday
                     $hlf = TTnew('HolidayListFactory');
                     $hlf->getByPolicyGroupUserIdAndDate($this->getUserDateObject()->getUser(), $this->getUserDateObject()->getDateStamp());
                     if ($hlf->getRecordCount() > 0) {
                         $holiday_obj = $hlf->getCurrent();
                         Debug::text(' Found Holiday: ' . $holiday_obj->getName(), __FILE__, __LINE__, __METHOD__, 10);
                         if ($holiday_obj->getHolidayPolicyObject()->getForceOverTimePolicy() == TRUE or $holiday_obj->isEligible($this->getUserDateObject()->getUser())) {
                             $trigger_time = $otp_obj->getTriggerTime();
                             Debug::text(' Is Eligible for Holiday: ' . $holiday_obj->getName() . ' Daily Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                         } else {
                             Debug::text(' Not Eligible for Holiday: ' . $holiday_obj->getName(), __FILE__, __LINE__, __METHOD__, 10);
                             continue 2;
                             //Skip to next policy
                         }
                     } else {
                         Debug::text(' Not Holiday...', __FILE__, __LINE__, __METHOD__, 10);
                         continue 2;
                         //Skip to next policy
                     }
                     unset($hlf, $holiday_obj);
                     break;
                 case 200:
                     //Over schedule (Daily) / No Schedule. Have trigger time extend the schedule time.
                     $trigger_time = $schedule_total_time + $otp_obj->getTriggerTime();
                     Debug::text(' Over Schedule/No Schedule Trigger Time: ' . $trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     break;
                 case 210:
                     //Over Schedule (Weekly) / No Schedule
                     //Get schedule time for the entire week, and add the Active After time to that.
                     $schedule_weekly_total_time = $slf->getWeekWorkTimeSumByUserIDAndEpochAndStartWeekEpoch($this->getUserDateObject()->getUser(), TTDate::getEndWeekEpoch($this->getUserDateObject()->getDateStamp(), $start_week_day_id), TTDate::getBeginWeekEpoch($this->getUserDateObject()->getDateStamp(), $start_week_day_id));
                     Debug::text('Schedule Weekly Total Time: ' . $schedule_weekly_total_time, __FILE__, __LINE__, __METHOD__, 10);
                     $trigger_time = $schedule_weekly_total_time + $otp_obj->getTriggerTime();
                     unset($schedule_weekly_total_time);
                     break;
             }
             if (is_numeric($trigger_time) and $trigger_time < 0) {
                 $trigger_time = 0;
             }
             if (is_numeric($trigger_time)) {
                 $trigger_time_arr[] = array('calculation_order' => $otp_calculation_order[$otp_obj->getType()], 'trigger_time' => $trigger_time, 'over_time_policy_id' => $otp_obj->getId(), 'over_time_policy_type_id' => $otp_obj->getType(), 'combined_rate' => $otp_obj->getRate() + $otp_obj->getAccrualRate());
             }
             unset($trigger_time);
         }
         if (isset($trigger_time_arr)) {
             $trigger_time_arr = $this->processTriggerTimeArray($trigger_time_arr, $weekly_total);
         }
         //Debug::Arr($trigger_time_arr, 'Trigger Time Array', __FILE__, __LINE__, __METHOD__, 10);
     } else {
         Debug::text('    No OverTime Policies found for this user.', __FILE__, __LINE__, __METHOD__, 10);
     }
     unset($otp_obj, $otplf);
     if (isset($trigger_time_arr)) {
         $total_daily_hours = 0;
         $total_daily_hours_used = 0;
         //get all worked total hours.
         $udtlf = TTnew('UserDateTotalListFactory');
         $udtlf->getByUserDateIdAndStatus($this->getUserDateID(), 20);
         if ($udtlf->getRecordCount() > 0) {
             Debug::text('Found Total Hours to attempt to apply policy: Record Count: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
             if ($trigger_time_arr[0]['trigger_time'] > 0) {
                 //No trigger time set at 0.
                 $enable_regular_hour_calculating = TRUE;
             } else {
                 $enable_regular_hour_calculating = FALSE;
             }
             $tmp_policy_total_time = NULL;
             foreach ($udtlf as $udt_obj) {
                 //Ignore incomplete punches
                 if ($udt_obj->getTotalTime() == 0) {
                     continue;
                 }
                 $udt_total_time = $udt_obj->getTotalTime();
                 if (isset($udt_meal_policy_adjustment_arr[$udt_obj->getId()])) {
                     $udt_total_time = bcadd($udt_total_time, $udt_meal_policy_adjustment_arr[$udt_obj->getId()]);
                 }
                 if (isset($udt_break_policy_adjustment_arr[$udt_obj->getId()])) {
                     $udt_total_time = bcadd($udt_total_time, $udt_break_policy_adjustment_arr[$udt_obj->getId()]);
                 }
                 $total_daily_hours = bcadd($total_daily_hours, $udt_total_time);
                 //Loop through each trigger.
                 $i = 0;
                 Debug::text('Total Hour: ID: ' . $udt_obj->getId() . ' Status: ' . $udt_obj->getStatus() . ' Total Time: ' . $udt_obj->getTotalTime() . ' Total Daily Hours: ' . $total_daily_hours . ' Used Total Time: ' . $total_daily_hours_used . ' Branch ID: ' . $udt_obj->getBranch() . ' Department ID: ' . $udt_obj->getDepartment() . ' Job ID: ' . $udt_obj->getJob() . ' Job Item ID: ' . $udt_obj->getJobItem() . ' Quantity: ' . $udt_obj->getQuantity(), __FILE__, __LINE__, __METHOD__, 10);
                 foreach ($trigger_time_arr as $trigger_time_data) {
                     if (isset($trigger_time_arr[$i + 1]['trigger_time']) and $total_daily_hours_used >= $trigger_time_arr[$i + 1]['trigger_time']) {
                         Debug::text('     ' . $i . ': SKIPPING THIS TRIGGER TIME: ' . $trigger_time_data['trigger_time'], __FILE__, __LINE__, __METHOD__, 10);
                         $i++;
                         continue;
                     }
                     Debug::text('     ' . $i . ': Trigger Time Data: Trigger Time: ' . $trigger_time_data['trigger_time'] . ' ID: ' . $trigger_time_data['over_time_policy_id'], __FILE__, __LINE__, __METHOD__, 10);
                     Debug::text('     ' . $i . ': Used Total Time: ' . $total_daily_hours_used, __FILE__, __LINE__, __METHOD__, 10);
                     //Only consider Regular Time ONCE per user date total row.
                     if ($i == 0 and $trigger_time_arr[$i]['trigger_time'] > 0 and $total_daily_hours_used < $trigger_time_arr[$i]['trigger_time']) {
                         Debug::text('     ' . $i . ': Trigger Time: ' . $trigger_time_arr[$i]['trigger_time'] . ' greater then 0, found Regular Time.', __FILE__, __LINE__, __METHOD__, 10);
                         if ($total_daily_hours > $trigger_time_arr[$i]['trigger_time']) {
                             $regular_total_time = $trigger_time_arr[$i]['trigger_time'] - $total_daily_hours_used;
                             $regular_quantity_percent = bcdiv($trigger_time_arr[$i]['trigger_time'], $udt_obj->getTotalTime());
                             $regular_quantity = round(bcmul($udt_obj->getQuantity(), $regular_quantity_percent), 2);
                             $regular_bad_quantity = round(bcmul($udt_obj->getBadQuantity(), $regular_quantity_percent), 2);
                         } else {
                             //$regular_total_time = $udt_obj->getTotalTime();
                             $regular_total_time = $udt_total_time;
                             $regular_quantity = $udt_obj->getQuantity();
                             $regular_bad_quantity = $udt_obj->getBadQuantity();
                         }
                         Debug::text('     ' . $i . ': Regular Total Time: ' . $regular_total_time . ' Regular Quantity: ' . $regular_quantity, __FILE__, __LINE__, __METHOD__, 10);
                         if (isset($user_data_total_compact_arr[20][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()])) {
                             Debug::text('     Adding to Compact Array: Branch: ' . (int) $udt_obj->getBranch() . ' Department: ' . (int) $udt_obj->getDepartment(), __FILE__, __LINE__, __METHOD__, 10);
                             $user_data_total_compact_arr[20][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['total_time'] += $regular_total_time;
                             $user_data_total_compact_arr[20][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['quantity'] += $regular_quantity;
                             $user_data_total_compact_arr[20][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['bad_quantity'] += $regular_bad_quantity;
                         } else {
                             Debug::text('     Initiating Compact Sub-Array: Branch: ' . (int) $udt_obj->getBranch() . ' Department: ' . (int) $udt_obj->getDepartment(), __FILE__, __LINE__, __METHOD__, 10);
                             $user_data_total_compact_arr[20][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()] = array('total_time' => $regular_total_time, 'quantity' => $regular_quantity, 'bad_quantity' => $regular_bad_quantity);
                         }
                         Debug::text('     Compact Array Regular Total: ' . $user_data_total_compact_arr[20][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['total_time'], __FILE__, __LINE__, __METHOD__, 10);
                         $total_daily_hours_used += $regular_total_time;
                     }
                     Debug::text('     ' . $i . ': Daily Total Time: ' . $total_daily_hours . ' Trigger Time: ' . $trigger_time_arr[$i]['trigger_time'] . ' Used Total Time: ' . $total_daily_hours_used . ' Overtime Policy Type: ' . $trigger_time_arr[$i]['over_time_policy_type_id'], __FILE__, __LINE__, __METHOD__, 10);
                     if ($total_daily_hours > $trigger_time_arr[$i]['trigger_time']) {
                         Debug::text('     ' . $i . ': Trigger Time: ' . $trigger_time_arr[$i]['trigger_time'] . ' greater then 0, found Over Time.', __FILE__, __LINE__, __METHOD__, 10);
                         if (isset($trigger_time_arr[$i + 1]['trigger_time'])) {
                             Debug::text('     ' . $i . ': Found trigger time after this one: ' . $trigger_time_arr[$i + 1]['trigger_time'], __FILE__, __LINE__, __METHOD__, 10);
                             $max_trigger_time = $trigger_time_arr[$i + 1]['trigger_time'] - $trigger_time_arr[$i]['trigger_time'];
                         } else {
                             $max_trigger_time = $trigger_time_arr[$i]['trigger_time'];
                         }
                         Debug::text('     aMax Trigger Time ' . $max_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                         if (isset($trigger_time_arr[$i + 1]['trigger_time']) and $total_daily_hours_used > $trigger_time_arr[$i]['trigger_time']) {
                             //$max_trigger_time = $max_trigger_time - ($total_daily_hours_used - $max_trigger_time);
                             $max_trigger_time = $max_trigger_time - ($total_daily_hours_used - $trigger_time_arr[$i]['trigger_time']);
                         }
                         Debug::text('     bMax Trigger Time ' . $max_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                         $over_time_total = $total_daily_hours - $total_daily_hours_used;
                         if (isset($trigger_time_arr[$i + 1]['trigger_time']) and $max_trigger_time > 0 and $over_time_total > $max_trigger_time) {
                             $over_time_total = $max_trigger_time;
                         }
                         if ($over_time_total > 0) {
                             $over_time_quantity_percent = bcdiv($over_time_total, $udt_obj->getTotalTime());
                             $over_time_quantity = round(bcmul($udt_obj->getQuantity(), $over_time_quantity_percent), 2);
                             $over_time_bad_quantity = round(bcmul($udt_obj->getBadQuantity(), $over_time_quantity_percent), 2);
                             Debug::text('     Inserting Hours (' . $over_time_total . ') for Policy ID: ' . $trigger_time_arr[$i]['over_time_policy_id'], __FILE__, __LINE__, __METHOD__, 10);
                             if (isset($user_data_total_compact_arr[30][$trigger_time_arr[$i]['over_time_policy_id']][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()])) {
                                 Debug::text('     Adding to Compact Array: Policy ID: ' . $trigger_time_arr[$i]['over_time_policy_id'] . ' Branch: ' . (int) $udt_obj->getBranch() . ' Department: ' . (int) $udt_obj->getDepartment(), __FILE__, __LINE__, __METHOD__, 10);
                                 $user_data_total_compact_arr[30][$trigger_time_arr[$i]['over_time_policy_id']][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['total_time'] += $over_time_total;
                                 $user_data_total_compact_arr[30][$trigger_time_arr[$i]['over_time_policy_id']][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['quantity'] += $over_time_quantity;
                                 $user_data_total_compact_arr[30][$trigger_time_arr[$i]['over_time_policy_id']][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['bad_quantity'] += $over_time_bad_quantity;
                             } else {
                                 Debug::text('     Initiating Compact Sub-Array: Policy ID: ' . $trigger_time_arr[$i]['over_time_policy_id'] . ' Branch: ' . (int) $udt_obj->getBranch() . ' Department: ' . (int) $udt_obj->getDepartment(), __FILE__, __LINE__, __METHOD__, 10);
                                 $user_data_total_compact_arr[30][$trigger_time_arr[$i]['over_time_policy_id']][(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()] = array('total_time' => $over_time_total, 'quantity' => $over_time_quantity, 'bad_quantity' => $over_time_bad_quantity);
                             }
                             $total_daily_hours_used += $over_time_total;
                         } else {
                             Debug::text('     Over Time Total is 0: ' . $over_time_total, __FILE__, __LINE__, __METHOD__, 10);
                         }
                         unset($over_time_total, $over_time_quantity_percent, $over_time_quantity, $over_time_bad_quantity);
                     } else {
                         break;
                     }
                     $i++;
                 }
                 unset($udt_total_time);
             }
             unset($tmp_policy_total_time, $trigger_time_data, $trigger_time_arr);
         }
     }
     $profiler->stopTimer('UserDateTotal::calcOverTimePolicyTotalTime() - Part 1');
     if (isset($user_data_total_compact_arr)) {
         return $user_data_total_compact_arr;
     }
     return FALSE;
 }
Пример #5
0
 function test_getWeek()
 {
     //Match up with PHP's function
     $date1 = strtotime('01-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 44);
     $this->assertEquals(TTDate::getWeek($date1, 1), 44);
     $date1 = strtotime('02-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('03-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('08-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 45);
     $this->assertEquals(TTDate::getWeek($date1, 1), 45);
     $date1 = strtotime('09-Nov-09 12:00PM');
     $this->assertEquals(date('W', $date1), 46);
     $this->assertEquals(TTDate::getWeek($date1, 1), 46);
     //Test with Sunday as start day of week.
     $date1 = strtotime('01-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('02-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('03-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 45);
     $date1 = strtotime('08-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 46);
     $date1 = strtotime('09-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 46);
     //Test with Tuesday as start day of week.
     $date1 = strtotime('01-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 44);
     $date1 = strtotime('02-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 44);
     $date1 = strtotime('03-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('08-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('09-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 45);
     $date1 = strtotime('10-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 46);
     $date1 = strtotime('11-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 2), 46);
     //Test with Wed as start day of week.
     $date1 = strtotime('03-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 3), 44);
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 3), 45);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 3), 45);
     //Test with Thu as start day of week.
     $date1 = strtotime('04-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 4), 44);
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 4), 45);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 4), 45);
     //Test with Fri as start day of week.
     $date1 = strtotime('05-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 5), 44);
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 5), 45);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 5), 45);
     //Test with Sat as start day of week.
     $date1 = strtotime('06-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 6), 44);
     $date1 = strtotime('07-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 6), 45);
     $date1 = strtotime('08-Nov-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 6), 45);
     //Test with different years
     $date1 = strtotime('31-Dec-09 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 1), 53);
     $date1 = strtotime('01-Jan-10 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 1), 53);
     $date1 = strtotime('04-Jan-10 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 1), 1);
     $date1 = strtotime('03-Jan-10 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 0), 1);
     $date1 = strtotime('09-Jan-10 12:00PM');
     $this->assertEquals(TTDate::getWeek($date1, 6), 1);
 }
 function getShifts($start_date, $end_date, &$holiday_data = array(), &$branch_options = array(), &$department_options = array(), &$shifts = array(), &$shifts_index = array())
 {
     //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::getWeek($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);
     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;
         }
         $current_week = TTDate::getWeek($i, 0);
         //Start week on Sunday to match Recurring Schedule.
         //Debug::text('I: '. $i .' User ID: '. $this->getColumn('user_id') .' Current Date: '. TTDate::getDate('DATE+TIME', $i) .' Current Week: '. $current_week,__FILE__, __LINE__, __METHOD__, 10);
         $template_week = abs($current_week - $start_date_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);
                 $iso_date_stamp = TTDate::getISODateStamp($i);
                 $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);
                 }
                 if (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])) {
                             if (TTDate::isTimeOverLap($shifts[$iso_date_stamp][$shift_key]['start_time'], $shifts[$iso_date_stamp][$shift_key]['end_time'], $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);
                 }
                 //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 = 10;
                 //Working
                 $absence_policy_id = FALSE;
                 $absence_policy = NULL;
                 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 = $holiday_data[$iso_date_stamp]['absence_policy'];
                     }
                 }
                 //Debug::text('I: '. $i .' 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 ),__FILE__, __LINE__, __METHOD__, 10);
                 $shifts[$iso_date_stamp][$this->getColumn('user_id') . $start_time] = array('user_id' => $this->getColumn('user_id'), 'user_full_name' => Misc::getFullName($this->getColumn('first_name'), NULL, $this->getColumn('last_name'), FALSE, FALSE), 'user_created_by' => $this->getColumn('user_created_by'), 'status_id' => $status_id, 'date_stamp' => TTDate::getAPIDate('DATE', $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, 'total_time' => $this->getTotalTime(), 'schedule_policy_id' => $this->getSchedulePolicyID(), 'absence_policy_id' => $absence_policy_id, 'absence_policy' => $absence_policy, 'branch_id' => $this->getColumn('schedule_branch_id'), 'branch' => Option::getByKey($this->getColumn('schedule_branch_id'), $branch_options, NULL), 'department_id' => $this->getColumn('schedule_department_id'), 'department' => Option::getByKey($this->getColumn('schedule_department_id'), $department_options, NULL), 'job_id' => $this->getJob(), 'job_item_id' => $this->getJobItem());
                 $shifts_index[$iso_date_stamp][$this->getColumn('user_id')][] = $this->getColumn('user_id') . $start_time;
                 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;
 }