Ejemplo n.º 1
0
 function sortFormData()
 {
     $this->profiler->startTimer('sort');
     if (is_array($this->getSortConfig()) and count($this->getSortConfig()) > 0) {
         $this->getProgressBarObject()->start($this->getAMFMessageID(), count($this->form_data), NULL, TTi18n::getText('Sorting Form Data...'));
         Debug::Arr($this->getSortConfig(), 'Sort Config: ', __FILE__, __LINE__, __METHOD__, 10);
         $this->form_data = Sort::arrayMultiSort($this->form_data, $this->getSortConfig());
         $this->getProgressBarObject()->set($this->getAMFMessageID(), count($this->form_data));
     }
     $this->profiler->stopTimer('sort');
     //Debug::Arr($this->form_data, 'Sort Data: ', __FILE__, __LINE__, __METHOD__,10);
     Debug::Text(' Memory Usage: Current: ' . memory_get_usage() . ' Peak: ' . memory_get_peak_usage(), __FILE__, __LINE__, __METHOD__, 10);
     return TRUE;
 }
 function processTriggerTimeArray($trigger_time_arr, $weekly_total_time = 0)
 {
     if (is_array($trigger_time_arr) == FALSE or count($trigger_time_arr) == 0) {
         return FALSE;
     }
     //Debug::Arr($trigger_time_arr, 'Source Trigger Arr: ', __FILE__, __LINE__, __METHOD__, 10);
     //Create a duplicate trigger_time_arr that we can sort so we know the
     //first trigger time is always the first in the array.
     //We don't want to use this array in the loop though, because it throws off other ordering.
     $tmp_trigger_time_arr = Sort::multiSort($trigger_time_arr, 'trigger_time');
     $first_trigger_time = $tmp_trigger_time_arr[0]['trigger_time'];
     //Get first trigger time.
     //Debug::Arr($tmp_trigger_time_arr, 'Trigger Time After Sort: ', __FILE__, __LINE__, __METHOD__, 10);
     Debug::text('Weekly Total Time: ' . (int) $weekly_total_time . ' First Trigger Time: ' . $first_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
     unset($tmp_trigger_time_arr);
     //Sort trigger_time array by calculation order before looping over it.
     //$trigger_time_arr = Sort::multiSort( $trigger_time_arr, 'calculation_order', 'trigger_time', 'asc', 'desc' );
     $trigger_time_arr = Sort::arrayMultiSort($trigger_time_arr, array('calculation_order' => SORT_ASC, 'trigger_time' => SORT_DESC, 'combined_rate' => SORT_DESC));
     //Debug::Arr($trigger_time_arr, 'Source Trigger Arr After Calculation Order Sort: ', __FILE__, __LINE__, __METHOD__, 10);
     //We need to calculate regular time as early as possible so we can adjust the trigger time
     //of weekly overtime policies and re-sort the array.
     $tmp_trigger_time_arr = array();
     foreach ($trigger_time_arr as $key => $trigger_time_data) {
         if ($trigger_time_data['over_time_policy_type_id'] == 20 or $trigger_time_data['over_time_policy_type_id'] == 30 or $trigger_time_data['over_time_policy_type_id'] == 210) {
             if (is_numeric($weekly_total_time) and $weekly_total_time > 0 and $weekly_total_time >= $trigger_time_data['trigger_time']) {
                 //Worked more then weekly trigger time already.
                 Debug::Text('Worked more then weekly trigger time...', __FILE__, __LINE__, __METHOD__, 10);
                 $tmp_trigger_time = 0;
             } else {
                 //Haven't worked more then the weekly trigger time yet.
                 $tmp_trigger_time = $trigger_time_data['trigger_time'] - $weekly_total_time;
                 Debug::Text('NOT Worked more then weekly trigger time... TMP Trigger Time: ' . $tmp_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                 if (is_numeric($weekly_total_time) and $weekly_total_time > 0 and $tmp_trigger_time > $first_trigger_time) {
                     Debug::Text('Using First Trigger Time: ' . $first_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
                     $tmp_trigger_time = $first_trigger_time;
                 }
             }
             $trigger_time_arr[$key]['trigger_time'] = $tmp_trigger_time;
         } else {
             Debug::Text('NOT weekly overtime policy...', __FILE__, __LINE__, __METHOD__, 10);
             $tmp_trigger_time = $trigger_time_data['trigger_time'];
         }
         Debug::Text('Trigger Time: ' . $tmp_trigger_time . ' Overtime Policy Id: ' . $trigger_time_data['over_time_policy_id'], __FILE__, __LINE__, __METHOD__, 10);
         if (!in_array($tmp_trigger_time, $tmp_trigger_time_arr)) {
             Debug::Text('Adding policy to final array... Trigger Time: ' . $tmp_trigger_time, __FILE__, __LINE__, __METHOD__, 10);
             $trigger_time_data['trigger_time'] = $tmp_trigger_time;
             $retval[] = $trigger_time_data;
         } else {
             Debug::Text('NOT Adding policy to final array...', __FILE__, __LINE__, __METHOD__, 10);
         }
         $tmp_trigger_time_arr[] = $trigger_time_arr[$key]['trigger_time'];
     }
     unset($trigger_time_arr, $tmp_trigger_time_arr, $trigger_time_data);
     $retval = Sort::multiSort($retval, 'trigger_time');
     //Debug::Arr($retval, 'Dest Trigger Arr: ', __FILE__, __LINE__, __METHOD__, 10);
     //Loop through final array and remove policies with higher trigger times and lower rates.
     //The rate matters as we don't want one policy after 8hrs to have a lower rate than a policy after 0hrs. (ie: Holiday OT after 0hrs @ 2x and Daily OT after 8hrs @ 1.5x)
     //Are there any scenarios where an employee works more hours and gets a lesser rate?
     $prev_combined_rate = 0;
     foreach ($retval as $key => $policy_data) {
         if ($policy_data['combined_rate'] < $prev_combined_rate) {
             Debug::Text('Removing policy with higher trigger time and lower combined rate... Key: ' . $key, __FILE__, __LINE__, __METHOD__, 10);
             unset($retval[$key]);
         } else {
             $prev_combined_rate = $policy_data['combined_rate'];
         }
     }
     unset($key, $policy_data);
     $retval = array_values($retval);
     //Rekey the array so there are no gaps.
     //Debug::Arr($retval, 'zDest Trigger Arr: ', __FILE__, __LINE__, __METHOD__, 10);
     return $retval;
 }
 function _outputPDFTimesheet($format)
 {
     Debug::Text(' Format: ' . $format, __FILE__, __LINE__, __METHOD__, 10);
     $border = 0;
     $current_company = $this->getUserObject()->getCompanyObject();
     if (!is_object($current_company)) {
         Debug::Text('Invalid company object...', __FILE__, __LINE__, __METHOD__, 10);
         return FALSE;
     }
     $pdf_created_date = time();
     $adjust_x = 10;
     $adjust_y = 10;
     //Debug::Arr($this->form_data, 'Form Data: ', __FILE__, __LINE__, __METHOD__,10);
     if (isset($this->form_data) and count($this->form_data) > 0) {
         //Make sure we sort the form data for printable timesheets.
         $this->form_data['user_date_total'] = Sort::arrayMultiSort($this->form_data['user_date_total'], $this->getSortConfig());
         //Get pay period schedule data for each pay period.
         $this->pdf = new TTPDF($this->config['other']['page_orientation'], 'mm', $this->config['other']['page_format'], $this->getUserObject()->getCompanyObject()->getEncoding());
         $this->pdf->SetAuthor(APPLICATION_NAME);
         $this->pdf->SetTitle($this->title);
         $this->pdf->SetSubject(APPLICATION_NAME . ' ' . TTi18n::getText('Report'));
         $this->pdf->setMargins($this->config['other']['left_margin'], $this->config['other']['top_margin'], $this->config['other']['right_margin']);
         //Debug::Arr($this->config['other'], 'Margins: ', __FILE__, __LINE__, __METHOD__,10);
         $this->pdf->SetAutoPageBreak(FALSE);
         $this->pdf->SetFont($this->config['other']['default_font'], '', $this->_pdf_fontSize(10));
         //Debug::Arr($this->form_data, 'zabUser Raw Data: ', __FILE__, __LINE__, __METHOD__,10);
         $filter_data = $this->getFilterConfig();
         $columns = Misc::trimSortPrefix($this->getOptions('columns'));
         $this->getProgressBarObject()->start($this->getAMFMessageID(), 2, NULL, TTi18n::getText('Querying Database...'));
         //Iterations need to be 2, otherwise progress bar is not created.
         $this->getProgressBarObject()->set($this->getAMFMessageID(), 2);
         if ($format == 'pdf_timesheet_detail') {
             $plf = TTnew('PunchListFactory');
             $plf->getSearchByCompanyIdAndArrayCriteria($this->getUserObject()->getCompany(), $filter_data);
             Debug::Text('Got punch data... Total Rows: ' . $plf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
             $this->getProgressBarObject()->start($this->getAMFMessageID(), $plf->getRecordCount(), NULL, TTi18n::getText('Retrieving Punch Data...'));
             if ($plf->getRecordCount() > 0) {
                 foreach ($plf as $key => $p_obj) {
                     $this->form_data['user_date_total'][$p_obj->getColumn('user_id')]['punch_rows'][$p_obj->getColumn('pay_period_id')][TTDate::strtotime($p_obj->getColumn('date_stamp'))][$p_obj->getPunchControlID()][$p_obj->getStatus()] = array('status_id' => $p_obj->getStatus(), 'type_id' => $p_obj->getType(), 'type_code' => $p_obj->getTypeCode(), 'time_stamp' => $p_obj->getTimeStamp());
                     $this->getProgressBarObject()->set($this->getAMFMessageID(), $key);
                 }
             }
             unset($plf, $p_obj);
         }
         Debug::Text('Drawing timesheets...', __FILE__, __LINE__, __METHOD__, 10);
         $this->getProgressBarObject()->start($this->getAMFMessageID(), count($this->form_data['user_date_total']), NULL, TTi18n::getText('Generating TimeSheets...'));
         $key = 0;
         foreach ($this->form_data['user_date_total'] as $user_data) {
             if ($this->_pdf_checkMaximumPageLimit() == FALSE) {
                 Debug::Text('Exceeded maximum page count...', __FILE__, __LINE__, __METHOD__, 10);
                 //Exceeded maximum pages, stop processing.
                 $this->_pdf_displayMaximumPageLimitError();
                 break;
             }
             if (isset($user_data['first_name']) and isset($user_data['last_name']) and isset($user_data['employee_number'])) {
                 $this->pdf->AddPage($this->config['other']['page_orientation'], 'Letter');
                 $this->timesheetHeader($user_data);
                 //Start displaying dates/times here. Start with header.
                 $column_widths = array('line' => 5, 'date_stamp' => 20, 'dow' => 10, 'in_punch_time_stamp' => 20, 'out_punch_time_stamp' => 20, 'worked_time' => 20, 'regular_time' => 20, 'over_time' => 40.6, 'absence_time' => 45);
                 if (isset($user_data['data']) and is_array($user_data['data'])) {
                     $user_data['data'] = Sort::arrayMultiSort($user_data['data'], array('time_stamp' => SORT_ASC));
                     $this->timesheet_week_totals = Misc::preSetArrayValues(NULL, array('worked_time', 'absence_time', 'regular_time', 'over_time'), 0);
                     $this->timesheet_totals = array();
                     $this->timesheet_totals = Misc::preSetArrayValues($this->timesheet_totals, array('worked_time', 'absence_time', 'regular_time', 'over_time'), 0);
                     $this->counter_i = 1;
                     //Overall row counter.
                     $this->counter_x = 1;
                     //Row counter, starts over each week.
                     $this->counter_y = 1;
                     //Week counter.
                     $this->max_i = count($user_data['data']);
                     $prev_data = FALSE;
                     foreach ($user_data['data'] as $data) {
                         if ($this->_pdf_checkMaximumPageLimit() == FALSE) {
                             Debug::Text('Exceeded maximum page count...', __FILE__, __LINE__, __METHOD__, 10);
                             //Exceeded maximum pages, stop processing.
                             $this->_pdf_displayMaximumPageLimitError();
                             break 2;
                         }
                         if (isset($this->form_data['pay_period'][$data['pay_period_id']])) {
                             //Debug::Arr( $data, 'Data: i: '. $this->counter_i .' x: '. $this->counter_x .' Max I: '. $this->max_i, __FILE__, __LINE__, __METHOD__,10);
                             $data = Misc::preSetArrayValues($data, array('time_stamp', 'in_punch_time_stamp', 'out_punch_time_stamp', 'worked_time', 'absence_time', 'regular_time', 'over_time'), '--');
                             $data['start_week_day'] = $this->form_data['pay_period'][$data['pay_period_id']]['start_week_day'];
                             $row_date_gap = $prev_data !== FALSE ? TTDate::getMiddleDayEpoch($data['time_stamp']) - TTDate::getMiddleDayEpoch($prev_data['time_stamp']) : 0;
                             //Take into account DST by using mid-day epochs.
                             //Debug::Text('Row Gap: '. $row_date_gap, __FILE__, __LINE__, __METHOD__,10);
                             if ($prev_data !== FALSE and $row_date_gap > 86400) {
                                 //Handle gaps between individual days with hours.
                                 $prev_data = $this->timesheetHandleDayGaps($prev_data['time_stamp'] + 86400, $data['time_stamp'], $format, $columns, $column_widths, $user_data, $data, $prev_data);
                             } elseif ($this->counter_i == 1 and TTDate::getMiddleDayEpoch($data['time_stamp']) - TTDate::getMiddleDayEpoch($data['pay_period_start_date']) >= 86400) {
                                 //Always fill gaps between the pay period start date and the date with time, even if not filtering by pay period.
                                 //Handle gaps before the first date with hours is displayed, only when filtering by pay period though.
                                 $prev_data = $this->timesheetHandleDayGaps($data['pay_period_start_date'], $data['time_stamp'], $format, $columns, $column_widths, $user_data, $data, $prev_data);
                             }
                             //Check for gaps at the end of the date range and before the end of the pay period.
                             //If we find one we have to increase $max_i by one so the last timesheetDayRow doesn't display the week totals.
                             if ($this->counter_i == $this->max_i and TTDate::getMiddleDayEpoch($data['pay_period_end_date']) - TTDate::getMiddleDayEpoch($data['time_stamp']) >= 86400) {
                                 $this->max_i++;
                             }
                             $this->timesheetDayRow($format, $columns, $column_widths, $user_data, $data, $prev_data);
                             $prev_data = $data;
                         } else {
                             Debug::Text('Pay Period does not exist, skipping... ID: ' . $data['pay_period_id'], __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     //Check for gaps at the end of the date range and before the end of the pay period so we can fill them in. Only when filtering by pay period though.
                     //as filtering by start/end date can result in a lot of data if they want show time for the last year but an employee was just hired.
                     if (isset($data['pay_period_end_date']) and TTDate::getMiddleDayEpoch($data['pay_period_end_date']) - TTDate::getMiddleDayEpoch($data['time_stamp']) >= 86400) {
                         //Handle gaps between the last day with hours and the end of the pay period.
                         //Always fill gaps between the pay period end date and the current date with time, even if not filtering by pay period.
                         $this->timesheetHandleDayGaps($data['time_stamp'] + 86400, $data['pay_period_end_date'], $format, $columns, $column_widths, $user_data, $data, $prev_data);
                     }
                     if (isset($this->timesheet_totals) and is_array($this->timesheet_totals)) {
                         //Display overall totals.
                         $this->timesheetTotal($column_widths, $this->timesheet_totals);
                         unset($totals);
                     }
                     $this->timesheetSignature($user_data, $data);
                     unset($data, $prev_data);
                 } else {
                     $this->timesheetNoData();
                 }
                 $this->timesheetFooter($pdf_created_date, $adjust_x, $adjust_y);
             }
             $this->getProgressBarObject()->set($this->getAMFMessageID(), $key);
             if ($key % 25 == 0 and $this->isSystemLoadValid() == FALSE) {
                 return FALSE;
             }
             $key++;
         }
         $output = $this->pdf->Output('', 'S');
         return $output;
     }
     Debug::Text('No data to return...', __FILE__, __LINE__, __METHOD__, 10);
     return FALSE;
 }