<?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: 1782 $
 * $Id: TimeTrexSoapServer.class.php 1782 2008-03-28 22:21:07Z ipso $
 * $Date: 2008-03-28 15:21:07 -0700 (Fri, 28 Mar 2008) $
 */
class TimeTrexSoapServer extends TimeTrexSoapServerUnAuthenticated {
	var $authentication = NULL;
	var $permission_obj = NULL;

	var $user_obj = NULL;
	var $company_obj = NULL;
	var $schedule_shift_obj = NULL;
	var $shift_obj = NULL;
	var $station_type = NULL;

	function __construct() {
		global $authentication, $current_user, $current_company, $current_station;

		$this->authentication = $authentication;

		$this->permission_obj = new Permission();

		$this->user_obj = $authentication->getObject();

		$current_user = $this->getUserObject();
		$current_company = $this->getCompanyObject();

		//Set Date Prefs
		$current_user->getUserPreferenceObject()->setDateTimePreferences();

		return TRUE;
	}

	function getUserObject() {
		return $this->user_obj;
	}

	function getStationObject() {
		//Debug::Arr($_GET, 'Station ID NOT Array ', __FILE__, __LINE__, __METHOD__, 10);
		if ( $_GET['StationID'] == '' ) {
			Debug::text('Station ID NOT SET! '. $_GET['StationID'], __FILE__, __LINE__, __METHOD__, 10);
			return FALSE;
		}

		$slf = new StationListFactory();
		$slf->getByStationIdandCompanyId( $_GET['StationID'], $this->getCompanyObject()->getId() );
		$current_station = $slf->getCurrent();
		unset($slf);

		return $current_station;
	}

	function getCompanyObject() {
		$clf = new CompanyListFactory();
		$current_company = $clf->getByID( $this->getUserObject()->getCompany() )->getCurrent();

		return $current_company;
	}

	function getScheduleShiftObject() {
		$sslf = new ScheduleShiftListFactory();
		$schedule_shift_obj = $sslf->getByUserIdAndCurrentScheduleShift( $this->getUserObject()->getId() )->getCurrent();

		Debug::text('Schedule Shift ID: '. $schedule_shift_obj->getId(), __FILE__, __LINE__, __METHOD__, 10);

		return $schedule_shift_obj;
	}

	function getPermissionObject() {
		return $this->permission_obj;
	}

	function helloworld2($text) {
		return "Hello World22: $text - ". $this->getUserFullName() ."";
	}

	function StationCheckAllowed() {
		if ( is_object( $this->getStationObject() ) ) {
			return $this->getStationObject()->checkAllowed( $this->getUserObject()->getId(), $this->getStationObject()->getStation(), $this->getStationObject()->getType() );
		}

		return FALSE;
	}

	function setStation($source, $station, $description = NULL, $type = 'PHONE') {
		Debug::text('Setting Station: ('. $station .') Source: '. $source .' Description: '. $description .' Type: '. $type, __FILE__, __LINE__, __METHOD__, 10);
		if ($source == '') {
			$source = 'Unavailable';
		}

		if ( $description == '' ) {
			$description = 'N/A';
		}

		if ($source == '') {
			$source = NULL;
		}

		//We using SOAP, we always have the IP address, always set it unless we're using
		//the phone punch in.
		if ( strtolower(trim($type)) != 'phone') {
			$source = $_SERVER['REMOTE_ADDR'];
		}

		$slf = new StationListFactory();
		$slf->getByStationIdandCompanyId( $station, $this->getCompanyObject()->getId() );
		$current_station = $slf->getCurrent();
		unset($slf);

		if ( $current_station->isNew() ) {
			Debug::text('Station not found... Adding new one...', __FILE__, __LINE__, __METHOD__, 10);

			$sf = new StationFactory();

			$sf->setCompany( $this->getCompanyObject()->getId() );
			$sf->setStatus( 'ENABLED' );
			$sf->setType( $type );
			$sf->setSource( $source );
			$sf->setStation( $station );
			$sf->setDescription( $description );

			//If this is a new iButton,Fingerprint, or Barcode station, default to allow all employees.
			if ( in_array( $sf->getType(), array(30,40,50) ) ) {
				$sf->setGroupSelectionType( 10 );
				$sf->setBranchSelectionType( 10 );
				$sf->setDepartmentSelectionType( 10 );
			}

			if ( $sf->isValid() ) {
				if ( $sf->Save(FALSE) ) {
					//return $source;
					return $sf->getStation();
				}
			}
		} else {
			Debug::text('Station FOUND!', __FILE__, __LINE__, __METHOD__, 10);
			return $current_station->getStation();
		}

		return FALSE;
	}

