CRM-17718 give precedence to financial type on recur record.
authoreileenmcnaughton <eileen@fuzion.co.nz>
Wed, 16 Dec 2015 17:55:31 +0000 (17:55 +0000)
committereileen <emcnaughton@wikimedia.org>
Wed, 23 Dec 2015 20:47:54 +0000 (09:47 +1300)
The financial type on the recurring contribution record can be updated over time and it should be preferred over that of the original contribution id
unless there is more than one line item (in which case updates are invalid). A passed in financial type should be preferred over both - with the same proviso as before

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

index 3fc2f4ca4bddcd6f1fab3fa04fef75603ebf00d2..e42aff2cc51aed32302f9f2f1cbc9c99f8879895 100644 (file)
@@ -2048,8 +2048,11 @@ LEFT JOIN  civicrm_contribution contribution ON ( componentPayment.contribution_
           // CRM-17718 the campaign id on the contribution recur record should get precedence.
           $contributionParams['campaign_id'] = $recurringContribution['campaign_id'];
         }
+        if (!empty($recurringContribution['financial_type_id'])) {
+          // CRM-17718 the campaign id on the contribution recur record should get precedence.
+          $contributionParams['financial_type_id'] = $recurringContribution['financial_type_id'];
+        }
       }
-
       $contributionParams['skipLineItem'] = TRUE;
       $contributionParams['status_id'] = 'Pending';
       if (isset($contributionParams['financial_type_id'])) {
@@ -4230,26 +4233,33 @@ WHERE con.id = {$contributionId}
       $inputContributionWhiteList[] = 'financial_type_id';
     }
 
+    $participant = CRM_Utils_Array::value('participant', $objects);
+    $memberships = CRM_Utils_Array::value('membership', $objects);
+    $recurContrib = CRM_Utils_Array::value('contributionRecur', $objects);
+    $event = CRM_Utils_Array::value('event', $objects);
+
     $contributionParams = array_merge(array(
       'contribution_status_id' => 'Completed',
-      'financial_type_id' => $contribution->financial_type_id,
+      'source' => self::getRecurringContributionDescription($contribution, $event),
     ), array_intersect_key($input, array_fill_keys($inputContributionWhiteList, 1)
     ));
 
-    $participant = CRM_Utils_Array::value('participant', $objects);
-    $memberships = CRM_Utils_Array::value('membership', $objects);
-    $recurContrib = CRM_Utils_Array::value('contributionRecur', $objects);
     if (!empty($recurContrib->id)) {
       $contributionParams['contribution_recur_id'] = $recurContrib->id;
     }
+    $changeDate = CRM_Utils_Array::value('trxn_date', $input, date('YmdHis'));
+
+    if (empty($contributionParams['receive_date']) && $changeDate) {
+      $contributionParams['receive_date'] = $changeDate;
+    }
+
     self::repeatTransaction($contribution, $input, $contributionParams);
+    $contributionParams['financial_type_id'] = $contribution->financial_type_id;
 
     if (is_numeric($memberships)) {
       $memberships = array($objects['membership']);
     }
 
-    $changeDate = CRM_Utils_Array::value('trxn_date', $input, date('YmdHis'));
-
     $values = array();
     if (isset($input['is_email_receipt'])) {
       $values['is_email_receipt'] = $input['is_email_receipt'];
@@ -4257,11 +4267,10 @@ WHERE con.id = {$contributionId}
 
     if ($input['component'] == 'contribute') {
       if ($contribution->contribution_page_id) {
+        // Figure out what we gain from this.
         CRM_Contribute_BAO_ContributionPage::setValues($contribution->contribution_page_id, $values);
-        $contributionParams['source'] = ts('Online Contribution') . ': ' . $values['title'];
       }
       elseif ($recurContrib && $recurContrib->id) {
-        $contributionParams['contribution_page_id'] = NULL;
         $values['amount'] = $recurContrib->amount;
         $values['financial_type_id'] = $objects['contributionType']->id;
         $values['title'] = $source = ts('Offline Recurring Contribution');
@@ -4270,10 +4279,6 @@ WHERE con.id = {$contributionId}
         $values['receipt_from_email'] = $domainValues[1];
       }
 
-      if (empty($contributionParams['receive_date']) && $changeDate) {
-        $contributionParams['receive_date'] = $changeDate;
-      }
-
       if ($recurContrib && $recurContrib->id && !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.
@@ -4362,9 +4367,7 @@ LIMIT 1;";
     }
     else {
       if (empty($input['IAmAHorribleNastyBeyondExcusableHackInTheCRMEventFORMTaskClassThatNeedsToBERemoved'])) {
-        $eventDetail = civicrm_api3('Event', 'getsingle', array('id' => $objects['event']->id));
-        $contributionParams['source'] = ts('Online Event Registration') . ': ' . $eventDetail['title'];
-        if ($eventDetail['is_email_confirm']) {
+        if ($event->is_email_confirm) {
           // @todo this should be set by the function that sends the mail after sending.
           $contributionParams['receipt_date'] = $changeDate;
         }
@@ -4630,4 +4633,27 @@ LIMIT 1;";
     return CRM_Core_BAO_FinancialTrxn::create($balanceTrxnParams);
   }
 
+  /**
+  * Get the description (source field) for the recurring contribution.
+  *
+  * @param CRM_Contribute_BAO_Contribution $contribution
+  * @param CRM_Event_DAO_Event|null $event
+  *
+  * @return array
+  * @throws \CiviCRM_API3_Exception
+  */
+  protected static function getRecurringContributionDescription($contribution, $event) {
+    if (!empty($contribution->contribution_page_id)) {
+      $contributionPageTitle = civicrm_api3('ContributionPage', 'getvalue', array(
+        'id' => $contribution->contribution_page_id,
+        'return' => 'title',
+      ));
+      return ts('Online Contribution') . ': ' . $contributionPageTitle;
+    }
+    .elseif ($event) {
+      return ts('Online Event Registration') . ': ' . $event->title;
+    }
+    return 'recurring contribution';
+  }
+
 }
index 565cd20689ef70dc0b3d99994578141ac7277690..39b6af36aa3d31e20464c333494ea3270f0f5312 100644 (file)
@@ -1601,6 +1601,56 @@ 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 testRepeatTransactionUpdatedFinancialType() {
+    $originalContribution = $this->setUpRecurringContribution(array(), array('financial_type_id' => 2));
+
+    $this->callAPISuccess('contribution', 'repeattransaction', array(
+      'contribution_recur_id' => $originalContribution['id'],
+      'contribution_status_id' => 'Completed',
+      'trxn_id' => uniqid(),
+    ));
+    $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.
    */
@@ -2357,11 +2407,13 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
    *
    * @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).
+   *
+   * @param array $recurParams
+   *   Parameters to merge into the recur only.
    *
    * @return array|int
    */
-  protected function setUpRecurringContribution($generalParams = array()) {
+  protected function setUpRecurringContribution($generalParams = array(), $recurParams = array()) {
     $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array_merge(array(
       'contact_id' => $this->_individualId,
       'installments' => '12',
@@ -2372,7 +2424,7 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
       'currency' => 'USD',
       'frequency_unit' => 'month',
       'payment_processor_id' => $this->paymentProcessorID,
-    ), $generalParams));
+    ), $generalParams, $recurParams));
     $originalContribution = $this->callAPISuccess('contribution', 'create', array_merge(
       $this->_params,
       array(