<?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: 2158 $
 * $Id: PayStubEntryAccountFactory.class.php 2158 2008-09-15 23:26:15Z ipso $
 * $Date: 2008-09-15 16:26:15 -0700 (Mon, 15 Sep 2008) $
 */

/**
 * @package Module_Pay_Stub
 */
class PayStubEntryAccountFactory extends Factory {
	protected $table = 'pay_stub_entry_account';
	protected $pk_sequence_name = 'pay_stub_entry_account_id_seq'; //PK Sequence name


	function _getFactoryOptions( $name ) {

		$retval = NULL;
		switch( $name ) {
			case 'status':
				$retval = array(
										10 => TTi18n::gettext('Enabled'),
										20 => TTi18n::gettext('Disabled'),
									);
				break;
			case 'type':
				$retval = array(
										10 => TTi18n::gettext('Earning'),
										20 => TTi18n::gettext('Employee Deduction'),
										30 => TTi18n::gettext('Employer Deduction'),
										40 => TTi18n::gettext('Total'),
										50 => TTi18n::gettext('Accrual'),
										//60 => TTi18n::gettext('Advance Earning'),
										//65 => TTi18n::gettext('Advance Deduction'),
									);
				break;
			case 'type_calculation_order':
				$retval = array(
										10 => 40,
										20 => 50,
										30 => 60,
										40 => 70,
										50 => 30,
										60 => 10,
										65 => 20,
									);
				break;

		}

		return $retval;
	}


	function getCompany() {
		if ( isset($this->data['company_id']) ) {
			return $this->data['company_id'];
		}

		return FALSE;
	}
	function setCompany($id) {
		$id = trim($id);

		Debug::Text('Company ID: '. $id, __FILE__, __LINE__, __METHOD__,10);
		$clf = new CompanyListFactory();

		if ( $this->Validator->isResultSetWithRows(	'company',
													$clf->getByID($id),
													TTi18n::gettext('Company is invalid')
													) ) {

			$this->data['company_id'] = $id;

			return TRUE;
		}

		return FALSE;
	}

	function getStatus() {
		return (int)$this->data['status_id'];
	}
	function setStatus($status) {
		$status = trim($status);

		$key = Option::getByValue($status, $this->getOptions('status') );
		if ($key !== FALSE) {
			$status = $key;
		}

		if ( $this->Validator->inArrayKey(	'status',
											$status,
											TTi18n::gettext('Incorrect Status'),
											$this->getOptions('status')) ) {

			$this->data['status_id'] = $status;

			return FALSE;
		}

		return FALSE;
	}

	//Returns the order in which accounts should be calculated
	//given a circular dependency scenario
	function getTypeCalculationOrder() {
		if ( $this->getType() !== FALSE ) {
			$order_arr = $this->getOptions('type_calculation_order');

			if ( isset($order_arr[$this->getType()] ) ) {
				return $order_arr[$this->getType()];
			}
		}

		return FALSE;
	}

	function getType() {
		if ( isset($this->data['type_id']) ) {
			return $this->data['type_id'];
		}

		return FALSE;
	}
	function setType($type) {
		$type = trim($type);

		$key = Option::getByValue($type, $this->getOptions('type') );
		if ($key !== FALSE) {
			$type = $key;
		}

		if ( $this->Validator->inArrayKey(	'type_id',
											$type,
											TTi18n::gettext('Incorrect Type'),
											$this->getOptions('type')) ) {

			$this->data['type_id'] = $type;

			return FALSE;
		}

		return FALSE;
	}

	function isUniqueName($name) {
		$ph = array(
					'company_id' => $this->getCompany(),
					'type_id' => $this->getType(),
					'name' => $name,
					);

		$query = 'select id from '. $this->getTable() .' where company_id = ? AND type_id = ? AND name = ? AND deleted=0';
		$id = $this->db->GetOne($query, $ph);
		Debug::Arr($id,'Unique Pay Stub Account: '. $name, __FILE__, __LINE__, __METHOD__,10);

		if ( $id === FALSE ) {
			return TRUE;
		} else {
			if ($id == $this->getId() ) {
				return TRUE;
			}
		}

		return FALSE;
	}
	function getName() {
		if ( isset($this->data['name']) ) {
			/*I18n:	apply gettext in the result of this function
					to be use in the getByIdArray() function in
					the PayStubEntryAccountListFactory.class.php
					file.
			*/
			return TTi18n::gettext($this->data['name']);
		}

		return FALSE;
	}
	function setName($value) {
		$value = trim($value);

		if 	(
				$this->Validator->isLength(		'name',
												$value,
												TTi18n::gettext('Name is too short or too long'),
												2,
												100)
				AND
				$this->Validator->isTrue(				'name',
														$this->isUniqueName($value),
														TTi18n::gettext('Name is already in use')
													)
													) {

			$this->data['name'] = $value;

			return TRUE;
		}

		return FALSE;
	}

