Deprecate creating partially paid contributions, other than by partially paying a...
authoreileen <emcnaughton@wikimedia.org>
Fri, 15 Nov 2019 04:10:27 +0000 (17:10 +1300)
committereileen <emcnaughton@wikimedia.org>
Thu, 21 Nov 2019 09:48:54 +0000 (22:48 +1300)
As https://github.com/civicrm/civicrm-core/pull/15706 signposts - creating a contribution with a status of 'Partially Paid'
is not actually a valid thing to do. There are no created financial_trxns & the balance is wrong. In some places the code does
this in conjunction with some parameters. These don't really work either. We need to deprecate & eliminate this flow.

I'm expecting some tests to fail & need fixing before this passes

CRM/Contribute/BAO/Contribution.php
tests/phpunit/CRM/Contribute/Form/TaskTest.php
tests/phpunit/api/v3/ContributionPageTest.php

index 0f1a0c635912ee70dc1eb79d25f4e13e8903a907..d2f34754b517381b7c32f161c6d8c9649a8dc71a 100644 (file)
@@ -132,7 +132,6 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
       }
     }
 
-    $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
     //if contribution is created with cancelled or refunded status, add credit note id
     // do the same for chargeback - this entered the code 'accidentally' but moving it to here
     // as part of cleanup maintains consistency.
@@ -141,7 +140,11 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
         $params['creditnote_id'] = self::createCreditNoteId();
       }
     }
-    if (empty($params['contribution_status_id'])) {
+    $contributionStatusID = $params['contribution_status_id'] ?? NULL;
+    if (CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', (int) $contributionStatusID) === 'Partially paid' && empty($params['is_post_payment_create'])) {
+      CRM_Core_Error::deprecatedFunctionWarning('Setting status to partially paid other than by using Payment.create is deprecated and unreliable');
+    }
+    if (!$contributionStatusID) {
       // Since the fee amount is expecting this (later on) ensure it is always set.
       // It would only not be set for an update where it is unchanged.
       $params['contribution_status_id'] = civicrm_api3('Contribution', 'getvalue', [
@@ -149,6 +152,7 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
         'return' => 'contribution_status_id',
       ]);
     }
+    $contributionStatus = CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', (int) $params['contribution_status_id']);
 
     if (!$contributionID
       && CRM_Utils_Array::value('membership_id', $params)
@@ -183,9 +187,10 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
     if ($contributionID && $setPrevContribution) {
       $params['prevContribution'] = self::getOriginalContribution($contributionID);
     }
+    $previousContributionStatus = ($contributionID && !empty($params['prevContribution'])) ? CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', (int) $params['prevContribution']->contribution_status_id) : NULL;
 
-    if ($contributionID && !empty($params['revenue_recognition_date']) && !empty($params['prevContribution'])
-      && !($contributionStatus[$params['prevContribution']->contribution_status_id] == 'Pending')
+    if ($contributionID && !empty($params['revenue_recognition_date'])
+      && !($previousContributionStatus === 'Pending')
       && !self::allowUpdateRevenueRecognitionDate($contributionID)
     ) {
       unset($params['revenue_recognition_date']);
@@ -236,7 +241,7 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution {
     if (self::isUpdateToRecurringContribution($params)) {
       CRM_Contribute_BAO_ContributionRecur::updateOnNewPayment(
         (!empty($params['contribution_recur_id']) ? $params['contribution_recur_id'] : $params['prevContribution']->contribution_recur_id),
-        $contributionStatus[$params['contribution_status_id']],
+        $contributionStatus,
         CRM_Utils_Array::value('receive_date', $params)
       );
     }
index 104cd0dd5df41ccb75212a2c0222d65c61ff66e7..acd140f5bb1775782c3f46051a01ff030963c27c 100644 (file)
@@ -27,6 +27,8 @@ class CRM_Contribute_Form_TaskTest extends CiviUnitTestCase {
   /**
    * CRM-19722 - Check CRM_Contribute_Form_Task::preProcessCommon()
    * executes without any error after sorting the search result.
+   *
+   * @throws \CRM_Core_Exception
    */
   public function testPreProcessCommonAfterSorting() {
     $fields = [
@@ -47,6 +49,10 @@ class CRM_Contribute_Form_TaskTest extends CiviUnitTestCase {
         'financial_type_id' => $financialTypes[$i],
         'contribution_status_id' => $status[$i],
       ];
+      if ($status[$i] === 'Partially paid') {
+        $contributionParams['contribution_status_id'] = 'Pending';
+        $contributionParams['api.Payment.create'] = ['total_amount' => 50];
+      }
       $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams);
       $contributionIds[] = $contribution['id'];
     }
index 806a962543bd73dff0e56f7462fcf5505b10ef84..b35c227b0c871881fd278e4ada7f627530f1e483 100644 (file)
@@ -1307,7 +1307,6 @@ class api_v3_ContributionPageTest extends CiviUnitTestCase {
     $submitParams = [
       'price_' . $this->_ids['price_field'][0] => reset($this->_ids['price_field_value']),
       'id' => (int) $this->_ids['contribution_page'],
-      'amount' => 10,
       'billing_first_name' => 'Billy',
       'billing_middle_name' => 'Goat',
       'billing_last_name' => 'Gruff',