示例#1
0
 function createAccrualBalance($user_id, $accrual_policy_id, $type = 30)
 {
     $af = new AccrualFactory();
     $af->setUser($user_id);
     $af->setType($type);
     //Awarded
     $af->setAccrualPolicyID($accrual_policy_id);
     $af->setAmount(rand(3600 * 8, 3600 * 24));
     $af->setTimeStamp(time() - 86400 * 3);
     $af->setEnableCalcBalance(TRUE);
     if ($af->isValid()) {
         $insert_id = $af->Save();
         Debug::Text('Accrual ID: ' . $insert_id, __FILE__, __LINE__, __METHOD__, 10);
         return $insert_id;
     }
     Debug::Text('Failed Creating Accrual Balance!', __FILE__, __LINE__, __METHOD__, 10);
     return FALSE;
 }
extract(FormVariables::GetVariables(array('action', 'id', 'user_id', 'filter_user_id', 'accrual_policy_id', 'data')));
if (isset($data)) {
    $data['time_stamp'] = TTDate::parseDateTime($data['time_stamp']);
    $data['amount'] = TTDate::parseTimeUnit($data['amount']);
}
$af = new AccrualFactory();
$action = Misc::findSubmitButton();
$action = strtolower($action);
switch ($action) {
    case 'submit':
        Debug::Text('Submit!', __FILE__, __LINE__, __METHOD__, 10);
        $af->setId($data['id']);
        $af->setUser($data['user_id']);
        $af->setType($data['type_id']);
        $af->setAccrualPolicyID($data['accrual_policy_id']);
        $af->setAmount($data['amount']);
        $af->setTimeStamp($data['time_stamp']);
        $af->setEnableCalcBalance(TRUE);
        if ($af->isValid()) {
            $af->Save();
            Redirect::Page(URLBuilder::getURL(array('filter_user_id' => $data['user_id']), 'UserAccrualBalanceList.php'));
            break;
        }
    default:
        if (isset($id)) {
            BreadCrumb::setCrumb($title);
            $alf = new AccrualListFactory();
            $alf->getById($id);
            foreach ($alf as $a_obj) {
                //Debug::Arr($station,'Department', __FILE__, __LINE__, __METHOD__,10);
                $data = array('id' => $a_obj->getId(), 'user_id' => $a_obj->getUser(), 'accrual_policy_id' => $a_obj->getAccrualPolicyID(), 'type_id' => $a_obj->getType(), 'amount' => $a_obj->getAmount(), 'time_stamp' => $a_obj->getTimeStamp(), 'user_date_total_id' => $a_obj->getUserDateTotalID(), 'created_date' => $a_obj->getCreatedDate(), 'created_by' => $a_obj->getCreatedBy(), 'updated_date' => $a_obj->getUpdatedDate(), 'updated_by' => $a_obj->getUpdatedBy(), 'deleted_date' => $a_obj->getDeletedDate(), 'deleted_by' => $a_obj->getDeletedBy());
 function addAccrualPolicyTime($epoch = NULL, $offset = 79200, $daily_total_time = NULL)
 {
     //22hr offset
     if ($epoch == '') {
         $epoch = TTDate::getTime();
     }
     Debug::Text('Accrual Policy ID: ' . $this->getId() . ' Current EPOCH: ' . TTDate::getDate('DATE+TIME', $epoch), __FILE__, __LINE__, __METHOD__, 10);
     $pglf = new PolicyGroupListFactory();
     $pglf->StartTransaction();
     $pglf->getSearchByCompanyIdAndArrayCriteria($this->getCompany(), array('accrual_policy_id' => array($this->getId())));
     if ($pglf->getRecordCount() > 0) {
         Debug::Text('Found Policy Group...', __FILE__, __LINE__, __METHOD__, 10);
         foreach ($pglf as $pg_obj) {
             //Get all users assigned to this policy group.
             $policy_group_users = $pg_obj->getUser();
             if (is_array($policy_group_users) and count($policy_group_users) > 0) {
                 Debug::Text('Found Policy Group Users: ' . count($policy_group_users), __FILE__, __LINE__, __METHOD__, 10);
                 foreach ($policy_group_users as $user_id) {
                     Debug::Text('Policy Group User ID: ' . $user_id, __FILE__, __LINE__, __METHOD__, 10);
                     //Get User Object
                     $ulf = new UserListFactory();
                     $ulf->getByIDAndCompanyID($user_id, $this->getCompany());
                     if ($ulf->getRecordCount() == 1) {
                         $u_obj = $ulf->getCurrent();
                         Debug::Text('User: '******' Status: ' . $u_obj->getStatus(), __FILE__, __LINE__, __METHOD__, 10);
                         //Make sure only active employees accrue time. Will this negative affect
                         //Employees who may be on leave?
                         if ($u_obj->getStatus() == 10 and ($this->getMinimumEmployedDays() == 0 or TTDate::getDays($epoch - $u_obj->getHireDate()) >= $this->getMinimumEmployedDays())) {
                             Debug::Text('  User is active and has been employed long enough.', __FILE__, __LINE__, __METHOD__, 10);
                             $annual_pay_periods = 0;
                             $in_apply_frequency_window = FALSE;
                             $accrual_balance = 0;
                             $accrual_amount = 0;
                             if ($this->getType() == 30) {
                                 Debug::Text('  Accrual policy is hour based, real-time window.', __FILE__, __LINE__, __METHOD__, 10);
                                 //Hour based, apply frequency is real-time.
                                 $in_apply_frequency_window = TRUE;
                             } else {
                                 if ($this->getApplyFrequency() == 10) {
                                     //Because of pay period frequencies, and users being assigned to different
                                     //pay period schedules we need to get the last pay period of each user individually.
                                     //This will return the pay period that just ended in the offset time.
                                     $pplf = new PayPeriodListFactory();
                                     $pplf->getByUserIdAndEndDate($user_id, $epoch - $offset);
                                     if ($pplf->getRecordCount() > 0) {
                                         foreach ($pplf as $pp_obj) {
                                             Debug::Text('  Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $pp_obj->getEndDate()), __FILE__, __LINE__, __METHOD__, 10);
                                             if ($this->inApplyFrequencyWindow($epoch, $offset, $pp_obj->getEndDate()) == TRUE) {
                                                 $in_apply_frequency_window = TRUE;
                                                 $annual_pay_periods = $pp_obj->getPayPeriodScheduleObject()->getAnnualPayPeriods();
                                                 break;
                                             } else {
                                                 Debug::Text('  User not in Apply Frequency Window: ', __FILE__, __LINE__, __METHOD__, 10);
                                             }
                                         }
                                     } else {
                                         Debug::Text('   No Pay Period Found.', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } elseif ($this->inApplyFrequencyWindow($epoch, $offset) == TRUE) {
                                     Debug::Text('  User IS in NON-PayPeriod Apply Frequency Window.', __FILE__, __LINE__, __METHOD__, 10);
                                     $in_apply_frequency_window = TRUE;
                                 } else {
                                     Debug::Text('  User is not in Apply Frequency Window.', __FILE__, __LINE__, __METHOD__, 10);
                                     $in_apply_frequency_window = FALSE;
                                 }
                             }
                             if ($in_apply_frequency_window == TRUE) {
                                 $milestone_obj = $this->getActiveMilestoneObject($u_obj, $epoch);
                                 if (isset($milestone_obj) and is_object($milestone_obj)) {
                                     Debug::Text('  Found Matching Milestone, Accrual Rate: (ID: ' . $milestone_obj->getId() . ') ' . $milestone_obj->getAccrualRate() . '/year', __FILE__, __LINE__, __METHOD__, 10);
                                     $accrual_balance = $this->getCurrentAccrualBalance($user_id, $this->getId());
                                     if ($accrual_balance < $milestone_obj->getMaximumTime()) {
                                         $accrual_amount = $this->calcAccrualAmount($milestone_obj, 0, $annual_pay_periods);
                                         if ($accrual_amount > 0) {
                                             $new_accrual_balance = bcadd($accrual_balance, $accrual_amount);
                                             //If Maximum time is set to 0, make that unlimited.
                                             if ($milestone_obj->getMaximumTime() > 0 and $new_accrual_balance > $milestone_obj->getMaximumTime()) {
                                                 $accrual_amount = bcsub($milestone_obj->getMaximumTime(), $accrual_balance, 0);
                                             }
                                             Debug::Text('&nbsp;&nbsp; Min/Max Adjusted Accrual Amount: ' . $accrual_amount . ' Limits: Min: ' . $milestone_obj->getMinimumTime() . ' Max: ' . $milestone_obj->getMaximumTime(), __FILE__, __LINE__, __METHOD__, 10);
                                             //Check to make sure there isn't an identical entry already made.
                                             $alf = new AccrualListFactory();
                                             $alf->getByCompanyIdAndUserIdAndAccrualPolicyIDAndTimeStampAndAmount($u_obj->getCompany(), $user_id, $this->getId(), TTDate::getMiddleDayEpoch($epoch), $accrual_amount);
                                             if ($alf->getRecordCount() == 0) {
                                                 //Round to nearest 1min
                                                 $af = new AccrualFactory();
                                                 $af->setUser($user_id);
                                                 $af->setType(75);
                                                 //Accrual Policy
                                                 $af->setAccrualPolicyID($this->getId());
                                                 $af->setAmount($accrual_amount);
                                                 $af->setTimeStamp(TTDate::getMiddleDayEpoch($epoch));
                                                 $af->setEnableCalcBalance(TRUE);
                                                 if ($af->isValid()) {
                                                     $af->Save();
                                                 }
                                             } else {
                                                 Debug::Text('&nbsp;&nbsp; Found duplicate accrual entry, skipping...', __FILE__, __LINE__, __METHOD__, 10);
                                             }
                                             unset($accrual_amount, $accrual_balance, $new_accrual_balance);
                                         } else {
                                             Debug::Text('&nbsp;&nbsp; Accrual Amount is 0...', __FILE__, __LINE__, __METHOD__, 10);
                                         }
                                     } else {
                                         Debug::Text('&nbsp;&nbsp; Accrual Balance is outside Milestone Range. Skipping...', __FILE__, __LINE__, __METHOD__, 10);
                                     }
                                 } else {
                                     Debug::Text('&nbsp;&nbsp;DID NOT Find Matching Milestone.', __FILE__, __LINE__, __METHOD__, 10);
                                 }
                                 unset($milestone_obj);
                             }
                         } else {
                             Debug::Text('&nbsp;&nbsp;User is not active (Status: ' . $u_obj->getStatus() . ') or has only been employed: ' . TTDate::getDays($epoch - $u_obj->getHireDate()) . ' Days, not enough.', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     } else {
                         Debug::Text('No User Found. Company ID: ' . $this->getCompany(), __FILE__, __LINE__, __METHOD__, 10);
                     }
                 }
             }
         }
     }
     $pglf->CommitTransaction();
     return TRUE;
 }
 function calcAccrualPolicy()
 {
     //FIXME: There is a minor bug for hour based accruals that if a milestone has a maximum limit,
     //  and an employee recalculates there timesheet, and the limit is reached midweek, if its recalculated
     //  again, the days that get the accrual time won't always be in order because the accrual balance is deleted
     //  only for the day currently being calculated, so on Monday it will delete 1hr of accrual, but the balance will
     //  still include Tue,Wed,Thu and the limit may already be reached.
     //We still need to calculate accruals even if the total time is 0, because we may want to override a
     //policy to 0hrs, and if we skip entries with TotalTime() == 0, the accruals won't be updated.
     if ($this->getDeleted() == FALSE) {
         Debug::text('Calculating Accrual Policies... Total Time: ' . $this->getTotalTime() . ' Date: ' . TTDate::getDate('DATE', $this->getUserDateObject()->getDateStamp()), __FILE__, __LINE__, __METHOD__, 10);
         //Calculate accrual policies assigned to other overtime/premium/absence policies
         //Debug::text('ID: '. $this->getId() .' Overtime Policy ID: '. (int)$this->getOverTimePolicyID()  .' Premium Policy ID: '. (int)$this->getPremiumPolicyID() .' Absence Policy ID: '. (int)$this->getAbsencePolicyID(), __FILE__, __LINE__, __METHOD__, 10);
         //If overtime, premium or absence policy is an accrual, handle that now.
         if ($this->getOverTimePolicyID() != FALSE) {
             $accrual_policy_id = $this->getOverTimePolicyObject()->getAccrualPolicyID();
             Debug::text('Over Time Accrual Policy ID: ' . $accrual_policy_id, __FILE__, __LINE__, __METHOD__, 10);
             if ($accrual_policy_id > 0) {
                 Debug::text('Over Time Accrual Rate: ' . $this->getOverTimePolicyObject()->getAccrualRate() . ' Policy ID: ' . $this->getOverTimePolicyObject()->getAccrualPolicyID(), __FILE__, __LINE__, __METHOD__, 10);
                 $af = new AccrualFactory();
                 $af->setUser($this->getUserDateObject()->getUser());
                 $af->setAccrualPolicyID($accrual_policy_id);
                 $af->setUserDateTotalID($this->getID());
                 $accrual_amount = bcmul($this->getTotalTime(), $this->getOverTimePolicyObject()->getAccrualRate());
                 if ($accrual_amount > 0) {
                     $af->setType(10);
                     //Banked
                 } else {
                     $af->setType(20);
                     //Used
                 }
                 $af->setAmount($accrual_amount);
                 $af->setEnableCalcBalance(TRUE);
                 if ($af->isValid()) {
                     $af->Save();
                 }
                 unset($accrual_amount);
             } else {
                 Debug::text('Skipping Over Time Accrual Policy ID: ' . $accrual_policy_id, __FILE__, __LINE__, __METHOD__, 10);
             }
         }
         if ($this->getPremiumPolicyID() != FALSE) {
             $accrual_policy_id = $this->getPremiumPolicyObject()->getAccrualPolicyID();
             Debug::text('Premium Accrual Policy ID: ' . $accrual_policy_id, __FILE__, __LINE__, __METHOD__, 10);
             if ($accrual_policy_id > 0) {
                 $af = new AccrualFactory();
                 $af->setUser($this->getUserDateObject()->getUser());
                 $af->setAccrualPolicyID($accrual_policy_id);
                 $af->setUserDateTotalID($this->getID());
                 $accrual_amount = bcmul($this->getTotalTime(), $this->getPremiumPolicyObject()->getAccrualRate());
                 if ($accrual_amount > 0) {
                     $af->setType(10);
                     //Banked
                 } else {
                     $af->setType(20);
                     //Used
                 }
                 $af->setAmount($accrual_amount);
                 $af->setEnableCalcBalance(TRUE);
                 if ($af->isValid()) {
                     $af->Save();
                 }
                 unset($accrual_amount);
             }
         }
         if ($this->getAbsencePolicyID() != FALSE) {
             $accrual_policy_id = $this->getAbsencePolicyObject()->getAccrualPolicyID();
             Debug::text('Absence Accrual Policy ID: ' . $accrual_policy_id, __FILE__, __LINE__, __METHOD__, 10);
             if ($accrual_policy_id > 0) {
                 $af = new AccrualFactory();
                 $af->setUser($this->getUserDateObject()->getUser());
                 $af->setAccrualPolicyID($accrual_policy_id);
                 $af->setUserDateTotalID($this->getID());
                 //By default we withdraw from accrual policy, so if there is a negative rate, deposit instead.
                 $accrual_amount = bcmul($this->getTotalTime(), bcmul($this->getAbsencePolicyObject()->getAccrualRate(), -1));
                 if ($accrual_amount > 0) {
                     $af->setType(10);
                     //Banked
                 } else {
                     $af->setType(20);
                     //Used
                 }
                 $af->setAmount($accrual_amount);
                 $af->setEnableCalcBalance(TRUE);
                 if ($af->isValid()) {
                     $af->Save();
                 }
             }
         }
         unset($af, $accrual_policy_id);
         //Calculate any hour based accrual policies.
         //if ( $this->getType() == 10 AND $this->getStatus() == 10 ) {
         if ($this->getStatus() == 10 and in_array($this->getType(), array(20, 30))) {
             //Calculate hour based accruals on regular/overtime only.
             $aplf = new AccrualPolicyListFactory();
             $aplf->getByPolicyGroupUserIdAndType($this->getUserDateObject()->getUser(), 30);
             if ($aplf->getRecordCount() > 0) {
                 Debug::text('Found Hour Based Accrual Policies to apply.', __FILE__, __LINE__, __METHOD__, 10);
                 foreach ($aplf as $ap_obj) {
                     if ($ap_obj->getMinimumEmployedDays() == 0 or TTDate::getDays($this->getUserDateObject()->getDateStamp() - $this->getUserDateObject()->getUserObject()->getHireDate()) >= $ap_obj->getMinimumEmployedDays()) {
                         Debug::Text('&nbsp;&nbsp;User has been employed long enough.', __FILE__, __LINE__, __METHOD__, 10);
                         $milestone_obj = $ap_obj->getActiveMilestoneObject($this->getUserDateObject()->getUserObject(), $this->getUserDateObject()->getDateStamp());
                         $accrual_balance = $ap_obj->getCurrentAccrualBalance($this->getUserDateObject()->getUserObject()->getId(), $ap_obj->getId());
                         //If Maximum time is set to 0, make that unlimited.
                         if (is_object($milestone_obj) and ($milestone_obj->getMaximumTime() == 0 or $accrual_balance < $milestone_obj->getMaximumTime())) {
                             $accrual_amount = $ap_obj->calcAccrualAmount($milestone_obj, $this->getTotalTime(), 0);
                             if ($accrual_amount > 0) {
                                 $new_accrual_balance = bcadd($accrual_balance, $accrual_amount);
                                 //If Maximum time is set to 0, make that unlimited.
                                 if ($milestone_obj->getMaximumTime() > 0 and $new_accrual_balance > $milestone_obj->getMaximumTime()) {
                                     $accrual_amount = bcsub($milestone_obj->getMaximumTime(), $accrual_balance, 4);
                                 }
                                 Debug::Text('&nbsp;&nbsp; Min/Max Adjusted Accrual Amount: ' . $accrual_amount . ' Limits: Min: ' . $milestone_obj->getMinimumTime() . ' Max: ' . $milestone_obj->getMaximumTime(), __FILE__, __LINE__, __METHOD__, 10);
                                 $af = new AccrualFactory();
                                 $af->setUser($this->getUserDateObject()->getUserObject()->getId());
                                 $af->setType(75);
                                 //Accrual Policy
                                 $af->setAccrualPolicyID($ap_obj->getId());
                                 $af->setUserDateTotalID($this->getID());
                                 $af->setAmount($accrual_amount);
                                 $af->setTimeStamp($this->getUserDateObject()->getDateStamp());
                                 $af->setEnableCalcBalance(TRUE);
                                 if ($af->isValid()) {
                                     $af->Save();
                                 }
                                 unset($accrual_amount, $accrual_balance, $new_accrual_balance);
                             } else {
                                 Debug::Text('&nbsp;&nbsp; Accrual Amount is 0...', __FILE__, __LINE__, __METHOD__, 10);
                             }
                         } else {
                             Debug::Text('&nbsp;&nbsp; Accrual Balance is outside Milestone Range. Or no milestone found. Skipping...', __FILE__, __LINE__, __METHOD__, 10);
                         }
                     } else {
                         Debug::Text('&nbsp;&nbsp;User has only been employed: ' . TTDate::getDays($this->getUserDateObject()->getDateStamp() - $this->getUserDateObject()->getUserObject()->getHireDate()) . ' Days, not enough.', __FILE__, __LINE__, __METHOD__, 10);
                     }
                 }
             } else {
                 Debug::text('No Hour Based Accrual Policies to apply.', __FILE__, __LINE__, __METHOD__, 10);
             }
         } else {
             Debug::text('No worked time on this day or not proper type/status, skipping hour based accrual policies...', __FILE__, __LINE__, __METHOD__, 10);
         }
     }
     /*
     //FIXME: Figure a better way to re-calculate accrual policies assigned to absences to update accrual balances
     if ( $this->getEnableCalcAccrualPolicy() == TRUE ) {
     	Debug::text('Recalculating Accruals assigned to absence policies...', __FILE__, __LINE__, __METHOD__, 10);
     
     	$udtlf = new UserDateTotalListFactory();
     	$udtlf->getByUserDateIdAndStatus( $this->getUserDateID(), 30 ); //Absences only
     	if ( $udtlf->getRecordCount() > 0 ) {
     		foreach( $udtlf as $udt_obj ) {
     			$accrual_policy_id = $udt_obj->getAbsencePolicyObject()->getAccrualPolicyID();
     			Debug::text('Absence Accrual Policy ID: '. $accrual_policy_id, __FILE__, __LINE__, __METHOD__, 10);
     
     			if ( $accrual_policy_id > 0 AND $this->getTotalTime() > 0 ) {
     				$af = new AccrualFactory();
     				$af->setUser( $this->getUserDateObject()->getUser() );
     				$af->setAccrualPolicyID( $accrual_policy_id );
     				$af->setType(20);
     				$af->setUserDateTotalID( $udt_obj->getID() );
     				$af->setAmount( bcmul( $udt_obj->getTotalTime(), -1 ) );
     				$af->setEnableCalcBalance(TRUE);
     				if ( $af->isValid() ) {
     					$af->Save();
     				}
     			}
     		}
     	}
     } else {
     	Debug::text('NOT Recalculating Accruals assigned to absence policies...', __FILE__, __LINE__, __METHOD__, 10);
     }
     */
     return TRUE;
 }