<?php
/*********************************************************************************
 * TimeTrex is a Payroll and Time Management program developed by
 * TimeTrex Payroll Services Copyright (C) 2003 - 2010 TimeTrex Payroll Services.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY TIMETREX, TIMETREX DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License along
 * with this program; if not, see http://www.gnu.org/licenses or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 *
 * You can contact TimeTrex headquarters at Unit 22 - 2475 Dobbin Rd. Suite
 * #292 Westbank, BC V4T 2E9, Canada or at email address info@timetrex.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by TimeTrex" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by TimeTrex".
 ********************************************************************************/
/*
 * $Revision: 1564 $
 * $Id: TimesheetSummary.php 1564 2007-12-26 20:00:13Z ipso $
 * $Date: 2007-12-26 12:00:13 -0800 (Wed, 26 Dec 2007) $
 */
require_once('../../includes/global.inc.php');
require_once(Environment::getBasePath() .'includes/Interface.inc.php');

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

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


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

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

$static_columns = array();

$columns = array(					'-0010-regular_time' => TTi18n::gettext('Regular Time'),
									);

$columns = Misc::prependArray( $static_columns, $columns);

//Get all Overtime policies.
$otplf = new OverTimePolicyListFactory();
$otplf->getByCompanyId($current_company->getId());
if ( $otplf->getRecordCount() > 0 ) {
	foreach ($otplf as $otp_obj ) {
		$otp_columns['-0020-over_time_policy-'.$otp_obj->getId()] = $otp_obj->getName();
	}

	$columns = array_merge( $columns, $otp_columns);
}

//Get all Premium policies.
$pplf = new PremiumPolicyListFactory();
$pplf->getByCompanyId($current_company->getId());
if ( $pplf->getRecordCount() > 0 ) {
	foreach ($pplf as $pp_obj ) {
		$pp_columns['-0030-premium_policy-'.$pp_obj->getId()] = $pp_obj->getName();
	}

	$columns = array_merge( $columns, $pp_columns);
}


//Get all Absence Policies.
$aplf = new AbsencePolicyListFactory();
$aplf->getByCompanyId($current_company->getId());
if ( $aplf->getRecordCount() > 0 ) {
	foreach ($aplf as $ap_obj ) {
		$ap_columns['-0040-absence_policy-'.$ap_obj->getId()] = $ap_obj->getName();
	}

	$columns = array_merge( $columns, $ap_columns);
}


$default_start_date = TTDate::getBeginMonthEpoch();
$default_end_date = TTDate::getEndMonthEpoch();

//Get all pay periods
$pplf = new PayPeriodListFactory();
$pplf->getByCompanyId( $current_company->getId() );
if ( $pplf->getRecordCount() > 0 ) {
	$pp=0;
	foreach ($pplf as $pay_period_obj) {
		$pay_period_ids[] = $pay_period_obj->getId();
		$pay_period_end_dates[$pay_period_obj->getId()] = $pay_period_obj->getEndDate();

		if ( $pp == 0 ) {
			$default_start_date = $pay_period_obj->getStartDate();
			$default_end_date = $pay_period_obj->getEndDate();
		}
		$pp++;
	}

	$pplf = new PayPeriodListFactory();
	$pay_period_options = $pplf->getByIdListArray($pay_period_ids, NULL, array('start_date' => 'desc'));
} else {
	$pay_period_options = array();
}

if ( isset($filter_data['start_date']) ) {
	$filter_data['start_date'] = TTDate::parseDateTime($filter_data['start_date']);
}

if ( isset($filter_data['end_date']) ) {
	$filter_data['end_date'] = TTDate::parseDateTime($filter_data['end_date']);
}

$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());

//Get Permission Hierarchy Children first, as this can be used for viewing, or editing.
$permission_children_ids = array();
if ( $permission->Check('punch','view') == FALSE ) {
	$hlf = new HierarchyListFactory();
	$permission_children_ids = $hlf->getHierarchyChildrenByCompanyIdAndUserIdAndObjectTypeID( $current_company->getId(), $current_user->getId() );
	Debug::Arr($permission_children_ids,'Permission Children Ids:', __FILE__, __LINE__, __METHOD__,10);

	if ( $permission->Check('punch','view_child') == FALSE ) {
		$permission_children_ids = array();
	}
	if ( $permission->Check('punch','view_own') ) {
		$permission_children_ids[] = $current_user->getId();
	}

	$filter_data['permission_children_ids'] = $permission_children_ids;
}

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

