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

/**
 * @package Module_Holiday
 */
class HolidayFactory extends Factory {
	protected $table = 'holidays';
	protected $pk_sequence_name = 'holidays_id_seq'; //PK Sequence name

	protected $holiday_policy_obj = NULL;
	function getHolidayPolicyObject() {
		if ( is_object($this->holiday_policy_obj) ) {
			return $this->holiday_policy_obj;
		} else {

			$hplf = new HolidayPolicyListFactory();
			$hplf->getById( $this->getHolidayPolicyID() );

			if ( $hplf->getRecordCount() == 1 ) {
				$this->holiday_policy_obj = $hplf->getCurrent();

				return $this->holiday_policy_obj;
			}

			return FALSE;
		}
	}

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

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

		$hplf = new HolidayPolicyListFactory();

		if (
				$this->Validator->isResultSetWithRows(	'holiday_policy',
													$hplf->getByID($id),
													TTi18n::gettext('Holiday Policy is invalid')
													) ) {

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

			return TRUE;
		}

		return FALSE;
	}

	function isUniqueDateStamp($date_stamp) {
		$ph = array(
					'policy_id' => $this->getHolidayPolicyID(),
					'date_stamp' => $this->db->BindDate( $date_stamp ),
					);

		$query = 'select id from '. $this->getTable() .'
					where holiday_policy_id = ?
						AND date_stamp = ?
						AND deleted=0';
		$date_stamp_id = $this->db->GetOne($query, $ph);
		Debug::Arr($date_stamp_id,'Unique Date Stamp: '. $date_stamp, __FILE__, __LINE__, __METHOD__,10);

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

		return FALSE;
	}
	function getDateStamp( $raw = FALSE ) {
		if ( isset($this->data['date_stamp']) ) {
			if ( $raw === TRUE ) {
				return $this->data['date_stamp'];
			} else {
				return TTDate::strtotime( $this->data['date_stamp'] );
			}
		}

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

		if 	(	$this->Validator->isDate(		'date_stamp',
												$epoch,
												TTi18n::gettext('Incorrect date'))
					AND
						$this->Validator->isTrue(		'date_stamp',
														$this->isUniqueDateStamp($epoch),
														TTi18n::gettext('Date is already in use by another Holiday'))

			) {

			if 	( $epoch > 0 ) {
				$this->data['date_stamp'] = $epoch;

				return TRUE;
			} else {
				$this->Validator->isTRUE(		'date_stamp',
												FALSE,
												TTi18n::gettext('Incorrect date'));
			}


		}

		return FALSE;
	}

	function isUniqueName($name) {
		$ph = array(
					'policy_id' => $this->getHolidayPolicyID(),
					'name' => $name,
					'start_date1' => $this->db->BindDate( TTDate::getBeginYearEpoch( $this->getDateStamp() ) ),
					'end_date1' => $this->db->BindDate( TTDate::getEndYearEpoch( $this->getDateStamp() ) ),
					'start_date2' => $this->db->BindDate( $this->getDateStamp()-(86400*15) ),
					'end_date2' => $this->db->BindDate( $this->getDateStamp()+(86400*15) ),
					);

		$query = 'select id from '. $this->getTable() .'
					where holiday_policy_id = ?
						AND name = ?
						AND
							(
								(
								date_stamp >= ?
								AND date_stamp <= ?
								)
							OR
								(
								date_stamp >= ?
								AND date_stamp <= ?
								)
							)
						AND deleted=0';
		$name_id = $this->db->GetOne($query, $ph);
		Debug::Arr($name_id,'Unique Name: '. $name, __FILE__, __LINE__, __METHOD__,10);

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

		return FALSE;
	}

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

		return FALSE;
	}
	function setName($name) {
		$name = trim($name);
		if (	$this->Validator->isLength(	'name',
											$name,
											TTi18n::gettext('Name is invalid'),
											2,50)
					AND
						$this->Validator->isTrue(		'name',
														$this->isUniqueName($name),
														TTi18n::gettext('Name is already in use in this year, or within 30 days'))

						) {

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

			return TRUE;
		}

		return FALSE;
	}

	function getAverageTime( $user_id ) {
		$udtlf = new UserDateTotalListFactory();
		//$last_days_worked_count = $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($user_id, ( $this->getDateStamp() - ( $this->getHolidayPolicyObject()->getMinimumWorkedPeriodDays() * 86400) ), $this->getDateStamp()-86400  );

		if ( $this->getHolidayPolicyObject()->getAverageTimeWorkedDays() == TRUE ) {
			$last_days_worked_count = $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($user_id, ( $this->getDateStamp() - ( $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400) ), $this->getDateStamp()-86400  );
		} else {
			Debug::text('NOT Using worked days!', __FILE__, __LINE__, __METHOD__,10);
			$last_days_worked_count = $this->getHolidayPolicyObject()->getAverageTimeDays();
		}
		Debug::text('Last Days Worked:'. $last_days_worked_count, __FILE__, __LINE__, __METHOD__,10);


		//$avg_seconds_worked_per_day = $slf->getAverageDailyHoursWorkedSinceDate($user_obj->getId(), ( $shift_start_date - ( $this->getStatutoryAverageDays() * 86400 ) ) );
		if ( $this->getHolidayPolicyObject()->getIncludeOverTime() == TRUE ) {
			Debug::text('Including OverTime!', __FILE__, __LINE__, __METHOD__,10);
			$total_seconds_worked = $udtlf->getWorkedTimeSumByUserIDAndStartDateAndEndDate( $user_id, ( $this->getDateStamp() - ( $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400) ), $this->getDateStamp()-86400 );
		} else {
			Debug::text('NOT Including OverTime!', __FILE__, __LINE__, __METHOD__,10);
			$total_seconds_worked = $udtlf->getRegularTimeSumByUserIDAndStartDateAndEndDate( $user_id, ( $this->getDateStamp() - ( $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400) ), $this->getDateStamp()-86400 );
		}

		if ( $this->getHolidayPolicyObject()->getIncludePaidAbsenceTime() == TRUE ) {
			Debug::text('Including Paid Absence Time!', __FILE__, __LINE__, __METHOD__,10);
			$total_seconds_worked += $udtlf->getPaidAbsenceTimeSumByUserIDAndStartDateAndEndDate( $user_id, ( $this->getDateStamp() - ( $this->getHolidayPolicyObject()->getAverageTimeDays() * 86400) ), $this->getDateStamp()-86400 );
		} else {
			Debug::text('NOT Including Paid Absence Time!', __FILE__, __LINE__, __METHOD__,10);
		}

		if ( $last_days_worked_count > 0 ) {
			$avg_seconds_worked_per_day = bcdiv($total_seconds_worked, $last_days_worked_count);
			Debug::text('AVG hours worked per day:'. TTDate::getHours( $avg_seconds_worked_per_day ), __FILE__, __LINE__, __METHOD__,10);
		} else {
			$avg_seconds_worked_per_day = 0;
		}

		if ( $this->getHolidayPolicyObject()->getMaximumTime() > 0
				AND $avg_seconds_worked_per_day > $this->getHolidayPolicyObject()->getMaximumTime() ) {
			$avg_seconds_worked_per_day = $this->getHolidayPolicyObject()->getMaximumTime();
			Debug::text('AVG hours worked per day exceeds maximum regulars hours per day, setting to:'. ($avg_seconds_worked_per_day / 60) / 60, __FILE__, __LINE__, __METHOD__,10);
		}

		if ( $avg_seconds_worked_per_day < $this->getHolidayPolicyObject()->getMinimumTime() ) {
			$avg_seconds_worked_per_day = $this->getHolidayPolicyObject()->getMinimumTime();
			Debug::text('AVG hours worked per day is less then minimum regulars hours per day, setting to:'. ($avg_seconds_worked_per_day / 60) / 60, __FILE__, __LINE__, __METHOD__,10);
		}

		//Round to nearest 15mins.
		if ( (int)$this->getHolidayPolicyObject()->getRoundIntervalPolicyID() != 0
				AND is_object($this->getHolidayPolicyObject()->getRoundIntervalPolicyObject() ) ) {
			$avg_seconds_worked_per_day = TTDate::roundTime($avg_seconds_worked_per_day, $this->getHolidayPolicyObject()->getRoundIntervalPolicyObject()->getInterval(), $this->getHolidayPolicyObject()->getRoundIntervalPolicyObject()->getRoundType() );

			//$avg_seconds_worked_per_day = TTDate::roundTime( $avg_seconds_worked_per_day, 900, 10);
			Debug::text('Rounding Stat Time To: '. $avg_seconds_worked_per_day, __FILE__, __LINE__, __METHOD__,10);
		} else {
			Debug::text('NOT Rounding Stat Time!', __FILE__, __LINE__, __METHOD__,10);
		}

		return $avg_seconds_worked_per_day;
	}

	function isEligible( $user_id ) {
		if ( $user_id == '' ) {
			return FALSE;
		}

		//$this->getHolidayPolicyObject();

		$ulf = new UserListFactory();
		$user_obj = $ulf->getById($user_id)->getCurrent();

		$udtlf = new UserDateTotalListFactory();

		//Make sure the employee has been employed long enough according to labor standards
		//Also make sure that the employee hasn't been terminated on or before the holiday.
		if ( $user_obj->getHireDate() <= ( $this->getDateStamp() - ( $this->getHolidayPolicyObject()->getMinimumEmployedDays() * 86400 ) )
				AND ( $user_obj->getTerminationDate() == '' OR ( $user_obj->getTerminationDate() != '' AND $user_obj->getTerminationDate() > $this->getDateStamp() )  ) ) {
			Debug::text('Employee has been employed long enough!', __FILE__, __LINE__, __METHOD__,10);

			//$last_days_worked_count = $slf->getDaysWorkedSinceDate($user_obj->getId(), ( $shift_start_date - ( $this->getStatutoryEmployedPeriod() * 86400 ) ) );
			//$last_days_worked_count = $slf->getDaysWorkedByStartDateAndEndDate($user_obj->getId(), ( $shift_start_date - ( $this->getStatutoryEmployedPeriod() * 86400 ) ), $shift_start_date );
			$last_days_worked_count = $udtlf->getDaysWorkedByUserIDAndStartDateAndEndDate($user_obj->getId(), ( $this->getDateStamp() - ( $this->getHolidayPolicyObject()->getMinimumWorkedPeriodDays() * 86400) ), $this->getDateStamp()-86400  );
			Debug::text('Employee has worked the last: '. $last_days_worked_count .' days (Must be at least: '. $this->getHolidayPolicyObject()->getMinimumWorkedDays() .')', __FILE__, __LINE__, __METHOD__,10);

			//Make sure employee has worked for a portion of those days.
			if ( $last_days_worked_count >= $this->getHolidayPolicyObject()->getMinimumWorkedDays() ) {
				Debug::text('Employee has worked enough of the past days!', __FILE__, __LINE__, __METHOD__,10);

				return TRUE;
			} else {
				Debug::text('Employee has NOT worked enough days prior to the holiday!', __FILE__, __LINE__, __METHOD__,10);
			}
		} else {
			Debug::text('Employee has NOT been employed long enough!', __FILE__, __LINE__, __METHOD__,10);
		}

		return FALSE;
	}

	function Validate() {
		return TRUE;
	}

	function preSave() {
		return TRUE;
	}

	function postSave() {
		return TRUE;
	}

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

}
?>
