* @throws \CiviCRM_API3_Exception|\CRM_Core_Exception
*/
public function cancelled($objects) {
+ CRM_Core_Error::deprecatedFunctionWarning('Use Contribution create api to cancel the contribution');
$contribution = &$objects['contribution'];
if (empty($contribution->id)) {
}
}
}
+ $participant = &$objects['participant'];
+
+ if ($participant) {
+ $this->cancelParticipant($participant->id);
+ }
}
else {
Contribution::update(FALSE)->setValues([
'contribution_status_id:name' => 'Cancelled',
])->addWhere('id', '=', $contribution->id)->execute();
}
- $participant = &$objects['participant'];
-
- if ($participant) {
- $this->cancelParticipant($participant->id);
- }
Civi::log()->debug("Setting contribution status to Cancelled");
return TRUE;
* Logic to cancel a participant record when the related contribution changes to failed/cancelled.
* @todo This is part of a bigger refactor for dev/core/issues/927 - "duplicate" functionality exists in CRM_Contribute_BAO_Contribution::cancel()
*
+ * @deprecated
+ *
* @param $participantID
*
* @throws \CiviCRM_API3_Exception
+--------------------------------------------------------------------+
*/
+use Civi\Api4\Contribution;
+
/**
*
* @package CRM
return;
}
if ($status === 'Refunded' || $status === 'Reversed') {
- $this->cancelled($objects);
+ Contribution::update(FALSE)->setValues([
+ 'cancel_date' => 'now',
+ 'contribution_status_id:name' => 'Cancelled',
+ ])->addWhere('id', '=', $contributionID)->execute();
+ Civi::log()->debug("Setting contribution status to Cancelled");
return;
}
if ($status !== 'Completed') {
+--------------------------------------------------------------------+
*/
+use Civi\Api4\Contribution;
+
/**
*
* @package CRM
Civi::log()->debug('Returning since contribution status is Pending');
return;
}
- elseif ($status === 'Refunded' || $status === 'Reversed') {
- $this->cancelled($objects);
+ if ($status === 'Refunded' || $status === 'Reversed') {
+ Contribution::update(FALSE)->setValues([
+ 'cancel_date' => 'now',
+ 'contribution_status_id:name' => 'Cancelled',
+ ])->addWhere('id', '=', $contribution->id)->execute();
+ Civi::log()->debug("Setting contribution status to Cancelled");
return;
}
elseif ($status !== 'Completed') {
use CRM_Contributioncancelactions_ExtensionUtil as E;
// phpcs:enable
use Civi\Api4\LineItem;
+use Civi\Api4\Participant;
/**
* Implements hook_civicrm_preProcess().
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]);
+ }
+}
use Civi\Api4\MembershipType;
use Civi\Api4\RelationshipType;
use Civi\Api4\Relationship;
+use Civi\Api4\Event;
+use Civi\Api4\PriceField;
+use Civi\Api4\Participant;
/**
* FIXME - Add test description.
return (int) $result['id'];
}
+ /**
+ * Test that a cancel from paypal pro results in an order being cancelled.
+ *
+ * @throws \API_Exception
+ * @throws \CRM_Core_Exception
+ */
+ public function testPaypalStandardCancel() {
+ $this->ids['contact'][0] = Civi\Api4\Contact::create()->setValues(['first_name' => 'Brer', 'last_name' => 'Rabbit'])->execute()->first()['id'];
+ $event = Event::create()->setValues(['title' => 'Event', 'start_date' => 'tomorrow', 'event_type_id:name' => 'Workshop'])->execute()->first();
+ $order = $this->callAPISuccess('Order', 'create', [
+ 'contact_id' => $this->ids['contact'][0],
+ 'financial_type_id' => 'Donation',
+ 'invoice_id' => 123,
+ 'line_items' => [
+ [
+ 'line_item' => [
+ [
+ 'line_total' => 5,
+ 'qty' => 1,
+ 'financial_type_id' => 1,
+ 'entity_table' => 'civicrm_participant',
+ 'price_field_id' => PriceField::get()->addSelect('id')->addWhere('name', '=', 'contribution_amount')->execute()->first()['id'],
+ ],
+ ],
+ 'params' => [
+ 'contact_id' => $this->ids['contact'][0],
+ 'event_id' => $event['id'],
+ ],
+ ],
+ ],
+ ]);
+ $ipn = new CRM_Core_Payment_PayPalIPN([
+ 'mc_gross' => 200,
+ 'contactID' => $this->ids['contact'][0],
+ 'contributionID' => $order['id'],
+ 'module' => 'event',
+ 'invoice' => 123,
+ 'eventID' => $event['id'],
+ 'participantID' => Participant::get()->addWhere('event_id', '=', (int) $event['id'])->addSelect('id')->execute()->first()['id'],
+ 'payment_status' => 'Refunded',
+ 'processor_id' => $this->createPaymentProcessor(['payment_processor_type_id' => 'PayPal_Standard']),
+ ]);
+ $ipn->main();
+ $this->callAPISuccessGetSingle('Contribution', ['contribution_status_id' => 'Cancelled']);
+ $this->callAPISuccessGetCount('Participant', ['status_id' => 'Cancelled'], 1);
+ }
+
}
+--------------------------------------------------------------------+
*/
+use Civi\Api4\Contribution;
+
/**
* Class CRM_Core_Payment_BaseIPNTest
* @group headless
public function testThatCancellingEventPaymentWillCancelAllAdditionalPendingParticipantsAndCreateCancellationActivities() {
$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',
]);
- $transaction = new CRM_Core_Transaction();
- $this->IPN->cancelled($this->objects);
+ Contribution::update(FALSE)->setValues([
+ 'cancel_date' => 'now',
+ 'contribution_status_id:name' => 'Cancelled',
+ ])->addWhere('id', '=', $this->_contributionId)->execute();
$cancelledParticipantsCount = civicrm_api3('Participant', 'get', [
'sequential' => 1,