From 9cf2fd2be9a25249399949313edaf41a55d87afb Mon Sep 17 00:00:00 2001 From: Ahed Date: Sat, 13 Feb 2021 12:14:18 +0200 Subject: [PATCH 01/11] MAE-318: Fix 'Undefined index: q' error in failing tests These test will implicitly call the method `CRM_Utils_System::currentPath` which will raise 'Undefined index:q' notice because PHPUnit converts PHP errors, warnings, and notices that are triggered during the execution of a test to an exception. --- .../Hook/PostProcess/UpdateSubscriptionTest.php | 12 ++++++++++++ .../Hook/Pre/MembershipEditTest.php | 15 +++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/tests/phpunit/CRM/MembershipExtras/Hook/PostProcess/UpdateSubscriptionTest.php b/tests/phpunit/CRM/MembershipExtras/Hook/PostProcess/UpdateSubscriptionTest.php index 15fb2890..7fa90191 100755 --- a/tests/phpunit/CRM/MembershipExtras/Hook/PostProcess/UpdateSubscriptionTest.php +++ b/tests/phpunit/CRM/MembershipExtras/Hook/PostProcess/UpdateSubscriptionTest.php @@ -45,6 +45,18 @@ public function setUp() { ])['values'][0]; $this->setUpUpdateSubscriptionForm(); + $this->setCurrentPath(); + } + + /** + * Set the current path here to fix the error `Undefined index: q ` + * when using CRM_Utils_System::currentPath + */ + private function setCurrentPath() { + $config = CRM_Core_Config::singleton(); + $tmpGlobals = []; + $tmpGlobals['_GET'][$config->userFrameworkURLVar] = ''; + CRM_Utils_GlobalStack::singleton()->push($tmpGlobals); } /** diff --git a/tests/phpunit/CRM/MembershipExtras/Hook/Pre/MembershipEditTest.php b/tests/phpunit/CRM/MembershipExtras/Hook/Pre/MembershipEditTest.php index 53a6c495..66b86c68 100644 --- a/tests/phpunit/CRM/MembershipExtras/Hook/Pre/MembershipEditTest.php +++ b/tests/phpunit/CRM/MembershipExtras/Hook/Pre/MembershipEditTest.php @@ -16,6 +16,21 @@ */ class CRM_MembershipExtras_Hook_Pre_MembershipEditTest extends BaseHeadlessTest { + public function setUp() { + $this->setCurrentPath(); + } + + /** + * Set the current path here to fix the error `Undefined index: q` + * when using CRM_Utils_System::currentPath + */ + private function setCurrentPath() { + $config = CRM_Core_Config::singleton(); + $tmpGlobals = []; + $tmpGlobals['_GET'][$config->userFrameworkURLVar] = ''; + CRM_Utils_GlobalStack::singleton()->push($tmpGlobals); + } + /** * Helper function to create memberships and its default price field value. * From a44880ad7f16eff721d4ea94aafc62d455d98807 Mon Sep 17 00:00:00 2001 From: Ahed Date: Mon, 15 Feb 2021 17:17:35 +0200 Subject: [PATCH 02/11] MAE-318: Add @throw line and fix typos in phpdoc --- .../MultipleInstalmentPlan.php | 8 ++++- .../Job/OfflineAutoRenewal/PaymentPlan.php | 36 +++++++++++++++++-- .../SingleInstalmentPlan.php | 9 +++++ 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php index e02fbf17..fe1870cc 100644 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php @@ -11,7 +11,7 @@ class CRM_MembershipExtras_Job_OfflineAutoRenewal_MultipleInstalmentPlan extends /** * Returns a list of payment plans with multiple instalments that have at * least one line item ready to be renewed (ie. has an end date, is not - * removed and is set to auto renew), mmeting these conditions: + * removed and is set to auto renew), meeting these conditions: * * 1- is using an offline payment processor (payment manual class). * 2- has an end date. @@ -69,6 +69,7 @@ protected function getRecurringContributions() { /** * @inheritdoc + * @throws \Exception */ public function renew() { $this->createRecurringContribution(); @@ -172,6 +173,7 @@ private function getMembership($id) { * @param int $paymentMethodId * * @return array + * @throws \CiviCRM_API3_Exception */ private function getPaymentMethodNameFromItsId($paymentMethodId) { return civicrm_api3('OptionValue', 'getvalue', [ @@ -187,6 +189,8 @@ private function getPaymentMethodNameFromItsId($paymentMethodId) { * * @param int $currentContributionID * @param int $nextContributionID + * + * @throws \Exception */ private function updateFieldsLinkingPeriods($currentContributionID, $nextContributionID) { $previousPeriodFieldID = $this->getCustomFieldID('related_payment_plan_periods', 'previous_period'); @@ -305,6 +309,7 @@ protected function getAllRecurringContributionActiveLineItems($recurringContribu /** * @inheritdoc + * @throws \CiviCRM_API3_Exception */ protected function getNewPaymentPlanActiveLineItems() { $lineItems = civicrm_api3('ContributionRecurLineItem', 'get', [ @@ -334,6 +339,7 @@ protected function getNewPaymentPlanActiveLineItems() { /** * @inheritdoc + * @throws \CiviCRM_API3_Exception */ protected function calculateRecurringContributionTotalAmount($recurringContributionID) { $totalAmount = 0; diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php index 36f9981d..b75d47a6 100755 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php @@ -123,6 +123,8 @@ abstract class CRM_MembershipExtras_Job_OfflineAutoRenewal_PaymentPlan { /** * CRM_MembershipExtras_Job_OfflineAutoRenewal_PaymentPlan constructor. + * + * @throws \CiviCRM_API3_Exception */ public function __construct() { $this->autoUpgradableMembershipCheckService = new CRM_MembershipExtras_Service_AutoUpgradableMembershipChecker(); @@ -139,6 +141,8 @@ public function __construct() { * into a clss attribute. * * @param $recurringContributionID + * + * @throws \CiviCRM_API3_Exception */ private function setCurrentRecurringContribution($recurringContributionID) { $this->currentRecurContributionID = $recurringContributionID; @@ -150,6 +154,8 @@ private function setCurrentRecurringContribution($recurringContributionID) { /** * Sets the value for the flag to determine if latest membership price should * be used or not on renewal. + * + * @throws \CiviCRM_API3_Exception */ private function setUseMembershipLatestPrice() { $settingFieldName = 'membershipextras_paymentplan_use_membership_latest_price'; @@ -165,6 +171,8 @@ private function setUseMembershipLatestPrice() { /** * Loads value for Pending contribution status into a class attribute. + * + * @throws \CiviCRM_API3_Exception */ private function setContributionPendingStatusValue() { $this->contributionPendingStatusValue = civicrm_api3('OptionValue', 'getvalue', [ @@ -177,7 +185,7 @@ private function setContributionPendingStatusValue() { /** * Gets contribution Statuses Name to value Mapping * - * @return array $contributionStatusesNameMap + * @throws \CiviCRM_API3_Exception */ private function setContributionStatusesNameMap() { $contributionStatuses = civicrm_api3('OptionValue', 'get', [ @@ -294,6 +302,8 @@ abstract protected function getNewPaymentPlanActiveLineItems(); /** * Sets $lastContribution + * + * @throws \CiviCRM_API3_Exception */ private function setLastContribution() { $contribution = civicrm_api3('Contribution', 'get', [ @@ -352,6 +362,7 @@ protected function getCustomFieldID($fieldGroup, $fieldName) { * @param array $lineItem * * @return float + * @throws \CiviCRM_API3_Exception */ protected function calculateLineItemUnitPrice($lineItem) { $priceFieldValue = !empty($lineItem['price_field_value_id']) ? $this->getPriceFieldValue($lineItem['price_field_value_id']) : []; @@ -376,6 +387,7 @@ protected function calculateLineItemUnitPrice($lineItem) { * @param int $priceFieldValueID * * @return array + * @throws \CiviCRM_API3_Exception */ protected function getPriceFieldValue($priceFieldValueID) { return civicrm_api3('PriceFieldValue', 'getsingle', [ @@ -412,6 +424,7 @@ protected function isMembershipLineItem($lineItem, $priceFieldValue = NULL) { * @param array $priceFieldValue * * @return mixed + * @throws \CiviCRM_API3_Exception */ private function getMembershipMinimumFeeFromLineItem($lineItem, $priceFieldValue) { if ($lineItem['entity_table'] == 'civicrm_membership') { @@ -437,6 +450,7 @@ private function getMembershipMinimumFeeFromLineItem($lineItem, $priceFieldValue * @param array $lineItem * * @return bool + * @throws \CiviCRM_API3_Exception */ private function isUseLatestPriceForMembership($lineItem) { $isOptoutUsingLastPrice = FALSE; @@ -501,10 +515,12 @@ protected function calculateLineItemTaxAmount($lineTotal, $financialTypeId) { } /** - * Updates amount on recurring contribution by calculating from associated line - * items. + * Updates amount on recurring contribution by calculating from associated + * line items. * * @param $recurringContributionID + * + * @throws \CiviCRM_API3_Exception */ protected function updateRecurringContributionAmount($recurringContributionID) { $totalAmount = $this->calculateRecurringContributionTotalAmount($recurringContributionID); @@ -579,6 +595,7 @@ protected function renewPaymentPlanMemberships($sourceRecurringContribution) { * @param array $priceFieldValue * * @return int + * @throws \CiviCRM_API3_Exception */ private function getExistingMembershipForLineItem($lineItem, $priceFieldValue) { if ($lineItem['entity_table'] == 'civicrm_membership') { @@ -614,6 +631,7 @@ private function getExistingMembershipForLineItem($lineItem, $priceFieldValue) { * @param array $priceFieldValue * * @return int + * @throws \CiviCRM_API3_Exception */ private function createMembership($lineItem, $priceFieldValue) { $membershipCreateResult = civicrm_api3('Membership', 'create', [ @@ -752,6 +770,8 @@ protected function setTotalAndTaxAmount() { /** * Records the payment plan first contribution. + * + * @throws \CiviCRM_API3_Exception */ protected function recordPaymentPlanFirstContribution() { $params = [ @@ -936,6 +956,8 @@ public static function isUpdateStartDateRenewal() { * @param int $newMembershipTypeId * @param int $recurContributionID * @param string $lineItemStartDate + * + * @throws \CiviCRM_API3_Exception */ protected function createUpgradableSubscriptionMembershipLine($newMembershipTypeId, $recurContributionID, $lineItemStartDate) { $newPriceFieldValue = civicrm_api3('PriceFieldValue', 'get', [ @@ -968,6 +990,12 @@ protected function createUpgradableSubscriptionMembershipLine($newMembershipType ]); } + /** + * @param $membershipTypeId + * + * @return mixed + * @throws \CiviCRM_API3_Exception + */ private function calculateUpgradedMembershipPrice($membershipTypeId) { $membershipMinimumFee = civicrm_api3('MembershipType', 'getvalue', [ 'return' => 'minimum_fee', @@ -983,6 +1011,8 @@ private function calculateUpgradedMembershipPrice($membershipTypeId) { * @param array $lineItemParams * @param string $startDate * @param int $newRecurContributionId + * + * @throws \CiviCRM_API3_Exception */ protected function duplicateSubscriptionLine($lineItemParams, $startDate, $newRecurContributionId) { $lineItemParams['unit_price'] = $this->calculateLineItemUnitPrice($lineItemParams) ?: 0; diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php index 35fbb78d..2f0342f7 100644 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php @@ -113,6 +113,7 @@ protected function getRecurringContributions() { /** * @inheritdoc + * @throws \Exception */ public function renew() { $this->membershipsStartDate = $this->calculateRenewedMembershipsStartDate(); @@ -155,6 +156,8 @@ private function areAnyMembershipsFixed() { /** * Sets new recurring contribution from current recurring contribution. + * + * @throws \CiviCRM_API3_Exception */ private function setNewRecurringContribution() { $this->newRecurringContributionID = $this->currentRecurContributionID; @@ -169,6 +172,8 @@ private function setNewRecurringContribution() { * end date for the old line items. * * @param $recurringContributionID + * + * @throws \Exception */ private function endCurrentLineItemsAndCreateNewOnesForNextPeriod($recurringContributionID) { $newStartDate = new DateTime($this->membershipsStartDate); @@ -227,7 +232,9 @@ private function endLineItem($lineID, DateTime $endDate) { /** * Calculates the new start date for the payment plan * if its paid with no instalments. + * * @return string + * @throws \CiviCRM_API3_Exception */ private function calculateNoInstalmentsPaymentPlanStartDate() { $currentRecurContribution = civicrm_api3('ContributionRecur', 'get', [ @@ -294,6 +301,7 @@ protected function getAllRecurringContributionActiveLineItems($recurringContribu /** * @inheritdoc + * @throws \CiviCRM_API3_Exception */ protected function getNewPaymentPlanActiveLineItems() { $lineItems = civicrm_api3('ContributionRecurLineItem', 'get', [ @@ -324,6 +332,7 @@ protected function getNewPaymentPlanActiveLineItems() { /** * @inheritdoc + * @throws \CiviCRM_API3_Exception */ protected function calculateRecurringContributionTotalAmount($recurringContributionID) { $totalAmount = 0; From 84d8c1ca91ed95dc46a181664291a65f659a1304 Mon Sep 17 00:00:00 2001 From: Ahed Date: Mon, 15 Feb 2021 17:23:02 +0200 Subject: [PATCH 03/11] MAE-318: Refactor getRecurringContributions to return array of integers A simple array of integers to hold the IDs is enough because the number of installments is not used. --- .../MultipleInstalmentPlan.php | 32 +++---------------- .../Job/OfflineAutoRenewal/PaymentPlan.php | 6 ++-- .../SingleInstalmentPlan.php | 10 +++--- 3 files changed, 11 insertions(+), 37 deletions(-) diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php index fe1870cc..b8da422b 100644 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php @@ -32,7 +32,7 @@ protected function getRecurringContributions() { $daysToRenewInAdvance = $this->daysToRenewInAdvance; $query = " - SELECT ccr.id as contribution_recur_id, ccr.installments + SELECT ccr.id as contribution_recur_id FROM civicrm_contribution_recur ccr LEFT JOIN membershipextras_subscription_line msl ON msl.contribution_recur_id = ccr.id LEFT JOIN civicrm_line_item cli ON msl.line_item_id = cli.id @@ -57,14 +57,12 @@ protected function getRecurringContributions() { "; $recurContributions = CRM_Core_DAO::executeQuery($query); - $recurContributionsList = []; + $recurContributionIDs = []; while ($recurContributions->fetch()) { - $recurContribution['contribution_recur_id'] = $recurContributions->contribution_recur_id; - $recurContribution['installments'] = $recurContributions->installments; - $recurContributionsList[] = $recurContribution; + $recurContributionIDs[] = $recurContributions->contribution_recur_id; } - return $recurContributionsList; + return $recurContributionIDs; } /** @@ -145,28 +143,6 @@ private function calculateNewPeriodStartDate() { return $instalmentReceiveDateCalculator->calculate(); } - /** - * Obtains membership identified with provided ID. - * - * @param int $id - * ID of the membership. - * - * @return array - * Membership's data. - * - * @throws \CiviCRM_API3_Exception - */ - private function getMembership($id) { - if (empty($id)) { - return []; - } - - return civicrm_api3('Membership', 'getsingle', [ - 'sequential' => 1, - 'id' => $id, - ]); - } - /** * Obtains payment method name, given its ID. * diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php index b75d47a6..4e1404b8 100755 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php @@ -227,17 +227,17 @@ public function run() { $exceptions = []; $paymentPlans = $this->getRecurringContributions(); - foreach ($paymentPlans as $recurContribution) { + foreach ($paymentPlans as $recurContributionID) { $transaction = new CRM_Core_Transaction(); try { - $this->setCurrentRecurringContribution($recurContribution['contribution_recur_id']); + $this->setCurrentRecurringContribution($recurContributionID); $this->setLastContribution(); $this->renew(); $this->dispatchMembershipRenewalHook(); } catch (Exception $e) { $transaction->rollback(); - $exceptions[] = "An error occurred renewing a payment plan with id ({$recurContribution['contribution_recur_id']}): " . $e->getMessage(); + $exceptions[] = "An error occurred renewing a payment plan with id ({$recurContributionID}): " . $e->getMessage(); } $transaction->commit(); diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php index 2f0342f7..9f940ece 100644 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php @@ -40,7 +40,7 @@ protected function getRecurringContributions() { $daysToRenewInAdvance = $this->daysToRenewInAdvance; $query = " - SELECT ccr.id as contribution_recur_id, ccr.installments, + SELECT ccr.id as contribution_recur_id, CASE WHEN frequency_unit = 'day' THEN DATE_ADD( CASE @@ -101,14 +101,12 @@ protected function getRecurringContributions() { "; $recurContributions = CRM_Core_DAO::executeQuery($query); - $recurContributionsList = []; + $recurContributionIDs = []; while ($recurContributions->fetch()) { - $recurContribution['contribution_recur_id'] = $recurContributions->contribution_recur_id; - $recurContribution['installments'] = $recurContributions->installments; - $recurContributionsList[] = $recurContribution; + $recurContributionIDs[] = $recurContributions->contribution_recur_id; } - return $recurContributionsList; + return $recurContributionIDs; } /** From f5e81afe0b80101f57e541d4cba4aa07a593d81a Mon Sep 17 00:00:00 2001 From: Ahed Date: Fri, 12 Feb 2021 12:38:25 +0200 Subject: [PATCH 04/11] MAE-318: Use queue to process memberships Use CiviCRM queue to process the memberships asynchronically to the auto-renewal job execution if the job triggered from the browser --- .../Job/OfflineAutoRenewal.php | 61 +++++--- CRM/MembershipExtras/Queue/Builder/Base.php | 50 +++++++ .../OfflineMultipleInstalmentPlans.php | 76 ++++++++++ .../Queue/Builder/OfflinePaymentPlans.php | 80 +++++++++++ .../Builder/OfflineSingleInstalmentPlans.php | 116 +++++++++++++++ .../Queue/OfflineAutoRenewal.php | 21 +++ CRM/MembershipExtras/Queue/Task/Base.php | 34 +++++ .../OfflineRenewMultipleInstalmentPlan.php} | 60 +------- .../Task/OfflineRenewPaymentPlan.php} | 135 +++++------------- .../OfflineRenewSingleInstalmentPlan.php} | 100 +------------ .../OfflineMultipleInstalmentPlansTest.php | 92 ++++++++++++ .../OfflineSingleInstalmentPlansTest.php | 92 ++++++++++++ .../CRM/MembershipExtras/Queue/TestCase.php | 81 +++++++++++ 13 files changed, 720 insertions(+), 278 deletions(-) create mode 100644 CRM/MembershipExtras/Queue/Builder/Base.php create mode 100644 CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlans.php create mode 100644 CRM/MembershipExtras/Queue/Builder/OfflinePaymentPlans.php create mode 100644 CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlans.php create mode 100644 CRM/MembershipExtras/Queue/OfflineAutoRenewal.php create mode 100644 CRM/MembershipExtras/Queue/Task/Base.php rename CRM/MembershipExtras/{Job/OfflineAutoRenewal/MultipleInstalmentPlan.php => Queue/Task/OfflineRenewMultipleInstalmentPlan.php} (79%) rename CRM/MembershipExtras/{Job/OfflineAutoRenewal/PaymentPlan.php => Queue/Task/OfflineRenewPaymentPlan.php} (89%) mode change 100755 => 100644 rename CRM/MembershipExtras/{Job/OfflineAutoRenewal/SingleInstalmentPlan.php => Queue/Task/OfflineRenewSingleInstalmentPlan.php} (67%) create mode 100644 tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlansTest.php create mode 100644 tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlansTest.php create mode 100644 tests/phpunit/CRM/MembershipExtras/Queue/TestCase.php diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php index 98816d96..1440f2da 100755 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php @@ -1,39 +1,62 @@ queue = OfflineAutoRenewalQueue::getQueue(); + } + /** * Starts the scheduled job for renewing offline * auto-renewal memberships. * * @return True - * - * @throws \CRM_Core_Exception */ public function run() { - $exceptions = []; + $this->addTasksToQueue(); + $this->runQueue(); - try { - $multipleInstalmentRenewal = new CRM_MembershipExtras_Job_OfflineAutoRenewal_MultipleInstalmentPlan(); - $multipleInstalmentRenewal->run(); - } - catch (CRM_Core_Exception $e) { - $exceptions[] = $e->getMessage(); - } + return TRUE; + } - try { - $singleInstalmentRenewal = new CRM_MembershipExtras_Job_OfflineAutoRenewal_SingleInstalmentPlan(); - $singleInstalmentRenewal->run(); - } - catch (CRM_Core_Exception $e) { - $exceptions[] = $e->getMessage(); + private function addTasksToQueue() { + $queueBuilders = [ + new OfflineMultipleInstalmentPlansQueueBuilder($this->queue), + new OfflineSingleInstalmentPlansQueueBuilder($this->queue), + ]; + foreach ($queueBuilders as $queueBuilder) { + $queueBuilder->run(); } + } + + private function runQueue() { + $runner = new CRM_Queue_Runner([ + 'title' => ts('Processing membership renewals, this may take a while depending on how many records are processed ..'), + 'queue' => $this->queue, + 'errorMode' => CRM_Queue_Runner::ERROR_CONTINUE, + 'onEnd' => array('CRM_MembershipExtras_Job_OfflineAutoRenewal', 'onEnd'), + 'onEndUrl' => CRM_Utils_System::url('civicrm/admin/job', ['reset' => 1]), + ]); - if (count($exceptions)) { - throw new CRM_Core_Exception("Errors found on auto-renewals: " . implode("\n", $exceptions)); + // Only use `runAllViaWeb` if the admin executed the job from CiviCRM UI. + $currentPath = CRM_Utils_System::currentPath(); + if ($currentPath === 'civicrm/admin/job') { + $runner->runAllViaWeb(); } + else { + $runner->runAll(); + } + } - return TRUE; + public static function onEnd(CRM_Queue_TaskContext $ctx) { + $message = ts('Membership Renewals Processing Completed'); + CRM_Core_Session::setStatus($message, '', 'success'); } } diff --git a/CRM/MembershipExtras/Queue/Builder/Base.php b/CRM/MembershipExtras/Queue/Builder/Base.php new file mode 100644 index 00000000..da30fad1 --- /dev/null +++ b/CRM/MembershipExtras/Queue/Builder/Base.php @@ -0,0 +1,50 @@ +queue = $queue; + } + + protected function buildQueue($records) { + foreach ($records as $record) { + if (count($this->records) >= self::RECORDS_LIMIT) { + $this->addQueueTaskItem(); + $this->records = []; + } + + $this->records[] = $record; + } + + if (!empty($this->records)) { + $this->addQueueTaskItem(); + } + } + + protected function addQueueTaskItem() { + $records = implode(', ', $this->records); + $taskTitle = sprintf('Processing the records: %s', $records); + + $task = new CRM_Queue_Task( + $this->taskCallback, + [$this->records], + $taskTitle + ); + + $this->queue->createItem($task); + } + +} diff --git a/CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlans.php b/CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlans.php new file mode 100644 index 00000000..f757fe10 --- /dev/null +++ b/CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlans.php @@ -0,0 +1,76 @@ +getRecurringContributions(); + $this->buildQueue($records); + } + + /** + * Returns a list of payment plans with multiple instalments that have at + * least one line item ready to be renewed (ie. has an end date, is not + * removed and is set to auto renew), mmeting these conditions: + * + * 1- is using an offline payment processor (payment manual class). + * 2- has an end date. + * 3- is set to auto-renew + * 4- is not in status cancelled + * 5- "Next Payment Plan Period" is empty + * 6- has either of the following conditions: + * - end date of at least one membership is equal to or smaller than today + * - there are no related line items with memberships to be renewed and + * line items have an end date + * + * @return array + */ + private function getRecurringContributions() { + $manualPaymentProcessorsIDs = implode(',', $this->manualPaymentProcessorIDs); + $cancelledStatusID = $this->contributionStatusesNameMap['Cancelled']; + $refundedStatusID = $this->contributionStatusesNameMap['Refunded']; + $daysToRenewInAdvance = $this->daysToRenewInAdvance; + + $query = " + SELECT ccr.id as contribution_recur_id + FROM civicrm_contribution_recur ccr + LEFT JOIN membershipextras_subscription_line msl ON msl.contribution_recur_id = ccr.id + LEFT JOIN civicrm_line_item cli ON msl.line_item_id = cli.id + LEFT JOIN civicrm_membership cm ON (cm.id = cli.entity_id AND cli.entity_table = 'civicrm_membership') + LEFT JOIN civicrm_value_payment_plan_periods ppp ON ppp.entity_id = ccr.id + WHERE (ccr.payment_processor_id IS NULL OR ccr.payment_processor_id IN ({$manualPaymentProcessorsIDs})) + AND ccr.installments > 1 + AND ccr.auto_renew = 1 + AND ( + ccr.contribution_status_id != {$cancelledStatusID} + AND ccr.contribution_status_id != {$refundedStatusID} + ) + AND (ppp.next_period IS NULL OR ppp.next_period = 0) + AND msl.auto_renew = 1 + AND msl.is_removed = 0 + GROUP BY ccr.id + HAVING MIN(cm.end_date) <= DATE_ADD(CURDATE(), INTERVAL {$daysToRenewInAdvance} DAY) + OR ( + COUNT(cm.id) = 0 + AND COUNT(msl.id) > 0 + ) + "; + $recurContributions = CRM_Core_DAO::executeQuery($query); + + $recurContributionIDs = []; + while ($recurContributions->fetch()) { + $recurContributionIDs[] = $recurContributions->contribution_recur_id; + } + + return $recurContributionIDs; + } + +} diff --git a/CRM/MembershipExtras/Queue/Builder/OfflinePaymentPlans.php b/CRM/MembershipExtras/Queue/Builder/OfflinePaymentPlans.php new file mode 100644 index 00000000..46561f0c --- /dev/null +++ b/CRM/MembershipExtras/Queue/Builder/OfflinePaymentPlans.php @@ -0,0 +1,80 @@ +setContributionStatusesNameMap(); + $this->setManualPaymentProcessorIDs(); + $this->setDaysToRenewInAdvance(); + } + + /** + * Gets contribution Statuses Name to value Mapping + * + * @throws \CiviCRM_API3_Exception + */ + private function setContributionStatusesNameMap() { + $contributionStatuses = civicrm_api3('OptionValue', 'get', [ + 'sequential' => 1, + 'return' => ['name', 'value'], + 'option_group_id' => 'contribution_status', + 'options' => ['limit' => 0], + ])['values']; + + $contributionStatusesNameMap = []; + foreach ($contributionStatuses as $status) { + $contributionStatusesNameMap[$status['name']] = $status['value']; + } + + $this->contributionStatusesNameMap = $contributionStatusesNameMap; + } + + /** + * Loads setting and assigns it to a class attribute. + */ + private function setDaysToRenewInAdvance() { + $this->daysToRenewInAdvance = CRM_MembershipExtras_SettingsManager::getDaysToRenewInAdvance(); + } + + /** + * Loads list of manual payment processors into an array as a class attribute. + */ + private function setManualPaymentProcessorIDs() { + $payLaterProcessorID = 0; + $this->manualPaymentProcessorIDs = array_merge([$payLaterProcessorID], CRM_MembershipExtras_Service_ManualPaymentProcessors::getIDs()); + } + +} diff --git a/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlans.php b/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlans.php new file mode 100644 index 00000000..2b84cbdc --- /dev/null +++ b/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlans.php @@ -0,0 +1,116 @@ +getRecurringContributions(); + $this->buildQueue($records); + } + + /** + * Obtains list of payment plans with a single instalment that are ready to + * be renewed. This means: + * + * 1- Recurring contribution is a manual payment plan + * 2- Recurring contribution is set to auto-renew. + * 3- Recurring contribution has no end date. + * 4- Recurring contribution is not cancelled nor complete. + * 5- Recurring contribution has either: + * - At least one auto-renew, un-removed line item for a membership with an + * end date before today + $daysToRenewInAdvance. + * - At least one auto-renew, un-removed line item and NO memberships, and + * next_run_date(*) is before today + $daysToRenewInAdvance. + * + * (*) next_run_date corresponds to either maximum end date of all line items + * related to the recurring contribution + 1 period, or the start date of the + * recurring contribution + 1 period, if there are no line items with end + * dates. + * + * @return array + */ + protected function getRecurringContributions() { + $manualPaymentProcessorsIDs = implode(',', $this->manualPaymentProcessorIDs); + $cancelledStatusID = $this->contributionStatusesNameMap['Cancelled']; + $refundedStatusID = $this->contributionStatusesNameMap['Refunded']; + $daysToRenewInAdvance = $this->daysToRenewInAdvance; + + $query = " + SELECT ccr.id as contribution_recur_id, + CASE + WHEN frequency_unit = 'day' THEN DATE_ADD( + CASE + WHEN MAX(msl.end_date) IS NULL THEN ccr.start_date + ELSE MAX(msl.end_date) + END, + INTERVAL frequency_interval DAY + ) + WHEN frequency_unit = 'week' THEN DATE_ADD( + CASE + WHEN MAX(msl.end_date) IS NULL THEN ccr.start_date + ELSE MAX(msl.end_date) + END, + INTERVAL frequency_interval WEEK + ) + WHEN frequency_unit = 'month' THEN DATE_ADD( + CASE + WHEN MAX(msl.end_date) IS NULL THEN ccr.start_date + ELSE MAX(msl.end_date) + END, + INTERVAL frequency_interval MONTH + ) + WHEN frequency_unit = 'year' THEN DATE_ADD( + CASE + WHEN MAX(msl.end_date) IS NULL THEN ccr.start_date + ELSE MAX(msl.end_date) + END, + INTERVAL frequency_interval YEAR + ) + END AS next_run_date + FROM civicrm_contribution_recur ccr + LEFT JOIN membershipextras_subscription_line msl ON msl.contribution_recur_id = ccr.id + LEFT JOIN civicrm_line_item cli ON msl.line_item_id = cli.id + LEFT JOIN civicrm_membership cm ON (cm.id = cli.entity_id AND cli.entity_table = 'civicrm_membership') + LEFT JOIN civicrm_value_payment_plan_periods ppp ON ppp.entity_id = ccr.id + WHERE (ccr.payment_processor_id IS NULL OR ccr.payment_processor_id IN ({$manualPaymentProcessorsIDs})) + AND ccr.end_date IS NULL + AND ( + ccr.installments < 2 + OR ccr.installments IS NULL + ) + AND ccr.auto_renew = 1 + AND ( + ccr.contribution_status_id != {$cancelledStatusID} + AND ccr.contribution_status_id != {$refundedStatusID} + ) + AND ppp.next_period IS NULL + AND msl.auto_renew = 1 + AND msl.is_removed = 0 + AND msl.end_date IS NULL + + GROUP BY ccr.id + HAVING MIN(cm.end_date) <= DATE_ADD(CURDATE(), INTERVAL {$daysToRenewInAdvance} DAY) + OR ( + COUNT(cm.id) = 0 + AND next_run_date <= DATE_ADD(CURDATE(), INTERVAL {$daysToRenewInAdvance} DAY) + ) + "; + $recurContributions = CRM_Core_DAO::executeQuery($query); + + $recurContributionIDs = []; + while ($recurContributions->fetch()) { + $recurContributionIDs[] = $recurContributions->contribution_recur_id; + } + + return $recurContributionIDs; + } + +} diff --git a/CRM/MembershipExtras/Queue/OfflineAutoRenewal.php b/CRM/MembershipExtras/Queue/OfflineAutoRenewal.php new file mode 100644 index 00000000..12b9b7d7 --- /dev/null +++ b/CRM/MembershipExtras/Queue/OfflineAutoRenewal.php @@ -0,0 +1,21 @@ +create([ + 'type' => 'Sql', + 'name' => self::QUEUE_NAME, + 'reset' => FALSE, + ]); + } + + return self::$queue; + } + +} diff --git a/CRM/MembershipExtras/Queue/Task/Base.php b/CRM/MembershipExtras/Queue/Task/Base.php new file mode 100644 index 00000000..9e853249 --- /dev/null +++ b/CRM/MembershipExtras/Queue/Task/Base.php @@ -0,0 +1,34 @@ +process($record); + } + catch (Exception $e) { + $errorMessage = 'Failed to process task ' . static::class . ' with Id: ' . $record . ' - Error message : ' . $e->getMessage(); + $ctx->log->err($errorMessage); + } + } + + $totalExecutionTime = (microtime(TRUE) - $processingStartTime); + $endProcessingMessage = 'Finished processing the ' . static::class . ' task In : ' . $totalExecutionTime . ' Seconds'; + $ctx->log->info($endProcessingMessage); + + return TRUE; + } + + abstract protected function process($record); + +} diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php b/CRM/MembershipExtras/Queue/Task/OfflineRenewMultipleInstalmentPlan.php similarity index 79% rename from CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php rename to CRM/MembershipExtras/Queue/Task/OfflineRenewMultipleInstalmentPlan.php index b8da422b..de5d3f6f 100644 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultipleInstalmentPlan.php +++ b/CRM/MembershipExtras/Queue/Task/OfflineRenewMultipleInstalmentPlan.php @@ -1,4 +1,5 @@ manualPaymentProcessorIDs); - $cancelledStatusID = $this->contributionStatusesNameMap['Cancelled']; - $refundedStatusID = $this->contributionStatusesNameMap['Refunded']; - $daysToRenewInAdvance = $this->daysToRenewInAdvance; - - $query = " - SELECT ccr.id as contribution_recur_id - FROM civicrm_contribution_recur ccr - LEFT JOIN membershipextras_subscription_line msl ON msl.contribution_recur_id = ccr.id - LEFT JOIN civicrm_line_item cli ON msl.line_item_id = cli.id - LEFT JOIN civicrm_membership cm ON (cm.id = cli.entity_id AND cli.entity_table = 'civicrm_membership') - LEFT JOIN civicrm_value_payment_plan_periods ppp ON ppp.entity_id = ccr.id - WHERE (ccr.payment_processor_id IS NULL OR ccr.payment_processor_id IN ({$manualPaymentProcessorsIDs})) - AND ccr.installments > 1 - AND ccr.auto_renew = 1 - AND ( - ccr.contribution_status_id != {$cancelledStatusID} - AND ccr.contribution_status_id != {$refundedStatusID} - ) - AND (ppp.next_period IS NULL OR ppp.next_period = 0) - AND msl.auto_renew = 1 - AND msl.is_removed = 0 - GROUP BY ccr.id - HAVING MIN(cm.end_date) <= DATE_ADD(CURDATE(), INTERVAL {$daysToRenewInAdvance} DAY) - OR ( - COUNT(cm.id) = 0 - AND COUNT(msl.id) > 0 - ) - "; - $recurContributions = CRM_Core_DAO::executeQuery($query); - - $recurContributionIDs = []; - while ($recurContributions->fetch()) { - $recurContributionIDs[] = $recurContributions->contribution_recur_id; - } - - return $recurContributionIDs; - } +class CRM_MembershipExtras_Queue_Task_OfflineRenewMultipleInstalmentPlan extends OfflineRenewPaymentPlanTask { /** * @inheritdoc diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php b/CRM/MembershipExtras/Queue/Task/OfflineRenewPaymentPlan.php old mode 100755 new mode 100644 similarity index 89% rename from CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php rename to CRM/MembershipExtras/Queue/Task/OfflineRenewPaymentPlan.php index 4e1404b8..5336a6a7 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal/PaymentPlan.php +++ b/CRM/MembershipExtras/Queue/Task/OfflineRenewPaymentPlan.php @@ -1,13 +1,16 @@ setUseMembershipLatestPrice(); $this->setContributionPendingStatusValue(); - $this->setContributionStatusesNameMap(); - $this->setManualPaymentProcessorIDs(); - $this->setDaysToRenewInAdvance(); } /** @@ -144,7 +123,7 @@ public function __construct() { * * @throws \CiviCRM_API3_Exception */ - private function setCurrentRecurringContribution($recurringContributionID) { + protected function setCurrentRecurringContribution($recurringContributionID) { $this->currentRecurContributionID = $recurringContributionID; $this->currentRecurringContribution = civicrm_api3('ContributionRecur', 'getsingle', [ 'id' => $this->currentRecurContributionID, @@ -157,7 +136,7 @@ private function setCurrentRecurringContribution($recurringContributionID) { * * @throws \CiviCRM_API3_Exception */ - private function setUseMembershipLatestPrice() { + protected function setUseMembershipLatestPrice() { $settingFieldName = 'membershipextras_paymentplan_use_membership_latest_price'; $useMembershipLatestPrice = civicrm_api3('Setting', 'get', [ 'sequential' => 1, @@ -174,7 +153,7 @@ private function setUseMembershipLatestPrice() { * * @throws \CiviCRM_API3_Exception */ - private function setContributionPendingStatusValue() { + protected function setContributionPendingStatusValue() { $this->contributionPendingStatusValue = civicrm_api3('OptionValue', 'getvalue', [ 'return' => 'value', 'option_group_id' => 'contribution_status', @@ -183,78 +162,28 @@ private function setContributionPendingStatusValue() { } /** - * Gets contribution Statuses Name to value Mapping + * Renews the given payment plan. + * + * @param $recurContributionID * * @throws \CiviCRM_API3_Exception */ - private function setContributionStatusesNameMap() { - $contributionStatuses = civicrm_api3('OptionValue', 'get', [ - 'sequential' => 1, - 'return' => ['name', 'value'], - 'option_group_id' => 'contribution_status', - 'options' => ['limit' => 0], - ])['values']; - - $contributionStatusesNameMap = []; - foreach ($contributionStatuses as $status) { - $contributionStatusesNameMap[$status['name']] = $status['value']; + protected function process($recurContributionID) { + $transaction = new CRM_Core_Transaction(); + try { + $this->setCurrentRecurringContribution($recurContributionID); + $this->setLastContribution(); + $this->renew(); + $this->dispatchMembershipRenewalHook(); } - - $this->contributionStatusesNameMap = $contributionStatusesNameMap; - } - - /** - * Loads setting and assigns it to a class attribute. - */ - private function setDaysToRenewInAdvance() { - $this->daysToRenewInAdvance = CRM_MembershipExtras_SettingsManager::getDaysToRenewInAdvance(); - } - - /** - * Loads list of manual payment processors into an array as a class attribute. - */ - private function setManualPaymentProcessorIDs() { - $payLaterProcessorID = 0; - $this->manualPaymentProcessorIDs = array_merge([$payLaterProcessorID], CRM_MembershipExtras_Service_ManualPaymentProcessors::getIDs()); - } - - /** - * Renews the given payment plan. - * - * @throws \CRM_Core_Exception - */ - public function run() { - $exceptions = []; - $paymentPlans = $this->getRecurringContributions(); - - foreach ($paymentPlans as $recurContributionID) { - $transaction = new CRM_Core_Transaction(); - try { - $this->setCurrentRecurringContribution($recurContributionID); - $this->setLastContribution(); - $this->renew(); - $this->dispatchMembershipRenewalHook(); - } - catch (Exception $e) { - $transaction->rollback(); - $exceptions[] = "An error occurred renewing a payment plan with id ({$recurContributionID}): " . $e->getMessage(); - } - - $transaction->commit(); + catch (Exception $e) { + $transaction->rollback(); + throw $e; } - if (count($exceptions)) { - throw new CRM_Core_Exception(implode(";\n", $exceptions)); - } + $transaction->commit(); } - /** - * Retunrs an array of recurring contributions that need to be renewed. - * - * @return array - */ - abstract protected function getRecurringContributions(); - /** * Renews the current payment plan. */ @@ -263,7 +192,7 @@ abstract public function renew(); /** * Dispatches postOfflineAutoRenewal hook for the recurring contribution. */ - private function dispatchMembershipRenewalHook() { + protected function dispatchMembershipRenewalHook() { $dispatcher = new PostOfflineAutoRenewalDispatcher(NULL, $this->newRecurringContributionID, $this->currentRecurContributionID); $dispatcher->dispatch(); } @@ -305,7 +234,7 @@ abstract protected function getNewPaymentPlanActiveLineItems(); * * @throws \CiviCRM_API3_Exception */ - private function setLastContribution() { + protected function setLastContribution() { $contribution = civicrm_api3('Contribution', 'get', [ 'sequential' => 1, 'return' => ['currency', 'contribution_source', 'net_amount', @@ -426,7 +355,7 @@ protected function isMembershipLineItem($lineItem, $priceFieldValue = NULL) { * @return mixed * @throws \CiviCRM_API3_Exception */ - private function getMembershipMinimumFeeFromLineItem($lineItem, $priceFieldValue) { + protected function getMembershipMinimumFeeFromLineItem($lineItem, $priceFieldValue) { if ($lineItem['entity_table'] == 'civicrm_membership') { $membershipTypeID = civicrm_api3('Membership', 'getsingle', [ 'id' => $lineItem['entity_id'], @@ -452,7 +381,7 @@ private function getMembershipMinimumFeeFromLineItem($lineItem, $priceFieldValue * @return bool * @throws \CiviCRM_API3_Exception */ - private function isUseLatestPriceForMembership($lineItem) { + protected function isUseLatestPriceForMembership($lineItem) { $isOptoutUsingLastPrice = FALSE; $optoutUsingLastPriceFieldID = civicrm_api3('CustomField', 'getvalue', [ 'return' => 'id', @@ -597,7 +526,7 @@ protected function renewPaymentPlanMemberships($sourceRecurringContribution) { * @return int * @throws \CiviCRM_API3_Exception */ - private function getExistingMembershipForLineItem($lineItem, $priceFieldValue) { + protected function getExistingMembershipForLineItem($lineItem, $priceFieldValue) { if ($lineItem['entity_table'] == 'civicrm_membership') { return $lineItem['entity_id']; } @@ -633,7 +562,7 @@ private function getExistingMembershipForLineItem($lineItem, $priceFieldValue) { * @return int * @throws \CiviCRM_API3_Exception */ - private function createMembership($lineItem, $priceFieldValue) { + protected function createMembership($lineItem, $priceFieldValue) { $membershipCreateResult = civicrm_api3('Membership', 'create', [ 'contact_id' => $this->currentRecurringContribution['contact_id'], 'membership_type_id' => $priceFieldValue['membership_type_id'], @@ -655,7 +584,7 @@ private function createMembership($lineItem, $priceFieldValue) { * * @throws \CiviCRM_API3_Exception */ - private function extendExistingMembership($membershipID) { + protected function extendExistingMembership($membershipID) { $endDate = MembershipEndDateCalculator::calculate($membershipID); $isUpdateStartDateRenewal = self::isUpdateStartDateRenewal(); $relatedMemberships = $this->loadRelatedMembershipIDs($membershipID); @@ -683,7 +612,7 @@ private function extendExistingMembership($membershipID) { * @return array * @throws \CiviCRM_API3_Exception */ - private function loadRelatedMembershipIDs($membershipID) { + protected function loadRelatedMembershipIDs($membershipID) { $result = civicrm_api3('Membership', 'get', [ 'sequential' => 1, 'owner_membership_id' => $membershipID, @@ -864,7 +793,7 @@ protected function recordPaymentPlanFirstContribution() { * * @throws \CiviCRM_API3_Exception */ - private function isDuplicateLineItem($lineItem) { + protected function isDuplicateLineItem($lineItem) { $priceFieldID = CRM_Utils_Array::value('price_field_id', $lineItem); $priceFieldValueID = CRM_Utils_Array::value('price_field_value_id', $lineItem); if (!$priceFieldID || !$priceFieldValueID) { @@ -996,7 +925,7 @@ protected function createUpgradableSubscriptionMembershipLine($newMembershipType * @return mixed * @throws \CiviCRM_API3_Exception */ - private function calculateUpgradedMembershipPrice($membershipTypeId) { + protected function calculateUpgradedMembershipPrice($membershipTypeId) { $membershipMinimumFee = civicrm_api3('MembershipType', 'getvalue', [ 'return' => 'minimum_fee', 'id' => $membershipTypeId, diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php b/CRM/MembershipExtras/Queue/Task/OfflineRenewSingleInstalmentPlan.php similarity index 67% rename from CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php rename to CRM/MembershipExtras/Queue/Task/OfflineRenewSingleInstalmentPlan.php index 9f940ece..23a2c507 100644 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlan.php +++ b/CRM/MembershipExtras/Queue/Task/OfflineRenewSingleInstalmentPlan.php @@ -1,4 +1,5 @@ manualPaymentProcessorIDs); - $cancelledStatusID = $this->contributionStatusesNameMap['Cancelled']; - $refundedStatusID = $this->contributionStatusesNameMap['Refunded']; - $daysToRenewInAdvance = $this->daysToRenewInAdvance; - - $query = " - SELECT ccr.id as contribution_recur_id, - CASE - WHEN frequency_unit = 'day' THEN DATE_ADD( - CASE - WHEN MAX(msl.end_date) IS NULL THEN ccr.start_date - ELSE MAX(msl.end_date) - END, - INTERVAL frequency_interval DAY - ) - WHEN frequency_unit = 'week' THEN DATE_ADD( - CASE - WHEN MAX(msl.end_date) IS NULL THEN ccr.start_date - ELSE MAX(msl.end_date) - END, - INTERVAL frequency_interval WEEK - ) - WHEN frequency_unit = 'month' THEN DATE_ADD( - CASE - WHEN MAX(msl.end_date) IS NULL THEN ccr.start_date - ELSE MAX(msl.end_date) - END, - INTERVAL frequency_interval MONTH - ) - WHEN frequency_unit = 'year' THEN DATE_ADD( - CASE - WHEN MAX(msl.end_date) IS NULL THEN ccr.start_date - ELSE MAX(msl.end_date) - END, - INTERVAL frequency_interval YEAR - ) - END AS next_run_date - FROM civicrm_contribution_recur ccr - LEFT JOIN membershipextras_subscription_line msl ON msl.contribution_recur_id = ccr.id - LEFT JOIN civicrm_line_item cli ON msl.line_item_id = cli.id - LEFT JOIN civicrm_membership cm ON (cm.id = cli.entity_id AND cli.entity_table = 'civicrm_membership') - LEFT JOIN civicrm_value_payment_plan_periods ppp ON ppp.entity_id = ccr.id - WHERE (ccr.payment_processor_id IS NULL OR ccr.payment_processor_id IN ({$manualPaymentProcessorsIDs})) - AND ccr.end_date IS NULL - AND ( - ccr.installments < 2 - OR ccr.installments IS NULL - ) - AND ccr.auto_renew = 1 - AND ( - ccr.contribution_status_id != {$cancelledStatusID} - AND ccr.contribution_status_id != {$refundedStatusID} - ) - AND ppp.next_period IS NULL - AND msl.auto_renew = 1 - AND msl.is_removed = 0 - AND msl.end_date IS NULL - - GROUP BY ccr.id - HAVING MIN(cm.end_date) <= DATE_ADD(CURDATE(), INTERVAL {$daysToRenewInAdvance} DAY) - OR ( - COUNT(cm.id) = 0 - AND next_run_date <= DATE_ADD(CURDATE(), INTERVAL {$daysToRenewInAdvance} DAY) - ) - "; - $recurContributions = CRM_Core_DAO::executeQuery($query); - - $recurContributionIDs = []; - while ($recurContributions->fetch()) { - $recurContributionIDs[] = $recurContributions->contribution_recur_id; - } - - return $recurContributionIDs; - } +class CRM_MembershipExtras_Queue_Task_OfflineRenewSingleInstalmentPlan extends OfflineRenewPaymentPlanTask { /** * @inheritdoc diff --git a/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlansTest.php b/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlansTest.php new file mode 100644 index 00000000..d672158b --- /dev/null +++ b/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlansTest.php @@ -0,0 +1,92 @@ +setDefaultPaymentPlanSettings(); + $this->createTestRollingMembershipType(); + } + + private function setDefaultPaymentPlanSettings() { + civicrm_api3('Setting', 'create', [ + 'membershipextras_paymentplan_days_to_renew_in_advance' => 0, + ]); + + civicrm_api3('Setting', 'create', [ + 'membershipextras_paymentplan_update_start_date_renewal' => 0, + ]); + } + + private function createTestRollingMembershipType() { + $this->testRollingMembershipType = MembershipTypeFabricator::fabricate( + [ + 'name' => 'Test Rolling Membership', + 'period_type' => 'rolling', + 'minimum_fee' => 120, + 'duration_interval' => 1, + 'duration_unit' => 'year', + ]); + + $this->testRollingMembershipTypePriceFieldValue = civicrm_api3('PriceFieldValue', 'get', [ + 'sequential' => 1, + 'membership_type_id' => $this->testRollingMembershipType['id'], + 'options' => ['limit' => 1], + ])['values'][0]; + } + + public function testBuildQueueWillAddTasksToQueue() { + $NumberOfPaymentPlans = 12; + for ($i = 0; $i < $NumberOfPaymentPlans; $i++) { + $paymentPlanMembershipOrder = new PaymentPlanMembershipOrder(); + $paymentPlanMembershipOrder->membershipStartDate = date('Y-m-d', strtotime('-1 year +1 day')); + $paymentPlanMembershipOrder->paymentPlanFrequency = 'Monthly'; + $paymentPlanMembershipOrder->paymentPlanStatus = 'Completed'; + $paymentPlanMembershipOrder->lineItems[] = [ + 'entity_table' => 'civicrm_membership', + 'price_field_id' => $this->testRollingMembershipTypePriceFieldValue['price_field_id'], + 'price_field_value_id' => $this->testRollingMembershipTypePriceFieldValue['id'], + 'label' => $this->testRollingMembershipType['name'], + 'qty' => 1, + 'unit_price' => $this->testRollingMembershipTypePriceFieldValue['amount'], + 'line_total' => $this->testRollingMembershipTypePriceFieldValue['amount'], + 'financial_type_id' => 'Member Dues', + 'non_deductible_amount' => 0, + ]; + PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); + } + + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + + $expectedNumberOfTasks = ceil($NumberOfPaymentPlans / CRM_MembershipExtras_Queue_Builder_Base::RECORDS_LIMIT); + $this->assertEquals($expectedNumberOfTasks, $this->getNumberOfTasks()); + } + +} diff --git a/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlansTest.php b/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlansTest.php new file mode 100644 index 00000000..d3d55940 --- /dev/null +++ b/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlansTest.php @@ -0,0 +1,92 @@ +setDefaultPaymentPlanSettings(); + $this->createTestRollingMembershipType(); + } + + private function setDefaultPaymentPlanSettings() { + civicrm_api3('Setting', 'create', [ + 'membershipextras_paymentplan_days_to_renew_in_advance' => 0, + ]); + + civicrm_api3('Setting', 'create', [ + 'membershipextras_paymentplan_update_start_date_renewal' => 0, + ]); + } + + private function createTestRollingMembershipType() { + $this->testRollingMembershipType = MembershipTypeFabricator::fabricate( + [ + 'name' => 'Test Rolling Membership', + 'period_type' => 'rolling', + 'minimum_fee' => 120, + 'duration_interval' => 1, + 'duration_unit' => 'year', + ]); + + $this->testRollingMembershipTypePriceFieldValue = civicrm_api3('PriceFieldValue', 'get', [ + 'sequential' => 1, + 'membership_type_id' => $this->testRollingMembershipType['id'], + 'options' => ['limit' => 1], + ])['values'][0]; + } + + public function testBuildQueueWillAddTasksToQueue() { + $NumberOfPaymentPlans = 12; + for ($i = 0; $i < $NumberOfPaymentPlans; $i++) { + $paymentPlanMembershipOrder = new PaymentPlanMembershipOrder(); + $paymentPlanMembershipOrder->membershipStartDate = date('Y-m-d', strtotime('-1 year -1 month')); + $paymentPlanMembershipOrder->paymentPlanFrequency = 'Yearly'; + $paymentPlanMembershipOrder->paymentPlanStatus = 'Completed'; + $paymentPlanMembershipOrder->lineItems[] = [ + 'entity_table' => 'civicrm_membership', + 'price_field_id' => $this->testRollingMembershipTypePriceFieldValue['price_field_id'], + 'price_field_value_id' => $this->testRollingMembershipTypePriceFieldValue['id'], + 'label' => $this->testRollingMembershipType['name'], + 'qty' => 1, + 'unit_price' => $this->testRollingMembershipTypePriceFieldValue['amount'], + 'line_total' => $this->testRollingMembershipTypePriceFieldValue['amount'], + 'financial_type_id' => 'Member Dues', + 'non_deductible_amount' => 0, + ]; + PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); + } + + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + + $expectedNumberOfTasks = ceil($NumberOfPaymentPlans / CRM_MembershipExtras_Queue_Builder_Base::RECORDS_LIMIT); + $this->assertEquals($expectedNumberOfTasks, $this->getNumberOfTasks()); + } + +} diff --git a/tests/phpunit/CRM/MembershipExtras/Queue/TestCase.php b/tests/phpunit/CRM/MembershipExtras/Queue/TestCase.php new file mode 100644 index 00000000..1e814a3c --- /dev/null +++ b/tests/phpunit/CRM/MembershipExtras/Queue/TestCase.php @@ -0,0 +1,81 @@ +setUpQueue(); + } + + public function tearDown() { + $this->tearDownQueue(); + } + + /** + * Create in-memory queue + */ + private function setUpQueue() { + $this->queueService = CRM_Queue_Service::singleton(TRUE); + $this->queue = $this->queueService->create([ + 'type' => 'Memory', + 'name' => 'uk.co.compucorp.membershipextras.test.queue.offlineautorenewal', + ]); + $this->runner = new CRM_Queue_Runner([ + 'queue' => $this->queue, + 'errorMode' => CRM_Queue_Runner::ERROR_ABORT, + ]); + } + + /** + * Delete the queue + */ + private function tearDownQueue() { + unset($this->queue); + unset($this->queueService); + unset($this->runner); + } + + /** + * Run the specified queue builder to add tasks to the queue + */ + protected function runQueueBuilder($queueBuilderClass) { + $queueBuilder = new $queueBuilderClass($this->queue); + $queueBuilder->run(); + } + + /** + * Run all the tasks + */ + protected function runQueueRunner() { + $this->runner->runAll(); + } + + /** + * Get the number of Tasks + * + * @return int + */ + protected function getNumberOfTasks() { + return $this->queue->numberOfItems(); + } + +} From faf8fe269199d7622cab675dcd5aa2265054c8cc Mon Sep 17 00:00:00 2001 From: Ahed Date: Sat, 13 Feb 2021 13:27:31 +0200 Subject: [PATCH 05/11] MAE-318: Fix failing tests because of the renamed files --- .../Task/RenewMultipleInstalmentPlanTest.php} | 84 ++++++++-------- .../Task/RenewSingleInstalmentPlanTest.php} | 96 ++++++++++--------- 2 files changed, 92 insertions(+), 88 deletions(-) rename tests/phpunit/CRM/MembershipExtras/{Job/OfflineAutoRenewal/MultiInstalmentPlanTest.php => Queue/Task/RenewMultipleInstalmentPlanTest.php} (95%) rename tests/phpunit/CRM/MembershipExtras/{Job/OfflineAutoRenewal/SingleInstalmentPlanTest.php => Queue/Task/RenewSingleInstalmentPlanTest.php} (95%) diff --git a/tests/phpunit/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultiInstalmentPlanTest.php b/tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewMultipleInstalmentPlanTest.php similarity index 95% rename from tests/phpunit/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultiInstalmentPlanTest.php rename to tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewMultipleInstalmentPlanTest.php index 5cc17afb..b7249ea2 100644 --- a/tests/phpunit/CRM/MembershipExtras/Job/OfflineAutoRenewal/MultiInstalmentPlanTest.php +++ b/tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewMultipleInstalmentPlanTest.php @@ -1,19 +1,20 @@ setDefaultPaymentPlanSettings(); $this->createTestRollingMembershipType(); } @@ -81,8 +83,8 @@ public function testRenewalWithMembershipEndDateLessThanTodayDateWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); } @@ -105,8 +107,8 @@ public function testRenewalWithMembershipEndDateEqualTodayDateWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year')); } @@ -129,8 +131,8 @@ public function testRenewalWithMembershipEndDateLargerThanTodayDateWillNotRenew( ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +1 day')); } @@ -161,8 +163,8 @@ public function testRenewalWithNonOfflinePaymentProcessorPaymentPlanWillNotRenew ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); } @@ -185,8 +187,8 @@ public function testRenewalWithNonCompletedInstalmentWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); } @@ -209,8 +211,8 @@ public function testRenewalWithCancelledPaymentPlanWillNotRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); } @@ -237,8 +239,8 @@ public function testRenewalWithMembershipEndDateLargerThanDateToRenewInAdvanceWi ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +1 day')); } @@ -265,8 +267,8 @@ public function testRenewalWithMembershipEndDateLessThanDateToRenewInAdvanceWill ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +14 day')); } @@ -293,8 +295,8 @@ public function testRenewalWithUpdateStartDateOnRenewalSettingOffWillNotUpdateMe ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $membership = civicrm_api3('Membership', 'get', [ 'sequential' => 1, @@ -325,8 +327,8 @@ public function testRenewalWithUpdateStartDateOnRenewalSettingOnWillUpdateMember ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $membership = civicrm_api3('Membership', 'get', [ 'sequential' => 1, @@ -354,8 +356,8 @@ public function testNewCopyOfLineItemsWillBeCreatedAfterRenewalInsteadOfReusingT ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $membershipId = (int) civicrm_api3('Membership', 'getvalue', [ 'return' => 'id', @@ -391,8 +393,8 @@ public function testRenewingMembershipWithEndDateLessThanTodayDateWillCreateCorr ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $currentPeriodSubscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); $nextPeriodId = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); @@ -460,8 +462,8 @@ public function testRenewingMembershipWillCreateCorrectMembershipPaymentRecords( ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $membershipId = (int) civicrm_api3('Membership', 'getvalue', [ 'return' => 'id', @@ -510,8 +512,8 @@ public function testRenewingUpgradableMembershipWithWillCreateUpgradedMembership 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $currentMembership = civicrm_api3('Membership', 'get', [ 'sequential' => 1, @@ -577,8 +579,8 @@ public function testRenewingUpgradableMembershipWillCreateCorrectMembershipPayme 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $nextPeriodId = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); @@ -661,8 +663,8 @@ public function testRenewingUpgradableMembershipWithWillCreateCorrectSubscriptio 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $currentPeriodSubscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); $nextPeriodId = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); @@ -798,8 +800,8 @@ public function testRenewalWithNonRenewableLineOnCurrentPeriodAndNewMembershipFo 'duration_unit' => 'year', ]); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $nextPeriodID = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); $this->assertPaymentPlanStructureIsOk($nextPeriodID, [ @@ -903,8 +905,8 @@ public function testRenewalWithMultipleLinesNotRenewingOnCurrentPeriodAndNewMemb 'duration_unit' => 'year', ]); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $nextPeriodID = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); @@ -997,8 +999,8 @@ public function testRenewalWithMultipleLinesSomeRenewingOnCurrentPeriodAndNewMem 'duration_unit' => 'year', ]); - $multipleInstalmentRenewal = new MultipleInstalmentRenewalJob(); - $multipleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $nextPeriodID = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); diff --git a/tests/phpunit/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlanTest.php b/tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewSingleInstalmentPlanTest.php similarity index 95% rename from tests/phpunit/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlanTest.php rename to tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewSingleInstalmentPlanTest.php index b34d6bdc..1f60aed4 100644 --- a/tests/phpunit/CRM/MembershipExtras/Job/OfflineAutoRenewal/SingleInstalmentPlanTest.php +++ b/tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewSingleInstalmentPlanTest.php @@ -1,19 +1,20 @@ setDefaultPaymentPlanSettings(); $this->createTestRollingMembershipType(); } @@ -81,8 +83,8 @@ public function testRenewalWithMembershipEndDateLessThanTodayDateWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); } @@ -105,8 +107,8 @@ public function testRenewalWithMembershipEndDateEqualTodayDateWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year')); } @@ -129,8 +131,8 @@ public function testRenewalWithMembershipEndDateLargerThanTodayDateWillNotRenew( ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +1 day')); } @@ -161,8 +163,8 @@ public function testRenewalWithNonOfflinePaymentProcessorPaymentPlanWillNotRenew ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); } @@ -185,8 +187,8 @@ public function testRenewalWithNonCompletedInstalmentWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); } @@ -209,8 +211,8 @@ public function testRenewalWithCancelledPaymentPlanWillNotRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); } @@ -237,8 +239,8 @@ public function testRenewalWithMembershipEndDateLargerThanDateToRenewInAdvanceWi ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +1 day')); } @@ -265,8 +267,8 @@ public function testRenewalWithMembershipEndDateLessThanDateToRenewInAdvanceWill ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +14 day')); } @@ -293,8 +295,8 @@ public function testRenewalWithUpdateStartDateOnRenewalSettingOffWillNotUpdateMe ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $membership = $this->getPaymentPlanAutorenewableMemberships($paymentPlan['id'])[0]; $this->assertEquals($paymentPlanMembershipOrder->membershipStartDate, $membership['start_date']); @@ -322,8 +324,8 @@ public function testRenewalWithUpdateStartDateOnRenewalSettingOnWillUpdateMember ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $membership = $this->getPaymentPlanAutorenewableMemberships($paymentPlan['id'])[0]; $expectedNewMembershipStartDate = date('Y-m-d', strtotime($paymentPlanMembershipOrder->membershipStartDate . ' +1 year')); @@ -348,8 +350,8 @@ public function testNewCopyOfLineItemsWillBeCreatedAfterRenewalInsteadOfReusingT ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $membershipId = (int) civicrm_api3('Membership', 'getvalue', [ 'return' => 'id', @@ -385,8 +387,8 @@ public function testRenewingMembershipWithEndDateLessThanTodayDateWillCreateCorr ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $subscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); @@ -447,8 +449,8 @@ public function testRenewingMembershipWithEndDateLargerThanDateToRenewInAdvanceW ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $subscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); @@ -505,8 +507,8 @@ public function testRenewingMembershipWillCreateCorrectMembershipPaymentRecords( ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $membershipId = (int) civicrm_api3('Membership', 'getvalue', [ 'return' => 'id', @@ -554,8 +556,8 @@ public function testRenewingUpgradableMembershipWithWillCreateUpgradedMembership 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $createdMemberships = $this->getPaymentPlanAutorenewableMemberships($paymentPlan['id']); $isFirstMembershipEnded = $createdMemberships[0]['end_date'] == date('Y-m-d', strtotime($paymentPlanMembershipOrder->membershipStartDate . ' +1 year -1 day')); @@ -612,8 +614,8 @@ public function testRenewingUpgradableMembershipWillCreateCorrectMembershipPayme 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $isAllMembershipPaymentRecordsCreated = TRUE; $createdMemberships = $this->getPaymentPlanAutorenewableMemberships($paymentPlan['id']); @@ -665,8 +667,8 @@ public function testRenewingUpgradableMembershipWithWillCreateCorrectSubscriptio 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $subscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); @@ -742,8 +744,8 @@ public function testRenewalWithMembershipFeeEqualZeroWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); } @@ -830,8 +832,8 @@ public function testRenewalWithNonRenewableLineOnCurrentPeriodAndNewMembershipFo 'duration_unit' => 'year', ]); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertPaymentPlanStructureIsOk($paymentPlan['id'], [ 'total_amount' => 1200, @@ -901,8 +903,8 @@ public function testRenewalWithMultipleLinesNotRenewingOnCurrentPeriodAndNewMemb 'duration_unit' => 'year', ]); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertPaymentPlanStructureIsOk($paymentPlan['id'], [ 'total_amount' => 480, @@ -992,8 +994,8 @@ public function testRenewalWithMultipleLinesSomeRenewingOnCurrentPeriodAndNewMem 'duration_unit' => 'year', ]); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $this->assertPaymentPlanStructureIsOk($paymentPlan['id'], [ 'total_amount' => 1320, @@ -1167,8 +1169,8 @@ public function testRenewalOfFixedMembershipWillResultInCorrectDates() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $singleInstalmentRenewal = new SingleInstalmentRenewalJob(); - $singleInstalmentRenewal->run(); + $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueRunner(); $contributions = $this->getPaymentPlanContributions($paymentPlan['id']); $this->assertEquals(2, count($contributions)); From cedd08a6093eb34194677524445b34ba74da164b Mon Sep 17 00:00:00 2001 From: Ahed Date: Mon, 15 Feb 2021 21:15:08 +0200 Subject: [PATCH 06/11] MAE-318: Handle edge case when the job executed twice If the job executed during the execution of the queue, there will be repeated tasks in the queue and this commit fixed it and only adds tasks when the queue is empty. --- CRM/MembershipExtras/Job/OfflineAutoRenewal.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php index 1440f2da..a7f20578 100755 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php @@ -8,8 +8,14 @@ class CRM_MembershipExtras_Job_OfflineAutoRenewal { private $queue; + /** + * @var int + */ + private $numberOfQueueItems; + public function __construct() { $this->queue = OfflineAutoRenewalQueue::getQueue(); + $this->numberOfQueueItems = (int) $this->queue->numberOfItems(); } /** @@ -26,6 +32,10 @@ public function run() { } private function addTasksToQueue() { + if ($this->numberOfQueueItems > 0) { + return; + } + $queueBuilders = [ new OfflineMultipleInstalmentPlansQueueBuilder($this->queue), new OfflineSingleInstalmentPlansQueueBuilder($this->queue), From b9eca5731f2fa4c88dc92b28f792fe1225cdbb3a Mon Sep 17 00:00:00 2001 From: Ahed Date: Thu, 18 Feb 2021 11:29:59 +0200 Subject: [PATCH 07/11] MAE-318: Only run the queue if it is not empty --- CRM/MembershipExtras/Job/OfflineAutoRenewal.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php index a7f20578..abae1ae0 100755 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php @@ -43,9 +43,15 @@ private function addTasksToQueue() { foreach ($queueBuilders as $queueBuilder) { $queueBuilder->run(); } + + $this->numberOfQueueItems = (int) $this->queue->numberOfItems(); } private function runQueue() { + if ($this->numberOfQueueItems === 0) { + return; + } + $runner = new CRM_Queue_Runner([ 'title' => ts('Processing membership renewals, this may take a while depending on how many records are processed ..'), 'queue' => $this->queue, From ad16f6822ed558c87a896b3183a07b2df496c96d Mon Sep 17 00:00:00 2001 From: Ahed Date: Wed, 17 Feb 2021 19:30:08 +0200 Subject: [PATCH 08/11] MAE-318: Create OfflineAutoRenewal folders in Builder and Task The created folders will hold the related classes and give a better separation. --- .../Job/OfflineAutoRenewal.php | 8 ++-- .../MultipleInstalmentPlan.php} | 8 ++-- .../PaymentPlan.php} | 2 +- .../SingleInstalmentPlan.php} | 8 ++-- .../RenewMultipleInstalmentPlans.php} | 4 +- .../RenewPaymentPlans.php} | 2 +- .../RenewSingleInstalmentPlans.php} | 4 +- .../MultipleInstalmentPlanTest.php} | 6 +-- .../SingleInstalmentPlanTest.php} | 6 +-- .../RenewMultipleInstalmentPlansTest.php} | 42 ++++++++-------- .../RenewSingleInstalmentPlanTest.php | 48 +++++++++---------- 11 files changed, 69 insertions(+), 69 deletions(-) rename CRM/MembershipExtras/Queue/Builder/{OfflineMultipleInstalmentPlans.php => OfflineAutoRenewal/MultipleInstalmentPlan.php} (85%) rename CRM/MembershipExtras/Queue/Builder/{OfflinePaymentPlans.php => OfflineAutoRenewal/PaymentPlan.php} (95%) rename CRM/MembershipExtras/Queue/Builder/{OfflineSingleInstalmentPlans.php => OfflineAutoRenewal/SingleInstalmentPlan.php} (89%) rename CRM/MembershipExtras/Queue/Task/{OfflineRenewMultipleInstalmentPlan.php => OfflineAutoRenewal/RenewMultipleInstalmentPlans.php} (97%) rename CRM/MembershipExtras/Queue/Task/{OfflineRenewPaymentPlan.php => OfflineAutoRenewal/RenewPaymentPlans.php} (99%) rename CRM/MembershipExtras/Queue/Task/{OfflineRenewSingleInstalmentPlan.php => OfflineAutoRenewal/RenewSingleInstalmentPlans.php} (97%) rename tests/phpunit/CRM/MembershipExtras/Queue/Builder/{OfflineMultipleInstalmentPlansTest.php => OfflineAutoRenewal/MultipleInstalmentPlanTest.php} (90%) rename tests/phpunit/CRM/MembershipExtras/Queue/Builder/{OfflineSingleInstalmentPlansTest.php => OfflineAutoRenewal/SingleInstalmentPlanTest.php} (90%) rename tests/phpunit/CRM/MembershipExtras/Queue/Task/{RenewMultipleInstalmentPlanTest.php => OfflineAutoRenewal/RenewMultipleInstalmentPlansTest.php} (96%) rename tests/phpunit/CRM/MembershipExtras/Queue/Task/{ => OfflineAutoRenewal}/RenewSingleInstalmentPlanTest.php (96%) diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php index abae1ae0..d46552e9 100755 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php @@ -1,7 +1,7 @@ queue), - new OfflineSingleInstalmentPlansQueueBuilder($this->queue), + new OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder($this->queue), + new OfflineAutoRenewalSingleInstalmentPlanQueueBuilder($this->queue), ]; foreach ($queueBuilders as $queueBuilder) { $queueBuilder->run(); diff --git a/CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlans.php b/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/MultipleInstalmentPlan.php similarity index 85% rename from CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlans.php rename to CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/MultipleInstalmentPlan.php index f757fe10..e8da33b6 100644 --- a/CRM/MembershipExtras/Queue/Builder/OfflineMultipleInstalmentPlans.php +++ b/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/MultipleInstalmentPlan.php @@ -1,15 +1,15 @@ getRecurringContributions(); diff --git a/CRM/MembershipExtras/Queue/Builder/OfflinePaymentPlans.php b/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/PaymentPlan.php similarity index 95% rename from CRM/MembershipExtras/Queue/Builder/OfflinePaymentPlans.php rename to CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/PaymentPlan.php index 46561f0c..e3263219 100644 --- a/CRM/MembershipExtras/Queue/Builder/OfflinePaymentPlans.php +++ b/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/PaymentPlan.php @@ -5,7 +5,7 @@ /** * Adds payment plans queue. */ -class CRM_MembershipExtras_Queue_Builder_OfflinePaymentPlans extends BaseQueueBuilder { +class CRM_MembershipExtras_Queue_Builder_OfflineAutoRenewal_PaymentPlan extends BaseQueueBuilder { /** * Maps contribution status names to their corresponding ID's. diff --git a/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlans.php b/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/SingleInstalmentPlan.php similarity index 89% rename from CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlans.php rename to CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/SingleInstalmentPlan.php index 2b84cbdc..d1ce01d3 100644 --- a/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlans.php +++ b/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/SingleInstalmentPlan.php @@ -1,15 +1,15 @@ getRecurringContributions(); diff --git a/CRM/MembershipExtras/Queue/Task/OfflineRenewMultipleInstalmentPlan.php b/CRM/MembershipExtras/Queue/Task/OfflineAutoRenewal/RenewMultipleInstalmentPlans.php similarity index 97% rename from CRM/MembershipExtras/Queue/Task/OfflineRenewMultipleInstalmentPlan.php rename to CRM/MembershipExtras/Queue/Task/OfflineAutoRenewal/RenewMultipleInstalmentPlans.php index de5d3f6f..fdaf23db 100644 --- a/CRM/MembershipExtras/Queue/Task/OfflineRenewMultipleInstalmentPlan.php +++ b/CRM/MembershipExtras/Queue/Task/OfflineAutoRenewal/RenewMultipleInstalmentPlans.php @@ -1,5 +1,5 @@ runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $expectedNumberOfTasks = ceil($NumberOfPaymentPlans / CRM_MembershipExtras_Queue_Builder_Base::RECORDS_LIMIT); $this->assertEquals($expectedNumberOfTasks, $this->getNumberOfTasks()); diff --git a/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlansTest.php b/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/SingleInstalmentPlanTest.php similarity index 90% rename from tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlansTest.php rename to tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/SingleInstalmentPlanTest.php index d3d55940..f9b6ae70 100644 --- a/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineSingleInstalmentPlansTest.php +++ b/tests/phpunit/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/SingleInstalmentPlanTest.php @@ -4,14 +4,14 @@ use CRM_MembershipExtras_Test_Entity_PaymentPlanMembershipOrder as PaymentPlanMembershipOrder; use CRM_MembershipExtras_Test_Fabricator_MembershipType as MembershipTypeFabricator; use CRM_MembershipExtras_Test_Fabricator_PaymentPlanOrder as PaymentPlanOrderFabricator; -use CRM_MembershipExtras_Queue_Builder_OfflineSingleInstalmentPlans as OfflineSingleInstalmentPlansQueueBuilder; +use CRM_MembershipExtras_Queue_Builder_OfflineAutoRenewal_SingleInstalmentPlan as OfflineAutoRenewalSingleInstalmentPlanQueueBuilder; /** * Class CRM_MembershipExtras_Queue_Builder_RenewSingleInstalmentPlanTest * * @group headless */ -class CRM_MembershipExtras_Queue_Builder_SingleInstalmentPlansTest extends QueueTestCase { +class CRM_MembershipExtras_Queue_Builder_OfflineAutoRenewal_SingleInstalmentPlanTest extends QueueTestCase { /** * A rolling membership type that we @@ -83,7 +83,7 @@ public function testBuildQueueWillAddTasksToQueue() { PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); } - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $expectedNumberOfTasks = ceil($NumberOfPaymentPlans / CRM_MembershipExtras_Queue_Builder_Base::RECORDS_LIMIT); $this->assertEquals($expectedNumberOfTasks, $this->getNumberOfTasks()); diff --git a/tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewMultipleInstalmentPlanTest.php b/tests/phpunit/CRM/MembershipExtras/Queue/Task/OfflineAutoRenewal/RenewMultipleInstalmentPlansTest.php similarity index 96% rename from tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewMultipleInstalmentPlanTest.php rename to tests/phpunit/CRM/MembershipExtras/Queue/Task/OfflineAutoRenewal/RenewMultipleInstalmentPlansTest.php index b7249ea2..ccad5c27 100644 --- a/tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewMultipleInstalmentPlanTest.php +++ b/tests/phpunit/CRM/MembershipExtras/Queue/Task/OfflineAutoRenewal/RenewMultipleInstalmentPlansTest.php @@ -5,7 +5,7 @@ use CRM_MembershipExtras_Test_Fabricator_MembershipType as MembershipTypeFabricator; use CRM_MembershipExtras_Test_Fabricator_PaymentPlanOrder as PaymentPlanOrderFabricator; use CRM_MembershipExtras_Test_Fabricator_AutoMembershipUpgradeRule as AutoMembershipUpgradeRuleFabricator; -use CRM_MembershipExtras_Queue_Builder_OfflineMultipleInstalmentPlans as OfflineMultipleInstalmentPlansQueueBuilder; +use CRM_MembershipExtras_Queue_Builder_OfflineAutoRenewal_MultipleInstalmentPlan as OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder; use CRM_MembershipExtras_Test_Fabricator_LineItem as LineItemFabricator; use CRM_MembershipExtras_Test_Fabricator_RecurringLineItem as RecurringLineItemFabricator; @@ -14,7 +14,7 @@ * * @group headless */ -class CRM_MembershipExtras_Queue_Task_RenewMultipleInstalmentPlanTest extends QueueTestCase { +class CRM_MembershipExtras_Queue_Task_OfflineAutoRenewal_RenewMultipleInstalmentPlansTest extends QueueTestCase { /** * A rolling membership type that we @@ -83,7 +83,7 @@ public function testRenewalWithMembershipEndDateLessThanTodayDateWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); @@ -107,7 +107,7 @@ public function testRenewalWithMembershipEndDateEqualTodayDateWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year')); @@ -131,7 +131,7 @@ public function testRenewalWithMembershipEndDateLargerThanTodayDateWillNotRenew( ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +1 day')); @@ -163,7 +163,7 @@ public function testRenewalWithNonOfflinePaymentProcessorPaymentPlanWillNotRenew ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); @@ -187,7 +187,7 @@ public function testRenewalWithNonCompletedInstalmentWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); @@ -211,7 +211,7 @@ public function testRenewalWithCancelledPaymentPlanWillNotRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); @@ -239,7 +239,7 @@ public function testRenewalWithMembershipEndDateLargerThanDateToRenewInAdvanceWi ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +1 day')); @@ -267,7 +267,7 @@ public function testRenewalWithMembershipEndDateLessThanDateToRenewInAdvanceWill ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +14 day')); @@ -295,7 +295,7 @@ public function testRenewalWithUpdateStartDateOnRenewalSettingOffWillNotUpdateMe ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $membership = civicrm_api3('Membership', 'get', [ @@ -327,7 +327,7 @@ public function testRenewalWithUpdateStartDateOnRenewalSettingOnWillUpdateMember ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $membership = civicrm_api3('Membership', 'get', [ @@ -356,7 +356,7 @@ public function testNewCopyOfLineItemsWillBeCreatedAfterRenewalInsteadOfReusingT ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $membershipId = (int) civicrm_api3('Membership', 'getvalue', [ @@ -393,7 +393,7 @@ public function testRenewingMembershipWithEndDateLessThanTodayDateWillCreateCorr ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $currentPeriodSubscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); @@ -462,7 +462,7 @@ public function testRenewingMembershipWillCreateCorrectMembershipPaymentRecords( ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $membershipId = (int) civicrm_api3('Membership', 'getvalue', [ @@ -512,7 +512,7 @@ public function testRenewingUpgradableMembershipWithWillCreateUpgradedMembership 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $currentMembership = civicrm_api3('Membership', 'get', [ @@ -579,7 +579,7 @@ public function testRenewingUpgradableMembershipWillCreateCorrectMembershipPayme 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $nextPeriodId = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); @@ -663,7 +663,7 @@ public function testRenewingUpgradableMembershipWithWillCreateCorrectSubscriptio 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $currentPeriodSubscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); @@ -800,7 +800,7 @@ public function testRenewalWithNonRenewableLineOnCurrentPeriodAndNewMembershipFo 'duration_unit' => 'year', ]); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $nextPeriodID = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); @@ -905,7 +905,7 @@ public function testRenewalWithMultipleLinesNotRenewingOnCurrentPeriodAndNewMemb 'duration_unit' => 'year', ]); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $nextPeriodID = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); @@ -999,7 +999,7 @@ public function testRenewalWithMultipleLinesSomeRenewingOnCurrentPeriodAndNewMem 'duration_unit' => 'year', ]); - $this->runQueueBuilder(OfflineMultipleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $nextPeriodID = $this->getTheNewRecurContributionIdFromCurrentOne($paymentPlan['id']); diff --git a/tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewSingleInstalmentPlanTest.php b/tests/phpunit/CRM/MembershipExtras/Queue/Task/OfflineAutoRenewal/RenewSingleInstalmentPlanTest.php similarity index 96% rename from tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewSingleInstalmentPlanTest.php rename to tests/phpunit/CRM/MembershipExtras/Queue/Task/OfflineAutoRenewal/RenewSingleInstalmentPlanTest.php index 1f60aed4..8603489a 100644 --- a/tests/phpunit/CRM/MembershipExtras/Queue/Task/RenewSingleInstalmentPlanTest.php +++ b/tests/phpunit/CRM/MembershipExtras/Queue/Task/OfflineAutoRenewal/RenewSingleInstalmentPlanTest.php @@ -5,7 +5,7 @@ use CRM_MembershipExtras_Test_Fabricator_MembershipType as MembershipTypeFabricator; use CRM_MembershipExtras_Test_Fabricator_PaymentPlanOrder as PaymentPlanOrderFabricator; use CRM_MembershipExtras_Test_Fabricator_AutoMembershipUpgradeRule as AutoMembershipUpgradeRuleFabricator; -use CRM_MembershipExtras_Queue_Builder_OfflineSingleInstalmentPlans as OfflineSingleInstalmentPlansQueueBuilder; +use CRM_MembershipExtras_Queue_Builder_OfflineAutoRenewal_SingleInstalmentPlan as OfflineAutoRenewalSingleInstalmentPlanQueueBuilder; use CRM_MembershipExtras_Test_Fabricator_LineItem as LineItemFabricator; use CRM_MembershipExtras_Test_Fabricator_RecurringLineItem as RecurringLineItemFabricator; @@ -14,7 +14,7 @@ * * @group headless */ -class CRM_MembershipExtras_Queue_Task_RenewSingleInstalmentPlanTest extends QueueTestCase { +class CRM_MembershipExtras_Queue_Task_OfflineAutoRenewal_RenewSingleInstalmentPlansTest extends QueueTestCase { /** * A rolling membership type that we @@ -83,7 +83,7 @@ public function testRenewalWithMembershipEndDateLessThanTodayDateWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); @@ -107,7 +107,7 @@ public function testRenewalWithMembershipEndDateEqualTodayDateWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year')); @@ -131,7 +131,7 @@ public function testRenewalWithMembershipEndDateLargerThanTodayDateWillNotRenew( ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +1 day')); @@ -163,7 +163,7 @@ public function testRenewalWithNonOfflinePaymentProcessorPaymentPlanWillNotRenew ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); @@ -187,7 +187,7 @@ public function testRenewalWithNonCompletedInstalmentWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); @@ -211,7 +211,7 @@ public function testRenewalWithCancelledPaymentPlanWillNotRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); @@ -239,7 +239,7 @@ public function testRenewalWithMembershipEndDateLargerThanDateToRenewInAdvanceWi ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +1 day')); @@ -267,7 +267,7 @@ public function testRenewalWithMembershipEndDateLessThanDateToRenewInAdvanceWill ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertFalse($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year +14 day')); @@ -295,7 +295,7 @@ public function testRenewalWithUpdateStartDateOnRenewalSettingOffWillNotUpdateMe ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $membership = $this->getPaymentPlanAutorenewableMemberships($paymentPlan['id'])[0]; @@ -324,7 +324,7 @@ public function testRenewalWithUpdateStartDateOnRenewalSettingOnWillUpdateMember ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $membership = $this->getPaymentPlanAutorenewableMemberships($paymentPlan['id'])[0]; @@ -350,7 +350,7 @@ public function testNewCopyOfLineItemsWillBeCreatedAfterRenewalInsteadOfReusingT ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $membershipId = (int) civicrm_api3('Membership', 'getvalue', [ @@ -387,7 +387,7 @@ public function testRenewingMembershipWithEndDateLessThanTodayDateWillCreateCorr ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $subscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); @@ -449,7 +449,7 @@ public function testRenewingMembershipWithEndDateLargerThanDateToRenewInAdvanceW ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $subscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); @@ -507,7 +507,7 @@ public function testRenewingMembershipWillCreateCorrectMembershipPaymentRecords( ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $membershipId = (int) civicrm_api3('Membership', 'getvalue', [ @@ -556,7 +556,7 @@ public function testRenewingUpgradableMembershipWithWillCreateUpgradedMembership 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $createdMemberships = $this->getPaymentPlanAutorenewableMemberships($paymentPlan['id']); @@ -614,7 +614,7 @@ public function testRenewingUpgradableMembershipWillCreateCorrectMembershipPayme 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $isAllMembershipPaymentRecordsCreated = TRUE; @@ -667,7 +667,7 @@ public function testRenewingUpgradableMembershipWithWillCreateCorrectSubscriptio 'period_length_unit' => CRM_MembershipExtras_SelectValues_AutoMembershipUpgradeRules_PeriodUnit::YEARS, ]); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $subscriptionLineItems = $this->getSubscriptionLineItems($paymentPlan['id']); @@ -744,7 +744,7 @@ public function testRenewalWithMembershipFeeEqualZeroWillRenew() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertTrue($this->isPaymentPlanMembershipRenewed($paymentPlan['id'], '+1 year -1 month -1 day')); @@ -832,7 +832,7 @@ public function testRenewalWithNonRenewableLineOnCurrentPeriodAndNewMembershipFo 'duration_unit' => 'year', ]); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertPaymentPlanStructureIsOk($paymentPlan['id'], [ @@ -903,7 +903,7 @@ public function testRenewalWithMultipleLinesNotRenewingOnCurrentPeriodAndNewMemb 'duration_unit' => 'year', ]); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertPaymentPlanStructureIsOk($paymentPlan['id'], [ @@ -994,7 +994,7 @@ public function testRenewalWithMultipleLinesSomeRenewingOnCurrentPeriodAndNewMem 'duration_unit' => 'year', ]); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $this->assertPaymentPlanStructureIsOk($paymentPlan['id'], [ @@ -1169,7 +1169,7 @@ public function testRenewalOfFixedMembershipWillResultInCorrectDates() { ]; $paymentPlan = PaymentPlanOrderFabricator::fabricate($paymentPlanMembershipOrder); - $this->runQueueBuilder(OfflineSingleInstalmentPlansQueueBuilder::class); + $this->runQueueBuilder(OfflineAutoRenewalSingleInstalmentPlanQueueBuilder::class); $this->runQueueRunner(); $contributions = $this->getPaymentPlanContributions($paymentPlan['id']); From c10abccdd0faf379cbda53a46866ab30867d1c86 Mon Sep 17 00:00:00 2001 From: Ahed Date: Wed, 17 Feb 2021 19:38:16 +0200 Subject: [PATCH 09/11] MAE-318: Change OfflinePaymentPlanBuilder to a trait --- .../Builder/OfflineAutoRenewal/MultipleInstalmentPlan.php | 6 ++++-- .../{PaymentPlan.php => PaymentPlanTrait.php} | 6 ++---- .../Builder/OfflineAutoRenewal/SingleInstalmentPlan.php | 6 ++++-- 3 files changed, 10 insertions(+), 8 deletions(-) rename CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/{PaymentPlan.php => PaymentPlanTrait.php} (90%) diff --git a/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/MultipleInstalmentPlan.php b/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/MultipleInstalmentPlan.php index e8da33b6..c5cd59e1 100644 --- a/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/MultipleInstalmentPlan.php +++ b/CRM/MembershipExtras/Queue/Builder/OfflineAutoRenewal/MultipleInstalmentPlan.php @@ -1,13 +1,15 @@ Date: Wed, 24 Feb 2021 18:51:40 +0200 Subject: [PATCH 10/11] MAE-318: Create JobLog on completion --- .../Job/OfflineAutoRenewal.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php index d46552e9..9831b392 100755 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php @@ -70,7 +70,27 @@ private function runQueue() { } } + /** + * @param \CRM_Queue_TaskContext $ctx + * + * @throws \CiviCRM_API3_Exception + */ public static function onEnd(CRM_Queue_TaskContext $ctx) { + $job = civicrm_api3('Job', 'getSingle', [ + 'name' => 'Renew offline auto-renewal memberships', + ]); + + $result = civicrm_api3('JobLog', 'create', [ + 'domain_id' => $job['domain_id'], + 'job_id' => $job['id'], + 'name' => $job['name'], + 'command' => ts("Entity:") . " " . $job['api_entity'] . " " . ts("Action:") . " " . $job['api_action'], + 'description' => 'Finished execution of Renew offline auto-renewal memberships with result: Success', + 'data' => " +Full message: +Finished execution of Renew offline auto-renewal memberships with result: Success ", + ]); + $message = ts('Membership Renewals Processing Completed'); CRM_Core_Session::setStatus($message, '', 'success'); } From b3d079268c135fcecb52ef4332ccd1abcb7d4778 Mon Sep 17 00:00:00 2001 From: Ahed Date: Wed, 24 Feb 2021 18:54:10 +0200 Subject: [PATCH 11/11] MAE-318: Add PostRunAllTask as the last task --- .../Job/OfflineAutoRenewal.php | 22 +++++++++++++++++++ .../Queue/Task/PostRunAll.php | 14 ++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 CRM/MembershipExtras/Queue/Task/PostRunAll.php diff --git a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php index 9831b392..23fafe47 100755 --- a/CRM/MembershipExtras/Job/OfflineAutoRenewal.php +++ b/CRM/MembershipExtras/Job/OfflineAutoRenewal.php @@ -2,6 +2,7 @@ use CRM_MembershipExtras_Queue_Builder_OfflineAutoRenewal_MultipleInstalmentPlan as OfflineAutoRenewalMultipleInstalmentPlanQueueBuilder; use CRM_MembershipExtras_Queue_Builder_OfflineAutoRenewal_SingleInstalmentPlan as OfflineAutoRenewalSingleInstalmentPlanQueueBuilder; +use CRM_MembershipExtras_Queue_Task_PostRunAll as PostRunAllTask; use CRM_MembershipExtras_Queue_OfflineAutoRenewal as OfflineAutoRenewalQueue; class CRM_MembershipExtras_Job_OfflineAutoRenewal { @@ -52,6 +53,8 @@ private function runQueue() { return; } + $this->addPostRunAllTask(); + $runner = new CRM_Queue_Runner([ 'title' => ts('Processing membership renewals, this may take a while depending on how many records are processed ..'), 'queue' => $this->queue, @@ -95,4 +98,23 @@ public static function onEnd(CRM_Queue_TaskContext $ctx) { CRM_Core_Session::setStatus($message, '', 'success'); } + /** + * PostRunAllTask will run as the last task in the queue. Leave + * CRM_MembershipExtras_Queue_Task_PostRunAll::process empty if there is no + * need for it because queue web-runner will show 'Done' message instead of + * the last task title. + */ + protected function addPostRunAllTask() { + $taskTitle = 'Done'; + $records = [1]; + + $task = new CRM_Queue_Task( + [PostRunAllTask::class, 'run'], + [$records], + $taskTitle + ); + + $this->queue->createItem($task); + } + } diff --git a/CRM/MembershipExtras/Queue/Task/PostRunAll.php b/CRM/MembershipExtras/Queue/Task/PostRunAll.php new file mode 100644 index 00000000..844dfabd --- /dev/null +++ b/CRM/MembershipExtras/Queue/Task/PostRunAll.php @@ -0,0 +1,14 @@ +