	function getOrder() {
		if ( isset($this->data['ps_order']) ) {
			return $this->data['ps_order'];
		}

		return FALSE;
	}
	function setOrder($value) {
		$value = trim($value);

		if ( $this->Validator->isNumeric(		'order',
												$value,
												TTi18n::gettext('Invalid Order')
										) ) {


			$this->data['ps_order'] = $value;

			return TRUE;
		}

		return FALSE;
	}

	function getDebitAccount() {
		if ( isset($this->data['debit_account']) ) {
			return $this->data['debit_account'];
		}

		return FALSE;
	}
	function setDebitAccount($value) {
		$value = trim($value);

		if 	(	$value == ''
				OR
				$this->Validator->isLength(		'debit_account',
												$value,
												TTi18n::gettext('Invalid Debit Account'),
												2,
												250) ) {

			$this->data['debit_account'] = $value;

			return TRUE;
		}

		return FALSE;
	}

	function getCreditAccount() {
		if ( isset($this->data['credit_account']) ) {
			return $this->data['credit_account'];
		}

		return FALSE;
	}
	function setCreditAccount($value) {
		$value = trim($value);

		if 	(	$value == ''
				OR
				$this->Validator->isLength(		'credit_account',
												$value,
												TTi18n::gettext('Invalid Credit Account'),
												2,
												250) ) {

			$this->data['credit_account'] = $value;

			return TRUE;
		}

		return FALSE;
	}

	/*
	function getByAccrualPayStubEntryAccount() {
		//Get all PSE accounts that have this account as their accrual.
		//Usually accounts like Vacation Accrual Release etc...
		if ( $this->

		$psealf = new PayStubEntryAccountListFactory();
		$psealf->getByCompanyIdAndStatusIdAndTypeId( $user_obj->getCompany(), 10, 50);

	}
	*/

	function getAccrual() {
		if ( isset($this->data['accrual_pay_stub_entry_account_id']) ) {
			return $this->data['accrual_pay_stub_entry_account_id'];
		}

		return FALSE;
	}
	function setAccrual($id) {
		$id = trim($id);

		Debug::Text('ID: '. $id, __FILE__, __LINE__, __METHOD__,10);
		$psealf = new PayStubEntryAccountListFactory();
		$psealf->getByID($id);
		if ( $psealf->getRecordCount() > 0 ) {
			if ( $psealf->getCurrent()->getType() != 50 ) {
				//Reset Result set so an error occurs.
				$psealf = new PayStubEntryAccountListFactory();
			}
		}

		if (
				( $id == '' OR $id == 0 )
				OR
				$this->Validator->isResultSetWithRows(	'accrual',
														$psealf,
														TTi18n::gettext('Accrual account is invalid')
													) ) {

			$this->data['accrual_pay_stub_entry_account_id'] = $id;

			return TRUE;
		}

		return FALSE;
	}