$action = Misc::findSubmitButton();
switch ($action) {
	case 'export':
		//Debug::setVerbosity(11);
		Debug::Text('Submit!', __FILE__, __LINE__, __METHOD__,10);
		Debug::Arr($filter_data, 'Filter Data', __FILE__, __LINE__, __METHOD__,10);
		Debug::Arr($setup_data, 'Setup 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->setScript( $_SERVER['SCRIPT_NAME'] );
		$ugdf->setName( $title );
		$ugdf->setData( $setup_data );
		$ugdf->setDefault( TRUE );
		if ( $ugdf->isValid() ) {
			$ugdf->Save();
		}

/*
	protected $status_options = array(
										10 => 'System',
										20 => 'Worked',
										30 => 'Absence'
									);

	protected $type_options = array(
										10 => 'Total',
										20 => 'Regular',
										30 => 'Overtime'
									);
*/

		$ulf = new UserListFactory();
		$ulf->getSearchByCompanyIdAndArrayCriteria( $current_company->getId(), $filter_data );
		if ( $ulf->getRecordCount() > 0 ) {
			if ( isset($filter_data['date_type']) AND $filter_data['date_type'] == 'pay_period_ids' ) {
				unset($filter_data['start_date']);
				unset($filter_data['end_date']);
			} else {
				unset($filter_data['pay_period_ids']);
			}

			foreach( $ulf as $u_obj ) {
				$filter_data['user_id'][] = $u_obj->getId();
			}

			if ( isset($filter_data['pay_period_ids']) ) {
				//Trim sort prefix from selected pay periods.
				$tmp_filter_pay_period_ids = $filter_data['pay_period_ids'];
				$filter_data['pay_period_ids'] = array();
				foreach( $tmp_filter_pay_period_ids as $key => $filter_pay_period_id) {
					$filter_data['pay_period_ids'][] = Misc::trimSortPrefix($filter_pay_period_id);
				}
				unset($key, $tmp_filter_pay_period_ids, $filter_pay_period_id);
			}

			//Get greatest end date of the selected ones.
			if ( isset($filter_data['pay_period_ids']) AND count($filter_data['pay_period_ids']) > 0 ) {
				if ( in_array('-1', $filter_data['pay_period_ids']) ) {
					$end_date = time();
				} else {
					$i=0;
					foreach ( $filter_data['pay_period_ids'] as $tmp_pay_period_id ) {
						$tmp_pay_period_id = Misc::trimSortPrefix($tmp_pay_period_id);
						if ( $i == 0 ) {
							$end_date = $pay_period_end_dates[$tmp_pay_period_id];
						} else {
							if ( $pay_period_end_dates[$tmp_pay_period_id] > $end_date ) {
								$end_date = $pay_period_end_dates[$tmp_pay_period_id];
							}
						}

						$i++;
					}
					unset($tmp_pay_period_id, $i);
				}
			} else {
				$end_date = $filter_data['end_date'];
			}
/*
			$uwlf = new UserWageListFactory();
			$uwlf->getLastWageByUserIdAndDate( $filter_data['user_id'], $end_date );
			if ( $uwlf->getRecordCount() > 0 ) {
				foreach($uwlf as $uw_obj) {
					$user_wage[$uw_obj->getUser()] = $uw_obj->getBaseCurrencyHourlyRate( $uw_obj->getHourlyRate() );
				}
			}
			unset($end_date);
			//var_dump($user_wage);
*/

			$udtlf = new UserDateTotalListFactory();
			$udtlf->getReportByCompanyIdAndArrayCriteria( $current_company->getId(), $filter_data );
			foreach ($udtlf as $udt_obj ) {
				$user_id = $udt_obj->getColumn('id');
				$pay_period_id = $udt_obj->getColumn('pay_period_id');

				$status_id = $udt_obj->getColumn('status_id');
				$type_id = $udt_obj->getColumn('type_id');

				if ( $status_id == 10 AND $type_id == 10 ) {
					$column = 'paid_time';
				} elseif ($status_id == 10 AND $type_id == 20) {
					$column = 'regular_time';
				} elseif ($status_id == 10 AND $type_id == 30) {
					$column = 'over_time_policy-'. $udt_obj->getColumn('over_time_policy_id');
				} elseif ($status_id == 10 AND $type_id == 40) {
					$column = 'premium_policy-'. $udt_obj->getColumn('premium_policy_id');
				} elseif ($status_id == 30 AND $type_id == 10) {
					$column = 'absence_policy-'. $udt_obj->getColumn('absence_policy_id');
				} elseif ( ($status_id == 20 AND $type_id == 10 ) OR ($status_id == 10 AND $type_id == 100 ) ) {
					$column = 'worked_time';
				} else {
					$column = NULL;
				}

				//Debug::Text('Column: '. $column .' Status ID: '. $status_id .' Type ID: '. $type_id , __FILE__, __LINE__, __METHOD__,10);

				if ( $column != NULL ) {
					if ( isset($tmp_rows[$user_id][$pay_period_id][$column]) ) {
						$tmp_rows[$user_id][$pay_period_id][$column] += (int)$udt_obj->getColumn('total_time');
					} else {
						$tmp_rows[$user_id][$pay_period_id][$column] = (int)$udt_obj->getColumn('total_time');
					}
				}
			}
			//print_r($tmp_rows);

			$ulf = new UserListFactory();

			$utlf = new UserTitleListFactory();
			$title_options = $utlf->getByCompanyIdArray( $current_company->getId() );

			$uglf = new UserGroupListFactory();
			$group_options = $uglf->getArrayByNodes( FastTree::FormatArray( $uglf->getByCompanyIdArray( $current_company->getId() ), 'no_tree_text', TRUE) );

			$blf = new BranchListFactory();
			$branch_options = $blf->getByCompanyIdArray( $current_company->getId() );

			$dlf = new DepartmentListFactory();
			$department_options = $dlf->getByCompanyIdArray( $current_company->getId() );

			if ( isset($tmp_rows) ) {
				$x=0;
				foreach($tmp_rows as $user_id => $data_a ) {
					$user_obj = $ulf->getById( $user_id )->getCurrent();

					foreach($data_a as $pay_period_id => $data_b ) {
						$rows[$x]['user_id'] = $user_obj->getId();
						$rows[$x]['first_name'] = $user_obj->getFirstName();
						$rows[$x]['middle_name'] = $user_obj->getMiddleName();
						$rows[$x]['last_name'] = $user_obj->getLastName();
						$rows[$x]['full_name'] = $user_obj->getFullName(TRUE);
						$rows[$x]['employee_number'] = $user_obj->getEmployeeNumber();
						$rows[$x]['status'] = Option::getByKey( $user_obj->getStatus(), $user_obj->getOptions('status') );

						$rows[$x]['province'] = $user_obj->getProvince();
						$rows[$x]['country'] = $user_obj->getCountry();

						$rows[$x]['pay_period_id'] = $pay_period_id;
						$rows[$x]['pay_period_order'] = Option::getByKey($pay_period_id, $pay_period_end_dates, NULL );
						$rows[$x]['pay_period_end_date'] = Option::getByKey($pay_period_id, $pay_period_end_dates, NULL );
						$rows[$x]['pay_period'] = Option::getByKey($pay_period_id, $pay_period_options, NULL );

						$rows[$x]['title'] = Option::getByKey($user_obj->getTitle(), $title_options, NULL );
						$rows[$x]['group'] = Option::getByKey($user_obj->getGroup(), $group_options, NULL );
						$rows[$x]['default_branch'] =  Option::getByKey($user_obj->getDefaultBranch(), $branch_options, NULL );
						$rows[$x]['default_department'] = Option::getByKey($user_obj->getDefaultDepartment(), $department_options, NULL );

						foreach($data_b as $column => $total_time) {
							$rows[$x][$column] = (int)$total_time;
						}

						$x++;
					}
				}
			}
			//var_dump($rows);
			unset($tmp_rows);

			$file_name = 'payroll_export.csv';
			if ( isset($rows) ) {
				switch ( $filter_data['export_type'] ) {
					case 'adp': //ADP export format.
						$file_name = 'EPI'. $setup_data['adp']['company_code'] . $setup_data['adp']['batch_id'] .'.csv';

						$export_column_map = array();
						$static_export_column_map = array(
												'company_code' => 'Co Code',
												'batch_id' => 'Batch ID',
												'employee_number' =>  'File #',
												);

						$static_export_data_map = array(
										'company_code' => $setup_data['adp']['company_code'],
										'batch_id' => $setup_data['adp']['batch_id'],
										);

						//
						//Format allows for multiple duplicate columns.
						//ie: Hours 3 Code, Hours 3 Amount, Hours 3 Code, Hours 3 Amount, ...
						//However, we can only have a SINGLE O/T Hours column.
						//We also need to combine hours with the same code together.
						//
						ksort($setup_data['adp']['columns']);
						$setup_data['adp']['columns'] = Misc::trimSortPrefix( $setup_data['adp']['columns'] );

						foreach( $setup_data['adp']['columns'] as $column_id => $column_data ) {
							$column_name = NULL;
							if ( $column_data['hour_column'] == 'regular_time' ) {
								$column_name = 'Reg Hours';
								$export_data_map[$column_id] = trim($setup_data['adp']['columns'][$column_id]['hour_code']);
							} elseif ($column_data['hour_column'] == 'overtime' ) {
								$column_name = 'O/T Hours';
								$export_data_map[$column_id] = trim($setup_data['adp']['columns'][$column_id]['hour_code']);
							} elseif ( $column_data['hour_column'] >= 3 ) {
								$column_name = 'Hours '. $column_data['hour_column'] .' Amount';
								$export_column_map[$setup_data['adp']['columns'][$column_id]['hour_code'].'_code'] = 'Hours '. $column_data['hour_column'] .' Code';
								$export_data_map[$column_id] = trim($setup_data['adp']['columns'][$column_id]['hour_code']);
							}

							if ( $column_name != '' ) {
								$export_column_map[trim($setup_data['adp']['columns'][$column_id]['hour_code'])] = $column_name;
							}
						}
						$export_column_map = Misc::prependArray( $static_export_column_map, $export_column_map);

						//
						//Combine time from all columns with the same hours code.
						//
						$i=0;
						foreach($rows as $row) {
							foreach ( $static_export_column_map as $column_id => $column_name ) {
								if ( isset($static_export_data_map[$column_id]) ) {
									//Copy over static config values like company code/batch_id.
									$tmp_rows[$i][$column_id] = $static_export_data_map[$column_id];
								} elseif( isset($row[$column_id]) ) {
									if ( isset($static_export_column_map[$column_id]) ) {
										//Copy over employee_number. (File #)
										$tmp_rows[$i][$column_id] = $row[$column_id];
									}
								}
							}

							foreach ( $export_data_map as $column_id => $column_name ) {
								if ( !isset($tmp_rows[$i][$column_name]) ) {
									$tmp_rows[$i][$column_name] = 0;
								}

								if ( isset($row[$column_id]) ) {
									$tmp_rows[$i][$column_name] += $row[$column_id];
								}
								$tmp_rows[$i][$column_name.'_code']  = $column_name;
							}

							$i++;
						}

						//Convert time from seconds to hours.
						$convert_unit_columns = array_keys($static_export_column_map);

						foreach( $tmp_rows as $row => $data ) {
							foreach( $data as $column_id => $column_data ) {
								//var_dump($column_id,$column_data);
								if ( is_int($column_data) AND !in_array( $column_id, $convert_unit_columns ) ) {
									$tmp_rows[$row][$column_id] = TTDate::getTimeUnit( $column_data, 20 );
								}
							}
						}
						unset($row, $data, $column_id, $column_data);

						$data = Misc::Array2CSV( $tmp_rows, $export_column_map, FALSE );

						break;
					case 'paychex_preview': //Paychex Preview export format.
						//Add an advanced PayChex Previous format that supports rates perhaps?
						$file_name = $setup_data['paychex_preview']['client_number'] .'_TA.txt';

						ksort($setup_data['paychex_preview']['columns']);
						$setup_data['paychex_preview']['columns'] = Misc::trimSortPrefix( $setup_data['paychex_preview']['columns'] );

						$data = NULL;
						foreach($rows as $row) {
							foreach( $setup_data['paychex_preview']['columns'] as $column_id => $column_data ) {
								if ( isset( $row[$column_id] ) AND trim($column_data['hour_code']) != '' ) {
									$data .= str_pad($row['employee_number'], 6, ' ', STR_PAD_LEFT);
									$data .= str_pad('E'. str_pad( $column_data['hour_code'], 2, 0, STR_PAD_LEFT) , 47, ' ', STR_PAD_LEFT);
									$data .= str_pad( str_pad( TTDate::getTimeUnit( $row[$column_id], 20 ), 8, 0, STR_PAD_LEFT) , 17, ' ', STR_PAD_LEFT)."\n";
								}
							}
						}

						break;
					case 'ceridian_insync': //Ceridian InSync export format.
						$data = NULL;

						ksort($setup_data['ceridian_insync']['columns']);
						$setup_data['ceridian_insync']['columns'] = Misc::trimSortPrefix( $setup_data['ceridian_insync']['columns'] );

						$export_column_map = array(	'employee_number' => '', 'import_type_id' => '', 'employee_number_b' => '', 'check_type' => '',
													'hour_code' => '', 'value' => '', 'distribution' => '', 'rate' => '', 'premium' => '', 'day' => '', 'pay_period' => '');
						foreach($rows as $row) {
							foreach( $setup_data['ceridian_insync']['columns'] as $column_id => $column_data ) {
								if ( isset( $row[$column_id] ) AND trim($column_data['hour_code']) != '' ) {
									$tmp_rows[] = array(
														'employee_number' => $row['employee_number'],
														'import_type_id' => 'COSTING',
														'employee_number_b' => str_pad( $row['employee_number'], 9, '0', STR_PAD_LEFT),
														'check_type' => 'REG',
														'hour_code' => trim($column_data['hour_code']),
														'value' => TTDate::getTimeUnit( $row[$column_id], 20 ),
														'distribution' => NULL,
														'rate' => NULL,
														'premium' => NULL,
														'day' => NULL,
														'pay_period' => NULL,
														);
								}
							}
						}

						if ( isset( $tmp_rows) ) {
							$data = Misc::Array2CSV( $tmp_rows, $export_column_map, FALSE, FALSE );
						}
						unset($tmp_rows, $export_column_map, $column_id, $column_data, $rows, $row);

						break;
					case 'millenium': //Millenium export format.
						$data = NULL;

						ksort($setup_data['millenium']['columns']);
						$setup_data['millenium']['columns'] = Misc::trimSortPrefix( $setup_data['millenium']['columns'] );

						$export_column_map = array('employee_number' => '', 'transaction_code' => '', 'hour_code' => '', 'hours' => '');
						foreach($rows as $row) {
							foreach( $setup_data['millenium']['columns'] as $column_id => $column_data ) {
								if ( isset( $row[$column_id] ) AND trim($column_data['hour_code']) != '' ) {
									$tmp_rows[] = array(
														'employee_number' => $row['employee_number'],
														'transaction_code' => 'E',
														'hour_code' => trim($column_data['hour_code']),
														'hours' => TTDate::getTimeUnit( $row[$column_id], 20 )
														);
								}
							}
						}

						if ( isset( $tmp_rows) ) {
							$data = Misc::Array2CSV( $tmp_rows, $export_column_map, FALSE, FALSE );
						}
						unset($tmp_rows, $export_column_map, $column_id, $column_data, $rows, $row);

						break;
					case 'csv': //Generic CSV
						$data = NULL;

						ksort($setup_data['csv']['columns']);
						$setup_data['csv']['columns'] = Misc::trimSortPrefix( $setup_data['csv']['columns'] );

						$export_column_map = array('employee' => '', 'employee_number' => '', 'default_branch' => '', 'default_department' => '', 'pay_period' => '', 'hour_code' => '', 'hours' => '');

						$i=0;
						foreach($rows as $row) {
							if ( $i == 0 ) {
								//Include header.
								$tmp_rows[] = array(
													'employee' => 'Employee',
													'employee_number' => 'Employee Number',
													'default_branch' => 'Default Branch',
													'default_department' => 'Default Department',
													'pay_period' => 'Pay Period',
													'hour_code' => 'Hours Code',
													'hours' => 'Hours',
													);
							}

							//Combine all hours from the same code together.
							foreach( $setup_data['csv']['columns'] as $column_id => $column_data ) {
								$hour_code = trim($column_data['hour_code']);
								if ( isset( $row[$column_id] ) AND $hour_code != '' ) {
									if ( !isset($tmp_hour_codes[$hour_code]) ) {
										$tmp_hour_codes[$hour_code] = 0;
									}
									$tmp_hour_codes[$hour_code] = bcadd( $tmp_hour_codes[$column_data['hour_code']], $row[$column_id] ); //Use seconds for math here.
								}
							}

							if ( isset($tmp_hour_codes) ) {
								foreach($tmp_hour_codes as $hour_code => $hours ) {
									$tmp_rows[] = array(
														'employee' => $row['full_name'],
														'employee_number' => $row['employee_number'],
														'default_branch' => $row['default_branch'],
														'default_department' => $row['default_department'],
														'pay_period' => $row['pay_period'],
														'hour_code' => $hour_code,
														'hours' => TTDate::getTimeUnit($hours, 20 ),
														);
								}
								unset($tmp_hour_codes, $hour_code, $hours);
							}

							$i++;
						}

						if ( isset( $tmp_rows) ) {
							$data = Misc::Array2CSV( $tmp_rows, $export_column_map, FALSE, FALSE );
						}
						unset($tmp_rows, $export_column_map, $column_id, $column_data, $rows, $row);

						break;

					case 'quickbooks': //Quickbooks Pro export format.
						$file_name = 'payroll_export.iif';

						ksort($setup_data['quickbooks']['columns']);
						$setup_data['quickbooks']['columns'] = Misc::trimSortPrefix( $setup_data['quickbooks']['columns'] );

						//
						// Quickbooks header
						//
						/*
							Company Create Time can be found by first running an Timer Activity export in QuickBooks and viewing the output.

							PITEM field needs to be populated, as that is the PAYROLL ITEM in quickbooks. It can be the same as the ITEM field.
							PROJ could be mapped to the default department/branch?
						*/
						$data =  "!TIMERHDR\tVER\tREL\tCOMPANYNAME\tIMPORTEDBEFORE\tFROMTIMER\tCOMPANYCREATETIME\n";
						$data .= "TIMERHDR\t8\t0\t". trim($setup_data['quickbooks']['company_name']) ."\tN\tY\t". trim($setup_data['quickbooks']['company_created_date']) ."\n";
						$data .= "!TIMEACT\tDATE\tJOB\tEMP\tITEM\tPITEM\tDURATION\tPROJ\tNOTE\tXFERTOPAYROLL\tBILLINGSTATUS\n";

						foreach($rows as $row) {
							foreach( $setup_data['quickbooks']['columns'] as $column_id => $column_data ) {
								if ( isset( $row[$column_id] ) AND trim($column_data['hour_code']) != '' ) {
									//Make sure employee name is in format: LastName, FirstName MiddleInitial
									$tmp_employee_name = $row['last_name'].', '. $row['first_name'];
									if ( isset($row['middle_name']) AND strlen($row['middle_name']) > 0 ) {
										$tmp_employee_name .= ' '.substr(trim($row['middle_name']),0,1);
									}

									$proj = NULL;
									if ( isset($row[$setup_data['quickbooks']['proj']]) ) {
										$proj = $row[$setup_data['quickbooks']['proj']];
									}

									$data .= "TIMEACT\t". date('n/j/y', $row['pay_period_end_date'])."\t\t". $tmp_employee_name ."\t". trim($column_data['hour_code']) ."\t". trim($column_data['hour_code']) ."\t".  TTDate::getTimeUnit( $row[$column_id], 10 ) ."\t". $proj ."\t\tY\t0\n";
									unset($tmp_employee_name);
								}
							}
						}

						break;
					case 'surepayroll': //SurePayroll Export format.
						ksort($setup_data['surepayroll']['columns']);
						$setup_data['surepayroll']['columns'] = Misc::trimSortPrefix( $setup_data['surepayroll']['columns'] );

						//
						//header
						//
						$data = 'TC'."\n";
						$data .= '00001'."\n";

						$export_column_map = array(	'pay_period_end_date' => 'Entry Date',
													'employee_number' => 'Employee Number',
													'last_name' => 'Last Name',
													'first_name' => 'First Name',
													'hour_code' => 'Payroll Code',
													'value' => 'Hours' );

						foreach($rows as $row) {
							foreach( $setup_data['surepayroll']['columns'] as $column_id => $column_data ) {

								if ( isset( $row[$column_id] ) AND trim($column_data['hour_code']) != '' ) {
									Debug::Arr($column_data,'Output2', __FILE__, __LINE__, __METHOD__,10);
									$tmp_rows[] = array(
														'pay_period_end_date' => date('m/d/Y', $row['pay_period_end_date']),
														'employee_number' => $row['employee_number'],
														'last_name' => $row['last_name'],
														'first_name' => $row['first_name'],
														'hour_code' => trim($column_data['hour_code']),
														'value' => TTDate::getTimeUnit( $row[$column_id], 20 ),
														);
								}
							}
						}

						if ( isset( $tmp_rows) ) {
							$data .= Misc::Array2CSV( $tmp_rows, $export_column_map, FALSE, FALSE );
							$data = str_replace('"','', $data);
						}
						unset($tmp_rows, $export_column_map, $column_id, $column_data, $rows, $row);
						break;
					default:
						break;
				}
			}
		}

		if ( Debug::getVerbosity() == 11 ) {
			Debug::Arr($data,'Output', __FILE__, __LINE__, __METHOD__,10);

			Debug::Display();
		} else {
			if ( isset($data) AND strlen($data) > 0 ) {
				Debug::Text('Exporting as CSV', __FILE__, __LINE__, __METHOD__,10);

				Misc::FileDownloadHeader( $file_name, 'application/csv', strlen($data) );
				echo $data;
			} else {
				echo TTi18n::gettext("No Data To Export!") ."<br>\n";
			}
		}

		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['pay_period_ids'] = array( '-0000-'.array_shift(array_keys($pay_period_options)) );
				$filter_data['start_date'] = $default_start_date;
				$filter_data['end_date'] = $default_end_date;
				$filter_data['group_ids'] = array( -1 );

				//$filter_data['user_ids'] = array_keys( UserListFactory::getByCompanyIdArray( $current_company->getId(), FALSE, FALSE ) );
				if ( !isset($filter_data['column_ids']) ) {
					$filter_data['column_ids']	= array();
				}
			}
		}
		$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->getSearchByCompanyIdAndArrayCriteria( $current_company->getId(), array('permission_children_ids' => $permission_children_ids ) );
		$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 );

		//Get pay periods
		$pplf = new PayPeriodListFactory();
		$pplf->getByCompanyId( $current_company->getId() );
		$pay_period_options = Misc::prependArray( $all_array_option, $pplf->getArrayByListFactory( $pplf, FALSE, TRUE ) );
		$filter_data['src_pay_period_options'] = Misc::arrayDiffByKey( (array)$filter_data['pay_period_ids'], $pay_period_options );
		$filter_data['selected_pay_period_options'] = Misc::arrayIntersectByKey( (array)$filter_data['pay_period_ids'], $pay_period_options );

		$filter_data['export_type_options'] = array(
													0 => TTi18n::gettext('-- Please Choose --'),
													'adp' => TTi18n::gettext('ADP'),
													'paychex_preview' => TTi18n::gettext('Paychex Preview'),
													'ceridian_insync' => TTi18n::gettext('Ceridian Insync'),
													'millenium' => TTi18n::gettext('Millenium'),
													'quickbooks' => TTi18n::gettext('QuickBooks Pro'),
													'surepayroll' => TTi18n::gettext('SurePayroll'),
													'csv' => TTi18n::gettext('Generic Excel/CSV'),
													'other' => TTi18n::gettext('-- Other --'),
													);

		$setup_data['src_column_options'] = $columns;

		//
		//ADP  specific columns
		//
		$setup_data['adp_hour_column_options'][0] = TTi18n::gettext('-- DO NOT EXPORT --');
		$setup_data['adp_hour_column_options']['regular_time'] = TTi18n::gettext('Regular Time');
		$setup_data['adp_hour_column_options']['overtime'] = TTi18n::gettext('Overtime');
		for ( $i=3; $i <= 4; $i++ ) {
			$setup_data['adp_hour_column_options'][$i] = TTi18n::gettext('Hours') .' '. $i;
		}

		//Quickbooks additional column mapping
		$setup_data['quickbooks_proj_options'] = array(
													0 => TTi18n::gettext('-- NONE --'),
													'default_branch' => TTi18n::gettext('Default Branch'),
													'default_department' => TTi18n::gettext('Default Department'),
													'group' => TTi18n::gettext('Group'),
													'title' => TTi18n::gettext('Title'),
													);

		$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/PayrollExport.tpl');

		break;
}
?>
