Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ready for core review] CRM-19153 Fixed future payment dates for future start pledge dates #8785

Merged
merged 11 commits into from
Nov 14, 2016
9 changes: 7 additions & 2 deletions CRM/Contribute/BAO/Contribution/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ public static function processConfirm(
$paymentParams['contactID'] = $form->_params['contactID'] = $contactID;

//fix for CRM-16317
$form->_params['receive_date'] = date('YmdHis');
if (empty($form->_params['receive_date'])) {
$form->_params['receive_date'] = date('YmdHis');
}
if (!empty($form->_params['start_date'])) {
$form->_params['start_date'] = date('YmdHis');
}
$form->assign('receive_date',
CRM_Utils_Date::mysqlToIso($form->_params['receive_date'])
);
Expand Down Expand Up @@ -134,7 +139,7 @@ public static function processConfirm(
$paymentParams['source'] = $paymentParams['contribution_source'];
}

if ($form->_values['is_recur'] && $contribution->contribution_recur_id) {
if (CRM_Utils_Array::value('is_recur', $form->_params) && $contribution->contribution_recur_id) {
$paymentParams['contributionRecurID'] = $contribution->contribution_recur_id;
}
if (isset($paymentParams['contribution_source'])) {
Expand Down
16 changes: 8 additions & 8 deletions CRM/Contribute/Form/Contribution/Confirm.php
Original file line number Diff line number Diff line change
Expand Up @@ -949,10 +949,9 @@ public static function processFormContribution(
$pledgeParams['frequency_day'] = 1;
}
$pledgeParams['create_date'] = $pledgeParams['start_date'] = $pledgeParams['scheduled_date'] = date("Ymd");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mlutfy @eileenmcnaughton I don't want to cause more work for JMA ;) but shouldn't date formats in reports be drawn from civicrm/admin/setting/date?action=reset=1 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JoeMurray I think the question is what is the destination once we have formatted the date, In this case here we are in the processFormContribution so most likely we are going to be inserting a date into the DB so need for format it into a date format that the db knows and i think Ymd is common for that. If we are building a form or something public then yes we would need to consider localised date formats. At least that is my thinking but @mlutfy @eileenmcnaughton correct me if i am wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree @seamuslee001

$pledgeBlock = CRM_Pledge_BAO_PledgeBlock::getPledgeBlock($contribution->contribution_page_id);
if (CRM_Utils_Array::value('start_date', $params) || !CRM_Utils_Array::value('is_pledge_start_date_visible', $pledgeBlock)) {
$pledgeStartDate = CRM_Utils_Array::value('start_date', $params, NULL);
$pledgeParams['start_date'] = $pledgeParams['scheduled_date'] = CRM_Pledge_BAO_Pledge::getPledgeStartDate($pledgeStartDate, $pledgeBlock);
if (CRM_Utils_Array::value('start_date', $params)) {
$pledgeParams['frequency_day'] = intval(date("d", strtotime(CRM_Utils_Array::value('start_date', $params))));
$pledgeParams['start_date'] = $pledgeParams['scheduled_date'] = date('Ymd', strtotime(CRM_Utils_Array::value('start_date', $params)));
}
$pledgeParams['status_id'] = $contribution->contribution_status_id;
$pledgeParams['max_reminders'] = $form->_values['max_reminders'];
Expand Down Expand Up @@ -1094,7 +1093,7 @@ public static function processRecurringContribution(&$form, &$params, $contactID

$recurParams['start_date'] = $recurParams['create_date'] = $recurParams['modified_date'] = date('YmdHis');
if (!empty($params['receive_date'])) {
$recurParams['start_date'] = $params['receive_date'];
$recurParams['start_date'] = date('YmdHis', strtotime($params['receive_date']));
}
$recurParams['invoice_id'] = CRM_Utils_Array::value('invoiceID', $params);
$recurParams['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
Expand All @@ -1111,7 +1110,6 @@ public static function processRecurringContribution(&$form, &$params, $contactID

$campaignId = CRM_Utils_Array::value('campaign_id', $params, CRM_Utils_Array::value('campaign_id', $form->_values));
$recurParams['campaign_id'] = $campaignId;

$recurring = CRM_Contribute_BAO_ContributionRecur::add($recurParams);
if (is_a($recurring, 'CRM_Core_Error')) {
CRM_Core_Error::displaySessionError($recurring);
Expand Down Expand Up @@ -1877,6 +1875,7 @@ public static function submit($params) {
$form->_fields['billing_last_name'] = 1;
// CRM-18854 - Set form values to allow pledge to be created for api test.
if (CRM_Utils_Array::value('pledge_block_id', $params)) {
$form->_values['pledge_id'] = CRM_Utils_Array::value('pledge_id', $params, NULL);
$form->_values['pledge_block_id'] = $params['pledge_block_id'];
$pledgeBlock = CRM_Pledge_BAO_PledgeBlock::getPledgeBlock($params['id']);
$form->_values['max_reminders'] = $pledgeBlock['max_reminders'];
Expand Down Expand Up @@ -1972,9 +1971,10 @@ protected function processFormSubmission($contactID) {
$this->_params['currencyID'] = CRM_Core_Config::singleton()->defaultCurrency;

// CRM-18854
if (CRM_Utils_Array::value('adjust_recur_start_date', $this->_values)) {
if (CRM_Utils_Array::value('is_pledge', $this->_params) && !CRM_Utils_Array::value('pledge_id', $this->_values) && CRM_Utils_Array::value('adjust_recur_start_date', $this->_values)) {
$pledgeBlock = CRM_Pledge_BAO_PledgeBlock::getPledgeBlock($this->_id);
if (CRM_Utils_Array::value('start_date', $this->_params) || !CRM_Utils_Array::value('is_pledge_start_date_visible', $pledgeBlock)) {
if (CRM_Utils_Array::value('start_date', $this->_params) || !CRM_Utils_Array::value('is_pledge_start_date_visible', $pledgeBlock)
|| !CRM_Utils_Array::value('is_pledge_start_date_editable', $pledgeBlock)) {
$pledgeStartDate = CRM_Utils_Array::value('start_date', $this->_params, NULL);
$this->_params['receive_date'] = CRM_Pledge_BAO_Pledge::getPledgeStartDate($pledgeStartDate, $pledgeBlock);
$recurParams = CRM_Pledge_BAO_Pledge::buildRecurParams($this->_params);
Expand Down
2 changes: 1 addition & 1 deletion CRM/Contribute/Form/ContributionPage/Amount.php
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ public function postProcess() {
'calendar_month' => 'pledge_calendar_month',
);
if ($params['pledge_default_toggle'] == 'contribution_date') {
$fieldValue = json_encode(array('contribution_date' => date('Ymd')));
$fieldValue = json_encode(array('contribution_date' => date('m/d/Y')));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This smells a bit to me since there are settings for how dates are formatted. Just because the default format is American m/d/Y doesn't mean this will work in Canada for Ymd or d/m/Y formats. I'm going to see about creating an instance to check this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this change was made in order to match how CiviCRM saves dates when used from the datepicker. I will check with Pradeep to see if there are any CRM functions I should be using instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JoeMurray
I've checked and it looks good. Like @seamuslee001 mentioned above, this is only to save the current date in the database.

}
else {
foreach ($pledgeDateFields as $key => $pledgeDateField) {
Expand Down
12 changes: 7 additions & 5 deletions CRM/Pledge/BAO/Pledge.php
Original file line number Diff line number Diff line change
Expand Up @@ -1204,15 +1204,17 @@ public static function buildRecurParams($params) {
public static function getPledgeStartDate($date, $pledgeBlock) {
$startDate = (array) json_decode($pledgeBlock['pledge_start_date']);
list($field, $value) = each($startDate);
if (!CRM_Utils_Array::value('is_pledge_start_date_visible', $pledgeBlock)) {
return date('Ymd', strtotime($value));
}
if (!CRM_Utils_Array::value('is_pledge_start_date_editable', $pledgeBlock)) {
if (!empty($date) && !CRM_Utils_Array::value('is_pledge_start_date_editable', $pledgeBlock)) {
return $date;
}
if (empty($date)) {
$date = $value;
}
switch ($field) {
case 'contribution_date':
$date = date('Ymd');
if (empty($date)) {
$date = date('Ymd');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, how does this work with localization of date formats, and why Ymd here but m/d/Y above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same explanation as above. The only reason m/d/Y was used above was that CiviCRM was somehow messing up form submissions when Ymd was being used and storing the wrong date.

}
break;

case 'calendar_date':
Expand Down
4 changes: 2 additions & 2 deletions CRM/Pledge/BAO/PledgeBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,8 @@ public static function buildPledgeBlock($form) {
switch ($field) {
case 'contribution_date':
$form->addDate('start_date', ts('First installment payment'));
$paymentDate = $value = date('d/m/Y');
list($defaults['start_date'], $defaults['start_date_time']) = CRM_Utils_Date::setDateDefaults($value);
$paymentDate = $value = date('m/d/Y');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks problematic for same reasons as above.

Copy link
Contributor Author

@Edzelopez Edzelopez Oct 25, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also the value that will be saved into database. I have already taken CiviCRM's date formats into account in the next step. https://github.com/JMAConsulting/civicrm-core/blob/e9f772df5f18cc584a3db22b704419c280bf50ff/CRM/Pledge/BAO/PledgeBlock.php#L314
This step is responsible for displaying the date to the user.

list($defaults['start_date'], $defaults['start_date_time']) = CRM_Utils_Date::setDateDefaults(NULL);
$form->assign('is_date', TRUE);
break;

Expand Down
5 changes: 3 additions & 2 deletions tests/phpunit/CRM/Pledge/BAO/PledgeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,14 @@ public function testGetPledgeStartDate() {
$this->assertEquals(date('m/d/Y', strtotime($date)), $paymentDate, "The two dates do not match");

// Try with fixed date
$date = NULL;
$params = array(
'pledge_start_date' => json_encode(array('contribution_date' => '2016-06-10')),
'pledge_start_date' => json_encode(array('calendar_date' => '06/10/2016')),
'is_pledge_start_date_visible' => FALSE,
);

$date = CRM_Pledge_BAO_Pledge::getPledgeStartDate($date, $params);
$this->assertEquals($date, '20160610', "The two dates do not match");
$this->assertEquals(date('m/d/Y', strtotime($date)), '06/10/2016', "The two dates do not match");
}

}
49 changes: 49 additions & 0 deletions tests/phpunit/api/v3/ContributionPageTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1003,4 +1003,53 @@ public function testSubmitPledgePaymentPaymentProcessorRecurFuturePayment() {
$this->assertEquals($recur['contribution_status_id'], 5); // In progress status.
}

/**
* Test submit pledge payment.
*
* - test submitting a pledge payment using contribution form.
*/
public function testSubmitPledgePayment() {
$this->testSubmitPledgePaymentPaymentProcessorRecurFuturePayment();
$pledge = $this->callAPISuccess('pledge', 'getsingle', array());
$params = array(
'pledge_id' => $pledge['id'],
);
$submitParams = array(
'id' => (int) $pledge['pledge_contribution_page_id'],
'pledge_amount' => array(2 => 1),
'billing_first_name' => 'Billy',
'billing_middle_name' => 'Goat',
'billing_last_name' => 'Gruff',
'email' => '[email protected]',
'payment_processor_id' => 1,
'credit_card_number' => '4111111111111111',
'credit_card_type' => 'Visa',
'credit_card_exp_date' => array('M' => 9, 'Y' => 2040),
'cvv2' => 123,
'pledge_id' => $pledge['id'],
'cid' => $pledge['contact_id'],
'contact_id' => $pledge['contact_id'],
'amount' => 100.00,
'is_pledge' => TRUE,
'pledge_block_id' => $this->_ids['pledge_block_id'],
);
$pledgePayment = $this->callAPISuccess('pledge_payment', 'get', $params);
$this->assertEquals($pledgePayment['values'][2]['status_id'], 2);

$this->callAPIAndDocument('contribution_page', 'submit', $submitParams, __FUNCTION__, __FILE__, 'submit contribution page', NULL);

// Check if contribution created.
$contribution = $this->callAPISuccess('contribution', 'getsingle', array(
'contribution_page_id' => $pledge['pledge_contribution_page_id'],
'contribution_status_id' => 'Completed',
'contact_id' => $pledge['contact_id'],
'contribution_recur_id' => array('IS NULL' => 1),
));

$this->assertEquals(100.00, $contribution['total_amount']);
$pledgePayment = $this->callAPISuccess('pledge_payment', 'get', $params);
$this->assertEquals($pledgePayment['values'][2]['status_id'], 1, "This pledge payment should have been completed");
$this->assertEquals($pledgePayment['values'][2]['contribution_id'], $contribution['id']);
}

}