	function getUserFullName() {
		return $this->getUserObject()->getFullName();
	}

	function getEnrollUsers() {
		//Check to make sure the logged in user has edit_advance permissions
		if ( $this->getPermissionObject()->Check('user','enroll') ) {
			$ulf = new UserListFactory();
			$user_list = $ulf->getByCompanyIdArray( $this->getUserObject()->getCompany(), FALSE, FALSE);

			//For ease in Java.
			$user_list= array_flip($user_list);

			return $user_list;
		}

		return FALSE;
	}


	function enroll($user_id, $id, $type = 'iButton') {
		Debug::text('User ID : '. $user_id .' ID: '. substr($id,0,100) .' Type: '. $type, __FILE__, __LINE__, __METHOD__, 10);

		$user_id = trim($user_id);
		$id = trim($id);
		$type = strtolower($type);

		//Fingerprints can send $id=NULL to clear an enrollment.
		if ( strpos( $type, 'finger_print' ) === FALSE AND $id == '') {
			Debug::text('ID is not valid: '. $id, __FILE__, __LINE__, __METHOD__, 10);
			return FALSE;
		}

		//Check to make sure the logged in user has edit_advance permissions
		if ( $this->getPermissionObject()->Check('user','enroll') ) {
			Debug::text('User : '. $this->getUserObject()->getFullName() .' has Enroll permission', __FILE__, __LINE__, __METHOD__, 10);

			$ulf = new UserListFactory();

			switch( $type ) {
				case 'finger_print_1':
				case 'finger_print_2':
				case 'finger_print_3':
				case 'finger_print_4':
					//$enroll_user_obj = $ulf->getByUserNameAndCompanyId( $user_name, $this->getUserObject()->getCompany() );
					$enroll_user_obj = $ulf->getByIdAndCompanyId( $user_id, $this->getUserObject()->getCompany() );

					if ( $enroll_user_obj->getRecordCount() == 1 ) {
						Debug::text('Enroller User ID : '. $user_id .' FOUND', __FILE__, __LINE__, __METHOD__, 10);

						$enroll_user_obj = $enroll_user_obj->getCurrent();

						//Update finger_print
						switch ( $type ) {
							case 'finger_print_1':
								$enroll_user_obj->setFingerPrint1( $id );
								break;
							case 'finger_print_2':
								$enroll_user_obj->setFingerPrint2( $id );
								break;
							case 'finger_print_3':
								$enroll_user_obj->setFingerPrint3( $id );
								break;
							case 'finger_print_4':
								$enroll_user_obj->setFingerPrint4( $id );
								break;
						}

						if ( $enroll_user_obj->isValid() ) {
							if ( $enroll_user_obj->save() ) {
								return TRUE;
							}
						}

						Debug::text('Enroll User Object not valid : '. $user_id, __FILE__, __LINE__, __METHOD__, 10);
					} else {
						Debug::text('User ID : '. $user_id .' NOT FOUND', __FILE__, __LINE__, __METHOD__, 10);
					}

					break;
				case 'ibutton':
					//Remove ibutton from current user.
					$ulf->getByCompanyIDAndIButtonId( $this->getUserObject()->getCompany(), $id );
					if ( $ulf->getRecordCount() > 0 ) {
						$old_user_obj = $ulf->getCurrent();

						Debug::text('Removing iButton ID from User: '. $old_user_obj->getUserName(), __FILE__, __LINE__, __METHOD__, 10);
						$old_user_obj->setIButtonID(NULL);
						if ( $old_user_obj->isValid() ) {
							$old_user_obj->Save();
						}

						unset($old_user_obj);
					} else {
						Debug::text('Didnt find current user with iButton assigned...', __FILE__, __LINE__, __METHOD__, 10);
					}

					//$enroll_user_obj = $ulf->getByUserNameAndCompanyId( $user_name, $this->getUserObject()->getCompany() );
					$enroll_user_obj = $ulf->getByIdAndCompanyId( $user_id, $this->getUserObject()->getCompany() );

					if ( $enroll_user_obj->getRecordCount() == 1 ) {
						Debug::text('Enroller User ID : '. $user_id .' FOUND', __FILE__, __LINE__, __METHOD__, 10);

						$enroll_user_obj = $enroll_user_obj->getCurrent();

						//Update ibutton id.
						$enroll_user_obj->setIButtonID( $id );
						if ( $enroll_user_obj->isValid() ) {
							if ( $enroll_user_obj->save() ) {
								return TRUE;
							}
						}

						Debug::text('Enroll User Object not valid : '. $user_id, __FILE__, __LINE__, __METHOD__, 10);
					} else {
						Debug::text('User ID : '. $user_id .' NOT FOUND', __FILE__, __LINE__, __METHOD__, 10);
					}

					break;
			}
		} else {
			Debug::text('User : '. $this->getUserObject()->getFullName() .' DOES NOT HAVE edit advance permission', __FILE__, __LINE__, __METHOD__, 10);
		}

		return FALSE;
	}

