From 3c49d90ca2aaff5967679ca9e89db7b189b59cee 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 --- CRM/Contribute/BAO/Contribution.php | 25 ++++++- CRM/Contribute/BAO/ContributionRecur.php | 4 ++ api/v3/Contribution.php | 12 +++- tests/phpunit/api/v3/ContributionTest.php | 81 +++++++++++++++++++++++ 4 files changed, 120 insertions(+), 2 deletions(-) diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 2e64f674ed..3fc2f4ca4b 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -2052,7 +2052,13 @@ LEFT JOIN civicrm_contribution contribution ON ( componentPayment.contribution_ $contributionParams['skipLineItem'] = TRUE; $contributionParams['status_id'] = 'Pending'; - $contributionParams['financial_type_id'] = $templateContribution['financial_type_id']; + if (isset($contributionParams['financial_type_id'])) { + // Give precedence to passed in type. + $contribution->financial_type_id = $contributionParams['financial_type_id']; + } + else { + $contributionParams['financial_type_id'] = $templateContribution['financial_type_id']; + } $contributionParams['contact_id'] = $templateContribution['contact_id']; $contributionParams['source'] = empty($templateContribution['source']) ? ts('Recurring contribution') : $templateContribution['source']; $createContribution = civicrm_api3('Contribution', 'create', $contributionParams); @@ -4169,6 +4175,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('id' => $id)); + return ($lineItemCount == 1); + } + /** * Complete an order. * @@ -4206,6 +4226,9 @@ WHERE con.id = {$contributionId} 'campaign_id', 'receive_date', ); + if (self::isSingleLineItem($primaryContributionID)) { + $inputContributionWhiteList[] = 'financial_type_id'; + } $contributionParams = array_merge(array( 'contribution_status_id' => 'Completed', diff --git a/CRM/Contribute/BAO/ContributionRecur.php b/CRM/Contribute/BAO/ContributionRecur.php index a5e5add641..b5a94192c4 100644 --- a/CRM/Contribute/BAO/ContributionRecur.php +++ b/CRM/Contribute/BAO/ContributionRecur.php @@ -590,6 +590,10 @@ INNER JOIN civicrm_contribution con ON ( con.id = mp.contribution_id ) $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 27d6bf3aa1..ef1efa9973 100644 --- a/api/v3/Contribution.php +++ b/api/v3/Contribution.php @@ -559,7 +559,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); @@ -670,6 +670,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 c8e5ea3b91..565cd20689 100644 --- a/tests/phpunit/api/v3/ContributionTest.php +++ b/tests/phpunit/api/v3/ContributionTest.php @@ -1550,6 +1550,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. */ @@ -2301,4 +2352,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