From 2202830d465fb188c5b4a5563fde1a2c250ae40e Mon Sep 17 00:00:00 2001 From: eileenmcnaughton Date: Wed, 16 Dec 2015 17:04:19 +0000 Subject: [PATCH] CRM-17718 update repeattransaction to permit the financial_type_id to be passed in Conflicts: CRM/Contribute/BAO/Contribution.php CRM/Contribute/BAO/ContributionRecur.php --- CRM/Contribute/BAO/Contribution.php | 14 ++++ CRM/Core/Payment/BaseIPN.php | 7 ++ api/v3/Contribution.php | 12 +++- tests/phpunit/api/v3/ContributionTest.php | 81 +++++++++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index c4f704525c..df48aab0a9 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -3766,6 +3766,20 @@ WHERE con.id = {$contributionId} } } + /** + * Is there only one line item attached to the contribution. + * + * @param int $id + * Contribution ID. + * + * @return bool + * @throws \CiviCRM_API3_Exception + */ + public static function isSingleLineItem($id) { + $lineItemCount = civicrm_api3('LineItem', 'getcount', array('contribution_id' => $id)); + return ($lineItemCount == 1); + } + /** * Generate credit note id with next avaible number * diff --git a/CRM/Core/Payment/BaseIPN.php b/CRM/Core/Payment/BaseIPN.php index ff38d3413e..f8cba5dadf 100644 --- a/CRM/Core/Payment/BaseIPN.php +++ b/CRM/Core/Payment/BaseIPN.php @@ -649,6 +649,9 @@ LIMIT 1;"; elseif (!empty($recurContrib->campaign_id)) { $contribution->campaign_id = $recurContrib->campaign_id; } + if (CRM_Contribute_BAO_Contribution::isSingleLineItem($primaryContributionID) && !empty($input['financial_type_id'])) { + $contribution->financial_type_id = $input['financial_type_id']; + } } $contributionStatuses = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'contribution_status_id', array( @@ -1092,6 +1095,10 @@ LIMIT 1;"; $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($originalContributionID); if (count($lineItems) == 1) { foreach ($lineItems as $index => $lineItem) { + if (isset($contribution->financial_type_id)) { + // CRM-17718 allow for possibility of changed financial type ID having been set prior to calling this. + $lineItems[$index]['financial_type_id'] = $contribution->financial_type_id; + } if ($lineItem['line_total'] != $contribution->total_amount) { // We are dealing with a changed amount! Per CRM-16397 we can work out what to do with these // if there is only one line item, and the UI should prevent this situation for those with more than one. diff --git a/api/v3/Contribution.php b/api/v3/Contribution.php index d90b4623fb..e836eda93c 100644 --- a/api/v3/Contribution.php +++ b/api/v3/Contribution.php @@ -507,7 +507,7 @@ function civicrm_api3_contribution_repeattransaction(&$params) { $contribution->contribution_status_id = $params['contribution_status_id']; $contribution->receive_date = $params['receive_date']; - $passThroughParams = array('trxn_id', 'total_amount', 'campaign_id', 'fee_amount'); + $passThroughParams = array('trxn_id', 'total_amount', 'campaign_id', 'fee_amount', 'financial_type_id'); $input = array_intersect_key($params, array_fill_keys($passThroughParams, NULL)); $params = _ipn_process_transaction($params, $contribution, $input, $ids, $original_contribution); @@ -618,6 +618,16 @@ function _civicrm_api3_contribution_repeattransaction_spec(&$params) { 'labelColumn' => 'title', ), ); + $params['financial_type_id'] = array( + 'title' => 'Financial ID (ignored if more than one line item)', + 'name' => 'financial_type_id', + 'type' => CRM_Utils_Type::T_INT, + 'pseudoconstant' => array( + 'table' => 'civicrm_financial_type', + 'keyColumn' => 'id', + 'labelColumn' => 'name', + ), + ); $params['payment_processor_id'] = array( 'description' => ts('Payment processor ID, will be loaded from contribution_recur if not provided'), 'title' => 'Payment processor ID', diff --git a/tests/phpunit/api/v3/ContributionTest.php b/tests/phpunit/api/v3/ContributionTest.php index 4829ea110a..d5196aa021 100644 --- a/tests/phpunit/api/v3/ContributionTest.php +++ b/tests/phpunit/api/v3/ContributionTest.php @@ -1517,6 +1517,57 @@ class api_v3_ContributionTest extends CiviUnitTestCase { $this->assertEquals($expectedLineItem, $lineItem2['values'][0]); } + /** + * CRM-17718 test appropriate action if financial type has changed for single line items. + */ + public function testRepeatTransactionPassedInFinancialType() { + $originalContribution = $this->setUpRecurringContribution(); + + $this->callAPISuccess('contribution', 'repeattransaction', array( + 'original_contribution_id' => $originalContribution['id'], + 'contribution_status_id' => 'Completed', + 'trxn_id' => uniqid(), + 'financial_type_id' => 2, + )); + $lineItemParams = array( + 'entity_id' => $originalContribution['id'], + 'sequential' => 1, + 'return' => array( + 'entity_table', + 'qty', + 'unit_price', + 'line_total', + 'label', + 'financial_type_id', + 'deductible_amount', + 'price_field_value_id', + 'price_field_id', + ), + ); + + $this->callAPISuccessGetSingle('contribution', array( + 'total_amount' => 100, + 'financial_type_id' => 2, + )); + $lineItem1 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array( + 'entity_id' => $originalContribution['id'], + ))); + $expectedLineItem = array_merge( + $lineItem1['values'][0], array( + 'line_total' => '100.00', + 'unit_price' => '100.00', + 'financial_type_id' => 2, + ) + ); + + $lineItem2 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array( + 'entity_id' => $originalContribution['id'] + 1, + ))); + unset($expectedLineItem['id'], $expectedLineItem['entity_id']); + unset($lineItem2['values'][0]['id'], $lineItem2['values'][0]['entity_id']); + $this->assertEquals($expectedLineItem, $lineItem2['values'][0]); + } + /** * CRM-16397 test appropriate action if campaign has been passed in. */ @@ -2210,4 +2261,34 @@ class api_v3_ContributionTest extends CiviUnitTestCase { } } + /** + * Set up the basic recurring contribution for tests. + * + * @param array $generalParams + * Parameters that can be merged into the recurring AND the contribution. + * (potentially add extra params if later we only want to merge to one). + * + * @return array|int + */ + protected function setUpRecurringContribution($generalParams = array()) { + $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array_merge(array( + 'contact_id' => $this->_individualId, + 'installments' => '12', + 'frequency_interval' => '1', + 'amount' => '100', + 'contribution_status_id' => 1, + 'start_date' => '2012-01-01 00:00:00', + 'currency' => 'USD', + 'frequency_unit' => 'month', + 'payment_processor_id' => $this->paymentProcessorID, + ), $generalParams)); + $originalContribution = $this->callAPISuccess('contribution', 'create', array_merge( + $this->_params, + array( + 'contribution_recur_id' => $contributionRecur['id'], + ), $generalParams) + ); + return $originalContribution; + } + } -- 2.25.1