* CRM_Utils_Date::intervalAdd( $params['frequency_unit'], $i * ($params['frequency_interval']) , calculateBaseScheduledDate( &$params )))
*
* @param array $params
- * @param int $paymentNo
*
* @return array
* Next scheduled date as an array
*/
- public static function calculateBaseScheduleDate(&$params, $paymentNo = NULL) {
+ public static function calculateBaseScheduleDate(&$params) {
$date = array();
$scheduled_date = CRM_Utils_Date::processDate($params['scheduled_date']);
$date['year'] = (int) substr($scheduled_date, 0, 4);
$date['month'] = (int) substr($scheduled_date, 4, 2);
$date['day'] = (int) substr($scheduled_date, 6, 2);
- $date['hour'] = (int) substr($scheduled_date, 7, 2);
- $date['minute'] = (int) substr($scheduled_date, 9, 2);
- $date['seconds'] = (int) substr($scheduled_date, 11, 2);
// calculation of schedule date according to frequency day of period
// frequency day is not applicable for daily installments
if ($params['frequency_unit'] != 'day' && $params['frequency_unit'] != 'year') {
if ($params['frequency_unit'] != 'week') {
// CRM-18316: To calculate pledge scheduled dates at the end of a month.
$date['day'] = $params['frequency_day'];
- $interval = $paymentNo * ($params['frequency_interval']);
- $lastDayOfMonth = date('t', mktime($date['hour'], $date['minute'], $date['seconds'], $date['month'] + $interval, 1, $date['year']));
+ $lastDayOfMonth = date('t', mktime(0, 0, 0, $date['month'], 1, $date['year']));
if ($lastDayOfMonth < $date['day']) {
$date['day'] = $lastDayOfMonth;
}
* formatted date
*/
public static function calculateNextScheduledDate(&$params, $paymentNo, $basePaymentDate = NULL) {
+ $interval = $paymentNo * ($params['frequency_interval']);
if (!$basePaymentDate) {
- $basePaymentDate = self::calculateBaseScheduleDate($params, $paymentNo);
+ $basePaymentDate = self::calculateBaseScheduleDate($params);
+ }
+
+ //CRM-18316 - change $basePaymentDate for the end dates of the month eg: 29, 30 or 31.
+ if ($params['frequency_unit'] == 'month' && in_array($params['frequency_day'], array(29, 30, 31))) {
+ $frequency = $params['frequency_day'];
+ extract(date_parse($basePaymentDate));
+ $lastDayOfMonth = date('t', mktime($hour, $minute, $second, $month + $interval, 1, $year));
+ // Take the last day in case the current month is Feb or frequency_day is set to 31.
+ if (in_array($lastDayOfMonth, array(28, 29)) || $frequency == 31) {
+ $frequency = 0;
+ $interval++;
+ }
+ $basePaymentDate = array(
+ 'M' => $month,
+ 'd' => $frequency,
+ 'Y' => $year,
+ );
}
+
return CRM_Utils_Date::format(
CRM_Utils_Date::intervalAdd(
$params['frequency_unit'],
- $paymentNo * ($params['frequency_interval']),
+ $interval,
$basePaymentDate
)
);
'frequency_day' => 31,
'frequency_interval' => 1,
);
- $scheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 2);
- $this->assertEquals('20110731000000', $scheduleDate);
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 2);
+ $this->assertEquals('20110731000000', $nextScheduleDate);
// assert pledge scheduled date for month february.
- $scheduleDateForFeb = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 9);
- $this->assertEquals('20120229000000', $scheduleDateForFeb);
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 9);
+ $this->assertEquals('20120229000000', $nextScheduleDate);
//Case: Frequency day = 31 and scheduled date = 31st of any month
$params['scheduled_date'] = '20110131';
$params['frequency_day'] = 31;
- $scheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 1);
- $this->assertEquals('20110228000000', $scheduleDate);
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 1);
+ $this->assertEquals('20110228000000', $nextScheduleDate);
//Case: Frequency day = 30 and scheduled date = 30th of any month
$params['scheduled_date'] = '20110130';
$params['frequency_day'] = 30;
- $scheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 3);
- $this->assertEquals('20110430000000', $scheduleDate);
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 3);
+ $this->assertEquals('20110430000000', $nextScheduleDate);
//Case: Frequency day = 30 and scheduled date = any day of month
$params['scheduled_date'] = '20110110';
$params['frequency_day'] = 30;
- $scheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 4);
- $this->assertEquals('20110530000000', $scheduleDate);
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 4);
+ $this->assertEquals('20110530000000', $nextScheduleDate);
//Case: Frequency day = any and scheduled date = 31st of any month
$params['scheduled_date'] = '20110131';
$params['frequency_day'] = 5;
- $scheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 5);
- $this->assertEquals('20110605000000', $scheduleDate);
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 5);
+ $this->assertEquals('20110605000000', $nextScheduleDate);
- //Case: Frequency day = any AND Satrt date = 30th of any month
+ //Case: Frequency day = any AND scheduled date = 30th of any month
$params['scheduled_date'] = '20110130';
$params['frequency_day'] = 10;
- $scheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 6);
- $this->assertEquals('20110710000000', $scheduleDate);
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 6);
+ $this->assertEquals('20110710000000', $nextScheduleDate);
- //Case: Frequency day = any AND Satrt date = any day month
+ //Case: Frequency day = any AND scheduled date = any day month
$params['scheduled_date'] = '20110124';
$params['frequency_day'] = 6;
- $scheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 7);
- $this->assertEquals('20110806000000', $scheduleDate);
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 7);
+ $this->assertEquals('20110806000000', $nextScheduleDate);
+
+ //Case: Frequency day = 31 AND scheduled date = 29 Feb
+ $params['scheduled_date'] = '20160229';
+ $params['frequency_day'] = 31;
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 5);
+ $this->assertEquals('20160731000000', $nextScheduleDate);
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 6);
+ $this->assertEquals('20160831000000', $nextScheduleDate);
+ //check date for february
+ $nextScheduleDate = CRM_Pledge_BAO_PledgePayment::calculateNextScheduledDate($params, 12);
+ $this->assertEquals('20170228000000', $nextScheduleDate);
}
/**