//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. //Problem is a late shift on say Monday: 2:00PM to 11:00PM won't trigger the exception at 1AM the next day, //but by 1AM the following day (2days later) its too late and emails are disabled if enable_premature_exceptions are disabled. $enable_premature_exceptions = FALSE; //if ( $end_date == TTDate::getMiddleDayEpoch( $ud_obj->getDateStamp() ) ) { if (TTDate::getMiddleDayEpoch($ud_obj->getDateStamp()) >= TTDate::getMiddleDayEpoch($execution_time) - 86400 * 2) { $enable_premature_exceptions = TRUE; } Debug::text($x . '(' . $i . '). User: '******' 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); TTDate::setTimeZone(); $i++; $x++; } } Debug::text('Company: ' . $c_obj->getName() . '(' . $c_obj->getId() . ') Finished In: ' . (microtime(TRUE) - $company_start_time) . 's', __FILE__, __LINE__, __METHOD__, 5); } } } Debug::writeToLog(); Debug::Display();
$udlf->getByCompanyIdAndPayPeriodID($current_company->getId(), $pay_period_ids); } else { TTLog::addEntry($filter_user_id, 500, TTi18n::gettext('Recalculating Employee TimeSheet'), $current_user->getId(), 'user_date_total'); $udlf->getByUserIdAndPayPeriodID($filter_user_id, $pay_period_ids); } if ($udlf->getRecordCount() > 0) { InitProgressBar(); $progress_bar->setValue(0); $progress_bar->display(); Debug::text('Found days to re-calculate: ' . $udlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); $x = 1; foreach ($udlf as $ud_obj) { //Debug::text($x .' / '. $udlf->getRecordCount() .' - User Date Id: '. $ud_obj->getId() .' Date: '.$ud_obj->getDateStamp(TRUE) .' User ID: '. $ud_obj->getUser() , __FILE__, __LINE__, __METHOD__, 10); $udlf->StartTransaction(); //If a transaction wraps the entire recalculation process, a deadlock is likely to occur for large batches. UserDateTotalFactory::reCalculateDay($ud_obj->getId(), TRUE); $udlf->CommitTransaction(); $progress_bar->setValue(Misc::calculatePercent($x, $udlf->getRecordCount())); $progress_bar->display(); $x++; } } else { Debug::text('No User Date rows to calculate!', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text('Pay Period is CLOSED: ', __FILE__, __LINE__, __METHOD__, 10); } } break; case 'generate_paystubs': //Debug::setVerbosity(11);
function postSave() { Debug::text(' postSave()', __FILE__, __LINE__, __METHOD__, 10); if ($this->getEnableReCalculateDay() == TRUE) { //Calculate total time. Mainly for docked. UserDateTotalFactory::reCalculateDay($this->getUserDateID(), TRUE, FALSE); //ExceptionPolicyFactory::calcExceptions( $this->getUserDateID() ); } return TRUE; }
static function smartReCalculate($user_id, $user_date_ids, $enable_exception = TRUE, $enable_premature_exceptions = FALSE, $enable_future_exceptions = TRUE) { if ($user_id == '') { return FALSE; } //Debug::Arr($user_date_ids, 'aUser Date IDs: ', __FILE__, __LINE__, __METHOD__, 10); if (!is_array($user_date_ids) and is_numeric($user_date_ids) and $user_date_ids > 0) { $user_date_ids = array($user_date_ids); } if (!is_array($user_date_ids)) { Debug::Text('Returning FALSE... User Date IDs not an array...', __FILE__, __LINE__, __METHOD__, 10); return FALSE; } $user_date_ids = array_unique($user_date_ids); //Debug::Arr($user_date_ids, 'bUser Date IDs: ', __FILE__, __LINE__, __METHOD__, 10); $start_week_day_id = 0; $ppslf = TTnew('PayPeriodScheduleListFactory'); $ppslf->getByUserId($user_id); if ($ppslf->getRecordCount() == 1) { $pps_obj = $ppslf->getCurrent(); $start_week_day_id = $pps_obj->getStartWeekDay(); } Debug::text('Start Week Day ID: ' . $start_week_day_id, __FILE__, __LINE__, __METHOD__, 10); //Get date stamps for all user_date_ids. $udlf = TTnew('UserDateListFactory'); $udlf->getByIds($user_date_ids, NULL, array('date_stamp' => 'asc')); //Order by date asc if ($udlf->getRecordCount() > 0) { //Order them, and get the one or more sets of date ranges that need to be recalculated. //Need to consider re-calculating multiple weeks at once. $i = 0; foreach ($udlf as $ud_obj) { $start_week_epoch = TTDate::getBeginWeekEpoch($ud_obj->getDateStamp(), $start_week_day_id); $end_week_epoch = TTDate::getEndWeekEpoch($ud_obj->getDateStamp(), $start_week_day_id); Debug::text('Current Date: ' . TTDate::getDate('DATE', $ud_obj->getDateStamp()) . ' Start Week: ' . TTDate::getDate('DATE', $start_week_epoch) . ' End Week: ' . TTDate::getDate('DATE', $end_week_epoch), __FILE__, __LINE__, __METHOD__, 10); if ($i == 0) { $range_arr[$start_week_epoch] = array('start_date' => $ud_obj->getDateStamp(), 'end_date' => $end_week_epoch); } else { //Loop through each range extending it if needed. foreach ($range_arr as $tmp_start_week_epoch => $tmp_range) { if ($ud_obj->getDateStamp() >= $tmp_range['start_date'] and $ud_obj->getDateStamp() <= $tmp_range['end_date']) { //Date falls within already existing range continue; } elseif ($ud_obj->getDateStamp() < $tmp_range['start_date'] and $ud_obj->getDateStamp() >= $tmp_start_week_epoch) { //Date falls within the same week, but before the current start date. $range_arr[$tmp_start_week_epoch]['start_date'] = $ud_obj->getDateStamp(); Debug::text('Pushing Start Date back...', __FILE__, __LINE__, __METHOD__, 10); } else { //Outside current range. Check to make sure it isn't within another range. if (isset($range_arr[$start_week_epoch])) { //Within another existing week, check to see if we need to extend it. if ($ud_obj->getDateStamp() < $range_arr[$start_week_epoch]['start_date']) { Debug::text('bPushing Start Date back...', __FILE__, __LINE__, __METHOD__, 10); $range_arr[$start_week_epoch]['start_date'] = $ud_obj->getDateStamp(); } } else { //Not within another existing week Debug::text('Adding new range...', __FILE__, __LINE__, __METHOD__, 10); $range_arr[$start_week_epoch] = array('start_date' => $ud_obj->getDateStamp(), 'end_date' => $end_week_epoch); } } } unset($tmp_range, $tmp_start_week_epoch); } $i++; } unset($start_week_epoch, $end_week_epoch, $udlf, $ud_obj); if (is_array($range_arr)) { ksort($range_arr); //Sort range by start week, so recalculating goes in date order. //Debug::Arr($range_arr, 'Range Array: ', __FILE__, __LINE__, __METHOD__, 10); foreach ($range_arr as $week_range) { $udlf = TTnew('UserDateListFactory'); $udlf->getByUserIdAndStartDateAndEndDate($user_id, $week_range['start_date'], $week_range['end_date']); if ($udlf->getRecordCount() > 0) { Debug::text('Found days to re-calculate: ' . $udlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); $udlf->StartTransaction(); $z = 1; $z_max = $udlf->getRecordCount(); foreach ($udlf as $ud_obj) { //We only need to re-calculate exceptions on the exact days specified by user_date_ids. //This was the case before we Over Weekly Time/Over Scheduled Weekly Time exceptions, //Now we have to enable calculating exceptions for the entire week. Debug::text('Re-calculating day with exceptions: ' . $ud_obj->getId(), __FILE__, __LINE__, __METHOD__, 10); if ($z == $z_max) { //Enable recalculating holidays at the end of each week. UserDateTotalFactory::reCalculateDay($ud_obj->getId(), $enable_exception, $enable_premature_exceptions, $enable_future_exceptions, TRUE); } else { UserDateTotalFactory::reCalculateDay($ud_obj->getId(), $enable_exception, $enable_premature_exceptions, $enable_future_exceptions); } $z++; } $udlf->CommitTransaction(); } } //Use the last date to base the future week calculation on. Make sure we don't unset $week_range['end_date'] //When BiWeekly overtime policies are calculated, it sets getEnableCalcFutureWeek() to TRUE. if (isset($week_range['end_date']) and UserDateTotalFactory::getEnableCalcFutureWeek() == TRUE) { $future_week_date = $week_range['end_date'] + 86400 * 7; Debug::text('Found Biweekly overtime policy, calculate one week into the future: ' . TTDate::getDate('DATE', $future_week_date), __FILE__, __LINE__, __METHOD__, 10); UserDateTotalFactory::reCalculateRange($user_id, TTDate::getBeginWeekEpoch($future_week_date, $start_week_day_id), TTDate::getEndWeekEpoch($future_week_date, $start_week_day_id)); UserDateTotalFactory::setEnableCalcFutureWeek(FALSE); //Return to FALSE so future weeks aren't calculate for other users. unset($future_week_date); } return TRUE; } } Debug::text('Returning FALSE!', __FILE__, __LINE__, __METHOD__, 10); return FALSE; }
function testTimeBasedPartialPremiumPolicyF3() { global $dd; TTDate::setTimeZone('PST8PDT'); $policy_ids['premium'][] = $this->createPremiumPolicy($this->company_id, 125); //Create Policy Group $dd->createPolicyGroup($this->company_id, NULL, NULL, NULL, NULL, $policy_ids['premium'], NULL, array($this->user_id)); $date_epoch = $this->pay_period_objs[0]->getStartDate() + 86400 * 6; $date_stamp = TTDate::getDate('DATE', $date_epoch); //Test punching in before the premium start time, and out after the premium end time. $dd->createPunchPair($this->user_id, strtotime($date_stamp . ' 5:00AM'), strtotime($date_stamp . ' 8:00PM'), array('in_type_id' => 10, 'out_type_id' => 10, 'branch_id' => 0, 'department_id' => 0, 'job_id' => 0, 'job_item_id' => 0), TRUE); $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch); //print_r($udt_arr); //Total Time $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10); $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10); $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 15 * 3600); //Regular Time $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10); $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 20); $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 15 * 3600); //Premium Time1 $this->assertEquals($udt_arr[$date_epoch][2]['status_id'], 10); $this->assertEquals($udt_arr[$date_epoch][2]['type_id'], 40); $this->assertEquals($udt_arr[$date_epoch][2]['total_time'], 12 * 3600); //Make sure no other hours $this->assertEquals(count($udt_arr[$date_epoch]), 3); $udlf = TTNew('UserDateListFactory'); $udlf->getByID($udt_arr[$date_epoch][0]['user_date_id']); unset($udt_arr); $user_date_id = $udlf->getCurrent()->getId(); TTDate::setTimeZone('EST5EDT'); $recalc_result = UserDateTotalFactory::reCalculateDay($user_date_id, TRUE); TTDate::setTimeZone('PST8PDT'); $date_epoch = $this->pay_period_objs[0]->getStartDate() + 86400 * 6; $udt_arr = $this->getUserDateTotalArray($date_epoch, $date_epoch); //print_r($udt_arr); //Total Time $this->assertEquals($udt_arr[$date_epoch][0]['status_id'], 10); $this->assertEquals($udt_arr[$date_epoch][0]['type_id'], 10); $this->assertEquals($udt_arr[$date_epoch][0]['total_time'], 15 * 3600); //Regular Time $this->assertEquals($udt_arr[$date_epoch][1]['status_id'], 10); $this->assertEquals($udt_arr[$date_epoch][1]['type_id'], 20); $this->assertEquals($udt_arr[$date_epoch][1]['total_time'], 15 * 3600); //Premium Time1 $this->assertEquals($udt_arr[$date_epoch][2]['status_id'], 10); $this->assertEquals($udt_arr[$date_epoch][2]['type_id'], 40); $this->assertEquals($udt_arr[$date_epoch][2]['total_time'], 12 * 3600); //Make sure no other hours $this->assertEquals(count($udt_arr[$date_epoch]), 3); return TRUE; }
/** * ReCalculate timesheet/policies * @return bool */ function reCalculateTimeSheet($pay_period_ids, $user_ids = NULL) { //Debug::text('Recalculating Employee Timesheet: User ID: '. $user_ids .' Pay Period ID: '. $pay_period_ids, __FILE__, __LINE__, __METHOD__,10); //Debug::setVerbosity(11); if (!$this->getPermissionObject()->Check('punch', 'enabled') or !($this->getPermissionObject()->Check('punch', 'edit') or $this->getPermissionObject()->Check('punch', 'edit_child'))) { return $this->getPermissionObject()->PermissionDenied(); } //Make sure pay period is not CLOSED. //We can re-calc on locked though. $pplf = TTnew('PayPeriodListFactory'); $pplf->getByIdList($pay_period_ids); if ($pplf->getRecordCount() > 0) { $pp_obj = $pplf->getCurrent(); if ($pp_obj->getStatus() != 20) { $udlf = TTnew('UserDateListFactory'); if (is_array($user_ids) and count($user_ids) > 0 and isset($user_ids[0]) and $user_ids[0] > 0) { $udlf->getByUserIdAndPayPeriodID($user_ids, $pay_period_ids); } elseif ($this->getPermissionObject()->Check('punch', 'edit') == TRUE) { //Make sure they have the permissions to recalculate all employees. TTLog::addEntry($this->getCurrentCompanyObject()->getId(), TTi18n::gettext('Notice'), TTi18n::gettext('Recalculating Company TimeSheet'), $this->getCurrentUserObject()->getId(), 'user_date_total'); $udlf->getByCompanyIdAndPayPeriodID($this->getCurrentCompanyObject()->getId(), $pay_period_ids); } else { return $this->getPermissionObject()->PermissionDenied(); } if ($udlf->getRecordCount() > 0) { Debug::text('Found days to re-calculate: ' . $udlf->getRecordCount(), __FILE__, __LINE__, __METHOD__, 10); $this->getProgressBarObject()->start($this->getAMFMessageID(), $udlf->getRecordCount(), NULL, TTi18n::getText('ReCalculating...')); $x = 1; $prev_date_stamp = FALSE; foreach ($udlf as $ud_obj) { Debug::text($x . ' / ' . $udlf->getRecordCount() . ' - User Date Id: ' . $ud_obj->getId() . ' Date: ' . $ud_obj->getDateStamp(TRUE) . ' User ID: ' . $ud_obj->getUser(), __FILE__, __LINE__, __METHOD__, 10); if ($prev_date_stamp != FALSE and abs($ud_obj->getDateStamp() - $prev_date_stamp) > 86400) { Debug::text('Found gap between user_date rows! - User Date Id: ' . $ud_obj->getId() . ' Date: ' . $ud_obj->getDateStamp(TRUE) . ' Previous Date: ' . TTDate::getDate('DATE', $prev_date_stamp) . ' User ID: ' . $ud_obj->getUser(), __FILE__, __LINE__, __METHOD__, 10); for ($n = $prev_date_stamp; $n < $ud_obj->getDateStamp(); $n += 86400) { $tmp_user_date_id = UserDateFactory::findOrInsertUserDate($ud_obj->getUser(), TTDate::getBeginDayEpoch($n)); Debug::text('Filling gap in user_date rows! - Date: ' . TTDate::getDate('DATE', $n) . ' User ID: ' . $ud_obj->getUser() . ' New User Date ID: ' . $tmp_user_date_id, __FILE__, __LINE__, __METHOD__, 10); UserDateTotalFactory::reCalculateDay($tmp_user_date_id, TRUE); } unset($n, $tmp_user_date_id); } TTLog::addEntry($ud_obj->getId(), 500, TTi18n::gettext('Recalculating Employee TimeSheet') . ': ' . $ud_obj->getUserObject()->getFullName() . ' ' . TTi18n::gettext('Date') . ': ' . TTDate::getDate('DATE', $ud_obj->getDateStamp()), $this->getCurrentUserObject()->getId(), 'user_date_total'); $udlf->StartTransaction(); //If a transaction wraps the entire recalculation process, a deadlock is likely to occur for large batches. UserDateTotalFactory::reCalculateDay($ud_obj->getId(), TRUE); $udlf->CommitTransaction(); $this->getProgressBarObject()->set($this->getAMFMessageID(), $x); $prev_date_stamp = $ud_obj->getDateStamp(); $x++; } $this->getProgressBarObject()->stop($this->getAMFMessageID()); } else { Debug::text('No User Date rows to calculate!', __FILE__, __LINE__, __METHOD__, 10); } } else { Debug::text('Pay Period is CLOSED: ', __FILE__, __LINE__, __METHOD__, 10); } } return $this->returnHandler(TRUE); }
/** * Set user_date_total data for one or more user_date_totales. * @param array $data user_date_total data * @return array */ function setUserDateTotal($data, $validate_only = FALSE) { $validate_only = (bool) $validate_only; if (!is_array($data)) { return $this->returnHandler(FALSE); } if (!$this->getPermissionObject()->Check('punch', 'enabled') or !($this->getPermissionObject()->Check('punch', 'edit') or $this->getPermissionObject()->Check('punch', 'edit_own') or $this->getPermissionObject()->Check('punch', 'edit_child') or $this->getPermissionObject()->Check('punch', 'add'))) { return $this->getPermissionObject()->PermissionDenied(); } if ($validate_only == TRUE) { Debug::Text('Validating Only!', __FILE__, __LINE__, __METHOD__, 10); $permission_children_ids = FALSE; } else { //Get Permission Hierarchy Children first, as this can be used for viewing, or editing. $permission_children_ids = $this->getPermissionChildren(); } extract($this->convertToMultipleRecords($data)); Debug::Text('Received data for: ' . $total_records . ' UserDateTotals', __FILE__, __LINE__, __METHOD__, 10); Debug::Arr($data, 'Data: ', __FILE__, __LINE__, __METHOD__, 10); $validator_stats = array('total_records' => $total_records, 'valid_records' => 0); if (is_array($data)) { $this->getProgressBarObject()->start($this->getAMFMessageID(), $total_records); foreach ($data as $key => $row) { $recalculate_user_date_id = FALSE; $primary_validator = new Validator(); $lf = TTnew('UserDateTotalListFactory'); $lf->StartTransaction(); if (isset($row['id']) and $row['id'] > 0) { //Modifying existing object. //Get user_date_total object, so we can only modify just changed data for specific records if needed. $lf->getByIdAndCompanyId($row['id'], $this->getCurrentCompanyObject()->getId()); if ($lf->getRecordCount() == 1) { //Object exists, check edit permissions if ($validate_only == TRUE or ($this->getPermissionObject()->Check('punch', 'edit') or $this->getPermissionObject()->Check('punch', 'edit_own') and $this->getPermissionObject()->isOwner($lf->getCurrent()->getCreatedBy(), $lf->getCurrent()->getID()) === TRUE or $this->getPermissionObject()->Check('punch', 'edit_child') and $this->getPermissionObject()->isChild($lf->getCurrent()->getUserDateObject()->getUser(), $permission_children_ids) === TRUE)) { Debug::Text('Row Exists, getting current data: ', $row['id'], __FILE__, __LINE__, __METHOD__, 10); $lf = $lf->getCurrent(); //When editing a record if the date changes, we need to recalculate the old date. //This must occur before we merge the data together. if (isset($row['user_date_id']) and $lf->getUserDateID() != $row['user_date_id'] or isset($row['date_stamp']) and is_object($lf->getUserDateObject()) and $lf->getUserDateObject()->getDateStamp() and TTDate::parseDateTime($row['date_stamp']) != $lf->getUserDateObject()->getDateStamp()) { Debug::Text('Date has changed, recalculate old date... New: [ Date: ' . $row['date_stamp'] . ' ] User Date ID: ' . $lf->getUserDateID(), __FILE__, __LINE__, __METHOD__, 10); $recalculate_user_date_id = $lf->getUserDateID(); } $row = array_merge($lf->getObjectAsArray(), $row); } else { $primary_validator->isTrue('permission', FALSE, TTi18n::gettext('Edit permission denied')); } } else { //Object doesn't exist. $primary_validator->isTrue('id', FALSE, TTi18n::gettext('Edit permission denied, record does not exist')); } } else { //Adding new object, check ADD permissions. if (!($validate_only == TRUE or $this->getPermissionObject()->Check('punch', 'add') and ($this->getPermissionObject()->Check('punch', 'edit') or isset($row['user_id']) and $this->getPermissionObject()->Check('punch', 'edit_own') and $this->getPermissionObject()->isOwner(FALSE, $row['user_id']) === TRUE or isset($row['user_id']) and $this->getPermissionObject()->Check('punch', 'edit_child') and $this->getPermissionObject()->isChild($row['user_id'], $permission_children_ids) === TRUE))) { $primary_validator->isTrue('permission', FALSE, TTi18n::gettext('Add permission denied')); } } Debug::Arr($row, 'Data: ', __FILE__, __LINE__, __METHOD__, 10); $is_valid = $primary_validator->isValid(); if ($is_valid == TRUE) { //Check to see if all permission checks passed before trying to save data. Debug::Text('Setting object data...', __FILE__, __LINE__, __METHOD__, 10); $lf->setObjectFromArray($row); //Force Company ID to current company. //$lf->setCompany( $this->getCurrentCompanyObject()->getId() ); $is_valid = $lf->isValid(); if ($is_valid == TRUE) { Debug::Text('Saving data...', __FILE__, __LINE__, __METHOD__, 10); if ($validate_only == TRUE) { $save_result[$key] = TRUE; } else { $lf->setEnableTimeSheetVerificationCheck(TRUE); //Unverify timesheet if its already verified. $lf->setEnableCalcSystemTotalTime(TRUE); $lf->setEnableCalcWeeklySystemTotalTime(TRUE); $lf->setEnableCalcException(TRUE); $save_result[$key] = $lf->Save(); Debug::Text('zInsert ID: ' . $save_result[$key], __FILE__, __LINE__, __METHOD__, 10); if ($recalculate_user_date_id > 0) { UserDateTotalFactory::reCalculateDay($recalculate_user_date_id, FALSE, FALSE, FALSE, FALSE); } } $validator_stats['valid_records']++; } } if ($is_valid == FALSE) { Debug::Text('Data is Invalid...', __FILE__, __LINE__, __METHOD__, 10); $lf->FailTransaction(); //Just rollback this single record, continue on to the rest. if ($primary_validator->isValid() == FALSE) { $validator[$key] = $primary_validator->getErrorsArray(); } else { $validator[$key] = $lf->Validator->getErrorsArray(); } } elseif ($validate_only == TRUE) { $lf->FailTransaction(); } $lf->CommitTransaction(); $this->getProgressBarObject()->set($this->getAMFMessageID(), $key); } $this->getProgressBarObject()->stop($this->getAMFMessageID()); if ($validator_stats['valid_records'] > 0 and $validator_stats['total_records'] == $validator_stats['valid_records']) { if ($validator_stats['total_records'] == 1) { return $this->returnHandler($save_result[$key]); //Single valid record } else { return $this->returnHandler(TRUE, 'SUCCESS', TTi18n::getText('MULTIPLE RECORDS SAVED'), $save_result, $validator_stats); //Multiple valid records } } else { return $this->returnHandler(FALSE, 'VALIDATION', TTi18n::getText('INVALID DATA'), $validator, $validator_stats); } } return $this->returnHandler(FALSE); }