false, 'undertime_absence' => false, 'break' => false, 'holiday' => false, 'schedule_absence' => false, 'absence' => false, 'regular' => false, 'overtime' => false, 'premium' => false, 'accrual' => false, 'exception' => true, //Exception options 'exception_premature' => true, //Calculates premature exceptions 'exception_future' => false, //Calculates exceptions in the future. //Calculate policies for future dates. 'future_dates' => false, //Calculates dates in the future. ]; $udtlf = new UserDateTotalListFactory(); //Use optimized query to speed this process up significantly. $udtlf->getMidDayExceptionsByStartDateAndEndDateAndPayPeriodStatus( $start_date, $end_date, [ 10, 12, 15, 30 ] ); Debug::text( ' calcQuickExceptions: Start Date: ' . TTDate::getDate( 'DATE+TIME', $start_date ) . ' End Date: ' . TTDate::getDate( 'DATE+TIME', $end_date ) . ' Rows: ' . $udtlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 5 ); if ( $udtlf->getRecordCount() > 0 ) { $system_job_queue_batch_id = TTUUID::generateUUID(); $i = 0; foreach ( $udtlf as $udt_obj ) { Debug::text( '(' . $i . '). User: ' . $udt_obj->getUser() . ' Start Date: ' . TTDate::getDate( 'DATE+TIME', strtotime( $udt_obj->getColumn( 'start_date' ) ) ) . ' End Date: ' . TTDate::getDate( 'DATE+TIME', strtotime( $udt_obj->getColumn( 'end_date' ) ) ), __FILE__, __LINE__, __METHOD__, 5 ); // See also: ScheduleFactory::handleFutureTimeSheetRecalculationForExceptions(), PunchFactory::handleFutureTimeSheetRecalculationForExceptions() //SystemJobQueue::Add( TTi18n::getText( 'ReCalculating Quick Exceptions' ), $system_job_queue_batch_id, 'CalculatePolicy', 'reCalculateForJobQueue', [ $udt_obj->getUser(), 'calcQuickExceptions', strtotime( $udt_obj->getColumn( 'start_date' ) ), strtotime( $udt_obj->getColumn( 'end_date' ) ) ], 110 ); if ( is_object( $udt_obj->getUserObject() ) ) { //Calculate pre-mature exceptions, so pre-mature Missing Out Punch exceptions aren't made active until they are ready. //Don't calculate future exceptions though. $transaction_function = function () use ( $udt_obj, $flags ) { $cp = TTNew( 'CalculatePolicy' ); /** @var CalculatePolicy $cp */ $cp->setFlag( $flags ); $cp->setUserObject( $udt_obj->getUserObject() ); $cp->getUserObject()->setTransactionMode( 'REPEATABLE READ' ); $cp->addPendingCalculationDate( strtotime( $udt_obj->getColumn( 'start_date' ) ), strtotime( $udt_obj->getColumn( 'end_date' ) ) ); $cp->calculate( strtotime( $udt_obj->getColumn( 'start_date' ) ) ); //This sets timezone itself. $cp->Save(); $cp->getUserObject()->setTransactionMode(); //Back to default isolation level. return true; }; $udt_obj->RetryTransaction( $transaction_function, 2, 3 ); //Set retry_sleep this fairly high so real-time punches have a chance to get saved between retries. } else { Debug::Arr( $udt_obj->getUserObject(), 'ERROR: Invalid UserObject: User ID: ' . $udt_obj->getUser(), __FILE__, __LINE__, __METHOD__, 10 ); } $i++; } } Debug::text( ' calcQuickExceptions: Done', __FILE__, __LINE__, __METHOD__, 5 ); ?>