Use payment create rather than transitionComponents
authorEileen McNaughton <emcnaughton@wikimedia.org>
Tue, 16 May 2023 00:57:23 +0000 (12:57 +1200)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Sun, 3 Dec 2023 23:14:19 +0000 (12:14 +1300)
CRM/Contribute/BAO/Contribution.php
CRM/Contribute/Form/Contribution.php
tests/phpunit/CRM/Member/Form/MembershipTest.php
tests/phpunit/api/v3/ContributionTest.php

index 2d3175cb5e2c1f94ab7c964630f20c90f2218c75..82b0ff93349f883d66707f81f296b2eba1f0d07e 100644 (file)
@@ -4212,11 +4212,7 @@ LIMIT 1;";
       }
       // @todo remove all this stuff in favour of letting the api call further down handle in
       // (it is a duplication of what the api does).
-      $dates = array_fill_keys([
-        'join_date',
-        'start_date',
-        'end_date',
-      ], NULL);
+      $dates = [];
       if ($currentMembership) {
         /*
          * Fixed FOR CRM-4433
@@ -4239,9 +4235,9 @@ LIMIT 1;";
       }
       else {
         //get the status for membership.
-        $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'],
-          $dates['end_date'],
-          $dates['join_date'],
+        $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'] ?? NULL,
+          $dates['end_date'] ?? NULL,
+          $dates['join_date'] ?? NULL,
           'now',
          TRUE,
           $membershipParams['membership_type_id'],
@@ -4255,7 +4251,23 @@ LIMIT 1;";
       //so make status override false.
       $membershipParams['is_override'] = FALSE;
       $membershipParams['status_override_end_date'] = 'null';
-      civicrm_api3('Membership', 'create', $membershipParams);
+      $membership = civicrm_api3('Membership', 'create', $membershipParams);
+      $membership = $membership['values'][$membership['id']];
+      // Update activity to Completed.
+      // Perhaps this should be in Membership::create? Test cover in
+      // api_v3_ContributionTest.testPendingToCompleteContribution.
+      $priorMembershipStatus = $memberships[$membership['id']]['status_id'] ?? NULL;
+      Activity::update(FALSE)->setValues([
+        'status_id:name' => 'Completed',
+        'subject' => ts('Status changed from %1 to %2'), [
+          1 => CRM_Core_PseudoConstant::getLabel('CRM_Member_BAO_Membership', 'status_id', $priorMembershipStatus),
+          2 => CRM_Core_PseudoConstant::getLabel('CRM_Member_BAO_Membership', 'status_id', $membership['status_id']),
+        ],
+
+      ])->addWhere('source_record_id', '=', $membership['id'])
+        ->addWhere('status_id:name', '=', 'Scheduled')
+        ->addWhere('activity_type_id:name', 'IN', ['Membership Signup', 'Membership Renewal'])
+        ->execute();
     }
   }
 
index f7a935aed89d4dcf67bb68595f0c69830f5384c7..8a343718bb9003c59ce72177237c0139417c38ee 100644 (file)
@@ -1974,7 +1974,6 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
 
       $fields = [
         'financial_type_id',
-        'contribution_status_id',
         'payment_instrument_id',
         'cancel_reason',
         'source',
@@ -1985,6 +1984,21 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
       foreach ($fields as $f) {
         $params[$f] = $formValues[$f] ?? NULL;
       }
+      if ($this->_id && $action & CRM_Core_Action::UPDATE) {
+        // Can only be updated to contribution which is handled via Payment.create
+        $params['contribution_status_id'] = $this->getSubmittedValue('contribution_status_id');
+
+        // Set is_pay_later flag for back-office offline Pending status contributions CRM-8996
+        // else if contribution_status is changed to Completed is_pay_later flag is changed to 0, CRM-15041
+        if ($params['contribution_status_id'] == CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending')) {
+          $params['is_pay_later'] = 1;
+        }
+        elseif ($params['contribution_status_id'] == CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed')) {
+          // @todo - if the contribution is new then it should be Pending status & then we use
+          // Payment.create to update to Completed.
+          $params['is_pay_later'] = 0;
+        }
+      }
 
       $params['revenue_recognition_date'] = NULL;
       if (!empty($formValues['revenue_recognition_date'])) {
@@ -2005,17 +2019,6 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
         $params['cancel_date'] = $params['cancel_reason'] = 'null';
       }
 
-      // Set is_pay_later flag for back-office offline Pending status contributions CRM-8996
-      // else if contribution_status is changed to Completed is_pay_later flag is changed to 0, CRM-15041
-      if ($params['contribution_status_id'] == CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending')) {
-        $params['is_pay_later'] = 1;
-      }
-      elseif ($params['contribution_status_id'] == CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed')) {
-        // @todo - if the contribution is new then it should be Pending status & then we use
-        // Payment.create to update to Completed.
-        $params['is_pay_later'] = 0;
-      }
-
       // Add Additional common information to formatted params.
       CRM_Contribute_Form_AdditionalInfo::postProcessCommon($formValues, $params, $this);
       if ($pId) {
@@ -2036,21 +2039,21 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP
       if (!empty($params['note']) && !empty($submittedValues['note'])) {
         unset($params['note']);
       }
-      $contribution = CRM_Contribute_BAO_Contribution::create($params);
-
       $previousStatus = CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $this->_values['contribution_status_id'] ?? NULL);
       // process associated membership / participant, CRM-4395
-      if ($contribution->id && $action & CRM_Core_Action::UPDATE
+      if ($this->getContributionID() && $this->getAction() & CRM_Core_Action::UPDATE
         && in_array($previousStatus, ['Pending', 'Partially paid'], TRUE)
         && 'Completed' === CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $this->getSubmittedValue('contribution_status_id'))) {
-        // @todo use Payment.create to do this, remove transitioncomponents function
-        // if contribution is being created with a completed status it should be
-        // created pending & then Payment.create adds the payment
-        CRM_Contribute_BAO_Contribution::transitionComponents([
-          'contribution_id' => $contribution->id,
-          'receive_date' => $contribution->receive_date,
+        // @todo make users use add payment form.
+        civicrm_api3('Payment', 'create', [
+          'contribution_id' => $this->getContributionID(),
+          'total_amount' => $this->getContributionValue('balance_amount'),
+          'currency' => $this->getSubmittedValue('currency'),
+          'payment_instrument_id' => $this->getSubmittedValue('payment_instrument_id'),
+          'check_number' => $this->getSubmittedValue('check_number'),
         ]);
       }
+      $contribution = CRM_Contribute_BAO_Contribution::create($params);
 
       array_unshift($this->statusMessage, ts('The contribution record has been saved.'));
 
index 88c2aed05095ad7e4b4eaae6b1ebe38e05cb7139..7d54a2d066df05f48fdd9d1539e32c52f498979d 100644 (file)
@@ -1109,7 +1109,7 @@ class CRM_Member_Form_MembershipTest extends CiviUnitTestCase {
 
     // Check if Membership is updated to New.
     $membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId]);
-    $this->assertEquals($membership['status_id'], array_search('New', $memStatus));
+    $this->assertEquals('New', CRM_Core_PseudoConstant::getName('CRM_Member_BAO_Membership', 'status_id', $membership['status_id']));
   }
 
   /**
index c4fd664940f642e1718dd9935019c77f59268b90..0bb1e080bd685c3b3550f2bc7e10954d005fab34 100644 (file)
@@ -3443,9 +3443,9 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
       'membership_id' => $this->getMembershipID(),
     ]);
     $this->assertEquals(4, $logs['count']);
-    //Assert only three activities are created.
+    //Assert activities are created.
     $activityNames = (array) ActivityContact::get(FALSE)
-      ->addWhere('contact_id', '=', $this->_ids['contact'])
+      ->addWhere('contact_id', '=', $membership['contact_id'])
       ->addSelect('activity_id.activity_type_id:name')->execute()->indexBy('activity_id.activity_type_id:name');
     $this->assertArrayHasKey('Contribution', $activityNames);
     $this->assertArrayHasKey('Membership Signup', $activityNames);
@@ -3458,7 +3458,7 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
    */
   public function testPendingToCompleteContribution(): void {
     $this->createPriceSetWithPage('membership');
-    $this->setUpPendingContribution($this->_ids['price_field_value'][0]);
+    $this->setUpPendingContribution($this->_ids['price_field_value'][0], 'new');
     $this->callAPISuccess('membership', 'getsingle', ['id' => $this->_ids['membership']]);
     // Case 1: Assert that Membership Signup Activity is created on Pending to Completed Contribution via backoffice
     $activity = $this->callAPISuccess('Activity', 'get', [
@@ -3575,11 +3575,6 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
     $this->assertEquals(date('Y-m-d', strtotime('yesterday + 5 years')), $membership['end_date']);
   }
 
-  public function cleanUpAfterPriceSets(): void {
-    $this->quickCleanUpFinancialEntities();
-    $this->contactDelete($this->_ids['contact']);
-  }
-
   /**
    * Set up a pending transaction with a specific price field id.
    *
@@ -3590,7 +3585,7 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
    * @param array $membershipParams
    */
   public function setUpPendingContribution(int $priceFieldValueID, string $key = 'first', array $contributionParams = [], array $lineParams = [], array $membershipParams = []): void {
-    $contactID = $this->individualCreate();
+    $contactID = $this->ids['Contact']['individual_0'] ?? $this->individualCreate();
     $membershipParams = array_merge([
       'contact_id' => $contactID,
       'membership_type_id' => $this->_ids['membership_type'],
@@ -3629,8 +3624,7 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
       ],
     ], $contributionParams));
 
-    $this->_ids['contact'] = $contactID;
-    $this->ids['contribution'][$key] = $contribution['id'];
+    $this->ids['Contribution'][$key] = $contribution['id'];
     $this->_ids['membership'] = $this->callAPISuccessGetValue('MembershipPayment', ['return' => 'membership_id', 'contribution_id' => $contribution['id']]);
   }
 
@@ -5113,7 +5107,10 @@ class api_v3_ContributionTest extends CiviUnitTestCase {
    * @return int
    */
   protected function getContributionID(string $key = 'first'): int {
-    return (int) $this->ids['contribution'][$key];
+    if (count($this->ids['Contribution']) === 1) {
+      return reset($this->ids['Contribution']);
+    }
+    return (int) $this->ids['Contribution'][$key];
   }
 
   /**