Update ContributionCancelActions to also handle 'failed'
authoreileen <emcnaughton@wikimedia.org>
Sun, 22 Nov 2020 21:05:50 +0000 (10:05 +1300)
committereileen <emcnaughton@wikimedia.org>
Mon, 23 Nov 2020 20:26:33 +0000 (09:26 +1300)
The failed action has no discernable difference from the no-longer-used cancel action. The cancel action had some minor refactoring
done to work through the conclusion that the call to addRecurLineItems was never reached in a meaningful way
but I think we can skip all that & see that fail is not functionally different to cancel & just deprecate the function.

At this point we are very close to simply removing the last core handling for failed & cance & making the extension visible.

The only thing I can see that still needs checking in the 2 functions still to be removed is the handling of
is_override & override_date is tested - which I will do as a follow up

CRM/Core/Payment/BaseIPN.php
CRM/Core/Payment/PayPalIPN.php
CRM/Core/Payment/PayPalProIPN.php
ext/contributioncancelactions/contributioncancelactions.php
tests/phpunit/CRM/Core/Payment/BaseIPNTest.php

index 7bf95e4710fbc7e4e0e5af20f0905333747e8c9e..994ab9a53dc3b64b6a13ef6828ce047fa2b83388 100644 (file)
@@ -165,10 +165,13 @@ class CRM_Core_Payment_BaseIPN {
    *
    * @param array $objects
    *
+   * @deprecated use the api.
+   *
    * @return bool
    * @throws \CiviCRM_API3_Exception|\CRM_Core_Exception
    */
   public function failed($objects) {
+    CRM_Core_Error::deprecatedFunctionWarning('use the api');
     $contribution = &$objects['contribution'];
     $memberships = [];
     if (!empty($objects['membership'])) {
index fd840025fc4169baab99c3b3620223fb98ddf87a..31af83e4eff60cc20afa3635d849ab404ef30503 100644 (file)
@@ -256,8 +256,9 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN {
   /**
    * Main function.
    *
-   * @throws \CRM_Core_Exception
+   * @throws \API_Exception
    * @throws \CiviCRM_API3_Exception
+   * @throws \Civi\API\Exception\UnauthorizedException
    */
   public function main() {
     try {
@@ -378,7 +379,11 @@ class CRM_Core_Payment_PayPalIPN extends CRM_Core_Payment_BaseIPN {
 
       $status = $input['paymentStatus'];
       if ($status === 'Denied' || $status === 'Failed' || $status === 'Voided') {
-        $this->failed($objects);
+        Contribution::update(FALSE)->setValues([
+          'cancel_date' => 'now',
+          'contribution_status_id:name' => 'Failed',
+        ])->addWhere('id', '=', $contributionID)->execute();
+        Civi::log()->debug("Setting contribution status to Failed");
         return;
       }
       if ($status === 'Pending') {
index d6f44109d6465a076c35b57ccf61c4745c31d49e..6a684216c90fb730f9efbcf0ebc1ea248263bda1 100644 (file)
@@ -293,6 +293,7 @@ class CRM_Core_Payment_PayPalProIPN extends CRM_Core_Payment_BaseIPN {
    * @param bool $first
    *
    * @return void
+   * @throws \API_Exception
    */
   public function single($input, $ids, $objects, $recur = FALSE, $first = FALSE) {
     $contribution = &$objects['contribution'];
@@ -322,7 +323,11 @@ class CRM_Core_Payment_PayPalProIPN extends CRM_Core_Payment_BaseIPN {
 
     $status = $input['paymentStatus'];
     if ($status === 'Denied' || $status === 'Failed' || $status === 'Voided') {
-      $this->failed($objects);
+      Contribution::update(FALSE)->setValues([
+        'cancel_date' => 'now',
+        'contribution_status_id:name' => 'Failed',
+      ])->addWhere('id', '=', $contribution->id)->execute();
+      Civi::log()->debug("Setting contribution status to Failed");
       return;
     }
     if ($status === 'Pending') {
index 61966d72a0bce3497976acfdbddf7b6616e37f98..8665b19d2412e662c2dace501a2718c0f489b7b5 100644 (file)
@@ -12,14 +12,21 @@ use Civi\Api4\Participant;
  *
  * This enacts the following
  * - find and cancel any related pending memberships
- * - (not yet implemented) find and cancel any related pending participant records
- * - (not yet implemented) find any related pledge payment records. Remove the contribution id.
+ * - (not yet implemented) find and cancel any related pending participant
+ * records
+ * - (not yet implemented) find any related pledge payment records. Remove the
+ * contribution id.
  *
  * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_post
+ *
+ * @throws \CiviCRM_API3_Exception
+ * @throws \API_Exception
  */
 function contributioncancelactions_civicrm_post($op, $objectName, $objectId, $objectRef) {
   if ($op === 'edit' && $objectName === 'Contribution') {
-    if ('Cancelled' === CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $objectRef->contribution_status_id)) {
+    if (in_array(CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $objectRef->contribution_status_id),
+      ['Cancelled', 'Failed']
+    )) {
       contributioncancelactions_cancel_related_pending_memberships((int) $objectId);
       contributioncancelactions_cancel_related_pending_participant_records((int) $objectId);
       contributioncancelactions_update_related_pledge((int) $objectId, (int) $objectRef->contribution_status_id);
index dac135b09919ccddfcd9128e5ce08f76a40186dc..a2a59ffeb595eb884df0210aa927720833c53e10 100644 (file)
@@ -435,16 +435,26 @@ class CRM_Core_Payment_BaseIPNTest extends CiviUnitTestCase {
     $this->assertEquals(2, $cancelledActivatesCount['count']);
   }
 
-  public function testThatFailedEventPaymentWillCancelAllAdditionalPendingParticipantsAndCreateCancellationActivities() {
+  /**
+   * Test that related pending participant records are cancelled.
+   *
+   * @throws \API_Exception
+   * @throws \CRM_Core_Exception
+   * @throws \CiviCRM_API3_Exception
+   * @throws \Civi\API\Exception\UnauthorizedException
+   */
+  public function testThatFailedEventPaymentWillCancelAllAdditionalPendingParticipantsAndCreateCancellationActivities(): void {
     $this->_setUpParticipantObjects('Pending from incomplete transaction');
-    $this->IPN->loadObjects($this->input, $this->ids, $this->objects, FALSE, $this->_processorId);
     $additionalParticipantId = $this->participantCreate([
       'event_id' => $this->_eventId,
       'registered_by_id' => $this->_participantId,
       'status_id' => 'Pending from incomplete transaction',
     ]);
 
-    $this->IPN->failed($this->objects);
+    Contribution::update(FALSE)->setValues([
+      'cancel_date' => 'now',
+      'contribution_status_id:name' => 'Failed',
+    ])->addWhere('id', '=', $this->ids['contribution'])->execute();
 
     $cancelledParticipantsCount = civicrm_api3('Participant', 'get', [
       'sequential' => 1,
@@ -586,7 +596,7 @@ class CRM_Core_Payment_BaseIPNTest extends CiviUnitTestCase {
    *
    * @throws \CRM_Core_Exception
    */
-  public function _setUpParticipantObjects($participantStatus = 'Attended') {
+  public function _setUpParticipantObjects($participantStatus = 'Attended'): void {
     $event = $this->eventCreate(['is_email_confirm' => 1]);
 
     $this->_eventId = $event['id'];
@@ -605,6 +615,7 @@ class CRM_Core_Payment_BaseIPNTest extends CiviUnitTestCase {
     $contribution->id = $this->_contributionId;
     $contribution->find();
     $this->objects['contribution'] = $contribution;
+    $this->ids['contribution'] = $contribution->id;
     $this->input = [
       'component' => 'event',
       'total_amount' => 150.00,