<?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: calcExceptions.php 2158 2008-09-15 23:26:15Z ipso $
 * $Date: 2008-09-15 16:26:15 -0700 (Mon, 15 Sep 2008) $
 */
/*
 * Calculate Exceptions for the previous day. This helps especially for
 * the "Unscheuled Absence" exception.
 *
 * Run this once a day. AFTER AddUserDate
 */
require_once( dirname(__FILE__) . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'includes'. DIRECTORY_SEPARATOR .'global.inc.php');
require_once( dirname(__FILE__) . DIRECTORY_SEPARATOR .'..'. DIRECTORY_SEPARATOR .'includes'. DIRECTORY_SEPARATOR .'CLI.inc.php');

//Debug::setVerbosity(5);

$execution_time = time();

$clf = new CompanyListFactory();
$clf->getAll();

$x=0;
if ( $clf->getRecordCount() > 0 ) {
	foreach ( $clf as $c_obj ) {

		if ( $c_obj->getStatus() != 30 ) {
			$company_start_time = microtime(TRUE);
			Debug::text('Company: '. $c_obj->getName() .'('.$c_obj->getId().')', __FILE__, __LINE__, __METHOD__,5);

			//Recalculate at least the last two days.
			$start_date = TTDate::getMiddleDayEpoch( $execution_time ) - (86400*2);
			$end_date = TTDate::getMiddleDayEpoch( time() ) - (86400);

			//Get the last time cron ran this script.
			$cjlf = new CronJobListFactory();
			$cjlf->getByName( 'calcExceptions');
			if ( $cjlf->getRecordCount() > 0 ) {
				foreach( $cjlf as $cj_obj ) {
					$tmp_start_date = $cj_obj->getLastRunDate();
					if ( $tmp_start_date < $start_date ) {
						$start_date = $tmp_start_date;
						Debug::text('  CRON Job hasnt run in more then 48hrs, reducing Start Date to: '. TTDate::getDate('DATE+TIME', $start_date ) , __FILE__, __LINE__, __METHOD__,5);
					}
				}
			}
			unset($cjlf, $cj_obj, $tmp_start_date);

			//Get maximum shift time for each pay period schedule, so we know how far back
			//we have to recalculate days at the minimum.
			$ppslf = new PayPeriodScheduleListFactory();
			$ppslf->getByCompanyId( $c_obj->getId() );
			if ( $ppslf->getRecordCount() > 0 ) {
				foreach( $ppslf as $pps_obj ) {
					$tmp_start_date = TTDate::getMiddleDayEpoch( $execution_time ) - $pps_obj->getMaximumShiftTime();
					if ( $tmp_start_date < $start_date ) {
						$start_date = $tmp_start_date;
						Debug::text('  Maximum Shift Time is greater then 48hrs, reducing Start Date to: '. TTDate::getDate('DATE+TIME', $start_date ) , __FILE__, __LINE__, __METHOD__,5);
					}
				}
			}
			unset($ppslf, $pps_obj, $tmp_start_date);

			//Get earliest pre_mature exception in a NON-closed pay period.
			$elf = new ExceptionListFactory();
			$elf->getByCompanyIDAndTypeAndPayPeriodStatus($c_obj->getId(), 5, array(10,12,15,30), 1, NULL, NULL, array( 'b.date_stamp' => 'asc' ) ); //Limit 1
			if ( $elf->getRecordCount() > 0 ) {
				foreach( $elf as $e_obj ) {
					$tmp_start_date = $e_obj->getUserDateObject()->getDateStamp();
					if ( $tmp_start_date < $start_date ) {
						$start_date = $tmp_start_date;
						Debug::text('  Pre-Mature exceptions occur before start date, reducing to: '. TTDate::getDate('DATE+TIME', $start_date ) .'('. $e_obj->getId().')', __FILE__, __LINE__, __METHOD__,5);
					}
				}
			}
			unset($elf, $e_obj, $tmp_start_date);

			$udlf = new UserDateListFactory();
			$udlf->getByCompanyIdAndStartDateAndEndDateAndPayPeriodStatus($c_obj->getId(), $start_date, $end_date, array(10,12,15,30) );
			Debug::text(' Start Date: '. TTDate::getDate('DATE+TIME', $start_date ) .' End Date: '. TTDate::getDate('DATE+TIME', $end_date ) .' User Date Rows: '. $udlf->getRecordCount(), __FILE__, __LINE__, __METHOD__,5);

			if ( $udlf->getRecordCount() > 0 ) {
				$i=0;
				foreach ($udlf as $ud_obj) {

					//Recalculate system time, and exceptions for the day.
					//Because if its a Monday, it will also recalculate the rest of the days in the week.
					//Shouldn't be a big deal though.
					//This isn't needed, since we now do it in AddRecurringScheduleShift, so dock time is
					//applied at the beginning of the day.
					//The problem is that AddRecurringScheduleShift does it, then for the entire day someone with
					//a dock policy shows up as dock time. Some users have complained about this a few times.

					//Reason for doing two days ago is that if someone starts a shift at 11pm, but doesn't end it in
					//time, it still needs to be re-calculated a day later.
					//Could maybe get around this by getting all punches of yesterday, and getting their date_ids
					//and just recalculating those.

					//Enable pre-mature exceptions if we're recalculating just one day ago.
					$enable_premature_exceptions = FALSE;
					if ( $end_date == TTDate::getMiddleDayEpoch( $ud_obj->getDateStamp() ) ) {
						$enable_premature_exceptions = TRUE;
					}
					Debug::text($x .'('.$i.'). User: '. $ud_obj->getUser() .' Date: '. TTDate::getDate('DATE+TIME', $ud_obj->getDateStamp() ) .' User Date ID: '. $ud_obj->getId() .' Enable PreMature Exceptions: '. (int)$enable_premature_exceptions, __FILE__, __LINE__, __METHOD__,5);

					UserDateTotalFactory::reCalculateDay( $ud_obj->getId(), TRUE, $enable_premature_exceptions );

					$i++;
					$x++;
				}
			}
			Debug::text('Company: '. $c_obj->getName() .'('.$c_obj->getId().') Finished In: '. (microtime(TRUE)-$company_start_time) .'s', __FILE__, __LINE__, __METHOD__,5);
		}
	}
}