	function getPunchData() {
		if ( $this->StationCheckAllowed() !== TRUE) {
			Debug::text('Station NOT allowed: ', __FILE__, __LINE__, __METHOD__, 10);
			return FALSE;
		}

		$epoch = TTDate::getTime();

		$slf = new ScheduleListFactory();

		//Get last punch for this day, for this user.
		$plf = new PunchListFactory();
		$plf->getPreviousPunchByUserIDAndEpoch( $this->getUserObject()->getId(), $epoch );
		if ($plf->getRecordCount() > 0 ) {
			$prev_punch_obj = $plf->getCurrent();
			Debug::Text(' Found Previous Punch within Continuous Time from now, ID: '. $prev_punch_obj->getId(), __FILE__, __LINE__, __METHOD__,10);

			$branch_id = $prev_punch_obj->getPunchControlObject()->getBranch();
			$department_id = $prev_punch_obj->getPunchControlObject()->getDepartment();
			$job_id = $prev_punch_obj->getPunchControlObject()->getJob();
			$job_item_id = $prev_punch_obj->getPunchControlObject()->getJobItem();

			if ( $branch_id == '' OR empty($branch_id)
					OR $department_id == '' OR empty($department_id)
					OR $job_id == '' OR empty($job_id)
					OR $job_item_id == '' OR empty($job_item_id) ) {
				Debug::Text(' Branch or department are null. ', __FILE__, __LINE__, __METHOD__,10);

				$s_obj = $slf->getScheduleObjectByUserIdAndEpoch( $this->getUserObject()->getId(), $epoch );

				if ( is_object($s_obj) ) {
					Debug::Text(' Found Schedule!: ', __FILE__, __LINE__, __METHOD__,10);

					if ( $branch_id == '' OR empty($branch_id) ) {
						Debug::Text(' overrriding branch: '. $s_obj->getBranch(), __FILE__, __LINE__, __METHOD__,10);
						$branch_id = $s_obj->getBranch();
					}
					if ( $department_id == '' OR empty($department_id) ) {
						Debug::Text(' overrriding department: '. $s_obj->getDepartment(), __FILE__, __LINE__, __METHOD__,10);
						$department_id = $s_obj->getDepartment();
					}

					if ( $job_id == '' OR empty($job_id) ) {
						Debug::Text(' overrriding job: '. $s_obj->getJob(), __FILE__, __LINE__, __METHOD__,10);
						$job_id = $s_obj->getJob();
					}
					if ( $job_item_id == '' OR empty($job_item_id) ) {
						Debug::Text(' overrriding job item: '. $s_obj->getJobItem(), __FILE__, __LINE__, __METHOD__,10);
						$job_item_id = $s_obj->getJobItem();
					}
				}
			}

			$next_type = $prev_punch_obj->getNextType();

			//CHeck for meal policy window.
			$prev_punch_obj->setScheduleID( $epoch );
			if ( is_object( $prev_punch_obj->getScheduleObject() )
					AND is_object($prev_punch_obj->getScheduleObject()->getSchedulePolicyObject() )
					AND is_object($prev_punch_obj->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject() )
					AND $prev_punch_obj->getType() != 20 ) {
				Debug::Text(' Found Schedule Meal Policy Object: Start Window: '. $prev_punch_obj->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getStartWindow(), __FILE__, __LINE__, __METHOD__,10);

				if ( $epoch >= ($prev_punch_obj->getScheduleObject()->getStartTime() + $prev_punch_obj->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getStartWindow() )
						AND $epoch <= ($prev_punch_obj->getScheduleObject()->getStartTime() + $prev_punch_obj->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getStartWindow() + $prev_punch_obj->getScheduleObject()->getSchedulePolicyObject()->getMealPolicyObject()->getWindowLength() ) ) {
					Debug::Text(' Setting Type to Lunch: ', __FILE__, __LINE__, __METHOD__,10);
					$next_type = 20;
				}
			} elseif ( is_object($prev_punch_obj) AND $prev_punch_obj->getType() != 20 ) {
				//Check NON-scheduled meal policies
				$mplf = new MealPolicyListFactory();
				$mplf->getByPolicyGroupUserId( $this->getUserObject()->getId() );
				if ( $mplf->getRecordCount() > 0 ) {
					$mp_obj = $mplf->getCurrent();
					Debug::Text(' Found NON Schedule Meal Policy start Window: '. $mp_obj->getStartWindow(), __FILE__, __LINE__, __METHOD__,10);

					if ( $epoch >= ($prev_punch_obj->getTimeStamp() + $mp_obj->getStartWindow())
							AND $epoch <= ($prev_punch_obj->getTimeStamp() + $mp_obj->getStartWindow() + $mp_obj->getWindowLength() ) ) {
						Debug::Text(' Setting Type to Lunch: ', __FILE__, __LINE__, __METHOD__,10);
						$next_type = 20;
					}
				} else {
					Debug::Text(' DID NOT Find NON Schedule Meal Policy start Window: ', __FILE__, __LINE__, __METHOD__,10);
				}
				unset($mplf, $mp_obj);
			}

			Debug::Text(' cJob Item ID: '. $job_item_id, __FILE__, __LINE__, __METHOD__,10);

			$data = array(
							'user_id' => (int)$this->getUserObject()->getId(),
							'user_full_name' => $this->getUserObject()->getFullName(),
							'time_stamp' => TTDate::getDate('TIME', $epoch),
							'date_stamp' => TTDate::getDate('DATE', $epoch),
							'full_time_stamp' => $epoch,
							'branch_id' => (int)$branch_id,
							'department_id' => (int)$department_id,
							'job_id' => $job_id,
							'job_item_id' => $job_item_id,
							'quantity' => $prev_punch_obj->getPunchControlObject()->getQuantity(),
							'bad_quantity' => $prev_punch_obj->getPunchControlObject()->getBadQuantity(),
							'note' => $prev_punch_obj->getPunchControlObject()->getNote(),
							'other_id1' => $prev_punch_obj->getPunchControlObject()->getOtherID1(),
							'other_id2' => $prev_punch_obj->getPunchControlObject()->getOtherID2(),
							'other_id3' => $prev_punch_obj->getPunchControlObject()->getOtherID3(),
							'other_id4' => $prev_punch_obj->getPunchControlObject()->getOtherID4(),
							'other_id5' => $prev_punch_obj->getPunchControlObject()->getOtherID5(),
							'status_id' => (int)$prev_punch_obj->getNextStatus(),
							'type_id' => (int)$next_type,
							'punch_control_id' => (int)$prev_punch_obj->getNextPunchControlID(),
							//'user_date_id' => (int)$prev_punch_obj->getPunchControlObject()->getUserDateID()
							);

		} else {
			Debug::Text(' DID NOT Find Previous Punch within Continuous Time from now: ', __FILE__, __LINE__, __METHOD__,10);
			$branch_id = NULL;
			$department_id = NULL;
			$job_id = NULL;
			$job_item_id = NULL;

			$s_obj = $slf->getScheduleObjectByUserIdAndEpoch( $this->getUserObject()->getId(), $epoch );
			if ( is_object($s_obj) ) {
				Debug::Text(' Found Schedule! ID:'. $s_obj->getID() .' Job ID: '. $s_obj->getJob(), __FILE__, __LINE__, __METHOD__,10);
				$branch_id = $s_obj->getBranch();
				$department_id = $s_obj->getDepartment();
				$job_id = $s_obj->getJob();
				$job_item_id = $s_obj->getJobItem();
			} else {
				//Check for defaults
				$branch_id = $this->getUserObject()->getDefaultBranch();
				$department_id = $this->getUserObject()->getDefaultDepartment();
			}

			$data = array(
							'user_id' => (int)$this->getUserObject()->getId(),
							'user_full_name' => $this->getUserObject()->getFullName(),
							'time_stamp' => TTDate::getDate('TIME', $epoch),
							'date_stamp' => TTDate::getDate('DATE', $epoch),
							'branch_id' => (int)$branch_id,
							'department_id' => (int)$department_id,
							'job_id' => $job_id,
							'job_item_id' => $job_item_id,
							'status_id' => 10, //In
							'type_id' => 10, //Normal
							);
		}

		//Get options.
		$blf = new BranchListFactory();
		$branch_options = $blf->getByCompanyIdArray( $this->getCompanyObject()->getId() );

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

		$job_options = array();
		$job_item_options = array();
		if ( getTTProductEdition() == TT_PRODUCT_PROFESSIONAL ) {
			$jlf = new JobListFactory();
			$job_options = $jlf->getByCompanyIdAndUserIdAndStatusArray( $this->getCompanyObject()->getId(),  $this->getUserObject()->getId(), array(10), TRUE );

			$jilf = new JobItemListFactory();
			$job_item_options = $jilf->getByCompanyIdArray( $this->getCompanyObject()->getId(), TRUE );
		}

		$pf = new PunchFactory();

		//Select box options;
		$data['status_options'] = $pf->getOptions('status');
		$data['type_options'] = $pf->getOptions('type');
		$data['branch_options'] = $branch_options;
		$data['department_options'] = $department_options;
		$data['job_options'] = $job_options;
		$data['job_item_options'] = $job_item_options;

		//Hack for PHP v5.0.4 shotty SOAP.
		//If it can cast the first array key to a INT, it rekeys the entire array.
		$data['status_options'] = Misc::prependArray( array('_' => NULL ), $data['status_options'] );
		$data['type_options'] = Misc::prependArray( array('_' => NULL ), $data['type_options'] );
		$data['branch_options'] = Misc::prependArray( array('_' => NULL ), $data['branch_options'] );
		$data['department_options'] = Misc::prependArray( array('_' => NULL ), $data['department_options'] );
		$data['job_options'] = Misc::prependArray( array('_' => NULL ), $data['job_options'] );
		$data['job_item_options'] = Misc::prependArray( array('_' => NULL ), $data['job_item_options'] );

		$data['timeout'] = 5;
		$data['date_format_example'] = (string)$this->getUserObject()->getUserPreferenceObject()->getDateFormatExample();
		$data['time_format_example'] = (string)$this->getUserObject()->getUserPreferenceObject()->getTimeFormatExample();
		//Debug::Arr($data, 'punchDataArray', __FILE__, __LINE__, __METHOD__,10);

		if ( !$this->getPermissionObject()->Check('job', 'enabled') ) {
			unset($data['job_options']);
			unset($data['job_item_options']);
		}

		//Debug::Arr($data, 'Return Data: ', __FILE__, __LINE__, __METHOD__,10);

		return $data;
		//return array(  10 => 'Test1', 20 => 'Test2');
		//return array(  '10' => 'Test1', '20' => 'Test2');
		//return array(  '_' => '', 10 => 'Test1', 20 => 'Test2');
		//return array(  '_' => NULL, 10 => 'Test1', 20 => 'Test2');
		//return $data['status_options'];
	}

