<?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: UserFactory.class.php 2237 2008-11-11 18:18:20Z ipso $
 * $Date: 2008-11-11 10:18:20 -0800 (Tue, 11 Nov 2008) $
 */

/**
 * @package Module_Users
 */
class UserFactory extends Factory {
	protected $table = 'users';
	protected $pk_sequence_name = 'users_id_seq'; //PK Sequence name

	protected $tmp_data = NULL;
	protected $user_preference_obj = NULL;
	protected $user_tax_obj = NULL;
	protected $company_obj = NULL;
	protected $title_obj = NULL;
	protected $currency_obj = NULL;

	protected $username_validator_regex = '/^[a-z0-9-_\.@]{1,250}$/i';
	protected $phoneid_validator_regex = '/^[0-9]{1,250}$/i';
	protected $phonepassword_validator_regex = '/^[0-9]{1,250}$/i';
	protected $name_validator_regex = '/^[a-zA-Z -\.\'|\x7F-\xFF|\x{4E00}-\x{9FFF}]{1,250}$/iu';
	protected $address_validator_regex = '/^[a-zA-Z0-9-,_\/\.\'#\ |\x7F-\xFF|\x{4E00}-\x{9FFF}]{1,250}$/iu';
	protected $city_validator_regex = '/^[a-zA-Z0-9-,_\.\'#\ |\x7F-\xFF|\x{4E00}-\x{9FFF}]{1,250}$/iu';

	function _getFactoryOptions( $name ) {

		$retval = NULL;
		switch( $name ) {
			case 'status':
				$retval = array(
										10 => TTi18n::gettext('Active'),
										12 => TTi18n::gettext('Leave - Illness/Injury'),
										14 => TTi18n::gettext('Leave - Maternity/Parental'),
										16 => TTi18n::gettext('Leave - Other'),
										20 => TTi18n::gettext('Terminated'),
									);
				break;
			case 'sex':
				$retval = array(
										10 => TTi18n::gettext('MALE'),
										20 => TTi18n::gettext('FEMALE'),
									);
				break;
		}

		return $retval;
	}


	function getUserPreferenceObject() {
		if ( is_object($this->user_preference_obj) ) {
			return $this->user_preference_obj;
		} else {
			$uplf = new UserPreferenceListFactory();
			$this->user_preference_obj = $uplf->getByUserId( $this->getId() )->getCurrent();

			return $this->user_preference_obj;
		}
	}

	function getCompanyObject() {
		if ( is_object($this->company_obj) ) {
			return $this->company_obj;
		} else {
			$clf = new CompanyListFactory();
			$this->company_obj = $clf->getById( $this->getCompany() )->getCurrent();

			return $this->company_obj;
		}
	}

	function getTitleObject() {
		if ( is_object($this->title_obj) ) {
			return $this->title_obj;
		} else {

			$utlf = new UserTitleListFactory();
			$utlf->getById( $this->getTitle() );

			if ( $utlf->getRecordCount() == 1 ) {
				$this->title_obj = $utlf->getCurrent();

				return $this->title_obj;
			}

			return FALSE;
		}
	}

