c00edb21 |
1 | <?php |
2 | |
3 | require_once 'contributioncancelactions.civix.php'; |
4 | // phpcs:disable |
5 | use CRM_Contributioncancelactions_ExtensionUtil as E; |
6 | // phpcs:enable |
6ff69e9c |
7 | use Civi\Api4\LineItem; |
a201e208 |
8 | use Civi\Api4\Participant; |
c00edb21 |
9 | |
10 | /** |
11 | * Implements hook_civicrm_preProcess(). |
12 | * |
6ff69e9c |
13 | * This enacts the following |
14 | * - find and cancel any related pending memberships |
61470a1a |
15 | * - (not yet implemented) find and cancel any related pending participant |
16 | * records |
17 | * - (not yet implemented) find any related pledge payment records. Remove the |
18 | * contribution id. |
6ff69e9c |
19 | * |
c00edb21 |
20 | * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_post |
61470a1a |
21 | * |
22 | * @throws \CiviCRM_API3_Exception |
23 | * @throws \API_Exception |
c00edb21 |
24 | */ |
25 | function contributioncancelactions_civicrm_post($op, $objectName, $objectId, $objectRef) { |
26 | if ($op === 'edit' && $objectName === 'Contribution') { |
61470a1a |
27 | if (in_array(CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $objectRef->contribution_status_id), |
28 | ['Cancelled', 'Failed'] |
29 | )) { |
a201e208 |
30 | contributioncancelactions_cancel_related_pending_memberships((int) $objectId); |
31 | contributioncancelactions_cancel_related_pending_participant_records((int) $objectId); |
4f1cfdfa |
32 | contributioncancelactions_update_related_pledge((int) $objectId, (int) $objectRef->contribution_status_id); |
c00edb21 |
33 | } |
34 | } |
35 | } |
a201e208 |
36 | |
4f1cfdfa |
37 | /** |
38 | * Update any related pledge when a contribution is cancelled. |
39 | * |
40 | * This updates the status of the pledge and amount paid. |
41 | * |
42 | * The functionality should probably be give more thought in that it currently |
43 | * does not un-assign the contribution id from the pledge payment. However, |
44 | * at time of writing the goal is to move rather than fix functionality. |
45 | * |
46 | * @param int $contributionID |
47 | * @param int $contributionStatusID |
48 | * |
49 | * @throws CiviCRM_API3_Exception |
50 | */ |
51 | function contributioncancelactions_update_related_pledge(int $contributionID, int $contributionStatusID) { |
52 | $pledgePayments = civicrm_api3('PledgePayment', 'get', ['contribution_id' => $contributionID])['values']; |
53 | if (!empty($pledgePayments)) { |
54 | $pledgePaymentIDS = array_keys($pledgePayments); |
55 | $pledgePayment = reset($pledgePayments); |
56 | CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($pledgePayment['pledge_id'], $pledgePaymentIDS, $contributionStatusID); |
57 | } |
58 | } |
59 | |
a201e208 |
60 | /** |
61 | * Find and cancel any pending participant records. |
62 | * |
63 | * @param int $contributionID |
64 | * @throws CiviCRM_API3_Exception |
65 | */ |
66 | function contributioncancelactions_cancel_related_pending_participant_records($contributionID): void { |
67 | $pendingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Pending'"); |
68 | $waitingStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Waiting'"); |
69 | $cancellableParticipantRecords = civicrm_api3('ParticipantPayment', 'get', [ |
70 | 'contribution_id' => $contributionID, |
71 | 'participant_id.status_id' => ['IN' => array_merge(array_keys($pendingStatuses), array_keys($waitingStatuses))], |
72 | ])['values']; |
73 | if (empty($cancellableParticipantRecords)) { |
74 | return; |
75 | } |
76 | Participant::update(FALSE) |
77 | ->addWhere('id', 'IN', array_keys($cancellableParticipantRecords)) |
78 | ->setValues(['status_id:name' => 'Cancelled']) |
79 | ->execute(); |
80 | } |
81 | |
82 | /** |
83 | * Find and cancel any pending memberships. |
84 | * |
85 | * @param int $contributionID |
86 | * @throws API_Exception |
87 | * @throws CiviCRM_API3_Exception |
88 | */ |
89 | function contributioncancelactions_cancel_related_pending_memberships($contributionID): void { |
90 | $connectedMemberships = (array) LineItem::get(FALSE)->setWhere([ |
91 | ['contribution_id', '=', $contributionID], |
92 | ['entity_table', '=', 'civicrm_membership'], |
93 | ])->execute()->indexBy('entity_id'); |
94 | |
95 | if (empty($connectedMemberships)) { |
96 | return; |
97 | } |
98 | // @todo we don't have v4 membership api yet so v3 for now. |
99 | $connectedMemberships = array_keys(civicrm_api3('Membership', 'get', [ |
100 | 'status_id' => 'Pending', |
101 | 'id' => ['IN' => array_keys($connectedMemberships)], |
102 | ])['values']); |
103 | if (empty($connectedMemberships)) { |
104 | return; |
105 | } |
106 | foreach ($connectedMemberships as $membershipID) { |
107 | civicrm_api3('Membership', 'create', ['status_id' => 'Cancelled', 'id' => $membershipID, 'is_override' => 1]); |
108 | } |
109 | } |