<?php
/*********************************************************************************
 * The contents of this file are subject to the TimeTrex Public License Version
 * 1.1.0 ("License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at http://www.TimeTrex.com/TPL
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * All copies of the Covered Code must include on each user interface screen:
 *    (i) the "Powered by TimeTrex" logo and
 *    (ii) the TimeTrex copyright notice
 * in the same form as they appear in the distribution.  See full license for
 * requirements.
 *
 * The Original Code is: TimeTrex Open Source
 * The Initial Developer of the Original Code is TimeTrex Payroll Services
 * Portions created by TimeTrex are Copyright (C) 2004-2007 TimeTrex Payroll Services;
 * All Rights Reserved.
 *
 ********************************************************************************/
/*
 * $Revision: 2237 $
 * $Id: Form940.php 2237 2008-11-11 18:18:20Z ipso $
 * $Date: 2008-11-11 10:18:20 -0800 (Tue, 11 Nov 2008) $
 */
require_once('../../includes/global.inc.php');
require_once(Environment::getBasePath() .'includes/Interface.inc.php');
require(Environment::getBasePath() .'/classes/fpdi/fpdi.php');

if ( !$permission->Check('report','enabled')
		OR !$permission->Check('report','view_form940') ) {
	$permission->Redirect( FALSE ); //Redirect
}

$smarty->assign('title', TTi18n::gettext($title = 'Form 940 Report')); // See index.php

/*
 * Get FORM variables
 */
extract	(FormVariables::GetVariables(
										array	(
												'action',
												'setup_data',
												'generic_data',
												'filter_data'
												) ) );

URLBuilder::setURL($_SERVER['SCRIPT_NAME'],
											array(
													'filter_data' => $filter_data
//													'sort_column' => $sort_column,
//													'sort_order' => $sort_order,
												) );

$pseallf = new PayStubEntryAccountLinkListFactory();
$pseallf->getByCompanyId( $current_company->getId() );
if ( $pseallf->getRecordCount() > 0 ) {
	$pseal_obj = $pseallf->getCurrent();
}

$column_ps_entry_name_map = array(
								'p2_3' => @$setup_data['total_payment_psea_ids'],
								'p2_4' => @$setup_data['exempt_payment_psea_ids'],
								);

$pplf = new PayPeriodListFactory();
$year_options = $pplf->getYearsArrayByCompanyId( $current_company->getId() );

$quarter_dates = array(
						1 => array( 'start' => mktime(0,0,0,1,1, $filter_data['year'] ),'end' => mktime(0,0,-1,4,1, $filter_data['year'] ) ),
						2 => array( 'start' => mktime(0,0,0,4,1, $filter_data['year'] ),'end' => mktime(0,0,-1,7,1, $filter_data['year'] ) ),
						3 => array( 'start' => mktime(0,0,0,7,1, $filter_data['year'] ),'end' => mktime(0,0,-1,10,1, $filter_data['year'] ) ),
						4 => array( 'start' => mktime(0,0,0,10,1, $filter_data['year'] ),'end' => mktime(0,0,-1,13,1, $filter_data['year'] ) ),
						);

//Get a unique list of states each employee belongs to
$ulf = new UserListFactory();
$ulf->getByCompanyId( $current_company->getId() );
if ( $ulf->getRecordCount() > 0 ) {
	foreach( $ulf as $u_obj ) {
		$state_options[$u_obj->getProvince()] = $u_obj->getProvince();
	}
}

$filter_data = Misc::preSetArrayValues( $filter_data, array('include_user_ids', 'exclude_user_ids', 'user_status_ids', 'group_ids', 'branch_ids', 'department_ids', 'user_title_ids', 'pay_period_ids', 'column_ids' ), array() );


$ugdlf = new UserGenericDataListFactory();
$ugdf = new UserGenericDataFactory();