	static function addPresets($company_id) {
		if ( $company_id == '' ) {
			return FALSE;
		}

		$clf = new CompanyListFactory();
		$clf->getById( $company_id );
		if ( $clf->getRecordCount() > 0 ) {
			$company_obj = $clf->getCurrent();
			$country = $company_obj->getCountry();
			$province = $company_obj->getProvince();
		} else {
			return FALSE;
		}

		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->StartTransaction();

		/*
										10 => 'Earning',
										20 => 'Employee Deduction',
										30 => 'Employer Deduction',
										40 => 'Total',
										50 => 'Accrual',
										60 => 'Advance Earning',
										65 => 'Advance Deduction',
		*/

		//See if accounts are already linked
		$pseallf = new PayStubEntryAccountLinkListFactory();
		$pseallf->getByCompanyId( $company_id );
		if ( $pseallf->getRecordCount() > 0 ) {
			$psealf = $pseallf->getCurrent();
		} else {
			$psealf = new PayStubEntryAccountLinkFactory();
			$psealf->setCompany( $company_id );
		}

		Debug::text('Country: '. $country , __FILE__, __LINE__, __METHOD__, 10);
		switch (strtolower($country)) {
			case 'ca':
				Debug::text('Saving.... Federal Taxes', __FILE__, __LINE__, __METHOD__, 10);
				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('Federal Income Tax');
				$pseaf->setOrder(210);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('Provincial Income Tax');
				$pseaf->setOrder(220);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('Additional Income Tax');
				$pseaf->setOrder(230);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('CPP');
				$pseaf->setOrder(240);

				if ( $pseaf->isValid() ) {
					$psea_id = $pseaf->Save();
					$psealf->setEmployeeCPP( $psea_id );
					unset($psea_id);
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('EI');
				$pseaf->setOrder(250);

				if ( $pseaf->isValid() ) {
					$psea_id = $pseaf->Save();
					$psealf->setEmployeeEI( $psea_id );
					unset($psea_id);
				}

				//Employer Contributions
				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(30);
				$pseaf->setName('CPP - Employer');
				$pseaf->setOrder(300);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(30);
				$pseaf->setName('EI - Employer');
				$pseaf->setOrder(310);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(30);
				$pseaf->setName('WCB - Employer');
				$pseaf->setOrder(320);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				Debug::text('Saving.... Vacation Accrual', __FILE__, __LINE__, __METHOD__, 10);
				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(50);
				$pseaf->setName('Vacation Accrual');
				$pseaf->setOrder(400);

				if ( $pseaf->isValid() ) {
					$vacation_accrual_id = $pseaf->Save();

					Debug::text('Saving.... Earnings - Vacation Accrual Release', __FILE__, __LINE__, __METHOD__, 10);
					$pseaf = new PayStubEntryAccountFactory();
					$pseaf->setCompany( $company_id );
					$pseaf->setStatus(10);
					$pseaf->setType(10);
					$pseaf->setName('Vacation Accrual Release');
					$pseaf->setOrder(180);
					$pseaf->setAccrual($vacation_accrual_id);

					if ( $pseaf->isValid() ) {
						$pseaf->Save();
					}

					unset($vaction_accrual_id);
				}

				break;
			case 'us':
				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('Federal Income Tax');
				$pseaf->setOrder(210);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('Advance EIC');
				$pseaf->setOrder(215);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('State Income Tax');
				$pseaf->setOrder(220);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('District Income Tax');
				$pseaf->setOrder(225);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('Federal Add. Income Tax');
				$pseaf->setOrder(230);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('State Add. Income Tax');
				$pseaf->setOrder(235);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('Social Security (FICA)');
				$pseaf->setOrder(240);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(30);
				$pseaf->setName('Social Security (FICA)');
				$pseaf->setOrder(340);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(30);
				$pseaf->setName('Fed. Unemployment Ins.');
				$pseaf->setOrder(342);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('State Unemployment Ins.');
				$pseaf->setOrder(240);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('Medicare');
				$pseaf->setOrder(245);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(30);
				$pseaf->setName('Medicare');
				$pseaf->setOrder(346);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(20);
				$pseaf->setName('State Disability Ins.');
				$pseaf->setOrder(250);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(30);
				$pseaf->setName('State Unemployment Ins.');
				$pseaf->setOrder(350);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(30);
				$pseaf->setName('State Employee Training');
				$pseaf->setOrder(352);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				break;
		}

		Debug::text('Province: '. $province , __FILE__, __LINE__, __METHOD__, 10);
		switch (strtolower($province)) {
			case 'ny':
				$pseaf = new PayStubEntryAccountFactory();
				$pseaf->setCompany( $company_id );
				$pseaf->setStatus(10);
				$pseaf->setType(30);
				$pseaf->setName('State Reemployment');
				$pseaf->setOrder(354);

				if ( $pseaf->isValid() ) {
					$pseaf->Save();
				}

				break;
		}

		Debug::text('Saving.... Earnings - Regular Time', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(10);
		$pseaf->setName('Regular Time');
		$pseaf->setOrder(100);

		if ( $pseaf->isValid() ) {
			$psea_id = $pseaf->Save();
			$psealf->setRegularTime( $psea_id );
			unset($psea_id);
		}

		Debug::text('Saving.... Earnings - Over Time 1', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(10);
		$pseaf->setName('Over Time 1');
		$pseaf->setOrder(150);

		if ( $pseaf->isValid() ) {
			$pseaf->Save();
		}

		Debug::text('Saving.... Earnings - Over Time 2', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(10);
		$pseaf->setName('Over Time 2');
		$pseaf->setOrder(151);

		if ( $pseaf->isValid() ) {
			$pseaf->Save();
		}

		Debug::text('Saving.... Earnings - Premium Time 1', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(10);
		$pseaf->setName('Premium 1');
		$pseaf->setOrder(170);

		if ( $pseaf->isValid() ) {
			$pseaf->Save();
		}

		Debug::text('Saving.... Earnings - Premium Time 2', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(10);
		$pseaf->setName('Premium 2');
		$pseaf->setOrder(171);

		if ( $pseaf->isValid() ) {
			$pseaf->Save();
		}

		Debug::text('Saving.... Earnings - Bonus', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(10);
		$pseaf->setName('Bonus');
		$pseaf->setOrder(185);

		if ( $pseaf->isValid() ) {
			$pseaf->Save();
		}

		Debug::text('Saving.... Earnings - Other', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(10);
		$pseaf->setName('Other');
		$pseaf->setOrder(189);

		if ( $pseaf->isValid() ) {
			$pseaf->Save();
		}

		Debug::text('Saving.... Union Dues', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(20);
		$pseaf->setName('Union Dues');
		$pseaf->setOrder(285);

		if ( $pseaf->isValid() ) {
			$pseaf->Save();
		}

		Debug::text('Saving.... Employee Benefits Plan', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(20);
		$pseaf->setName('Benefits Plan');
		$pseaf->setOrder(225);

		if ( $pseaf->isValid() ) {
			$pseaf->Save();
		}

		Debug::text('Saving.... Employer Benefits Plan', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(30);
		$pseaf->setName('Benefits Plan');
		$pseaf->setOrder(330);

		if ( $pseaf->isValid() ) {
			$pseaf->Save();
		}

		Debug::text('Saving.... Total Earnings', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(40);
		$pseaf->setName('Total Gross');
		$pseaf->setOrder(199);

		if ( $pseaf->isValid() ) {
			$psea_id = $pseaf->Save();
			$psealf->setTotalGross( $psea_id );
			unset($psea_id);
		}

		Debug::text('Saving.... Total Deductions', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(40);
		$pseaf->setName('Total Deductions');
		$pseaf->setOrder(298);

		if ( $pseaf->isValid() ) {
			$psea_id = $pseaf->Save();
			$psealf->setTotalEmployeeDeduction( $psea_id );
			unset($psea_id);
		}

		Debug::text('Saving.... Net Pay', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(40);
		$pseaf->setName('Net Pay');
		$pseaf->setOrder(299);

		if ( $pseaf->isValid() ) {
			$psea_id = $pseaf->Save();
			$psealf->setTotalNetPay( $psea_id );
			unset($psea_id);
		}

		Debug::text('Saving.... Employer Total Cont', __FILE__, __LINE__, __METHOD__, 10);
		$pseaf = new PayStubEntryAccountFactory();
		$pseaf->setCompany( $company_id );
		$pseaf->setStatus(10);
		$pseaf->setType(40);
		$pseaf->setName('Employer Total Contributions');
		$pseaf->setOrder(399);

		if ( $pseaf->isValid() ) {
			$psea_id = $pseaf->Save();
			$psealf->setTotalEmployerDeduction( $psea_id );
			unset($psea_id);
		}

		if ( $psealf->isValid() == TRUE ) {
			Debug::text('Saving.... PSA Linking', __FILE__, __LINE__, __METHOD__, 10);
			$psealf->Save();
		} else {
			Debug::text('Saving.... PSA Linking FAILED!', __FILE__, __LINE__, __METHOD__, 10);
		}

		$pseaf->CommitTransaction();
		//$pseaf->FailTransaction();

		return TRUE;
	}

	function Validate() {
		if ( $this->getType() == 50 ) {
			//If the PSE account is an accrual, it can't link to one as well.
			$this->setAccrual(NULL);
		}

		//Make sure this account doesn't point to itself as an accrual.
		if ( $this->isNew() == FALSE AND $this->getAccrual() == $this->getId() ) {
			$this->Validator->isTrue(				'accrual',
													FALSE,
													TTi18n::gettext('Accrual account is invalid')
												);
		}

		//Make sure PS order is correct, in that types can't be separated by total or accrual accounts.
		$pseallf = new PayStubEntryAccountLinkListFactory();
		$pseallf->getByCompanyId( $this->getCompany() );
		if ( $pseallf->getRecordCount() > 0 ) {
			$pseal_obj = $pseallf->getCurrent();

			$psealf = new PayStubEntryAccountListFactory();
			$psealf->getByCompanyIdAndTypeId( $this->getCompany(), 40 );
			if ( $psealf->getRecordCount() > 0 ) {
				foreach( $psealf as $psea_obj ) {
					$psea_map[$psea_obj->getId()] = $psea_obj->getOrder();
				}
				unset($psea_obj);
			}

			switch( $this->getType() ) {
				case 10: //Earning
					//Greater the 0, less then Total Gross Account
					if ( isset($psea_map[$pseal_obj->getTotalGross()]) ) {
						$min_ps_order = 0;
						$max_ps_order = $psea_map[$pseal_obj->getTotalGross()];
					}
					break;
				case 20: //EE Deduction
					//Greater then Total Gross Account, less then Total Employee Deduction
					if ( isset($psea_map[$pseal_obj->getTotalGross()]) AND isset($psea_map[$pseal_obj->getTotalEmployeeDeduction()]) ) {
						$min_ps_order = $psea_map[$pseal_obj->getTotalGross()];
						$max_ps_order = $psea_map[$pseal_obj->getTotalEmployeeDeduction()];
					}
					break;
				case 30: //ER Deduction
					//Greater then Net Pay Account, less then Total Employer Deduction
					if ( isset($psea_map[$pseal_obj->getTotalNetPay()]) AND isset($psea_map[$pseal_obj->getTotalEmployerDeduction()]) ) {
						$min_ps_order = $psea_map[$pseal_obj->getTotalNetPay()];
						$max_ps_order = $psea_map[$pseal_obj->getTotalEmployerDeduction()];
					}
					break;
				case 50: //Accrual
					//Greater then Total Employer Deduction
					if ( isset($psea_map[$pseal_obj->getTotalEmployerDeduction()]) ) {
						$min_ps_order = $psea_map[$pseal_obj->getTotalEmployerDeduction()];
						$max_ps_order = 10001;
					}
					break;
			}

			if ( isset($min_ps_order) AND isset($max_ps_order) AND ( $this->getOrder() <= $min_ps_order OR $this->getOrder() >= $max_ps_order ) ) {
				Debug::text('PS Order... Min: '. $min_ps_order .' Max: '. $max_ps_order, __FILE__, __LINE__, __METHOD__, 10);
				$this->Validator->isTrue(				'order',
														FALSE,
														TTi18n::gettext('Order is invalid for this type of account, it must be between'). ' '. ($min_ps_order+1) . ' ' . TTi18n::gettext('and') . ' ' . ($max_ps_order-1) );
			}
		}

		return TRUE;

	}

	function preSave() {
		if ( $this->getDeleted() == TRUE ) {
			Debug::text('Attempting to delete PSE Account', __FILE__, __LINE__, __METHOD__, 10);

			//Check to see if account is in use.
			$pself = new PayStubEntryListFactory();
			$pself->getByEntryNameId( $this->getId() );
			if ( $pself->getRecordCount() > 0 ) {
				Debug::text('PSE Account is in use... Disabling instead.', __FILE__, __LINE__, __METHOD__, 10);
				$this->setDeleted(FALSE); //Can't delete, account is in use.
				$this->setStatus(20); //Disable instead
			} else {
				Debug::text('PSE Account is NOT in use... Deleting...', __FILE__, __LINE__, __METHOD__, 10);
			}
		}

		return TRUE;
	}

	function postSave() {
		$this->removeCache( 'company_id-'.$this->getCompany() );
		$this->removeCache( $this->getId() );
	}

	function addLog( $log_action ) {
		return TTLog::addEntry( $this->getId(), $log_action,  TTi18n::getText('Pay Stub Account'), NULL, $this->getTable() );
	}
}
?>
