Skip to content

Commit

Permalink
Merge pull request #26563 from jitendrapurohit/renew_reminders
Browse files Browse the repository at this point in the history
Exclude Cancelled & Failed recurring from Autorenew membership reminders
  • Loading branch information
eileenmcnaughton authored Mar 29, 2024
2 parents 9de8ca7 + aa8991f commit 3b5affe
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 2 deletions.
20 changes: 18 additions & 2 deletions CRM/Member/ActionMapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,29 @@ public function createQuery($schedule, $phase, $defaultParams): CRM_Utils_SQL_Se
$query['casDateField'] = 'e.' . $query['casDateField'];
}

$recurStatuses = \Civi\Api4\ContributionRecur::getFields(FALSE)
->setLoadOptions(TRUE)
->addWhere('name', '=', 'contribution_status_id')
->addSelect('options')
->execute()
->first()['options'];
// Exclude the renewals that are cancelled or failed.
$nonRenewStatusIds = array_keys(array_intersect($recurStatuses, ['Cancelled', 'Failed']));
// FIXME: Numbers should be constants.
if (in_array(2, $selectedStatuses)) {
//auto-renew memberships
$query->where("e.contribution_recur_id IS NOT NULL");
$query->join('cr', 'INNER JOIN civicrm_contribution_recur cr on e.contribution_recur_id = cr.id');
$query->where("cr.contribution_status_id NOT IN (#nonRenewStatusIds)")
->param('nonRenewStatusIds', $nonRenewStatusIds);
}
elseif (in_array(1, $selectedStatuses)) {
$query->where("e.contribution_recur_id IS NULL");
// non-auto-renew memberships
// Include the renewals that were cancelled or Failed.
$query->join('cr', 'LEFT JOIN civicrm_contribution_recur cr on e.contribution_recur_id = cr.id');
$query->where("e.contribution_recur_id IS NULL OR (
e.contribution_recur_id IS NOT NULL AND cr.contribution_status_id IN (#nonRenewStatusIds)
)")
->param('nonRenewStatusIds', $nonRenewStatusIds);
}

if (!empty($selectedValues)) {
Expand Down
88 changes: 88 additions & 0 deletions tests/phpunit/CRM/Core/BAO/ActionScheduleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1718,6 +1718,94 @@ public function testMultipleMembershipEndDateMatch(): void {
]);
}

/**
* Test Membership Renewal Reminders.
*/
public function testAutoRenewMembershipSchedule(): void {
// Create 3 memberships.
// Normal membership with end_date = 20120615
$membership = $this->createMembershipFromFixture('rolling_membership', 'Grace');
$this->callAPISuccess('Email', 'create', [
'contact_id' => $membership['contact_id'],
'email' => 'test-member@example.com',
]);
$membershipTypeID = $membership['membership_type_id'];

// Auto-renew membership with cancelled recurring payment.
$membership2 = $this->createMembershipFromFixture('rolling_membership', 'Grace', [], ['membership_type_id' => $membershipTypeID]);
$this->callAPISuccess('Email', 'create', [
'contact_id' => $membership2['contact_id'],
'email' => 'test-cancelrenew@example.com',
]);

$contributionRecur = $this->callAPISuccess('contribution_recur', 'create', [
'contact_id' => $membership2['contact_id'],
'installments' => NULL,
'frequency_interval' => '3',
'amount' => '100',
'contribution_status_id' => 4,
'start_date' => '2012-03-15 00:00:00',
'currency' => 'USD',
'frequency_unit' => 'month',
]);
$this->callAPISuccess('Membership', 'create', [
'id' => $membership2['id'],
'contribution_recur_id' => $contributionRecur['id'],
]);

// Auto-renew membership with active recurring payment.
$membership3 = $this->createMembershipFromFixture('rolling_membership', 'Grace', [], ['membership_type_id' => $membershipTypeID]);
$this->callAPISuccess('Email', 'create', [
'contact_id' => $membership3['contact_id'],
'email' => 'test-activerenew@example.com',
]);

$contributionRecur2 = $this->callAPISuccess('contribution_recur', 'create', [
'contact_id' => $membership3['contact_id'],
'installments' => NULL,
'frequency_interval' => '3',
'amount' => '100',
'contribution_status_id' => 2,
'start_date' => '2012-03-15 00:00:00',
'currency' => 'USD',
'frequency_unit' => 'month',
]);
$this->callAPISuccess('Membership', 'create', [
'id' => $membership3['id'],
'contribution_recur_id' => $contributionRecur2['id'],
]);

// Create Reminder to send to auto-renew memberships only.
$this->createScheduleFromFixtures('sched_membership_end_2month', [
'entity_value' => $membership['membership_type_id'],
'entity_status' => 2,
]);

// end_date=2012-06-15 ; schedule is 2 month after end_date
$this->assertCronRuns([
[
// Only active auto-renew contact shiould receive the reminder.
'time' => '2012-08-15 01:00:00',
'recipients' => [['test-activerenew@example.com']],
],
]);

// Create Reminder to send to normal memberships only.
$this->createScheduleFromFixtures('sched_membership_end_2month', [
'entity_value' => $membership['membership_type_id'],
'entity_status' => 1,
]);

// end_date=2012-06-15 ; schedule is 2 month after end_date
$this->assertCronRuns([
[
// Both normal member & cancelled renewal member shiould receive the reminder.
'time' => '2012-08-15 01:00:00',
'recipients' => [['test-member@example.com'], ['test-cancelrenew@example.com']],
],
]);
}

/**
* Test membership end date email.
*
Expand Down

0 comments on commit 3b5affe

Please sign in to comment.