/*
//Two days ago.
$date = TTDate::getMiddleDayEpoch( time() ) - (86400*2);
//$date = TTDate::getBeginDayEpoch( time() );

$udlf = new UserDateListFactory();
$udlf->getByDate( $date );
if ( $udlf->getRecordCount() > 0 ) {
	$i=0;
	foreach ($udlf as $ud_obj) {
		Debug::text($i .'. User: '. $ud_obj->getUser() .' Date: '. TTDate::getDate('DATE+TIME', $ud_obj->getDateStamp() ) .' User Date ID: '. $ud_obj->getId() , __FILE__, __LINE__, __METHOD__,5);

		//ExceptionPolicyFactory::calcExceptions( $ud_obj->getId() );

		//Recalculate system time, and exceptions for the day.
		//Because if its a Monday, it will also recalculate the rest of the days in the week.
		//Shouldn't be a big deal though.
		//This isn't needed, since we now do it in AddRecurringScheduleShift, so dock time is
		//applied at the beginning of the day.
		//The problem is that AddRecurringScheduleShift does it, then for the entire day someone with
		//a dock policy shows up as dock time. Some users have complained about this a few times.

		//Reason for doing two days ago is that if someone starts a shift at 11pm, but doesn't end it in
		//time, it still needs to be re-calculated a day later.
		//Could maybe get around this by getting all punches of yesterday, and getting their date_ids
		//and just recalculating those.
		UserDateTotalFactory::reCalculateDay( $ud_obj->getId(), TRUE );

		$i++;
	}
}

//One day ago
$date = TTDate::getMiddleDayEpoch( time() ) - (86400);

$udlf = new UserDateListFactory();
$udlf->getByDate( $date );
if ( $udlf->getRecordCount() > 0 ) {
	$i=0;
	foreach ($udlf as $ud_obj) {
		Debug::text($i .'. User: '. $ud_obj->getUser() .' Date: '. TTDate::getDate('DATE+TIME', $ud_obj->getDateStamp() ) .' User Date ID: '. $ud_obj->getId(), __FILE__, __LINE__, __METHOD__,5);

		//ExceptionPolicyFactory::calcExceptions( $ud_obj->getId() );
		UserDateTotalFactory::reCalculateDay( $ud_obj->getId(), TRUE, TRUE );

		$i++;
	}
}
*/
Debug::writeToLog();
Debug::Display();
?>