$action = Misc::findSubmitButton();
Debug::Text('Action: '. $action, __FILE__, __LINE__, __METHOD__,10);
switch ($action) {
	case 'display_form':
	case 'print_form':
	case 'display_report':
		//Debug::setVerbosity(11);
		if ( $action == 'print_form' ) {
			$show_background = FALSE;
		} else {
			$show_background = TRUE;
		}

		Debug::Text('Submit!: '. $action, __FILE__, __LINE__, __METHOD__,10);
		Debug::Arr($filter_data, 'aFilter Data', __FILE__, __LINE__, __METHOD__,10);

		//Save report setup data
		$ugdlf->getByCompanyIdAndScriptAndDefault( $current_company->getId(), $_SERVER['SCRIPT_NAME'] );
		if ( $ugdlf->getRecordCount() > 0 ) {
			$ugdf->setID( $ugdlf->getCurrent()->getID() );
		}
		$ugdf->setCompany( $current_company->getId() );
		$ugdf->setName( $title );
		$ugdf->setScript( $_SERVER['SCRIPT_NAME'] );
		$ugdf->setData( $setup_data );
		$ugdf->setDefault( TRUE );
		if ( $ugdf->isValid() ) {
			$ugdf->Save();
		}

		$ulf = new UserListFactory();
		$ulf->getSearchByCompanyIdAndArrayCriteria( $current_company->getId(), $filter_data );

		if ( $ulf->getRecordCount() > 0 ) {
			foreach( $ulf as $u_obj ) {
				$filter_data['user_ids'][] = $u_obj->getId();
			}

			if ( isset($filter_data['user_ids']) AND isset($filter_data['year']) ) {
				$pseallf = new PayStubEntryAccountLinkListFactory();
				$pseallf->getByCompanyId( $current_company->getId() );
				if ( $pseallf->getRecordCount() > 0 ) {
					$pseal_obj = $pseallf->getCurrent();
				}

				//
				//Get all data for the form.
				//
				foreach( $quarter_dates as $quarter_id => $quarter_dates_arr ) {
					//Get Pay Periods in date range.
					Debug::Text('Start Date: '. TTDate::getDate('DATE+TIME', $quarter_dates_arr['start']) .' End Date: '. TTDate::getDate('DATE+TIME', $quarter_dates_arr['end']), __FILE__, __LINE__, __METHOD__,10);

					$pplf = new PayPeriodListFactory();
					$pplf->getByCompanyIdAndTransactionStartDateAndTransactionEndDate( $current_company->getId(), $quarter_dates_arr['start'], $quarter_dates_arr['end'] );
					if ( $pplf->getRecordCount() > 0 ) {
						foreach($pplf as $pp_obj) {
							$pay_period_ids[] = $pp_obj->getID();
						}
					}

					if ( isset($pay_period_ids) ) {
						$payments_over_cutoff = 4000;

						//PS Account Amounts...
						//Get employees who have recieved pay stubs.
						$pself = new PayStubEntryListFactory();
						$pself->getReportByCompanyIdAndUserIdAndPayPeriodId( $current_company->getId(), $filter_data['user_ids'], $pay_period_ids );
						Debug::Text('Record Count: '. $pself->getRecordCount(), __FILE__, __LINE__, __METHOD__,10);
						if ( $pself->getRecordCount() > 0 ) {
							foreach( $pself as $pse_obj ) {
								$user_id = $pse_obj->getColumn('user_id');
								//$pay_stub_entry_name_id = $pse_obj->getColumn('pay_stub_entry_name_id');
								$pay_stub_entry_name_id = $pse_obj->getPayStubEntryNameId();

								if ( isset($ps_entries[$pay_stub_entry_name_id]) ) {
									$ps_entries[$pay_stub_entry_name_id] = bcadd($ps_entries[$pay_stub_entry_name_id],$pse_obj->getColumn('amount'),2 );
								} else {
									$ps_entries[$pay_stub_entry_name_id] = $pse_obj->getColumn('amount');
								}

								if ( isset($user_quarter_ps_entries[$user_id][$pay_stub_entry_name_id]) ) {
									$user_quarter_ps_entries[$quarter_id][$user_id][$pay_stub_entry_name_id] = bcadd($user_quarter_ps_entries[$quarter_id][$user_id][$pay_stub_entry_name_id],$pse_obj->getColumn('amount'),2 );
								} else {
									$user_quarter_ps_entries[$quarter_id][$user_id][$pay_stub_entry_name_id] = $pse_obj->getColumn('amount');
								}

								if ( isset($user_total_ps_entries[$user_id][$pay_stub_entry_name_id]) ) {
									$user_total_ps_entries[$user_id][$pay_stub_entry_name_id] = bcadd($user_total_ps_entries[$user_id][$pay_stub_entry_name_id],$pse_obj->getColumn('amount'),2 );
								} else {
									$user_total_ps_entries[$user_id][$pay_stub_entry_name_id] = $pse_obj->getColumn('amount');
								}
							}

							$lines_arr[$quarter_id]['p2_3'] = Misc::sumMultipleColumns( $ps_entries, $column_ps_entry_name_map['p2_3']);
							$lines_arr[$quarter_id]['p2_4'] = Misc::sumMultipleColumns( $ps_entries, $column_ps_entry_name_map['p2_4']);
							$lines_arr[$quarter_id]['p2_5'] = 0;

							//Get over cutoff amounts for each user.
							$i=0;
							foreach( $user_quarter_ps_entries[$quarter_id] as $user_id => $user_quarter_ps_entry_arr ) {
								$user_quarter_lines_arr[$user_id]['p2_3'] = Misc::sumMultipleColumns( $user_quarter_ps_entry_arr, $column_ps_entry_name_map['p2_3']);
								$user_quarter_lines_arr[$user_id]['p2_4'] = Misc::sumMultipleColumns( $user_quarter_ps_entry_arr, $column_ps_entry_name_map['p2_4']);
								$tmp_quarter_user_payment = ($user_quarter_lines_arr[$user_id]['p2_3'] - $user_quarter_lines_arr[$user_id]['p2_4']);

								if ( !isset($user_total_lines_arr[$user_id]['p2_3']) ) {
									$user_total_lines_arr[$user_id]['p2_3'] = 0;
								}
								if ( !isset($user_total_lines_arr[$user_id]['p2_4']) ) {
									$user_total_lines_arr[$user_id]['p2_4'] = 0;
								}
								if ( !isset($user_total_lines_arr[$user_id]['p2_5']) ) {
									$user_total_lines_arr[$user_id]['p2_5'] = 0;
								}
								if ( !isset($user_total_lines_arr[$user_id]['total_payment']) ) {
									$user_total_lines_arr[$user_id]['total_payment'] = 0;
								}

								$user_total_lines_arr[$user_id]['p2_3'] += $user_quarter_lines_arr[$user_id]['p2_3'];
								$user_total_lines_arr[$user_id]['p2_4'] += $user_quarter_lines_arr[$user_id]['p2_4'];
								$user_total_lines_arr[$user_id]['total_payment'] += $tmp_quarter_user_payment;

								//If we the user exceeds the cutoff, simply minus the cutoff
								if ( $user_total_lines_arr[$user_id]['total_payment'] > $payments_over_cutoff ) {
									Debug::Text('User ID: '. $user_id .' Over Cutoff...', __FILE__, __LINE__, __METHOD__,10);

									if ( $user_total_lines_arr[$user_id]['p2_5'] == 0 ) {
										$user_total_lines_arr[$user_id]['p2_5'] = $user_total_lines_arr[$user_id]['total_payment'] - $payments_over_cutoff;
										$lines_arr[$quarter_id]['p2_5'] += $user_total_lines_arr[$user_id]['p2_5'];
										Debug::Text('User ID: '. $user_id .' Over Cutoff First Time, by: '. $user_total_lines_arr[$user_id]['p2_5'] , __FILE__, __LINE__, __METHOD__,10);
									} else {
										$user_total_lines_arr[$user_id]['p2_5'] += $tmp_quarter_user_payment;
										$lines_arr[$quarter_id]['p2_5'] += $tmp_quarter_user_payment;
										Debug::Text('User ID: '. $user_id .' Over Cutoff Other Time... Current: '. $tmp_quarter_user_payment .' Total: '. $user_total_lines_arr[$user_id]['p2_5'], __FILE__, __LINE__, __METHOD__,10);

									}
								}
								Debug::Text('User ID: '. $user_id .' Quarter Payment: '. $tmp_quarter_user_payment .' Total Payment: '. $user_total_lines_arr[$user_id]['total_payment'], __FILE__, __LINE__, __METHOD__,10);

								$i++;
							}

							$lines_arr[$quarter_id]['p2_6'] = $lines_arr[$quarter_id]['p2_4'] + $lines_arr[$quarter_id]['p2_5'];
							$lines_arr[$quarter_id]['p2_7'] = $lines_arr[$quarter_id]['p2_3'] - $lines_arr[$quarter_id]['p2_6'];
							$lines_arr[$quarter_id]['p2_8'] = $lines_arr[$quarter_id]['p2_7'] * 0.008;
							$lines_arr[$quarter_id]['p3_9'] = $lines_arr[$quarter_id]['p2_7'] * 0.054;
							$lines_arr[$quarter_id]['p4_12'] = $lines_arr[$quarter_id]['p2_8'] + $lines_arr[$quarter_id]['p3_9'];
						}
						unset($user_id);
						//var_dump($user_ps_entries);

					}
					unset($pay_period_ids, $ps_entries);
				}

				//Calc Annual Total.
				if ( isset($lines_arr) ) {
					$lines_arr['total'] = Misc::ArrayAssocSum($lines_arr, NULL, 6);
					Debug::Arr($lines_arr, 'Lines Array: ', __FILE__, __LINE__, __METHOD__,10);
				}

				if  ( isset($lines_arr['total']['p4_12']) ) {
					//P4 - Line14
					$lines_arr['total']['p4_14'] = $lines_arr['total']['p4_12'];
				}

				$border = 0;

				$adjust_x = 0;
				$adjust_y = 0;

				$pdf = new fpdi();

				if ( $show_background == TRUE ) {
					//Import original Gov't supplied PDF.
					$pagecount = $pdf->setSourceFile(Environment::getBasePath().'interface'. DIRECTORY_SEPARATOR .'forms'. DIRECTORY_SEPARATOR .'us'. DIRECTORY_SEPARATOR .'tax'. DIRECTORY_SEPARATOR .'f940.pdf');
					$tplidx[1] = $pdf->ImportPage(1);
					$tplidx[2] = $pdf->ImportPage(2);
					$tplidx[3] = $pdf->ImportPage(3);
					$tplidx[4] = $pdf->ImportPage(4);
				}

				$pdf->setMargins(0,0,0,0);
				$pdf->SetAutoPageBreak(FALSE);
				$pdf->SetFont('freeserif','', 10);

				$pdf->AddPage();
				if ( isset($tplidx) ) {
					$pdf->useTemplate($tplidx[1],0,0);
				}

				//Form year
				if ( $show_background == TRUE ) {
					//Form number and year
					$pdf->SetFont('freeserif','B', 18);
					$pdf->setFillColor( 255,255,255 );
					$pdf->setXY( Misc::AdjustXY(19, $adjust_x), Misc::AdjustXY(10, $adjust_y) );
					$pdf->Cell(35,10,'940 for '. $filter_data['year'], $border, 0, 'C', 1);

					//Year in type of return
					$pdf->SetFont('freeserif','', 9);
					$pdf->setFillColor( 245,245,245 ); //Gray background.
					$pdf->setXY( Misc::AdjustXY(162, $adjust_x), Misc::AdjustXY(54, $adjust_y) );
					$pdf->Cell(7,3,$filter_data['year'], $border, 0, 'C', 1);

					//Form revision at bottom right of 1st page
					$pdf->SetFont('freeserif','', 7);
					$pdf->setFillColor( 255,255,255 );
					$pdf->setXY( Misc::AdjustXY(195, $adjust_x), Misc::AdjustXY(265, $adjust_y) );
					$pdf->Cell(9, 4, '('. $filter_data['year'] .')', $border, 0, 'C', 1);

					//Form year in black bars
					$pdf->SetFont('freeserif','B', 10);
					$pdf->setTextColor( 255,255,255 );
					$pdf->setFillColor( 0,0,0 );
					$pdf->setXY( Misc::AdjustXY(103, $adjust_x), Misc::AdjustXY(106.8, $adjust_y) );
					$pdf->Cell(9, 3.5, $filter_data['year'], $border, 0, 'C', 1);
					$pdf->setXY( Misc::AdjustXY(124, $adjust_x), Misc::AdjustXY(204.5, $adjust_y) );
					$pdf->Cell(9, 3.5, $filter_data['year'], $border, 0, 'C', 1);
					$pdf->setTextColor( 0,0,0 );

					$pdf->SetFont('freeserif','', 10);
					$pdf->setFillColor( 245,245,245 );
					$pdf->setXY( Misc::AdjustXY(80, $adjust_x), Misc::AdjustXY(237.72, $adjust_y) );
					$pdf->Cell(8, 3.5, $filter_data['year'], $border, 0, 'C', 1);

					$pdf->setFillColor( 255,255,255 );
					$pdf->SetFont('freeserif','', 10);
				}

				//EIN
				$ein = str_replace(array('-', ' '), '', $current_company->getBusinessNumber() );
				if ( isset($ein) AND strlen($ein) > 5 ) {
					$pdf->setXY( Misc::AdjustXY(54, $adjust_x), Misc::AdjustXY(24, $adjust_y) );
					$pdf->Cell(7,7,$ein[0], $border, 0, 'C');

					$pdf->setXY( Misc::AdjustXY(63, $adjust_x), Misc::AdjustXY(24, $adjust_y) );
					$pdf->Cell(7,7,$ein[1], $border, 0, 'C');

					$pdf->setXY( Misc::AdjustXY(77, $adjust_x), Misc::AdjustXY(24, $adjust_y) );
					$pdf->Cell(7,7,$ein[2], $border, 0, 'C');

					$pdf->setXY( Misc::AdjustXY(85, $adjust_x), Misc::AdjustXY(24, $adjust_y) );
					$pdf->Cell(7,7,$ein[3], $border, 0, 'C');

					$pdf->setXY( Misc::AdjustXY(94, $adjust_x), Misc::AdjustXY(24, $adjust_y) );
					$pdf->Cell(7,7,$ein[4], $border, 0, 'C');

					$pdf->setXY( Misc::AdjustXY(103, $adjust_x), Misc::AdjustXY(24, $adjust_y) );
					$pdf->Cell(7,7,$ein[5], $border, 0, 'C');

					$pdf->setXY( Misc::AdjustXY(112, $adjust_x), Misc::AdjustXY(24, $adjust_y) );
					$pdf->Cell(7,7,$ein[6], $border, 0, 'C');

					$pdf->setXY( Misc::AdjustXY(121, $adjust_x), Misc::AdjustXY(24, $adjust_y) );
					$pdf->Cell(7,7,$ein[7], $border, 0, 'C');

					$pdf->setXY( Misc::AdjustXY(130, $adjust_x), Misc::AdjustXY(24, $adjust_y) );
					$pdf->Cell(7,7,$ein[8], $border, 0, 'C');
				}

				//Name
				if ( $setup_data['name'] != '' ) {
					$pdf->setXY( Misc::AdjustXY(49, $adjust_x), Misc::AdjustXY(33, $adjust_y) );
					$pdf->Cell(90,6,$setup_data['name'], $border, 0, 'L');
				}

				//Trade name
				$pdf->setXY( Misc::AdjustXY(41, $adjust_x), Misc::AdjustXY(42, $adjust_y) );
				$pdf->Cell(90,6,$current_company->getName(), $border, 0, 'L');

				$pdf->setXY( Misc::AdjustXY(28, $adjust_x), Misc::AdjustXY(50, $adjust_y) );
				$pdf->Cell(100,6,$current_company->getAddress1() .' '. $current_company->getAddress2(), $border, 0, 'L');

				$pdf->setXY( Misc::AdjustXY(28, $adjust_x), Misc::AdjustXY(59, $adjust_y) );
				$pdf->Cell(65,6,$current_company->getCity(), $border, 0, 'L');

				$pdf->setXY( Misc::AdjustXY(96, $adjust_x), Misc::AdjustXY(59, $adjust_y) );
				$pdf->Cell(12,6,$current_company->getProvince(), $border, 0, 'C');

				$pdf->setXY( Misc::AdjustXY(111, $adjust_x), Misc::AdjustXY(59, $adjust_y) );
				$pdf->Cell(23,6,$current_company->getPostalCode(), $border, 0, 'C');

				if ( isset($setup_data['return_type']) AND is_array($setup_data['return_type']) ) {
					foreach( $setup_data['return_type'] as $return_type ) {
						switch ( $return_type ) {
							case 10: //Amended
								$pdf->setXY( Misc::AdjustXY(149, $adjust_x), Misc::AdjustXY(36, $adjust_y) );
								$pdf->Cell(5,5,'X', $border, 0, 'C');
								break;
							case 20: //Successor
								$pdf->setXY( Misc::AdjustXY(149, $adjust_x), Misc::AdjustXY(43, $adjust_y) );
								$pdf->Cell(5,5,'X', $border, 0, 'C');
								break;
							case 30: //No Payments
								$pdf->setXY( Misc::AdjustXY(149, $adjust_x), Misc::AdjustXY(49, $adjust_y) );
								$pdf->Cell(5,5,'X', $border, 0, 'C');
								break;
							case 40: //Final
								$pdf->setXY( Misc::AdjustXY(149, $adjust_x), Misc::AdjustXY(55, $adjust_y) );
								$pdf->Cell(5,5,'X', $border, 0, 'C');
								break;
						}
					}
				}

				//Multi-state company
				if ( count($state_options) > 1 ) {
					//2006 form doesn't support this yet.
				} else {
					$state = trim( array_shift($state_options) );

					if ( strlen($state) == 2 ) {
						//Line 1a
						$pdf->setXY( Misc::AdjustXY(111, $adjust_x), Misc::AdjustXY(83, $adjust_y) );
						$pdf->Cell(5,5,$state[0], $border, 0, 'C');
						$pdf->setXY( Misc::AdjustXY(121, $adjust_x), Misc::AdjustXY(83, $adjust_y) );
						$pdf->Cell(5,5,$state[1], $border, 0, 'C');
					}
				}

				//Exempt payment check boxes
				if ( isset($setup_data['exempt_payment']) AND is_array($setup_data['exempt_payment']) ) {
					foreach( $setup_data['exempt_payment'] as $return_type ) {
						switch ( $return_type ) {
							case 10: //Fringe
								$pdf->setXY( Misc::AdjustXY(55, $adjust_x), Misc::AdjustXY(130, $adjust_y) );
								$pdf->Cell(5,5,'X', $border, 0, 'C');
								break;
							case 20: //Group life insurance
								$pdf->setXY( Misc::AdjustXY(55, $adjust_x), Misc::AdjustXY(134, $adjust_y) );
								$pdf->Cell(5,5,'X', $border, 0, 'C');
								break;
							case 30: //Retirement/Pension
								$pdf->setXY( Misc::AdjustXY(101, $adjust_x), Misc::AdjustXY(130, $adjust_y) );
								$pdf->Cell(5,5,'X', $border, 0, 'C');
								break;
							case 40: //Dependant care
								$pdf->setXY( Misc::AdjustXY(101, $adjust_x), Misc::AdjustXY(134, $adjust_y) );
								$pdf->Cell(5,5,'X', $border, 0, 'C');
								break;
							case 50: //Other
								$pdf->setXY( Misc::AdjustXY(139, $adjust_x), Misc::AdjustXY(130, $adjust_y) );
								$pdf->Cell(5,5,'X', $border, 0, 'C');
								break;
						}
					}
				}

				if ( isset($lines_arr) ) {
					//
					// Part 2
					//

					//Line 3
					$pdf->setXY( Misc::AdjustXY(159, $adjust_x), Misc::AdjustXY(114, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_3'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_3'], FALSE) ), $border, 0, 'R');

					//Line 4
					$pdf->setXY( Misc::AdjustXY(108, $adjust_x), Misc::AdjustXY(123, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_4'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_4'], FALSE) ), $border, 0, 'R');

					//Line 5
					$pdf->setXY( Misc::AdjustXY(108, $adjust_x), Misc::AdjustXY(142, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_5'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_5'], FALSE) ), $border, 0, 'R');

					//Line 6
					$pdf->setXY( Misc::AdjustXY(159, $adjust_x), Misc::AdjustXY(150, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_6'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_6'], FALSE) ), $border, 0, 'R');

					//Line 7
					$pdf->setXY( Misc::AdjustXY(159, $adjust_x), Misc::AdjustXY(158, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_7'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_7'], FALSE) ), $border, 0, 'R');

					//Line 8
					$pdf->setXY( Misc::AdjustXY(159, $adjust_x), Misc::AdjustXY(166, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_8'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p2_8'], FALSE) ), $border, 0, 'R');

					//
					//Part 3
					//

					//Line 9
					$pdf->setXY( Misc::AdjustXY(159, $adjust_x), Misc::AdjustXY(179, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p3_9'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p3_9'], FALSE) ), $border, 0, 'R');

					//
					//Part 4
					//

					//Line 12
					$pdf->setXY( Misc::AdjustXY(159, $adjust_x), Misc::AdjustXY(212, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p4_12'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p4_12'], FALSE) ), $border, 0, 'R');

					//Line 14
					$pdf->setXY( Misc::AdjustXY(159, $adjust_x), Misc::AdjustXY(235, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p4_12'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p4_12'], FALSE) ), $border, 0, 'R');

					$pdf->AddPage();
					if ( isset($tplidx) ) {
						$pdf->useTemplate($tplidx[2],0,0);
					}

					//Form year
					if ( $show_background == TRUE ) {
						//Form revision at bottom right of 2nd page
						$pdf->SetFont('freeserif','', 7);
						$pdf->setFillColor( 255,255,255 );
						$pdf->setXY( Misc::AdjustXY(195, $adjust_x), Misc::AdjustXY(246, $adjust_y) );
						$pdf->Cell(9, 4, '('. $filter_data['year'] .')', $border, 0, 'C', 1);

						$pdf->SetFont('freeserif','', 10);
					}

					//Company
					$pdf->setXY(Misc::AdjustXY(14, $adjust_x), Misc::AdjustXY(23, $adjust_y));
					$pdf->Cell(90,6,$current_company->getName(), $border, 0, 'L');

					//EIN
					$pdf->setXY(Misc::AdjustXY(141, $adjust_x), Misc::AdjustXY(23, $adjust_y));
					$pdf->Cell(50,6,$current_company->getBusinessNumber(), $border, 0, 'L');

					//
					//Part 5
					//

					if ( $lines_arr['total']['p4_12'] > 500 ) {
						//Line 16a
						if ( isset($lines_arr[1]['p4_12']) AND $lines_arr[1]['p4_12'] > 0 ) {
							$pdf->setXY( Misc::AdjustXY(121, $adjust_x), Misc::AdjustXY(46, $adjust_y) );
							$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr[1]['p4_12'], FALSE) ), $border, 0, 'R');
							$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr[1]['p4_12'], FALSE) ), $border, 0, 'R');
						}

						//Line 16b
						if ( isset($lines_arr[2]['p4_12']) AND $lines_arr[2]['p4_12'] > 0 ) {
							$pdf->setXY( Misc::AdjustXY(121, $adjust_x), Misc::AdjustXY(55, $adjust_y) );
							$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr[2]['p4_12'], FALSE) ), $border, 0, 'R');
							$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr[2]['p4_12'], FALSE) ), $border, 0, 'R');
						}

						//Line 16c
						if ( isset($lines_arr[3]['p4_12']) AND $lines_arr[3]['p4_12'] > 0 ) {
							$pdf->setXY( Misc::AdjustXY(121, $adjust_x), Misc::AdjustXY(63, $adjust_y) );
							$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr[3]['p4_12'], FALSE) ), $border, 0, 'R');
							$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr[3]['p4_12'], FALSE) ), $border, 0, 'R');
						}

						//Line 16c
						if ( isset($lines_arr[4]['p4_12']) AND $lines_arr[4]['p4_12'] > 0 ) {
							$pdf->setXY( Misc::AdjustXY(121, $adjust_x), Misc::AdjustXY(72, $adjust_y) );
							$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr[4]['p4_12'], FALSE) ), $border, 0, 'R');
							$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr[4]['p4_12'], FALSE) ), $border, 0, 'R');
						}

						//Line 17
						$pdf->setXY( Misc::AdjustXY(121, $adjust_x), Misc::AdjustXY(80, $adjust_y) );
						$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p4_12'], FALSE) ), $border, 0, 'R');
						$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p4_12'], FALSE) ), $border, 0, 'R');
					}

					//Add Vochure page.
					$pdf->AddPage();
					if ( isset($tplidx) ) {
						$pdf->useTemplate($tplidx[3],0,0);
					}

					//Form year
					if ( $show_background == TRUE ) {
						$pdf->SetFont('freeserif','B', 24);
						$pdf->setFillColor( 255,255,255 );
						$pdf->setXY( Misc::AdjustXY(185, $adjust_x), Misc::AdjustXY(209, $adjust_y) );
						$pdf->Cell(10,7, substr( $filter_data['year'], 2, 2) , $border, 0, 'C', 1);

						//Form year in instructions
						$pdf->SetFont('freeserif','', 10);
						$pdf->setXY( Misc::AdjustXY(89, $adjust_x), Misc::AdjustXY(51.8, $adjust_y) );
						$pdf->Cell(8, 4, $filter_data['year'], $border, 0, 'C', 1);
						$pdf->setXY( Misc::AdjustXY(120, $adjust_x), Misc::AdjustXY(69, $adjust_y) );
						$pdf->Cell(9, 4, $filter_data['year'].'.', $border, 0, 'C', 1);
						$pdf->setXY( Misc::AdjustXY(131, $adjust_x), Misc::AdjustXY(84.8, $adjust_y) );
						$pdf->Cell(9, 4, $filter_data['year'], $border, 0, 'C', 1);
						$pdf->setXY( Misc::AdjustXY(185, $adjust_x), Misc::AdjustXY(88.5, $adjust_y) );
						$pdf->Cell(9, 4, $filter_data['year'], $border, 0, 'C', 1);

						$pdf->SetFont('freeserif','', 10);
					}

					$ein = str_replace(array('-', ' '), '', $current_company->getBusinessNumber() );
					if ( isset($ein) AND strlen($ein) > 5 ) {
						$pdf->setXY( Misc::AdjustXY(20, $adjust_x), Misc::AdjustXY(224, $adjust_y) );
						$pdf->Cell(10,7,$ein[0].$ein[1], $border, 0, 'C');

						$pdf->setXY( Misc::AdjustXY(33, $adjust_x), Misc::AdjustXY(224, $adjust_y) );
						$pdf->Cell(25,7,$ein[2].$ein[3].$ein[4].$ein[5].$ein[6].$ein[7].$ein[8], $border, 0, 'L');
					}

					$pdf->setXY( Misc::AdjustXY(153, $adjust_x), Misc::AdjustXY(224, $adjust_y) );
					$pdf->Cell(35,6, Misc::getBeforeDecimal( Misc::MoneyFormat( $lines_arr['total']['p4_12'], FALSE) ), $border, 0, 'R');
					$pdf->Cell(8,6, Misc::getAfterDecimal( Misc::MoneyFormat( $lines_arr['total']['p4_12'], FALSE) ), $border, 0, 'R');

					//Trade name
					$pdf->setXY( Misc::AdjustXY(80, $adjust_x), Misc::AdjustXY(233, $adjust_y) );
					$pdf->Cell(90,6,$current_company->getName(), $border, 0, 'L');

					$pdf->setXY( Misc::AdjustXY(80, $adjust_x), Misc::AdjustXY(241, $adjust_y) );
					$pdf->Cell(100,6,$current_company->getAddress1() .' '. $current_company->getAddress2(), $border, 0, 'L');

					$pdf->setXY( Misc::AdjustXY(80, $adjust_x), Misc::AdjustXY(250, $adjust_y) );
					$pdf->Cell(100,6,$current_company->getCity().', '.$current_company->getProvince().' '.$current_company->getPostalCode() , $border, 0, 'L');
				}

				//Finish off PDF
				$output = $pdf->Output('','S');

				if ( Debug::getVerbosity() == 11 ) {
					Debug::Display();
				} else {
					Misc::FileDownloadHeader('f940.pdf', 'application/pdf', strlen($output));
					echo $output;
				}
				exit;
			}
		}
		break;
	case 'delete':
	case 'save':
		Debug::Text('Action: '. $action, __FILE__, __LINE__, __METHOD__,10);

		$generic_data['id'] = UserGenericDataFactory::reportFormDataHandler( $action, $filter_data, $generic_data, URLBuilder::getURL(NULL, $_SERVER['SCRIPT_NAME']) );
		unset($generic_data['name']);
	default:
		BreadCrumb::setCrumb($title);

		$ugdlf->getByCompanyIdAndScriptAndDefault( $current_company->getId(), $_SERVER['SCRIPT_NAME'] );
		if ( $ugdlf->getRecordCount() > 0 ) {
			Debug::Text('Found Company Report Setup!', __FILE__, __LINE__, __METHOD__,10);
			$ugd_obj = $ugdlf->getCurrent();
			$setup_data = $ugd_obj->getData();
		}
		unset($ugd_obj);

		if ( $action == 'load' ) {
			Debug::Text('Loading Report!', __FILE__, __LINE__, __METHOD__,10);
			extract( UserGenericDataFactory::getReportFormData( $generic_data['id'] ) );
		} elseif ( $action == '' ) {
			//Check for default saved report first.
			$ugdlf->getByUserIdAndScriptAndDefault( $current_user->getId(), $_SERVER['SCRIPT_NAME'] );
			if ( $ugdlf->getRecordCount() > 0 ) {
				Debug::Text('Found Default Report!', __FILE__, __LINE__, __METHOD__,10);

				$ugd_obj = $ugdlf->getCurrent();
				$filter_data = $ugd_obj->getData();
				$generic_data['id'] = $ugd_obj->getId();
			} else {
				Debug::Text('Default Settings!', __FILE__, __LINE__, __METHOD__,10);
				//Default selections
				$filter_data['user_status_ids'] = array( -1 );
				$filter_data['branch_ids'] = array( -1 );
				$filter_data['department_ids'] = array( -1 );
				$filter_data['user_title_ids'] = array( -1 );
				$filter_data['group_ids'] = array( -1 );
			}
		}
		$filter_data = Misc::preSetArrayValues( $filter_data, array('include_user_ids', 'exclude_user_ids', 'user_status_ids', 'group_ids', 'branch_ids', 'department_ids', 'user_title_ids', 'pay_period_ids', 'column_ids' ), NULL );

		$ulf = new UserListFactory();
		$all_array_option = array('-1' => TTi18n::gettext('-- All --'));

		//Get include employee list.
		$ulf->getByCompanyId( $current_company->getId() );
		$user_options = $ulf->getArrayByListFactory( $ulf, FALSE, TRUE );

		$filter_data['src_include_user_options'] = Misc::arrayDiffByKey( (array)$filter_data['include_user_ids'], $user_options );
		$filter_data['selected_include_user_options'] = Misc::arrayIntersectByKey( (array)$filter_data['include_user_ids'], $user_options );

		//Get exclude employee list
		$exclude_user_options = Misc::prependArray( $all_array_option, $ulf->getArrayByListFactory( $ulf, FALSE, TRUE ) );
		$filter_data['src_exclude_user_options'] = Misc::arrayDiffByKey( (array)$filter_data['exclude_user_ids'], $user_options );
		$filter_data['selected_exclude_user_options'] = Misc::arrayIntersectByKey( (array)$filter_data['exclude_user_ids'], $user_options );

		//Get employee status list.
		$user_status_options = Misc::prependArray( $all_array_option, $ulf->getOptions('status') );
		$filter_data['src_user_status_options'] = Misc::arrayDiffByKey( (array)$filter_data['user_status_ids'], $user_status_options );
		$filter_data['selected_user_status_options'] = Misc::arrayIntersectByKey( (array)$filter_data['user_status_ids'], $user_status_options );

		//Get Employee Groups
		$uglf = new UserGroupListFactory();
		$group_options = Misc::prependArray( $all_array_option, $uglf->getArrayByNodes( FastTree::FormatArray( $uglf->getByCompanyIdArray( $current_company->getId() ), 'TEXT', TRUE) ) );
		$filter_data['src_group_options'] = Misc::arrayDiffByKey( (array)$filter_data['group_ids'], $group_options );
		$filter_data['selected_group_options'] = Misc::arrayIntersectByKey( (array)$filter_data['group_ids'], $group_options );

		//Get branches
		$blf = new BranchListFactory();
		$blf->getByCompanyId( $current_company->getId() );
		$branch_options = Misc::prependArray( $all_array_option, $blf->getArrayByListFactory( $blf, FALSE, TRUE ) );
		$filter_data['src_branch_options'] = Misc::arrayDiffByKey( (array)$filter_data['branch_ids'], $branch_options );
		$filter_data['selected_branch_options'] = Misc::arrayIntersectByKey( (array)$filter_data['branch_ids'], $branch_options );

		//Get departments
		$dlf = new DepartmentListFactory();
		$dlf->getByCompanyId( $current_company->getId() );
		$department_options = Misc::prependArray( $all_array_option, $dlf->getArrayByListFactory( $dlf, FALSE, TRUE ) );
		$filter_data['src_department_options'] = Misc::arrayDiffByKey( (array)$filter_data['department_ids'], $department_options );
		$filter_data['selected_department_options'] = Misc::arrayIntersectByKey( (array)$filter_data['department_ids'], $department_options );

		//Get employee titles
		$utlf = new UserTitleListFactory();
		$utlf->getByCompanyId( $current_company->getId() );
		$user_title_options = Misc::prependArray( $all_array_option, $utlf->getArrayByListFactory( $utlf, FALSE, TRUE ) );
		$filter_data['src_user_title_options'] = Misc::arrayDiffByKey( (array)$filter_data['user_title_ids'], $user_title_options );
		$filter_data['selected_user_title_options'] = Misc::arrayIntersectByKey( (array)$filter_data['user_title_ids'], $user_title_options );

		//Deduction PSEA accounts
		$psealf = new PayStubEntryAccountListFactory();
		$filter_data['deduction_pay_stub_entry_account_options'] = $psealf->getByCompanyIdAndStatusIdAndTypeIdArray( $current_company->getId(), 10, array(20,30,40), TRUE );
		$filter_data['earning_pay_stub_entry_account_options'] = $psealf->getByCompanyIdAndStatusIdAndTypeIdArray( $current_company->getId(), 10, array(10,40), TRUE );
		$filter_data['income_pay_stub_entry_account_options'] = $psealf->getByCompanyIdAndStatusIdAndTypeIdArray( $current_company->getId(), 10, array(10,30,40), TRUE );

		$filter_data['return_type_options'] = array(
											10 => TTi18n::getText('Amended'),
											20 => TTi18n::getText('Successor Employer'),
											30 => TTi18n::getText('No Payments to Employees'),
											40 => TTi18n::getText('Final: Business closed or stopped paying wages'),
										);

		$filter_data['exempt_payment_options'] = array(
											10 => TTi18n::getText('4a. Fringe benefits'),
											20 => TTi18n::getText('4b. Group term life insurance'),
											30 => TTi18n::getText('4c. Retirement/Pension'),
											40 => TTi18n::getText('4d. Dependant care'),
											50 => TTi18n::getText('4e. Other'),
										);

		$filter_data['state_options'] = $state_options;

		//Get employee list
		//$filter_data['user_options'] = UserListFactory::getByCompanyIdArray( $current_company->getId(), FALSE );

		//Quarters
		$filter_data['year_options'] = $year_options;

		$saved_report_options = $ugdlf->getByUserIdAndScriptArray( $current_user->getId(), $_SERVER['SCRIPT_NAME']);
		$generic_data['saved_report_options'] = $saved_report_options;
		$smarty->assign_by_ref('generic_data', $generic_data);

		$smarty->assign_by_ref('filter_data', $filter_data);
		$smarty->assign_by_ref('setup_data', $setup_data);

		$smarty->assign_by_ref('ugdf', $ugdf);

		$smarty->display('report/Form940.tpl');

		break;
}
?>