function getPayStub($pslf = NULL, $hide_employer_rows = TRUE)
 {
     if (!is_object($pslf) and $this->getId() != '') {
         $pslf = new PayStubListFactory();
         $pslf->getById($this->getId());
     }
     if (get_class($pslf) !== 'PayStubListFactory') {
         return FALSE;
     }
     $border = 0;
     if ($pslf->getRecordCount() > 0) {
         $pdf = new TTPDF('P', 'mm', 'Letter');
         $pdf->setMargins(0, 0);
         //$pdf->SetAutoPageBreak(TRUE, 30);
         $pdf->SetAutoPageBreak(FALSE);
         $pdf->SetFont('freeserif', '', 10);
         //$pdf->SetFont('FreeSans','',10);
         $i = 0;
         foreach ($pslf as $pay_stub_obj) {
             $psealf = new PayStubEntryAccountListFactory();
             Debug::text($i . '. Pay Stub Transaction Date: ' . $pay_stub_obj->getTransactionDate(), __FILE__, __LINE__, __METHOD__, 10);
             //Get Pay Period information
             $pplf = new PayPeriodListFactory();
             $pay_period_obj = $pplf->getById($pay_stub_obj->getPayPeriod())->getCurrent();
             //Use Pay Stub dates, not Pay Period dates.
             $pp_start_date = $pay_stub_obj->getStartDate();
             $pp_end_date = $pay_stub_obj->getEndDate();
             $pp_transaction_date = $pay_stub_obj->getTransactionDate();
             //Get pay period numbers
             $ppslf = new PayPeriodScheduleListFactory();
             $pay_period_schedule_obj = $ppslf->getById($pay_period_obj->getPayPeriodSchedule())->getCurrent();
             //Get User information
             $ulf = new UserListFactory();
             $user_obj = $ulf->getById($pay_stub_obj->getUser())->getCurrent();
             //Get company information
             $clf = new CompanyListFactory();
             $company_obj = $clf->getById($user_obj->getCompany())->getCurrent();
             //Change locale to users own locale.
             TTi18n::setCountry($user_obj->getCountry());
             TTi18n::setLanguage($user_obj->getUserPreferenceObject()->getLanguage());
             TTi18n::setLocale();
             //
             // Pay Stub Header
             //
             $pdf->AddPage();
             $adjust_x = 20;
             $adjust_y = 10;
             //Logo
             $pdf->Image($company_obj->getLogoFileName(), Misc::AdjustXY(0, $adjust_x + 0), Misc::AdjustXY(1, $adjust_y + 0), 50, 12, '', '', '', FALSE, 300, '', FALSE, FALSE, 0, TRUE);
             //Company name/address
             $pdf->SetFont('', 'B', 14);
             $pdf->setXY(Misc::AdjustXY(50, $adjust_x), Misc::AdjustXY(0, $adjust_y));
             $pdf->Cell(75, 5, $company_obj->getName(), $border, 0, 'C');
             $pdf->SetFont('', '', 10);
             $pdf->setXY(Misc::AdjustXY(50, $adjust_x), Misc::AdjustXY(5, $adjust_y));
             $pdf->Cell(75, 5, $company_obj->getAddress1() . ' ' . $company_obj->getAddress2(), $border, 0, 'C');
             $pdf->setXY(Misc::AdjustXY(50, $adjust_x), Misc::AdjustXY(10, $adjust_y));
             $pdf->Cell(75, 5, $company_obj->getCity() . ', ' . $company_obj->getProvince() . ' ' . strtoupper($company_obj->getPostalCode()), $border, 0, 'C');
             //Pay Period info
             $pdf->SetFont('', '', 10);
             $pdf->setXY(Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY(0, $adjust_y));
             $pdf->Cell(30, 5, TTi18n::gettext('Pay Start Date:') . ' ', $border, 0, 'R');
             $pdf->setXY(Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY(5, $adjust_y));
             $pdf->Cell(30, 5, TTi18n::gettext('Pay End Date:') . ' ', $border, 0, 'R');
             $pdf->setXY(Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY(10, $adjust_y));
             $pdf->Cell(30, 5, TTi18n::gettext('Payment Date:') . ' ', $border, 0, 'R');
             $pdf->SetFont('', 'B', 10);
             $pdf->setXY(Misc::AdjustXY(155, $adjust_x), Misc::AdjustXY(0, $adjust_y));
             $pdf->Cell(20, 5, TTDate::getDate('DATE', $pp_start_date), $border, 0, 'R');
             $pdf->setXY(Misc::AdjustXY(155, $adjust_x), Misc::AdjustXY(5, $adjust_y));
             $pdf->Cell(20, 5, TTDate::getDate('DATE', $pp_end_date), $border, 0, 'R');
             $pdf->setXY(Misc::AdjustXY(155, $adjust_x), Misc::AdjustXY(10, $adjust_y));
             $pdf->Cell(20, 5, TTDate::getDate('DATE', $pp_transaction_date), $border, 0, 'R');
             //Line
             $pdf->setLineWidth(1);
             $pdf->Line(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY(17, $adjust_y), Misc::AdjustXY(185, $adjust_y), Misc::AdjustXY(17, $adjust_y));
             $pdf->SetFont('', 'B', 14);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY(19, $adjust_y));
             $pdf->Cell(175, 5, TTi18n::gettext('STATEMENT OF EARNINGS AND DEDUCTIONS'), $border, 0, 'C', 0);
             //Line
             $pdf->setLineWidth(1);
             $pdf->Line(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY(27, $adjust_y), Misc::AdjustXY(185, $adjust_y), Misc::AdjustXY(27, $adjust_y));
             $pdf->setLineWidth(0.25);
             //Get pay stub entries.
             $pself = new PayStubEntryListFactory();
             $pself->getByPayStubId($pay_stub_obj->getId());
             Debug::text('Pay Stub Entries: ' . $pself->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
             $prev_type = NULL;
             $description_subscript_counter = 1;
             foreach ($pself as $pay_stub_entry) {
                 Debug::text('Pay Stub Entry Account ID: ' . $pay_stub_entry->getPayStubEntryNameId(), __FILE__, __LINE__, __METHOD__, 10);
                 $description_subscript = NULL;
                 $pay_stub_entry_name_obj = $psealf->getById($pay_stub_entry->getPayStubEntryNameId())->getCurrent();
                 //Use this to put the total for each type at the end of the array.
                 if ($prev_type == 40 or $pay_stub_entry_name_obj->getType() != 40) {
                     $type = $pay_stub_entry_name_obj->getType();
                 }
                 //Debug::text('Pay Stub Entry Name ID: '. $pay_stub_entry_name_obj->getId() .' Type ID: '. $pay_stub_entry_name_obj->getType() .' Type: '. $type, __FILE__, __LINE__, __METHOD__,10);
                 if ($pay_stub_entry->getDescription() !== NULL and $pay_stub_entry->getDescription() !== FALSE and strlen($pay_stub_entry->getDescription()) > 0) {
                     $pay_stub_entry_descriptions[] = array('subscript' => $description_subscript_counter, 'description' => $pay_stub_entry->getDescription());
                     $description_subscript = $description_subscript_counter;
                     $description_subscript_counter++;
                 }
                 //If type if 40 (a total) and the amount is 0, skip it.
                 //This if the employee has no deductions at all, it won't be displayed
                 //on the pay stub.
                 if ($type != 40 or $type == 40 and $pay_stub_entry->getAmount() != 0) {
                     $pay_stub_entries[$type][] = array('id' => $pay_stub_entry->getId(), 'pay_stub_entry_name_id' => $pay_stub_entry->getPayStubEntryNameId(), 'type' => $pay_stub_entry_name_obj->getType(), 'name' => $pay_stub_entry_name_obj->getName(), 'display_name' => $pay_stub_entry_name_obj->getName(), 'rate' => $pay_stub_entry->getRate(), 'units' => $pay_stub_entry->getUnits(), 'ytd_units' => $pay_stub_entry->getYTDUnits(), 'amount' => $pay_stub_entry->getAmount(), 'ytd_amount' => $pay_stub_entry->getYTDAmount(), 'description' => $pay_stub_entry->getDescription(), 'description_subscript' => $description_subscript, 'created_date' => $pay_stub_entry->getCreatedDate(), 'created_by' => $pay_stub_entry->getCreatedBy(), 'updated_date' => $pay_stub_entry->getUpdatedDate(), 'updated_by' => $pay_stub_entry->getUpdatedBy(), 'deleted_date' => $pay_stub_entry->getDeletedDate(), 'deleted_by' => $pay_stub_entry->getDeletedBy());
                 }
                 $prev_type = $pay_stub_entry_name_obj->getType();
             }
             //There should always be pay stub entries for a pay stub.
             if (!isset($pay_stub_entries)) {
                 continue;
             }
             //Debug::Arr($pay_stub_entries, 'Pay Stub Entries...', __FILE__, __LINE__, __METHOD__,10);
             //$pay_period_number = $pay_period_schedule_obj->getCurrentPayPeriodNumber( $pay_period_obj->getTransactionDate(), $pay_period_obj->getEndDate() );
             $block_adjust_y = 30;
             //
             //Earnings
             //
             if (isset($pay_stub_entries[10])) {
                 //Earnings Header
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $pdf->Cell(90, 5, TTi18n::gettext('Earnings'), $border, 0, 'L');
                 $pdf->Cell(17, 5, TTi18n::gettext('Rate'), $border, 0, 'R');
                 $pdf->Cell(23, 5, TTi18n::gettext('Hrs/Units'), $border, 0, 'R');
                 $pdf->Cell(20, 5, TTi18n::gettext('Amount'), $border, 0, 'R');
                 $pdf->Cell(25, 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R');
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 10);
                 foreach ($pay_stub_entries[10] as $pay_stub_entry) {
                     if ($pay_stub_entry['type'] == 10) {
                         if ($pay_stub_entry['description_subscript'] != '') {
                             $subscript = '[' . $pay_stub_entry['description_subscript'] . ']';
                         } else {
                             $subscript = NULL;
                         }
                         $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell(88, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L');
                         $pdf->Cell(17, 5, TTi18n::formatNumber($pay_stub_entry['rate'], TRUE), $border, 0, 'R');
                         $pdf->Cell(23, 5, TTi18n::formatNumber($pay_stub_entry['units'], TRUE), $border, 0, 'R');
                         $pdf->Cell(20, 5, TTi18n::formatNumber($pay_stub_entry['amount']), $border, 0, 'R');
                         $pdf->Cell(25, 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount']), $border, 0, 'R');
                     } else {
                         //Total
                         $pdf->SetFont('', 'B', 10);
                         $pdf->line(Misc::AdjustXY(110, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(130, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->line(Misc::AdjustXY(131, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(150, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->line(Misc::AdjustXY(151, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell(90, 5, $pay_stub_entry['name'], $border, 0, 'L');
                         $pdf->Cell(17, 5, '', $border, 0, 'R');
                         $pdf->Cell(23, 5, TTi18n::formatNumber($pay_stub_entry['units'], TRUE), $border, 0, 'R');
                         $pdf->Cell(20, 5, TTi18n::formatNumber($pay_stub_entry['amount']), $border, 0, 'R');
                         $pdf->Cell(25, 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount']), $border, 0, 'R');
                     }
                     $block_adjust_y = $block_adjust_y + 5;
                 }
             }
             //
             // Deductions
             //
             if (isset($pay_stub_entries[20])) {
                 $max_deductions = count($pay_stub_entries[20]);
                 //Deductions Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 if ($max_deductions > 2) {
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell(40, 5, TTi18n::gettext('Deductions'), $border, 0, 'L');
                     $pdf->Cell(20, 5, TTi18n::gettext('Amount'), $border, 0, 'R');
                     $pdf->Cell(25, 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R');
                     $pdf->setXY(Misc::AdjustXY(90, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell(40, 5, TTi18n::gettext('Deductions'), $border, 0, 'L');
                 } else {
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell(130, 5, TTi18n::gettext('Deductions'), $border, 0, 'L');
                 }
                 $pdf->Cell(20, 5, TTi18n::gettext('Amount'), $border, 0, 'R');
                 $pdf->Cell(25, 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R');
                 $block_adjust_y = $tmp_block_adjust_y = $top_block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 10);
                 $x = 0;
                 $max_block_adjust_y = 0;
                 foreach ($pay_stub_entries[20] as $pay_stub_entry) {
                     //Start with the right side.
                     if ($x < floor($max_deductions / 2)) {
                         $tmp_adjust_x = 90;
                     } else {
                         if ($tmp_block_adjust_y != 0) {
                             $block_adjust_y = $tmp_block_adjust_y;
                             $tmp_block_adjust_y = 0;
                         }
                         $tmp_adjust_x = 0;
                     }
                     if ($pay_stub_entry['type'] == 20) {
                         if ($pay_stub_entry['description_subscript'] != '') {
                             $subscript = '[' . $pay_stub_entry['description_subscript'] . ']';
                         } else {
                             $subscript = NULL;
                         }
                         if ($max_deductions > 2) {
                             $pdf->setXY(Misc::AdjustXY(2, $tmp_adjust_x + $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             $pdf->Cell(38, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L');
                         } else {
                             $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             $pdf->Cell(128, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L');
                         }
                         $pdf->Cell(20, 5, TTi18n::formatNumber($pay_stub_entry['amount']), $border, 0, 'R');
                         $pdf->Cell(25, 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount']), $border, 0, 'R');
                     } else {
                         $block_adjust_y = $max_block_adjust_y + 0;
                         //Total
                         $pdf->SetFont('', 'B', 10);
                         $pdf->line(Misc::AdjustXY(130, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(150, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->line(Misc::AdjustXY(151, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell(130, 5, $pay_stub_entry['name'], $border, 0, 'L');
                         $pdf->Cell(20, 5, TTi18n::formatNumber($pay_stub_entry['amount']), $border, 0, 'R');
                         $pdf->Cell(25, 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount']), $border, 0, 'R');
                     }
                     $block_adjust_y = $block_adjust_y + 5;
                     if ($block_adjust_y > $max_block_adjust_y) {
                         $max_block_adjust_y = $block_adjust_y;
                     }
                     $x++;
                 }
                 //Draw line to separate the two columns
                 if ($max_deductions > 2) {
                     $pdf->Line(Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($top_block_adjust_y - 5, $adjust_y), Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($max_block_adjust_y - 5, $adjust_y));
                 }
                 unset($x, $max_deductions, $tmp_adjust_x, $max_block_adjust_y, $tmp_block_adjust_y, $top_block_adjust_y);
             }
             if (isset($pay_stub_entries[40][0])) {
                 $block_adjust_y = $block_adjust_y + 5;
                 //Net Pay entry
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $pdf->Cell(130, 5, $pay_stub_entries[40][0]['name'], $border, 0, 'L');
                 $pdf->Cell(20, 5, TTi18n::formatNumber($pay_stub_entries[40][0]['amount']), $border, 0, 'R');
                 $pdf->Cell(25, 5, TTi18n::formatNumber($pay_stub_entries[40][0]['ytd_amount']), $border, 0, 'R');
                 $block_adjust_y = $block_adjust_y + 5;
             }
             //
             //Employer Contributions
             //
             //echo "Employee Ded: <br>\n";
             if (isset($pay_stub_entries[30]) and $hide_employer_rows != TRUE) {
                 $max_deductions = count($pay_stub_entries[30]);
                 //echo "Max Employee Ded: ". $max_deductions ."<br>\n";
                 //Deductions Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 if ($max_deductions > 2) {
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell(40, 5, TTi18n::gettext('Employer Contributions'), $border, 0, 'L');
                     $pdf->Cell(20, 5, TTi18n::gettext('Amount'), $border, 0, 'R');
                     $pdf->Cell(25, 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R');
                     $pdf->setXY(Misc::AdjustXY(90, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell(40, 5, TTi18n::gettext('Employer Contributions'), $border, 0, 'L');
                 } else {
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell(130, 5, TTi18n::gettext('Employer Contributions'), $border, 0, 'L');
                 }
                 $pdf->Cell(20, 5, TTi18n::gettext('Amount'), $border, 0, 'R');
                 $pdf->Cell(25, 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R');
                 $block_adjust_y = $tmp_block_adjust_y = $top_block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 10);
                 $x = 0;
                 $max_block_adjust_y = 0;
                 foreach ($pay_stub_entries[30] as $pay_stub_entry) {
                     //Start with the right side.
                     if ($x < floor($max_deductions / 2)) {
                         $tmp_adjust_x = 90;
                     } else {
                         if ($tmp_block_adjust_y != 0) {
                             $block_adjust_y = $tmp_block_adjust_y;
                             $tmp_block_adjust_y = 0;
                         }
                         $tmp_adjust_x = 0;
                     }
                     if ($pay_stub_entry['type'] == 30) {
                         if ($pay_stub_entry['description_subscript'] != '') {
                             $subscript = '[' . $pay_stub_entry['description_subscript'] . ']';
                         } else {
                             $subscript = NULL;
                         }
                         if ($max_deductions > 2) {
                             $pdf->setXY(Misc::AdjustXY(2, $tmp_adjust_x + $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             $pdf->Cell(38, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L');
                         } else {
                             $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             $pdf->Cell(128, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L');
                         }
                         $pdf->Cell(20, 5, TTi18n::formatNumber($pay_stub_entry['amount']), $border, 0, 'R');
                         $pdf->Cell(25, 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount']), $border, 0, 'R');
                     } else {
                         $block_adjust_y = $max_block_adjust_y + 0;
                         //Total
                         $pdf->SetFont('', 'B', 10);
                         $pdf->line(Misc::AdjustXY(130, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(150, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->line(Misc::AdjustXY(151, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell(130, 5, $pay_stub_entry['name'], $border, 0, 'L');
                         $pdf->Cell(20, 5, TTi18n::formatNumber($pay_stub_entry['amount']), $border, 0, 'R');
                         $pdf->Cell(25, 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount']), $border, 0, 'R');
                     }
                     $block_adjust_y = $block_adjust_y + 5;
                     if ($block_adjust_y > $max_block_adjust_y) {
                         $max_block_adjust_y = $block_adjust_y;
                     }
                     $x++;
                 }
                 //Draw line to separate the two columns
                 if ($max_deductions > 2) {
                     $pdf->Line(Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($top_block_adjust_y - 5, $adjust_y), Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($max_block_adjust_y - 5, $adjust_y));
                 }
                 unset($x, $max_deductions, $tmp_adjust_x, $max_block_adjust_y, $tmp_block_adjust_y, $top_block_adjust_y);
             }
             //
             //Accruals PS accounts
             //
             if (isset($pay_stub_entries[50])) {
                 //Accrual Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $pdf->Cell(130, 5, TTi18n::gettext('Accruals'), $border, 0, 'L');
                 $pdf->Cell(20, 5, TTi18n::gettext('Amount'), $border, 0, 'R');
                 $pdf->Cell(25, 5, TTi18n::gettext('Balance'), $border, 0, 'R');
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 10);
                 foreach ($pay_stub_entries[50] as $pay_stub_entry) {
                     if ($pay_stub_entry['type'] == 50) {
                         if ($pay_stub_entry['description_subscript'] != '') {
                             $subscript = '[' . $pay_stub_entry['description_subscript'] . ']';
                         } else {
                             $subscript = NULL;
                         }
                         $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell(128, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L');
                         $pdf->Cell(20, 5, TTi18n::formatNumber($pay_stub_entry['amount']), $border, 0, 'R');
                         $pdf->Cell(25, 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount']), $border, 0, 'R');
                     }
                     $block_adjust_y = $block_adjust_y + 5;
                 }
             }
             //
             //Accrual Policy Balances
             //
             $ablf = new AccrualBalanceListFactory();
             $ablf->getByUserIdAndCompanyIdAndEnablePayStubBalanceDisplay($user_obj->getId(), $user_obj->getCompany(), TRUE);
             if ($ablf->getRecordCount() > 0) {
                 //Accrual Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(40, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $accrual_time_header_start_x = $pdf->getX();
                 $accrual_time_header_start_y = $pdf->getY();
                 $pdf->Cell(70, 5, TTi18n::gettext('Accrual Time Balances as of ') . TTDate::getDate('DATE', time()), $border, 0, 'L');
                 $pdf->Cell(25, 5, TTi18n::gettext('Balance (hrs)'), $border, 0, 'R');
                 $block_adjust_y = $block_adjust_y + 5;
                 $box_height = 5;
                 $pdf->SetFont('', '', 10);
                 foreach ($ablf as $ab_obj) {
                     $balance = $ab_obj->getBalance();
                     if (!is_numeric($balance)) {
                         $balance = 0;
                     }
                     $pdf->setXY(Misc::AdjustXY(40, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell(70, 5, $ab_obj->getColumn('name'), $border, 0, 'L');
                     $pdf->Cell(25, 5, TTi18n::formatNumber(TTDate::getHours($balance)), $border, 0, 'R');
                     $block_adjust_y = $block_adjust_y + 5;
                     $box_height = $box_height + 5;
                     unset($balance);
                 }
                 $pdf->Rect($accrual_time_header_start_x, $accrual_time_header_start_y, 95, $box_height);
                 unset($accrual_time_header_start_x, $accrual_time_header_start_y, $box_height);
             }
             //
             //Descriptions
             //
             if (isset($pay_stub_entry_descriptions) and count($pay_stub_entry_descriptions) > 0) {
                 //Description Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $pdf->Cell(175, 5, TTi18n::gettext('Notes'), $border, 0, 'L');
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 8);
                 $x = 0;
                 foreach ($pay_stub_entry_descriptions as $pay_stub_entry_description) {
                     if ($x % 2 == 0) {
                         $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     } else {
                         $pdf->setXY(Misc::AdjustXY(90, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     }
                     //$pdf->Cell(173,5, '['.$pay_stub_entry_description['subscript'].'] '.$pay_stub_entry_description['description'], $border, 0, 'L');
                     $pdf->Cell(85, 5, '[' . $pay_stub_entry_description['subscript'] . '] ' . $pay_stub_entry_description['description'], $border, 0, 'L');
                     if ($x % 2 != 0) {
                         $block_adjust_y = $block_adjust_y + 5;
                     }
                     $x++;
                 }
             }
             unset($x, $pay_stub_entry_descriptions, $pay_stub_entry_description);
             //
             // Pay Stub Footer
             //
             $block_adjust_y = 215;
             //Line
             $pdf->setLineWidth(1);
             $pdf->Line(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(185, $adjust_y), Misc::AdjustXY($block_adjust_y, $adjust_y));
             //Non Negotiable
             $pdf->SetFont('', 'B', 14);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 3, $adjust_y));
             $pdf->Cell(175, 5, TTi18n::gettext('NON NEGOTIABLE'), $border, 0, 'C', 0);
             //Employee Address
             $pdf->SetFont('', 'B', 12);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 9, $adjust_y));
             $pdf->Cell(60, 5, TTi18n::gettext('CONFIDENTIAL'), $border, 0, 'C', 0);
             $pdf->SetFont('', '', 10);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 14, $adjust_y));
             $pdf->Cell(60, 5, $user_obj->getFullName(), $border, 0, 'C', 0);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 19, $adjust_y));
             $pdf->Cell(60, 5, $user_obj->getAddress1(), $border, 0, 'C', 0);
             $address2_adjust_y = 0;
             if ($user_obj->getAddress2() != '') {
                 $address2_adjust_y = 5;
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 24, $adjust_y));
                 $pdf->Cell(60, 5, $user_obj->getAddress2(), $border, 0, 'C', 0);
             }
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 24 + $address2_adjust_y, $adjust_y));
             $pdf->Cell(60, 5, $user_obj->getCity() . ', ' . $user_obj->getProvince() . ' ' . $user_obj->getPostalCode(), $border, 1, 'C', 0);
             //Pay Period - Balance - ID
             $net_pay_amount = 0;
             if (isset($pay_stub_entries[40][0])) {
                 $net_pay_amount = $pay_stub_entries[40][0]['amount'];
             }
             if (isset($pay_stub_entries[65]) and count($pay_stub_entries[65]) > 0) {
                 $net_pay_label = TTi18n::gettext('Balance');
             } else {
                 $net_pay_label = TTi18n::gettext('Net Pay');
             }
             /*
             if ( $pay_period_schedule_obj->getType() != 5 AND $pay_period_number > 0 AND $pay_period_schedule_obj->getAnnualPayPeriods() > 0 ) {
             	$pdf->setXY( Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY($block_adjust_y+10, $adjust_y) );
             	$pdf->Cell(50, 5, TTi18n::gettext('Pay Period').' '. $pay_period_number .' '. TTi18n::gettext('of') .' '. $pay_period_schedule_obj->getAnnualPayPeriods(), $border, 1, 'L', 0);
             }
             */
             $pdf->SetFont('', 'B', 12);
             $pdf->setXY(Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY($block_adjust_y + 17, $adjust_y));
             $pdf->Cell(50, 5, $net_pay_label . ': ' . $pay_stub_obj->getCurrencyObject()->getSymbol() . $net_pay_amount . ' ' . $pay_stub_obj->getCurrencyObject()->getISOCode(), $border, 1, 'L', 0);
             if ($pay_stub_obj->getTainted() == TRUE) {
                 $tainted_flag = 'T';
             } else {
                 $tainted_flag = '';
             }
             $pdf->SetFont('', '', 8);
             $pdf->setXY(Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY($block_adjust_y + 30, $adjust_y));
             $pdf->Cell(50, 5, TTi18n::gettext('Identification #:') . ' ' . str_pad($pay_stub_obj->getId(), 12, 0, STR_PAD_LEFT) . $tainted_flag, $border, 1, 'L', 0);
             unset($net_pay_amount, $tainted_flag);
             //Line
             $pdf->setLineWidth(1);
             $pdf->Line(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 35, $adjust_y), Misc::AdjustXY(185, $adjust_y), Misc::AdjustXY($block_adjust_y + 35, $adjust_y));
             $pdf->SetFont('', '', 6);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 38, $adjust_y));
             $pdf->Cell(175, 1, TTi18n::gettext('Pay Stub Generated by') . ' ' . APPLICATION_NAME, $border, 0, 'C', 0);
             unset($pay_period_schedule_obj, $pay_stub_entries, $pay_period_number);
             $i++;
         }
         $output = $pdf->Output('', 'S');
     }
     TTi18n::setMasterLocale();
     if (isset($output)) {
         return $output;
     }
     return FALSE;
 }
Esempio n. 2
0
     } else {
         $tmp_rows[$pay_period_id][$user_id][$date_stamp][$column] = (int) $udt_obj->getColumn('total_time');
     }
     if (isset($tmp_rows[$pay_period_id][$user_id][$date_stamp]['actual_time'])) {
         $tmp_rows[$pay_period_id][$user_id][$date_stamp]['actual_time'] += $udt_obj->getColumn('actual_total_time');
     } else {
         $tmp_rows[$pay_period_id][$user_id][$date_stamp]['actual_time'] = $udt_obj->getColumn('actual_total_time');
     }
     $actual_time_diff = bcsub($udt_obj->getColumn('actual_total_time'), $udt_obj->getColumn('total_time'));
     if (isset($tmp_rows[$pay_period_id][$user_id][$date_stamp]['actual_time_diff'])) {
         $tmp_rows[$pay_period_id][$user_id][$date_stamp]['actual_time_diff'] += $actual_time_diff;
     } else {
         $tmp_rows[$pay_period_id][$user_id][$date_stamp]['actual_time_diff'] = $actual_time_diff;
     }
     if (isset($user_wage[$user_id])) {
         $tmp_rows[$pay_period_id][$user_id][$date_stamp]['actual_time_diff_wage'] = Misc::MoneyFormat(bcmul(TTDate::getHours($actual_time_diff), $user_wage[$user_id]), FALSE);
     } else {
         $tmp_rows[$pay_period_id][$user_id][$date_stamp]['actual_time_diff_wage'] = Misc::MoneyFormat(0, FALSE);
     }
     unset($actual_time_diff);
 } elseif ($column != NULL) {
     if ($udt_obj->getColumn('total_time') > 0) {
         //Total up all absence time.
         if ($status_id == 30 and $type_id == 10) {
             if (isset($tmp_rows[$pay_period_id][$user_id][$date_stamp]['absence_time'])) {
                 $tmp_rows[$pay_period_id][$user_id][$date_stamp]['absence_time'] += $udt_obj->getColumn('total_time');
             } else {
                 $tmp_rows[$pay_period_id][$user_id][$date_stamp]['absence_time'] = $udt_obj->getColumn('total_time');
             }
         }
         if ($status_id == 10 and $type_id == 30) {
 function getAnnualHourlyRate($annual_wage, $epoch = FALSE, $accurate_calculation = FALSE)
 {
     if ($epoch == FALSE) {
         $epoch = TTDate::getTime();
     }
     if ($annual_wage == '') {
         return FALSE;
     }
     if ($accurate_calculation == TRUE) {
         Debug::text('EPOCH: ' . $epoch, __FILE__, __LINE__, __METHOD__, 10);
         $annual_week_days = TTDate::getAnnualWeekDays($epoch);
         Debug::text('Annual Week Days: ' . $annual_week_days, __FILE__, __LINE__, __METHOD__, 10);
         //Calculate weeks from adjusted annual weekdays
         //We could use just 52 weeks in a year, but that isn't as accurate.
         $annual_work_weeks = bcdiv($annual_week_days, 5);
         Debug::text('Adjusted annual work weeks : ' . $annual_work_weeks, __FILE__, __LINE__, __METHOD__, 10);
     } else {
         $annual_work_weeks = 52;
     }
     $average_weekly_hours = TTDate::getHours($this->getWeeklyTime());
     //Debug::text('Average Weekly Hours: '. $average_weekly_hours , __FILE__, __LINE__, __METHOD__,10);
     if ($average_weekly_hours == 0) {
         //No default schedule, can't pay them.
         $hourly_wage = 0;
     } else {
         //Divide by average hours/day from default schedule?
         $hours_per_year = bcmul($annual_work_weeks, $average_weekly_hours);
         if ($hours_per_year > 0) {
             $hourly_wage = bcdiv($annual_wage, $hours_per_year);
         }
         unset($hours_per_year);
     }
     //Debug::text('User Wage: '. $this->getWage() , __FILE__, __LINE__, __METHOD__,10);
     //Debug::text('Annual Hourly Rate: '. $hourly_wage , __FILE__, __LINE__, __METHOD__,10);
     return $hourly_wage;
 }
Esempio n. 4
0
 function reCalculate()
 {
     //Re-generate final pay stub
     //get current pay period based off their last day of work
     $pplf = TTnew('PayPeriodListFactory');
     $pay_period_id = $pplf->getByUserIdAndEndDate($this->getUser(), $this->getLastDate())->getCurrent()->getId();
     Debug::Text('Pay Period ID: ' . $pay_period_id, __FILE__, __LINE__, __METHOD__, 10);
     if (is_numeric($pay_period_id) == FALSE) {
         UserGenericStatusFactory::queueGenericStatus($this->getUserObject()->getFullName(TRUE) . ' - ' . TTi18n::gettext('Pay Stub'), 10, TTi18n::gettext('Pay Period is invalid!'), NULL);
         return FALSE;
     }
     if ($this->getEnableGeneratePayStub() == TRUE) {
         //Find out if a pay stub is already generated for the pay period we are currently in.
         //If it is, delete it so we can start from fresh
         $pslf = TTnew('PayStubListFactory');
         $pslf->getByUserIdAndPayPeriodId($this->getUser(), $pay_period_id);
         foreach ($pslf as $pay_stub) {
             Debug::Text('Found Pay Stub ID: ' . $pay_stub->getId(), __FILE__, __LINE__, __METHOD__, 10);
             //Do not delete PAID pay stubs!
             if ($pay_stub->getStatus() == 10) {
                 Debug::Text('Last Pay Stub Exists: ' . $pay_stub->getId(), __FILE__, __LINE__, __METHOD__, 10);
                 $pay_stub->setDeleted(TRUE);
                 $pay_stub->Save();
             }
         }
         //FIXME: Make sure user isn't already in-active! Otherwise pay stub won't generate.
         //Check if pay stub is already generated as well, if it is, and marked paid, then
         //we can't re-generate it, we need to skip this step.
         Debug::Text('Calculating Pay Stub...', __FILE__, __LINE__, __METHOD__, 10);
         $cps = new CalculatePayStub();
         $cps->setUser($this->getUser());
         $cps->setPayPeriod($pay_period_id);
         $cps->calculate();
         Debug::Text('Done Calculating Pay Stub', __FILE__, __LINE__, __METHOD__, 10);
     } else {
         UserGenericStatusFactory::queueGenericStatus($this->getUserObject()->getFullName(TRUE), 20, TTi18n::gettext('Not generating final pay stub!'), NULL);
     }
     //FIXME: Alert the user if they don't have enough information in TimeTrex to get accurate values.
     //Get insurable hours, earnings, and vacation pay now that the final pay stub is generated
     $ugdlf = TTnew('UserGenericDataListFactory');
     $ugdlf->getByCompanyIdAndScriptAndDefault($this->getUserObject()->getCompany(), $this->getTable());
     if ($ugdlf->getRecordCount() > 0) {
         Debug::Text('Found Company Form Setup!', __FILE__, __LINE__, __METHOD__, 10);
         $ugd_obj = $ugdlf->getCurrent();
         $setup_data = $ugd_obj->getData();
     }
     unset($ugd_obj);
     $absence_policy_ids = array();
     $insurable_earnings_psea_ids = array();
     if (isset($setup_data)) {
         //var_dump($setup_data);
         if (isset($setup_data['insurable_earnings_psea_ids'])) {
             $insurable_earnings_psea_ids = $setup_data['insurable_earnings_psea_ids'];
         } else {
             //Fall back to Total Gross.
             $insurable_earnings_psea_ids = $this->getPayStubEntryAccountLinkObject()->getTotalGross();
         }
         if (isset($setup_data['absence_policy_ids'])) {
             $absence_policy_ids = $setup_data['absence_policy_ids'];
         }
     }
     //Find out the date of how far back we have to go to get insurable values.
     //Insurable Hours
     $insurable_hours_start_date = $this->getInsurablePayPeriodStartDate($this->getInsurableHoursReportPayPeriods());
     //All worked time and overtime is considered insurable.
     $udtlf = TTnew('UserDateTotalListFactory');
     $worked_total_time = $udtlf->getWorkedTimeSumByUserIDAndStartDateAndEndDate($this->getUser(), $insurable_hours_start_date, $this->getLastDate());
     Debug::text('Worked Total Time: ' . $worked_total_time, __FILE__, __LINE__, __METHOD__, 10);
     //User definable absence policies for insurable hours.
     $absence_total_time = $udtlf->getAbsenceTimeSumByUserIDAndAbsenceIDAndStartDateAndEndDate($this->getUser(), $absence_policy_ids, $insurable_hours_start_date, $this->getLastDate());
     Debug::text('Absence Total Time: ' . $absence_total_time, __FILE__, __LINE__, __METHOD__, 10);
     $total_hours = Misc::MoneyFormat(TTDate::getHours($worked_total_time + $absence_total_time), FALSE);
     Debug::Text('Total Insurable Hours: ' . $total_hours, __FILE__, __LINE__, __METHOD__, 10);
     $insurable_earnings_start_date = $this->getInsurablePayPeriodStartDate($this->getInsurableEarningsReportPayPeriods());
     $pself = TTnew('PayStubEntryListFactory');
     $total_earnings = $this->getTotalInsurableEarnings();
     //Note, this includes the current pay stub we just generated
     Debug::Text('Total Insurable Earnings: ' . $total_earnings, __FILE__, __LINE__, __METHOD__, 10);
     UserGenericStatusFactory::queueGenericStatus($this->getUserObject()->getFullName(TRUE) . ' - ' . TTi18n::gettext('Record of Employment'), 30, TTi18n::gettext('Insurable Hours:') . ' ' . $total_hours . ' ' . TTi18n::gettext('Insurable Earnings:') . ' ' . $total_earnings, NULL);
     //ReSave these
     if ($this->getId() != '') {
         $rlf = TTnew('ROEListFactory');
         $rlf->getById($this->getId());
         if ($rlf->getRecordCount() > 0) {
             $roe_obj = $rlf->getCurrent();
             $roe_obj->setInsurableHours($total_hours);
             $roe_obj->setInsurableEarnings($total_earnings);
             if ($roe_obj->isValid()) {
                 $roe_obj->Save();
             }
         }
     }
     return TRUE;
 }
 function calcSystemTotalTime()
 {
     global $profiler;
     $profiler->startTimer("UserDateTotal::calcSystemTotalTime() - Part 1");
     if (is_object($this->getUserDateObject()) and is_object($this->getUserDateObject()->getPayPeriodObject()) and $this->getUserDateObject()->getPayPeriodObject()->getStatus() == 20) {
         Debug::text(' Pay Period is closed!', __FILE__, __LINE__, __METHOD__, 10);
         return FALSE;
     }
     //Take the worked hours, and calculate Total,Regular,Overtime,Premium hours from that.
     //This is where many of the policies will be applied
     //Such as any meal/overtime/premium policies.
     $return_value = FALSE;
     $udtlf = new UserDateTotalListFactory();
     $this->deleteSystemTotalTime();
     //We can't assign a dock absence to a given branch/dept automatically,
     //Because several punches with different branches could fall within a schedule punch pair.
     //Just total up entire day, and entire scheduled time to see if we're over/under
     //FIXME: Handle multiple schedules on a single day better.
     $schedule_total_time = 0;
     $meal_policy_obj = NULL;
     $slf = new ScheduleListFactory();
     $profiler->startTimer("UserDateTotal::calcSystemTotalTime() - Holiday");
     //Check for Holidays
     $holiday_time = 0;
     $hlf = new 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->isEligible($this->getUserDateObject()->getUser())) {
             Debug::text(' User is Eligible for Holiday: ' . $holiday_obj->getName(), __FILE__, __LINE__, __METHOD__, 10);
             $holiday_time = $holiday_obj->getHolidayTime($this->getUserDateObject()->getUser());
             Debug::text(' User average time for Holiday: ' . TTDate::getHours($holiday_time), __FILE__, __LINE__, __METHOD__, 10);
             if ($holiday_time > 0 and $holiday_obj->getHolidayPolicyObject()->getAbsencePolicyID() != FALSE) {
                 Debug::text(' Adding Holiday hours: ' . TTDate::getHours($holiday_time), __FILE__, __LINE__, __METHOD__, 10);
                 $udtf = new UserDateTotalFactory();
                 $udtf->setUserDateID($this->getUserDateID());
                 $udtf->setStatus(30);
                 //Absence
                 $udtf->setType(10);
                 //Total
                 $udtf->setBranch($this->getUserDateObject()->getUserObject()->getDefaultBranch());
                 $udtf->setDepartment($this->getUserDateObject()->getUserObject()->getDefaultDepartment());
                 $udtf->setAbsencePolicyID($holiday_obj->getHolidayPolicyObject()->getAbsencePolicyID());
                 $udtf->setTotalTime($holiday_time);
                 $udtf->setEnableCalcSystemTotalTime(FALSE);
                 if ($udtf->isValid()) {
                     $udtf->Save();
                 }
             }
         }
         $slf->getByUserDateIdAndStatusId($this->getUserDateID(), 20);
         $schedule_absence_total_time = 0;
         if ($slf->getRecordCount() > 0) {
             //Check for schedule policy
             foreach ($slf as $s_obj) {
                 Debug::text(' Schedule Absence Total Time: ' . $s_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                 $schedule_absence_total_time += $s_obj->getTotalTime();
                 if (is_object($s_obj->getSchedulePolicyObject()) and $s_obj->getSchedulePolicyObject()->getAbsencePolicyID() > 0) {
                     $holiday_absence_policy_id = $s_obj->getSchedulePolicyObject()->getAbsencePolicyID();
                     Debug::text(' Found Absence Policy for docking: ' . $holiday_absence_policy_id, __FILE__, __LINE__, __METHOD__, 10);
                 } else {
                     Debug::text(' NO Absence Policy : ', __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
         }
         $holiday_total_under_time = $schedule_absence_total_time - $holiday_time;
         if (isset($holiday_absence_policy_id) and $holiday_total_under_time > 0) {
             Debug::text(' Schedule Under Time Case: ' . $holiday_total_under_time, __FILE__, __LINE__, __METHOD__, 10);
             $udtf = new UserDateTotalFactory();
             $udtf->setUserDateID($this->getUserDateID());
             $udtf->setStatus(30);
             //Absence
             $udtf->setType(10);
             //Total
             $udtf->setBranch($this->getUserDateObject()->getUserObject()->getDefaultBranch());
             $udtf->setDepartment($this->getUserDateObject()->getUserObject()->getDefaultDepartment());
             $udtf->setAbsencePolicyID($holiday_absence_policy_id);
             $udtf->setTotalTime($holiday_total_under_time);
             $udtf->setEnableCalcSystemTotalTime(FALSE);
             if ($udtf->isValid()) {
                 $udtf->Save();
             }
         }
         unset($holiday_total_under_time, $holiday_absence_policy_id, $schedule_absence_total_time);
     }
     $profiler->stopTimer("UserDateTotal::calcSystemTotalTime() - Holiday");
     //Do this after holiday policies have been applied, so if someone
     //schedules a holiday manually, we don't double up on the time.
     $slf->getByUserDateId($this->getUserDateID());
     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);
             if ($s_obj->getStatus() == 20 and $s_obj->getAbsencePolicyID() != '') {
                 Debug::text(' Scheduled Absence Found of Total Time: ' . $s_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                 //If a holiday policy is applied on this day, ignore the schedule so we don't duplicate it.
                 //We could take the difference, and use the greatest of the two,
                 //But I think that will just open the door for errors.
                 if (!isset($holiday_obj) or $holiday_time == 0 and is_object($holiday_obj) and $holiday_obj->getHolidayPolicyObject()->getAbsencePolicyID() != $s_obj->getAbsencePolicyID()) {
                     $udtf = new UserDateTotalFactory();
                     $udtf->setUserDateID($this->getUserDateID());
                     $udtf->setStatus(30);
                     //Absence
                     $udtf->setType(10);
                     //Total
                     $udtf->setBranch($s_obj->getBranch());
                     $udtf->setDepartment($s_obj->getDepartment());
                     $udtf->setJob($s_obj->getJob());
                     $udtf->setJobItem($s_obj->getJobItem());
                     $udtf->setAbsencePolicyID($s_obj->getAbsencePolicyID());
                     $udtf->setTotalTime($s_obj->getTotalTime());
                     $udtf->setEnableCalcSystemTotalTime(FALSE);
                     if ($udtf->isValid()) {
                         $udtf->Save();
                     }
                 } else {
                     Debug::text(' Holiday Time Found, ignoring schedule!', __FILE__, __LINE__, __METHOD__, 10);
                 }
             } elseif ($s_obj->getStatus() == 10) {
                 $schedule_total_time += $s_obj->getTotalTime();
                 if (is_object($s_obj->getSchedulePolicyObject())) {
                     $schedule_absence_policy_id = $s_obj->getSchedulePolicyObject()->getAbsencePolicyID();
                     $meal_policy_obj = $s_obj->getSchedulePolicyObject()->getMealPolicyObject();
                     Debug::text(' Found Absence Policy for docking: ' . $schedule_absence_policy_id, __FILE__, __LINE__, __METHOD__, 10);
                 } else {
                     Debug::text(' NO Absence Policy : ', __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
         }
     } else {
         Debug::text(' No Schedules found. ', __FILE__, __LINE__, __METHOD__, 10);
     }
     unset($s_obj);
     unset($holiday_time, $holiday_obj);
     //Handle Meal Policy time.
     //Do this after schedule meal policies have been looked up, as those override any policy group meal policies.
     $meal_policy_time = $this->calcMealPolicyTotalTime($meal_policy_obj);
     $udt_meal_policy_adjustment_arr = $this->calcUserTotalMealPolicyAdjustment($meal_policy_time);
     //Debug::Arr($udt_meal_policy_adjustment_arr, 'UserDateTotal Meal Policy Adjustment: ', __FILE__, __LINE__, __METHOD__,10);
     $break_policy_time = $this->calcBreakPolicyTotalTime();
     $udt_break_policy_adjustment_arr = $this->calcUserTotalBreakPolicyAdjustment($break_policy_time);
     //Debug::Arr($udt_break_policy_adjustment_arr, 'UserDateTotal Break Policy Adjustment: ', __FILE__, __LINE__, __METHOD__,10);
     $daily_total_time = $this->getDailyTotalTime();
     Debug::text(' Daily Total Time: ' . $daily_total_time . ' Schedule Total Time: ' . $schedule_total_time, __FILE__, __LINE__, __METHOD__, 10);
     //Check for overtime policies or undertime absence policies
     if ($daily_total_time > $schedule_total_time) {
         Debug::text(' Schedule Over Time Case: ', __FILE__, __LINE__, __METHOD__, 10);
     } elseif (isset($schedule_absence_policy_id) and $schedule_absence_policy_id != '' and $daily_total_time < $schedule_total_time) {
         $total_under_time = bcsub($schedule_total_time, $daily_total_time);
         if ($total_under_time > 0) {
             Debug::text(' Schedule Under Time Case: ' . $total_under_time . ' Absence Policy ID: ' . $schedule_absence_policy_id, __FILE__, __LINE__, __METHOD__, 10);
             $udtf = new UserDateTotalFactory();
             $udtf->setUserDateID($this->getUserDateID());
             $udtf->setStatus(30);
             //Absence
             $udtf->setType(10);
             //Total
             $udtf->setBranch($this->getUserDateObject()->getUserObject()->getDefaultBranch());
             $udtf->setDepartment($this->getUserDateObject()->getUserObject()->getDefaultDepartment());
             $udtf->setAbsencePolicyID($schedule_absence_policy_id);
             $udtf->setTotalTime($total_under_time);
             $udtf->setEnableCalcSystemTotalTime(FALSE);
             if ($udtf->isValid()) {
                 $udtf->Save();
             }
         } else {
             Debug::text(' Schedule Under Time is a negative value, skipping dock time: ' . $total_under_time . ' Absence Policy ID: ' . $schedule_absence_policy_id, __FILE__, __LINE__, __METHOD__, 10);
         }
     } else {
         Debug::text(' No Dock Absenses', __FILE__, __LINE__, __METHOD__, 10);
     }
     unset($schedule_absence_policy_id);
     //Do this AFTER the UnderTime absence policy is submitted.
     $recalc_daily_total_time = $this->calcAbsencePolicyTotalTime();
     if ($recalc_daily_total_time == TRUE) {
         //Total up all "worked" hours for the day again, this time include
         //Paid Absences.
         $daily_total_time = $this->getDailyTotalTime();
         //$daily_total_time = $udtlf->getTotalSumByUserDateID( $this->getUserDateID() );
         Debug::text('ReCalc Daily Total Time for Day: ' . $daily_total_time, __FILE__, __LINE__, __METHOD__, 10);
     }
     $profiler->stopTimer("UserDateTotal::calcSystemTotalTime() - Part 1");
     $user_data_total_compact_arr = $this->calcOverTimePolicyTotalTime($udt_meal_policy_adjustment_arr, $udt_break_policy_adjustment_arr);
     //Debug::Arr($user_data_total_compact_arr, 'User Data Total Compact Array: ', __FILE__, __LINE__, __METHOD__, 10);
     //Insert User Date Total rows for each compacted array entry.
     //The reason for compacting is to reduce the amount of rows as much as possible.
     if (is_array($user_data_total_compact_arr)) {
         $profiler->startTimer("UserDateTotal::calcSystemTotalTime() - Part 2");
         Debug::text('Compact Array Exists: ', __FILE__, __LINE__, __METHOD__, 10);
         foreach ($user_data_total_compact_arr as $type_id => $udt_arr) {
             Debug::text('Compact Array Entry: Type ID: ' . $type_id, __FILE__, __LINE__, __METHOD__, 10);
             if ($type_id == 20) {
                 //Regular Time
                 //Debug::text('Compact Array Entry: Branch ID: '. $udt_arr[' , __FILE__, __LINE__, __METHOD__, 10);
                 foreach ($udt_arr as $branch_id => $branch_arr) {
                     //foreach($branch_arr as $department_id => $total_time ) {
                     foreach ($branch_arr as $department_id => $department_arr) {
                         foreach ($department_arr as $job_id => $job_arr) {
                             foreach ($job_arr as $job_item_id => $data_arr) {
                                 Debug::text('Compact Array Entry: Regular Time - Branch ID: ' . $branch_id . ' Department ID: ' . $department_id . ' Job ID: ' . $job_id . ' Job Item ID: ' . $job_item_id . ' Total Time: ' . $data_arr['total_time'], __FILE__, __LINE__, __METHOD__, 10);
                                 $user_data_total_expanded[] = array('type_id' => $type_id, 'over_time_policy_id' => NULL, 'branch_id' => $branch_id, 'department_id' => $department_id, 'job_id' => $job_id, 'job_item_id' => $job_item_id, 'total_time' => $data_arr['total_time'], 'quantity' => $data_arr['quantity'], 'bad_quantity' => $data_arr['bad_quantity']);
                             }
                         }
                     }
                 }
             } else {
                 //Overtime
                 //Overtime array is completely different then regular time array!
                 foreach ($udt_arr as $over_time_policy_id => $policy_arr) {
                     foreach ($policy_arr as $branch_id => $branch_arr) {
                         //foreach($branch_arr as $department_id => $total_time ) {
                         foreach ($branch_arr as $department_id => $department_arr) {
                             foreach ($department_arr as $job_id => $job_arr) {
                                 foreach ($job_arr as $job_item_id => $data_arr) {
                                     Debug::text('Compact Array Entry: Policy ID: ' . $over_time_policy_id . ' Branch ID: ' . $branch_id . ' Department ID: ' . $department_id . ' Job ID: ' . $job_id . ' Job Item ID: ' . $job_item_id . ' Total Time: ' . $data_arr['total_time'], __FILE__, __LINE__, __METHOD__, 10);
                                     $user_data_total_expanded[] = array('type_id' => $type_id, 'over_time_policy_id' => $over_time_policy_id, 'branch_id' => $branch_id, 'department_id' => $department_id, 'job_id' => $job_id, 'job_item_id' => $job_item_id, 'total_time' => $data_arr['total_time'], 'quantity' => $data_arr['quantity'], 'bad_quantity' => $data_arr['bad_quantity']);
                                 }
                             }
                         }
                     }
                 }
             }
             unset($policy_arr, $branch_arr, $department_arr, $job_arr, $over_time_policy_id, $branch_id, $department_id, $job_id, $job_item_id, $data_arr);
         }
         $profiler->stopTimer("UserDateTotal::calcSystemTotalTime() - Part 2");
         //var_dump($user_data_total_expanded);
         //Do the actual inserts now.
         if (isset($user_data_total_expanded)) {
             foreach ($user_data_total_expanded as $data_arr) {
                 $profiler->startTimer("UserDateTotal::calcSystemTotalTime() - Part 2b");
                 Debug::text('Inserting from expanded array, Type ID: ' . $data_arr['type_id'], __FILE__, __LINE__, __METHOD__, 10);
                 $udtf = new UserDateTotalFactory();
                 $udtf->setUserDateID($this->getUserDateID());
                 $udtf->setStatus(10);
                 //System
                 $udtf->setType($data_arr['type_id']);
                 if (isset($data_arr['over_time_policy_id'])) {
                     $udtf->setOverTimePolicyId($data_arr['over_time_policy_id']);
                 }
                 $udtf->setBranch($data_arr['branch_id']);
                 $udtf->setDepartment($data_arr['department_id']);
                 $udtf->setJob($data_arr['job_id']);
                 $udtf->setJobItem($data_arr['job_item_id']);
                 $udtf->setQuantity($data_arr['quantity']);
                 $udtf->setBadQuantity($data_arr['bad_quantity']);
                 $udtf->setTotalTime($data_arr['total_time']);
                 $udtf->setEnableCalcSystemTotalTime(FALSE);
                 if ($udtf->isValid()) {
                     $udtf->Save();
                 } else {
                     Debug::text('aINVALID UserDateTotal Entry!!: ', __FILE__, __LINE__, __METHOD__, 10);
                 }
                 $profiler->stopTimer("UserDateTotal::calcSystemTotalTime() - Part 2b");
             }
             unset($user_data_total_expanded);
         }
     } else {
         $profiler->startTimer("UserDateTotal::calcSystemTotalTime() - Part 3");
         //We need to break this out by branch, dept, job, task
         $udtlf = new UserDateTotalListFactory();
         //FIXME: Should Absence time be included as "regular time". We do this on
         //the timesheet view manually as of 12-Jan-06. If we included it in the
         //regular time system totals, we wouldn't have to do it manually.
         //$udtlf->getByUserDateIdAndStatus( $this->getUserDateID(), array(20,30) );
         $udtlf->getByUserDateIdAndStatus($this->getUserDateID(), array(20));
         if ($udtlf->getRecordCount() > 0) {
             Debug::text('Found Total Hours for just regular time: Record Count: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
             $user_date_regular_time_compact_arr = NULL;
             foreach ($udtlf as $udt_obj) {
                 //Create compact array, so we don't make as many system entries.
                 //Check if this is a paid absence or not.
                 if ($udt_obj->getStatus() == 20 and $udt_obj->getTotalTime() > 0) {
                     $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()]);
                     }
                     if (isset($user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()])) {
                         Debug::text('&nbsp;&nbsp;&nbsp;&nbsp; Adding to Compact Array: Regular Time -  Branch: ' . (int) $udt_obj->getBranch() . ' Department: ' . (int) $udt_obj->getDepartment(), __FILE__, __LINE__, __METHOD__, 10);
                         $user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['total_time'] += $udt_total_time;
                         $user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['quantity'] += $udt_obj->getQuantity();
                         $user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['bad_quantity'] += $udt_obj->getBadQuantity();
                     } else {
                         $user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()] = array('total_time' => $udt_total_time, 'quantity' => $udt_obj->getQuantity(), 'bad_quantity' => $udt_obj->getBadQuantity());
                     }
                     unset($udt_total_time);
                 } else {
                     Debug::text('Total Time is 0!!: ' . $udt_obj->getTotalTime() . ' Or its an UNPAID absence: ' . $udt_obj->getStatus(), __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
             if (isset($user_date_regular_time_compact_arr)) {
                 foreach ($user_date_regular_time_compact_arr as $branch_id => $branch_arr) {
                     //foreach($branch_arr as $department_id => $total_time ) {
                     foreach ($branch_arr as $department_id => $department_arr) {
                         foreach ($department_arr as $job_id => $job_arr) {
                             foreach ($job_arr as $job_item_id => $data_arr) {
                                 Debug::text('Compact Array Entry: bRegular Time - Branch ID: ' . $branch_id . ' Department ID: ' . $department_id . ' Job ID: ' . $job_id . ' Job Item ID: ' . $job_item_id . ' Total Time: ' . $data_arr['total_time'], __FILE__, __LINE__, __METHOD__, 10);
                                 $udtf = new UserDateTotalFactory();
                                 $udtf->setUserDateID($this->getUserDateID());
                                 $udtf->setStatus(10);
                                 //System
                                 $udtf->setType(20);
                                 //Regular
                                 $udtf->setBranch($branch_id);
                                 $udtf->setDepartment($department_id);
                                 $udtf->setJob($job_id);
                                 $udtf->setJobItem($job_item_id);
                                 $udtf->setQuantity($data_arr['quantity']);
                                 $udtf->setBadQuantity($data_arr['bad_quantity']);
                                 $udtf->setTotalTime($data_arr['total_time']);
                                 $udtf->setEnableCalcSystemTotalTime(FALSE);
                                 $udtf->Save();
                             }
                         }
                     }
                 }
             }
             unset($user_date_regular_time_compact_arr);
         }
     }
     //Handle Premium time.
     $this->calcPremiumPolicyTotalTime($udt_meal_policy_adjustment_arr, $udt_break_policy_adjustment_arr, $daily_total_time);
     //Total Hours
     $udtf = new UserDateTotalFactory();
     $udtf->setUserDateID($this->getUserDateID());
     $udtf->setStatus(10);
     //System
     $udtf->setType(10);
     //Total
     $udtf->setTotalTime($daily_total_time);
     $udtf->setEnableCalcSystemTotalTime(FALSE);
     if ($udtf->isValid()) {
         $return_value = $udtf->Save();
     } else {
         $return_value = FALSE;
     }
     $profiler->stopTimer("UserDateTotal::calcSystemTotalTime() - Part 3");
     if ($this->getEnableCalcException() == TRUE) {
         ExceptionPolicyFactory::calcExceptions($this->getUserDateID(), $this->getEnablePreMatureException());
     }
     return $return_value;
 }
 function _getData($format = NULL)
 {
     $this->tmp_data = array('schedule' => array(), 'user' => array(), 'total_shift' => array());
     $columns = $this->getColumnDataConfig();
     $filter_data = $this->getFilterConfig();
     if ($this->getPermissionObject()->Check('schedule', 'view') == FALSE or $this->getPermissionObject()->Check('wage', 'view') == FALSE) {
         $hlf = TTnew('HierarchyListFactory');
         $permission_children_ids = $wage_permission_children_ids = $hlf->getHierarchyChildrenByCompanyIdAndUserIdAndObjectTypeID($this->getUserObject()->getCompany(), $this->getUserObject()->getID());
         Debug::Arr($permission_children_ids, 'Permission Children Ids:', __FILE__, __LINE__, __METHOD__, 10);
     } else {
         //Get Permission Hierarchy Children first, as this can be used for viewing, or editing.
         $permission_children_ids = array();
         $wage_permission_children_ids = array();
     }
     if ($this->getPermissionObject()->Check('schedule', 'view') == FALSE) {
         if ($this->getPermissionObject()->Check('schedule', 'view_child') == FALSE) {
             $permission_children_ids = array();
         }
         if ($this->getPermissionObject()->Check('schedule', 'view_own')) {
             $permission_children_ids[] = $this->getUserObject()->getID();
         }
         $filter_data['permission_children_ids'] = $permission_children_ids;
     }
     //Get Wage Permission Hierarchy Children first, as this can be used for viewing, or editing.
     if ($this->getPermissionObject()->Check('wage', 'view') == TRUE) {
         $wage_permission_children_ids = TRUE;
     } elseif ($this->getPermissionObject()->Check('wage', 'view') == FALSE) {
         if ($this->getPermissionObject()->Check('wage', 'view_child') == FALSE) {
             $wage_permission_children_ids = array();
         }
         if ($this->getPermissionObject()->Check('wage', 'view_own')) {
             $wage_permission_children_ids[] = $this->getUserObject()->getID();
         }
     }
     //Debug::Text(' Permission Children: '. count($permission_children_ids) .' Wage Children: '. count($wage_permission_children_ids), __FILE__, __LINE__, __METHOD__,10);
     //Debug::Arr($permission_children_ids, 'Permission Children: '. count($permission_children_ids), __FILE__, __LINE__, __METHOD__,10);
     //Debug::Arr($wage_permission_children_ids, 'Wage Children: '. count($wage_permission_children_ids), __FILE__, __LINE__, __METHOD__,10);
     if ($this->getUserObject()->getCompanyObject()->getProductEdition() >= TT_PRODUCT_CORPORATE) {
         $jlf = TTnew('JobListFactory');
         $job_status_options = $jlf->getOptions('status');
     } else {
         $job_status_options = array();
     }
     $pay_period_ids = array();
     if (strpos($format, 'schedule') === FALSE) {
         //Avoid running these queries when printing out the schedule.
         $slf = TTnew('ScheduleListFactory');
         $slf->getScheduleSummaryReportByCompanyIdAndArrayCriteria($this->getUserObject()->getCompany(), $filter_data, NULL, NULL, NULL, array('last_name' => 'asc'));
         //Sort by last name mainly for the PDF schedule for printing.
         Debug::Text(' Total Rows: ' . $slf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
         $this->getProgressBarObject()->start($this->getAMFMessageID(), $slf->getRecordCount(), NULL, TTi18n::getText('Retrieving Data...'));
         if ($slf->getRecordCount() > 0) {
             foreach ($slf as $key => $s_obj) {
                 $hourly_rate = 0;
                 if ($wage_permission_children_ids === TRUE or in_array($s_obj->getColumn('user_id'), $wage_permission_children_ids)) {
                     $hourly_rate = $s_obj->getColumn('user_wage_hourly_rate');
                 }
                 $date_stamp_epoch = TTDate::strtotime($s_obj->getColumn('date_stamp'));
                 $shift_arr = array('user_id' => $s_obj->getColumn('user_id'), 'status_id' => $s_obj->getColumn('status_id'), 'group' => $s_obj->getColumn('group'), 'default_branch' => $s_obj->getColumn('default_branch'), 'default_department' => $s_obj->getColumn('default_department'), 'branch' => $s_obj->getColumn('branch'), 'department' => $s_obj->getColumn('department'), 'job' => $s_obj->getColumn('job'), 'job_status_id' => Option::getByKey($s_obj->getColumn('job_status_id'), $job_status_options, NULL), 'job_manual_id' => $s_obj->getColumn('job_manual_id'), 'job_description' => $s_obj->getColumn('job_description'), 'job_branch' => $s_obj->getColumn('job_branch'), 'job_department' => $s_obj->getColumn('job_department'), 'job_group' => $s_obj->getColumn('job_group'), 'job_item' => $s_obj->getColumn('job_item'), 'quantity' => $s_obj->getColumn('quantity'), 'bad_quantity' => $s_obj->getColumn('bad_quantity'), 'total_time' => $s_obj->getColumn('total_time'), 'total_time_wage' => Misc::MoneyFormat(bcmul(TTDate::getHours($s_obj->getColumn('total_time')), $hourly_rate), FALSE), 'total_time_wage_burden' => Misc::MoneyFormat(bcmul(TTDate::getHours($s_obj->getColumn('total_time')), bcmul($hourly_rate, bcdiv($s_obj->getColumn('user_labor_burden_percent'), 100))), FALSE), 'total_time_wage_with_burden' => Misc::MoneyFormat(bcmul(TTDate::getHours($s_obj->getColumn('total_time')), bcmul($hourly_rate, bcadd(bcdiv($s_obj->getColumn('user_labor_burden_percent'), 100), 1))), FALSE), 'other_id1' => $s_obj->getColumn('other_id1'), 'other_id2' => $s_obj->getColumn('other_id2'), 'other_id3' => $s_obj->getColumn('other_id3'), 'other_id4' => $s_obj->getColumn('other_id4'), 'other_id5' => $s_obj->getColumn('other_id5'), 'date_stamp' => $date_stamp_epoch, 'schedule_policy' => $s_obj->getColumn('schedule_policy'), 'absence_policy' => $s_obj->getColumn('absence_policy'), 'schedule_status' => Option::getByKey($s_obj->getStatus(), $s_obj->getOptions('status'), NULL), 'start_time' => TTDate::strtotime($s_obj->getColumn('start_time')), 'end_time' => TTDate::strtotime($s_obj->getColumn('end_time')), 'user_wage_id' => $s_obj->getColumn('user_wage_id'), 'hourly_rate' => Misc::MoneyFormat($hourly_rate, FALSE), 'pay_period_start_date' => strtotime($s_obj->getColumn('pay_period_start_date')), 'pay_period_end_date' => strtotime($s_obj->getColumn('pay_period_end_date')), 'pay_period_transaction_date' => strtotime($s_obj->getColumn('pay_period_transaction_date')), 'pay_period' => strtotime($s_obj->getColumn('pay_period_transaction_date')), 'pay_period_id' => $s_obj->getColumn('pay_period_id'), 'schedule_note' => $s_obj->getColumn('note'), 'total_shift' => 1);
                 unset($hourly_rate);
                 $this->tmp_data['schedule'][$s_obj->getColumn('user_id')][] = $shift_arr;
                 $this->getProgressBarObject()->set($this->getAMFMessageID(), $key);
             }
         }
         //Debug::Arr($this->tmp_data['schedule'], 'Schedule Raw Data: ', __FILE__, __LINE__, __METHOD__,10);
         //Debug::Arr($this->form_data, 'Schedule Raw Data: ', __FILE__, __LINE__, __METHOD__,10);
     }
     unset($filter_data['status_id']);
     //This is for schedule status, not user status.
     //If we're printing the schedule, make sure we include the required columns.
     if (in_array($format, $this->special_output_format)) {
         $this->config['columns_data']['first_name'] = TRUE;
         $this->config['columns_data']['last_name'] = TRUE;
     }
     //Get user data for joining.
     $ulf = TTnew('UserListFactory');
     $ulf->getAPISearchByCompanyIdAndArrayCriteria($this->getUserObject()->getCompany(), $filter_data);
     Debug::Text(' User Total Rows: ' . $ulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     $this->getProgressBarObject()->start($this->getAMFMessageID(), $ulf->getRecordCount(), NULL, TTi18n::getText('Retrieving Data...'));
     foreach ($ulf as $key => $u_obj) {
         $this->tmp_data['user'][$u_obj->getId()] = $this->form_data['user'][$u_obj->getId()] = (array) $u_obj->getObjectAsArray($this->getColumnDataConfig());
         $this->getProgressBarObject()->set($this->getAMFMessageID(), $key);
     }
     //Add OPEN user to the list so it can printed on schedules.
     $this->tmp_data['user'][0] = $this->form_data['user'][0] = array('first_name' => TTi18n::getText('OPEN'), 'last_name' => '');
     //Debug::Arr($this->tmp_data['user'], 'User Raw Data: ', __FILE__, __LINE__, __METHOD__,10);
     return TRUE;
 }
 function isActiveLengthOfService($u_obj, $epoch)
 {
     if ($this->getMinimumLengthOfServiceUnit() == 50 or $this->getMaximumLengthOfServiceUnit() == 50) {
         //Hour based length of service, get users hours up until this period.
         $worked_time = TTDate::getHours($this->getWorkedTimeByUserIdAndEndDate($u_obj->getId(), $epoch));
         Debug::Text('&nbsp;&nbsp;Worked Time: ' . $worked_time . 'hrs', __FILE__, __LINE__, __METHOD__, 10);
     }
     $employed_days = TTDate::getDays($epoch - $u_obj->getHireDate());
     Debug::Text('&nbsp;&nbsp;Employed Days: ' . $employed_days, __FILE__, __LINE__, __METHOD__, 10);
     $minimum_length_of_service_result = FALSE;
     $maximum_length_of_service_result = FALSE;
     //Check minimum length of service
     if ($this->getMinimumLengthOfService() == 0 or $this->getMinimumLengthOfServiceUnit() == 50 and $worked_time >= $this->getMinimumLengthOfService() or $this->getMinimumLengthOfServiceUnit() != 50 and $employed_days >= $this->getMinimumLengthOfServiceDays()) {
         $minimum_length_of_service_result = TRUE;
     }
     //Check maximum length of service.
     if ($this->getMaximumLengthOfService() == 0 or $this->getMaximumLengthOfServiceUnit() == 50 and $worked_time <= $this->getMaximumLengthOfService() or $this->getMaximumLengthOfServiceUnit() != 50 and $employed_days <= $this->getMaximumLengthOfServiceDays()) {
         $maximum_length_of_service_result = TRUE;
     }
     Debug::Text('&nbsp;&nbsp; Min Result: : ' . (int) $minimum_length_of_service_result . ' Max Result: ' . (int) $maximum_length_of_service_result, __FILE__, __LINE__, __METHOD__, 10);
     if ($minimum_length_of_service_result == TRUE and $maximum_length_of_service_result == TRUE) {
         return TRUE;
     }
     return FALSE;
 }
 function getAverageTime($user_id)
 {
     $udtlf = new UserDateTotalListFactory();
     //Check if Min and Max time is the same, if so we can skip any averaging.
     if ($this->getHolidayPolicyObject()->getMinimumTime() > 0 and $this->getHolidayPolicyObject()->getMaximumTime() > 0 and $this->getHolidayPolicyObject()->getMinimumTime() == $this->getHolidayPolicyObject()->getMaximumTime()) {
         Debug::text('Min and Max times are equal.', __FILE__, __LINE__, __METHOD__, 10);
         return $this->getHolidayPolicyObject()->getMinimumTime();
     }
     if ($this->getHolidayPolicyObject()->getAverageTimeWorkedDays() == TRUE) {
         $last_days_worked_count = $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
     } else {
         Debug::text('NOT Using worked days!', __FILE__, __LINE__, __METHOD__, 10);
         $last_days_worked_count = $this->getHolidayPolicyObject()->getAverageTimeDays();
     }
     Debug::text('Last Days Worked:' . $last_days_worked_count, __FILE__, __LINE__, __METHOD__, 10);
     if ($this->getHolidayPolicyObject()->getIncludeOverTime() == TRUE) {
         Debug::text('Including OverTime!', __FILE__, __LINE__, __METHOD__, 10);
         $total_seconds_worked = $udtlf->getWorkedTimeSumByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
     } else {
         Debug::text('NOT Including OverTime!', __FILE__, __LINE__, __METHOD__, 10);
         $total_seconds_worked = $udtlf->getRegularTimeSumByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
     }
     if ($this->getHolidayPolicyObject()->getIncludePaidAbsenceTime() == TRUE) {
         Debug::text('Including Paid Absence Time!', __FILE__, __LINE__, __METHOD__, 10);
         $total_seconds_worked += $udtlf->getPaidAbsenceTimeSumByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
     } else {
         Debug::text('NOT Including Paid Absence Time!', __FILE__, __LINE__, __METHOD__, 10);
     }
     if ($last_days_worked_count > 0) {
         $avg_seconds_worked_per_day = bcdiv($total_seconds_worked, $last_days_worked_count);
         Debug::text('AVG hours worked per day:' . TTDate::getHours($avg_seconds_worked_per_day), __FILE__, __LINE__, __METHOD__, 10);
     } else {
         $avg_seconds_worked_per_day = 0;
     }
     if ($this->getHolidayPolicyObject()->getMaximumTime() > 0 and $avg_seconds_worked_per_day > $this->getHolidayPolicyObject()->getMaximumTime()) {
         $avg_seconds_worked_per_day = $this->getHolidayPolicyObject()->getMaximumTime();
         Debug::text('AVG hours worked per day exceeds maximum regulars hours per day, setting to:' . $avg_seconds_worked_per_day / 60 / 60, __FILE__, __LINE__, __METHOD__, 10);
     }
     if ($avg_seconds_worked_per_day < $this->getHolidayPolicyObject()->getMinimumTime()) {
         $avg_seconds_worked_per_day = $this->getHolidayPolicyObject()->getMinimumTime();
         Debug::text('AVG hours worked per day is less then minimum regulars hours per day, setting to:' . $avg_seconds_worked_per_day / 60 / 60, __FILE__, __LINE__, __METHOD__, 10);
     }
     //Round to nearest 15mins.
     if ((int) $this->getHolidayPolicyObject()->getRoundIntervalPolicyID() != 0 and is_object($this->getHolidayPolicyObject()->getRoundIntervalPolicyObject())) {
         $avg_seconds_worked_per_day = TTDate::roundTime($avg_seconds_worked_per_day, $this->getHolidayPolicyObject()->getRoundIntervalPolicyObject()->getInterval(), $this->getHolidayPolicyObject()->getRoundIntervalPolicyObject()->getRoundType());
         Debug::text('Rounding Stat Time To: ' . $avg_seconds_worked_per_day, __FILE__, __LINE__, __METHOD__, 10);
     } else {
         Debug::text('NOT Rounding Stat Time!', __FILE__, __LINE__, __METHOD__, 10);
     }
     return $avg_seconds_worked_per_day;
 }
Esempio n. 9
0
     $filter_data['job_item_ids'] = array(-1);
 }
 //$plf->getReportByStartDateAndEndDateAndUserIdListAndBranchIdAndDepartmentIdAndJobIdListAndJobItemIdList( $filter_data['start_date'], $filter_data['end_date'], $filter_data['user_ids'], $filter_data['punch_branch_ids'], $filter_data['punch_department_ids'], $filter_data['job_ids'], $filter_data['job_item_ids'] );
 $plf->getSearchByCompanyIdAndArrayCriteria($current_company->getId(), $filter_data);
 foreach ($plf as $p_obj) {
     //Debug::Text('User ID: '. $p_obj->getColumn('user_id') .' Status ID: '. $p_obj->getColumn('status_id') .' Time Stamp: '. TTDate::getDate('DATE+TIME', TTDate::strtotime( $p_obj->getColumn('punch_time_stamp') ) ), __FILE__, __LINE__, __METHOD__,10);
     if (!isset($tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')])) {
         $hourly_rate = 0;
         if ($permission->Check('wage', 'view') == TRUE or in_array($p_obj->getColumn('user_id'), $wage_filter_data['permission_children_ids']) == TRUE) {
             $uw_obj = getUserWageObject($p_obj->getColumn('user_wage_id'), $p_obj->getColumn('user_id'));
             if (is_object($uw_obj)) {
                 $hourly_rate = $uw_obj->getHourlyRate();
             }
         }
         $actual_time_diff = (int) $p_obj->getColumn('actual_total_time') - (int) $p_obj->getColumn('total_time');
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')] = array('user_id' => $p_obj->getColumn('user_id'), 'group_id' => $p_obj->getColumn('group_id'), 'branch_id' => $p_obj->getColumn('branch_id'), 'department_id' => $p_obj->getColumn('department_id'), 'job_id' => $p_obj->getColumn('job_id'), 'job_name' => $p_obj->getColumn('job_name'), 'job_status_id' => $p_obj->getColumn('job_status_id'), 'job_manual_id' => $p_obj->getColumn('job_manual_id'), 'job_description' => $p_obj->getColumn('job_description'), 'job_branch_id' => $p_obj->getColumn('job_branch_id'), 'job_department_id' => $p_obj->getColumn('job_department_id'), 'job_group_id' => $p_obj->getColumn('job_group_id'), 'job_item_id' => $p_obj->getColumn('job_item_id'), 'quantity' => $p_obj->getColumn('quantity'), 'bad_quantity' => $p_obj->getColumn('bad_quantity'), 'note' => $p_obj->getColumn('note'), 'total_time' => $p_obj->getColumn('total_time'), 'total_time_wage' => Misc::MoneyFormat(bcmul(TTDate::getHours($p_obj->getColumn('total_time')), $hourly_rate), FALSE), 'actual_total_time' => $p_obj->getColumn('actual_total_time'), 'actual_total_time_diff' => $actual_time_diff, 'actual_total_time_wage' => Misc::MoneyFormat(bcmul(TTDate::getHours($p_obj->getColumn('actual_total_time')), $hourly_rate), FALSE), 'actual_total_time_diff_wage' => Misc::MoneyFormat(bcmul(TTDate::getHours($actual_time_diff), $hourly_rate)), 'other_id1' => $p_obj->getColumn('other_id1'), 'other_id2' => $p_obj->getColumn('other_id2'), 'other_id3' => $p_obj->getColumn('other_id3'), 'other_id4' => $p_obj->getColumn('other_id4'), 'other_id5' => $p_obj->getColumn('other_id5'), 'date_stamp' => TTDate::strtotime($p_obj->getColumn('date_stamp')), 'in_time_stamp' => NULL, 'in_actual_time_stamp' => NULL, 'in_type' => NULL, 'out_time_stamp' => NULL, 'out_actual_time_stamp' => NULL, 'out_type' => NULL, 'user_wage_id' => $p_obj->getColumn('user_wage_id'), 'hourly_rate' => Misc::MoneyFormat($hourly_rate, FALSE), 'in_station_type_id' => NULL, 'in_station_station_id' => NULL, 'in_station_source' => NULL, 'in_station_description' => NULL, 'out_station_type_id' => NULL, 'out_station_station_id' => NULL, 'out_station_source' => NULL, 'out_station_description' => NULL);
     }
     if ($p_obj->getColumn('status_id') == 10) {
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_time_stamp'] = TTDate::strtotime($p_obj->getColumn('time_stamp'));
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_type'] = $p_obj->getColumn('type_id');
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_actual_time_stamp'] = TTDate::strtotime($p_obj->getColumn('actual_time_stamp'));
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_station_type_id'] = $p_obj->getColumn('station_type_id');
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_station_station_id'] = $p_obj->getColumn('station_station_id');
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_station_source'] = $p_obj->getColumn('station_source');
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_station_description'] = $p_obj->getColumn('station_description');
     } else {
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_time_stamp'] = TTDate::strtotime($p_obj->getColumn('time_stamp'));
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_type'] = $p_obj->getColumn('type_id');
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_actual_time_stamp'] = TTDate::strtotime($p_obj->getColumn('actual_time_stamp'));
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_station_type_id'] = $p_obj->getColumn('station_type_id');
         $tmp_rows[$p_obj->getColumn('pay_period_id')][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_station_station_id'] = $p_obj->getColumn('station_station_id');
                 break;
         }
         //$policy_hourly_rate = $policy_rates[$column]->getHourlyRate( $hourly_rate );
     } else {
         //Debug::Text('Column: '. $column .' NOT Premium Policy: Policy Rate: '. $policy_rates[$column], __FILE__, __LINE__, __METHOD__,10);
         $policy_hourly_rate = bcmul($policy_rates[$column], $hourly_rate);
     }
 } elseif ($column == 'regular_time') {
     //$rate = 1;
     $policy_hourly_rate = $hourly_rate;
 } else {
     $policy_hourly_rate = 0;
     //$rate = 0;
 }
 //Debug::Text('Column: '. $column .' Total Time: '. $total_time .' Hourly Rate: '. $hourly_rate .' Policy Hourly Rate: '. $policy_hourly_rate .' Amount: '. TTDate::getHours( $total_time ) * $policy_hourly_rate, __FILE__, __LINE__, __METHOD__,10);
 $amount = bcmul(TTDate::getHours($total_time), $policy_hourly_rate);
 if (in_array($column, $wage_columns)) {
     //Debug::Text('...Column: '. $column .' Hourly Wage: '. $hourly_rate .' Rate: '. $rate .' Total Wage: '. ($hourly_rate * $rate), __FILE__, __LINE__, __METHOD__,10);
     if (isset($tmp_rows[$x][$column . '_wage'])) {
         $tmp_rows[$x][$column . '_wage'] = Misc::MoneyFormat($tmp_rows[$x][$column . '_wage'] + $amount, FALSE);
     } else {
         $tmp_rows[$x][$column . '_wage'] = Misc::MoneyFormat($amount, FALSE);
     }
 }
 if (isset($tmp_rows[$x]['gross_wage'])) {
     //Debug::Text('Adding to Gross, Prev Amount: '. $tmp_rows[$x]['gross_wage'] .' Amount: '. $amount, __FILE__, __LINE__, __METHOD__,10);
     $tmp_rows[$x]['gross_wage'] = Misc::MoneyFormat($tmp_rows[$x]['gross_wage'] + $amount, FALSE);
 } else {
     //Debug::Text('Setting Gross...', __FILE__, __LINE__, __METHOD__,10);
     $tmp_rows[$x]['gross_wage'] = Misc::MoneyFormat($amount, FALSE);
 }
 function getActiveMilestoneObject($u_obj, $epoch = NULL)
 {
     if (!is_object($u_obj)) {
         return FALSE;
     }
     if ($epoch == '') {
         $epoch = TTDate::getTime();
     }
     $milestone_obj = FALSE;
     $apmlf = new AccrualPolicyMilestoneListFactory();
     $apmlf->getByAccrualPolicyId($this->getId(), NULL, array('length_of_service_days' => 'desc'));
     Debug::Text('&nbsp;&nbsp;Total Accrual Policy MileStones: ' . (int) $apmlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     if ($apmlf->getRecordCount() > 0) {
         $worked_time = NULL;
         $length_of_service_days = NULL;
         foreach ($apmlf as $apm_obj) {
             if ($apm_obj->getLengthOfServiceUnit() == 50) {
                 Debug::Text('&nbsp;&nbsp;MileStone is in Hours...', __FILE__, __LINE__, __METHOD__, 10);
                 //Hour based
                 if ($worked_time == NULL) {
                     //Get users worked time.
                     $worked_time = TTDate::getHours($this->getWorkedTimeByUserIdAndEndDate($u_obj->getId(), $epoch));
                     Debug::Text('&nbsp;&nbsp;Worked Time: ' . $worked_time . 'hrs', __FILE__, __LINE__, __METHOD__, 10);
                 }
                 if ($worked_time >= $apm_obj->getLengthOfService()) {
                     Debug::Text('&nbsp;&nbsp;bLength Of Service: ' . $apm_obj->getLengthOfService() . 'hrs', __FILE__, __LINE__, __METHOD__, 10);
                     $milestone_obj = $apmlf->getCurrent();
                     break;
                 } else {
                     Debug::Text('&nbsp;&nbsp;Skipping Milestone...', __FILE__, __LINE__, __METHOD__, 10);
                 }
             } else {
                 Debug::Text('&nbsp;&nbsp;MileStone is in Days...', __FILE__, __LINE__, __METHOD__, 10);
                 //Calendar based
                 if ($length_of_service_days == NULL) {
                     $length_of_service_days = TTDate::getDays($epoch - $this->getMilestoneRolloverDate($u_obj->getHireDate()));
                     if ($length_of_service_days < 0) {
                         $length_of_service_days = 0;
                     }
                     Debug::Text('&nbsp;&nbsp;Length of Service Days: ' . $length_of_service_days, __FILE__, __LINE__, __METHOD__, 10);
                 }
                 if ($length_of_service_days >= $apm_obj->getLengthOfServiceDays()) {
                     $milestone_obj = $apmlf->getCurrent();
                     break;
                 } else {
                     Debug::Text('&nbsp;&nbsp;Skipping Milestone...', __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
         }
     }
     unset($apmlf, $apm_obj);
     return $milestone_obj;
 }
Esempio n. 12
0
 function columnFormatter($type, $column, $value, $format = NULL)
 {
     if (is_array($value) and isset($value['display'])) {
         //Found sorting array, use display column.
         return $value['display'];
     } else {
         $retval = $value;
         if ($format == 'csv' or $format == 'raw') {
             //Force specific field formats for exporting to CSV format.
             switch ($type) {
                 case 'report_date':
                     $column = strpos($column, 'custom_column') === FALSE ? $column : $column . '-' . 'date_stamp';
                     $retval = TTDate::getReportDates($column, $value, TRUE, $this->getUserObject());
                     break;
                 case 'currency':
                 case 'percent':
                 case 'numeric':
                     //Don't format above types.
                     break;
                 case 'time_unit':
                     $retval = TTDate::getHours($value);
                     //Force to hours always.
                     break;
                 case 'date_stamp':
                     $retval = TTDate::getDate('DATE', $value);
                     break;
                 case 'time':
                     $retval = TTDate::getDate('TIME', $value);
                     break;
                 case 'time_stamp':
                     $retval = TTDate::getDate('DATE+TIME', $value);
                     break;
                 case 'boolean':
                     if ($value == TRUE) {
                         $retval = TTi18n::getText('Yes');
                     } else {
                         $retval = TTi18n::getText('No');
                     }
                 default:
                     break;
             }
         } elseif ($format == 'xml') {
             //Use standard XML formats whenever possible.
             switch ($type) {
                 case 'report_date':
                     $column = strpos($column, 'custom_column') === FALSE ? $column : $column . '-' . 'date_stamp';
                     $retval = TTDate::getReportDates($column, $value, TRUE, $this->getUserObject());
                     break;
                 case 'currency':
                 case 'percent':
                 case 'numeric':
                     //Don't format above types.
                     break;
                 case 'time_unit':
                     $retval = TTDate::getHours($value);
                     //Force to hours always.
                     break;
                 case 'date_stamp':
                     $retval = date('Y-m-d', $value);
                     ////type="xs:date"
                     break;
                 case 'time':
                     $retval = date('H:i:s', $value);
                     //type="xs:time"
                     break;
                 case 'time_stamp':
                     $retval = date('c', $value);
                     //type="xs:dateTime"
                     break;
                 case 'boolean':
                     if ($value == TRUE) {
                         $retval = TTi18n::getText('Yes');
                     } else {
                         $retval = TTi18n::getText('No');
                     }
                 default:
                     break;
             }
         } else {
             switch ($type) {
                 case 'report_date':
                     $column = strpos($column, 'custom_column') === FALSE ? $column : $column . '-' . 'date_stamp';
                     $retval = TTDate::getReportDates($column, $value, TRUE, $this->getUserObject());
                     break;
                 case 'currency':
                     if (is_object($this->getCurrencyObject())) {
                         //Set MIN decimals to 2 and max to the currency rounding.
                         $retval = $this->getCurrencyObject()->getSymbol() . TTi18n::formatNumber($value, TRUE, 2, $this->getCurrencyObject()->getRoundDecimalPlaces());
                     } else {
                         $retval = TTi18n::formatCurrency($value);
                     }
                     break;
                 case 'percent':
                     $retval = TTi18n::formatNumber($value, TRUE) . '%';
                     break;
                 case 'numeric':
                     $retval = TTi18n::formatNumber($value, TRUE);
                     break;
                 case 'time_unit':
                     $retval = TTDate::getTimeUnit($value);
                     break;
                 case 'date_stamp':
                     $retval = TTDate::getDate('DATE', $value);
                     break;
                 case 'time':
                     $retval = TTDate::getDate('TIME', $value);
                     break;
                 case 'time_stamp':
                     $retval = TTDate::getDate('DATE+TIME', $value);
                     break;
                 case 'boolean':
                     if ($value == TRUE) {
                         $retval = TTi18n::getText('Yes');
                     } else {
                         $retval = TTi18n::getText('No');
                     }
                     break;
                 case 'time_since':
                     $retval = TTDate::getHumanTimeSince($value);
                     break;
                 default:
                     break;
             }
         }
         //Debug::Text('Column: '. $column .' Value: '. $value .' Type: '. $type .' Retval: '. $retval, __FILE__, __LINE__, __METHOD__,10);
         return $retval;
     }
 }
Esempio n. 13
0
 function calculate($epoch = NULL)
 {
     if ($this->getUserObject() == FALSE) {
         return FALSE;
     }
     if ($this->getPayPeriodObject() == FALSE) {
         return FALSE;
     }
     if ($epoch == NULL or $epoch == '') {
         $epoch = TTDate::getTime();
     }
     //Use User Termination Date instead of ROE.
     if ($this->getUserObject()->getTerminationDate() != '' and $this->getUserObject()->getTerminationDate() >= $this->getPayPeriodObject()->getStartDate() and $this->getUserObject()->getTerminationDate() <= $this->getPayPeriodObject()->getEndDate()) {
         Debug::text('User has been terminated in this pay period!', __FILE__, __LINE__, __METHOD__, 10);
         $is_terminated = TRUE;
     } else {
         $is_terminated = FALSE;
     }
     //Allow generating pay stubs for employees who have any status, but if its not ID=10
     //Then the termination date must fall within the start/end date of the pay period, or after the end date (if its the current pay period)
     //The idea here is to allow employees to be marked terminated (or on leave) and still get their previous or final pay stub generated.
     //Also allow pay stubs to be generated in pay periods *before* their termination date.
     if ($this->getUserObject()->getStatus() != 10 and ($is_terminated == FALSE and ($this->getUserObject()->getTerminationDate() == '' or $this->getUserObject()->getTerminationDate() < $this->getPayPeriodObject()->getStartDate()))) {
         Debug::text('Pay Period is after users termination date (' . $this->getUserObject()->getTerminationDate() . '), or no termination date is set...', __FILE__, __LINE__, __METHOD__, 10);
         return FALSE;
     }
     Debug::text('User Id: ' . $this->getUser() . ' Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $this->getPayPeriodObject()->getEndDate()), __FILE__, __LINE__, __METHOD__, 10);
     $generic_queue_status_label = $this->getUserObject()->getFullName(TRUE) . ' - ' . TTi18n::gettext('Pay Stub');
     $pay_stub = TTnew('PayStubFactory');
     $pay_stub->StartTransaction();
     $old_pay_stub_id = NULL;
     if ($this->getEnableCorrection() == TRUE) {
         Debug::text('Correction Enabled!', __FILE__, __LINE__, __METHOD__, 10);
         $pay_stub->setTemp(TRUE);
         //Check for current pay stub ID so we can compare against it.
         $pslf = TTnew('PayStubListFactory');
         $pslf->getByUserIdAndPayPeriodId($this->getUser(), $this->getPayPeriod());
         if ($pslf->getRecordCount() > 0) {
             $old_pay_stub_id = $pslf->getCurrent()->getId();
             Debug::text('Comparing Against Pay Stub ID: ' . $old_pay_stub_id, __FILE__, __LINE__, __METHOD__, 10);
         }
     }
     $pay_stub->setUser($this->getUser());
     $pay_stub->setPayPeriod($this->getPayPeriod());
     $pay_stub->setCurrency($this->getUserObject()->getCurrency());
     $pay_stub->setStatus(10);
     //New
     if ($is_terminated == TRUE) {
         Debug::text('User is Terminated, assuming final pay, setting End Date to terminated date: ' . TTDate::getDate('DATE+TIME', $this->getUserObject()->getTerminationDate()), __FILE__, __LINE__, __METHOD__, 10);
         $pay_stub->setStartDate($pay_stub->getPayPeriodObject()->getStartDate());
         $pay_stub->setEndDate($this->getUserObject()->getTerminationDate());
         //Use the PS generation date instead of terminated date...
         //Unlikely they would pay someone before the pay stub is generated.
         //Perhaps still use the pay period transaction date for this too?
         //Anything we set won't be correct for everyone. Maybe a later date is better though?
         //Perhaps add to the user factory under Termination Date a: "Final Transaction Date" for this purpose?
         //Use the end of the current date for the transaction date, as if the employee is terminated
         //on the same day they are generating the pay stub, the transaction date could be before the end date
         //as the end date is at 11:59PM
         //For now make sure that the transaction date for a terminated employee is never before their termination date.
         if (TTDate::getEndDayEpoch(TTDate::getTime()) < $this->getUserObject()->getTerminationDate()) {
             $pay_stub->setTransactionDate($this->getUserObject()->getTerminationDate());
         } else {
             $pay_stub->setTransactionDate(TTDate::getEndDayEpoch(TTDate::getTime()));
         }
     } else {
         Debug::text('User Termination Date is NOT set, assuming normal pay.', __FILE__, __LINE__, __METHOD__, 10);
         $pay_stub->setDefaultDates();
     }
     //This must go after setting advance
     if ($this->getEnableCorrection() == FALSE and $pay_stub->IsUniquePayStub() == FALSE) {
         Debug::text('Pay Stub already exists', __FILE__, __LINE__, __METHOD__, 10);
         $this->CommitTransaction();
         UserGenericStatusFactory::queueGenericStatus($generic_queue_status_label, 20, TTi18n::gettext('Pay Stub for this employee already exists, skipping...'), NULL);
         return FALSE;
     }
     if ($pay_stub->isValid() == TRUE) {
         $pay_stub->Save(FALSE);
         $pay_stub->setStatus(25);
         //Open
     } else {
         Debug::text('Pay Stub isValid failed!', __FILE__, __LINE__, __METHOD__, 10);
         UserGenericStatusFactory::queueGenericStatus($generic_queue_status_label, 10, $pay_stub->Validator->getTextErrors(), NULL);
         $this->FailTransaction();
         $this->CommitTransaction();
         return FALSE;
     }
     $pay_stub->loadPreviousPayStub();
     $user_date_total_arr = $this->getWageObject()->getUserDateTotalArray();
     if (isset($user_date_total_arr['entries']) and is_array($user_date_total_arr['entries'])) {
         foreach ($user_date_total_arr['entries'] as $udt_arr) {
             //Allow negative amounts so flat rate premium policies can reduce an employees wage if need be.
             if ($udt_arr['amount'] != 0) {
                 Debug::text('Adding Pay Stub Entry: ' . $udt_arr['pay_stub_entry'] . ' Amount: ' . $udt_arr['amount'], __FILE__, __LINE__, __METHOD__, 10);
                 $pay_stub->addEntry($udt_arr['pay_stub_entry'], $udt_arr['amount'], TTDate::getHours($udt_arr['total_time']), $udt_arr['rate']);
             } else {
                 Debug::text('NOT Adding ($0 amount) Pay Stub Entry: ' . $udt_arr['pay_stub_entry'] . ' Amount: ' . $udt_arr['amount'], __FILE__, __LINE__, __METHOD__, 10);
             }
         }
     } else {
         //No Earnings, CHECK FOR PS AMENDMENTS next for earnings.
         Debug::text('NO TimeSheet EARNINGS ON PAY STUB... Checking for PS amendments', __FILE__, __LINE__, __METHOD__, 10);
     }
     //Get all PS amendments and Tax / Deductions so we can determine the proper order to calculate them in.
     $psalf = TTnew('PayStubAmendmentListFactory');
     $psalf->getByUserIdAndAuthorizedAndStartDateAndEndDate($this->getUser(), TRUE, $this->getPayPeriodObject()->getStartDate(), $this->getPayPeriodObject()->getEndDate());
     $udlf = TTnew('UserDeductionListFactory');
     $udlf->getByCompanyIdAndUserId($this->getUserObject()->getCompany(), $this->getUserObject()->getId());
     if (getTTProductEdition() >= TT_PRODUCT_ENTERPRISE and $this->getUserObject()->getCompanyObject()->getProductEdition() >= TT_PRODUCT_ENTERPRISE) {
         $uelf = TTnew('UserExpenseListFactory');
         $uelf->getByUserIdAndAuthorizedAndStartDateAndEndDate($this->getUser(), TRUE, $this->getPayPeriodObject()->getStartDate(), $this->getPayPeriodObject()->getEndDate());
         Debug::text('Total User Expenses: ' . $uelf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     } else {
         $uelf = FALSE;
     }
     $deduction_order_arr = $this->getOrderedDeductionAndPSAmendment($udlf, $psalf, $uelf);
     if (is_array($deduction_order_arr) and count($deduction_order_arr) > 0) {
         foreach ($deduction_order_arr as $calculation_order => $data_arr) {
             Debug::text('Found PS Amendment/Deduction: Type: ' . $data_arr['type'] . ' Name: ' . $data_arr['name'] . ' Order: ' . $calculation_order, __FILE__, __LINE__, __METHOD__, 10);
             if (isset($data_arr['obj']) and is_object($data_arr['obj'])) {
                 if ($data_arr['type'] == 'UserDeductionListFactory') {
                     $ud_obj = $data_arr['obj'];
                     //Determine if this deduction is valid based on start/end dates.
                     //Determine if this deduction is valid based on min/max length of service.
                     //Determine if this deduction is valid based on min/max user age.
                     if ($ud_obj->getCompanyDeductionObject()->isActiveDate($pay_stub->getPayPeriodObject()->getEndDate()) == TRUE and $ud_obj->getCompanyDeductionObject()->isActiveLengthOfService($this->getUserObject(), $pay_stub->getPayPeriodObject()->getEndDate()) == TRUE and $ud_obj->getCompanyDeductionObject()->isActiveUserAge($this->getUserObject(), $pay_stub->getPayPeriodObject()->getEndDate()) == TRUE and $ud_obj->getCompanyDeductionObject()->inApplyFrequencyWindow($pay_stub->getPayPeriodObject()->getStartDate(), $pay_stub->getPayPeriodObject()->getEndDate(), $this->getUserObject()->getHireDate(), $this->getUserObject()->getTerminationDate(), $this->getUserObject()->getBirthDate()) == TRUE) {
                         $amount = $ud_obj->getDeductionAmount($this->getUserObject()->getId(), $pay_stub, $this->getPayPeriodObject());
                         Debug::text('User Deduction: ' . $ud_obj->getCompanyDeductionObject()->getName() . ' Amount: ' . $amount . ' Calculation Order: ' . $ud_obj->getCompanyDeductionObject()->getCalculationOrder(), __FILE__, __LINE__, __METHOD__, 10);
                         //Allow negative amounts, so they can reduce previously calculated deductions or something.
                         if (isset($amount) and $amount != 0) {
                             $pay_stub->addEntry($ud_obj->getCompanyDeductionObject()->getPayStubEntryAccount(), $amount, NULL, NULL, $ud_obj->getCompanyDeductionObject()->getPayStubEntryDescription());
                         } else {
                             Debug::text('Amount is 0, skipping...', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     }
                     unset($amount, $ud_obj);
                 } elseif ($data_arr['type'] == 'PayStubAmendmentListFactory') {
                     $psa_obj = $data_arr['obj'];
                     Debug::text('Found Pay Stub Amendment: ID: ' . $psa_obj->getID() . ' Entry Name ID: ' . $psa_obj->getPayStubEntryNameId() . ' Type: ' . $psa_obj->getType(), __FILE__, __LINE__, __METHOD__, 10);
                     $amount = $psa_obj->getCalculatedAmount($pay_stub);
                     if (isset($amount) and $amount != 0) {
                         Debug::text('Pay Stub Amendment Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                         //Keep in mind this causes pay stubs to be re-generated every time, as this modifies the updated time
                         //to slightly more then the pay stub creation time.
                         $psa_obj->setStatus(52);
                         //InUse
                         if ($psa_obj->isValid()) {
                             $pay_stub->addEntry($psa_obj->getPayStubEntryNameId(), $amount, $psa_obj->getUnits(), $psa_obj->getRate(), $psa_obj->getDescription(), $psa_obj->getID(), NULL, NULL, $psa_obj->getYTDAdjustment());
                             $psa_obj->Save();
                         }
                     } else {
                         Debug::text('bPay Stub Amendment Amount is not set...', __FILE__, __LINE__, __METHOD__, 10);
                     }
                     unset($amount, $psa_obj);
                 } elseif ($data_arr['type'] == 'UserExpenseListFactory') {
                     $ue_obj = $data_arr['obj'];
                     Debug::text('Found User Expense: ID: ' . $ue_obj->getID() . ' Expense Policy ID: ' . $ue_obj->getExpensePolicy(), __FILE__, __LINE__, __METHOD__, 10);
                     $amount = $ue_obj->getReimburseAmount();
                     if (isset($amount) and $amount != 0) {
                         Debug::text('User Expense reimbursable Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                         $pay_stub->addEntry($ue_obj->getExpensePolicyObject()->getPayStubEntryAccount(), $amount, NULL, NULL, NULL, NULL, NULL, NULL, FALSE, $ue_obj->getID());
                         //Keep in mind this causes pay stubs to be re-generated every time, as this modifies the updated time
                         //to slightly more then the pay stub creation time.
                         $ue_obj->setStatus(35);
                         //InUse
                         $ue_obj->Save();
                     } else {
                         Debug::text('bUser Expense Amount is not set...', __FILE__, __LINE__, __METHOD__, 10);
                     }
                     unset($amount, $ue_obj);
                 }
             }
         }
     }
     unset($deduction_order_arr, $calculation_order, $data_arr);
     $pay_stub_id = $pay_stub->getId();
     $pay_stub->setEnableProcessEntries(TRUE);
     $pay_stub->processEntries();
     if ($pay_stub->isValid() == TRUE) {
         Debug::text('Pay Stub is valid, final save.', __FILE__, __LINE__, __METHOD__, 10);
         $pay_stub->setEnableCalcYTD(TRUE);
         //When recalculating old pay stubs in the middle of the year, we need to make sure YTD values are updated.
         $pay_stub->Save();
         if ($this->getEnableCorrection() == TRUE) {
             if (isset($old_pay_stub_id)) {
                 Debug::text('bCorrection Enabled - Doing Comparison here', __FILE__, __LINE__, __METHOD__, 10);
                 PayStubFactory::CalcDifferences($pay_stub_id, $old_pay_stub_id);
             }
             //Delete newly created temp paystub.
             //This used to be in the above IF block that depended on $old_pay_stub_id
             //being set, however in cases where the old pay stub didn't exist
             //TimeTrex wouldn't delete these temporary pay stubs.
             //Moving this code outside that IF statement so it only depends on EnableCorrection()
             //to be TRUE should fix that issue.
             $pslf = TTnew('PayStubListFactory');
             $pslf->getById($pay_stub_id);
             if ($pslf->getRecordCount() > 0) {
                 $tmp_ps_obj = $pslf->getCurrent();
                 $tmp_ps_obj->setDeleted(TRUE);
                 $tmp_ps_obj->Save();
                 unset($tmp_ps_obj);
             }
         }
         $pay_stub->CommitTransaction();
         UserGenericStatusFactory::queueGenericStatus($generic_queue_status_label, 30, NULL, NULL);
         return TRUE;
     }
     Debug::text('Pay Stub is NOT valid returning FALSE', __FILE__, __LINE__, __METHOD__, 10);
     UserGenericStatusFactory::queueGenericStatus($generic_queue_status_label, 10, $pay_stub->Validator->getTextErrors(), NULL);
     $pay_stub->FailTransaction();
     //Reduce transaction count by one.
     $pay_stub->CommitTransaction();
     return FALSE;
 }
Esempio n. 14
0
 function getPayStub($pslf = NULL, $hide_employer_rows = TRUE)
 {
     if (!is_object($pslf) and $this->getId() != '') {
         $pslf = TTnew('PayStubListFactory');
         $pslf->getById($this->getId());
     }
     if (get_class($pslf) !== 'PayStubListFactory') {
         return FALSE;
     }
     $border = 0;
     if ($pslf->getRecordCount() > 0) {
         $pdf = new TTPDF('P', 'mm', 'Letter');
         $pdf->setMargins(0, 0);
         //$pdf->SetAutoPageBreak(TRUE, 30);
         $pdf->SetAutoPageBreak(FALSE);
         $i = 0;
         foreach ($pslf as $pay_stub_obj) {
             $psealf = TTnew('PayStubEntryAccountListFactory');
             //Debug::text($i .'. Pay Stub Transaction Date: '. $pay_stub_obj->getTransactionDate(), __FILE__, __LINE__, __METHOD__,10);
             //Get Pay Period information
             $pplf = TTnew('PayPeriodListFactory');
             $pay_period_obj = $pplf->getById($pay_stub_obj->getPayPeriod())->getCurrent();
             //Use Pay Stub dates, not Pay Period dates.
             $pp_start_date = $pay_stub_obj->getStartDate();
             $pp_end_date = $pay_stub_obj->getEndDate();
             $pp_transaction_date = $pay_stub_obj->getTransactionDate();
             //Get User information
             $ulf = TTnew('UserListFactory');
             $user_obj = $ulf->getById($pay_stub_obj->getUser())->getCurrent();
             //Get company information
             $clf = TTnew('CompanyListFactory');
             $company_obj = $clf->getById($user_obj->getCompany())->getCurrent();
             //Change locale to users own locale.
             TTi18n::setLanguage($user_obj->getUserPreferenceObject()->getLanguage());
             TTi18n::setCountry($user_obj->getCountry());
             TTi18n::setLocale();
             $pdf->SetFont(TTi18n::getPDFDefaultFont($user_obj->getUserPreferenceObject()->getLanguage()), '', 10);
             //
             // Pay Stub Header
             //
             $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
             $pdf->AddPage();
             $adjust_x = 20;
             $adjust_y = 10;
             //Logo
             $pdf->Image($company_obj->getLogoFileName(NULL, TRUE, FALSE, 'large'), Misc::AdjustXY(0, $adjust_x + 0), Misc::AdjustXY(1, $adjust_y + 0), $pdf->pixelsToUnits(167), $pdf->pixelsToUnits(42), '', '', '', FALSE, 300, '', FALSE, FALSE, 0, TRUE);
             //Company name/address
             $pdf->SetFont('', 'B', 14);
             $pdf->setXY(Misc::AdjustXY(50, $adjust_x), Misc::AdjustXY(0, $adjust_y));
             $pdf->Cell(75, 5, $company_obj->getName(), $border, 0, 'C', FALSE, '', 1);
             $pdf->SetFont('', '', 10);
             $pdf->setXY(Misc::AdjustXY(50, $adjust_x), Misc::AdjustXY(6, $adjust_y));
             $pdf->Cell(75, 5, $company_obj->getAddress1() . ' ' . $company_obj->getAddress2(), $border, 0, 'C', FALSE, '', 1);
             $pdf->setXY(Misc::AdjustXY(50, $adjust_x), Misc::AdjustXY(10, $adjust_y));
             $pdf->Cell(75, 5, $company_obj->getCity() . ', ' . $company_obj->getProvince() . ' ' . strtoupper($company_obj->getPostalCode()), $border, 0, 'C', FALSE, '', 1);
             //Pay Period info
             $pdf->SetFont('', '', 10);
             $pdf->setXY(Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY(0, $adjust_y));
             $pdf->Cell(30, 5, TTi18n::gettext('Pay Start Date:') . ' ', $border, 0, 'R', FALSE, '', 1);
             $pdf->setXY(Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY(5, $adjust_y));
             $pdf->Cell(30, 5, TTi18n::gettext('Pay End Date:') . ' ', $border, 0, 'R', FALSE, '', 1);
             $pdf->setXY(Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY(10, $adjust_y));
             $pdf->Cell(30, 5, TTi18n::gettext('Payment Date:') . ' ', $border, 0, 'R', FALSE, '', 1);
             $pdf->SetFont('', 'B', 10);
             $pdf->setXY(Misc::AdjustXY(155, $adjust_x), Misc::AdjustXY(0, $adjust_y));
             $pdf->Cell(20, 5, TTDate::getDate('DATE', $pp_start_date), $border, 0, 'R', FALSE, '', 1);
             $pdf->setXY(Misc::AdjustXY(155, $adjust_x), Misc::AdjustXY(5, $adjust_y));
             $pdf->Cell(20, 5, TTDate::getDate('DATE', $pp_end_date), $border, 0, 'R', FALSE, '', 1);
             $pdf->setXY(Misc::AdjustXY(155, $adjust_x), Misc::AdjustXY(10, $adjust_y));
             $pdf->Cell(20, 5, TTDate::getDate('DATE', $pp_transaction_date), $border, 0, 'R', FALSE, '', 1);
             //Line
             $pdf->setLineWidth(1);
             $pdf->Line(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY(17, $adjust_y), Misc::AdjustXY(185, $adjust_y), Misc::AdjustXY(17, $adjust_y));
             $pdf->SetFont('', 'B', 14);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY(19, $adjust_y));
             $pdf->Cell(175, 5, TTi18n::gettext('STATEMENT OF EARNINGS AND DEDUCTIONS'), $border, 0, 'C', FALSE, '', 1);
             //Line
             $pdf->setLineWidth(1);
             $pdf->Line(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY(27, $adjust_y), Misc::AdjustXY(185, $adjust_y), Misc::AdjustXY(27, $adjust_y));
             $pdf->setLineWidth(0.25);
             //Get pay stub entries.
             $pself = TTnew('PayStubEntryListFactory');
             $pself->getByPayStubId($pay_stub_obj->getId());
             Debug::text('Pay Stub Entries: ' . $pself->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
             $max_widths = array('units' => 0, 'rate' => 0, 'amount' => 0, 'ytd_amount' => 0);
             $prev_type = NULL;
             $description_subscript_counter = 1;
             foreach ($pself as $pay_stub_entry) {
                 //Debug::text('Pay Stub Entry Account ID: '.$pay_stub_entry->getPayStubEntryNameId()  , __FILE__, __LINE__, __METHOD__,10);
                 $description_subscript = NULL;
                 $pay_stub_entry_name_obj = $psealf->getById($pay_stub_entry->getPayStubEntryNameId())->getCurrent();
                 //Use this to put the total for each type at the end of the array.
                 if ($prev_type == 40 or $pay_stub_entry_name_obj->getType() != 40) {
                     $type = $pay_stub_entry_name_obj->getType();
                 }
                 //Debug::text('Pay Stub Entry Name ID: '. $pay_stub_entry_name_obj->getId() .' Type ID: '. $pay_stub_entry_name_obj->getType() .' Type: '. $type, __FILE__, __LINE__, __METHOD__,10);
                 if ($pay_stub_entry->getDescription() !== NULL and $pay_stub_entry->getDescription() !== FALSE and strlen($pay_stub_entry->getDescription()) > 0 and ($type != 30 or $type == 30 and $hide_employer_rows == FALSE)) {
                     //Make sure PSA descriptions are not shown on employee pay stubs.
                     $pay_stub_entry_descriptions[] = array('subscript' => $description_subscript_counter, 'description' => $pay_stub_entry->getDescription());
                     $description_subscript = $description_subscript_counter;
                     $description_subscript_counter++;
                 }
                 //If type if 40 (a total) and the amount is 0, skip it.
                 //This if the employee has no deductions at all, it won't be displayed
                 //on the pay stub.
                 if ($type != 40 or $type == 40 and $pay_stub_entry->getAmount() != 0) {
                     $pay_stub_entries[$type][] = array('id' => $pay_stub_entry->getId(), 'pay_stub_entry_name_id' => $pay_stub_entry->getPayStubEntryNameId(), 'type' => $pay_stub_entry_name_obj->getType(), 'name' => $pay_stub_entry_name_obj->getName(), 'display_name' => $pay_stub_entry_name_obj->getName(), 'rate' => $pay_stub_entry->getRate(), 'units' => $pay_stub_entry->getUnits(), 'ytd_units' => $pay_stub_entry->getYTDUnits(), 'amount' => $pay_stub_entry->getAmount(), 'ytd_amount' => $pay_stub_entry->getYTDAmount(), 'description' => $pay_stub_entry->getDescription(), 'description_subscript' => $description_subscript, 'created_date' => $pay_stub_entry->getCreatedDate(), 'created_by' => $pay_stub_entry->getCreatedBy(), 'updated_date' => $pay_stub_entry->getUpdatedDate(), 'updated_by' => $pay_stub_entry->getUpdatedBy(), 'deleted_date' => $pay_stub_entry->getDeletedDate(), 'deleted_by' => $pay_stub_entry->getDeletedBy());
                     //Calculate maximum widths of numeric values.
                     $width_units = strlen($pay_stub_entry->getUnits());
                     if ($width_units > $max_widths['units']) {
                         $max_widths['units'] = $width_units;
                     }
                     $width_rate = strlen($pay_stub_entry->getRate());
                     if ($width_rate > $max_widths['rate']) {
                         $max_widths['rate'] = $width_rate;
                     }
                     $width_amount = strlen($pay_stub_entry->getAmount());
                     if ($width_amount > $max_widths['amount']) {
                         $max_widths['amount'] = $width_amount;
                     }
                     $width_ytd_amount = strlen($pay_stub_entry->getYTDAmount());
                     if ($width_amount > $max_widths['ytd_amount']) {
                         $max_widths['ytd_amount'] = $width_ytd_amount;
                     }
                     unset($width_rate, $width_units, $width_amount, $width_ytd_amount);
                 }
                 $prev_type = $pay_stub_entry_name_obj->getType();
             }
             //There should always be pay stub entries for a pay stub.
             if (!isset($pay_stub_entries)) {
                 continue;
             }
             //Debug::Arr($pay_stub_entries, 'Pay Stub Entries...', __FILE__, __LINE__, __METHOD__,10);
             //Debug::Arr($max_widths, 'Maximum Widths: ', __FILE__, __LINE__, __METHOD__,10);
             $block_adjust_y = 30;
             //
             //Earnings
             //
             if (isset($pay_stub_entries[10])) {
                 $column_widths['ytd_amount'] = $max_widths['ytd_amount'] * 2 < 25 ? 25 : $max_widths['ytd_amount'] * 2;
                 $column_widths['amount'] = $max_widths['amount'] * 2 < 20 ? 20 : $max_widths['amount'] * 2;
                 $column_widths['rate'] = $max_widths['rate'] * 2 < 5 ? 5 : $max_widths['rate'] * 2;
                 $column_widths['units'] = $max_widths['units'] * 2 < 17 ? 17 : $max_widths['units'] * 2;
                 $column_widths['name'] = 175 - ($column_widths['ytd_amount'] + $column_widths['amount'] + $column_widths['rate'] + $column_widths['units']);
                 //Debug::Arr($column_widths, 'Column Widths: ', __FILE__, __LINE__, __METHOD__,10);
                 //Earnings Header
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Earnings'), $border, 0, 'L', FALSE, '', 1);
                 $pdf->Cell($column_widths['rate'], 5, TTi18n::gettext('Rate'), $border, 0, 'R', FALSE, '', 1);
                 $pdf->Cell($column_widths['units'], 5, TTi18n::gettext('Hrs/Units'), $border, 0, 'R', FALSE, '', 1);
                 $pdf->Cell($column_widths['amount'], 5, TTi18n::gettext('Amount'), $border, 0, 'R', FALSE, '', 1);
                 $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R', FALSE, '', 1);
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 10);
                 foreach ($pay_stub_entries[10] as $pay_stub_entry) {
                     if ($pay_stub_entry['type'] == 10) {
                         if ($pay_stub_entry['description_subscript'] != '') {
                             $subscript = '[' . $pay_stub_entry['description_subscript'] . ']';
                         } else {
                             $subscript = NULL;
                         }
                         $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell($column_widths['name'] - 2, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L', FALSE, '', 1);
                         //68
                         $pdf->Cell($column_widths['rate'], 5, TTi18n::formatNumber($pay_stub_entry['rate'], TRUE), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['units'], 5, TTi18n::formatNumber($pay_stub_entry['units'], TRUE), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entry['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                     } else {
                         //Total
                         $pdf->SetFont('', 'B', 10);
                         $pdf->line(Misc::AdjustXY(175 - $column_widths['ytd_amount'] - $column_widths['amount'] - $column_widths['units'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175 - (1 + $column_widths['ytd_amount']) - $column_widths['amount'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         //90
                         $pdf->line(Misc::AdjustXY(175 - $column_widths['ytd_amount'] - $column_widths['amount'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175 - (1 + $column_widths['ytd_amount']), $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         //111
                         $pdf->line(Misc::AdjustXY(175 - $column_widths['ytd_amount'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         //141
                         $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell($column_widths['name'], 5, $pay_stub_entry['name'], $border, 0, 'L', FALSE, '', 1);
                         $pdf->Cell($column_widths['rate'], 5, '', $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['units'], 5, TTi18n::formatNumber($pay_stub_entry['units'], TRUE), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entry['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                     }
                     $block_adjust_y = $block_adjust_y + 5;
                 }
             }
             //
             // Deductions
             //
             if (isset($pay_stub_entries[20])) {
                 $max_deductions = count($pay_stub_entries[20]);
                 $two_column_threshold = 2;
                 //Deductions Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 if ($max_deductions > $two_column_threshold) {
                     $column_widths['name'] = 85 - ($column_widths['ytd_amount'] + $column_widths['amount']);
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Deductions'), $border, 0, 'L', FALSE, '', 1);
                     $pdf->Cell($column_widths['amount'], 5, TTi18n::gettext('Amount'), $border, 0, 'R', FALSE, '', 1);
                     $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R', FALSE, '', 1);
                     $pdf->setXY(Misc::AdjustXY(90, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Deductions'), $border, 0, 'L', FALSE, '', 1);
                 } else {
                     $column_widths['name'] = 175 - ($column_widths['ytd_amount'] + $column_widths['amount']);
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Deductions'), $border, 0, 'L', FALSE, '', 1);
                 }
                 $pdf->Cell($column_widths['amount'], 5, TTi18n::gettext('Amount'), $border, 0, 'R', FALSE, '', 1);
                 $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R', FALSE, '', 1);
                 $block_adjust_y = $tmp_block_adjust_y = $top_block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 10);
                 $x = 0;
                 $max_block_adjust_y = 0;
                 foreach ($pay_stub_entries[20] as $pay_stub_entry) {
                     //Start with the right side.
                     if ($x < floor($max_deductions / 2)) {
                         $tmp_adjust_x = 90;
                     } else {
                         if ($tmp_block_adjust_y != 0) {
                             $block_adjust_y = $tmp_block_adjust_y;
                             $tmp_block_adjust_y = 0;
                         }
                         $tmp_adjust_x = 0;
                     }
                     if ($pay_stub_entry['type'] == 20) {
                         if ($pay_stub_entry['description_subscript'] != '') {
                             $subscript = '[' . $pay_stub_entry['description_subscript'] . ']';
                         } else {
                             $subscript = NULL;
                         }
                         if ($max_deductions > $two_column_threshold) {
                             $pdf->setXY(Misc::AdjustXY(2, $tmp_adjust_x + $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             //$pdf->Cell( $column_widths['name']-2, 5, Misc::TruncateString( $pay_stub_entry['name'], $column_widths['name']/1.7, 0, TRUE ) . $subscript, $border, 0, 'L', FALSE, '', 1);
                             $pdf->Cell($column_widths['name'] - 2, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L', FALSE, '', 1);
                         } else {
                             $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             $pdf->Cell($column_widths['name'] - 2, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L', FALSE, '', 1);
                         }
                         $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entry['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         //Debug::Text('Y Adjustments: '. $adjust_y .' Block: '. $block_adjust_y, __FILE__, __LINE__, __METHOD__,10);
                     } else {
                         $block_adjust_y = $max_block_adjust_y + 0;
                         //Total
                         $pdf->SetFont('', 'B', 10);
                         $pdf->line(Misc::AdjustXY(175 - $column_widths['ytd_amount'] - $column_widths['amount'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175 - (1 + $column_widths['ytd_amount']), $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         //111
                         $pdf->line(Misc::AdjustXY(175 - $column_widths['ytd_amount'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         //141
                         $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell(175 - ($column_widths['amount'] + $column_widths['ytd_amount']), 5, $pay_stub_entry['name'], $border, 0, 'L', FALSE, '', 1);
                         //110
                         $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entry['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                     }
                     $block_adjust_y = $block_adjust_y + 5;
                     if ($block_adjust_y > $max_block_adjust_y) {
                         $max_block_adjust_y = $block_adjust_y;
                     }
                     $x++;
                 }
                 //Draw line to separate the two columns
                 if ($max_deductions > $two_column_threshold) {
                     $pdf->Line(Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($top_block_adjust_y - 5, $adjust_y), Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($max_block_adjust_y - 5, $adjust_y));
                 }
                 unset($x, $max_deductions, $tmp_adjust_x, $max_block_adjust_y, $tmp_block_adjust_y, $top_block_adjust_y);
             }
             if (isset($pay_stub_entries[40][0])) {
                 $block_adjust_y = $block_adjust_y + 5;
                 //Net Pay entry
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $pdf->Cell(175 - ($column_widths['amount'] + $column_widths['ytd_amount']), 5, $pay_stub_entries[40][0]['name'], $border, 0, 'L', FALSE, '', 1);
                 $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entries[40][0]['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                 $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entries[40][0]['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                 $block_adjust_y = $block_adjust_y + 5;
             }
             //
             //Miscellaneous
             //
             if (isset($pay_stub_entries[80])) {
                 $max_deductions = count($pay_stub_entries[80]);
                 //Deductions Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 if ($max_deductions > 2) {
                     $column_widths['name'] = 85 - ($column_widths['ytd_amount'] + $column_widths['amount']);
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Miscellaneous'), $border, 0, 'L', FALSE, '', 1);
                     $pdf->Cell($column_widths['amount'], 5, TTi18n::gettext('Amount'), $border, 0, 'R', FALSE, '', 1);
                     $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R', FALSE, '', 1);
                     $pdf->setXY(Misc::AdjustXY(90, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Miscellaneous'), $border, 0, 'L', FALSE, '', 1);
                 } else {
                     $column_widths['name'] = 175 - ($column_widths['ytd_amount'] + $column_widths['amount']);
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Miscellaneous'), $border, 0, 'L', FALSE, '', 1);
                 }
                 $pdf->Cell($column_widths['amount'], 5, TTi18n::gettext('Amount'), $border, 0, 'R', FALSE, '', 1);
                 $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R', FALSE, '', 1);
                 $block_adjust_y = $tmp_block_adjust_y = $top_block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 10);
                 $x = 0;
                 $max_block_adjust_y = 0;
                 foreach ($pay_stub_entries[80] as $pay_stub_entry) {
                     //Start with the right side.
                     if ($x < floor($max_deductions / 2)) {
                         $tmp_adjust_x = 90;
                     } else {
                         if ($tmp_block_adjust_y != 0) {
                             $block_adjust_y = $tmp_block_adjust_y;
                             $tmp_block_adjust_y = 0;
                         }
                         $tmp_adjust_x = 0;
                     }
                     if ($pay_stub_entry['type'] == 80) {
                         if ($pay_stub_entry['description_subscript'] != '') {
                             $subscript = '[' . $pay_stub_entry['description_subscript'] . ']';
                         } else {
                             $subscript = NULL;
                         }
                         if ($max_deductions > 2) {
                             $pdf->setXY(Misc::AdjustXY(2, $tmp_adjust_x + $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             $pdf->Cell($column_widths['name'] - 2, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L', FALSE, '', 1);
                             //38
                         } else {
                             $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             $pdf->Cell($column_widths['name'] - 2, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L', FALSE, '', 1);
                             //128
                         }
                         $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entry['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                     } else {
                         $block_adjust_y = $max_block_adjust_y + 0;
                         //Total
                         $pdf->SetFont('', 'B', 10);
                         $pdf->line(Misc::AdjustXY(175 - $column_widths['ytd_amount'] - $column_widths['amount'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175 - (1 + $column_widths['ytd_amount']), $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         //111
                         $pdf->line(Misc::AdjustXY(175 - $column_widths['ytd_amount'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         //141
                         $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell(175 - ($column_widths['amount'] + $column_widths['ytd_amount']), 5, $pay_stub_entry['name'], $border, 0, 'L', FALSE, '', 1);
                         $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entry['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                     }
                     $block_adjust_y = $block_adjust_y + 5;
                     if ($block_adjust_y > $max_block_adjust_y) {
                         $max_block_adjust_y = $block_adjust_y;
                     }
                     $x++;
                 }
                 //Draw line to separate the two columns
                 if ($max_deductions > 2) {
                     $pdf->Line(Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($top_block_adjust_y - 5, $adjust_y), Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($max_block_adjust_y - 5, $adjust_y));
                 }
                 unset($x, $max_deductions, $tmp_adjust_x, $max_block_adjust_y, $tmp_block_adjust_y, $top_block_adjust_y);
             }
             //
             //Employer Contributions
             //
             if (isset($pay_stub_entries[30]) and $hide_employer_rows != TRUE) {
                 $max_deductions = count($pay_stub_entries[30]);
                 //Deductions Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 if ($max_deductions > 2) {
                     $column_widths['name'] = 85 - ($column_widths['ytd_amount'] + $column_widths['amount']);
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Employer Contributions'), $border, 0, 'L', FALSE, '', 1);
                     $pdf->Cell($column_widths['amount'], 5, TTi18n::gettext('Amount'), $border, 0, 'R', FALSE, '', 1);
                     $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R', FALSE, '', 1);
                     $pdf->setXY(Misc::AdjustXY(90, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Employer Contributions'), $border, 0, 'L', FALSE, '', 1);
                 } else {
                     $column_widths['name'] = 175 - ($column_widths['ytd_amount'] + $column_widths['amount']);
                     $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell($column_widths['name'], 5, TTi18n::gettext('Employer Contributions'), $border, 0, 'L', FALSE, '', 1);
                 }
                 $pdf->Cell($column_widths['amount'], 5, TTi18n::gettext('Amount'), $border, 0, 'R', FALSE, '', 1);
                 $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::gettext('YTD Amount'), $border, 0, 'R', FALSE, '', 1);
                 $block_adjust_y = $tmp_block_adjust_y = $top_block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 10);
                 $x = 0;
                 $max_block_adjust_y = 0;
                 foreach ($pay_stub_entries[30] as $pay_stub_entry) {
                     //Start with the right side.
                     if ($x < floor($max_deductions / 2)) {
                         $tmp_adjust_x = 90;
                     } else {
                         if ($tmp_block_adjust_y != 0) {
                             $block_adjust_y = $tmp_block_adjust_y;
                             $tmp_block_adjust_y = 0;
                         }
                         $tmp_adjust_x = 0;
                     }
                     if ($pay_stub_entry['type'] == 30) {
                         if ($pay_stub_entry['description_subscript'] != '') {
                             $subscript = '[' . $pay_stub_entry['description_subscript'] . ']';
                         } else {
                             $subscript = NULL;
                         }
                         if ($max_deductions > 2) {
                             $pdf->setXY(Misc::AdjustXY(2, $tmp_adjust_x + $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             $pdf->Cell($column_widths['name'] - 2, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L', FALSE, '', 1);
                             //38
                         } else {
                             $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                             $pdf->Cell($column_widths['name'] - 2, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L', FALSE, '', 1);
                             //128
                         }
                         $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entry['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                     } else {
                         $block_adjust_y = $max_block_adjust_y + 0;
                         //Total
                         $pdf->SetFont('', 'B', 10);
                         $pdf->line(Misc::AdjustXY(175 - $column_widths['ytd_amount'] - $column_widths['amount'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175 - (1 + $column_widths['ytd_amount']), $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         //111
                         $pdf->line(Misc::AdjustXY(175 - $column_widths['ytd_amount'], $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(175, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         //141
                         $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell(175 - ($column_widths['amount'] + $column_widths['ytd_amount']), 5, $pay_stub_entry['name'], $border, 0, 'L', FALSE, '', 1);
                         $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entry['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                     }
                     $block_adjust_y = $block_adjust_y + 5;
                     if ($block_adjust_y > $max_block_adjust_y) {
                         $max_block_adjust_y = $block_adjust_y;
                     }
                     $x++;
                 }
                 //Draw line to separate the two columns
                 if ($max_deductions > 2) {
                     $pdf->Line(Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($top_block_adjust_y - 5, $adjust_y), Misc::AdjustXY(88, $adjust_x), Misc::AdjustXY($max_block_adjust_y - 5, $adjust_y));
                 }
                 unset($x, $max_deductions, $tmp_adjust_x, $max_block_adjust_y, $tmp_block_adjust_y, $top_block_adjust_y);
             }
             //
             //Accruals PS accounts
             //
             if (isset($pay_stub_entries[50])) {
                 //Accrual Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $pdf->Cell(175 - ($column_widths['amount'] + $column_widths['ytd_amount']), 5, TTi18n::gettext('Accruals'), $border, 0, 'L', FALSE, '', 1);
                 $pdf->Cell($column_widths['amount'], 5, TTi18n::gettext('Amount'), $border, 0, 'R', FALSE, '', 1);
                 $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::gettext('Balance'), $border, 0, 'R', FALSE, '', 1);
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 10);
                 foreach ($pay_stub_entries[50] as $pay_stub_entry) {
                     if ($pay_stub_entry['type'] == 50) {
                         if ($pay_stub_entry['description_subscript'] != '') {
                             $subscript = '[' . $pay_stub_entry['description_subscript'] . ']';
                         } else {
                             $subscript = NULL;
                         }
                         $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                         $pdf->Cell(175 - ($column_widths['amount'] + $column_widths['ytd_amount']) - 2, 5, $pay_stub_entry['name'] . $subscript, $border, 0, 'L', FALSE, '', 1);
                         $pdf->Cell($column_widths['amount'], 5, TTi18n::formatNumber($pay_stub_entry['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                         $pdf->Cell($column_widths['ytd_amount'], 5, TTi18n::formatNumber($pay_stub_entry['ytd_amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces()), $border, 0, 'R', FALSE, '', 1);
                     }
                     $block_adjust_y = $block_adjust_y + 5;
                 }
             }
             //
             //Accrual Policy Balances
             //
             $ablf = TTnew('AccrualBalanceListFactory');
             $ablf->getByUserIdAndCompanyIdAndEnablePayStubBalanceDisplay($user_obj->getId(), $user_obj->getCompany(), TRUE);
             if ($ablf->getRecordCount() > 0) {
                 //Accrual Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(40, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $accrual_time_header_start_x = $pdf->getX();
                 $accrual_time_header_start_y = $pdf->getY();
                 $pdf->Cell(70, 5, TTi18n::gettext('Accrual Time Balances as of ') . TTDate::getDate('DATE', time()), $border, 0, 'L', FALSE, '', 1);
                 $pdf->Cell(25, 5, TTi18n::gettext('Balance (hrs)'), $border, 0, 'R', FALSE, '', 1);
                 $block_adjust_y = $block_adjust_y + 5;
                 $box_height = 5;
                 $pdf->SetFont('', '', 10);
                 foreach ($ablf as $ab_obj) {
                     $balance = $ab_obj->getBalance();
                     if (!is_numeric($balance)) {
                         $balance = 0;
                     }
                     $pdf->setXY(Misc::AdjustXY(40, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     $pdf->Cell(70, 5, $ab_obj->getColumn('name'), $border, 0, 'L', FALSE, '', 1);
                     $pdf->Cell(25, 5, TTi18n::formatNumber(TTDate::getHours($balance)), $border, 0, 'R', FALSE, '', 1);
                     $block_adjust_y = $block_adjust_y + 5;
                     $box_height = $box_height + 5;
                     unset($balance);
                 }
                 $pdf->Rect($accrual_time_header_start_x, $accrual_time_header_start_y, 95, $box_height);
                 unset($accrual_time_header_start_x, $accrual_time_header_start_y, $box_height);
             }
             //
             //Descriptions
             //
             if (isset($pay_stub_entry_descriptions) and count($pay_stub_entry_descriptions) > 0) {
                 //Description Header
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', 'B', 10);
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                 $pdf->Cell(175, 5, TTi18n::gettext('Notes'), $border, 0, 'L', FALSE, '', 1);
                 $block_adjust_y = $block_adjust_y + 5;
                 $pdf->SetFont('', '', 8);
                 $x = 0;
                 foreach ($pay_stub_entry_descriptions as $pay_stub_entry_description) {
                     if ($x % 2 == 0) {
                         $pdf->setXY(Misc::AdjustXY(2, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     } else {
                         $pdf->setXY(Misc::AdjustXY(90, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y));
                     }
                     $pdf->Cell(85, 5, '[' . $pay_stub_entry_description['subscript'] . '] ' . html_entity_decode($pay_stub_entry_description['description']), $border, 0, 'L', FALSE, '', 1);
                     if ($x % 2 != 0) {
                         $block_adjust_y = $block_adjust_y + 5;
                     }
                     $x++;
                 }
             }
             unset($x, $pay_stub_entry_descriptions, $pay_stub_entry_description);
             //
             // Pay Stub Footer
             //
             $block_adjust_y = 215;
             //Line
             $pdf->setLineWidth(1);
             $pdf->Line(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y, $adjust_y), Misc::AdjustXY(185, $adjust_y), Misc::AdjustXY($block_adjust_y, $adjust_y));
             //Non Negotiable
             $pdf->SetFont('', 'B', 14);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 3, $adjust_y));
             $pdf->Cell(175, 5, TTi18n::gettext('NON NEGOTIABLE'), $border, 0, 'C', FALSE, '', 1);
             //Employee Address
             $pdf->SetFont('', 'B', 12);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 9, $adjust_y));
             $pdf->Cell(60, 5, TTi18n::gettext('CONFIDENTIAL'), $border, 0, 'C', FALSE, '', 1);
             $pdf->SetFont('', '', 10);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 14, $adjust_y));
             $pdf->Cell(60, 5, $user_obj->getFullName() . ' (#' . $user_obj->getEmployeeNumber() . ')', $border, 0, 'C', FALSE, '', 1);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 19, $adjust_y));
             $pdf->Cell(60, 5, $user_obj->getAddress1(), $border, 0, 'C', FALSE, '', 1);
             $address2_adjust_y = 0;
             if ($user_obj->getAddress2() != '') {
                 $address2_adjust_y = 5;
                 $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 24, $adjust_y));
                 $pdf->Cell(60, 5, $user_obj->getAddress2(), $border, 0, 'C', FALSE, '', 1);
             }
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 24 + $address2_adjust_y, $adjust_y));
             $pdf->Cell(60, 5, $user_obj->getCity() . ', ' . $user_obj->getProvince() . ' ' . $user_obj->getPostalCode(), $border, 1, 'C', FALSE, '', 1);
             //Pay Period - Balance - ID
             $net_pay_amount = 0;
             if (isset($pay_stub_entries[40][0])) {
                 $net_pay_amount = TTi18n::formatNumber($pay_stub_entries[40][0]['amount'], TRUE, $pay_stub_obj->getCurrencyObject()->getRoundDecimalPlaces());
             }
             if (isset($pay_stub_entries[65]) and count($pay_stub_entries[65]) > 0) {
                 $net_pay_label = TTi18n::gettext('Balance');
             } else {
                 $net_pay_label = TTi18n::gettext('Net Pay');
             }
             $pdf->SetFont('', 'B', 12);
             $pdf->setXY(Misc::AdjustXY(75, $adjust_x), Misc::AdjustXY($block_adjust_y + 17, $adjust_y));
             $pdf->Cell(100, 5, $net_pay_label . ': ' . $pay_stub_obj->getCurrencyObject()->getSymbol() . $net_pay_amount . ' ' . $pay_stub_obj->getCurrencyObject()->getISOCode(), $border, 1, 'R', FALSE, '', 1);
             if ($pay_stub_obj->getTainted() == TRUE) {
                 $tainted_flag = 'T';
             } else {
                 $tainted_flag = '';
             }
             $pdf->SetFont('', '', 8);
             $pdf->setXY(Misc::AdjustXY(125, $adjust_x), Misc::AdjustXY($block_adjust_y + 30, $adjust_y));
             $pdf->Cell(50, 5, TTi18n::gettext('Identification #:') . ' ' . str_pad($pay_stub_obj->getId(), 12, 0, STR_PAD_LEFT) . $tainted_flag, $border, 1, 'R', FALSE, '', 1);
             unset($net_pay_amount, $tainted_flag);
             //Line
             $pdf->setLineWidth(1);
             $pdf->Line(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 35, $adjust_y), Misc::AdjustXY(185, $adjust_y), Misc::AdjustXY($block_adjust_y + 35, $adjust_y));
             $pdf->SetFont('', '', 6);
             $pdf->setXY(Misc::AdjustXY(0, $adjust_x), Misc::AdjustXY($block_adjust_y + 38, $adjust_y));
             $pdf->Cell(175, 1, TTi18n::getText('Pay Stub Generated by') . ' ' . APPLICATION_NAME . ' @ ' . TTDate::getDate('DATE+TIME', $pay_stub_obj->getCreatedDate()), $border, 0, 'C', FALSE, '', 1);
             unset($pay_stub_entries, $pay_period_number);
             $this->getProgressBarObject()->set(NULL, $pslf->getCurrentRow());
             $i++;
         }
         Debug::Text('Generating PDF...', __FILE__, __LINE__, __METHOD__, 10);
         $output = $pdf->Output('', 'S');
     }
     TTi18n::setMasterLocale();
     if (isset($output)) {
         return $output;
     }
     return FALSE;
 }
 function getDeductionAmount($user_id, $pay_stub_obj, $pay_period_obj)
 {
     if ($user_id == '') {
         Debug::Text('Missing User ID: ', __FILE__, __LINE__, __METHOD__, 10);
         return FALSE;
     }
     if (!is_object($pay_stub_obj)) {
         Debug::Text('Missing Pay Stub Object: ', __FILE__, __LINE__, __METHOD__, 10);
         return FALSE;
     }
     if (!is_object($pay_period_obj)) {
         Debug::Text('Missing Pay Period Object: ', __FILE__, __LINE__, __METHOD__, 10);
         return FALSE;
     }
     //Calculates the deduction.
     $cd_obj = $this->getCompanyDeductionObject();
     $annual_pay_periods = $pay_period_obj->getPayPeriodScheduleObject()->getAnnualPayPeriods();
     if (!is_object($cd_obj)) {
         return FALSE;
     }
     require_once Environment::getBasePath() . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'payroll_deduction' . DIRECTORY_SEPARATOR . 'PayrollDeduction.class.php';
     $retval = 0;
     Debug::Text('Company Deduction: ID: ' . $cd_obj->getID() . ' Name: ' . $cd_obj->getName() . ' Calculation ID: ' . $cd_obj->getCalculation(), __FILE__, __LINE__, __METHOD__, 10);
     switch ($cd_obj->getCalculation()) {
         case 10:
             //Basic Percent
             if ($this->getUserValue1() == '') {
                 $percent = $cd_obj->getUserValue1();
             } else {
                 $percent = $this->getUserValue1();
             }
             $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
             $retval = bcmul($amount, bcdiv($percent, 100));
             break;
         case 15:
             //Advanced Percent
             if ($this->getUserValue1() == '') {
                 $percent = $cd_obj->getUserValue1();
             } else {
                 $percent = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $wage_base = $cd_obj->getUserValue2();
             } else {
                 $wage_base = $this->getUserValue2();
             }
             if ($this->getUserValue3() == '') {
                 $exempt_amount = $cd_obj->getUserValue3();
             } else {
                 $exempt_amount = $this->getUserValue3();
             }
             //Annual Wage Base is the maximum earnings that an employee can earn before they are no longer eligible for this deduction
             //Annual Deduction Amount
             Debug::Text('Percent: ' . $percent . ' Wage Base: ' . $wage_base . ' Exempt Amount: ' . $exempt_amount, __FILE__, __LINE__, __METHOD__, 10);
             if ($percent != 0) {
                 if ($exempt_amount > 0) {
                     $amount = bcsub($cd_obj->getCalculationPayStubAmount($pay_stub_obj), bcdiv($exempt_amount, $annual_pay_periods));
                     Debug::Text('Amount After Exemption: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                 } else {
                     $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
                     Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                 }
                 if ($wage_base > 0) {
                     //*NOTE: If the first pay stub in TimeTrex is near the end of the year, and the employee has already exceeded the wage base amount
                     //the payroll admin needs to make sure they add a YTD Adjustment for each Include PS Accounts that this calculation is based on,
                     //NOT the total amount they have paid for the resulting calculation, as that has no effect whatsoever.
                     //getCalculationYTDAmount is the previous pay stub YTD amount, but it includes any YTD Adjustments in the current pay stub too.
                     $ytd_amount = $cd_obj->getCalculationYTDAmount($pay_stub_obj);
                     Debug::Text('Wage Base is set: ' . $wage_base . ' Amount: ' . $amount . ' Current YTD: ' . $ytd_amount, __FILE__, __LINE__, __METHOD__, 10);
                     //Possible calcations:
                     //
                     //Wage Base: 3000
                     //Amount: 500 YTD: 0		= 500
                     //Amount: 500 YTD: 2900		= 100
                     //Amount: 500 YTD: 3100		= 0
                     //Amount: 3500 YTD: 0		= 3000
                     //AMount: 3500 YTD: 2900	= 100
                     //Amount: 3500 YTD: 3100	= 0
                     //Check to see if YTD is less than wage base.
                     $remaining_wage_base = bcsub($wage_base, $ytd_amount);
                     Debug::Text('Remaining Wage Base to be calculated: ' . $remaining_wage_base, __FILE__, __LINE__, __METHOD__, 10);
                     if ($remaining_wage_base > 0) {
                         if ($amount > $remaining_wage_base) {
                             $amount = $remaining_wage_base;
                         }
                     } else {
                         $amount = 0;
                         //Exceeded wage base, nothing to calculate.
                     }
                     unset($remaining_wage_base);
                 } else {
                     Debug::Text('Wage Base is NOT set: ' . $wage_base, __FILE__, __LINE__, __METHOD__, 10);
                 }
                 $retval = bcmul($amount, bcdiv($percent, 100));
             } else {
                 $retval = 0;
             }
             if ($percent >= 0 and $retval < 0) {
                 $retval = 0;
             }
             unset($amount, $ytd_amount, $percent, $wage_base);
             break;
         case 17:
             //Advanced Percent (Range Bracket)
             if ($this->getUserValue1() == '') {
                 $percent = $cd_obj->getUserValue1();
             } else {
                 $percent = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $min_wage = $cd_obj->getUserValue2();
             } else {
                 $min_wage = $this->getUserValue2();
             }
             if ($this->getUserValue3() == '') {
                 $max_wage = $cd_obj->getUserValue3();
             } else {
                 $max_wage = $this->getUserValue3();
             }
             if ($this->getUserValue4() == '') {
                 $annual_deduction_amount = $cd_obj->getUserValue4();
             } else {
                 $annual_deduction_amount = $this->getUserValue4();
             }
             if ($this->getUserValue5() == '') {
                 $annual_fixed_amount = $cd_obj->getUserValue5();
             } else {
                 $annual_fixed_amount = $this->getUserValue5();
             }
             $min_wage = bcdiv($min_wage, $annual_pay_periods);
             $max_wage = bcdiv($max_wage, $annual_pay_periods);
             $annual_deduction_amount = bcdiv($annual_deduction_amount, $annual_pay_periods);
             $annual_fixed_amount = bcdiv($annual_fixed_amount, $annual_pay_periods);
             Debug::Text('Percent: ' . $percent . ' Min Wage: ' . $min_wage . ' Max Wage: ' . $max_wage . ' Annual Deduction: ' . $annual_deduction_amount, __FILE__, __LINE__, __METHOD__, 10);
             if ($percent != 0) {
                 $amount = bcsub($cd_obj->getCalculationPayStubAmount($pay_stub_obj), $annual_deduction_amount);
                 Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                 if ($amount >= $min_wage and $amount <= $max_wage) {
                     $retval = bcadd(bcmul($amount, bcdiv($percent, 100)), $annual_fixed_amount);
                 }
             } else {
                 $retval = 0;
             }
             if ($percent >= 0 and $retval < 0) {
                 $retval = 0;
             }
             unset($amount, $percent, $min_wage, $max_wage, $annual_deduction_amount, $annual_fixed_amount);
             break;
         case 18:
             //Advanced Percent (Tax Bracket)
             if ($this->getUserValue1() == '') {
                 $percent = $cd_obj->getUserValue1();
             } else {
                 $percent = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $wage_base = $cd_obj->getUserValue2();
             } else {
                 $wage_base = $this->getUserValue2();
             }
             if ($this->getUserValue3() == '') {
                 $exempt_amount = $cd_obj->getUserValue3();
             } else {
                 $exempt_amount = $this->getUserValue3();
             }
             if ($this->getUserValue4() == '') {
                 $annual_deduction_amount = $cd_obj->getUserValue4();
             } else {
                 $annual_deduction_amount = $this->getUserValue4();
             }
             Debug::Text('Percent: ' . $percent . ' Wage Base: ' . $wage_base . ' Exempt Amount: ' . $exempt_amount, __FILE__, __LINE__, __METHOD__, 10);
             if ($percent != 0) {
                 if ($exempt_amount > 0) {
                     $pp_exempt_amount = bcdiv($exempt_amount, $annual_pay_periods);
                 } else {
                     $pp_exempt_amount = 0;
                 }
                 //Debug::Text('PP Exempt Amount: '. $pp_exempt_amount, __FILE__, __LINE__, __METHOD__,10);
                 if ($wage_base > 0) {
                     $pp_wage_base_amount = bcdiv($wage_base, $annual_pay_periods);
                 } else {
                     $pp_wage_base_amount = 0;
                 }
                 if ($annual_deduction_amount > 0) {
                     $pp_annual_deduction_amount = bcdiv($annual_deduction_amount, $annual_pay_periods);
                 } else {
                     $pp_annual_deduction_amount = 0;
                 }
                 //Debug::Text('PP Wage Base Base Amount: '. $pp_wage_base_amount, __FILE__, __LINE__, __METHOD__,10);
                 $amount = bcsub($cd_obj->getCalculationPayStubAmount($pay_stub_obj), $pp_annual_deduction_amount);
                 //Debug::Text('Calculation Pay Stub Amount: '. $cd_obj->getCalculationPayStubAmount( $pay_stub_obj ), __FILE__, __LINE__, __METHOD__,10);
                 if ($pp_wage_base_amount > 0 and $amount > $pp_wage_base_amount) {
                     //Debug::Text('Exceeds Wage Base...'. $amount, __FILE__, __LINE__, __METHOD__,10);
                     $amount = bcsub($pp_wage_base_amount, $pp_exempt_amount);
                 } else {
                     //Debug::Text('Under Wage Base...'. $amount, __FILE__, __LINE__, __METHOD__,10);
                     $amount = bcsub($amount, $pp_exempt_amount);
                 }
                 Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                 $retval = bcmul($amount, bcdiv($percent, 100));
             } else {
                 $retval = 0;
             }
             if ($percent >= 0 and $retval < 0) {
                 $retval = 0;
             }
             unset($amount, $percent, $wage_base, $pp_wage_base_amount, $pp_exempt_amount, $annual_deduction_amount, $pp_annual_deduction_amount);
             break;
         case 19:
             //Advanced Percent (Tax Bracket Alternate)
             /*
             	This is designed to be used for single line item tax calculations, in that the formula looks like this,
             	where only ONE bracket would be applied to the employee, NOT all:
             	Wage between 0 - 10,000 calculate 10%
             	Wage between 10,001 - 20,000 calculate 15% + $1000 (10% of 10,000 as per above)
             	Wage between 20,001 - 30,000 calculate 20% + $2500 (10% of 10,000 as first bracket, and 15% of 10,000 as per 2nd bracket)
             */
             if ($this->getUserValue1() == '') {
                 $percent = $cd_obj->getUserValue1();
             } else {
                 $percent = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $min_wage = $cd_obj->getUserValue2();
             } else {
                 $min_wage = $this->getUserValue2();
             }
             if ($this->getUserValue3() == '') {
                 $max_wage = $cd_obj->getUserValue3();
             } else {
                 $max_wage = $this->getUserValue3();
             }
             if ($this->getUserValue4() == '') {
                 $annual_deduction_amount = $cd_obj->getUserValue4();
             } else {
                 $annual_deduction_amount = $this->getUserValue4();
             }
             if ($this->getUserValue5() == '') {
                 $annual_fixed_amount = $cd_obj->getUserValue5();
             } else {
                 $annual_fixed_amount = $this->getUserValue5();
             }
             $min_wage = bcdiv($min_wage, $annual_pay_periods);
             $max_wage = bcdiv($max_wage, $annual_pay_periods);
             $annual_deduction_amount = bcdiv($annual_deduction_amount, $annual_pay_periods);
             $annual_fixed_amount = bcdiv($annual_fixed_amount, $annual_pay_periods);
             Debug::Text('Percent: ' . $percent . ' Min Wage: ' . $min_wage . ' Max Wage: ' . $max_wage . ' Annual Deduction: ' . $annual_deduction_amount, __FILE__, __LINE__, __METHOD__, 10);
             if ($percent != 0) {
                 $amount = bcsub($cd_obj->getCalculationPayStubAmount($pay_stub_obj), $annual_deduction_amount);
                 Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                 if ($amount >= $min_wage and $amount <= $max_wage) {
                     $retval = bcadd(bcmul(bcsub($amount, $min_wage), bcdiv($percent, 100)), $annual_fixed_amount);
                 }
             } else {
                 $retval = 0;
             }
             if ($percent >= 0 and $retval < 0) {
                 $retval = 0;
             }
             unset($amount, $percent, $min_wage, $max_wage, $annual_deduction_amount, $annual_fixed_amount);
             break;
         case 20:
             //Fixed amount
             if ($this->getUserValue1() == FALSE) {
                 $amount = $cd_obj->getUserValue1();
             } else {
                 $amount = $this->getUserValue1();
             }
             $retval = $amount;
             unset($amount);
             break;
         case 30:
             //Fixed Amount (Range Bracket)
             if ($this->getUserValue1() == '') {
                 $fixed_amount = $cd_obj->getUserValue1();
             } else {
                 $fixed_amount = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $min_wage = $cd_obj->getUserValue2();
             } else {
                 $min_wage = $this->getUserValue2();
             }
             if ($this->getUserValue3() == '') {
                 $max_wage = $cd_obj->getUserValue3();
             } else {
                 $max_wage = $this->getUserValue3();
             }
             if ($this->getUserValue4() == '') {
                 $annual_deduction_amount = $cd_obj->getUserValue4();
             } else {
                 $annual_deduction_amount = $this->getUserValue4();
             }
             $min_wage = bcdiv($min_wage, $annual_pay_periods);
             $max_wage = bcdiv($max_wage, $annual_pay_periods);
             $annual_deduction_amount = bcdiv($annual_deduction_amount, $annual_pay_periods);
             Debug::Text('Amount: ' . $fixed_amount . ' Min Wage: ' . $min_wage . ' Max Wage: ' . $max_wage . ' Annual Deduction: ' . $annual_deduction_amount, __FILE__, __LINE__, __METHOD__, 10);
             if ($fixed_amount != 0) {
                 $amount = bcsub($cd_obj->getCalculationPayStubAmount($pay_stub_obj), $annual_deduction_amount);
                 Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                 if ($amount >= $min_wage and $amount <= $max_wage) {
                     $retval = $fixed_amount;
                 }
             } else {
                 $retval = 0;
             }
             unset($fixed_amount, $amount, $percent, $min_wage, $max_wage, $annual_deduction_amount);
             break;
         case 52:
             //Fixed Amount (w/Limit)
             if ($this->getUserValue1() == '') {
                 $fixed_amount = $cd_obj->getUserValue1();
             } else {
                 $fixed_amount = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $target_amount = $cd_obj->getUserValue2();
             } else {
                 $target_amount = $this->getUserValue2();
             }
             Debug::Text('Amount: ' . $fixed_amount . ' Target Amount: ' . $target_amount, __FILE__, __LINE__, __METHOD__, 10);
             $retval = 0;
             if ($fixed_amount != 0) {
                 $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
                 Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
                 if ($amount !== $target_amount) {
                     if (abs($fixed_amount) < abs(bcsub($amount, $target_amount))) {
                         //Use full fixed amount
                         Debug::Text('Not within reach of target, use full fixed amount...', __FILE__, __LINE__, __METHOD__, 10);
                         $retval = $fixed_amount;
                     } else {
                         Debug::Text('Within reach of target, use partial fixed amount...', __FILE__, __LINE__, __METHOD__, 10);
                         //Use partial fixed_amount
                         $retval = bcadd(abs($amount), $target_amount);
                     }
                 }
             }
             $retval = abs($retval);
             unset($fixed_amount, $tmp_amount, $amount, $min_limit, $max_limit);
             break;
         case 69:
             // Custom Formulas
             if ($this->getUserValue1() == '') {
                 $user_value1 = $cd_obj->getUserValue1();
             } else {
                 $user_value1 = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $user_value2 = $cd_obj->getUserValue2();
             } else {
                 $user_value2 = $this->getUserValue2();
             }
             if ($this->getUserValue3() == '') {
                 $user_value3 = $cd_obj->getUserValue3();
             } else {
                 $user_value3 = $this->getUserValue3();
             }
             if ($this->getUserValue4() == '') {
                 $user_value4 = $cd_obj->getUserValue4();
             } else {
                 $user_value4 = $this->getUserValue4();
             }
             if ($this->getUserValue5() == '') {
                 $user_value5 = $cd_obj->getUserValue5();
             } else {
                 $user_value5 = $this->getUserValue5();
             }
             if ($this->getUserValue6() == '') {
                 $user_value6 = $cd_obj->getUserValue6();
             } else {
                 $user_value6 = $this->getUserValue6();
             }
             if ($this->getUserValue7() == '') {
                 $user_value7 = $cd_obj->getUserValue7();
             } else {
                 $user_value7 = $this->getUserValue7();
             }
             if ($this->getUserValue8() == '') {
                 $user_value8 = $cd_obj->getUserValue8();
             } else {
                 $user_value8 = $this->getUserValue8();
             }
             if ($this->getUserValue9() == '') {
                 $user_value9 = $cd_obj->getUserValue9();
             } else {
                 $user_value9 = $this->getUserValue9();
             }
             if ($this->getUserValue10() == '') {
                 $user_value10 = $cd_obj->getUserValue10();
             } else {
                 $user_value10 = $this->getUserValue10();
             }
             // evaluate math expressions as the company_value1 and user_value1-10 defined by user.
             $company_value1 = $cd_obj->getCompanyValue1();
             // Custom Formula
             $variables = array();
             $formula_variables = array_keys((array) TTMath::parseColumnsFromFormula($company_value1));
             Debug::Arr($formula_variables, 'Formula Variables: ', __FILE__, __LINE__, __METHOD__, 10);
             if (is_array($formula_variables)) {
                 if (in_array('currency_conversion_rate', $formula_variables) and is_object($this->getUserObject()) and is_object($this->getUserObject()->getCurrencyObject())) {
                     $currency_iso_code = $this->getUserObject()->getCurrencyObject()->getISOCode();
                     $currency_conversion_rate = $this->getUserObject()->getCurrencyObject()->getConversionRate();
                     Debug::Text('Currency Variables: Rate: ' . $currency_conversion_rate . ' ISO: ' . $currency_iso_code, __FILE__, __LINE__, __METHOD__, 10);
                 }
                 //First pass to gather any necessary data based on variables
                 if (in_array('employee_hourly_rate', $formula_variables) or in_array('employee_annual_wage', $formula_variables) or in_array('employee_wage_average_weekly_hours', $formula_variables)) {
                     $uwlf = TTnew('UserWageListFactory');
                     $uwlf->getWageByUserIdAndPayPeriodEndDate($this->getUser(), $pay_period_obj->getEndDate());
                     if ($uwlf->getRecordCount() > 0) {
                         $uwf = $uwlf->getCurrent();
                         $employee_hourly_rate = $uwf->getHourlyRate();
                         $employee_annual_wage = $uwf->getAnnualWage();
                         $employee_wage_average_weekly_hours = TTDate::getHours($uwf->getWeeklyTime());
                     } else {
                         $employee_hourly_rate = 0;
                         $employee_annual_wage = 0;
                         $employee_wage_average_weekly_hours = 0;
                     }
                     Debug::Text('Employee Hourly Rate: ' . $employee_hourly_rate, __FILE__, __LINE__, __METHOD__, 10);
                 }
                 if ($cd_obj->getCompanyValue2() != '' and $cd_obj->getCompanyValue2() > 0 and $cd_obj->getCompanyValue3() != '' and $cd_obj->getCompanyValue3() > 0) {
                     Debug::Text('Formula Lookback enable: ' . $cd_obj->getCompanyValue2(), __FILE__, __LINE__, __METHOD__, 10);
                     foreach ($formula_variables as $formula_variable) {
                         if (strpos($formula_variable, 'lookback_') !== FALSE) {
                             Debug::Text('Lookback variables exist...', __FILE__, __LINE__, __METHOD__, 10);
                             $lookback_dates = $cd_obj->getLookbackStartAndEndDates($pay_period_obj);
                             $lookback_pay_stub_dates = $cd_obj->getLookbackPayStubs($this->getUser(), $pay_period_obj);
                             break;
                         }
                     }
                 }
                 //Second pass to define variables.
                 foreach ($formula_variables as $formula_variable) {
                     if (!isset($variables[$formula_variable])) {
                         switch ($formula_variable) {
                             case 'custom_value1':
                                 $variables[$formula_variable] = $user_value1;
                                 break;
                             case 'custom_value2':
                                 $variables[$formula_variable] = $user_value2;
                                 break;
                             case 'custom_value3':
                                 $variables[$formula_variable] = $user_value3;
                                 break;
                             case 'custom_value4':
                                 $variables[$formula_variable] = $user_value4;
                                 break;
                             case 'custom_value5':
                                 $variables[$formula_variable] = $user_value5;
                                 break;
                             case 'custom_value6':
                                 $variables[$formula_variable] = $user_value6;
                                 break;
                             case 'custom_value7':
                                 $variables[$formula_variable] = $user_value7;
                                 break;
                             case 'custom_value8':
                                 $variables[$formula_variable] = $user_value8;
                                 break;
                             case 'custom_value9':
                                 $variables[$formula_variable] = $user_value9;
                                 break;
                             case 'custom_value10':
                                 $variables[$formula_variable] = $user_value10;
                                 break;
                             case 'employee_hourly_rate':
                                 $variables[$formula_variable] = $employee_hourly_rate;
                                 break;
                             case 'employee_annual_wage':
                                 $variables[$formula_variable] = $employee_annual_wage;
                                 break;
                             case 'employee_wage_average_weekly_hours':
                                 $variables[$formula_variable] = $employee_wage_average_weekly_hours;
                                 break;
                             case 'annual_pay_periods':
                                 $variables[$formula_variable] = $annual_pay_periods;
                                 break;
                             case 'pay_period_start_date':
                                 $variables[$formula_variable] = $pay_period_obj->getStartDate();
                                 break;
                             case 'pay_period_end_date':
                                 $variables[$formula_variable] = $pay_period_obj->getEndDate();
                                 break;
                             case 'pay_period_transaction_date':
                                 $variables[$formula_variable] = $pay_period_obj->getTransactionDate();
                                 break;
                             case 'employee_hire_date':
                                 $variables[$formula_variable] = $this->getUserObject()->getHireDate();
                                 break;
                             case 'employee_termination_date':
                                 $variables[$formula_variable] = $this->getUserObject()->getTerminationDate();
                                 break;
                             case 'employee_birth_date':
                                 $variables[$formula_variable] = $this->getUserObject()->getBirthDate();
                                 break;
                             case 'currency_iso_code':
                                 $variables[$formula_variable] = $currency_iso_code;
                                 break;
                             case 'currency_conversion_rate':
                                 $variables[$formula_variable] = $currency_conversion_rate;
                                 break;
                             case 'include_pay_stub_amount':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, 10);
                                 break;
                             case 'include_pay_stub_ytd_amount':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, 30);
                                 break;
                             case 'include_pay_stub_units':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, 20);
                                 break;
                             case 'include_pay_stub_ytd_units':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, 40);
                                 break;
                             case 'exclude_pay_stub_amount':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, NULL, 10);
                                 break;
                             case 'exclude_pay_stub_ytd_amount':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, NULL, 30);
                                 break;
                             case 'exclude_pay_stub_units':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, NULL, 20);
                                 break;
                             case 'exclude_pay_stub_ytd_units':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, NULL, 40);
                                 break;
                             case 'pay_stub_amount':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, 10, 10);
                                 break;
                             case 'pay_stub_ytd_amount':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, 30, 30);
                                 break;
                             case 'pay_stub_units':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, 20, 20);
                                 break;
                             case 'pay_stub_ytd_units':
                                 $variables[$formula_variable] = $cd_obj->getCalculationPayStubAmount($pay_stub_obj, 40, 40);
                                 break;
                                 //Lookback variables.
                             //Lookback variables.
                             case 'lookback_total_pay_stubs':
                                 $variables[$formula_variable] = isset($lookback_pay_stub_dates['total_pay_stubs']) ? $lookback_pay_stub_dates['total_pay_stubs'] : 0;
                                 break;
                             case 'lookback_start_date':
                                 $variables[$formula_variable] = isset($lookback_dates['start_date']) ? $lookback_dates['start_date'] : 0;
                                 break;
                             case 'lookback_end_date':
                                 $variables[$formula_variable] = isset($lookback_dates['end_date']) ? $lookback_dates['end_date'] : 0;
                                 break;
                             case 'lookback_first_pay_stub_start_date':
                                 $variables[$formula_variable] = isset($lookback_pay_stub_dates['first_pay_stub_start_date']) ? $lookback_pay_stub_dates['first_pay_stub_start_date'] : 0;
                                 break;
                             case 'lookback_first_pay_stub_end_date':
                                 $variables[$formula_variable] = isset($lookback_pay_stub_dates['first_pay_stub_end_date']) ? $lookback_pay_stub_dates['first_pay_stub_end_date'] : 0;
                                 break;
                             case 'lookback_first_pay_stub_transaction_date':
                                 $variables[$formula_variable] = isset($lookback_pay_stub_dates['first_pay_stub_transaction_date']) ? $lookback_pay_stub_dates['first_pay_stub_transaction_date'] : 0;
                                 break;
                             case 'lookback_last_pay_stub_start_date':
                                 $variables[$formula_variable] = isset($lookback_pay_stub_dates['last_pay_stub_start_date']) ? $lookback_pay_stub_dates['last_pay_stub_start_date'] : 0;
                                 break;
                             case 'lookback_last_pay_stub_end_date':
                                 $variables[$formula_variable] = isset($lookback_pay_stub_dates['last_pay_stub_end_date']) ? $lookback_pay_stub_dates['last_pay_stub_end_date'] : 0;
                                 break;
                             case 'lookback_last_pay_stub_transaction_date':
                                 $variables[$formula_variable] = isset($lookback_pay_stub_dates['last_pay_stub_transaction_date']) ? $lookback_pay_stub_dates['last_pay_stub_end_date'] : 0;
                                 break;
                             case 'lookback_include_pay_stub_amount':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(10);
                                 break;
                             case 'lookback_include_pay_stub_ytd_amount':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(30);
                                 break;
                             case 'lookback_include_pay_stub_units':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(20);
                                 break;
                             case 'lookback_include_pay_stub_ytd_units':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(40);
                                 break;
                             case 'lookback_exclude_pay_stub_amount':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(NULL, 10);
                                 break;
                             case 'lookback_exclude_pay_stub_ytd_amount':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(NULL, 30);
                                 break;
                             case 'lookback_exclude_pay_stub_units':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(NULL, 20);
                                 break;
                             case 'lookback_exclude_pay_stub_ytd_units':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(NULL, 40);
                                 break;
                             case 'lookback_pay_stub_amount':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(10, 10);
                                 break;
                             case 'lookback_pay_stub_ytd_amount':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(30, 30);
                                 break;
                             case 'lookback_pay_stub_units':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(20, 20);
                                 break;
                             case 'lookback_pay_stub_ytd_units':
                                 $variables[$formula_variable] = $cd_obj->getLookbackCalculationPayStubAmount(40, 40);
                                 break;
                         }
                     }
                 }
                 unset($uwlf, $uwf, $employee_hourly_rate, $employee_annual_wage, $employee_wage_average_weekly_hours, $annual_pay_periods, $lookback_dates, $lookback_pay_stub_dates, $currency_iso_code, $currency_conversion_rate);
             }
             //Debug::Arr( $variables,  'Formula Variable values: ', __FILE__, __LINE__, __METHOD__, 10 );
             Debug::Arr(array(str_replace("\r", '; ', $company_value1), str_replace("\r", '; ', TTMath::translateVariables($company_value1, $variables))), 'Original/Translated Formula: ', __FILE__, __LINE__, __METHOD__, 10);
             $retval = TTMath::evaluate(TTMath::translateVariables($company_value1, $variables));
             Debug::Text('Formula Retval: ' . $retval, __FILE__, __LINE__, __METHOD__, 10);
             break;
         case 80:
             //US Earning Income Credit (EIC). Repealed as of 31-Dec-2010.
             if ($this->getUserValue1() == '') {
                 $user_value1 = $cd_obj->getUserValue1();
             } else {
                 $user_value1 = $this->getUserValue1();
             }
             Debug::Text('UserValue1: ' . $user_value1, __FILE__, __LINE__, __METHOD__, 10);
             $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
             Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('Annual Pay Periods: ' . $annual_pay_periods, __FILE__, __LINE__, __METHOD__, 10);
             $pd_obj = new PayrollDeduction('US', NULL);
             $pd_obj->setCompany($this->getUserObject()->getCompany());
             $pd_obj->setUser($this->getUser());
             $pd_obj->setDate($pay_period_obj->getTransactionDate());
             $pd_obj->setAnnualPayPeriods($annual_pay_periods);
             if (is_object($this->getUserObject())) {
                 $currency_id = $this->getUserObject()->getCurrency();
                 $pd_obj->setUserCurrency($currency_id);
                 Debug::Text('User Currency ID: ' . $currency_id, __FILE__, __LINE__, __METHOD__, 10);
             }
             $pd_obj->setEICFilingStatus($user_value1);
             $pd_obj->setGrossPayPeriodIncome($amount);
             //Allow negative value, infact it always should be.
             $retval = $pd_obj->getEIC();
             break;
         case 82:
             //US - Medicare - Employee
         //US - Medicare - Employee
         case 83:
             //US - Medicare - Employer
         //US - Medicare - Employer
         case 84:
             //US - Social Security - Employee
         //US - Social Security - Employee
         case 85:
             //US - Social Security - Employer
             if ($this->getUserValue1() == '') {
                 $user_value1 = $cd_obj->getUserValue1();
             } else {
                 $user_value1 = $this->getUserValue1();
             }
             Debug::Text('UserValue1: ' . $user_value1, __FILE__, __LINE__, __METHOD__, 10);
             $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
             Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('Annual Pay Periods: ' . $annual_pay_periods, __FILE__, __LINE__, __METHOD__, 10);
             $pd_obj = new PayrollDeduction('US', NULL);
             $pd_obj->setCompany($this->getUserObject()->getCompany());
             $pd_obj->setUser($this->getUser());
             $pd_obj->setDate($pay_period_obj->getTransactionDate());
             $pd_obj->setAnnualPayPeriods($annual_pay_periods);
             if (is_object($this->getUserObject())) {
                 $currency_id = $this->getUserObject()->getCurrency();
                 $pd_obj->setUserCurrency($currency_id);
                 Debug::Text('User Currency ID: ' . $currency_id, __FILE__, __LINE__, __METHOD__, 10);
             }
             $pd_obj->setGrossPayPeriodIncome($amount);
             switch ($cd_obj->getCalculation()) {
                 case 82:
                     //US - Medicare - Employee
                     $pd_obj->setMedicareFilingStatus($user_value1);
                     $pd_obj->setYearToDateGrossIncome($cd_obj->getCalculationYTDAmount($pay_stub_obj));
                     $retval = $pd_obj->getEmployeeMedicare();
                     break;
                 case 83:
                     //US - Medicare - Employer
                     $retval = $pd_obj->getEmployerMedicare();
                     break;
                 case 84:
                     //US - Social Security - Employee
                     $retval = $pd_obj->getEmployeeSocialSecurity();
                     break;
                 case 85:
                     //US - Social Security - Employer
                     $retval = $pd_obj->getEmployerSocialSecurity();
                     break;
             }
             break;
         case 90:
             //Canada - CPP
             $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
             Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('Annual Pay Periods: ' . $annual_pay_periods, __FILE__, __LINE__, __METHOD__, 10);
             $pd_obj = new PayrollDeduction('CA', NULL);
             $pd_obj->setCompany($this->getUserObject()->getCompany());
             $pd_obj->setUser($this->getUser());
             $pd_obj->setDate($pay_period_obj->getTransactionDate());
             $pd_obj->setAnnualPayPeriods($annual_pay_periods);
             $pd_obj->setEnableCPPAndEIDeduction(TRUE);
             if ($this->getPayStubEntryAccountLinkObject()->getEmployeeCPP() != '') {
                 Debug::Text('Found Employee CPP account link!: ', __FILE__, __LINE__, __METHOD__, 10);
                 $previous_ytd_cpp_arr = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('previous', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeCPP());
                 $current_ytd_cpp_arr = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('current', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeCPP());
                 Debug::text('YTD CPP Contribution: Previous Amount: ' . $previous_ytd_cpp_arr['ytd_amount'] . ' Current Amount: ' . $current_ytd_cpp_arr['amount'], __FILE__, __LINE__, __METHOD__, 10);
                 $pd_obj->setYearToDateCPPContribution(bcadd($previous_ytd_cpp_arr['ytd_amount'], $current_ytd_cpp_arr['ytd_amount']));
                 unset($previous_ytd_cpp_arr, $current_ytd_cpp_arr);
             }
             $pd_obj->setGrossPayPeriodIncome($amount);
             $retval = $pd_obj->getEmployeeCPP();
             if ($retval < 0) {
                 $retval = 0;
             }
             break;
         case 91:
             //Canada - EI
             $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
             Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('Annual Pay Periods: ' . $annual_pay_periods, __FILE__, __LINE__, __METHOD__, 10);
             $pd_obj = new PayrollDeduction('CA', NULL);
             $pd_obj->setCompany($this->getUserObject()->getCompany());
             $pd_obj->setUser($this->getUser());
             $pd_obj->setDate($pay_period_obj->getTransactionDate());
             $pd_obj->setAnnualPayPeriods($annual_pay_periods);
             $pd_obj->setEnableCPPAndEIDeduction(TRUE);
             if ($this->getPayStubEntryAccountLinkObject()->getEmployeeEI() != '') {
                 Debug::Text('Found Employee EI account link!: ', __FILE__, __LINE__, __METHOD__, 10);
                 $previous_ytd_ei_arr = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('previous', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeEI());
                 $current_ytd_ei_arr = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('current', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeEI());
                 Debug::text('YTD EI Contribution: Previous Amount: ' . $previous_ytd_ei_arr['ytd_amount'] . ' Current Amount: ' . $current_ytd_ei_arr['amount'], __FILE__, __LINE__, __METHOD__, 10);
                 $pd_obj->setYearToDateEIContribution(bcadd($previous_ytd_ei_arr['ytd_amount'], $current_ytd_ei_arr['ytd_amount']));
                 unset($previous_ytd_ei_arr, $current_ytd_ei_arr);
             }
             $pd_obj->setGrossPayPeriodIncome($amount);
             $retval = $pd_obj->getEmployeeEI();
             if ($retval < 0) {
                 $retval = 0;
             }
             break;
         case 100:
             //Federal Income Tax
             if ($this->getUserValue1() == '') {
                 $user_value1 = $cd_obj->getUserValue1();
             } else {
                 $user_value1 = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $user_value2 = $cd_obj->getUserValue2();
             } else {
                 $user_value2 = $this->getUserValue2();
             }
             Debug::Text('UserValue1: ' . $user_value1, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('UserValue2: ' . $user_value2, __FILE__, __LINE__, __METHOD__, 10);
             $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
             Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('Annual Pay Periods: ' . $annual_pay_periods, __FILE__, __LINE__, __METHOD__, 10);
             $pd_obj = new PayrollDeduction($this->getCompanyDeductionObject()->getCountry(), NULL);
             $pd_obj->setCompany($this->getUserObject()->getCompany());
             $pd_obj->setUser($this->getUser());
             $pd_obj->setDate($pay_period_obj->getTransactionDate());
             $pd_obj->setAnnualPayPeriods($annual_pay_periods);
             if (is_object($this->getUserObject())) {
                 $currency_id = $this->getUserObject()->getCurrency();
                 $pd_obj->setUserCurrency($currency_id);
                 Debug::Text('User Currency ID: ' . $currency_id, __FILE__, __LINE__, __METHOD__, 10);
             }
             if ($this->getCompanyDeductionObject()->getCountry() == 'CA') {
                 //CA
                 $pd_obj->setFederalTotalClaimAmount($user_value1);
                 $pd_obj->setEnableCPPAndEIDeduction(TRUE);
                 //$pself = TTnew( 'PayStubEntryListFactory' );
                 if ($this->getPayStubEntryAccountLinkObject()->getEmployeeCPP() != '') {
                     Debug::Text('Found Employee CPP account link!: ', __FILE__, __LINE__, __METHOD__, 10);
                     //Check to see if CPP was calculated on the CURRENT pay stub, if not assume they are CPP exempt.
                     //Single this calculation formula doesn't know directly if the user was CPP exempt or not, we have to assume it by
                     //the calculate CPP on the current pay stub. However if the CPP calculation is done AFTER this, it may mistakenly assume they are exempt.
                     //Make sure we handle the maximum CPP contribution cases properly as well.
                     $current_cpp = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('current', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeCPP());
                     if (isset($current_cpp['amount']) and $current_cpp['amount'] == 0) {
                         Debug::Text('Current CPP: ' . $current_cpp['amount'] . ' Setting CPP exempt in Federal Income Tax calculation...', __FILE__, __LINE__, __METHOD__, 10);
                         $pd_obj->setCPPExempt(TRUE);
                     }
                     $ytd_cpp_arr = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('previous', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeCPP());
                     Debug::text('YTD CPP Contribution: ' . $ytd_cpp_arr['ytd_amount'], __FILE__, __LINE__, __METHOD__, 10);
                     $pd_obj->setYearToDateCPPContribution($ytd_cpp_arr['ytd_amount']);
                     unset($ytd_cpp_arr, $current_cpp);
                 }
                 if ($this->getPayStubEntryAccountLinkObject()->getEmployeeEI() != '') {
                     Debug::Text('Found Employee EI account link!: ', __FILE__, __LINE__, __METHOD__, 10);
                     //See comment above regarding CPP exempt.
                     $current_ei = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('current', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeEI());
                     if (isset($current_ei['amount']) and $current_ei['amount'] == 0) {
                         Debug::Text('Current EI: ' . $current_ei['amount'] . ' Setting EI exempt in Federal Income Tax calculation...', __FILE__, __LINE__, __METHOD__, 10);
                         $pd_obj->setEIExempt(TRUE);
                     }
                     $ytd_ei_arr = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('previous', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeEI());
                     Debug::text('YTD EI Contribution: ' . $ytd_ei_arr['ytd_amount'], __FILE__, __LINE__, __METHOD__, 10);
                     $pd_obj->setYearToDateEIContribution($ytd_ei_arr['ytd_amount']);
                     unset($ytd_ei_arr, $current_ei);
                 }
             } elseif ($this->getCompanyDeductionObject()->getCountry() == 'US') {
                 //US
                 $pd_obj->setFederalFilingStatus($user_value1);
                 $pd_obj->setFederalAllowance($user_value2);
             } elseif ($this->getCompanyDeductionObject()->getCountry() == 'CR') {
                 //CR
                 $pd_obj->setFederalFilingStatus($user_value1);
                 //Single/Married
                 $pd_obj->setFederalAllowance($user_value2);
                 //Allownces/Children
             }
             $pd_obj->setGrossPayPeriodIncome($amount);
             $retval = $pd_obj->getFederalPayPeriodDeductions();
             if ($retval < 0) {
                 $retval = 0;
             }
             break;
         case 200:
             //Province Income Tax
             if ($this->getUserValue1() == '') {
                 $user_value1 = $cd_obj->getUserValue1();
             } else {
                 $user_value1 = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $user_value2 = $cd_obj->getUserValue2();
             } else {
                 $user_value2 = $this->getUserValue2();
             }
             if ($this->getUserValue3() == '') {
                 $user_value3 = $cd_obj->getUserValue3();
             } else {
                 $user_value3 = $this->getUserValue3();
             }
             Debug::Text('UserValue1: ' . $user_value1, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('UserValue2: ' . $user_value2, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('UserValue3: ' . $user_value3, __FILE__, __LINE__, __METHOD__, 10);
             $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
             Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('Annual Pay Periods: ' . $annual_pay_periods, __FILE__, __LINE__, __METHOD__, 10);
             $pd_obj = new PayrollDeduction($this->getCompanyDeductionObject()->getCountry(), $this->getCompanyDeductionObject()->getProvince());
             $pd_obj->setCompany($this->getUserObject()->getCompany());
             $pd_obj->setUser($this->getUser());
             $pd_obj->setDate($pay_period_obj->getTransactionDate());
             $pd_obj->setAnnualPayPeriods($annual_pay_periods);
             $pd_obj->setGrossPayPeriodIncome($amount);
             if ($this->getCompanyDeductionObject()->getCountry() == 'CA') {
                 Debug::Text('Canada Pay Period Deductions...', __FILE__, __LINE__, __METHOD__, 10);
                 $pd_obj->setProvincialTotalClaimAmount($user_value1);
                 $pd_obj->setEnableCPPAndEIDeduction(TRUE);
                 //$pself = TTnew( 'PayStubEntryListFactory' );
                 if ($this->getPayStubEntryAccountLinkObject()->getEmployeeCPP() != '') {
                     Debug::Text('Found Employee CPP account link!: ', __FILE__, __LINE__, __METHOD__, 10);
                     //Check to see if CPP was calculated on the CURRENT pay stub, if not assume they are CPP exempt.
                     //Single this calculation formula doesn't know directly if the user was CPP exempt or not, we have to assume it by
                     //the calculate CPP on the current pay stub. However if the CPP calculation is done AFTER this, it may mistakenly assume they are exempt.
                     //Make sure we handle the maximum CPP contribution cases properly as well.
                     $current_cpp = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('current', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeCPP());
                     if (isset($current_cpp['amount']) and $current_cpp['amount'] == 0) {
                         Debug::Text('Current CPP: ' . $current_cpp['amount'] . ' Setting CPP exempt in Provincial Income Tax calculation...', __FILE__, __LINE__, __METHOD__, 10);
                         $pd_obj->setCPPExempt(TRUE);
                     }
                     $ytd_cpp_arr = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('previous', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeCPP());
                     Debug::text('YTD CPP Contribution: ' . $ytd_cpp_arr['ytd_amount'], __FILE__, __LINE__, __METHOD__, 10);
                     $pd_obj->setYearToDateCPPContribution($ytd_cpp_arr['ytd_amount']);
                     unset($ytd_cpp_arr, $current_cpp);
                 }
                 if ($this->getPayStubEntryAccountLinkObject()->getEmployeeEI() != '') {
                     Debug::Text('Found Employee EI account link!: ', __FILE__, __LINE__, __METHOD__, 10);
                     //See comment above regarding CPP exempt.
                     $current_ei = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('current', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeEI());
                     if (isset($current_ei['amount']) and $current_ei['amount'] == 0) {
                         Debug::Text('Current EI: ' . $current_ei['amount'] . ' Setting EI exempt in Provincial Income Tax calculation...', __FILE__, __LINE__, __METHOD__, 10);
                         $pd_obj->setEIExempt(TRUE);
                     }
                     $ytd_ei_arr = $pay_stub_obj->getSumByEntriesArrayAndTypeIDAndPayStubAccountID('previous', NULL, $this->getPayStubEntryAccountLinkObject()->getEmployeeEI());
                     Debug::text('YTD EI Contribution: ' . $ytd_ei_arr['ytd_amount'], __FILE__, __LINE__, __METHOD__, 10);
                     $pd_obj->setYearToDateEIContribution($ytd_ei_arr['ytd_amount']);
                     unset($ytd_ei_arr, $current_ei);
                 }
                 $retval = $pd_obj->getProvincialPayPeriodDeductions();
             } elseif ($this->getCompanyDeductionObject()->getCountry() == 'US') {
                 Debug::Text('US Pay Period Deductions...', __FILE__, __LINE__, __METHOD__, 10);
                 //Need to set Federal settings here.
                 $udlf = TTnew('UserDeductionListFactory');
                 $udlf->getByUserIdAndCountryID($user_id, $this->getCompanyDeductionObject()->getCountry());
                 if ($udlf->getRecordCount() > 0) {
                     Debug::Text('Found Federal User Deduction...', __FILE__, __LINE__, __METHOD__, 10);
                     $tmp_ud_obj = $udlf->getCurrent();
                     if ($tmp_ud_obj->getUserValue1() == '') {
                         $tmp_user_value1 = $tmp_ud_obj->getCompanyDeductionObject()->getUserValue1();
                     } else {
                         $tmp_user_value1 = $tmp_ud_obj->getUserValue1();
                     }
                     if ($tmp_ud_obj->getUserValue2() == '') {
                         $tmp_user_value2 = $tmp_ud_obj->getCompanyDeductionObject()->getUserValue2();
                     } else {
                         $tmp_user_value2 = $tmp_ud_obj->getUserValue2();
                     }
                     Debug::Text('TmpUserValue1: ' . $tmp_user_value1, __FILE__, __LINE__, __METHOD__, 10);
                     Debug::Text('TmpUserValue2: ' . $tmp_user_value2, __FILE__, __LINE__, __METHOD__, 10);
                     $pd_obj->setFederalFilingStatus($tmp_user_value1);
                     $pd_obj->setFederalAllowance($tmp_user_value2);
                     unset($tmp_ud_obj, $tmp_user_value1, $tmp_user_value1);
                 }
                 unset($udlf);
                 $pd_obj->setStateFilingStatus($user_value1);
                 $pd_obj->setStateAllowance($user_value2);
                 $pd_obj->setUserValue1($user_value1);
                 $pd_obj->setUserValue2($user_value2);
                 $pd_obj->setUserValue3($user_value3);
                 $retval = $pd_obj->getStatePayPeriodDeductions();
             }
             if ($retval < 0) {
                 $retval = 0;
             }
             break;
         case 300:
             //District Income Tax
             if ($this->getUserValue1() == '') {
                 $user_value1 = $cd_obj->getUserValue1();
             } else {
                 $user_value1 = $this->getUserValue1();
             }
             if ($this->getUserValue2() == '') {
                 $user_value2 = $cd_obj->getUserValue2();
             } else {
                 $user_value2 = $this->getUserValue2();
             }
             if ($this->getUserValue3() == '') {
                 $user_value3 = $cd_obj->getUserValue3();
             } else {
                 $user_value3 = $this->getUserValue3();
             }
             Debug::Text('UserValue1: ' . $user_value1, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('UserValue2: ' . $user_value2, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('UserValue3: ' . $user_value3, __FILE__, __LINE__, __METHOD__, 10);
             $amount = $cd_obj->getCalculationPayStubAmount($pay_stub_obj);
             Debug::Text('Amount: ' . $amount, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('Annual Pay Periods: ' . $annual_pay_periods, __FILE__, __LINE__, __METHOD__, 10);
             Debug::Text('District: ' . $this->getCompanyDeductionObject()->getDistrict(), __FILE__, __LINE__, __METHOD__, 10);
             $pd_obj = new PayrollDeduction($this->getCompanyDeductionObject()->getCountry(), $this->getCompanyDeductionObject()->getProvince(), $this->getCompanyDeductionObject()->getDistrict());
             $pd_obj->setCompany($this->getUserObject()->getCompany());
             $pd_obj->setUser($this->getUser());
             $pd_obj->setDate($pay_period_obj->getTransactionDate());
             $pd_obj->setAnnualPayPeriods($annual_pay_periods);
             $pd_obj->setDistrictFilingStatus($user_value1);
             $pd_obj->setDistrictAllowance($user_value2);
             $pd_obj->setUserValue1($user_value1);
             $pd_obj->setUserValue2($user_value2);
             $pd_obj->setUserValue3($user_value3);
             $pd_obj->setGrossPayPeriodIncome($amount);
             $retval = $pd_obj->getDistrictPayPeriodDeductions();
             if ($retval < 0) {
                 $retval = 0;
             }
             break;
     }
     Debug::Text('Deduction Amount: ' . $retval, __FILE__, __LINE__, __METHOD__, 10);
     //Allow negative values, as some advanced tax bracket setups require this.
     if ($retval < 0) {
         //Debug::Text('Deduction was negative, setting to 0...', __FILE__, __LINE__, __METHOD__,10);
         Debug::Text('Deduction was negative...', __FILE__, __LINE__, __METHOD__, 10);
         //$retval = 0;
     }
     return $retval;
 }
 function calcSystemTotalTime()
 {
     global $profiler;
     $profiler->startTimer('UserDateTotal::calcSystemTotalTime() - Part 1');
     if (!is_object($this->getUserDateObject())) {
         Debug::text(' UserDateObject not found!', __FILE__, __LINE__, __METHOD__, 10);
         return FALSE;
     }
     if (is_object($this->getUserDateObject()) and is_object($this->getUserDateObject()->getPayPeriodObject()) and $this->getUserDateObject()->getPayPeriodObject()->getStatus() == 20) {
         Debug::text(' Pay Period is closed!', __FILE__, __LINE__, __METHOD__, 10);
         return FALSE;
     }
     //IMPORTANT: Make sure the timezone is set to the users timezone, prior to calculating policies,
     //as that will affect when date/time premium policies apply
     //Its also important that the timezone gets set back after calculating multiple punches in a batch as this can prevent other employees
     //from using the wrong timezone.
     //FIXME: How do we handle the employee moving between stations that themselves are in different timezones from the users default timezone?
     //How do we apply time based premium policies in that case?
     if (is_object($this->getUserDateObject()) and is_object($this->getUserDateObject()->getUserObject()) and is_object($this->getUserDateObject()->getUserObject()->getUserPreferenceObject())) {
         $original_time_zone = TTDate::getTimeZone();
         TTDate::setTimeZone($this->getUserDateObject()->getUserObject()->getUserPreferenceObject()->getTimeZone());
     }
     //Take the worked hours, and calculate Total,Regular,Overtime,Premium hours from that.
     //This is where many of the policies will be applied
     //Such as any meal/overtime/premium policies.
     $return_value = FALSE;
     $udtlf = TTnew('UserDateTotalListFactory');
     $this->deleteSystemTotalTime();
     //We can't assign a dock absence to a given branch/dept automatically,
     //Because several punches with different branches could fall within a schedule punch pair.
     //Just total up entire day, and entire scheduled time to see if we're over/under
     //FIXME: Handle multiple schedules on a single day better.
     $schedule_total_time = 0;
     $meal_policy_ids = NULL;
     $break_policy_ids = NULL;
     $slf = TTnew('ScheduleListFactory');
     $profiler->startTimer('UserDateTotal::calcSystemTotalTime() - Holiday');
     //Check for Holidays
     $holiday_time = 0;
     $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->isEligible($this->getUserDateObject()->getUser())) {
             Debug::text(' User is Eligible for Holiday: ' . $holiday_obj->getName(), __FILE__, __LINE__, __METHOD__, 10);
             $holiday_time = $holiday_obj->getHolidayTime($this->getUserDateObject()->getUser());
             Debug::text(' User average time for Holiday: ' . TTDate::getHours($holiday_time), __FILE__, __LINE__, __METHOD__, 10);
             if ($holiday_time > 0 and $holiday_obj->getHolidayPolicyObject()->getAbsencePolicyID() != FALSE) {
                 Debug::text(' Adding Holiday hours: ' . TTDate::getHours($holiday_time), __FILE__, __LINE__, __METHOD__, 10);
                 $udtf = TTnew('UserDateTotalFactory');
                 $udtf->setUserDateID($this->getUserDateID());
                 $udtf->setStatus(30);
                 //Absence
                 $udtf->setType(10);
                 //Total
                 $udtf->setBranch($this->getUserDateObject()->getUserObject()->getDefaultBranch());
                 $udtf->setDepartment($this->getUserDateObject()->getUserObject()->getDefaultDepartment());
                 $udtf->setAbsencePolicyID($holiday_obj->getHolidayPolicyObject()->getAbsencePolicyID());
                 $udtf->setTotalTime($holiday_time);
                 $udtf->setEnableCalcSystemTotalTime(FALSE);
                 if ($udtf->isValid()) {
                     $udtf->Save();
                 }
             }
         }
         $slf->getByUserDateIdAndStatusId($this->getUserDateID(), 20);
         $schedule_absence_total_time = 0;
         if ($slf->getRecordCount() > 0) {
             //Check for schedule policy
             foreach ($slf as $s_obj) {
                 Debug::text(' Schedule Absence Total Time: ' . $s_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                 $schedule_absence_total_time += $s_obj->getTotalTime();
                 if (is_object($s_obj->getSchedulePolicyObject()) and $s_obj->getSchedulePolicyObject()->getAbsencePolicyID() > 0) {
                     $holiday_absence_policy_id = $s_obj->getSchedulePolicyObject()->getAbsencePolicyID();
                     Debug::text(' Found Absence Policy for docking: ' . $holiday_absence_policy_id, __FILE__, __LINE__, __METHOD__, 10);
                 } else {
                     Debug::text(' NO Absence Policy : ', __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
         }
         $holiday_total_under_time = $schedule_absence_total_time - $holiday_time;
         if (isset($holiday_absence_policy_id) and $holiday_total_under_time > 0) {
             Debug::text(' Schedule Under Time Case: ' . $holiday_total_under_time, __FILE__, __LINE__, __METHOD__, 10);
             $udtf = TTnew('UserDateTotalFactory');
             $udtf->setUserDateID($this->getUserDateID());
             $udtf->setStatus(30);
             //Absence
             $udtf->setType(10);
             //Total
             $udtf->setBranch($this->getUserDateObject()->getUserObject()->getDefaultBranch());
             $udtf->setDepartment($this->getUserDateObject()->getUserObject()->getDefaultDepartment());
             $udtf->setAbsencePolicyID($holiday_absence_policy_id);
             $udtf->setTotalTime($holiday_total_under_time);
             $udtf->setEnableCalcSystemTotalTime(FALSE);
             if ($udtf->isValid()) {
                 $udtf->Save();
             }
         }
         unset($holiday_total_under_time, $holiday_absence_policy_id, $schedule_absence_total_time);
     }
     $profiler->stopTimer('UserDateTotal::calcSystemTotalTime() - Holiday');
     //Do this after holiday policies have been applied, so if someone
     //schedules a holiday manually, we don't double up on the time.
     $slf->getByUserDateId($this->getUserDateID());
     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);
             if ($s_obj->getStatus() == 20 and $s_obj->getAbsencePolicyID() != '') {
                 Debug::text(' Scheduled Absence Found of Total Time: ' . $s_obj->getTotalTime(), __FILE__, __LINE__, __METHOD__, 10);
                 //If a holiday policy is applied on this day, ignore the schedule so we don't duplicate it.
                 //We could take the difference, and use the greatest of the two,
                 //But I think that will just open the door for errors.
                 if (!isset($holiday_obj) or $holiday_time == 0 and is_object($holiday_obj) and $holiday_obj->getHolidayPolicyObject()->getAbsencePolicyID() != $s_obj->getAbsencePolicyID()) {
                     $udtf = TTnew('UserDateTotalFactory');
                     $udtf->setUserDateID($this->getUserDateID());
                     $udtf->setStatus(30);
                     //Absence
                     $udtf->setType(10);
                     //Total
                     $udtf->setBranch($s_obj->getBranch());
                     $udtf->setDepartment($s_obj->getDepartment());
                     $udtf->setJob($s_obj->getJob());
                     $udtf->setJobItem($s_obj->getJobItem());
                     $udtf->setAbsencePolicyID($s_obj->getAbsencePolicyID());
                     $udtf->setTotalTime($s_obj->getTotalTime());
                     $udtf->setEnableCalcSystemTotalTime(FALSE);
                     if ($udtf->isValid()) {
                         $udtf->Save();
                     }
                 } else {
                     Debug::text(' Holiday Time Found, ignoring schedule!', __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
             /*
             elseif ( $s_obj->getStatus() == 10 ) {
             
             	$schedule_policy_ids[] = $s_obj->getSchedulePolicyID(); //Save schedule policies ID so we can passs them onto Premium Policies.
             
             	$schedule_total_time += $s_obj->getTotalTime();
             	if ( is_object($s_obj->getSchedulePolicyObject() ) ) {
             		$schedule_absence_policy_id = $s_obj->getSchedulePolicyObject()->getAbsencePolicyID();
             		$meal_policy_obj = $s_obj->getSchedulePolicyObject()->getMealPolicyObject();
             		Debug::text(' Found Absence Policy for docking: '. $schedule_absence_policy_id, __FILE__, __LINE__, __METHOD__,10);
             	} else {
             		Debug::text(' NO Absence Policy : ', __FILE__, __LINE__, __METHOD__,10);
             	}
             }
             */
         }
     } else {
         Debug::text(' No Schedules found. ', __FILE__, __LINE__, __METHOD__, 10);
     }
     unset($s_obj);
     unset($holiday_time, $holiday_obj);
     //Loop through punches on this day finding matching schedules.
     //Since schedules and punches may or may not fall on the same day, (there are always cases where they may not, due to employees coming in late) this is the only real way to match them properly.
     //This can happen even with assign shifts to the day they start on, if an employees shift starts at 11PM and they are 1.5hrs late, or if the shift starts at 12:30AM and they are 30 mins early.
     $schedule_policy_ids = array();
     $plf = TTnew('PunchListFactory');
     $plf->getByUserDateId($this->getUserDateID());
     if ($plf->getRecordCount() > 0) {
         foreach ($plf as $p_obj) {
             $schedule_ids[] = $p_obj->findScheduleID(NULL, $this->getUserDateObject()->getUser());
         }
     } else {
         //Debug::text(' No Punches found, grabbing all schedules on this day...', __FILE__, __LINE__, __METHOD__,10);
         //FIXME: If no punches are on a specific day, then its schedules are not even considered.
         //This breaks undertime absences, since they should have a full day of absence time but instead they won't have any.
         //It also doesn't work properly with split shifts, where the employee works the first part but not the 2nd part and should get undertime absence for the 2nd.
         //However if we handle it this way, the same scheduled shift can accounted for twice when the schedule and punches fall on different days.
         /*
         $slf->getByUserDateId( $this->getUserDateID() );
         if ( $slf->getRecordCount() > 0 ) {
         	//Check for schedule policy
         	foreach ( $slf as $s_obj ) {
         		$schedule_ids[] = $s_obj->getId();
         	}
         }
         */
     }
     if (isset($schedule_ids)) {
         $slf->getByCompanyIDAndId($this->getUserDateObject()->getUserObject()->getCompany(), array_unique((array) $schedule_ids));
         if ($slf->getRecordCount() > 0) {
             foreach ($slf as $s_obj) {
                 //Save schedule policies ID so we can pass them onto Premium Policies.
                 //Do this for both working and absence schedules, for purposes of calculating premium when employees are not scheduled.
                 $schedule_policy_ids[] = $s_obj->getSchedulePolicyID();
                 if ($s_obj->getStatus() == 10) {
                     $schedule_total_time += $s_obj->getTotalTime();
                     if (is_object($s_obj->getSchedulePolicyObject())) {
                         $schedule_absence_policy_id = $s_obj->getSchedulePolicyObject()->getAbsencePolicyID();
                         $meal_policy_ids = $s_obj->getSchedulePolicyObject()->getMealPolicyID();
                         $break_policy_ids = $s_obj->getSchedulePolicyObject()->getBreakPolicy();
                         Debug::text(' Found Absence Policy for docking: ' . $schedule_absence_policy_id, __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text(' NO Absence Policy : ', __FILE__, __LINE__, __METHOD__, 10);
                     }
                 }
             }
         }
     }
     unset($plf, $p_obj, $s_obj, $slf, $schedule_ids);
     //Handle Meal Policy time.
     //Do this after schedule meal policies have been looked up, as those override any policy group meal policies.
     $meal_policy_time = $this->calcMealPolicyTotalTime($meal_policy_ids);
     $udt_meal_policy_adjustment_arr = $this->calcUserTotalMealPolicyAdjustment($meal_policy_time);
     //Debug::Arr($udt_meal_policy_adjustment_arr, 'UserDateTotal Meal Policy Adjustment: ', __FILE__, __LINE__, __METHOD__,10);
     $break_policy_time = $this->calcBreakPolicyTotalTime($break_policy_ids);
     $udt_break_policy_adjustment_arr = $this->calcUserTotalBreakPolicyAdjustment($break_policy_time);
     //Debug::Arr($udt_break_policy_adjustment_arr, 'UserDateTotal Break Policy Adjustment: ', __FILE__, __LINE__, __METHOD__,10);
     $daily_total_time = $this->getDailyTotalTime();
     Debug::text(' Daily Total Time: ' . $daily_total_time . ' Schedule Total Time: ' . $schedule_total_time, __FILE__, __LINE__, __METHOD__, 10);
     //Check for overtime policies or undertime absence policies
     if ($daily_total_time > $schedule_total_time) {
         Debug::text(' Schedule Over Time Case: ', __FILE__, __LINE__, __METHOD__, 10);
     } elseif (isset($schedule_absence_policy_id) and $schedule_absence_policy_id != '' and $daily_total_time < $schedule_total_time) {
         $total_under_time = bcsub($schedule_total_time, $daily_total_time);
         if ($total_under_time > 0) {
             Debug::text(' Schedule Under Time Case: ' . $total_under_time . ' Absence Policy ID: ' . $schedule_absence_policy_id, __FILE__, __LINE__, __METHOD__, 10);
             $udtf = TTnew('UserDateTotalFactory');
             $udtf->setUserDateID($this->getUserDateID());
             $udtf->setStatus(30);
             //Absence
             $udtf->setType(10);
             //Total
             $udtf->setBranch($this->getUserDateObject()->getUserObject()->getDefaultBranch());
             $udtf->setDepartment($this->getUserDateObject()->getUserObject()->getDefaultDepartment());
             $udtf->setAbsencePolicyID($schedule_absence_policy_id);
             $udtf->setTotalTime($total_under_time);
             $udtf->setEnableCalcSystemTotalTime(FALSE);
             if ($udtf->isValid()) {
                 $udtf->Save();
             }
         } else {
             Debug::text(' Schedule Under Time is a negative value, skipping dock time: ' . $total_under_time . ' Absence Policy ID: ' . $schedule_absence_policy_id, __FILE__, __LINE__, __METHOD__, 10);
         }
     } else {
         Debug::text(' No Dock Absenses', __FILE__, __LINE__, __METHOD__, 10);
     }
     unset($schedule_absence_policy_id);
     /*
     //This is no longer needed as calcAbsencePolicyTotalTime() is a NO-OP now.
     //Do this AFTER the UnderTime absence policy is submitted.
     $recalc_daily_total_time = $this->calcAbsencePolicyTotalTime();
     if ( $recalc_daily_total_time == TRUE ) {
     	//Total up all "worked" hours for the day again, this time include
     	//Paid Absences.
     	$daily_total_time = $this->getDailyTotalTime();
     	Debug::text('ReCalc Daily Total Time for Day: '. $daily_total_time, __FILE__, __LINE__, __METHOD__, 10);
     }
     */
     $profiler->stopTimer('UserDateTotal::calcSystemTotalTime() - Part 1');
     $user_data_total_compact_arr = $this->calcOverTimePolicyTotalTime($udt_meal_policy_adjustment_arr, $udt_break_policy_adjustment_arr);
     //Debug::Arr($user_data_total_compact_arr, 'User Data Total Compact Array: ', __FILE__, __LINE__, __METHOD__, 10);
     //Insert User Date Total rows for each compacted array entry.
     //The reason for compacting is to reduce the amount of rows as much as possible.
     if (is_array($user_data_total_compact_arr)) {
         $profiler->startTimer('UserDateTotal::calcSystemTotalTime() - Part 2');
         Debug::text('Compact Array Exists: ', __FILE__, __LINE__, __METHOD__, 10);
         foreach ($user_data_total_compact_arr as $type_id => $udt_arr) {
             Debug::text('Compact Array Entry: Type ID: ' . $type_id, __FILE__, __LINE__, __METHOD__, 10);
             if ($type_id == 20) {
                 //Regular Time
                 //Debug::text('Compact Array Entry: Branch ID: '. $udt_arr[' , __FILE__, __LINE__, __METHOD__, 10);
                 foreach ($udt_arr as $branch_id => $branch_arr) {
                     //foreach($branch_arr as $department_id => $total_time ) {
                     foreach ($branch_arr as $department_id => $department_arr) {
                         foreach ($department_arr as $job_id => $job_arr) {
                             foreach ($job_arr as $job_item_id => $data_arr) {
                                 Debug::text('Compact Array Entry: Regular Time - Branch ID: ' . $branch_id . ' Department ID: ' . $department_id . ' Job ID: ' . $job_id . ' Job Item ID: ' . $job_item_id . ' Total Time: ' . $data_arr['total_time'], __FILE__, __LINE__, __METHOD__, 10);
                                 $user_data_total_expanded[] = array('type_id' => $type_id, 'over_time_policy_id' => NULL, 'branch_id' => $branch_id, 'department_id' => $department_id, 'job_id' => $job_id, 'job_item_id' => $job_item_id, 'total_time' => $data_arr['total_time'], 'quantity' => $data_arr['quantity'], 'bad_quantity' => $data_arr['bad_quantity']);
                             }
                         }
                     }
                 }
             } else {
                 //Overtime
                 //Overtime array is completely different then regular time array!
                 foreach ($udt_arr as $over_time_policy_id => $policy_arr) {
                     foreach ($policy_arr as $branch_id => $branch_arr) {
                         //foreach($branch_arr as $department_id => $total_time ) {
                         foreach ($branch_arr as $department_id => $department_arr) {
                             foreach ($department_arr as $job_id => $job_arr) {
                                 foreach ($job_arr as $job_item_id => $data_arr) {
                                     Debug::text('Compact Array Entry: Policy ID: ' . $over_time_policy_id . ' Branch ID: ' . $branch_id . ' Department ID: ' . $department_id . ' Job ID: ' . $job_id . ' Job Item ID: ' . $job_item_id . ' Total Time: ' . $data_arr['total_time'], __FILE__, __LINE__, __METHOD__, 10);
                                     $user_data_total_expanded[] = array('type_id' => $type_id, 'over_time_policy_id' => $over_time_policy_id, 'branch_id' => $branch_id, 'department_id' => $department_id, 'job_id' => $job_id, 'job_item_id' => $job_item_id, 'total_time' => $data_arr['total_time'], 'quantity' => $data_arr['quantity'], 'bad_quantity' => $data_arr['bad_quantity']);
                                 }
                             }
                         }
                     }
                 }
             }
             unset($policy_arr, $branch_arr, $department_arr, $job_arr, $over_time_policy_id, $branch_id, $department_id, $job_id, $job_item_id, $data_arr);
         }
         $profiler->stopTimer('UserDateTotal::calcSystemTotalTime() - Part 2');
         //var_dump($user_data_total_expanded);
         //Do the actual inserts now.
         if (isset($user_data_total_expanded)) {
             foreach ($user_data_total_expanded as $data_arr) {
                 $profiler->startTimer('UserDateTotal::calcSystemTotalTime() - Part 2b');
                 Debug::text('Inserting from expanded array, Type ID: ' . $data_arr['type_id'], __FILE__, __LINE__, __METHOD__, 10);
                 $udtf = TTnew('UserDateTotalFactory');
                 $udtf->setUserDateID($this->getUserDateID());
                 $udtf->setStatus(10);
                 //System
                 $udtf->setType($data_arr['type_id']);
                 if (isset($data_arr['over_time_policy_id'])) {
                     $udtf->setOverTimePolicyId($data_arr['over_time_policy_id']);
                 }
                 $udtf->setBranch($data_arr['branch_id']);
                 $udtf->setDepartment($data_arr['department_id']);
                 $udtf->setJob($data_arr['job_id']);
                 $udtf->setJobItem($data_arr['job_item_id']);
                 $udtf->setQuantity($data_arr['quantity']);
                 $udtf->setBadQuantity($data_arr['bad_quantity']);
                 $udtf->setTotalTime($data_arr['total_time']);
                 $udtf->setEnableCalcSystemTotalTime(FALSE);
                 if ($udtf->isValid()) {
                     $udtf->Save();
                 } else {
                     Debug::text('aINVALID UserDateTotal Entry!!: ', __FILE__, __LINE__, __METHOD__, 10);
                 }
                 $profiler->stopTimer('UserDateTotal::calcSystemTotalTime() - Part 2b');
             }
             unset($user_data_total_expanded);
         }
     } else {
         $profiler->startTimer('UserDateTotal::calcSystemTotalTime() - Part 3');
         //We need to break this out by branch, dept, job, task
         $udtlf = TTnew('UserDateTotalListFactory');
         //FIXME: Should Absence time be included as "regular time". We do this on
         //the timesheet view manually as of 12-Jan-06. If we included it in the
         //regular time system totals, we wouldn't have to do it manually.
         //$udtlf->getByUserDateIdAndStatus( $this->getUserDateID(), array(20,30) );
         $udtlf->getByUserDateIdAndStatus($this->getUserDateID(), array(20));
         if ($udtlf->getRecordCount() > 0) {
             Debug::text('Found Total Hours for just regular time: Record Count: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
             $user_date_regular_time_compact_arr = NULL;
             foreach ($udtlf as $udt_obj) {
                 //Create compact array, so we don't make as many system entries.
                 //Check if this is a paid absence or not.
                 if ($udt_obj->getStatus() == 20 and $udt_obj->getTotalTime() > 0) {
                     $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()]);
                     }
                     if (isset($user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()])) {
                         Debug::text('     Adding to Compact Array: Regular Time -  Branch: ' . (int) $udt_obj->getBranch() . ' Department: ' . (int) $udt_obj->getDepartment(), __FILE__, __LINE__, __METHOD__, 10);
                         $user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['total_time'] += $udt_total_time;
                         $user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['quantity'] += $udt_obj->getQuantity();
                         $user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()]['bad_quantity'] += $udt_obj->getBadQuantity();
                     } else {
                         $user_date_regular_time_compact_arr[(int) $udt_obj->getBranch()][(int) $udt_obj->getDepartment()][(int) $udt_obj->getJob()][(int) $udt_obj->getJobItem()] = array('total_time' => $udt_total_time, 'quantity' => $udt_obj->getQuantity(), 'bad_quantity' => $udt_obj->getBadQuantity());
                     }
                     unset($udt_total_time);
                 } else {
                     Debug::text('Total Time is 0!!: ' . $udt_obj->getTotalTime() . ' Or its an UNPAID absence: ' . $udt_obj->getStatus(), __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
             if (isset($user_date_regular_time_compact_arr)) {
                 foreach ($user_date_regular_time_compact_arr as $branch_id => $branch_arr) {
                     //foreach($branch_arr as $department_id => $total_time ) {
                     foreach ($branch_arr as $department_id => $department_arr) {
                         foreach ($department_arr as $job_id => $job_arr) {
                             foreach ($job_arr as $job_item_id => $data_arr) {
                                 Debug::text('Compact Array Entry: bRegular Time - Branch ID: ' . $branch_id . ' Department ID: ' . $department_id . ' Job ID: ' . $job_id . ' Job Item ID: ' . $job_item_id . ' Total Time: ' . $data_arr['total_time'], __FILE__, __LINE__, __METHOD__, 10);
                                 $udtf = TTnew('UserDateTotalFactory');
                                 $udtf->setUserDateID($this->getUserDateID());
                                 $udtf->setStatus(10);
                                 //System
                                 $udtf->setType(20);
                                 //Regular
                                 $udtf->setBranch($branch_id);
                                 $udtf->setDepartment($department_id);
                                 $udtf->setJob($job_id);
                                 $udtf->setJobItem($job_item_id);
                                 $udtf->setQuantity($data_arr['quantity']);
                                 $udtf->setBadQuantity($data_arr['bad_quantity']);
                                 $udtf->setTotalTime($data_arr['total_time']);
                                 $udtf->setEnableCalcSystemTotalTime(FALSE);
                                 $udtf->Save();
                             }
                         }
                     }
                 }
             }
             unset($user_date_regular_time_compact_arr);
         }
     }
     //Handle Premium time.
     $this->calcPremiumPolicyTotalTime($udt_meal_policy_adjustment_arr, $udt_break_policy_adjustment_arr, $daily_total_time, $schedule_policy_ids);
     //Total Hours
     $udtf = TTnew('UserDateTotalFactory');
     $udtf->setUserDateID($this->getUserDateID());
     $udtf->setStatus(10);
     //System
     $udtf->setType(10);
     //Total
     $udtf->setTotalTime($daily_total_time);
     $udtf->setEnableCalcSystemTotalTime(FALSE);
     if ($udtf->isValid()) {
         $return_value = $udtf->Save();
     } else {
         $return_value = FALSE;
     }
     $profiler->stopTimer('UserDateTotal::calcSystemTotalTime() - Part 3');
     if ($this->getEnableCalcException() == TRUE) {
         ExceptionPolicyFactory::calcExceptions($this->getUserDateID(), $this->getEnablePreMatureException());
     }
     if (isset($original_time_zone)) {
         TTDate::setTimeZone($original_time_zone);
     }
     return $return_value;
 }
 function getNextPayPeriod($end_date = NULL)
 {
     if (!$this->Validator->isValid()) {
         return FALSE;
     }
     //Manual Pay Period Schedule, skip repeating...
     if ($this->getType() == 5) {
         return FALSE;
     }
     $pplf = new PayPeriodListFactory();
     //Debug::text('PP Schedule ID: '. $this->getId(), __FILE__, __LINE__, __METHOD__, 10);
     //Debug::text('PP Schedule Name: '. $this->getName(), __FILE__, __LINE__, __METHOD__, 10);
     Debug::text('PP Schedule Type (' . $this->getType() . '): ' . Option::getByKey($this->getType(), $this->getOptions('type')), __FILE__, __LINE__, __METHOD__, 10);
     //Debug::text('Anchor Date: '. $this->getAnchorDate() ." - ". TTDate::getDate('DATE+TIME', $this->getAnchorDate() ), __FILE__, __LINE__, __METHOD__, 10);
     //Debug::text('Primary Date: '. $this->getPrimaryDate() ." - ". TTDate::getDate('DATE+TIME', $this->getPrimaryDate() ), __FILE__, __LINE__, __METHOD__, 10);
     //Debug::text('Secondary Date: '. $this->getSecondaryDate() ." - ". TTDate::getDate('DATE+TIME', $this->getPrimaryDate() ), __FILE__, __LINE__, __METHOD__, 10);
     $last_pay_period_is_new = FALSE;
     if ($end_date != '' and $end_date != 0) {
         Debug::text('End Date is set: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10);
         $last_pay_period_end_date = $end_date;
     } else {
         Debug::text('Checking for Previous pay periods...', __FILE__, __LINE__, __METHOD__, 10);
         //Get the last pay period schedule in the database.
         $pplf->getByPayPeriodScheduleId($this->getId(), NULL, NULL, NULL, array('start_date' => 'desc'));
         $last_pay_period = $pplf->getCurrent();
         if ($last_pay_period->isNew()) {
             $last_pay_period_is_new = TRUE;
             Debug::text('No Previous pay periods...', __FILE__, __LINE__, __METHOD__, 10);
             //Do this so a rollover doesn't happen while we're calculating.
             //$last_pay_period_end_date = TTDate::getTime();
             //This causes the pay period schedule to jump ahead one month. So set this to be beginning of the month.
             $last_pay_period_end_date = TTDate::getBeginMonthEpoch();
         } else {
             Debug::text('Previous pay periods found... ID: ' . $last_pay_period->getId(), __FILE__, __LINE__, __METHOD__, 10);
             $last_pay_period_end_date = $last_pay_period->getEndDate();
         }
         unset($last_pay_period, $pplf);
     }
     Debug::text('aLast Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $last_pay_period_end_date) . ' (' . $last_pay_period_end_date . ')', __FILE__, __LINE__, __METHOD__, 10);
     //FIXME: This breaks having pay periods with different daily start times.
     //However, without it, I think DST breaks pay periods.
     //$last_pay_period_end_date = TTDate::getEndDayEpoch( $last_pay_period_end_date + 1 ) - 86400;
     $last_pay_period_end_date = TTDate::getEndDayEpoch($last_pay_period_end_date - 86400 / 2);
     Debug::text('bLast Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $last_pay_period_end_date) . ' (' . $last_pay_period_end_date . ')', __FILE__, __LINE__, __METHOD__, 10);
     if ($this->getDayStartTime() != 0) {
         Debug::text('Daily Start Time is set, adjusting Last Pay Period End Date by: ' . TTDate::getHours($this->getDayStartTime()), __FILE__, __LINE__, __METHOD__, 10);
         //Next adjust last_pay_period_end_date (which becomes the start date) to DayStartTime because then there could be a gap if they
         //change this mid-schedule. The End Date will take care of it after the first pay period.
         $last_pay_period_end_date = TTDate::getTimeLockedDate(TTDate::getBeginDayEpoch($last_pay_period_end_date) + $this->getDayStartTime(), $last_pay_period_end_date);
         Debug::text('cLast Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $last_pay_period_end_date) . ' (' . $last_pay_period_end_date . ')', __FILE__, __LINE__, __METHOD__, 10);
     }
     $insert_pay_period = 1;
     //deprecate primary pay periods.
     switch ($this->getType()) {
         case 10:
             //Weekly
         //Weekly
         case 20:
             //Bi-Weekly
             $last_pay_period_end_day_of_week = TTDate::getDayOfWeek($last_pay_period_end_date);
             Debug::text('Last Pay Period End Day Of Week: ' . $last_pay_period_end_day_of_week . ' Start Day Of Week: ' . $this->getStartDayOfWeek(), __LINE__, __METHOD__, 10);
             if ($last_pay_period_end_day_of_week != $this->getStartDayOfWeek()) {
                 Debug::text('zTmp Pay Period End Date: ' . 'next ' . TTDate::getDayOfWeekByInt($this->getStartDayOfWeek()), __FILE__, __LINE__, __METHOD__, 10);
                 //$tmp_pay_period_end_date = strtotime('next '. TTDate::getDayOfWeekByInt( $this->getStartDayOfWeek() ), $last_pay_period_end_date )-1;
                 $tmp_pay_period_end_date = strtotime('next ' . TTDate::getDayOfWeekByInt($this->getStartDayOfWeek(), FALSE), $last_pay_period_end_date);
                 //strtotime doesn't keep time when using "next", it resets it to midnight on the day, so we need to adjust for that.
                 $tmp_pay_period_end_date = TTDate::getTimeLockedDate(TTDate::getBeginDayEpoch($tmp_pay_period_end_date) + $this->getDayStartTime(), $tmp_pay_period_end_date) - 1;
             } else {
                 $tmp_pay_period_end_date = $last_pay_period_end_date;
                 //This should fix a bug where if they are creating a new pay period schedule
                 //starting on Monday with the anchor date of 01-Jul-08, it would start on 01-Jul-08 (Tue)
                 //rather moving back to the Monday.
                 if (TTDate::getDayOfMonth($tmp_pay_period_end_date) != TTDate::getDayOfMonth($tmp_pay_period_end_date + 1)) {
                     Debug::text('Right on day boundary, minus an additional second to account for difference...', __FILE__, __LINE__, __METHOD__, 10);
                     $tmp_pay_period_end_date--;
                 }
             }
             Debug::text('aTmp Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $tmp_pay_period_end_date) . ' (' . $tmp_pay_period_end_date . ')', __FILE__, __LINE__, __METHOD__, 10);
             $start_date = $tmp_pay_period_end_date + 1;
             if ($this->getType() == 10) {
                 //Weekly
                 $tmp_pay_period_end_date = TTDate::getMiddleDayEpoch($start_date) + 86400 * 7;
                 //Add one week
             } elseif ($this->getType() == 20) {
                 //Bi-Weekly
                 $tmp_pay_period_end_date = TTDate::getMiddleDayEpoch($start_date) + 86400 * 14;
                 //Add two weeks
             }
             //Use Begin Day Epoch to nullify DST issues.
             $end_date = TTDate::getBeginDayEpoch($tmp_pay_period_end_date) - 1;
             $transaction_date = TTDate::getMiddleDayEpoch(TTDate::getMiddleDayEpoch($end_date) + $this->getTransactionDate() * 86400);
             break;
         case 30:
             //Semi-monthly
             $tmp_last_pay_period_end_day_of_month = TTDate::getDayOfMonth($last_pay_period_end_date + 1);
             Debug::text('bLast Pay Period End Day Of Month: ' . $tmp_last_pay_period_end_day_of_month, __FILE__, __LINE__, __METHOD__, 10);
             if ($tmp_last_pay_period_end_day_of_month == $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth())) {
                 $insert_pay_period = 1;
                 $primary = TRUE;
             } elseif ($tmp_last_pay_period_end_day_of_month == $this->convertLastDayOfMonth($this->getSecondaryDayOfMonth())) {
                 $insert_pay_period = 2;
                 $primary = FALSE;
             } else {
                 Debug::text('Finding if Primary or Secondary is closest...', __FILE__, __LINE__, __METHOD__, 10);
                 $primary_date_offset = TTDate::getDateOfNextDayOfMonth($last_pay_period_end_date, NULL, $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth())) - $last_pay_period_end_date;
                 $secondary_date_offset = TTDate::getDateOfNextDayOfMonth($last_pay_period_end_date, NULL, $this->convertLastDayOfMonth($this->getSecondaryDayOfMonth())) - $last_pay_period_end_date;
                 Debug::text('Primary Date Offset: ' . TTDate::getDays($primary_date_offset) . ' Secondary Date Offset: ' . TTDate::getDays($secondary_date_offset), __FILE__, __LINE__, __METHOD__, 10);
                 if ($primary_date_offset <= $secondary_date_offset) {
                     $insert_pay_period = 1;
                     $primary = TRUE;
                     $last_pay_period_end_date = TTDate::getDateOfNextDayOfMonth($last_pay_period_end_date, NULL, $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth()));
                 } else {
                     $insert_pay_period = 2;
                     $primary = FALSE;
                     $last_pay_period_end_date = TTDate::getDateOfNextDayOfMonth($last_pay_period_end_date, NULL, $this->convertLastDayOfMonth($this->getSecondaryDayOfMonth()));
                 }
                 $last_pay_period_end_date = TTDate::getBeginDayEpoch($last_pay_period_end_date);
             }
             unset($tmp_last_pay_period_end_day_of_month);
             Debug::text('cLast Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $last_pay_period_end_date) . ' (' . $last_pay_period_end_date . ') Primary: ' . (int) $primary, __FILE__, __LINE__, __METHOD__, 10);
             $start_date = $last_pay_period_end_date + 1;
             if ($primary == TRUE) {
                 $end_date = TTDate::getBeginDayEpoch(TTDate::getDateOfNextDayOfMonth($start_date, NULL, $this->convertLastDayOfMonth($this->getSecondaryDayOfMonth()))) - 1;
                 $transaction_date = TTDate::getMiddleDayEpoch(TTDate::getDateOfNextDayOfMonth(TTDate::getMiddleDayEpoch($end_date), NULL, $this->convertLastDayOfMonth($this->getPrimaryTransactionDayOfMonth())));
             } else {
                 $end_date = TTDate::getBeginDayEpoch(TTDate::getDateOfNextDayOfMonth($start_date, NULL, $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth()))) - 1;
                 $transaction_date = TTDate::getMiddleDayEpoch(TTDate::getDateOfNextDayOfMonth(TTDate::getMiddleDayEpoch($end_date), NULL, $this->convertLastDayOfMonth($this->getSecondaryTransactionDayOfMonth())));
             }
             break;
         case 50:
             //Monthly
             $start_date = $last_pay_period_end_date + 1;
             $end_date = TTDate::getDateOfNextDayOfMonth($start_date + 86400, NULL, $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth()));
             //Use Begin Day Epoch to nullify DST issues.
             $end_date = TTDate::getBeginDayEpoch(TTDate::getBeginMinuteEpoch($end_date)) - 1;
             $transaction_date = TTDate::getMiddleDayEpoch(TTDate::getDateOfNextDayOfMonth($end_date, NULL, $this->convertLastDayOfMonth($this->getPrimaryTransactionDayOfMonth())));
             break;
     }
     if ($this->getDayStartTime() != 0) {
         Debug::text('Daily Start Time is set, adjusting End Date by: ' . TTDate::getHours($this->getDayStartTime()) . ' Start Date: ' . TTDate::getDate('DATE+TIME', $start_date), __FILE__, __LINE__, __METHOD__, 10);
         //We already account for DayStartTime in weekly/bi-weekly start_date cases above, so skip applying it again here.
         if ($this->getType() != 10 and $this->getType() != 20) {
             $start_date = $start_date + $this->getDayStartTime();
         }
         $end_date = $end_date + $this->getDayStartTime();
         //Need to do this, otherwise transaction date could be earlier then end date.
         $transaction_date = $transaction_date + $this->getDayStartTime();
     }
     Debug::text('aStart Date(' . $start_date . '): ' . TTDate::getDate('DATE+TIME', $start_date), __FILE__, __LINE__, __METHOD__, 10);
     Debug::text('aEnd Date(' . $end_date . '): ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10);
     Debug::text('aPay Date(' . $transaction_date . '): ' . TTDate::getDate('DATE+TIME', $transaction_date), __FILE__, __LINE__, __METHOD__, 10);
     //Handle last day of the month flag for primary and secondary dates here
     if ($this->getType() == 30 and ($insert_pay_period == 1 and ($this->getPrimaryDayOfMonth() == 31 or $this->getPrimaryDayOfMonth() == -1) or $insert_pay_period == 2 and ($this->getSecondaryDayOfMonth() == 31 or $this->getSecondaryDayOfMonth() == -1)) or $this->getType() == 50 and ($this->getPrimaryDayOfMonth() == 31 or $this->getPrimaryDayOfMonth() == -1)) {
         Debug::text('Last day of the month set for start date: ', __FILE__, __LINE__, __METHOD__, 10);
         if ($this->getDayStartTime() > 0) {
             //Minus one day, THEN add daily start time, otherwise it will go past the month boundary
             $end_date = TTDate::getEndMonthEpoch($end_date) - 86400 + $this->getDayStartTime();
             //End month epoch is 23:59:59, so don't minus one.
         } else {
             $end_date = TTDate::getEndMonthEpoch($end_date) + $this->getDayStartTime();
             //End month epoch is 23:59:59, so don't minus one.
         }
     }
     //Handle "last day of the month" for transaction dates.
     if ($this->getPrimaryDayOfMonth() == 31 or $this->getPrimaryDayOfMonth() == -1) {
         //Debug::text('LDOM set for Primary: ', __FILE__, __LINE__, __METHOD__, 10);
         $transaction_date = TTDate::getEndMonthEpoch($transaction_date);
     }
     //Handle "always business day" flag for transaction dates here.
     if ($this->getTransactionDateBusinessDay() == TRUE) {
         $transaction_date = $this->getTransactionBusinessDay($transaction_date);
     }
     if ($transaction_date < $end_date) {
         $transaction_date = $end_date;
     }
     Debug::text('Start Date: ' . TTDate::getDate('DATE+TIME', $start_date), __FILE__, __LINE__, __METHOD__, 10);
     Debug::text('End Date: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10);
     Debug::text('Pay Date: ' . TTDate::getDate('DATE+TIME', $transaction_date), __FILE__, __LINE__, __METHOD__, 10);
     Debug::text("<br><br>\n\n", __FILE__, __LINE__, __METHOD__, 10);
     $this->next_start_date = $start_date;
     $this->next_end_date = $end_date;
     $this->next_transaction_date = $transaction_date;
     //Its a primary pay period
     if ($insert_pay_period == 1) {
         $this->next_primary = TRUE;
     } else {
         $this->next_primary = FALSE;
     }
     return TRUE;
 }
 function getProjectedAccrualAmount($u_obj, $start_epoch, $end_epoch)
 {
     $start_epoch = TTDate::getMiddleDayEpoch($start_epoch);
     $end_epoch = TTDate::getMiddleDayEpoch($end_epoch);
     $offset = 79200;
     $accrual_amount = 0;
     Debug::Text('Start Date ' . TTDate::getDate('DATE+TIME', $start_epoch) . ' End Date: ' . TTDate::getDate('DATE+TIME', $end_epoch), __FILE__, __LINE__, __METHOD__, 10);
     $ppslf = TTNew('PayPeriodScheduleListFactory');
     $ppslf->getByCompanyIdAndUserId($u_obj->getCompany(), $u_obj->getId());
     if ($ppslf->getRecordCount() > 0) {
         $pps_obj = $ppslf->getCurrent();
         $accrual_balance = $this->getCurrentAccrualBalance($u_obj->getID(), $this->getId());
         $pay_period_arr = array();
         if ($this->getApplyFrequency() == 10) {
             $pay_period_arr = $this->getPayPeriodArray($pps_obj, $u_obj, $start_epoch, $end_epoch);
         }
         $accrual_amount = 0;
         for ($epoch = $start_epoch; $epoch <= $end_epoch; $epoch += 86400) {
             $epoch = TTDate::getBeginDayEpoch($epoch) + 7200;
             //This is required because the epoch has to be slightly AFTER the pay period end date, which is 11:59PM.
             $accrual_amount += $this->calcAccrualPolicyTime($u_obj, $epoch, $offset, $pps_obj, $pay_period_arr, $accrual_balance, FALSE);
         }
         Debug::Text('Projected Accrual Amount: ' . TTDate::getHours($accrual_amount), __FILE__, __LINE__, __METHOD__, 10);
     }
     return $accrual_amount;
 }
 function getShifts($start_date, $end_date, &$holiday_data = array(), &$branch_options = array(), &$department_options = array(), &$n, &$shifts = array(), &$shifts_index = array(), $open_shift_conflict_index = array(), $permission_children_ids = NULL)
 {
     //Debug::text('Start Date: '. TTDate::getDate('DATE+TIME', $start_date) .' End Date: '. TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10);
     $recurring_schedule_control_start_date = TTDate::strtotime($this->getColumn('recurring_schedule_control_start_date'));
     //Debug::text('Recurring Schedule Control Start Date: '. TTDate::getDate('DATE+TIME', $recurring_schedule_control_start_date),__FILE__, __LINE__, __METHOD__, 10);
     $current_template_week = $this->getColumn('remapped_week');
     $max_week = $this->getColumn('max_week');
     //Debug::text('Template Week: '. $current_template_week .' Max Week: '. $this->getColumn('max_week') .' ReMapped Week: '. $this->getColumn('remapped_week') ,__FILE__, __LINE__, __METHOD__, 10);
     if ($recurring_schedule_control_start_date == '') {
         return FALSE;
     }
     //Get week of start_date
     $start_date_week = TTDate::getBeginWeekEpoch($recurring_schedule_control_start_date, 0);
     //Start week on Sunday to match Recurring Schedule.
     //Debug::text('Week of Start Date: '. $start_date_week ,__FILE__, __LINE__, __METHOD__, 10);
     $apf = TTnew('AbsencePolicyFactory');
     $absence_policy_paid_type_options = $apf->getOptions('paid_type');
     for ($i = $start_date; $i <= $end_date; $i += 86400 + 43200) {
         //Handle DST by adding 12hrs to the date to get the mid-day epoch, then forcing it back to the beginning of the day.
         $i = TTDate::getBeginDayEpoch($i);
         if ($this->getColumn('hire_date') != '' and $i < $this->getColumn('hire_date') or $this->getColumn('termination_date') != '' and $i > $this->getColumn('termination_date')) {
             //Debug::text('Skipping due to Hire/Termination date: User ID: '. $this->getColumn('user_id') .' I: '. $i .' Hire Date: '. $this->getColumn('hire_date') .' Termination Date: '. $this->getColumn('termination_date') ,__FILE__, __LINE__, __METHOD__, 10);
             continue;
         }
         //This needs to take into account weeks spanning January 1st of each year. Where the week goes from 53 to 1.
         //Rather then use the week of the year, calculate the weeks between the recurring schedule start date and now.
         $current_week = round((TTDate::getBeginWeekEpoch($i, 0) - $start_date_week) / 604800);
         //Find out which week we are on based on the recurring schedule start date. Use round due to DST the week might be 6.9 or 7.1, so we need to round to the nearest full week.
         //Debug::text('I: '. $i .' User ID: '. $this->getColumn('user_id') .' Current Date: '. TTDate::getDate('DATE+TIME', $i) .' Current Week: '. $current_week .' Start Week: '. $start_date_week,__FILE__, __LINE__, __METHOD__, 10);
         $template_week = $current_week % $max_week + 1;
         //Debug::text('Template Week: '. $template_week .' Max Week: '. $max_week,__FILE__, __LINE__, __METHOD__, 10);
         if ($template_week == $current_template_week) {
             //Debug::text('Current Date: '. TTDate::getDate('DATE+TIME', $i) .' Current Week: '. $current_week,__FILE__, __LINE__, __METHOD__, 10);
             //Debug::text('&nbsp;Template Week: '. $template_week .' Max Week: '. $max_week,__FILE__, __LINE__, __METHOD__, 10);
             if ($this->isActiveShiftDay($i)) {
                 //Debug::text('&nbsp;&nbsp;Active Shift on this day...',__FILE__, __LINE__, __METHOD__, 10);
                 $start_time = TTDate::getTimeLockedDate($this->getStartTime(), $i);
                 $end_time = TTDate::getTimeLockedDate($this->getEndTime(), $i);
                 if ($end_time < $start_time) {
                     //Spans the day boundary, add 86400 to end_time
                     $end_time = $end_time + 86400;
                     //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Schedule spans day boundary, bumping endtime to next day: ',__FILE__, __LINE__, __METHOD__, 10);
                 }
                 $iso_date_stamp = TTDate::getISODateStamp(PayPeriodScheduleFactory::getShiftAssignedDate($start_time, $end_time, $this->getColumn('shift_assigned_day_id')));
                 //$iso_date_stamp = TTDate::getISODateStamp( $i );
                 $open_shift_multiplier = $this->getColumn('user_id') == 0 ? $this->getOpenShiftMultiplier() : 1;
                 //Debug::text('Open Shift Multiplier: '. $open_shift_multiplier,__FILE__, __LINE__, __METHOD__, 10);
                 for ($x = 0; $x < $open_shift_multiplier; $x++) {
                     //Check all non-OPEN shifts for conflicts.
                     if ($this->getColumn('user_id') > 0 and isset($shifts_index[$iso_date_stamp][$this->getColumn('user_id')])) {
                         //User has previous recurring schedule shifts, check for overlap.
                         //Loop over each employees shift for this day and check for conflicts
                         foreach ($shifts_index[$iso_date_stamp][$this->getColumn('user_id')] as $shift_key) {
                             if (isset($shifts[$iso_date_stamp][$shift_key])) {
                                 //Must use parseDateTime() when called from the API due to date formats that strtotime() fails on.
                                 if (TTDate::isTimeOverLap(defined('TIMETREX_API') ? TTDate::parseDateTime($shifts[$iso_date_stamp][$shift_key]['start_date']) : $shifts[$iso_date_stamp][$shift_key]['start_date'], defined('TIMETREX_API') ? TTDate::parseDateTime($shifts[$iso_date_stamp][$shift_key]['end_date']) : $shifts[$iso_date_stamp][$shift_key]['end_date'], $start_time, $end_time) == TRUE) {
                                     //Debug::text('&nbsp;&nbsp;Found overlapping recurring schedules! User ID: '. $this->getColumn('user_id') .' Start Time: '. $start_time,__FILE__, __LINE__, __METHOD__, 10);
                                     continue 2;
                                 }
                             }
                         }
                         unset($shift_key);
                     } elseif ($this->getColumn('user_id') == 0 and isset($shifts_index[$iso_date_stamp])) {
                         //Debug::text('    Checking OPEN shift conflicts... Date: '. $iso_date_stamp,__FILE__, __LINE__, __METHOD__, 10);
                         //Check all OPEN shifts for conflicts.
                         //This is special, since there can be multiple open shifts for the same branch,department,job,task, so we need to check if are conflicts with *any* employee.
                         //Do we allow conflicting shifts between committed and recurring OPEN shifts? For example what if there are two open shifts on the same day
                         //6AM-3PM (x2) and they want to override one of those shifts to 7AM-4PM? If we use this check:
                         //   ( $shifts[$iso_date_stamp][$shift_key]['user_id'] > 0 OR ( isset($shifts[$iso_date_stamp][$shift_key]['id']) AND $shifts[$iso_date_stamp][$shift_key]['id'] > 0 ) )
                         //That allows committed OPEN shifts to override recurring open shifts, which is great, but it prevents adding additional open shifts that may
                         //also overlap unless they override all recurring shifts first. I think this is the trade-off we have to make as its more likely that they
                         //will adjust an open shift time rather than add/remove specific shifts. Removing recurring OPEN shifts can be done by making them ABSENT.
                         //This will also affect when recurring OPEN shifts are committed by preventing the shifts from doubling up.
                         foreach ($shifts_index[$iso_date_stamp] as $tmp_index_user_id => $tmp_index_arr) {
                             foreach ($tmp_index_arr as $shift_key) {
                                 $tmp_start_date = defined('TIMETREX_API') ? TTDate::parseDateTime($shifts[$iso_date_stamp][$shift_key]['start_date']) : $shifts[$iso_date_stamp][$shift_key]['start_date'];
                                 $tmp_end_date = defined('TIMETREX_API') ? TTDate::parseDateTime($shifts[$iso_date_stamp][$shift_key]['end_date']) : $shifts[$iso_date_stamp][$shift_key]['end_date'];
                                 if (($shifts[$iso_date_stamp][$shift_key]['user_id'] > 0 or isset($shifts[$iso_date_stamp][$shift_key]['id']) and $shifts[$iso_date_stamp][$shift_key]['id'] > 0) and (!isset($open_shift_conflict_index['open'][$this->getID()][$shift_key]) and (isset($shifts[$iso_date_stamp][$shift_key]['id']) and !isset($open_shift_conflict_index['scheduled'][$shifts[$iso_date_stamp][$shift_key]['id']]))) and $this->getColumn('schedule_branch_id') == $shifts[$iso_date_stamp][$shift_key]['branch_id'] and $this->getColumn('schedule_department_id') == $shifts[$iso_date_stamp][$shift_key]['department_id'] and $this->getColumn('job_id') == $shifts[$iso_date_stamp][$shift_key]['job_id'] and $this->getColumn('job_item_id') == $shifts[$iso_date_stamp][$shift_key]['job_item_id'] and ($tmp_start_date == $start_time and $tmp_end_date == $end_time)) {
                                     //Debug::text('      Found OPEN shift conflict... Skipping...! Shift Key: '. $shift_key,__FILE__, __LINE__, __METHOD__, 10);
                                     //We need to track each shift_key that caused a conflict so it can't cause another conflict later on.
                                     //  Make sure we just track it on a per template basis though, otherwise the same $shift_key from a previous template can affect other templates.
                                     //  The above issue would show up as OPEN shifts not being overridden.
                                     //We also need to track which scheduled shift that caused a conflict so it can't cause another one later on.
                                     //  This prevents a single scheduled shift from overriding multiple OPEN shifts of different times.
                                     //However we need to be smarter about which shifts override which OPEN shifts...
                                     //  So if there are two open shifts, 10AM-4PM and 3:50PM-9PM, a 10AM-4PM scheduled shift overrides the OPEN shift that best fits it (10AM to 4PM, *not* 3:50-9PM)
                                     //  For now require an exact match to override an OPEN shift, if we start using partial schedules it gets much more complicated.
                                     //  Or we could introduce a hardcoded "fudge factor" setting (ie: 5 mins) that is always used instead.
                                     $open_shift_conflict_index['open'][$this->getID()][$shift_key] = TRUE;
                                     $open_shift_conflict_index['scheduled'][$shifts[$iso_date_stamp][$shift_key]['id']] = TRUE;
                                     continue 3;
                                 }
                                 unset($tmp_start_date, $tmp_end_date);
                             }
                         }
                         unset($tmp_index_user_id, $tmp_index_arr);
                     }
                     //This check has to occurr after the committed schedule check, otherwise no committed schedules will appear.
                     if ($this->getColumn('recurring_schedule_control_start_date') != '' and $i < TTDate::strtotime($this->getColumn('recurring_schedule_control_start_date')) or $this->getColumn('recurring_schedule_control_end_date') != '' and $i > TTDate::strtotime($this->getColumn('recurring_schedule_control_end_date'))) {
                         //Debug::text('Skipping due to Recurring Schedule Start/End date: ID: '. $this->getColumn('id') .' User ID: '. $this->getColumn('user_id') .' I: '. $i .' Start Date: '. $this->getColumn('recurring_schedule_control_start_date') .' ('. TTDate::strtotime( $this->getColumn('recurring_schedule_control_start_date') ) .') End Date: '. $this->getColumn('recurring_schedule_control_end_date') ,__FILE__, __LINE__, __METHOD__, 10);
                         continue;
                     }
                     //Debug::text('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Start Date: '. TTDate::getDate('DATE+TIME', $start_time) .' End Date: '. TTDate::getDate('DATE+TIME', $end_time),__FILE__, __LINE__, __METHOD__, 10);
                     $status_id = $this->getColumn('status_id');
                     $absence_policy_id = $this->getColumn('absence_policy_id');
                     $absence_policy_type_id = $this->getColumn('absence_policy_type_id');
                     $absence_policy = $this->getColumn('absence_policy') != '' ? $this->getColumn('absence_policy') : NULL;
                     //Must be NULL to be converted to N/A
                     if (isset($holiday_data[$iso_date_stamp])) {
                         //We have to assume they are eligible, because we really won't know
                         //if they will have worked enough days or not. We could assume they
                         //work whatever their schedule is, but chances are they will be eligible then anyways.
                         //Debug::text('&nbsp;&nbsp;Found Holiday on this day...',__FILE__, __LINE__, __METHOD__, 10);
                         $status_id = $holiday_data[$iso_date_stamp]['status_id'];
                         if (isset($holiday_data[$iso_date_stamp]['absence_policy_id'])) {
                             $absence_policy_id = $holiday_data[$iso_date_stamp]['absence_policy_id'];
                             $absence_policy_type_id = $holiday_data[$iso_date_stamp]['type_id'];
                             $absence_policy = $holiday_data[$iso_date_stamp]['absence_policy'];
                         }
                     }
                     $hourly_rate = Misc::MoneyFormat($this->getColumn('user_wage_hourly_rate'), FALSE);
                     if ($absence_policy_id > 0 and in_array($absence_policy_type_id, $absence_policy_paid_type_options) == FALSE) {
                         //UnPaid Absence.
                         $total_time_wage = Misc::MoneyFormat(0);
                     } else {
                         $total_time_wage = Misc::MoneyFormat(bcmul(TTDate::getHours($this->getTotalTime()), $hourly_rate), FALSE);
                     }
                     //Debug::text('I: '. $i .' N: '. $n .' User ID: '. $this->getColumn('user_id') .' Current Date: '. TTDate::getDate('DATE+TIME', $i) .' Current Week: '. $current_week .' Start Time: '. TTDate::getDate('DATE+TIME', $start_time ) .' Absence Policy: '. $absence_policy,__FILE__, __LINE__, __METHOD__, 10);
                     //$shifts[$iso_date_stamp][$this->getColumn('user_id').$start_time] = array(
                     $shifts[$iso_date_stamp][$n] = array('pay_period_id' => FALSE, 'user_id' => (int) $this->getColumn('user_id'), 'user_created_by' => $this->getColumn('user_created_by'), 'user_full_name' => $this->getColumn('user_id') > 0 ? Misc::getFullName($this->getColumn('first_name'), NULL, $this->getColumn('last_name'), FALSE, FALSE) : TTi18n::getText('OPEN'), 'first_name' => $this->getColumn('first_name'), 'last_name' => $this->getColumn('last_name'), 'title_id' => $this->getColumn('title_id'), 'title' => $this->getColumn('title'), 'group_id' => $this->getColumn('group_id'), 'group' => $this->getColumn('group'), 'default_branch_id' => $this->getColumn('default_branch_id'), 'default_branch' => $this->getColumn('default_branch'), 'default_department_id' => $this->getColumn('default_department_id'), 'default_department' => $this->getColumn('default_department'), 'job_id' => $this->getJob(), 'job' => $this->getColumn('job'), 'job_status_id' => $this->getColumn('job_status_id'), 'job_manual_id' => $this->getColumn('job_manual_id'), 'job_branch_id' => $this->getColumn('job_branch_id'), 'job_department_id' => $this->getColumn('job_department_id'), 'job_group_id' => $this->getColumn('job_group_id'), 'job_item_id' => $this->getJobItem(), 'job_item' => $this->getColumn('job_item'), 'type_id' => 20, 'status_id' => $status_id, 'date_stamp' => TTDate::getAPIDate('DATE', strtotime($iso_date_stamp)), 'start_date_stamp' => defined('TIMETREX_API') ? TTDate::getAPIDate('DATE', $start_time) : $start_time, 'start_date' => defined('TIMETREX_API') ? TTDate::getAPIDate('DATE+TIME', $start_time) : $start_time, 'end_date' => defined('TIMETREX_API') ? TTDate::getAPIDate('DATE+TIME', $end_time) : $end_time, 'start_time' => defined('TIMETREX_API') ? TTDate::getAPIDate('TIME', $start_time) : $start_time, 'end_time' => defined('TIMETREX_API') ? TTDate::getAPIDate('TIME', $end_time) : $end_time, 'start_time_stamp' => $start_time, 'end_time_stamp' => $end_time, 'total_time' => $this->getTotalTime(), 'hourly_rate' => $hourly_rate, 'total_time_wage' => $total_time_wage, 'note' => FALSE, 'schedule_policy_id' => $this->getSchedulePolicyID(), 'absence_policy_id' => $absence_policy_id, 'absence_policy' => $absence_policy, 'branch_id' => $this->getColumn('schedule_branch_id'), 'branch' => $this->getColumn('schedule_branch'), 'department_id' => $this->getColumn('schedule_department_id'), 'department' => $this->getColumn('schedule_department'), 'created_by_id' => $this->getColumn('recurring_schedule_control_created_by'), 'created_date' => $this->getCreatedDate(), 'updated_date' => $this->getUpdatedDate());
                     //Make sure we add in permission columns.
                     $this->getPermissionColumns($shifts[$iso_date_stamp][$n], (int) $this->getColumn('user_id'), $this->getColumn('recurring_schedule_control_created_by'), $permission_children_ids);
                     //$shifts_index[$iso_date_stamp][$this->getColumn('user_id')][] = $this->getColumn('user_id').$start_time;
                     $shifts_index[$iso_date_stamp][$this->getColumn('user_id')][] = $n;
                     $n++;
                 }
                 unset($open_shift_multiplier);
                 unset($start_time, $end_time);
             } else {
                 //Debug::text('&nbsp;&nbsp;NOT active shift on this day... ID: '. $this->getColumn('id') .' User ID: '. $this->getColumn('user_id') .' Start Time: '. TTDate::getDate('DATE+TIME', $i),__FILE__, __LINE__, __METHOD__, 10);
             }
         }
     }
     if (isset($shifts)) {
         //Debug::Arr($shifts, 'Template Shifts: ',__FILE__, __LINE__, __METHOD__, 10);
         return $shifts;
     }
     return FALSE;
 }
Esempio n. 20
0
 function getWage($seconds, $rate)
 {
     if ($seconds == '' or empty($seconds)) {
         return 0;
     }
     if ($rate == '' or empty($rate)) {
         return 0;
     }
     return bcmul(TTDate::getHours($seconds), $rate);
 }
Esempio n. 21
0
 function getScheduleArray($filter_data, $permission_children_ids = NULL)
 {
     global $current_user, $current_user_prefs;
     //Get all schedule data by general filter criteria.
     //Debug::Arr($filter_data, 'Filter Data: ', __FILE__, __LINE__, __METHOD__, 10);
     if (!isset($filter_data['start_date']) or $filter_data['start_date'] == '') {
         return FALSE;
     }
     if (!isset($filter_data['end_date']) or $filter_data['end_date'] == '') {
         return FALSE;
     }
     $filter_data['start_date'] = TTDate::getBeginDayEpoch($filter_data['start_date']);
     $filter_data['end_date'] = TTDate::getEndDayEpoch($filter_data['end_date']);
     $schedule_shifts_index = array();
     $branch_options = array();
     //No longer needed, use SQL instead.
     $department_options = array();
     //No longer needed, use SQL instead.
     $apf = TTnew('AbsencePolicyFactory');
     $absence_policy_paid_type_options = $apf->getOptions('paid_type');
     $max_i = 0;
     $slf = TTnew('ScheduleListFactory');
     $slf->getSearchByCompanyIdAndArrayCriteria($current_user->getCompany(), $filter_data);
     Debug::text('Found Scheduled Rows: ' . $slf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     //Debug::Arr($absence_policy_paid_type_options, 'Paid Absences: ', __FILE__, __LINE__, __METHOD__, 10);
     if ($slf->getRecordCount() > 0) {
         $this->getProgressBarObject()->start($this->getAMFMessageID(), $slf->getRecordCount(), NULL, TTi18n::getText('Processing Committed Shifts...'));
         $i = 0;
         foreach ($slf as $s_obj) {
             //Debug::text('Schedule ID: '. $s_obj->getId() .' User ID: '. $s_obj->getColumn('user_id') .' Start Time: '. $s_obj->getStartTime(), __FILE__, __LINE__, __METHOD__, 10);
             if ($s_obj->getAbsencePolicyID() > 0) {
                 $absence_policy_name = $s_obj->getColumn('absence_policy');
             } else {
                 $absence_policy_name = NULL;
                 //Must be NULL for it to appear as "N/A" in legacy interface.
             }
             $hourly_rate = Misc::MoneyFormat($s_obj->getColumn('user_wage_hourly_rate'), FALSE);
             if ($s_obj->getAbsencePolicyID() > 0 and is_object($s_obj->getAbsencePolicyObject()) and in_array($s_obj->getAbsencePolicyObject()->getType(), $absence_policy_paid_type_options) == FALSE) {
                 //UnPaid Absence.
                 $total_time_wage = Misc::MoneyFormat(0);
             } else {
                 $total_time_wage = Misc::MoneyFormat(bcmul(TTDate::getHours($s_obj->getColumn('total_time')), $hourly_rate), FALSE);
             }
             //$iso_date_stamp = TTDate::getISODateStamp($s_obj->getStartTime());
             $iso_date_stamp = TTDate::getISODateStamp(strtotime($s_obj->getColumn('date_stamp')));
             //$schedule_shifts[$iso_date_stamp][$s_obj->getColumn('user_id').$s_obj->getStartTime()] = array(
             $schedule_shifts[$iso_date_stamp][$i] = array('id' => (int) $s_obj->getID(), 'pay_period_id' => (int) $s_obj->getColumn('pay_period_id'), 'user_id' => (int) $s_obj->getColumn('user_id'), 'user_created_by' => (int) $s_obj->getColumn('user_created_by'), 'user_full_name' => $s_obj->getColumn('user_id') > 0 ? Misc::getFullName($s_obj->getColumn('first_name'), NULL, $s_obj->getColumn('last_name'), FALSE, FALSE) : TTi18n::getText('OPEN'), 'first_name' => $s_obj->getColumn('user_id') > 0 ? $s_obj->getColumn('first_name') : TTi18n::getText('OPEN'), 'last_name' => $s_obj->getColumn('last_name'), 'title_id' => $s_obj->getColumn('title_id'), 'title' => $s_obj->getColumn('title'), 'group_id' => $s_obj->getColumn('group_id'), 'group' => $s_obj->getColumn('group'), 'default_branch_id' => $s_obj->getColumn('default_branch_id'), 'default_branch' => $s_obj->getColumn('default_branch'), 'default_department_id' => $s_obj->getColumn('default_department_id'), 'default_department' => $s_obj->getColumn('default_department'), 'job_id' => $s_obj->getColumn('job_id'), 'job' => $s_obj->getColumn('job'), 'job_status_id' => $s_obj->getColumn('job_status_id'), 'job_manual_id' => $s_obj->getColumn('job_manual_id'), 'job_branch_id' => $s_obj->getColumn('job_branch_id'), 'job_department_id' => $s_obj->getColumn('job_department_id'), 'job_group_id' => $s_obj->getColumn('job_group_id'), 'job_item_id' => $s_obj->getColumn('job_item_id'), 'job_item' => $s_obj->getColumn('job_item'), 'type_id' => 10, 'status_id' => (int) $s_obj->getStatus(), 'date_stamp' => TTDate::getAPIDate('DATE', strtotime($s_obj->getColumn('date_stamp'))), 'start_date_stamp' => defined('TIMETREX_API') ? TTDate::getAPIDate('DATE', $s_obj->getStartTime()) : $s_obj->getStartTime(), 'start_date' => defined('TIMETREX_API') ? TTDate::getAPIDate('DATE+TIME', $s_obj->getStartTime()) : $s_obj->getStartTime(), 'end_date' => defined('TIMETREX_API') ? TTDate::getAPIDate('DATE+TIME', $s_obj->getEndTime()) : $s_obj->getEndTime(), 'start_time' => defined('TIMETREX_API') ? TTDate::getAPIDate('TIME', $s_obj->getStartTime()) : $s_obj->getStartTime(), 'end_time' => defined('TIMETREX_API') ? TTDate::getAPIDate('TIME', $s_obj->getEndTime()) : $s_obj->getEndTime(), 'start_time_stamp' => $s_obj->getStartTime(), 'end_time_stamp' => $s_obj->getEndTime(), 'total_time' => $s_obj->getTotalTime(), 'hourly_rate' => $hourly_rate, 'total_time_wage' => $total_time_wage, 'note' => $s_obj->getColumn('note'), 'schedule_policy_id' => (int) $s_obj->getSchedulePolicyID(), 'absence_policy_id' => (int) $s_obj->getAbsencePolicyID(), 'absence_policy' => $absence_policy_name, 'branch_id' => (int) $s_obj->getBranch(), 'branch' => $s_obj->getColumn('branch'), 'department_id' => (int) $s_obj->getDepartment(), 'department' => $s_obj->getColumn('department'), 'created_by_id' => $s_obj->getCreatedBy(), 'created_date' => $s_obj->getCreatedDate(), 'updated_date' => $s_obj->getUpdatedDate());
             //Make sure we add in permission columns.
             $this->getPermissionColumns($schedule_shifts[$iso_date_stamp][$i], (int) $s_obj->getColumn('user_id'), $s_obj->getCreatedBy(), $permission_children_ids);
             //$schedule_shifts_index[$iso_date_stamp][$s_obj->getColumn('user_id')][] = $s_obj->getColumn('user_id').$s_obj->getStartTime();
             $schedule_shifts_index[$iso_date_stamp][$s_obj->getColumn('user_id')][] = $i;
             unset($absence_policy_name);
             $this->getProgressBarObject()->set($this->getAMFMessageID(), $slf->getCurrentRow());
             $i++;
         }
         $max_i = $i;
         unset($i);
         $this->getProgressBarObject()->stop($this->getAMFMessageID());
         //Debug::Arr($schedule_shifts, 'Committed Schedule Shifts: ', __FILE__, __LINE__, __METHOD__, 10);
         //Debug::Arr($schedule_shifts_index, 'Committed Schedule Shifts Index: ', __FILE__, __LINE__, __METHOD__, 10);
     } else {
         $schedule_shifts = array();
     }
     unset($slf);
     //Get holidays
     //FIXME: What if there are two holiday policies, one that defaults to working, and another that defaults to not working, and they are assigned
     //to two different groups of employees? For that matter what if the holiday policy isn't assigned to a specific user at all.
     $holiday_data = array();
     $hlf = TTnew('HolidayListFactory');
     $hlf->getByCompanyIdAndStartDateAndEndDate($current_user->getCompany(), $filter_data['start_date'], $filter_data['end_date']);
     Debug::text('Found Holiday Rows: ' . $hlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     foreach ($hlf as $h_obj) {
         if (is_object($h_obj->getHolidayPolicyObject()) and is_object($h_obj->getHolidayPolicyObject()->getAbsencePolicyObject())) {
             $holiday_data[TTDate::getISODateStamp($h_obj->getDateStamp())] = array('status_id' => (int) $h_obj->getHolidayPolicyObject()->getDefaultScheduleStatus(), 'absence_policy_id' => $h_obj->getHolidayPolicyObject()->getAbsencePolicyID(), 'type_id' => $h_obj->getHolidayPolicyObject()->getAbsencePolicyObject()->getType(), 'absence_policy' => $h_obj->getHolidayPolicyObject()->getAbsencePolicyObject()->getName());
         } else {
             $holiday_data[TTDate::getISODateStamp($h_obj->getDateStamp())] = array('status_id' => 10);
             //Working
         }
     }
     unset($hlf);
     $recurring_schedule_shifts = array();
     $open_shift_conflict_index = array();
     $rstlf = TTnew('RecurringScheduleTemplateListFactory');
     //Order for this is critcal to working with OPEN shifts. OPEN shifts (user_id=0) must come last, so it can find all conflicting shifts that will override it.
     //Also order by start_time so earlier shifts come first and therefore are the first to be overridden.
     $rstlf->getSearchByCompanyIdAndArrayCriteria($current_user->getCompany(), $filter_data, NULL, NULL, NULL, array('c.start_date' => 'asc', 'cb.user_id' => 'desc', 'a.week' => 'asc', 'a.start_time' => 'asc'));
     Debug::text('Found Recurring Schedule Template Rows: ' . $rstlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     if ($rstlf->getRecordCount() > 0) {
         $this->getProgressBarObject()->start($this->getAMFMessageID(), $rstlf->getRecordCount(), NULL, TTi18n::getText('Processing Recurring Shifts...'));
         foreach ($rstlf as $rst_obj) {
             //Debug::text('Recurring Schedule Template ID: '. $rst_obj->getID() , __FILE__, __LINE__, __METHOD__, 10);
             $rst_obj->getShifts($filter_data['start_date'], $filter_data['end_date'], $holiday_data, $branch_options, $department_options, $max_i, $schedule_shifts, $schedule_shifts_index, $open_shift_conflict_index, $permission_children_ids);
             $this->getProgressBarObject()->set($this->getAMFMessageID(), $rstlf->getCurrentRow());
         }
         $this->getProgressBarObject()->stop($this->getAMFMessageID());
     } else {
         Debug::text('DID NOT find Recurring Schedule for this time period: ', __FILE__, __LINE__, __METHOD__, 10);
     }
     unset($rstlf, $rst_obj, $open_shift_conflict_index);
     //Debug::Arr($schedule_shifts, 'Schedule Shifts: ', __FILE__, __LINE__, __METHOD__, 10);
     //Include employees without scheduled shifts.
     if (isset($filter_data['include_all_users']) and $filter_data['include_all_users'] == TRUE) {
         if (!isset($filter_data['exclude_id'])) {
             $filter_data['exclude_id'] = array();
         }
         //If the user is searching for scheduled branch/departments, convert that to default branch/departments when Show All Employees is enabled.
         if (isset($filter_data['branch_ids']) and !isset($filter_data['default_branch_ids'])) {
             $filter_data['default_branch_ids'] = $filter_data['branch_ids'];
         }
         if (isset($filter_data['department_ids']) and !isset($filter_data['default_department_ids'])) {
             $filter_data['default_department_ids'] = $filter_data['department_ids'];
         }
         //Loop through schedule_shifts_index getting user_ids.
         foreach ($schedule_shifts_index as $date_stamp => $date_shifts) {
             $filter_data['exclude_id'] = array_unique(array_merge($filter_data['exclude_id'], array_keys($date_shifts)));
         }
         unset($date_stamp, $date_shifts);
         if (isset($filter_data['exclude_id'])) {
             //Debug::Arr($filter_data['exclude_id'], 'Including all employees. Excluded User Ids: ', __FILE__, __LINE__, __METHOD__, 10);
             //Debug::Arr($filter_data, 'All Filter Data: ', __FILE__, __LINE__, __METHOD__, 10);
             //Only include active employees without any scheduled shifts.
             $filter_data['status_id'] = 10;
             $ulf = TTnew('UserListFactory');
             $ulf->getAPISearchByCompanyIdAndArrayCriteria($current_user->getCompany(), $filter_data);
             Debug::text('Found blank employees: ' . $ulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
             if ($ulf->getRecordCount() > 0) {
                 $this->getProgressBarObject()->start($this->getAMFMessageID(), $ulf->getRecordCount(), NULL, TTi18n::getText('Processing Employees...'));
                 $i = $max_i;
                 foreach ($ulf as $u_obj) {
                     //Create dummy shift arrays with no start/end time.
                     //$schedule_shifts[TTDate::getISODateStamp( $filter_data['start_date'] )][$u_obj->getID().TTDate::getBeginDayEpoch($filter_data['start_date'])] = array(
                     $schedule_shifts[TTDate::getISODateStamp($filter_data['start_date'])][$i] = array('pay_period_id' => FALSE, 'user_id' => (int) $u_obj->getID(), 'user_created_by' => (int) $u_obj->getCreatedBy(), 'user_full_name' => Misc::getFullName($u_obj->getFirstName(), NULL, $u_obj->getLastName(), FALSE, FALSE), 'first_name' => $u_obj->getFirstName(), 'last_name' => $u_obj->getLastName(), 'title_id' => $u_obj->getTitle(), 'title' => $u_obj->getColumn('title'), 'group_id' => $u_obj->getColumn('group_id'), 'group' => $u_obj->getColumn('group'), 'default_branch_id' => $u_obj->getColumn('default_branch_id'), 'default_branch' => $u_obj->getColumn('default_branch'), 'default_department_id' => $u_obj->getColumn('default_department_id'), 'default_department' => $u_obj->getColumn('default_department'), 'branch_id' => (int) $u_obj->getDefaultBranch(), 'branch' => $u_obj->getColumn('default_branch'), 'department_id' => (int) $u_obj->getDefaultDepartment(), 'department' => $u_obj->getColumn('default_department'), 'created_by_id' => $u_obj->getCreatedBy(), 'created_date' => $u_obj->getCreatedDate(), 'updated_date' => $u_obj->getUpdatedDate());
                     //Make sure we add in permission columns.
                     $this->getPermissionColumns($schedule_shifts[TTDate::getISODateStamp($filter_data['start_date'])][$i], (int) $u_obj->getID(), $u_obj->getCreatedBy(), $permission_children_ids);
                     $this->getProgressBarObject()->set($this->getAMFMessageID(), $ulf->getCurrentRow());
                     $i++;
                 }
                 $this->getProgressBarObject()->stop($this->getAMFMessageID());
             }
         }
         //Debug::Arr($schedule_shifts, 'Final Scheduled Shifts: ', __FILE__, __LINE__, __METHOD__, 10);
     }
     unset($schedule_shifts_index);
     if (isset($schedule_shifts)) {
         return $schedule_shifts;
     }
     return FALSE;
 }
Esempio n. 22
0
 function getAverageTime($user_id)
 {
     $udtlf = TTnew('UserDateTotalListFactory');
     //Check if Min and Max time is the same, if so we can skip any averaging.
     if ($this->getHolidayPolicyObject()->getMinimumTime() > 0 and $this->getHolidayPolicyObject()->getMaximumTime() > 0 and $this->getHolidayPolicyObject()->getMinimumTime() == $this->getHolidayPolicyObject()->getMaximumTime()) {
         Debug::text('Min and Max times are equal.', __FILE__, __LINE__, __METHOD__, 10);
         return $this->getHolidayPolicyObject()->getMinimumTime();
     }
     if ($this->getHolidayPolicyObject()->getAverageTimeWorkedDays() == TRUE) {
         Debug::text('Using worked days only...', __FILE__, __LINE__, __METHOD__, 10);
         if ($this->getHolidayPolicyObject()->getIncludeOverTime() == TRUE) {
             $last_days_worked = (array) $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
         } else {
             //Make sure if they aren't including overtime, we don't include days where they only worked overtime.
             $last_days_worked = (array) $udtlf->getDaysWorkedRegularTimeByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
         }
         $paid_absence_before_days = array();
         if ($this->getHolidayPolicyObject()->getIncludePaidAbsenceTime() == TRUE) {
             $paid_absence_before_days = (array) $udtlf->getDaysPaidAbsenceByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
             Debug::text('Employee has paid absence days prior: ' . count($paid_absence_before_days), __FILE__, __LINE__, __METHOD__, 10);
         }
         //Debug::Arr($last_days_worked, 'Last Days Worked: ', __FILE__, __LINE__, __METHOD__,10);
         $last_days_worked_count = count(array_unique(array_merge($last_days_worked, $paid_absence_before_days)));
         unset($last_days_worked, $paid_absence_before_days);
     } else {
         $last_days_worked_count = $this->getHolidayPolicyObject()->getAverageDays();
     }
     Debug::text('Average time over days:' . $last_days_worked_count, __FILE__, __LINE__, __METHOD__, 10);
     if ($this->getHolidayPolicyObject()->getIncludeOverTime() == TRUE) {
         Debug::text('Including OverTime!', __FILE__, __LINE__, __METHOD__, 10);
         $total_seconds_worked = $udtlf->getWorkedTimeSumByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
     } else {
         Debug::text('NOT Including OverTime!', __FILE__, __LINE__, __METHOD__, 10);
         $total_seconds_worked = $udtlf->getRegularTimeSumByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
     }
     if ($this->getHolidayPolicyObject()->getIncludePaidAbsenceTime() == TRUE) {
         //FIXME: How does this affect the number of days worked above?
         Debug::text('Including Paid Absence Time!', __FILE__, __LINE__, __METHOD__, 10);
         $total_seconds_worked += $udtlf->getPaidAbsenceTimeSumByUserIDAndStartDateAndEndDate($user_id, $this->getDateStamp() - $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400, $this->getDateStamp() - 86400);
     } else {
         Debug::text('NOT Including Paid Absence Time!', __FILE__, __LINE__, __METHOD__, 10);
     }
     if ($last_days_worked_count > 0) {
         $avg_seconds_worked_per_day = bcdiv($total_seconds_worked, $last_days_worked_count);
         Debug::text('AVG hours worked per day:' . TTDate::getHours($avg_seconds_worked_per_day), __FILE__, __LINE__, __METHOD__, 10);
     } else {
         $avg_seconds_worked_per_day = 0;
     }
     if ($this->getHolidayPolicyObject()->getMaximumTime() > 0 and $avg_seconds_worked_per_day > $this->getHolidayPolicyObject()->getMaximumTime()) {
         $avg_seconds_worked_per_day = $this->getHolidayPolicyObject()->getMaximumTime();
         Debug::text('AVG hours worked per day exceeds maximum regulars hours per day, setting to:' . $avg_seconds_worked_per_day / 60 / 60, __FILE__, __LINE__, __METHOD__, 10);
     }
     if ($avg_seconds_worked_per_day < $this->getHolidayPolicyObject()->getMinimumTime()) {
         $avg_seconds_worked_per_day = $this->getHolidayPolicyObject()->getMinimumTime();
         Debug::text('AVG hours worked per day is less then minimum regulars hours per day, setting to:' . $avg_seconds_worked_per_day / 60 / 60, __FILE__, __LINE__, __METHOD__, 10);
     }
     //Round to nearest 15mins.
     if ((int) $this->getHolidayPolicyObject()->getRoundIntervalPolicyID() != 0 and is_object($this->getHolidayPolicyObject()->getRoundIntervalPolicyObject())) {
         $avg_seconds_worked_per_day = TTDate::roundTime($avg_seconds_worked_per_day, $this->getHolidayPolicyObject()->getRoundIntervalPolicyObject()->getInterval(), $this->getHolidayPolicyObject()->getRoundIntervalPolicyObject()->getRoundType());
         Debug::text('Rounding Stat Time To: ' . $avg_seconds_worked_per_day, __FILE__, __LINE__, __METHOD__, 10);
     } else {
         Debug::text('NOT Rounding Stat Time!', __FILE__, __LINE__, __METHOD__, 10);
     }
     return $avg_seconds_worked_per_day;
 }
Esempio n. 23
0
     } else {
         $tmp_rows[$user_id][$pay_period_id][$column] = (int) $udt_obj->getColumn('total_time');
     }
     if (isset($tmp_rows[$user_id][$pay_period_id]['actual_time'])) {
         $tmp_rows[$user_id][$pay_period_id]['actual_time'] += (int) $udt_obj->getColumn('actual_total_time');
     } else {
         $tmp_rows[$user_id][$pay_period_id]['actual_time'] = (int) $udt_obj->getColumn('actual_total_time');
     }
     $actual_time_diff = $udt_obj->getColumn('actual_total_time') - $udt_obj->getColumn('total_time');
     if (isset($tmp_rows[$user_id][$pay_period_id]['actual_time_diff'])) {
         $tmp_rows[$user_id][$pay_period_id]['actual_time_diff'] += $actual_time_diff;
     } else {
         $tmp_rows[$user_id][$pay_period_id]['actual_time_diff'] = $actual_time_diff;
     }
     if (isset($user_wage[$user_id])) {
         $tmp_rows[$user_id][$pay_period_id]['actual_time_diff_wage'] = Misc::MoneyFormat(TTDate::getHours($tmp_rows[$user_id][$pay_period_id]['actual_time_diff']) * $user_wage[$user_id], FALSE);
     } else {
         $tmp_rows[$user_id][$pay_period_id]['actual_time_diff_wage'] = Misc::MoneyFormat(0, FALSE);
     }
     unset($actual_time_diff);
 } elseif ($column != NULL) {
     if (isset($tmp_rows[$user_id][$pay_period_id][$column])) {
         $tmp_rows[$user_id][$pay_period_id][$column] += $udt_obj->getColumn('total_time');
     } else {
         $tmp_rows[$user_id][$pay_period_id][$column] = $udt_obj->getColumn('total_time');
     }
 }
 if (isset($schedule_rows[$user_id][$pay_period_id]['working'])) {
     $tmp_rows[$user_id][$pay_period_id]['schedule_working'] = $schedule_rows[$user_id][$pay_period_id]['working'];
 } else {
     $tmp_rows[$user_id][$pay_period_id]['schedule_working'] = NULL;
 function _getData($format = NULL)
 {
     $this->tmp_data = array('punch' => array(), 'user' => array(), 'verified_timesheet' => array());
     $columns = $this->getColumnDataConfig();
     $filter_data = $this->getFilterConfig();
     if ($this->getPermissionObject()->Check('punch', 'view') == FALSE or $this->getPermissionObject()->Check('wage', 'view') == FALSE) {
         $hlf = TTnew('HierarchyListFactory');
         $permission_children_ids = $wage_permission_children_ids = $hlf->getHierarchyChildrenByCompanyIdAndUserIdAndObjectTypeID($this->getUserObject()->getCompany(), $this->getUserObject()->getID());
         //Debug::Arr($permission_children_ids,'Permission Children Ids:', __FILE__, __LINE__, __METHOD__,10);
     } else {
         //Get Permission Hierarchy Children first, as this can be used for viewing, or editing.
         $permission_children_ids = array();
         $wage_permission_children_ids = array();
     }
     if ($this->getPermissionObject()->Check('punch', 'view') == FALSE) {
         if ($this->getPermissionObject()->Check('punch', 'view_child') == FALSE) {
             $permission_children_ids = array();
         }
         if ($this->getPermissionObject()->Check('punch', 'view_own')) {
             $permission_children_ids[] = $this->getUserObject()->getID();
         }
         $filter_data['permission_children_ids'] = $permission_children_ids;
     }
     //Get Wage Permission Hierarchy Children first, as this can be used for viewing, or editing.
     if ($this->getPermissionObject()->Check('wage', 'view') == TRUE) {
         $wage_permission_children_ids = TRUE;
     } elseif ($this->getPermissionObject()->Check('wage', 'view') == FALSE) {
         if ($this->getPermissionObject()->Check('wage', 'view_child') == FALSE) {
             $wage_permission_children_ids = array();
         }
         if ($this->getPermissionObject()->Check('wage', 'view_own')) {
             $wage_permission_children_ids[] = $this->getUserObject()->getID();
         }
     }
     //Debug::Text(' Permission Children: '. count($permission_children_ids) .' Wage Children: '. count($wage_permission_children_ids), __FILE__, __LINE__, __METHOD__,10);
     //Debug::Arr($permission_children_ids, 'Permission Children: '. count($permission_children_ids), __FILE__, __LINE__, __METHOD__,10);
     //Debug::Arr($wage_permission_children_ids, 'Wage Children: '. count($wage_permission_children_ids), __FILE__, __LINE__, __METHOD__,10);
     $slf = TTnew('StationListFactory');
     $station_type_options = $slf->getOptions('type');
     if ($this->getUserObject()->getCompanyObject()->getProductEdition() >= TT_PRODUCT_CORPORATE) {
         $jlf = TTnew('JobListFactory');
         $job_status_options = $jlf->getOptions('status');
     } else {
         $job_status_options = array();
     }
     $pay_period_ids = array();
     $plf = TTnew('PunchListFactory');
     $punch_type_options = $plf->getOptions('type');
     $plf->getPunchSummaryReportByCompanyIdAndArrayCriteria($this->getUserObject()->getCompany(), $filter_data);
     Debug::Text(' Total Rows: ' . $plf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     $this->getProgressBarObject()->start($this->getAMFMessageID(), $plf->getRecordCount(), NULL, TTi18n::getText('Retrieving Data...'));
     if ($plf->getRecordCount() > 0) {
         foreach ($plf as $key => $p_obj) {
             $pay_period_ids[$p_obj->getColumn('pay_period_id')] = TRUE;
             if (!isset($this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')])) {
                 $hourly_rate = 0;
                 if ($wage_permission_children_ids === TRUE or in_array($p_obj->getColumn('user_id'), $wage_permission_children_ids)) {
                     $hourly_rate = $p_obj->getColumn('hourly_rate');
                 }
                 $actual_time_diff = (int) $p_obj->getColumn('actual_total_time') - (int) $p_obj->getColumn('total_time');
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')] = array('user_id' => $p_obj->getColumn('user_id'), 'user_group' => $p_obj->getColumn('group'), 'branch' => $p_obj->getColumn('branch'), 'department' => $p_obj->getColumn('department'), 'job' => $p_obj->getColumn('job'), 'job_status_id' => $p_obj->getColumn('job_status_id'), 'job_status' => Option::getByKey($p_obj->getColumn('job_status_id'), $job_status_options, NULL), 'job_manual_id' => $p_obj->getColumn('job_manual_id'), 'job_description' => $p_obj->getColumn('job_description'), 'job_branch' => $p_obj->getColumn('job_branch'), 'job_department' => $p_obj->getColumn('job_department'), 'job_group' => $p_obj->getColumn('job_group'), 'job_item' => $p_obj->getColumn('job_item'), 'job_other_id1' => $p_obj->getColumn('job_other_id1'), 'job_other_id2' => $p_obj->getColumn('job_other_id2'), 'job_other_id3' => $p_obj->getColumn('job_other_id3'), 'job_other_id4' => $p_obj->getColumn('job_other_id4'), 'job_other_id5' => $p_obj->getColumn('job_other_id5'), 'quantity' => $p_obj->getColumn('quantity'), 'bad_quantity' => $p_obj->getColumn('bad_quantity'), 'note' => $p_obj->getColumn('note'), 'total_time' => $p_obj->getColumn('total_time'), 'total_time_wage' => Misc::MoneyFormat(bcmul(TTDate::getHours($p_obj->getColumn('total_time')), $hourly_rate), FALSE), 'total_time_wage_burden' => Misc::MoneyFormat(bcmul(TTDate::getHours($p_obj->getColumn('total_time')), bcmul($hourly_rate, bcdiv($p_obj->getColumn('labor_burden_percent'), 100))), FALSE), 'total_time_wage_with_burden' => Misc::MoneyFormat(bcmul(TTDate::getHours($p_obj->getColumn('total_time')), bcmul($hourly_rate, bcadd(bcdiv($p_obj->getColumn('labor_burden_percent'), 100), 1))), FALSE), 'actual_total_time' => $p_obj->getColumn('actual_total_time'), 'actual_total_time_diff' => $actual_time_diff, 'actual_total_time_wage' => Misc::MoneyFormat(bcmul(TTDate::getHours($p_obj->getColumn('actual_total_time')), $hourly_rate), FALSE), 'actual_total_time_diff_wage' => Misc::MoneyFormat(bcmul(TTDate::getHours($actual_time_diff), $hourly_rate)), 'other_id1' => $p_obj->getColumn('other_id1'), 'other_id2' => $p_obj->getColumn('other_id2'), 'other_id3' => $p_obj->getColumn('other_id3'), 'other_id4' => $p_obj->getColumn('other_id4'), 'other_id5' => $p_obj->getColumn('other_id5'), 'date_stamp' => TTDate::strtotime($p_obj->getColumn('date_stamp')), 'in_time_stamp' => NULL, 'in_actual_time_stamp' => NULL, 'in_type' => NULL, 'out_time_stamp' => NULL, 'out_actual_time_stamp' => NULL, 'out_type' => NULL, 'user_wage_id' => $p_obj->getColumn('user_wage_id'), 'hourly_rate' => Misc::MoneyFormat($hourly_rate, FALSE), 'tainted' => 0, 'tainted_status' => NULL, 'in_station_type' => NULL, 'in_station_station_id' => NULL, 'in_station_source' => NULL, 'in_station_description' => NULL, 'out_station_type' => NULL, 'out_station_station_id' => NULL, 'out_station_source' => NULL, 'out_station_description' => NULL, 'pay_period_start_date' => strtotime($p_obj->getColumn('pay_period_start_date')), 'pay_period_end_date' => strtotime($p_obj->getColumn('pay_period_end_date')), 'pay_period_transaction_date' => strtotime($p_obj->getColumn('pay_period_transaction_date')), 'pay_period' => strtotime($p_obj->getColumn('pay_period_transaction_date')), 'pay_period_id' => $p_obj->getColumn('pay_period_id'), 'total_punch' => 0, 'total_tainted_punch' => 0);
             }
             if ($p_obj->getColumn('status_id') == 10) {
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_time_stamp'] = TTDate::strtotime($p_obj->getColumn('punch_time_stamp'));
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_type'] = Option::getByKey($p_obj->getColumn('type_id'), $punch_type_options, NULL);
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_actual_time_stamp'] = TTDate::strtotime($p_obj->getColumn('punch_actual_time_stamp'));
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_station_type'] = Option::getByKey($p_obj->getColumn('station_type_id'), $station_type_options, '--');
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_station_station_id'] = $p_obj->getColumn('station_station_id');
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_station_source'] = $p_obj->getColumn('station_source');
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_station_description'] = $p_obj->getColumn('station_description');
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_created_date'] = TTDate::strtotime($p_obj->getColumn('punch_created_date'));
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_created_by'] = Misc::getFullName($p_obj->getColumn('punch_created_by_first_name'), $p_obj->getColumn('punch_created_by_middle_name'), $p_obj->getColumn('punch_created_by_last_name'), FALSE, FALSE);
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_updated_date'] = TTDate::strtotime($p_obj->getColumn('punch_updated_date'));
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['in_updated_by'] = Misc::getFullName($p_obj->getColumn('punch_updated_by_first_name'), $p_obj->getColumn('punch_updated_by_middle_name'), $p_obj->getColumn('punch_updated_by_last_name'), FALSE, FALSE);
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['total_punch']++;
             } else {
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_time_stamp'] = TTDate::strtotime($p_obj->getColumn('punch_time_stamp'));
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_type'] = Option::getByKey($p_obj->getColumn('type_id'), $punch_type_options, NULL);
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_actual_time_stamp'] = TTDate::strtotime($p_obj->getColumn('punch_actual_time_stamp'));
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_station_type'] = Option::getByKey($p_obj->getColumn('station_type_id'), $station_type_options, '--');
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_station_station_id'] = $p_obj->getColumn('station_station_id');
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_station_source'] = $p_obj->getColumn('station_source');
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_station_description'] = $p_obj->getColumn('station_description');
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_created_date'] = TTDate::strtotime($p_obj->getColumn('punch_created_date'));
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_created_by'] = Misc::getFullName($p_obj->getColumn('punch_created_by_first_name'), $p_obj->getColumn('punch_created_by_middle_name'), $p_obj->getColumn('punch_created_by_last_name'), FALSE, FALSE);
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_updated_date'] = TTDate::strtotime($p_obj->getColumn('punch_updated_date'));
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['out_updated_by'] = Misc::getFullName($p_obj->getColumn('punch_updated_by_first_name'), $p_obj->getColumn('punch_updated_by_middle_name'), $p_obj->getColumn('punch_updated_by_last_name'), FALSE, FALSE);
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['total_punch']++;
             }
             if ($p_obj->getTainted() == TRUE) {
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['tainted'] = 1;
                 $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['total_tainted_punch']++;
                 if ($this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['tainted_status'] !== NULL) {
                     $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['tainted_status'] = TTi18n::getText('Both (In&Out)');
                 } else {
                     if ($p_obj->getColumn('status_id') == 10) {
                         $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['tainted_status'] = TTi18n::getText('In');
                     } else {
                         $this->tmp_data['punch'][$p_obj->getColumn('user_id')][$p_obj->getColumn('punch_control_id')]['tainted_status'] = TTi18n::getText('Out');
                     }
                 }
             }
             unset($hourly_rate, $uw_obj, $actual_time_diff);
             $this->getProgressBarObject()->set($this->getAMFMessageID(), $key);
         }
     }
     //Debug::Arr($this->tmp_data['punch'], 'Punch Raw Data: ', __FILE__, __LINE__, __METHOD__,10);
     //Get user data for joining.
     $ulf = TTnew('UserListFactory');
     $ulf->getAPISearchByCompanyIdAndArrayCriteria($this->getUserObject()->getCompany(), $filter_data);
     Debug::Text(' User Total Rows: ' . $ulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
     $this->getProgressBarObject()->start($this->getAMFMessageID(), $ulf->getRecordCount(), NULL, TTi18n::getText('Retrieving Data...'));
     foreach ($ulf as $key => $u_obj) {
         $this->tmp_data['user'][$u_obj->getId()] = (array) $u_obj->getObjectAsArray($this->getColumnDataConfig());
         $this->getProgressBarObject()->set($this->getAMFMessageID(), $key);
     }
     //Debug::Arr($this->tmp_data['user'], 'User Raw Data: ', __FILE__, __LINE__, __METHOD__,10);
     //Get verified timesheets for all pay periods considered in report.
     $pay_period_ids = array_keys($pay_period_ids);
     if (isset($pay_period_ids) and count($pay_period_ids) > 0) {
         $pptsvlf = TTnew('PayPeriodTimeSheetVerifyListFactory');
         $pptsvlf->getByPayPeriodIdAndCompanyId($pay_period_ids, $this->getUserObject()->getCompany());
         if ($pptsvlf->getRecordCount() > 0) {
             foreach ($pptsvlf as $pptsv_obj) {
                 $this->tmp_data['verified_timesheet'][$pptsv_obj->getUser()][$pptsv_obj->getPayPeriod()] = array('status' => $pptsv_obj->getVerificationStatusShortDisplay(), 'created_date' => $pptsv_obj->getCreatedDate());
             }
         }
     }
     return TRUE;
 }