From 294cc627580b968a9e8efa0a93806ecd8769470e Mon Sep 17 00:00:00 2001 From: eileenmcnaugton Date: Fri, 1 Apr 2016 17:24:12 +1300 Subject: [PATCH] CRM-18341 Pledges not being completed by completeTransaction --- CRM/Contribute/BAO/Contribution.php | 12 +++-- CRM/Contribute/BAO/ContributionRecur.php | 29 +++++----- tests/phpunit/CiviTest/CiviUnitTestCase.php | 1 + tests/phpunit/api/v3/ContributionTest.php | 59 +++++++++++++++++++++ xml/schema/Pledge/Pledge.xml | 3 ++ xml/schema/Pledge/PledgePayment.xml | 3 ++ 6 files changed, 90 insertions(+), 17 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 3459480dd8..2e967673f9 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -4353,6 +4353,7 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) $participant = CRM_Utils_Array::value('participant', $objects); $memberships = CRM_Utils_Array::value('membership', $objects); $recurContrib = CRM_Utils_Array::value('contributionRecur', $objects); + $recurringContributionID = (empty($recurContrib->id)) ? NULL : $recurContrib->id; $event = CRM_Utils_Array::value('event', $objects); $completedContributionStatusID = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); @@ -4363,8 +4364,8 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) ), array_intersect_key($input, array_fill_keys($inputContributionWhiteList, 1) )); - if (!empty($recurContrib->id)) { - $contributionParams['contribution_recur_id'] = $recurContrib->id; + if ($recurringContributionID) { + $contributionParams['contribution_recur_id'] = $recurringContributionID; } $changeDate = CRM_Utils_Array::value('trxn_date', $input, date('YmdHis')); @@ -4389,7 +4390,7 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) // Figure out what we gain from this. CRM_Contribute_BAO_ContributionPage::setValues($contribution->contribution_page_id, $values); } - elseif ($recurContrib && $recurContrib->id) { + elseif ($recurContrib && $recurringContributionID) { $values['amount'] = $recurContrib->amount; $values['financial_type_id'] = $objects['contributionType']->id; $values['title'] = $source = ts('Offline Recurring Contribution'); @@ -4398,7 +4399,7 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) $values['receipt_from_email'] = $domainValues[1]; } - if ($recurContrib && $recurContrib->id && !isset($input['is_email_receipt'])) { + if ($recurContrib && $recurringContributionID && !isset($input['is_email_receipt'])) { //CRM-13273 - is_email_receipt setting on recurring contribution should take precedence over contribution page setting // but CRM-16124 if $input['is_email_receipt'] is set then that should not be overridden. $values['is_email_receipt'] = $recurContrib->is_email_receipt; @@ -4551,7 +4552,8 @@ LIMIT 1;"; CRM_Core_Error::debug_log_message("Contribution record updated successfully"); $transaction->commit(); - CRM_Contribute_BAO_ContributionRecur::updateRecurLinkedPledge($contribution); + CRM_Contribute_BAO_ContributionRecur::updateRecurLinkedPledge($contribution->id, $recurringContributionID, + $input['contribution_status_id'], $input['total_amount']); // create an activity record if ($input['component'] == 'contribute') { diff --git a/CRM/Contribute/BAO/ContributionRecur.php b/CRM/Contribute/BAO/ContributionRecur.php index 7478d39c52..da44e17b04 100644 --- a/CRM/Contribute/BAO/ContributionRecur.php +++ b/CRM/Contribute/BAO/ContributionRecur.php @@ -692,13 +692,18 @@ INNER JOIN civicrm_contribution con ON ( con.id = mp.contribution_id ) * The pledge payment record should already exist & will need to be updated with the new contribution ID. * If not the contribution will also need to be linked to the pledge * - * @param CRM_Contribute_BAO_Contribution $contribution + * @param int $contributionID + * @param int $contributionRecurID + * @param int $contributionStatusID + * @param float $contributionAmount + * + * @throws \CiviCRM_API3_Exception */ - public static function updateRecurLinkedPledge($contribution) { + public static function updateRecurLinkedPledge($contributionID, $contributionRecurID, $contributionStatusID, $contributionAmount) { $returnProperties = array('id', 'pledge_id'); $paymentDetails = $paymentIDs = array(); - if (CRM_Core_DAO::commonRetrieveAll('CRM_Pledge_DAO_PledgePayment', 'contribution_id', $contribution->id, + if (CRM_Core_DAO::commonRetrieveAll('CRM_Pledge_DAO_PledgePayment', 'contribution_id', $contributionID, $paymentDetails, $returnProperties ) ) { @@ -710,12 +715,12 @@ INNER JOIN civicrm_contribution con ON ( con.id = mp.contribution_id ) else { //payment is not already linked - if it is linked with a pledge we need to create a link. // return if it is not recurring contribution - if (!$contribution->contribution_recur_id) { + if (!$contributionRecurID) { return; } $relatedContributions = new CRM_Contribute_DAO_Contribution(); - $relatedContributions->contribution_recur_id = $contribution->contribution_recur_id; + $relatedContributions->contribution_recur_id = $contributionRecurID; $relatedContributions->find(); while ($relatedContributions->fetch()) { @@ -740,18 +745,18 @@ INNER JOIN civicrm_contribution con ON ( con.id = mp.contribution_id ) // return now so we don't create a core error & roll back return; } - $paymentDetails['contribution_id'] = $contribution->id; - $paymentDetails['status_id'] = $contribution->contribution_status_id; - $paymentDetails['actual_amount'] = $contribution->total_amount; + $paymentDetails['contribution_id'] = $contributionID; + $paymentDetails['status_id'] = $contributionStatusID; + $paymentDetails['actual_amount'] = $contributionAmount; // put contribution against it - $payment = CRM_Pledge_BAO_PledgePayment::add($paymentDetails); - $paymentIDs[] = $payment->id; + $payment = civicrm_api3('PledgePayment', 'create', $paymentDetails); + $paymentIDs[] = $payment['id']; } // update pledge and corresponding payment statuses - CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($pledgeId, $paymentIDs, $contribution->contribution_status_id, - NULL, $contribution->total_amount + CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($pledgeId, $paymentIDs, $contributionStatusID, + NULL, $contributionAmount ); } diff --git a/tests/phpunit/CiviTest/CiviUnitTestCase.php b/tests/phpunit/CiviTest/CiviUnitTestCase.php index dd1a107c46..68bd30ab7a 100644 --- a/tests/phpunit/CiviTest/CiviUnitTestCase.php +++ b/tests/phpunit/CiviTest/CiviUnitTestCase.php @@ -2498,6 +2498,7 @@ AND ( TABLE_NAME LIKE 'civicrm_value_%' ) 'civicrm_participant', 'civicrm_participant_payment', 'civicrm_pledge', + 'civicrm_pledge_payment', 'civicrm_price_set_entity', 'civicrm_price_field_value', 'civicrm_price_field', diff --git a/tests/phpunit/api/v3/ContributionTest.php b/tests/phpunit/api/v3/ContributionTest.php index d536229bd8..3ec831da6e 100644 --- a/tests/phpunit/api/v3/ContributionTest.php +++ b/tests/phpunit/api/v3/ContributionTest.php @@ -2027,6 +2027,38 @@ class api_v3_ContributionTest extends CiviUnitTestCase { $this->assertEquals(date('Y-m-d 00:00:00', strtotime('+1 month')), $contributionRecur['next_sched_contribution_date']); } + /** + * Test completing a pledge with the completeTransaction api.. + * + * Note that we are creating a logged in user because email goes out from + * that person. + */ + public function testCompleteTransactionUpdatePledgePayment() { + $mut = new CiviMailUtils($this, TRUE); + $mut->clearMessages(); + $this->createLoggedInUser(); + $contributionID = $this->createPendingPledgeContribution(); + $this->callAPISuccess('contribution', 'completetransaction', array( + 'id' => $contributionID, + 'trxn_date' => '1 Feb 2013', + )); + $pledge = $this->callAPISuccessGetSingle('Pledge', array( + 'id' => $this->_ids['pledge'], + )); + $this->assertEquals('Completed', $pledge['pledge_status']); + + $status = $this->callAPISuccessGetValue('PledgePayment', array( + 'pledge_id' => $this->_ids['pledge'], + 'return' => 'status_id', + )); + $this->assertEquals(1, $status); + $mut->checkMailLog(array( + '$ 500.00', + 'May 11th, 2012 12:00 AM', + )); + $mut->stop(); + } + /** * Test completing a transaction with an event via the API. * @@ -2307,6 +2339,33 @@ class api_v3_ContributionTest extends CiviUnitTestCase { } } + /** + * Create a pending contribution & linked pending pledge record. + */ + public function createPendingPledgeContribution() { + + $pledgeID = $this->pledgeCreate(array('contact_id' => $this->_individualId, 'installments' => 1, 'amount' => 500)); + $this->_ids['pledge'] = $pledgeID; + $contribution = $this->callAPISuccess('contribution', 'create', array_merge($this->_params, array( + 'contribution_status_id' => 'Pending', + 'total_amount' => 500, + )) + ); + $paymentID = $this->callAPISuccessGetValue('PledgePayment', array( + 'options' => array('limit' => 1), + 'return' => 'id', + )); + $this->callAPISuccess('PledgePayment', 'create', array( + 'id' => $paymentID, + 'contribution_id' => + $contribution['id'], + 'status_id' => 'Pending', + 'scheduled_amount' => 500, + )); + + return $contribution['id']; + } + /** * Create a pending contribution & linked pending participant record (along with an event). */ diff --git a/xml/schema/Pledge/Pledge.xml b/xml/schema/Pledge/Pledge.xml index e407d86c70..56b61580d4 100644 --- a/xml/schema/Pledge/Pledge.xml +++ b/xml/schema/Pledge/Pledge.xml @@ -289,6 +289,9 @@ true false int unsigned + + contribution_status + Implicit foreign key to civicrm_option_values in the contribution_status option group. 2.1 diff --git a/xml/schema/Pledge/PledgePayment.xml b/xml/schema/Pledge/PledgePayment.xml index 7a79f476f6..c646bb5aa9 100644 --- a/xml/schema/Pledge/PledgePayment.xml +++ b/xml/schema/Pledge/PledgePayment.xml @@ -129,6 +129,9 @@ false int unsigned 2.1 + + contribution_status + index_status -- 2.25.1