function setOfflinePunch($data)
 {
     Debug::Text('Setting Offline Punches... Rows: ' . count($data), __FILE__, __LINE__, __METHOD__, 10);
     //
     //WHen in Offline mode, default Type/Status to "AUTO"...
     //That way once I get the punches, I can determine what they should be on my end.
     //
     if (!is_array($data) or count($data) == 0) {
         return FALSE;
     }
     ksort($data);
     //Debug::Arr($data, 'offlinePunchDataArr', __FILE__, __LINE__, __METHOD__,10);
     /*
     		//Original
     		$data[] = array(
     						'user_id' => 1,
     						'time_stamp' => '12:00 PM',
     						'date_stamp' => '03-Dec-05',
     						'branch_id' => 1,
     						'department_id' => NULL,
     						'status_id' => 20,
     						'type_id' => 20,
     						'punch_control_id' => 0,
     						'station_id' => '7D00000023352A81'
     						);
     */
     /*
     		unset($data);
     
     		$data[] = array(
     						'user_id' => 1001,
     						'time_stamp' => '08:00 AM',
     						'date_stamp' => '05-Dec-05',
     						'branch_id' => 5,
     						'department_id' => 3,
     						'status_id' => 0,
     						'type_id' => 0,
     						'punch_control_id' => 0,
     						'station_id' => '7D00000023352A81'
     						);
     
     		$data[] = array(
     						'user_id' => 1001,
     						'time_stamp' => '12:00 PM',
     						'date_stamp' => '05-Dec-05',
     						'branch_id' => 0,
     						'department_id' => 3,
     						'status_id' => 20,
     						'type_id' => 0,
     						'punch_control_id' => 0,
     						'station_id' => '7D00000023352A81'
     						);
     */
     /*
     		$data[] = array(
     						'user_id' => 1001,
     						'time_stamp' => '1:00 PM',
     						'date_stamp' => '05-Dec-05',
     						'branch_id' => 6,
     						'department_id' => 0,
     						'status_id' => 0,
     						'type_id' => 20,
     						'punch_control_id' => 0,
     						'station_id' => '7D00000023352A81'
     						);
     */
     /*
     		$data[] = array(
     						'user_id' => 1001,
     						'time_stamp' => '5:00 PM',
     						'date_stamp' => '05-Dec-05',
     						'branch_id' => 0,
     						'department_id' => 0,
     						'status_id' => 0,
     						'type_id' => 0,
     						'punch_control_id' => 0,
     						'station_id' => '7D00000023352A81'
     						);
     */
     //Debug::Arr($data, 'offlinePunchDataArr', __FILE__, __LINE__, __METHOD__,10);
     //One punch per row
     foreach ($data as $row_key => $punch_row) {
         Debug::Text('--------------------------========================---------------------------', __FILE__, __LINE__, __METHOD__, 10);
         Debug::Text('--------------------------========================---------------------------', __FILE__, __LINE__, __METHOD__, 10);
         Debug::Text('Row Key: ' . $row_key . ' Date: ' . $punch_row['date_stamp'] . ' Time: ' . $punch_row['time_stamp'] . ' Station ID: ' . $punch_row['station_id'], __FILE__, __LINE__, __METHOD__, 10);
         if (isset($punch_row['station_id'])) {
             $slf = new StationListFactory();
             $slf->getByStationId($punch_row['station_id']);
             if ($slf->getRecordCount() > 0) {
                 Debug::Text('Found Station Data...', __FILE__, __LINE__, __METHOD__, 10);
                 $current_station = $slf->getCurrent();
             } else {
                 Debug::Text('DID NOT Find Station Data...', __FILE__, __LINE__, __METHOD__, 10);
                 continue;
             }
             unset($slf);
         }
         if (isset($punch_row['user_id']) and $punch_row['user_id'] != '') {
             $ulf = new UserListFactory();
             $ulf->getById($punch_row['user_id']);
             if ($ulf->getRecordCount() > 0) {
                 $current_user = $ulf->getCurrent();
                 Debug::Text('Valid User ID: ' . $punch_row['user_id'] . ' User Name: ' . $current_user->getFullName(), __FILE__, __LINE__, __METHOD__, 10);
                 //Need to handle timezone somehow. The station should send us the system's timezone
                 //so we can calculate based on that.
                 //Or just use the employees date preference.
                 $current_user->getUserPreferenceObject()->setDateTimePreferences();
             } else {
                 Debug::Text('aInValid User ID: ' . $punch_row['user_id'], __FILE__, __LINE__, __METHOD__, 10);
                 continue;
             }
         } else {
             Debug::Text('bInValid User ID: ' . $punch_row['user_id'], __FILE__, __LINE__, __METHOD__, 10);
             continue;
         }
         //Check to make sure the station is allowed.
         if (is_object($current_station) and is_object($current_user) and $current_station->checkAllowed($current_user->getId(), $current_station->getStation(), $current_station->getType()) == FALSE) {
             Debug::text('Station NOT allowed: Station ID: ' . $current_station->getId() . ' User: '******'date_stamp'] . ' ' . $punch_row['time_stamp']);
         //Make sure time stamp converts properly, otherwise skip this punch.
         if (!is_int($punch_full_time_stamp)) {
             Debug::Text('Failed TimeStamp: ' . $punch_full_time_stamp, __FILE__, __LINE__, __METHOD__, 10);
             continue;
         }
         Debug::Text('Punch Date/Time: ' . $punch_full_time_stamp . ' Offset that was already applied: ' . $punch_row['offset'], __FILE__, __LINE__, __METHOD__, 10);
         $fail_transaction = FALSE;
         $pf = new PunchFactory();
         $pf->StartTransaction();
         $slf = new ScheduleListFactory();
         //Auto Punch
         if (isset($punch_row['status_id']) and $punch_row['status_id'] == 0 or isset($punch_row['type_id']) and $punch_row['type_id'] == 0 or isset($punch_row['branch_id']) and $punch_row['branch_id'] == 0 or isset($punch_row['department_id']) and $punch_row['department_id'] == 0 or isset($punch_row['job_id']) and $punch_row['job_id'] == 0 or isset($punch_row['job_item_id']) and $punch_row['job_item_id'] == 0) {
             $plf = new PunchListFactory();
             $plf->getPreviousPunchByUserIDAndEpoch($punch_row['user_id'], $punch_full_time_stamp);
             if ($plf->getRecordCount() > 0) {
                 Debug::Text(' Found Previous Punch within Continuous Time from now: ', __FILE__, __LINE__, __METHOD__, 10);
                 $prev_punch_obj = $plf->getCurrent();
                 $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();
                 $quantity = $prev_punch_obj->getPunchControlObject()->getQuantity();
                 $bad_quantity = $prev_punch_obj->getPunchControlObject()->getBadQuantity();
                 if ($branch_id == '' or empty($branch_id) or $department_id == '' or empty($department_id)) {
                     Debug::Text(' Branch or department are null. ', __FILE__, __LINE__, __METHOD__, 10);
                     $s_obj = $slf->getScheduleObjectByUserIdAndEpoch($punch_row['user_id'], $punch_full_time_stamp);
                     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();
                         }
                     }
                 }
                 $type_id = $prev_punch_obj->getNextType();
                 $status_id = $prev_punch_obj->getNextStatus();
                 $next_type = $prev_punch_obj->getNextType();
                 //Check for break policy window.
                 if ($next_type != 30 and ($prev_punch_obj->getStatus() != 30 and $prev_punch_obj->getType() != 30)) {
                     $prev_punch_obj->setUser($current_user->getId());
                     $prev_punch_obj->setScheduleID($prev_punch_obj->findScheduleID($punch_full_time_stamp));
                     if ($prev_punch_obj->inBreakPolicyWindow($punch_full_time_stamp, $prev_punch_obj->getTimeStamp()) == TRUE) {
                         Debug::Text(' Setting Type to Break: ', __FILE__, __LINE__, __METHOD__, 10);
                         $next_type = 30;
                     }
                 }
                 //Check for meal policy window.
                 if ($next_type != 20 and ($prev_punch_obj->getStatus() != 20 and $prev_punch_obj->getType() != 20)) {
                     $prev_punch_obj->setUser($current_user->getId());
                     $prev_punch_obj->setScheduleID($prev_punch_obj->findScheduleID($punch_full_time_stamp));
                     if ($prev_punch_obj->inMealPolicyWindow($punch_full_time_stamp, $prev_punch_obj->getTimeStamp()) == TRUE) {
                         Debug::Text(' Setting Type to Lunch: ', __FILE__, __LINE__, __METHOD__, 10);
                         $next_type = 20;
                     }
                 }
             } 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($punch_row['user_id'], $punch_full_time_stamp);
                 if (is_object($s_obj)) {
                     Debug::Text(' Found Schedule!: ', __FILE__, __LINE__, __METHOD__, 10);
                     $branch_id = $s_obj->getBranch();
                     $department_id = $s_obj->getDepartment();
                 } else {
                     $branch_id = $current_user->getDefaultBranch();
                     $department_id = $current_user->getDefaultDepartment();
                     //Check station for default/forced settings.
                     if (is_object($current_station)) {
                         if ($current_station->getDefaultBranch() !== FALSE and $current_station->getDefaultBranch() != 0) {
                             $branch_id = $current_station->getDefaultBranch();
                         }
                         if ($current_station->getDefaultDepartment() !== FALSE and $current_station->getDefaultDepartment() != 0) {
                             $department_id = $current_station->getDefaultDepartment();
                         }
                         if ($current_station->getDefaultJob() !== FALSE and $current_station->getDefaultJob() != 0) {
                             $job_id = $current_station->getDefaultJob();
                         }
                         if ($current_station->getDefaultJobItem() !== FALSE and $current_station->getDefaultJobItem() != 0) {
                             $job_item_id = $current_station->getDefaultJobItem();
                         }
                     }
                 }
                 $status_id = 10;
                 //In
                 $type_id = 10;
                 //Normal
             }
             if (isset($punch_row['status_id']) and $punch_row['status_id'] != 0) {
                 Debug::Text(' Status ID is NOT AUTO: ' . $punch_row['status_id'], __FILE__, __LINE__, __METHOD__, 10);
                 $status_id = $punch_row['status_id'];
             }
             if (isset($punch_row['type_id']) and $punch_row['type_id'] != 0) {
                 Debug::Text(' Type ID is NOT AUTO: ' . $punch_row['type_id'], __FILE__, __LINE__, __METHOD__, 10);
                 $type_id = $punch_row['type_id'];
             }
             if (isset($punch_row['branch_id']) and $punch_row['branch_id'] != 0) {
                 Debug::Text(' Branch ID is NOT AUTO: ' . $punch_row['branch_id'], __FILE__, __LINE__, __METHOD__, 10);
                 $branch_id = $punch_row['branch_id'];
             }
             if (isset($punch_row['department_id']) and $punch_row['department_id'] != 0) {
                 Debug::Text(' Department ID is NOT AUTO: ' . $punch_row['department_id'], __FILE__, __LINE__, __METHOD__, 10);
                 $department_id = $punch_row['department_id'];
             }
             if (isset($punch_row['job_id']) and $punch_row['job_id'] != 0) {
                 Debug::Text(' Job ID is NOT AUTO: ' . $punch_row['job_id'], __FILE__, __LINE__, __METHOD__, 10);
                 $job_id = $punch_row['job_id'];
             }
             if (isset($punch_row['job_item_id']) and $punch_row['job_item_id'] != 0) {
                 Debug::Text(' Job Item ID is NOT AUTO: ' . $punch_row['job_item_id'], __FILE__, __LINE__, __METHOD__, 10);
                 $job_item_id = $punch_row['job_item_id'];
             }
             if (isset($punch_row['quantity'])) {
                 Debug::Text(' Quantity is NOT AUTO: ' . $punch_row['quantity'], __FILE__, __LINE__, __METHOD__, 10);
                 $quantity = $punch_row['quantity'];
             }
             if (isset($punch_row['bad_quantity'])) {
                 Debug::Text(' Bad Quantity is NOT AUTO: ' . $punch_row['bad_quantity'], __FILE__, __LINE__, __METHOD__, 10);
                 $bad_quantity = $punch_row['bad_quantity'];
             }
         } else {
             $status_id = $punch_row['status_id'];
             $type_id = $punch_row['type_id'];
             $branch_id = $punch_row['branch_id'];
             $department_id = $punch_row['department_id'];
             $job_id = $punch_row['job_id'];
             $job_item_id = $punch_row['job_item_id'];
             $quantity = $punch_row['quantity'];
             $bad_quantity = $punch_row['bad_quantity'];
         }
         //Set User before setTimeStamp so rounding can be done properly.
         $pf->setUser($punch_row['user_id']);
         if (isset($punch_row['transfer']) and $punch_row['transfer'] == 1) {
             Debug::Text(' Enabling Transfer!: ', __FILE__, __LINE__, __METHOD__, 10);
             $type_id = 10;
             $status_id = 10;
             $pf->setTransfer(TRUE);
         }
         $pf->setType($type_id);
         $pf->setStatus($status_id);
         $pf->setTimeStamp($punch_full_time_stamp, TRUE);
         //Make sure we round here.
         if (isset($status_id) and $status_id == 20 and isset($punch_row['punch_control_id']) and $punch_row['punch_control_id'] != '' and $punch_row['punch_control_id'] != 0) {
             $pf->setPunchControlID($punch_row['punch_control_id']);
         } else {
             $pf->setPunchControlID($pf->findPunchControlID());
         }
         $pf->setStation($current_station->getId());
         if ($pf->isNew()) {
             $pf->setActualTimeStamp($punch_full_time_stamp);
             $pf->setOriginalTimeStamp($pf->getTimeStamp());
         }
         if ($pf->isValid() == TRUE) {
             if ($pf->Save(FALSE) == TRUE) {
                 $pcf = new PunchControlFactory();
                 $pcf->setId($pf->getPunchControlID());
                 $pcf->setPunchObject($pf);
                 if (isset($branch_id) and $branch_id != '') {
                     $pcf->setBranch($branch_id);
                 }
                 if (isset($department_id) and $department_id != '') {
                     $pcf->setDepartment($department_id);
                 }
                 if (isset($job_id) and $job_id != '') {
                     $pcf->setJob($job_id);
                 }
                 if (isset($job_item_id) and $job_item_id != '') {
                     $pcf->setJobItem($job_item_id);
                 }
                 if (isset($quantity) and $quantity != '') {
                     $pcf->setQuantity($quantity);
                 }
                 if (isset($bad_quantity) and $bad_quantity != '') {
                     $pcf->setBadQuantity($bad_quantity);
                 }
                 if (isset($punch_row['note']) and $punch_row['note'] != '') {
                     $pcf->setNote($punch_row['note']);
                 }
                 if (isset($punch_row['other_id1']) and $punch_row['other_id1'] != '') {
                     $pcf->setOtherID1($punch_row['other_id1']);
                 }
                 if (isset($punch_row['other_id2']) and $punch_row['other_id2'] != '') {
                     $pcf->setOtherID2($punch_row['other_id2']);
                 }
                 if (isset($punch_row['other_id3']) and $punch_row['other_id3'] != '') {
                     $pcf->setOtherID3($punch_row['other_id3']);
                 }
                 if (isset($punch_row['other_id4']) and $punch_row['other_id4'] != '') {
                     $pcf->setOtherID4($punch_row['other_id4']);
                 }
                 if (isset($punch_row['other_id5']) and $punch_row['other_id5'] != '') {
                     $pcf->setOtherID5($punch_row['other_id5']);
                 }
                 $pcf->setEnableStrictJobValidation(TRUE);
                 $pcf->setEnableCalcUserDateID(TRUE);
                 $pcf->setEnableCalcTotalTime(TRUE);
                 $pcf->setEnableCalcSystemTotalTime(TRUE);
                 $pcf->setEnableCalcUserDateTotal(TRUE);
                 $pcf->setEnableCalcException(TRUE);
                 $pcf->setEnablePreMatureException(TRUE);
                 //Enable pre-mature exceptions at this point.
                 if ($pcf->isValid() == TRUE) {
                     Debug::Text(' Punch Control is valid, saving...: ', __FILE__, __LINE__, __METHOD__, 10);
                     if ($pcf->Save(TRUE, TRUE) == TRUE) {
                         //Force isNew() lookup.
                         Debug::text('Saved Punch!', __FILE__, __LINE__, __METHOD__, 10);
                     } else {
                         Debug::text('PCF Save failed... Failing Transaction!', __FILE__, __LINE__, __METHOD__, 10);
                         $fail_transaction = TRUE;
                     }
                 } else {
                     Debug::text('PCF Validate failed... Failing Transaction!', __FILE__, __LINE__, __METHOD__, 10);
                     $fail_transaction = TRUE;
                 }
             } else {
                 Debug::text('PF Save failed... Failing Transaction!', __FILE__, __LINE__, __METHOD__, 10);
                 $fail_transaction = TRUE;
             }
         } else {
             Debug::text('PF Validate failed... Failing Transaction!', __FILE__, __LINE__, __METHOD__, 10);
             $fail_transaction = TRUE;
         }
         if ($fail_transaction == FALSE) {
             $pf->CommitTransaction();
         } else {
             $pf->FailTransaction();
         }
         unset($punch_full_time_stamp, $current_station, $current_user);
         //End Foreach
     }
     return TRUE;
 }
