From ac4d4d8cb747d0556a4563b0ead885ed117eb7d4 Mon Sep 17 00:00:00 2001 From: Matthew Wire Date: Wed, 15 Jan 2020 14:41:41 +0000 Subject: [PATCH] Add parameters to process_membership job --- CRM/Member/BAO/Membership.php | 74 +++++++++++++++++++++++------------ api/v3/Job.php | 22 ++++++++++- 2 files changed, 70 insertions(+), 26 deletions(-) diff --git a/CRM/Member/BAO/Membership.php b/CRM/Member/BAO/Membership.php index c927be1aff..6d351d4b67 100644 --- a/CRM/Member/BAO/Membership.php +++ b/CRM/Member/BAO/Membership.php @@ -2164,21 +2164,56 @@ INNER JOIN civicrm_contact contact ON ( contact.id = membership.contact_id AND * IMPORTANT: * Sending renewal reminders has been migrated from this job to the Scheduled Reminders function as of 4.3. * + * @param array $params + * only_active_membership_types, exclude_test_memberships, exclude_membership_status_ids + * * @return array * * @throws \CiviCRM_API3_Exception * @throws \CRM_Core_Exception */ - public static function updateAllMembershipStatus() { - // Tests for this function are in api_v3_JobTest. Please add tests for all updates. - - $updateCount = $processCount = self::updateDeceasedMembersStatuses(); - + public static function updateAllMembershipStatus($params = []) { + if (empty($params['only_active_membership_types'])) { + $params['only_active_membership_types'] = TRUE; + } + if (empty($params['exclude_test_memberships'])) { + $params['exclude_test_memberships'] = TRUE; + } // We want all of the statuses as id => name, even the disabled ones (cf. // CRM-15475), to identify which are Pending, Deceased, Cancelled, and // Expired. $allStatus = CRM_Member_BAO_Membership::buildOptions('status_id', 'validate'); - $allTypes = CRM_Member_PseudoConstant::membershipType(); + if (empty($params['exclude_membership_status_ids'])) { + $params['exclude_membership_status_ids'] = [ + array_search('Pending', $allStatus), + array_search('Cancelled', $allStatus), + array_search('Expired', $allStatus) ?: 0, + array_search('Deceased', $allStatus), + ]; + } + // Deceased is *always* excluded because it is has very specific processing below. + elseif (!in_array(array_search('Deceased', $allStatus), $params['exclude_membership_status_ids'])) { + $params['exclude_membership_status_ids'][] = array_search('Deceased', $allStatus); + } + + for ($index = 0; $index < count($params['exclude_membership_status_ids']); $index++) { + $queryParams[$index] = [$params['exclude_membership_status_ids'][$index], 'Integer']; + } + $membershipStatusClause = 'civicrm_membership.status_id NOT IN (%' . implode(', %', array_keys($queryParams)) . ')'; + + // Tests for this function are in api_v3_JobTest. Please add tests for all updates. + + $updateCount = $processCount = self::updateDeceasedMembersStatuses(); + + $whereClauses[] = 'civicrm_contact.is_deceased = 0'; + if ($params['exclude_test_memberships']) { + $whereClauses[] = 'civicrm_membership.is_test = 0'; + } + $whereClause = implode(' AND ', $whereClauses); + $activeMembershipClause = ''; + if ($params['only_active_membership_types']) { + $activeMembershipClause = ' AND civicrm_membership_type.is_active = 1'; + } // This query retrieves ALL memberships of active types. $baseQuery = " @@ -2197,15 +2232,8 @@ SELECT civicrm_membership.id as membership_id, FROM civicrm_membership INNER JOIN civicrm_contact ON ( civicrm_membership.contact_id = civicrm_contact.id ) INNER JOIN civicrm_membership_type ON - (civicrm_membership.membership_type_id = civicrm_membership_type.id AND civicrm_membership_type.is_active = 1) -WHERE civicrm_membership.is_test = 0 - AND civicrm_contact.is_deceased = 0 "; - - $deceaseStatusId = array_search('Deceased', $allStatus); - $pendingStatusId = array_search('Pending', $allStatus); - $cancelledStatusId = array_search('Cancelled', $allStatus); - // Expired is not reserved so might not exist. A value of `0` won't break. - $expiredStatusId = array_search('Expired', $allStatus) ?: 0; + (civicrm_membership.membership_type_id = civicrm_membership_type.id {$activeMembershipClause}) +WHERE {$whereClause}"; $query = $baseQuery . " AND civicrm_membership.is_override IS NOT NULL AND civicrm_membership.status_override_end_date IS NOT NULL"; $dao1 = CRM_Core_DAO::executeQuery($query); @@ -2214,18 +2242,14 @@ WHERE civicrm_membership.is_test = 0 } $query = $baseQuery . " AND (civicrm_membership.is_override = 0 OR civicrm_membership.is_override IS NULL) - AND civicrm_membership.status_id NOT IN (%1, %2, %3, %4) + AND {$membershipStatusClause} AND civicrm_membership.owner_membership_id IS NULL "; - $params = [ - 1 => [$pendingStatusId, 'Integer'], - 2 => [$cancelledStatusId, 'Integer'], - 3 => [$expiredStatusId, 'Integer'], - 4 => [$deceaseStatusId, 'Integer'], - ]; - $dao2 = CRM_Core_DAO::executeQuery($query, $params); + + $allMembershipTypes = CRM_Member_BAO_MembershipType::getAllMembershipTypes(); + + $dao2 = CRM_Core_DAO::executeQuery($query, $queryParams); while ($dao2->fetch()) { - // echo "."; $processCount++; // Put common parameters into array for easy access @@ -2234,7 +2258,7 @@ WHERE civicrm_membership.is_test = 0 'status_id' => $dao2->status_id, 'contact_id' => $dao2->contact_id, 'membership_type_id' => $dao2->membership_type_id, - 'membership_type' => $allTypes[$dao2->membership_type_id], + 'membership_type' => $allMembershipTypes[$dao2->membership_type_id]['name'], 'join_date' => $dao2->join_date, 'start_date' => $dao2->start_date, 'end_date' => $dao2->end_date, diff --git a/api/v3/Job.php b/api/v3/Job.php index f34d7d48a2..47f1eeca5f 100644 --- a/api/v3/Job.php +++ b/api/v3/Job.php @@ -466,7 +466,14 @@ function civicrm_api3_job_process_membership($params) { return civicrm_api3_create_error('Could not acquire lock, another Membership Processing process is running'); } - $result = CRM_Member_BAO_Membership::updateAllMembershipStatus(); + // We need to pass this through as a simple array of membership status IDs as values. + if (!empty($params['exclude_membership_status_ids'])) { + is_array($params['exclude_membership_status_ids']) ?: $params['exclude_membership_status_ids'] = [$params['exclude_membership_status_ids']]; + } + if (!empty($params['exclude_membership_status_ids']['IN'])) { + $params['exclude_membership_status_ids'] = $params['exclude_membership_status_ids']['IN']; + } + $result = CRM_Member_BAO_Membership::updateAllMembershipStatus($params); $lock->release(); if ($result['is_error'] == 0) { @@ -477,6 +484,19 @@ function civicrm_api3_job_process_membership($params) { } } +function _civicrm_api3_job_process_membership_spec(&$params) { + $params['exclude_test_memberships']['api.default'] = TRUE; + $params['exclude_test_memberships']['title'] = 'Exclude test memberships'; + $params['exclude_test_memberships']['description'] = 'Exclude test memberships from calculations (default = TRUE)'; + $params['exclude_test_memberships']['type'] = CRM_Utils_Type::T_BOOLEAN; + $params['only_active_membership_types']['api.default'] = TRUE; + $params['only_active_membership_types']['title'] = 'Exclude disabled membership types'; + $params['only_active_membership_types']['description'] = 'Exclude disabled membership types from calculations (default = TRUE)'; + $params['only_active_membership_types']['type'] = CRM_Utils_Type::T_BOOLEAN; + $params['exclude_membership_status_ids']['title'] = 'Exclude membership status IDs from calculations'; + $params['exclude_membership_status_ids']['description'] = 'Default: Exclude Pending, Cancelled, Expired. Deceased will always be excluded'; +} + /** * This api checks and updates the status of all survey respondents. * -- 2.25.1