	function setPunchData($data) {
		//Debug::Arr($data, 'punchDataArray', __FILE__, __LINE__, __METHOD__,10);
		/*
		<b>TimeTrexSoapServer::setPunchData()</b>:  Data:  <pre> array(10) {
		["date_stamp"]=>   string(9) "05-Nov-05"
		["transfer"]=>   int(0)
		["branch_id"]=>   string(1) "0"
		["time_stamp"]=>   string(7) "4:42 PM"
		["user_date_id"]=>   string(5) "14774"
		["punch_control_id"]=>   string(5) "26614"
		["type_id"]=>   string(2) "10"
		["department_id"]=>   string(1) "0"
		["status_id"]=>   string(2) "20"
		["user_id"]=>   string(1) "1" } </pre><br>
		*/
		//Debug::Arr($data, ' Data: ', __FILE__, __LINE__, __METHOD__,10);

		//User prefs should be set before we parse the date/time.
		$punch_full_time_stamp = TTDate::strtotime($data['date_stamp'].' '.$data['time_stamp']);
		Debug::Text(' Punch Full TimeStamp: '. date('r'. $punch_full_time_stamp) .'('.$punch_full_time_stamp.') TimeZone: '. $this->getUserObject()->getUserPreferenceObject()->getTimeZone(), __FILE__, __LINE__, __METHOD__,10);

		$pcf = new PunchControlFactory();
		$pf = new PunchFactory();

		$pf->StartTransaction();

		if ( isset($data['status_id']) AND $data['status_id'] == 20 ) { //Out
			if ( isset($data['punch_control_id']) ) {
				$pcf->setId( $data['punch_control_id'] );
			}
		} else {
			$data['status_id'] = 10; // In
		}

		if ( isset($data['transfer']) AND $data['transfer'] == 1 ) {
			Debug::Text(' Enabling Transfer!: ', __FILE__, __LINE__, __METHOD__,10);
			$data['type_id'] = 10;
			$data['status_id'] = 10;
		}

		if ( !isset($data['user_date_id']) OR $data['user_date_id'] == '' ) {
			$pcf->findUserDate( $this->getUserObject()->getId(), $punch_full_time_stamp, $data['status_id'] );
		} else {
			$pcf->setUserDateID( $data['user_date_id'] );
		}

		//Debug::Text(' Branch ID: '. $data['branch_id'], __FILE__, __LINE__, __METHOD__,10);
		if ( isset($data['branch_id']) AND $data['branch_id'] != '') {
			$pcf->setBranch( $data['branch_id'] );
		}
		if ( isset($data['department_id']) AND $data['department_id'] != '' ) {
			$pcf->setDepartment( $data['department_id'] );
		}

		if ( isset($data['job_id']) AND $data['job_id'] != '' ) {
			$pcf->setJob( $data['job_id'] );
		}
		if ( isset($data['job_item_id']) AND $data['job_item_id'] != '') {
			$pcf->setJobItem( $data['job_item_id'] );
		}
		if ( isset($data['quantity']) AND $data['quantity'] != '' ) {
			$pcf->setQuantity( $data['quantity'] );
		}
		if ( isset($data['bad_quantity']) AND $data['bad_quantity'] != '' ) {
			$pcf->setBadQuantity( $data['bad_quantity'] );
		}

		//Don't overwrite note if a new one isn't set. This makes it more difficult to delete a note if they want to,
		//But thats better then accidently deleting it.
		if ( isset($data['note']) AND $data['note'] != '' ) {
			$pcf->setNote( $data['note'] );
		}

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

		if ( $pcf->isValid() ) {
			$punch_control_id = $pcf->Save();

			//If its an update, not a new insert
			if ( $punch_control_id === TRUE ) {
				Debug::Text(' Updating Punch Control Object', __FILE__, __LINE__, __METHOD__,10);
				$punch_control_id = $data['punch_control_id'];
			}
			Debug::Text(' Punch Control ID: '. $punch_control_id, __FILE__, __LINE__, __METHOD__,10);

			if ( isset($data['transfer']) AND $data['transfer'] == 1 ) {
				Debug::Text(' Enabling Transfer!: ', __FILE__, __LINE__, __METHOD__,10);
				$pf->setTransfer( TRUE );
			}

			$pf->setPunchControlID( $punch_control_id );
			$pf->setType( $data['type_id'] );
			$pf->setStatus( $data['status_id'] );
			$pf->setTimeStamp( $punch_full_time_stamp );

			if ( $pf->isNew() ) {
				$pf->setActualTimeStamp( $punch_full_time_stamp );
				$pf->setOriginalTimeStamp( $pf->getTimeStamp() );
			}

			$pf->setStation( $this->getStationObject()->getId() );

			if ( $pf->isValid() ) {
				$return_date = $pf->getTimeStamp();
				if ( $pf->getStatus() == 10 ) {
					$label = 'In';
				} else {
					$label = 'Out';
				}

				$pf->setEnableCalcTotalTime( TRUE );
				$pf->setEnableCalcSystemTotalTime( TRUE );
				$pf->setEnableCalcUserDateTotal( TRUE );
				$pf->setEnableCalcException( TRUE );
				$pf->setEnablePreMatureException( TRUE );

				$pf->Save();

				Debug::text('Return Date: '. $return_date, __FILE__, __LINE__, __METHOD__, 10);
				$retval = '<div style="font-size:28px; font-weight: bold">
				<table>
				<tr>
					<td>'.$this->getUserObject()->getFullName() .'</td>
				</tr>
				<tr>
					<td>
					Punch '.$label.': '. TTDate::getDate('TIME', $return_date) .'
					</td>
				</tr>
				</table>
				</div>';

				//Mike Benoit - Start Lunch: <time>
				//$retval = '<div style="font-size:28px" nowrap>'.$this->getUserObject()->getFullName() ."\n".$label.': <div style="color: '.$color.'" nowrap>'. TTDate::getDate('TIME', $return_date) .'</div></div>';

				Debug::text('RetVal: '. $retval, __FILE__, __LINE__, __METHOD__, 10);

				//Set stations last punch time stamp so we can filter out duplicates later on.
				/*
				$this->getStationObject()->setLastPunchTimeStamp( $punch_full_time_stamp );
				if ( $this->getStationObject()->isValid() ) {
					$this->getStationObject()->Save(FALSE);
				}
				*/

				$pf->CommitTransaction();

				return $retval;

			} else {
				Debug::text('Punch is NOT VALID: ', __FILE__, __LINE__, __METHOD__, 10);
			}
		}

		$pf->FailTransaction();

		Debug::text('Returning FALSE: Action Failed! ', __FILE__, __LINE__, __METHOD__, 10);
		return FALSE;


		//return "FAILED...John Doe Signed in at 8:00AM";
//		return "John Doe Signed in at 8:00AM";
	}


	function Logout() {
		return $this->authentication->Logout();
	}

	function addLogEntry( $object_id, $action_id, $description, $user_id, $table ) {
		TTLog::addEntry( $object_id, $action_id, $description, $user_id, $table );
	}
}
?>
