function preSave() { if ($this->getFrequency() == 40) { if (TTDate::getDayOfMonth($this->getStartDate()) > 28) { Debug::text(' Start Date is After the 28th, making the 28th: ', __FILE__, __LINE__, __METHOD__, 10); $this->setStartDate(TTDate::getDateOfNextDayOfMonth($this->getStartDate(), strtotime('28-Feb-05'))); } } if ($this->getType() == 10) { //If amount isn't set, but Rate and units are, calc amount for them. if (($this->getAmount() == NULL or $this->getAmount() == 0 or $this->getAmount() == '') and $this->getRate() !== NULL and $this->getUnits() !== NULL and $this->getRate() != 0 and $this->getUnits() != 0 and $this->getRate() != '' and $this->getUnits() != '') { $this->setAmount(bcmul($this->getRate(), $this->getUnits(), 4)); } } if ($this->isNew() == TRUE) { $this->first_insert = TRUE; } return TRUE; }
function getNextPayPeriod($end_date = NULL) { if (!$this->Validator->isValid()) { return FALSE; } //Manual Pay Period Schedule, skip repeating... if ($this->getType() == 5) { return FALSE; } $pplf = new PayPeriodListFactory(); //Debug::text('PP Schedule ID: '. $this->getId(), __FILE__, __LINE__, __METHOD__, 10); //Debug::text('PP Schedule Name: '. $this->getName(), __FILE__, __LINE__, __METHOD__, 10); Debug::text('PP Schedule Type (' . $this->getType() . '): ' . Option::getByKey($this->getType(), $this->getOptions('type')), __FILE__, __LINE__, __METHOD__, 10); //Debug::text('Anchor Date: '. $this->getAnchorDate() ." - ". TTDate::getDate('DATE+TIME', $this->getAnchorDate() ), __FILE__, __LINE__, __METHOD__, 10); //Debug::text('Primary Date: '. $this->getPrimaryDate() ." - ". TTDate::getDate('DATE+TIME', $this->getPrimaryDate() ), __FILE__, __LINE__, __METHOD__, 10); //Debug::text('Secondary Date: '. $this->getSecondaryDate() ." - ". TTDate::getDate('DATE+TIME', $this->getPrimaryDate() ), __FILE__, __LINE__, __METHOD__, 10); $last_pay_period_is_new = FALSE; if ($end_date != '' and $end_date != 0) { Debug::text('End Date is set: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10); $last_pay_period_end_date = $end_date; } else { Debug::text('Checking for Previous pay periods...', __FILE__, __LINE__, __METHOD__, 10); //Get the last pay period schedule in the database. $pplf->getByPayPeriodScheduleId($this->getId(), NULL, NULL, NULL, array('start_date' => 'desc')); $last_pay_period = $pplf->getCurrent(); if ($last_pay_period->isNew()) { $last_pay_period_is_new = TRUE; Debug::text('No Previous pay periods...', __FILE__, __LINE__, __METHOD__, 10); //Do this so a rollover doesn't happen while we're calculating. //$last_pay_period_end_date = TTDate::getTime(); //This causes the pay period schedule to jump ahead one month. So set this to be beginning of the month. $last_pay_period_end_date = TTDate::getBeginMonthEpoch(); } else { Debug::text('Previous pay periods found... ID: ' . $last_pay_period->getId(), __FILE__, __LINE__, __METHOD__, 10); $last_pay_period_end_date = $last_pay_period->getEndDate(); } unset($last_pay_period, $pplf); } Debug::text('aLast Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $last_pay_period_end_date) . ' (' . $last_pay_period_end_date . ')', __FILE__, __LINE__, __METHOD__, 10); //FIXME: This breaks having pay periods with different daily start times. //However, without it, I think DST breaks pay periods. //$last_pay_period_end_date = TTDate::getEndDayEpoch( $last_pay_period_end_date + 1 ) - 86400; $last_pay_period_end_date = TTDate::getEndDayEpoch($last_pay_period_end_date - 86400 / 2); Debug::text('bLast Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $last_pay_period_end_date) . ' (' . $last_pay_period_end_date . ')', __FILE__, __LINE__, __METHOD__, 10); if ($this->getDayStartTime() != 0) { Debug::text('Daily Start Time is set, adjusting Last Pay Period End Date by: ' . TTDate::getHours($this->getDayStartTime()), __FILE__, __LINE__, __METHOD__, 10); //Next adjust last_pay_period_end_date (which becomes the start date) to DayStartTime because then there could be a gap if they //change this mid-schedule. The End Date will take care of it after the first pay period. $last_pay_period_end_date = TTDate::getTimeLockedDate(TTDate::getBeginDayEpoch($last_pay_period_end_date) + $this->getDayStartTime(), $last_pay_period_end_date); Debug::text('cLast Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $last_pay_period_end_date) . ' (' . $last_pay_period_end_date . ')', __FILE__, __LINE__, __METHOD__, 10); } $insert_pay_period = 1; //deprecate primary pay periods. switch ($this->getType()) { case 10: //Weekly //Weekly case 20: //Bi-Weekly $last_pay_period_end_day_of_week = TTDate::getDayOfWeek($last_pay_period_end_date); Debug::text('Last Pay Period End Day Of Week: ' . $last_pay_period_end_day_of_week . ' Start Day Of Week: ' . $this->getStartDayOfWeek(), __LINE__, __METHOD__, 10); if ($last_pay_period_end_day_of_week != $this->getStartDayOfWeek()) { Debug::text('zTmp Pay Period End Date: ' . 'next ' . TTDate::getDayOfWeekByInt($this->getStartDayOfWeek()), __FILE__, __LINE__, __METHOD__, 10); //$tmp_pay_period_end_date = strtotime('next '. TTDate::getDayOfWeekByInt( $this->getStartDayOfWeek() ), $last_pay_period_end_date )-1; $tmp_pay_period_end_date = strtotime('next ' . TTDate::getDayOfWeekByInt($this->getStartDayOfWeek(), FALSE), $last_pay_period_end_date); //strtotime doesn't keep time when using "next", it resets it to midnight on the day, so we need to adjust for that. $tmp_pay_period_end_date = TTDate::getTimeLockedDate(TTDate::getBeginDayEpoch($tmp_pay_period_end_date) + $this->getDayStartTime(), $tmp_pay_period_end_date) - 1; } else { $tmp_pay_period_end_date = $last_pay_period_end_date; //This should fix a bug where if they are creating a new pay period schedule //starting on Monday with the anchor date of 01-Jul-08, it would start on 01-Jul-08 (Tue) //rather moving back to the Monday. if (TTDate::getDayOfMonth($tmp_pay_period_end_date) != TTDate::getDayOfMonth($tmp_pay_period_end_date + 1)) { Debug::text('Right on day boundary, minus an additional second to account for difference...', __FILE__, __LINE__, __METHOD__, 10); $tmp_pay_period_end_date--; } } Debug::text('aTmp Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $tmp_pay_period_end_date) . ' (' . $tmp_pay_period_end_date . ')', __FILE__, __LINE__, __METHOD__, 10); $start_date = $tmp_pay_period_end_date + 1; if ($this->getType() == 10) { //Weekly $tmp_pay_period_end_date = TTDate::getMiddleDayEpoch($start_date) + 86400 * 7; //Add one week } elseif ($this->getType() == 20) { //Bi-Weekly $tmp_pay_period_end_date = TTDate::getMiddleDayEpoch($start_date) + 86400 * 14; //Add two weeks } //Use Begin Day Epoch to nullify DST issues. $end_date = TTDate::getBeginDayEpoch($tmp_pay_period_end_date) - 1; $transaction_date = TTDate::getMiddleDayEpoch(TTDate::getMiddleDayEpoch($end_date) + $this->getTransactionDate() * 86400); break; case 30: //Semi-monthly $tmp_last_pay_period_end_day_of_month = TTDate::getDayOfMonth($last_pay_period_end_date + 1); Debug::text('bLast Pay Period End Day Of Month: ' . $tmp_last_pay_period_end_day_of_month, __FILE__, __LINE__, __METHOD__, 10); if ($tmp_last_pay_period_end_day_of_month == $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth())) { $insert_pay_period = 1; $primary = TRUE; } elseif ($tmp_last_pay_period_end_day_of_month == $this->convertLastDayOfMonth($this->getSecondaryDayOfMonth())) { $insert_pay_period = 2; $primary = FALSE; } else { Debug::text('Finding if Primary or Secondary is closest...', __FILE__, __LINE__, __METHOD__, 10); $primary_date_offset = TTDate::getDateOfNextDayOfMonth($last_pay_period_end_date, NULL, $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth())) - $last_pay_period_end_date; $secondary_date_offset = TTDate::getDateOfNextDayOfMonth($last_pay_period_end_date, NULL, $this->convertLastDayOfMonth($this->getSecondaryDayOfMonth())) - $last_pay_period_end_date; Debug::text('Primary Date Offset: ' . TTDate::getDays($primary_date_offset) . ' Secondary Date Offset: ' . TTDate::getDays($secondary_date_offset), __FILE__, __LINE__, __METHOD__, 10); if ($primary_date_offset <= $secondary_date_offset) { $insert_pay_period = 1; $primary = TRUE; $last_pay_period_end_date = TTDate::getDateOfNextDayOfMonth($last_pay_period_end_date, NULL, $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth())); } else { $insert_pay_period = 2; $primary = FALSE; $last_pay_period_end_date = TTDate::getDateOfNextDayOfMonth($last_pay_period_end_date, NULL, $this->convertLastDayOfMonth($this->getSecondaryDayOfMonth())); } $last_pay_period_end_date = TTDate::getBeginDayEpoch($last_pay_period_end_date); } unset($tmp_last_pay_period_end_day_of_month); Debug::text('cLast Pay Period End Date: ' . TTDate::getDate('DATE+TIME', $last_pay_period_end_date) . ' (' . $last_pay_period_end_date . ') Primary: ' . (int) $primary, __FILE__, __LINE__, __METHOD__, 10); $start_date = $last_pay_period_end_date + 1; if ($primary == TRUE) { $end_date = TTDate::getBeginDayEpoch(TTDate::getDateOfNextDayOfMonth($start_date, NULL, $this->convertLastDayOfMonth($this->getSecondaryDayOfMonth()))) - 1; $transaction_date = TTDate::getMiddleDayEpoch(TTDate::getDateOfNextDayOfMonth(TTDate::getMiddleDayEpoch($end_date), NULL, $this->convertLastDayOfMonth($this->getPrimaryTransactionDayOfMonth()))); } else { $end_date = TTDate::getBeginDayEpoch(TTDate::getDateOfNextDayOfMonth($start_date, NULL, $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth()))) - 1; $transaction_date = TTDate::getMiddleDayEpoch(TTDate::getDateOfNextDayOfMonth(TTDate::getMiddleDayEpoch($end_date), NULL, $this->convertLastDayOfMonth($this->getSecondaryTransactionDayOfMonth()))); } break; case 50: //Monthly $start_date = $last_pay_period_end_date + 1; $end_date = TTDate::getDateOfNextDayOfMonth($start_date + 86400, NULL, $this->convertLastDayOfMonth($this->getPrimaryDayOfMonth())); //Use Begin Day Epoch to nullify DST issues. $end_date = TTDate::getBeginDayEpoch(TTDate::getBeginMinuteEpoch($end_date)) - 1; $transaction_date = TTDate::getMiddleDayEpoch(TTDate::getDateOfNextDayOfMonth($end_date, NULL, $this->convertLastDayOfMonth($this->getPrimaryTransactionDayOfMonth()))); break; } if ($this->getDayStartTime() != 0) { Debug::text('Daily Start Time is set, adjusting End Date by: ' . TTDate::getHours($this->getDayStartTime()) . ' Start Date: ' . TTDate::getDate('DATE+TIME', $start_date), __FILE__, __LINE__, __METHOD__, 10); //We already account for DayStartTime in weekly/bi-weekly start_date cases above, so skip applying it again here. if ($this->getType() != 10 and $this->getType() != 20) { $start_date = $start_date + $this->getDayStartTime(); } $end_date = $end_date + $this->getDayStartTime(); //Need to do this, otherwise transaction date could be earlier then end date. $transaction_date = $transaction_date + $this->getDayStartTime(); } Debug::text('aStart Date(' . $start_date . '): ' . TTDate::getDate('DATE+TIME', $start_date), __FILE__, __LINE__, __METHOD__, 10); Debug::text('aEnd Date(' . $end_date . '): ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10); Debug::text('aPay Date(' . $transaction_date . '): ' . TTDate::getDate('DATE+TIME', $transaction_date), __FILE__, __LINE__, __METHOD__, 10); //Handle last day of the month flag for primary and secondary dates here if ($this->getType() == 30 and ($insert_pay_period == 1 and ($this->getPrimaryDayOfMonth() == 31 or $this->getPrimaryDayOfMonth() == -1) or $insert_pay_period == 2 and ($this->getSecondaryDayOfMonth() == 31 or $this->getSecondaryDayOfMonth() == -1)) or $this->getType() == 50 and ($this->getPrimaryDayOfMonth() == 31 or $this->getPrimaryDayOfMonth() == -1)) { Debug::text('Last day of the month set for start date: ', __FILE__, __LINE__, __METHOD__, 10); if ($this->getDayStartTime() > 0) { //Minus one day, THEN add daily start time, otherwise it will go past the month boundary $end_date = TTDate::getEndMonthEpoch($end_date) - 86400 + $this->getDayStartTime(); //End month epoch is 23:59:59, so don't minus one. } else { $end_date = TTDate::getEndMonthEpoch($end_date) + $this->getDayStartTime(); //End month epoch is 23:59:59, so don't minus one. } } //Handle "last day of the month" for transaction dates. if ($this->getPrimaryDayOfMonth() == 31 or $this->getPrimaryDayOfMonth() == -1) { //Debug::text('LDOM set for Primary: ', __FILE__, __LINE__, __METHOD__, 10); $transaction_date = TTDate::getEndMonthEpoch($transaction_date); } //Handle "always business day" flag for transaction dates here. if ($this->getTransactionDateBusinessDay() == TRUE) { $transaction_date = $this->getTransactionBusinessDay($transaction_date); } if ($transaction_date < $end_date) { $transaction_date = $end_date; } Debug::text('Start Date: ' . TTDate::getDate('DATE+TIME', $start_date), __FILE__, __LINE__, __METHOD__, 10); Debug::text('End Date: ' . TTDate::getDate('DATE+TIME', $end_date), __FILE__, __LINE__, __METHOD__, 10); Debug::text('Pay Date: ' . TTDate::getDate('DATE+TIME', $transaction_date), __FILE__, __LINE__, __METHOD__, 10); Debug::text("<br><br>\n\n", __FILE__, __LINE__, __METHOD__, 10); $this->next_start_date = $start_date; $this->next_end_date = $end_date; $this->next_transaction_date = $transaction_date; //Its a primary pay period if ($insert_pay_period == 1) { $this->next_primary = TRUE; } else { $this->next_primary = FALSE; } return TRUE; }
function test_getDateOfNextDayOfMonth() { Debug::text('Testing Date Format: Y-m-d', __FILE__, __LINE__, __METHOD__, 10); TTDate::setDateFormat('Y-m-d'); TTDate::setTimeZone('PST'); TTDate::setTimeFormat('g:i A'); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('01-Dec-06'), strtotime('02-Dec-06')), strtotime('02-Dec-06')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('14-Dec-06'), strtotime('23-Nov-06')), strtotime('23-Dec-06')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('14-Dec-06'), strtotime('13-Dec-06')), strtotime('13-Jan-07')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('14-Dec-06'), strtotime('14-Dec-06')), strtotime('14-Dec-06')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('12-Dec-06'), strtotime('01-Dec-04')), strtotime('01-Jan-07')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('12-Dec-06'), NULL, 1), strtotime('01-Jan-07')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('12-Dec-06'), NULL, 12), strtotime('12-Dec-06')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('12-Dec-06'), NULL, 31), strtotime('31-Dec-06')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('01-Feb-07'), NULL, 31), strtotime('28-Feb-07')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('01-Feb-08'), NULL, 29), strtotime('29-Feb-08')); $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('01-Feb-08'), NULL, 31), strtotime('29-Feb-08')); //Anchor Epoch: 09-Apr-04 11:59 PM PDT Day Of Month Epoch: Day Of Month: 24<br> $this->assertEquals(TTDate::getDateOfNextDayOfMonth(strtotime('09-Apr-04'), NULL, 24), strtotime('24-Apr-04')); }