CRM-17718 update repeattransaction to permit the financial_type_id to be passed in
authoreileenmcnaughton <eileen@fuzion.co.nz>
Wed, 16 Dec 2015 17:04:19 +0000 (17:04 +0000)
committereileenmcnaugton <eileen@fuzion.co.nz>
Sun, 14 Feb 2016 23:06:37 +0000 (12:06 +1300)
Conflicts:
CRM/Contribute/BAO/Contribution.php
CRM/Contribute/BAO/ContributionRecur.php

CRM/Contribute/BAO/Contribution.php
CRM/Core/Payment/BaseIPN.php
api/v3/Contribution.php
tests/phpunit/api/v3/ContributionTest.php

index c4f704525ccd255c3b65abfdf29429a8e4d3951b..df48aab0a946a9d641677c4c9d4ecbd7256d73bf 100644 (file)
@@ -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
    *
index ff38d3413e563d442285493293ff1cae308e5af0..f8cba5dadfb156656bd3e2353751dfc21e852fda 100644 (file)
@@ -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.
index d90b4623fb1d7de5f61a40d44ca3401fa7db1330..e836eda93cea14df37e221c13be72a12156e252a 100644 (file)
@@ -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',
index 4829ea110a4e382fe057447f07b429cc45a207d3..d5196aa021459d41ca457896b775123ce5fbaceb 100644 (file)
@@ -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;
+  }
+
 }