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; }
if ($i == 0 and isset($pc_data['id']) and $pc_data['id'] != '') { Debug::Text('Using existing Punch Control ID: ' . $pc_data['id'], __FILE__, __LINE__, __METHOD__, 10); $pf->setPunchControlID($pc_data['id']); } else { Debug::Text('Finding Punch Control ID: ' . $pc_data['id'], __FILE__, __LINE__, __METHOD__, 10); $pf->setPunchControlID($pf->findPunchControlID()); } if ($pf->isNew()) { $pf->setActualTimeStamp($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 ($i == 0 and $pc_data['user_date_id'] != '') { //This is important when editing a punch, without it there can be issues calculating exceptions //because if a specific punch was modified that caused the day to change, smartReCalculate //may only be able to recalculate a single day, instead of both. $pcf->setUserDateID($pc_data['user_date_id']); } if (isset($pc_data['branch_id'])) { $pcf->setBranch($pc_data['branch_id']); } if (isset($pc_data['department_id'])) { $pcf->setDepartment($pc_data['department_id']); } if (isset($pc_data['job_id'])) { $pcf->setJob($pc_data['job_id']); }
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 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; }
if ($pf_out->isValid()) { Debug::text('Punch Out: Valid!', __FILE__, __LINE__, __METHOD__, 10); $pf_out->setEnableCalcTotalTime(TRUE); $pf_out->setEnableCalcSystemTotalTime(TRUE); $pf_out->setEnableCalcUserDateTotal(TRUE); $pf_out->setEnableCalcException(TRUE); $pf_out->Save(FALSE); } else { Debug::text('Punch Out: InValid!', __FILE__, __LINE__, __METHOD__, 10); } if ($pf_in->isValid() == TRUE or $pf_out->isValid() == TRUE) { Debug::text('Punch In and Out succeeded, saving punch control!', __FILE__, __LINE__, __METHOD__, 10); $pcf = new PunchControlFactory(); $pcf->setId($pf_in->getPunchControlID()); if ($pf_in->isValid() == TRUE) { $pcf->setPunchObject($pf_in); } elseif ($pf_out->isValid() == TRUE) { $pcf->setPunchObject($pf_out); } if ($recurring_schedule_shift['branch_id'] == -1) { $pcf->setBranch($user_obj->getDefaultBranch()); } else { $pcf->setBranch($recurring_schedule_shift['branch_id']); } if ($recurring_schedule_shift['department_id'] == -1) { $pcf->setDepartment($user_obj->getDefaultDepartment()); } else { $pcf->setDepartment($recurring_schedule_shift['department_id']); } if (getTTProductEdition() == TT_PRODUCT_PROFESSIONAL) { if (isset($recurring_schedule_shift['job_id'])) {
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; }