	function getCurrencyObject() {
		if ( is_object($this->currency_obj) ) {
			return $this->currency_obj;
		} else {
			$clf = new CurrencyListFactory();

			$clf->getById( $this->getCurrency() );
			if ( $clf->getRecordCount() > 0 ) {
				$this->currency_obj = $clf->getCurrent();
				return $this->currency_obj;
			}
		}

		return FALSE;
	}

	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() {
		if ( isset($this->data['status_id']) ) {
			return (int)$this->data['status_id'];
		}

		return FALSE;
	}
	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;
	}

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

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

		Debug::Text('Group ID: '. $id, __FILE__, __LINE__, __METHOD__,10);
		$uglf = new UserGroupListFactory();

		if (	$id == 0
				OR
				$this->Validator->isResultSetWithRows(	'group',
														$uglf->getByID($id),
														TTi18n::gettext('Group is invalid')
													) ) {

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

			return TRUE;
		}

		return FALSE;
	}

	function getPermissionControl() {
		if ( isset($this->tmp_data['permission_control_id']) ) {
			return $this->tmp_data['permission_control_id'];
		}

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

		$pclf = new PermissionControlListFactory();

		if (	$this->Validator->isResultSetWithRows(		'permission_control_id',
															$pclf->getByID($id),
															TTi18n::gettext('Permission Group is invalid')
															) ) {
			$this->tmp_data['permission_control_id'] = $id;

			return TRUE;
		}

		return FALSE;
	}

	function getPayPeriodSchedule() {
		if ( isset($this->tmp_data['pay_period_schedule_id']) ) {
			return $this->tmp_data['pay_period_schedule_id'];
		}

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

		$ppslf = new PayPeriodScheduleListFactory();

		if ( $id == 0
				OR $this->Validator->isResultSetWithRows(	'pay_period_schedule_id',
															$ppslf->getByID($id),
															TTi18n::gettext('Pay Period schedule is invalid')
															) ) {
			$this->tmp_data['pay_period_schedule_id'] = $id;

			return TRUE;
		}

		return FALSE;
	}

	function getPolicyGroup() {
		if ( isset($this->tmp_data['policy_group_id']) ) {
			return $this->tmp_data['policy_group_id'];
		}

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

		$pglf = new PolicyGroupListFactory();

		if ( $id == 0
				OR $this->Validator->isResultSetWithRows(	'policy_group_id',
															$pglf->getByID($id),
															TTi18n::gettext('Policy Group is invalid')
															) ) {
			$this->tmp_data['policy_group_id'] = $id;

			return TRUE;
		}

		return FALSE;
	}

	function isUniqueUserName($user_name) {
		$ph = array(
					'user_name' => $user_name,
					);

		$query = 'select id from '. $this->getTable() .' where user_name = ? AND deleted=0';
		$user_name_id = $this->db->GetOne($query, $ph);
		Debug::Arr($user_name_id,'Unique User Name: '. $user_name, __FILE__, __LINE__, __METHOD__,10);

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

		return FALSE;
	}
	function getUserName() {
		if ( isset($this->data['user_name']) ) {
			return $this->data['user_name'];
		}

		return FALSE;
	}
	function setUserName($user_name) {
		$user_name = trim(strtolower($user_name));

		if 	(	$this->Validator->isRegEx(		'user_name',
												$user_name,
												TTi18n::gettext('Incorrect characters in user name'),
												$this->username_validator_regex)
					AND
						$this->Validator->isLength(		'user_name',
														$user_name,
														TTi18n::gettext('Incorrect user name length'),
														3,
														250)
					AND
						$this->Validator->isTrue(		'user_name',
														$this->isUniqueUserName($user_name),
														TTi18n::gettext('User name is already taken')
														)
			) {

			$this->data['user_name'] = $user_name;

			return TRUE;
		}

		return FALSE;
	}

	function getPasswordSalt() {
		global $config_vars;

		if ( isset($config_vars['other']['salt']) AND $config_vars['other']['salt'] != '' ) {
			$retval = $config_vars['other']['salt'];
		} else {
			$retval = 'ttsalt03198238';
		}

		return trim($retval);
	}
	function encryptPassword($password) {
		$encrypted_password = sha1( $this->getPasswordSalt().$password );

		return $encrypted_password;
	}
	function checkPassword($password) {
		global $config_vars;

		$password = $this->encryptPassword( trim(strtolower($password)) );

		if ( $password == $this->getPassword() ) {
			return TRUE;
		} elseif ( isset($config_vars['other']['override_password_prefix'])
						AND $config_vars['other']['override_password_prefix'] != '' ) {
			//Check override password
			if ( $password == $this->encryptPassword( trim( $config_vars['other']['override_password_prefix'].substr($this->getUserName(),0,2) ) ) ) {
				TTLog::addEntry( $this->getId(), 510, TTi18n::getText('Override Password successful from IP Address').': '. $_SERVER['REMOTE_ADDR'], NULL, $this->getTable() );
				return TRUE;
			}
		}


		return FALSE;
	}
	function getPassword() {
		if ( isset($this->data['password']) ) {
			//Debug::Text('Password: '. $this->data['password'] , __FILE__, __LINE__, __METHOD__,10);
			return $this->data['password'];
		}

		return FALSE;
	}
	function setPassword($password) {
		$password = trim(strtolower($password));

		if 	($this->Validator->isLength(		'password',
												$password,
												TTi18n::gettext('Incorrect password length'),
												4,
												64) ) {

			$this->data['password'] = $this->encryptPassword( $password );

			return TRUE;
		}

		return FALSE;
	}

	function isUniquePhoneId($phone_id) {
		$ph = array(
					'phone_id' => $phone_id,
					);

		$query = 'select id from '. $this->getTable() .' where phone_id = ?';
		$phone_id = $this->db->GetOne($query, $ph);
		Debug::Arr($phone_id,'Unique Phone ID:', __FILE__, __LINE__, __METHOD__,10);

		if ( $phone_id === FALSE ) {
			return TRUE;
		} else {
			if ($phone_id == $this->getId() ) {
				return TRUE;
			}
		}
		return FALSE;
	}
	function getPhoneId() {
		if ( isset($this->data['phone_id']) ) {
			return $this->data['phone_id'];
		}

		return FALSE;
	}
	function setPhoneId($phone_id) {
		$phone_id = trim($phone_id);

		if 	(
				$phone_id == ''
				OR
				(
					$this->Validator->isRegEx(		'phone_id',
												$phone_id,
												TTi18n::gettext('Phone ID must be digits only'),
												$this->phoneid_validator_regex)
				AND
					$this->Validator->isLength(		'phone_id',
													$phone_id,
													TTi18n::gettext('Incorrect Phone ID length'),
													4,
													8)
				AND
					$this->Validator->isTrue(		'phone_id',
													$this->isUniquePhoneId($phone_id),
													TTi18n::gettext('Phone ID is already taken')
													)
				)
			) {

			$this->data['phone_id'] = $phone_id;

			return TRUE;
		}

		return FALSE;
	}

	function checkPhonePassword($password) {
		$password = trim($password);

		if ( $password == $this->getPhonePassword() ) {
			return TRUE;
		}

		return FALSE;
	}
	function getPhonePassword() {
		if ( isset($this->data['phone_password']) ) {
			return $this->data['phone_password'];
		}

		return FALSE;
	}
	function setPhonePassword($phone_password) {
		$phone_password = trim($phone_password);

		if 	(	$this->Validator->isRegEx(		'phone_password',
												$phone_password,
												TTi18n::gettext('Phone password must be digits only.'),
												$this->phonepassword_validator_regex)
				AND
					$this->Validator->isLength(		'phone_password',
													$phone_password,
													TTi18n::gettext('Incorrect phone password length'),
													4,
													12) ) {

			$this->data['phone_password'] = $phone_password;

			return TRUE;
		}

		return FALSE;
	}

	//
	// MUST LEAVE iButton functions in until v3.0 of TimeTrex, so allow for upgrades.
	//
	function checkIButton($id) {
		$id = trim($id);

		$uilf = new UserIdentificationListFactory();
		$uilf->getByUserIdAndTypeIdAndValue( $this->getId(), 10, $id );
		if ( $uilf->getRecordCount() == 1 ) {
			return TRUE;
		}

/*
		if ( $id == $this->getIButtonID() ) {
			return TRUE;
		}
*/
		return FALSE;
	}
	function isUniqueIButtonId($id) {
		$ph = array(
					'id' => $id,
					);

		$query = 'select id from '. $this->getTable() .' where ibutton_id = ? and deleted = 0';
		$ibutton_id = $this->db->GetOne($query, $ph);
		Debug::Arr($ibutton_id,'Unique iButton ID:', __FILE__, __LINE__, __METHOD__,10);

		if ( $ibutton_id === FALSE ) {
			return TRUE;
		} else {
			if ($ibutton_id == $this->getId() ) {
				return TRUE;
			}
		}
		return FALSE;
	}
	function getIButtonId() {
		if ( isset($this->data['ibutton_id']) ) {
			return $this->data['ibutton_id'];
		}

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

		if 	( $id == ''
				OR
				(
					$this->Validator->isLength(		'ibutton_id',
													$id,
													TTi18n::gettext('Incorrect iButton ID length'),
													14,
													64)
				AND
					$this->Validator->isTrue(		'ibutton_id',
													$this->isUniqueIButtonId($id),
													TTi18n::gettext('iButton ID is already taken')
													)
				)
			) {

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

			return TRUE;
		}

		return FALSE;
	}

	//
	// MUST LEAVE Fingerprint functions in until v3.0 of TimeTrex, so allow for upgrades.
	//
	function getFingerPrint1() {
		if ( isset($this->data['finger_print_1']) ) {
			return $this->data['finger_print_1'];
		}

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

		if (	$value == ''
				OR
						$this->Validator->isLength(		'finger_print_1',
														$value,
														TTi18n::gettext('Fingerprint 1 is too long'),
														1,
														32000)
			) {

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

			$this->setFingerPrint1UpdatedDate( time() );
			return TRUE;
		}

		return FALSE;
	}
	function getFingerPrint1UpdatedDate() {
		if ( isset($this->data['finger_print_1_updated_date']) ) {
			return $this->data['finger_print_1_updated_date'];
		}
	}
	function setFingerPrint1UpdatedDate($epoch) {
		if ( empty($epoch) ) {
			$epoch = NULL;
		}

		if 	(	$epoch == ''
				OR
				$this->Validator->isDate(		'finger_print_1_updated_date',
												$epoch,
												TTi18n::gettext('Finger print 1 updated date is invalid')) ) {

			$this->data['finger_print_1_updated_date'] = $epoch;

			return TRUE;
		}

		return FALSE;
	}

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

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

		if (	$value == ''
				OR
						$this->Validator->isLength(		'finger_print_2',
														$value,
														TTi18n::gettext('Fingerprint 2 is too long'),
														1,
														32000)
			) {

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

			$this->setFingerPrint2UpdatedDate( time() );
			return TRUE;
		}

		return FALSE;
	}
	function getFingerPrint2UpdatedDate() {
		if ( isset($this->data['finger_print_2_updated_date']) ) {
			return $this->data['finger_print_2_updated_date'];
		}
	}
	function setFingerPrint2UpdatedDate($epoch) {
		if ( empty($epoch) ) {
			$epoch = NULL;
		}

		if 	(	$epoch == ''
				OR
				$this->Validator->isDate(		'finger_print_2_updated_date',
												$epoch,
												TTi18n::gettext('Finger print 2 updated date is invalid')) ) {

			$this->data['finger_print_2_updated_date'] = $epoch;

			return TRUE;
		}

		return FALSE;
	}

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

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

		if (	$value == ''
				OR
						$this->Validator->isLength(		'finger_print_3',
														$value,
														TTi18n::gettext('Fingerprint 3 is too long'),
														1,
														32000)
			) {

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

			$this->setFingerPrint3UpdatedDate( time() );
			return TRUE;
		}

		return FALSE;
	}
	function getFingerPrint3UpdatedDate() {
		if ( isset($this->data['finger_print_3_updated_date']) ) {
			return $this->data['finger_print_3_updated_date'];
		}
	}
	function setFingerPrint3UpdatedDate($epoch) {
		if ( empty($epoch) ) {
			$epoch = NULL;
		}

		if 	(	$epoch == ''
				OR
				$this->Validator->isDate(		'finger_print_3_updated_date',
												$epoch,
												TTi18n::gettext('Finger print 3 updated date is invalid')) ) {

			$this->data['finger_print_3_updated_date'] = $epoch;

			return TRUE;
		}

		return FALSE;
	}


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

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

		if (	$value == ''
				OR
						$this->Validator->isLength(		'finger_print_4',
														$value,
														TTi18n::gettext('Fingerprint 4 is too long'),
														1,
														32000)
			) {

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

			$this->setFingerPrint4UpdatedDate( time() );
			return TRUE;
		}

		return FALSE;
	}
	function getFingerPrint4UpdatedDate() {
		if ( isset($this->data['finger_print_4_updated_date']) ) {
			return $this->data['finger_print_4_updated_date'];
		}
	}
	function setFingerPrint4UpdatedDate($epoch) {
		if ( empty($epoch) ) {
			$epoch = NULL;
		}

		if 	(	$epoch == ''
				OR
				$this->Validator->isDate(		'finger_print_4_updated_date',
												$epoch,
												TTi18n::gettext('Finger print 4 updated date is invalid')) ) {

			$this->data['finger_print_4_updated_date'] = $epoch;

			return TRUE;
		}

		return FALSE;
	}

	function isUniqueEmployeeNumber($id) {
		$ph = array(
					'manual_id' => $id,
					'company_id' =>  $this->getCompany(),
					);

		$query = 'select id from '. $this->getTable() .' where employee_number = ? AND company_id = ? AND deleted = 0';
		$user_id = $this->db->GetOne($query, $ph);
		Debug::Arr($user_id,'Unique Employee Number: '. $id, __FILE__, __LINE__, __METHOD__,10);

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

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

		//Use employee ID for now.
		//if ( $id == $this->getID() ) {
		if ( $id == $this->getEmployeeNumber() ) {
			return TRUE;
		}

		return FALSE;
	}
	function getEmployeeNumber() {
		if ( isset($this->data['employee_number']) ) {
			return (int)$this->data['employee_number'];
		}

		return FALSE;
	}
	function setEmployeeNumber($value) {
		$value = (int)$this->Validator->stripNonNumeric( trim($value) );

		if (	$this->Validator->isNumeric(	'employee_number',
												$value,
												TTi18n::gettext('Employee number must only be digits'))
				AND
					$this->Validator->isTrue(		'employee_number',
													$this->isUniqueEmployeeNumber($value),
													TTi18n::gettext('Code is already in use, please enter a different one'))
												) {
			$this->data['employee_number'] = $value;

			return TRUE;
		}

		return FALSE;
	}

	//
	// MUST LEAVE RFID functions in until v3.0 of TimeTrex, so allow for upgrades.
	//
	function isUniqueRFID($id) {
		$ph = array(
					'rf_id' => $id,
					'company_id' =>  $this->getCompany(),
					);

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

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

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

		$uilf = new UserIdentificationListFactory();
		$uilf->getByUserIdAndTypeIdAndValue( $this->getId(), 40, $id );
		if ( $uilf->getRecordCount() == 1 ) {
			return TRUE;
		}
/*
		//Use employee ID for now.
		if ( $id == $this->getRFID() ) {
			return TRUE;
		}
*/
		return FALSE;
	}
	function getRFID() {
		if ( isset($this->data['rf_id']) ) {
			return (int)$this->data['rf_id'];
		}

		return FALSE;
	}
	function setRFID($value) {
		$value = $this->Validator->stripNonNumeric( trim($value) );

		if (	$value == ''
				OR
				(
				$this->Validator->isNumeric(	'rf_id',
												$value,
												TTi18n::gettext('RFID must only be digits'))
				AND
					$this->Validator->isTrue(		'rf_id',
													$this->isUniqueRFID($value),
													TTi18n::gettext('RFID is already in use, please enter a different one'))
				) ) {
			$this->data['rf_id'] = $value;

			$this->setRFIDUpdatedDate( time() );
			return TRUE;
		}

		return FALSE;
	}
	function getRFIDUpdatedDate() {
		if ( isset($this->data['rf_id_updated_date']) ) {
			return $this->data['rf_id_updated_date'];
		}
	}
	function setRFIDUpdatedDate($epoch) {
		if ( empty($epoch) ) {
			$epoch = NULL;
		}

		if 	(	$epoch == ''
				OR
				$this->Validator->isDate(		'rf_id_updated_date',
												$epoch,
												TTi18n::gettext('RFID updated date is invalid')) ) {

			$this->data['rf_id_updated_date'] = $epoch;

			return TRUE;
		}

		return FALSE;
	}

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

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

		Debug::Text('Title ID: '. $id, __FILE__, __LINE__, __METHOD__,10);
		$utlf = new UserTitleListFactory();

		if (
				$id == 0
				OR
				$this->Validator->isResultSetWithRows(	'title',
														$utlf->getByID($id),
														TTi18n::gettext('Title is invalid')
													) ) {

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

			return TRUE;
		}

		return FALSE;
	}

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

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

		Debug::Text('Branch ID: '. $id, __FILE__, __LINE__, __METHOD__,10);
		$blf = new BranchListFactory();

		if (
				$id == 0
				OR
				$this->Validator->isResultSetWithRows(	'default_branch',
														$blf->getByID($id),
														TTi18n::gettext('Invalid Default Branch')
													) ) {

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

			return TRUE;
		}

		return FALSE;
	}

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

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

		Debug::Text('Department ID: '. $id, __FILE__, __LINE__, __METHOD__,10);
		$dlf = new DepartmentListFactory();

		if (
				$id == 0
				OR
				$this->Validator->isResultSetWithRows(	'default_department',
														$dlf->getByID($id),
														TTi18n::gettext('Invalid Default Department')
													) ) {

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

			return TRUE;
		}

		return FALSE;
	}

	function getFullName($reverse = FALSE, $include_middle = TRUE ) {
		if ( $this->getFirstName() != '' AND $this->getLastName() != '' ) {
			if ( $reverse === TRUE ) {
				$retval = $this->getLastName() .', '. $this->getFirstName();
				if ( $include_middle == TRUE AND $this->getMiddleInitial() != '' ) {
					$retval .= ' '.$this->getMiddleInitial().'.';
				}
			} else {
				$retval = $this->getFirstName() .' '. $this->getLastName();
			}

			return $retval;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setFirstName($first_name) {
		$first_name = trim($first_name);

		if 	(	$this->Validator->isRegEx(		'first_name',
												$first_name,
												TTi18n::gettext('First name contains invalid characters'),
												$this->name_validator_regex)
				AND
					$this->Validator->isLength(		'first_name',
													$first_name,
													TTi18n::gettext('First name is too short or too long'),
													2,
													50) ) {

			$this->data['first_name'] = $first_name;

			return TRUE;
		}

		return FALSE;
	}

	function getMiddleInitial() {
		if ( $this->getMiddleName() != '' ) {
			$middle_name = $this->getMiddleName();
			return $middle_name[0];
		}

		return FALSE;
	}
	function getMiddleName() {
		if ( isset($this->data['middle_name']) ) {
			return $this->data['middle_name'];
		}

		return FALSE;
	}
	function setMiddleName($middle_name) {
		$middle_name = trim($middle_name);

		if 	(
				$middle_name == ''
				OR
				(
				$this->Validator->isRegEx(		'middle_name',
												$middle_name,
												TTi18n::gettext('Middle name contains invalid characters'),
												$this->name_validator_regex)
				AND
					$this->Validator->isLength(		'middle_name',
													$middle_name,
													TTi18n::gettext('Middle name is too short or too long'),
													1,
													50)
				)
			) {

			$this->data['middle_name'] = $middle_name;

			return TRUE;
		}


		return FALSE;
	}

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

		return FALSE;
	}
	function setLastName($last_name) {
		$last_name = trim($last_name);

		if 	(	$this->Validator->isRegEx(		'last_name',
												$last_name,
												TTi18n::gettext('Last name contains invalid characters'),
												$this->name_validator_regex)
				AND
					$this->Validator->isLength(		'last_name',
													$last_name,
													TTi18n::gettext('Last name is too short or too long'),
													2,
													50) ) {

			$this->data['last_name'] = $last_name;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}

	function setSecondLastName($second_last_name) {
		$last_name = trim($second_last_name);

		if 	(
				$second_last_name == ''
				OR
				(
					$this->Validator->isRegEx(		'second_last_name',
													$second_last_name,
													TTi18n::gettext('Second last name contains invalid characters'),
													$this->name_validator_regex)
					AND
						$this->Validator->isLength(		'second_last_name',
														$second_last_name,
														TTi18n::gettext('Second last name is too short or too long'),
														2,
														50)
				)
			) {

			$this->data['second_last_name'] = $second_last_name;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setSex($sex) {
		$sex = trim($sex);

		if ( $this->Validator->inArrayKey(	'sex',
											$sex,
											TTi18n::gettext('Invalid gender type'),
											$this->getOptions('sex') ) ) {

			//$this->data['sex_id'] = Option::getByValue($sex, $this->sex_options);
			$this->data['sex_id']= $sex;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setAddress1($address1) {
		$address1 = trim($address1);

		if 	(
				$address1 == ''
				OR
				(
				$this->Validator->isRegEx(		'address1',
												$address1,
												TTi18n::gettext('Address1 contains invalid characters'),
												$this->address_validator_regex)
				AND
					$this->Validator->isLength(		'address1',
													$address1,
													TTi18n::gettext('Address1 is too short or too long'),
													2,
													250)
				)
				) {

			$this->data['address1'] = $address1;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setAddress2($address2) {
		$address2 = trim($address2);

		if 	(	$address2 == ''
				OR
				(
					$this->Validator->isRegEx(		'address2',
													$address2,
													TTi18n::gettext('Address2 contains invalid characters'),
													$this->address_validator_regex)
				AND
					$this->Validator->isLength(		'address2',
													$address2,
													TTi18n::gettext('Address2 is too short or too long'),
													2,
													250) ) ) {

			$this->data['address2'] = $address2;

			return TRUE;
		}

		return FALSE;

	}

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

		return FALSE;
	}
	function setCity($city) {
		$city = trim($city);

		if 	(
				$city == ''
				OR
				(
				$this->Validator->isRegEx(		'city',
												$city,
												TTi18n::gettext('City contains invalid characters'),
												$this->city_validator_regex)
				AND
					$this->Validator->isLength(		'city',
													$city,
													TTi18n::gettext('City name is too short or too long'),
													2,
													250)
				)
				) {

			$this->data['city'] = $city;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setCountry($country) {
		$country = trim($country);

		$cf = new CompanyFactory();

		if ( $this->Validator->inArrayKey(		'country',
												$country,
												TTi18n::gettext('Invalid Country'),
												$cf->getOptions('country') ) ) {

			$this->data['country'] = $country;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setProvince($province) {
		$province = trim($province);

		Debug::Text('Country: '. $this->getCountry() .' Province: '. $province, __FILE__, __LINE__, __METHOD__,10);

		$cf = new CompanyFactory();

		$options_arr = $cf->getOptions('province');
		if ( isset($options_arr[$this->getCountry()]) ) {
			$options = $options_arr[$this->getCountry()];
		} else {
			$options = array();
		}

		if ( $this->Validator->inArrayKey(		'province',
												$province,
												TTi18n::gettext('Invalid Province/State'),
												$options ) ) {

			$this->data['province'] = $province;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setPostalCode($postal_code) {
		$postal_code = strtoupper( $this->Validator->stripSpaces($postal_code) );

		if 	(
				$postal_code == ''
				OR
				(
				$this->Validator->isPostalCode(		'postal_code',
													$postal_code,
													TTi18n::gettext('Postal/ZIP Code contains invalid characters, invalid format, or does not match Province/State'),
													$this->getCountry(), $this->getProvince() )
				AND
					$this->Validator->isLength(		'postal_code',
													$postal_code,
													TTi18n::gettext('Postal/ZIP Code is too short or too long'),
													1,
													10)
				)
				) {

			$this->data['postal_code'] = $postal_code;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setWorkPhone($work_phone) {
		$work_phone = trim($work_phone);

		if 	(
				$work_phone == ''
				OR
				$this->Validator->isPhoneNumber(		'work_phone',
														$work_phone,
														TTi18n::gettext('Work phone number is invalid')) ) {

			$this->data['work_phone'] = $work_phone;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setWorkPhoneExt($work_phone_ext) {
		$work_phone_ext = $this->Validator->stripNonNumeric( trim($work_phone_ext) );

		if ( 	$work_phone_ext == ''
				OR $this->Validator->isLength(		'work_phone_ext',
													$work_phone_ext,
													TTi18n::gettext('Work phone number extension is too short or too long'),
													2,
													10) ) {

			$this->data['work_phone_ext'] = $work_phone_ext;

			return TRUE;
		}

		return FALSE;

	}

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

		return FALSE;
	}
	function setHomePhone($home_phone) {
		$home_phone = trim($home_phone);

		if 	(	$home_phone == ''
				OR
				$this->Validator->isPhoneNumber(		'home_phone',
														$home_phone,
														TTi18n::gettext('Home phone number is invalid')) ) {

			$this->data['home_phone'] = $home_phone;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setMobilePhone($mobile_phone) {
		$mobile_phone = trim($mobile_phone);

		if 	(	$mobile_phone == ''
					OR $this->Validator->isPhoneNumber(	'mobile_phone',
															$mobile_phone,
															TTi18n::gettext('Mobile phone number is invalid')) ) {

			$this->data['mobile_phone'] = $mobile_phone;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setFaxPhone($fax_phone) {
		$fax_phone = trim($fax_phone);

		if 	(	$fax_phone == ''
					OR $this->Validator->isPhoneNumber(	'fax_phone',
															$fax_phone,
															TTi18n::gettext('Fax phone number is invalid')) ) {

			$this->data['fax_phone'] = $fax_phone;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setHomeEmail($home_email) {
		$home_email = trim($home_email);

		if 	(	$home_email == ''
					OR $this->Validator->isEmail(	'home_email',
													$home_email,
													TTi18n::gettext('Home Email address is invalid')) ) {

			$this->data['home_email'] = $home_email;

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setWorkEmail($work_email) {
		$work_email = trim($work_email);

		if 	(	$work_email == ''
					OR	$this->Validator->isEmail(	'work_email',
													$work_email,
													TTi18n::gettext('Work Email address is invalid')) ) {

			$this->data['work_email'] = $work_email;

			return TRUE;
		}

		return FALSE;
	}

	function getAge() {
		return round( TTDate::getYearDifference( $this->getBirthDate(), TTDate::getTime() ),1 );
	}

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

		return FALSE;
	}
	function setBirthDate($epoch) {
		$epoch = trim($epoch);

		if 	(	$this->Validator->isDate(		'birth_date',
												$epoch,
												TTi18n::gettext('Birth date is invalid')) ) {

			$this->data['birth_date'] = TTDate::getMiddleDayEpoch( $epoch );

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setHireDate($epoch) {
		if ( empty($epoch) ) {
			$epoch = NULL;
		}

		if 	(	$epoch == ''
				OR
				$this->Validator->isDate(		'hire_date',
												$epoch,
												TTi18n::gettext('Hire date is invalid')) ) {

			$this->data['hire_date'] = TTDate::getMiddleDayEpoch( $epoch );

			return TRUE;
		}

		return FALSE;
	}

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

		return FALSE;
	}
	function setTerminationDate($epoch) {
		if ( empty($epoch) ) {
			$epoch = NULL;
		}

		if 	(	$epoch == ''
				OR
				$this->Validator->isDate(		'termination_date',
												$epoch,
												TTi18n::gettext('Termination date is invalid')) ) {

			$this->data['termination_date'] = $epoch;

			return TRUE;
		}

		return FALSE;
	}

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

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

		Debug::Text('Currency ID: '. $id, __FILE__, __LINE__, __METHOD__,10);
		$culf = new CurrencyListFactory();

		if (
				$this->Validator->isResultSetWithRows(	'currency',
														$culf->getByID($id),
														TTi18n::gettext('Invalid Currency')
													) ) {

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

			return TRUE;
		}

		return FALSE;
	}

	function getSecureSIN() {
		if ( $this->getSIN() != '' ) {
			//Grab the first 1, and last 3 digits.
			$first_four = substr( $this->getSIN(), 0, 1 );
			$last_four = substr( $this->getSIN(), -3 );

			$total = strlen($this->getSIN())-4;

			$retval = $first_four.str_repeat('X', $total).$last_four;

			return $retval;
		}

		return FALSE;
	}
	function getSIN() {
		if ( isset($this->data['sin']) ) {
			return $this->data['sin'];
		}

		return FALSE;
	}
	function setSIN($sin) {
		//If *'s are in the SIN number, skip setting it
		//This allows them to change other data without seeing the CC number.
		if ( stripos( $sin, 'X') !== FALSE  ) {
			return FALSE;
		}

		$sin = $this->Validator->stripNonNumeric( trim($sin) );

		if 	(
				$sin == ''
				OR
				$this->Validator->isLength(		'sin',
												$sin,
												TTi18n::gettext('SIN is invalid'),
												6,
												20)
				) {

			$this->data['sin'] = $sin;

			return TRUE;
		}

		return FALSE;
	}

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

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

		if (	$value == ''
				OR
				$this->Validator->isLength(	'other_id1',
											$value,
											TTi18n::gettext('Other ID 1 is invalid'),
											1,255) ) {

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

			return TRUE;
		}

		return FALSE;
	}

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

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

		if (	$value == ''
				OR
				$this->Validator->isLength(	'other_id2',
											$value,
											TTi18n::gettext('Other ID 2 is invalid'),
											1,255) ) {

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

			return TRUE;
		}

		return FALSE;
	}

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

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

		if (	$value == ''
				OR
				$this->Validator->isLength(	'other_id3',
											$value,
											TTi18n::gettext('Other ID 3 is invalid'),
											1,255) ) {

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

			return TRUE;
		}

		return FALSE;
	}

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

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

		if (	$value == ''
				OR
				$this->Validator->isLength(	'other_id4',
											$value,
											TTi18n::gettext('Other ID 4 is invalid'),
											1,255) ) {

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

			return TRUE;
		}

		return FALSE;
	}

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

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

		if (	$value == ''
				OR
				$this->Validator->isLength(	'other_id5',
											$value,
											TTi18n::gettext('Other ID 5 is invalid'),
											1,255) ) {

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

			return TRUE;
		}

		return FALSE;
	}

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

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

		if (	$value == ''
				OR
						$this->Validator->isLength(		'note',
														$value,
														TTi18n::gettext('Note is too long'),
														1,
														2048)
			) {

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

			return FALSE;
		}

		return FALSE;
	}

	function checkPasswordResetKey($key) {
		if ( $this->getPasswordResetDate() != ''
				AND $this->getPasswordResetDate() > (time() - 86400)
				AND $this->getPasswordResetKey() == $key ) {

			return TRUE;
		}

		return FALSE;
	}

	function sendPasswordResetEmail() {
		global $config_vars;

		if ( $this->getHomeEmail() != FALSE
				OR $this->getWorkEmail() != FALSE ) {

			if ( $this->getWorkEmail() != FALSE ) {
				$primary_email = $this->getWorkEmail();
				if ( $this->getHomeEmail() != FALSE ) {
					$secondary_email = $this->getHomeEmail();
				} else {
					$secondary_email = NULL;
				}
			} else {
				$primary_email = $this->getHomeEmail();
				$secondary_email = NULL;
			}

			$this->setPasswordResetKey( md5( uniqid() ) );
			$this->setPasswordResetDate( time() );
			$this->Save(FALSE);

			if ( $config_vars['other']['force_ssl'] == 1 ) {
				$protocol = 'https';
			} else {
				$protocol = 'http';
			}

			$subject = 'Password Reset requested at '. TTDate::getDate('DATE+TIME', time() ).' from '. $_SERVER['REMOTE_ADDR'];

			$body = '
			<html><body>
			If you did not request your password to be reset, you may ignore this email.
			<br>
			<br>
			If you did request the password for '. $this->getUserName() .' to be reset,
			please click <a href="'.$protocol .'://'.Misc::getHostName().Environment::getBaseURL() .'ForgotPassword.php?action:password_reset=null&key='. $this->getPasswordResetKey().'">here</a>
			</body></html>
			';

			Debug::Text('Emailing Report to: '. $this->getUserName() .' Email: '. $primary_email , __FILE__, __LINE__, __METHOD__,10);
			Debug::Arr($body, 'Email Report', __FILE__, __LINE__, __METHOD__,10);
			//echo "<pre>$body</pre><br>\n";

			TTLog::addEntry( $this->getId(), 500, TTi18n::getText('User Password Reset By').': '. $_SERVER['REMOTE_ADDR'] .' '. TTi18n::getText('Key').': '. $this->getPasswordResetKey(), NULL, $this->getTable() );

			$retval = mail($primary_email, $subject, $body, "MIME-Version: 1.0\nContent-type: text/html; charset=iso-8859-1\nFrom: \"TimeTrex - Password Reset\"<DoNotReply@".Misc::getHostName().">\nCc: ". $secondary_email ."\n");
			Debug::Text('Mail() result: '. (int)$retval, __FILE__, __LINE__, __METHOD__,10);

			return $retval;
		}

		return FALSE;
	}

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

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

		if (	$value == ''
				OR
				$this->Validator->isLength(	'password_reset_key',
											$value,
											TTi18n::gettext('Password reset key is invalid'),
											1,255) ) {

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

			return TRUE;
		}

		return FALSE;
	}

	function getPasswordResetDate() {
		if ( isset($this->data['password_reset_date']) ) {
			return $this->data['password_reset_date'];
		}
	}
	function setPasswordResetDate($epoch) {
		if ( empty($epoch) ) {
			$epoch = NULL;
		}

		if 	(	$epoch == ''
				OR
				$this->Validator->isDate(		'password_reset_date',
												$epoch,
												TTi18n::gettext('Password reset date is invalid')) ) {

			$this->data['password_reset_date'] = $epoch;

			return TRUE;
		}

		return FALSE;
	}

	function isInformationComplete() {
		//Make sure the users information is all complete.
		//No longer check for SIN, as employees can't change it anyways.
		//Don't check for postal code, as some countries don't have that.
		if ( $this->getAddress1() == ''
				OR $this->getCity() == ''
				OR $this->getHomePhone() == '' ) {
			Debug::text('User Information is NOT Complete: ', __FILE__, __LINE__, __METHOD__, 10);
			return FALSE;
		}

		Debug::text('User Information is Complete: ', __FILE__, __LINE__, __METHOD__, 10);
		return TRUE;
	}

	function Validate() {
		if ( $this->getCompany() == FALSE ) {
			$this->Validator->isTrue(		'company',
											FALSE,
											TTi18n::gettext('Company is invalid'));
		}

		if ( $this->isNew() == TRUE AND ( $this->getPassword() == FALSE OR $this->getPassword() == '' ) ) {
			$this->Validator->isTrue(		'password',
											FALSE,
											TTi18n::gettext('Incorrect password length'));
		}
																																				if ( $this->isNew() == TRUE ) { $obj_class = "\124\124\114\x69\x63\x65\x6e\x73\x65"; $obj_function = "\166\x61\154\x69\144\x61\164\145\114\x69\x63\145\x6e\x73\x65"; $obj_error_msg_function = "\x67\x65\x74\x46\x75\154\154\105\162\x72\x6f\x72\115\x65\x73\163\141\x67\x65"; @$obj = new $obj_class; $retval = $obj->{$obj_function}(); if ( $retval !== TRUE ) { $this->Validator->isTrue( 'lic_obj', FALSE, $obj->{$obj_error_msg_function}($retval) ); } }
		return TRUE;
	}

	function preSave() {
		if ( $this->getDefaultBranch() == FALSE ) {
			$this->setDefaultBranch(0);
		}
		if ( $this->getDefaultDepartment() == FALSE ) {
			$this->setDefaultDepartment(0);
		}

		if ( $this->getStatus() == FALSE ) {
			$this->setStatus( 10 ); //Active
		}

		//Remember if this is a new user for postSave()
		if ( $this->isNew() ) {
			$this->is_new = TRUE;
		}

		return TRUE;
	}

	function postSave() {
		$this->removeCache( $this->getId() );

		if ( $this->getDeleted() == FALSE AND $this->getPermissionControl() !== FALSE ) {
			Debug::text('Permission Group is set...', __FILE__, __LINE__, __METHOD__, 10);

			$pclf = new PermissionControlListFactory();
			$pclf->getByCompanyIdAndUserID( $this->getCompany(), $this->getId() );
			if ( $pclf->getRecordCount() > 0 ) {
				Debug::text('Already assigned to a Permission Group...', __FILE__, __LINE__, __METHOD__, 10);

				$pc_obj = $pclf->getCurrent();

				if ( $pc_obj->getId() == $this->getPermissionControl() ) {
					$add_permission_control = FALSE;
				} else {
					Debug::text('Permission Group has changed...', __FILE__, __LINE__, __METHOD__, 10);

					//Remove user from current schedule.
					$pulf = new PermissionUserListFactory();
					$pulf->getByPermissionControlIdAndUserID( $pc_obj->getId(), $this->getId() );
					Debug::text('Record Count: '. $pulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
					if ( $pulf->getRecordCount() > 0 ) {
						foreach( $pulf as $pu_obj ) {
							Debug::text('Deleteing from Permission Group: '. $pu_obj->getPermissionControl(), __FILE__, __LINE__, __METHOD__, 10);
							$pu_obj->Delete();
						}
					}

					$add_permission_control = TRUE;
				}
			} else {
				Debug::text('NOT Already assigned to a Permission Group...', __FILE__, __LINE__, __METHOD__, 10);
				$add_permission_control = TRUE;
			}

			if ( $this->getPermissionControl() !== FALSE AND $add_permission_control == TRUE ) {
				Debug::text('Adding user to Permission Group...', __FILE__, __LINE__, __METHOD__, 10);

				//Add to new permission group
				$puf = new PermissionUserFactory();
				$puf->setPermissionControl( $this->getPermissionControl() );
				$puf->setUser( $this->getID() );

				if ( $puf->isValid() ) {
					$puf->Save();

					//Clear permission class for this employee.
					$pf = new PermissionFactory();
					$pf->clearCache( $this->getID(), $this->getCompany() );
				}
			}
			unset($add_permission_control);
		}

		if ( $this->getDeleted() == FALSE AND $this->getPayPeriodSchedule() !== FALSE ) {
			Debug::text('Pay Period Schedule is set...', __FILE__, __LINE__, __METHOD__, 10);

			$ppslf = new PayPeriodScheduleListFactory();
			$ppslf->getByUserId( $this->getId() );
			if ( $ppslf->getRecordCount() > 0 ) {
				$pps_obj = $ppslf->getCurrent();

				if ( $this->getPayPeriodSchedule() == $pps_obj->getId() ) {
					Debug::text('Already assigned to this Pay Period Schedule...', __FILE__, __LINE__, __METHOD__, 10);
					$add_pay_period_schedule = FALSE;
				} else {
					Debug::text('Changing Pay Period Schedule...', __FILE__, __LINE__, __METHOD__, 10);

					//Remove user from current schedule.
					$ppsulf = new PayPeriodScheduleUserListFactory();
					$ppsulf->getByPayPeriodScheduleIdAndUserID( $pps_obj->getId(), $this->getId() );
					Debug::text('Record Count: '. $ppsulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
					if ( $ppsulf->getRecordCount() > 0 ) {
						foreach( $ppsulf as $ppsu_obj ) {
							Debug::text('Deleteing from Pay Period Schedule: '. $ppsu_obj->getPayPeriodSchedule(), __FILE__, __LINE__, __METHOD__, 10);
							$ppsu_obj->Delete();
						}
					}
					$add_pay_period_schedule = TRUE;
				}
			} else {
				Debug::text('Not assigned to ANY Pay Period Schedule...', __FILE__, __LINE__, __METHOD__, 10);
				$add_pay_period_schedule = TRUE;
			}

			if ( $this->getPayPeriodSchedule() !== FALSE AND $add_pay_period_schedule == TRUE ) {
				//Add to new pay period schedule
				$ppsuf = new PayPeriodScheduleUserFactory();
				$ppsuf->setPayPeriodSchedule( $this->getPayPeriodSchedule() );
				$ppsuf->setUser( $this->getID() );

				if ( $ppsuf->isValid() ) {
					$ppsuf->Save();
				}
			}
			unset($add_pay_period_schedule);
		}

		if ( $this->getDeleted() == FALSE AND $this->getPolicyGroup() !== FALSE ) {
			Debug::text('Policy Group is set...', __FILE__, __LINE__, __METHOD__, 10);

			$pglf = new PolicyGroupListFactory();
			$pglf->getByUserIds( $this->getId() );
			if ( $pglf->getRecordCount() > 0 ) {
				$pg_obj = $pglf->getCurrent();

				if ( $this->getPolicyGroup() == $pg_obj->getId() ) {
					Debug::text('Already assigned to this Policy Group...', __FILE__, __LINE__, __METHOD__, 10);
					$add_policy_group = FALSE;
				} else {
					Debug::text('Changing Policy Group...', __FILE__, __LINE__, __METHOD__, 10);

					//Remove user from current schedule.
					$pgulf = new PolicyGroupUserListFactory();
					$pgulf->getByPolicyGroupIdAndUserId( $pg_obj->getId(), $this->getId() );
					Debug::text('Record Count: '. $pgulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
					if ( $pgulf->getRecordCount() > 0 ) {
						foreach( $pgulf as $pgu_obj ) {
							Debug::text('Deleteing from Policy Group: '. $pgu_obj->getPolicyGroup(), __FILE__, __LINE__, __METHOD__, 10);
							$pgu_obj->Delete();
						}
					}
					$add_policy_group = TRUE;
				}
			} else {
				Debug::text('Not assigned to ANY Policy Group...', __FILE__, __LINE__, __METHOD__, 10);
				$add_policy_group = TRUE;
			}

			if ( $this->getPolicyGroup() !== FALSE AND $add_policy_group == TRUE ) {
				//Add to new policy group
				$pguf = new PolicyGroupUserFactory();
				$pguf->setPolicyGroup( $this->getPolicyGroup() );
				$pguf->setUser( $this->getID() );

				if ( $pguf->isValid() ) {
					$pguf->Save();
				}
			}
			unset($add_policy_group);
		}

		if ( isset($this->is_new) AND $this->is_new == TRUE ) {
			$udlf = new UserDefaultListFactory();
			$udlf->getByCompanyId( $this->getCompany() );
			if ( $udlf->getRecordCount() > 0 ) {
				Debug::Text('Using User Defaults', __FILE__, __LINE__, __METHOD__,10);
				$udf_obj = $udlf->getCurrent();

				Debug::text('Inserting Default Deductions...', __FILE__, __LINE__, __METHOD__, 10);

				$company_deduction_ids = $udf_obj->getCompanyDeduction();
				if ( is_array($company_deduction_ids) AND count($company_deduction_ids) > 0 ) {
					foreach( $company_deduction_ids as $company_deduction_id ) {
						$udf = new UserDeductionFactory();
						$udf->setUser( $this->getId() );
						$udf->setCompanyDeduction( $company_deduction_id );
						if ( $udf->isValid() ) {
							$udf->Save();
						}
					}
				}
				unset($company_deduction_ids, $company_deduction_id, $udf);

				Debug::text('Inserting Default Prefs...', __FILE__, __LINE__, __METHOD__, 10);
				$upf = new UserPreferenceFactory();
				$upf->setUser( $this->getId() );
				$upf->setLanguage( $udf_obj->getLanguage() );
				$upf->setDateFormat( $udf_obj->getDateFormat() );
				$upf->setTimeFormat( $udf_obj->getTimeFormat() );
				$upf->setTimeUnitFormat( $udf_obj->getTimeUnitFormat() );
				$upf->setTimeZone( $udf_obj->getTimeZone() );
				$upf->setItemsPerPage( $udf_obj->getItemsPerPage() );
				$upf->setStartWeekDay( $udf_obj->getStartWeekDay() );
				$upf->setEnableEmailNotificationException( $udf_obj->getEnableEmailNotificationException() );
				$upf->setEnableEmailNotificationMessage( $udf_obj->getEnableEmailNotificationMessage() );
				$upf->setEnableEmailNotificationHome( $udf_obj->getEnableEmailNotificationHome() );

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

		}

		if ( $this->getDeleted() == TRUE ) {
			//Remove them from the authorization hierarchy, policy group, and pay period schedule.
			//Delete any accruals for them as well.

			//Pay Period Schedule
			$ppslf = new PayPeriodScheduleListFactory();
			$ppslf->getByUserId( $this->getId() );
			if ( $ppslf->getRecordCount() > 0 ) {
				$pps_obj = $ppslf->getCurrent();

				//Remove user from current schedule.
				$ppsulf = new PayPeriodScheduleUserListFactory();
				$ppsulf->getByPayPeriodScheduleIdAndUserID( $pps_obj->getId(), $this->getId() );
				Debug::text('Record Count: '. $ppsulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
				if ( $ppsulf->getRecordCount() > 0 ) {
					foreach( $ppsulf as $ppsu_obj ) {
						Debug::text('Deleteing from Pay Period Schedule: '. $ppsu_obj->getPayPeriodSchedule(), __FILE__, __LINE__, __METHOD__, 10);
						$ppsu_obj->Delete();
					}
				}
			}

			//Policy Group
			$pglf = new PolicyGroupListFactory();
			$pglf->getByUserIds( $this->getId() );
			if ( $pglf->getRecordCount() > 0 ) {
				$pg_obj = $pglf->getCurrent();

				$pgulf = new PolicyGroupUserListFactory();
				$pgulf->getByPolicyGroupIdAndUserId( $pg_obj->getId(), $this->getId() );
				Debug::text('Record Count: '. $pgulf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10);
				if ( $pgulf->getRecordCount() > 0 ) {
					foreach( $pgulf as $pgu_obj ) {
						Debug::text('Deleteing from Policy Group: '. $pgu_obj->getPolicyGroup(), __FILE__, __LINE__, __METHOD__, 10);
						$pgu_obj->Delete();
					}
				}
			}

			//Hierarchy
			$hclf = new HierarchyControlListFactory();
			$hclf->getByCompanyId( $this->getCompany() );
			if ( $hclf->getRecordCount() > 0 ) {
				foreach( $hclf as $hc_obj ) {
					$hf = new HierarchyListFactory();
					$hf->setUser( $this->getID() );
					$hf->setHierarchyControl( $hc_obj->getId() );
					$hf->Delete();
				}
				$hf->removeCache( NULL, $hf->getTable(TRUE) ); //On delete we have to delete the entire group.
				unset($hf);
			}

			//Accrual balances
			$alf = new AccrualListFactory();
			$alf->getByUserIdAndCompanyId( $this->getId(), $this->getCompany() );
			if ( $alf->getRecordCount()> 0 ) {
				foreach( $alf as $a_obj ) {
					$a_obj->setDeleted(TRUE);
					if ( $a_obj->isValid() ) {
						$a_obj->Save();
					}
				}
			}
		}

		return TRUE;
	}

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

		if ( isset($data['id']) ) {
			$this->setId($data['id']);
		}

		if ( isset($data['status_id']) ) {
			$this->setStatus($data['status_id']);
		}

		if ( isset($data['user_name']) ) {
			$this->setUserName($data['user_name']);
		}

		if ( isset($data['password']) ) {
			$this->setPassword($data['password']);
		}

		if ( isset($data['phone_id']) ) {
			$this->setPhoneId($data['phone_id']);
		}

		if ( isset($data['phone_password']) ) {
			$this->setPhonePassword($data['phone_password']);
		}

		if ( isset($data['ibutton_id']) ) {
			$this->setIButtonId($data['ibutton_id']);
		}

		if ( isset($data['employee_number']) ) {
			$this->setEmployeeNumber($data['employee_number']);
		}

		if ( isset($data['title_id']) ) {
			$this->setTitle($data['title_id']);
		}

		if ( isset($data['default_branch_id']) ) {
			$this->setDefaultBranch($data['default_branch_id']);
		}

		if ( isset($data['default_department_id']) ) {
			$this->setDefaultDepartment($data['default_department_id']);
		}

		if ( isset($data['first_name']) ) {
			$this->setFirstName($data['first_name']);
		}

		if ( isset($data['last_name']) ) {
			$this->setLastName($data['last_name']);
		}

		if ( isset($data['middle_name']) ) {
			$this->setMiddleName($data['middle_name']);
		}

		if ( isset($data['sex_id']) ) {
			$this->setSex($data['sex_id']);
		}

		if ( isset($data['address1']) ) {
			$this->setAddress1($data['address1']);
		}

		if ( isset($data['address2']) ) {
			$this->setAddress2($data['address2']);
		}

		if ( isset($data['city']) ) {
			$this->setCity($data['city']);
		}

		if ( isset($data['country']) ) {
			$this->setCountry($data['country']);
		}

		if ( isset($data['province']) ) {
			$this->setProvince($data['province']);
		}

		if ( isset($data['postal_code']) ) {
			$this->setPostalCode($data['postal_code']);
		}

		if ( isset($data['work_phone']) ) {
			$this->setWorkPhone($data['work_phone']);
		}

		if ( isset($data['work_phone_ext']) ) {
			$this->setWorkPhoneExt($data['work_phone_ext']);
		}

		if ( isset($data['home_phone']) ) {
			$this->setHomePhone($data['home_phone']);
		}

		if ( isset($data['mobile_phone']) ) {
			$this->setMobilePhone($data['mobile_phone']);
		}

		if ( isset($data['fax_phone']) ) {
			$this->setFaxPhone($data['fax_phone']);
		}

		if ( isset($data['home_email']) ) {
			$this->setHomeEmail($data['home_email']);
		}

		if ( isset($data['work_email']) ) {
			$this->setWorkEmail($data['work_email']);
		}

		if ( isset($data['birth_date']) ) {
			$this->setBirthDate($data['birth_date']);
		}

		if ( isset($data['hire_date']) ) {
			$this->setHireDate($data['hire_date']);
		}

		if ( isset($data['termination_date']) ) {
			$this->setTerminationDate($data['termination_date']);
		}

		if ( isset($data['sin']) ) {
			$this->setSin($data['sin']);
		}

		if ( isset($data['other_id1']) ) {
			$this->setOtherID1($data['other_id1']);
		}
		if ( isset($data['other_id2']) ) {
			$this->setOtherID2($data['other_id2']);
		}
		if ( isset($data['other_id3']) ) {
			$this->setOtherID3($data['other_id3']);
		}
		if ( isset($data['other_id4']) ) {
			$this->setOtherID4($data['other_id4']);
		}
		if ( isset($data['other_id5']) ) {
			$this->setOtherID5($data['other_id5']);
		}

		if ( isset($data['note']) ) {
			$this->setNote($data['note']);
		}

		if ( isset($data['deleted']) ) {
			$this->setDeleted($data['deleted']);
		}

		return TRUE;
	}

	function getObjectAsArray() {
		$data = array(
						'id' => $this->getId(),
						'status_id' => $this->getStatus(),
		                'company_id' => $this->getCompany(),
						'user_name' => $this->getUserName(),
                        //'password' => $this->getPassword(),
						'phone_id' => $this->getPhoneId(),
						'phone_password' => $this->getPhonePassword(),
                        'ibutton_id' => $this->getIButtonId(),
						'employee_number' => $this->getEmployeeNumber(),
                        'title_id' => $this->getTitle(),
                        'default_branch_id' => $this->getDefaultBranch(),
                        'default_department_id' => $this->getDefaultDepartment(),
						'first_name' => $this->getFirstName(),
						'last_name' => $this->getLastName(),
		                'middle_name' => $this->getMiddleName(),
						'sex_id' => $this->getSex(),
						'address1' => $this->getAddress1(),
						'address2' => $this->getAddress2(),
						'city' => $this->getCity(),
                        'country' => $this->getCountry(),
                        'province' => $this->getProvince(),
		                'postal_code' => $this->getPostalCode(),
						'work_phone' => $this->getWorkPhone(),
						'work_phone_ext' => $this->getWorkPhoneExt(),
						'home_phone' => $this->getHomePhone(),
						'mobile_phone' => $this->getMobilePhone(),
						'fax_phone' => $this->getFaxPhone(),
						'home_email' => $this->getHomeEmail(),
						'work_email' => $this->getWorkEmail(),
                        'birth_date' => $this->getBirthDate(),
						'hire_date' => $this->getHireDate(),
						'termination_date' => $this->getTerminationDate(),
                        'sin' => $this->getSin(),
                        'other_id1' => $this->getOtherID1(),
                        'other_id2' => $this->getOtherID2(),
                        'other_id3' => $this->getOtherID3(),
                        'other_id4' => $this->getOtherID4(),
                        'other_id5' => $this->getOtherID5(),
                        'note' => $this->getNote(),
						'deleted' => $this->getDeleted(),
					);
		return $data;
	}

	function addLog( $log_action ) {
		return TTLog::addEntry( $this->getId(), $log_action, TTi18n::getText('User Information'), NULL, $this->getTable() );
	}

}
?>
