Move handling of participant.cancel to contributioncancelactions extension
[civicrm-core.git] / ext / contributioncancelactions / contributioncancelactions.php
index 2ec3aae284fa85aef5c403b27c3158e63d7d898d..3cfa1b56a069f5166528b8ca02305c25dec0bd14 100644 (file)
@@ -5,6 +5,7 @@ require_once 'contributioncancelactions.civix.php';
 use CRM_Contributioncancelactions_ExtensionUtil as E;
 // phpcs:enable
 use Civi\Api4\LineItem;
+use Civi\Api4\Participant;
 
 /**
  * Implements hook_civicrm_preProcess().
@@ -19,25 +20,59 @@ use Civi\Api4\LineItem;
 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)) {
-      // Find and cancel any pending memberships.
-      $connectedMemberships = (array) LineItem::get(FALSE)->setWhere([
-        ['contribution_id', '=', $objectId],
-        ['entity_table', '=', 'civicrm_membership'],
-      ])->execute()->indexBy('entity_id');
-      if (empty($connectedMemberships)) {
-        return;
-      }
-      // @todo we don't have v4 membership api yet so v3 for now.
-      $connectedMemberships = array_keys(civicrm_api3('Membership', 'get', [
-        'status_id' => 'Pending',
-        'id' => ['IN' => array_keys($connectedMemberships)],
-      ])['values']);
-      if (empty($connectedMemberships)) {
-        return;
-      }
-      foreach ($connectedMemberships as $membershipID) {
-        civicrm_api3('Membership', 'create', ['status_id' => 'Cancelled', 'id' => $membershipID, 'is_override' => 1]);
-      }
+      contributioncancelactions_cancel_related_pending_memberships((int) $objectId);
+      contributioncancelactions_cancel_related_pending_participant_records((int) $objectId);
     }
   }
 }
+
+/**
+ * Find and cancel any pending participant records.
+ *
+ * @param int $contributionID
+ * @throws CiviCRM_API3_Exception
+ */
+function contributioncancelactions_cancel_related_pending_participant_records($contributionID): void {
+  $pendingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Pending'");
+  $waitingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Waiting'");
+  $cancellableParticipantRecords = civicrm_api3('ParticipantPayment', 'get', [
+    'contribution_id' => $contributionID,
+    'participant_id.status_id' => ['IN' => array_merge(array_keys($pendingStatuses), array_keys($waitingStatuses))],
+  ])['values'];
+  if (empty($cancellableParticipantRecords)) {
+    return;
+  }
+  Participant::update(FALSE)
+    ->addWhere('id', 'IN', array_keys($cancellableParticipantRecords))
+    ->setValues(['status_id:name' => 'Cancelled'])
+    ->execute();
+}
+
+/**
+ * Find and cancel any pending memberships.
+ *
+ * @param int $contributionID
+ * @throws API_Exception
+ * @throws CiviCRM_API3_Exception
+ */
+function contributioncancelactions_cancel_related_pending_memberships($contributionID): void {
+  $connectedMemberships = (array) LineItem::get(FALSE)->setWhere([
+    ['contribution_id', '=', $contributionID],
+    ['entity_table', '=', 'civicrm_membership'],
+  ])->execute()->indexBy('entity_id');
+
+  if (empty($connectedMemberships)) {
+    return;
+  }
+  // @todo we don't have v4 membership api yet so v3 for now.
+  $connectedMemberships = array_keys(civicrm_api3('Membership', 'get', [
+    'status_id' => 'Pending',
+    'id' => ['IN' => array_keys($connectedMemberships)],
+  ])['values']);
+  if (empty($connectedMemberships)) {
+    return;
+  }
+  foreach ($connectedMemberships as $membershipID) {
+    civicrm_api3('Membership', 'create', ['status_id' => 'Cancelled', 'id' => $membershipID, 'is_override' => 1]);
+  }
+}