Beispiel #2
0
 }
 if (isset($pc_data['other_id2'])) {
     $pcf->setOtherID2($pc_data['other_id2']);
 }
 if (isset($pc_data['other_id3'])) {
     $pcf->setOtherID3($pc_data['other_id3']);
 }
 if (isset($pc_data['other_id4'])) {
     $pcf->setOtherID4($pc_data['other_id4']);
 }
 if (isset($pc_data['other_id5'])) {
     $pcf->setOtherID5($pc_data['other_id5']);
 }
 $pcf->setEnableStrictJobValidation(TRUE);
 $pcf->setEnableCalcUserDateID(TRUE);
 $pcf->setEnableCalcTotalTime(TRUE);
 $pcf->setEnableCalcSystemTotalTime(TRUE);
 $pcf->setEnableCalcWeeklySystemTotalTime(TRUE);
 $pcf->setEnableCalcUserDateTotal(TRUE);
 $pcf->setEnableCalcException(TRUE);
 if ($pcf->isValid() == TRUE) {
     Debug::Text(' Punch Control is valid, saving...: ', __FILE__, __LINE__, __METHOD__, 10);
     if ($pcf->Save(TRUE, TRUE) != TRUE) {
         //Force isNew() lookup.
         Debug::Text(' aFail Transaction: ', __FILE__, __LINE__, __METHOD__, 10);
         $fail_transaction = TRUE;
         break;
     }
 } else {
     Debug::Text(' bFail Transaction: ', __FILE__, __LINE__, __METHOD__, 10);
     $fail_transaction = TRUE;
 function preSave()
 {
     if ($this->isNew()) {
         //Debug::text(' Setting Original TimeStamp: '. $this->getTimeStamp(), __FILE__, __LINE__, __METHOD__,10);
         $this->setOriginalTimeStamp($this->getTimeStamp());
     }
     if ($this->getDeleted() == FALSE) {
         if ($this->getTransfer() == TRUE and $this->getEnableAutoTransfer() == TRUE) {
             Debug::text(' Transfer is Enabled, automatic punch out of last punch pair: ', __FILE__, __LINE__, __METHOD__, 10);
             //Check to make sure there is an open punch pair.
             $plf = new PunchListFactory();
             $plf->getPreviousPunchByUserIdAndEpoch($this->getUser(), $this->getTimeStamp());
             if ($plf->getRecordCount() > 0) {
                 $p_obj = $plf->getCurrent();
                 Debug::text(' Found Last Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                 if ($p_obj->getStatus() == 10) {
                     Debug::text(' Last Punch was in. Auto Punch Out now: ', __FILE__, __LINE__, __METHOD__, 10);
                     //Make sure the current punch status is IN
                     $this->setStatus(10);
                     //In
                     $this->setType(10);
                     //Normal (can't transfer in/out of lunches?)
                     $pf = new PunchFactory();
                     $pf->setUser($this->getUser());
                     $pf->setEnableAutoTransfer(FALSE);
                     $pf->setPunchControlID($p_obj->getPunchControlID());
                     $pf->setTransfer(TRUE);
                     $pf->setType($p_obj->getNextType());
                     $pf->setStatus(20);
                     //Out
                     $pf->setTimeStamp($this->getTimeStamp(), FALSE);
                     //Disable rounding.
                     $pf->setActualTimeStamp($this->getTimeStamp());
                     $pf->setOriginalTimeStamp($this->getTimeStamp());
                     if ($pf->isValid()) {
                         if ($pf->Save(FALSE) == TRUE) {
                             $p_obj->getPunchControlObject()->setEnableCalcTotalTime(TRUE);
                             $p_obj->getPunchControlObject()->setEnableCalcSystemTotalTime(TRUE);
                             $p_obj->getPunchControlObject()->setEnableCalcUserDateTotal(TRUE);
                             $p_obj->getPunchControlObject()->setEnableCalcException(TRUE);
                             $p_obj->getPunchControlObject()->setEnablePreMatureException(TRUE);
                             if ($p_obj->getPunchControlObject()->isValid()) {
                                 $p_obj->getPunchControlObject()->Save();
                             } else {
                                 Debug::text(' aError saving auto out punch...', __FILE__, __LINE__, __METHOD__, 10);
                             }
                         } else {
                             Debug::text(' bError saving auto out punch...', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     } else {
                         Debug::text(' cError saving auto out punch...', __FILE__, __LINE__, __METHOD__, 10);
                     }
                 } else {
                     Debug::text(' Last Punch was out. No Auto Punch ', __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
             unset($plf, $p_obj, $pf);
         }
         //Split punch at midnight.
         //This has to be an Out punch, and the previous punch has to be an in punch in order for the split to occur.
         //Check to make sure there is an open punch pair.
         //Make sure this punch isn't right at midnight either, as no point in splitting a punch at that time.
         //FIXME: What happens if a supervisor edits a 11:30PM punch and makes it 5:00AM the next day?
         //		We can't split punches when editing, because we have to split punch_control_ids prior to saving etc...
         if ($this->isNew() == TRUE and $this->getStatus() == 20 and $this->getEnableSplitAtMidnight() == TRUE and $this->getTimeStamp() != TTDate::getBeginDayEpoch($this->getTimeStamp()) and (is_object($this->getPunchControlObject()) and is_object($this->getPunchControlObject()->getPayPeriodScheduleObject()) and $this->getPunchControlObject()->getPayPeriodScheduleObject()->getShiftAssignedDay() == 40)) {
             $plf = new PunchListFactory();
             $plf->getPreviousPunchByUserIdAndEpoch($this->getUser(), $this->getTimeStamp());
             if ($plf->getRecordCount() > 0) {
                 $p_obj = $plf->getCurrent();
                 Debug::text(' Found Last Punch: ', __FILE__, __LINE__, __METHOD__, 10);
                 if ($p_obj->getStatus() == 10 and TTDate::doesRangeSpanMidnight($this->getTimeStamp(), $p_obj->getTimeStamp())) {
                     Debug::text(' Last Punch was in and this is an out punch that spans midnight. Split Punch at midnight now: ', __FILE__, __LINE__, __METHOD__, 10);
                     //FIXME: This will fail if a shift spans multiple days!
                     //Make sure the current punch status is OUT
                     //But we can split LUNCH/Break punches, because someone could punch in at 8PM, then out for lunch at 1:00AM, this would need to be split.
                     $this->setStatus(20);
                     //Out
                     //Reduce the out punch by 60 seconds, and increase the current punch by 60seconds so no time is lost.
                     $this->setTimeStamp($this->getTimeStamp() + 60);
                     //FIXME: May need to use ActualTimeStamp here so we aren't double rounding.
                     //Get new punch control ID for the midnight punch and this one.
                     $new_punch_control_id = $this->getPunchControlObject()->getNextInsertId();
                     $this->setPunchControlID($new_punch_control_id);
                     Debug::text(' Split Punch: Punching out just before midnight yesterday...', __FILE__, __LINE__, __METHOD__, 10);
                     //
                     //Punch out just before midnight
                     //
                     $pf = new PunchFactory();
                     $pf->setUser($this->getUser());
                     $pf->setEnableSplitAtMidnight(FALSE);
                     $pf->setTransfer(FALSE);
                     $pf->setEnableAutoTransfer(FALSE);
                     $pf->setType(10);
                     //Normal
                     $pf->setStatus(20);
                     //Out
                     $before_midnight_timestamp = TTDate::getBeginDayEpoch($this->getTimeStamp()) - 60;
                     $pf->setTimeStamp($before_midnight_timestamp, FALSE);
                     //Disable rounding.
                     $pf->setActualTimeStamp($before_midnight_timestamp);
                     $pf->setOriginalTimeStamp($before_midnight_timestamp);
                     $pf->setPunchControlID($p_obj->getPunchControlID());
                     if ($pf->isValid()) {
                         if ($pf->Save(FALSE) == TRUE) {
                             $p_obj->getPunchControlObject()->setEnableCalcTotalTime(TRUE);
                             $p_obj->getPunchControlObject()->setEnableCalcSystemTotalTime(TRUE);
                             $p_obj->getPunchControlObject()->setEnableCalcUserDateTotal(TRUE);
                             $p_obj->getPunchControlObject()->setEnableCalcException(TRUE);
                             $p_obj->getPunchControlObject()->setEnablePreMatureException(TRUE);
                             $p_obj->getPunchControlObject()->Save();
                         }
                     }
                     unset($pf, $p_obj, $before_midnight_timestamp);
                     Debug::text(' Split Punch: Punching int at midnight today...', __FILE__, __LINE__, __METHOD__, 10);
                     //
                     //Punch in again right at midnight.
                     //
                     $pf = new PunchFactory();
                     $pf->setUser($this->getUser());
                     $pf->setEnableSplitAtMidnight(FALSE);
                     $pf->setTransfer(FALSE);
                     $pf->setEnableAutoTransfer(FALSE);
                     $pf->setType(10);
                     //Normal
                     $pf->setStatus(10);
                     //In
                     $at_midnight_timestamp = TTDate::getBeginDayEpoch($this->getTimeStamp());
                     $pf->setTimeStamp($at_midnight_timestamp, FALSE);
                     //Disable rounding.
                     $pf->setActualTimeStamp($at_midnight_timestamp);
                     $pf->setOriginalTimeStamp($at_midnight_timestamp);
                     $pf->setPunchControlID($new_punch_control_id);
                     if ($pf->isValid()) {
                         if ($pf->Save(FALSE) == TRUE) {
                             $pcf = new PunchControlFactory();
                             $pcf->setId($pf->getPunchControlID());
                             $pcf->setPunchObject($pf);
                             $pcf->setBranch($this->getPunchControlObject()->getBranch());
                             $pcf->setDepartment($this->getPunchControlObject()->getDepartment());
                             $pcf->setJob($this->getPunchControlObject()->getJob());
                             $pcf->setJobItem($this->getPunchControlObject()->getJobItem());
                             $pcf->setOtherID1($this->getPunchControlObject()->getOtherID1());
                             $pcf->setOtherID2($this->getPunchControlObject()->getOtherID2());
                             $pcf->setOtherID3($this->getPunchControlObject()->getOtherID3());
                             $pcf->setOtherID4($this->getPunchControlObject()->getOtherID4());
                             $pcf->setOtherID5($this->getPunchControlObject()->getOtherID5());
                             $pcf->setEnableStrictJobValidation(TRUE);
                             $pcf->setEnableCalcUserDateID(TRUE);
                             $pcf->setEnableCalcTotalTime(TRUE);
                             $pcf->setEnableCalcSystemTotalTime(TRUE);
                             $pcf->setEnableCalcWeeklySystemTotalTime(TRUE);
                             $pcf->setEnableCalcUserDateTotal(TRUE);
                             $pcf->setEnableCalcException(TRUE);
                             if ($pcf->isValid() == TRUE) {
                                 $pcf->Save(TRUE, TRUE);
                                 //Force isNEW() lookup.
                             }
                         }
                     }
                     unset($pf, $at_midnight_timestamp, $new_punch_control_id);
                 } else {
                     Debug::text(' Last Punch was out. No Auto Punch ', __FILE__, __LINE__, __METHOD__, 10);
                 }
             }
         }
     }
     return TRUE;
 }
 function createPunchPair($user_id, $in_time_stamp, $out_time_stamp, $data = NULL, $calc_total_time = TRUE)
 {
     $fail_transaction = FALSE;
     Debug::Text('Punch Full In Time Stamp: (' . $in_time_stamp . ') ' . TTDate::getDate('DATE+TIME', $in_time_stamp) . ' Out: (' . $out_time_stamp . ') ' . TTDate::getDate('DATE+TIME', $out_time_stamp), __FILE__, __LINE__, __METHOD__, 10);
     $pf = new PunchFactory();
     $pf->StartTransaction();
     //Out Punch
     //Save out punch first so the $pf object is for the In Punch if there is one.
     if ($out_time_stamp !== NULL) {
         $pf_in = new PunchFactory();
         $pf_in->setTransfer(FALSE);
         $pf_in->setUser($user_id);
         $pf_in->setType($data['out_type_id']);
         $pf_in->setStatus(20);
         $pf_in->setTimeStamp($out_time_stamp);
         if ($pf_in->isNew()) {
             $pf_in->setActualTimeStamp($out_time_stamp);
             $pf_in->setOriginalTimeStamp($pf_in->getTimeStamp());
         }
         $pf_in->setPunchControlID($pf_in->findPunchControlID());
         if ($pf_in->isValid()) {
             if ($pf_in->Save(FALSE) === FALSE) {
                 Debug::Text(' aFail Transaction: ', __FILE__, __LINE__, __METHOD__, 10);
                 $fail_transaction = TRUE;
             }
         }
     }
     if ($in_time_stamp !== NULL) {
         //In Punch
         $pf_out = new PunchFactory();
         $pf_out->setTransfer(FALSE);
         $pf_out->setUser($user_id);
         $pf_out->setType($data['in_type_id']);
         $pf_out->setStatus(10);
         $pf_out->setTimeStamp($in_time_stamp);
         if ($pf_out->isNew()) {
             $pf_out->setActualTimeStamp($in_time_stamp);
             $pf_out->setOriginalTimeStamp($pf_out->getTimeStamp());
         }
         if (isset($pf_in) and $pf_in->getPunchControlID() != FALSE) {
             //Get Punch Control ID from above Out punch.
             $pf_out->setPunchControlID($pf_in->getPunchControlID());
         } else {
             $pf_out->setPunchControlID($pf_out->findPunchControlID());
         }
         if ($pf_out->isValid()) {
             if ($pf_out->Save(FALSE) === FALSE) {
                 Debug::Text(' aFail Transaction: ', __FILE__, __LINE__, __METHOD__, 10);
                 $fail_transaction = TRUE;
             }
         }
     }
     if ($fail_transaction == FALSE) {
         if (isset($pf_in) and is_object($pf_in)) {
             Debug::Text(' Using In Punch Object... TimeStamp: ' . $pf_in->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
             $pf = $pf_in;
         } elseif (isset($pf_out) and is_object($pf_out)) {
             Debug::Text(' Using Out Punch Object... TimeStamp: ' . $pf_out->getTimeStamp(), __FILE__, __LINE__, __METHOD__, 10);
             $pf = $pf_out;
         }
         $pcf = new PunchControlFactory();
         $pcf->setId($pf->getPunchControlID());
         $pcf->setPunchObject($pf);
         $pcf->setBranch($data['branch_id']);
         $pcf->setDepartment($data['department_id']);
         if (isset($data['job_id'])) {
             $pcf->setJob($data['job_id']);
         }
         if (isset($data['job_item_id'])) {
             $pcf->setJobItem($data['job_item_id']);
         }
         if (isset($data['quantity'])) {
             $pcf->setQuantity($data['quantity']);
         }
         if (isset($data['bad_quantity'])) {
             $pcf->setBadQuantity($data['bad_quantity']);
         }
         $pcf->setEnableCalcUserDateID(TRUE);
         $pcf->setEnableCalcTotalTime($calc_total_time);
         $pcf->setEnableCalcSystemTotalTime($calc_total_time);
         $pcf->setEnableCalcWeeklySystemTotalTime($calc_total_time);
         $pcf->setEnableCalcUserDateTotal($calc_total_time);
         $pcf->setEnableCalcException($calc_total_time);
         if ($pcf->isValid() == TRUE) {
             $punch_control_id = $pcf->Save(TRUE, TRUE);
             //Force lookup
             if ($fail_transaction == FALSE) {
                 Debug::Text('Punch Control ID: ' . $punch_control_id, __FILE__, __LINE__, __METHOD__, 10);
                 $pf->CommitTransaction();
                 return TRUE;
             }
         }
     }
     Debug::Text('Failed Creating Punch!', __FILE__, __LINE__, __METHOD__, 10);
     $pf->FailTransaction();
     return FALSE;
 }
    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::parseDateTime($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);
        $pf = new PunchFactory();
        $pf->StartTransaction();
        //Set User before setTimeStamp so rounding can be done properly.
        $pf->setUser($this->getUserObject()->getId());
        if (isset($data['transfer']) and $data['transfer'] == 1) {
            Debug::Text(' Enabling Transfer!: ', __FILE__, __LINE__, __METHOD__, 10);
            $data['type_id'] = 10;
            $data['status_id'] = 10;
            $pf->setTransfer(TRUE);
        }
        $pf->setType($data['type_id']);
        $pf->setStatus($data['status_id']);
        $pf->setTimeStamp($punch_full_time_stamp);
        if (isset($data['status_id']) and $data['status_id'] == 20 and isset($data['punch_control_id']) and $data['punch_control_id'] != '') {
            $pf->setPunchControlID($data['punch_control_id']);
        } else {
            $pf->setPunchControlID($pf->findPunchControlID());
        }
        $pf->setStation($this->getStationObject()->getId());
        if ($pf->isNew()) {
            $pf->setActualTimeStamp($punch_full_time_stamp);
            $pf->setOriginalTimeStamp($pf->getTimeStamp());
        }
        if ($pf->isValid() == TRUE) {
            $return_date = $pf->getTimeStamp();
            if ($pf->getStatus() == 10) {
                $label = 'In';
            } else {
                $label = 'Out';
            }
            if ($pf->Save(FALSE) == TRUE) {
                $pcf = new PunchControlFactory();
                $pcf->setId($pf->getPunchControlID());
                $pcf->setPunchObject($pf);
                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']);
                }
                //$pcf->setEnableStrictJobValidation( TRUE );
                $pcf->setEnableCalcUserDateID(TRUE);
                $pcf->setEnableCalcTotalTime(TRUE);
                $pcf->setEnableCalcSystemTotalTime(TRUE);
                $pcf->setEnableCalcUserDateTotal(TRUE);
                $pcf->setEnableCalcException(TRUE);
                $pcf->setEnablePreMatureException(TRUE);
                //Enable pre-mature exceptions at this point.
                if ($pcf->isValid() == TRUE) {
                    Debug::Text(' Punch Control is valid, saving...: ', __FILE__, __LINE__, __METHOD__, 10);
                    if ($pcf->Save(TRUE, TRUE) == TRUE) {
                        //Force isNew() lookup.
                        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>';
                        Debug::text('RetVal: ' . $retval, __FILE__, __LINE__, __METHOD__, 10);
                        //Set stations last punch time stamp so we can filter out duplicates later on.
                        //$pf->FailTransaction();
                        $pf->CommitTransaction();
                        return $retval;
                    } else {
                        Debug::text('Punch Control save failed!', __FILE__, __LINE__, __METHOD__, 10);
                    }
                } else {
                    Debug::text('Punch Control is NOT VALID!', __FILE__, __LINE__, __METHOD__, 10);
                }
            } else {
                Debug::text('Punch save failed!', __FILE__, __LINE__, __METHOD__, 10);
            }
        } else {
            Debug::text('Punch is NOT VALID: ', __FILE__, __LINE__, __METHOD__, 10);
        }
        $pf->FailTransaction();
        Debug::text('Returning FALSE: Action Failed! ', __FILE__, __LINE__, __METHOD__, 10);
        //Get text errors to display to the user.
        $errors = NULL;
        if (isset($pf) and is_object($pf)) {
            $errors .= $pf->Validator->getErrors();
        }
        if (isset($pcf) and is_object($pcf)) {
            $errors .= $pcf->Validator->getErrors();
        }
        $errors = wordwrap($errors, 40, "<br>\n");
        $retval = '<table bgcolor="red">
		<tr>
			<td style="font-size:28px; font-weight: bold">Action Failed!</td>
		</tr>
		<tr>
			<td style="font-size:14px; font-weight: bold">
				' . $errors . '
			</td>
		</tr>
		</table>';
        return $retval;
        //return FALSE;
    }