From cc94960644392afecf2523025347bfb6a1dfcc50 Mon Sep 17 00:00:00 2001 From: "deb.monish" Date: Mon, 5 Feb 2018 19:15:06 +0530 Subject: [PATCH] CRM-21675: scheduled reminders: limit to group doesn't support smart groups --- CRM/Contact/BAO/Group.php | 2 +- Civi/ActionSchedule/RecipientBuilder.php | 33 ++++--- .../CRM/Core/BAO/ActionScheduleTest.php | 88 +++++++++++++++++++ 3 files changed, 112 insertions(+), 11 deletions(-) diff --git a/CRM/Contact/BAO/Group.php b/CRM/Contact/BAO/Group.php index 05e78491fc..81b3797f83 100644 --- a/CRM/Contact/BAO/Group.php +++ b/CRM/Contact/BAO/Group.php @@ -1334,7 +1334,7 @@ WHERE {$whereClause}"; public static function getChildGroupIds($regularGroupIDs) { $childGroupIDs = array(); - foreach ($regularGroupIDs as $regularGroupID) { + foreach ((array) $regularGroupIDs as $regularGroupID) { // temporary store the child group ID(s) of regular group identified by $id, // later merge with main child group array $tempChildGroupIDs = array(); diff --git a/Civi/ActionSchedule/RecipientBuilder.php b/Civi/ActionSchedule/RecipientBuilder.php index 87b942dc5a..45e3efc0c9 100644 --- a/Civi/ActionSchedule/RecipientBuilder.php +++ b/Civi/ActionSchedule/RecipientBuilder.php @@ -419,18 +419,31 @@ class RecipientBuilder { $actionSchedule = $this->actionSchedule; if ($actionSchedule->group_id) { - if ($this->isSmartGroup($actionSchedule->group_id)) { - // Check that the group is in place in the cache and up to date - \CRM_Contact_BAO_GroupContactCache::check($actionSchedule->group_id); - return \CRM_Utils_SQL_Select::fragment() - ->join('grp', "INNER JOIN civicrm_group_contact_cache grp ON {$contactIdField} = grp.contact_id") - ->where(" grp.group_id IN ({$actionSchedule->group_id})"); + $regularGroupIDs = $smartGroupIDs = $groupWhereCLause = array(); + $query = \CRM_Utils_SQL_Select::fragment(); + + // get child group IDs if any + $childGroupIDs = \CRM_Contact_BAO_Group::getChildGroupIds($actionSchedule->group_id); + foreach (array_merge(array($actionSchedule->group_id), $childGroupIDs) as $groupID) { + if ($this->isSmartGroup($groupID)) { + // Check that the group is in place in the cache and up to date + \CRM_Contact_BAO_GroupContactCache::check($groupID); + $smartGroupIDs[] = $groupID; + } + else { + $regularGroupIDs[] = $groupID; + } } - else { - return \CRM_Utils_SQL_Select::fragment() - ->join('grp', " INNER JOIN civicrm_group_contact grp ON {$contactIdField} = grp.contact_id AND grp.status = 'Added'") - ->where(" grp.group_id IN ({$actionSchedule->group_id})"); + + if (!empty($smartGroupIDs)) { + $query->join('sg', "LEFT JOIN civicrm_group_contact_cache sg ON {$contactIdField} = sg.contact_id"); + $groupWhereCLause[] = " sg.group_id IN ( " . implode(', ', $smartGroupIDs) . " ) "; + } + if (!empty($regularGroupIDs)) { + $query->join('rg', " LEFT JOIN civicrm_group_contact rg ON {$contactIdField} = rg.contact_id AND rg.status = 'Added'"); + $groupWhereCLause[] = " rg.group_id IN ( " . implode(', ', $regularGroupIDs) . " ) "; } + return $query->where(implode(" OR ", $groupWhereCLause)); } elseif (!empty($actionSchedule->recipient_manual)) { $rList = \CRM_Utils_Type::escape($actionSchedule->recipient_manual, 'String'); diff --git a/tests/phpunit/CRM/Core/BAO/ActionScheduleTest.php b/tests/phpunit/CRM/Core/BAO/ActionScheduleTest.php index 65d124f7aa..741cf7c16e 100644 --- a/tests/phpunit/CRM/Core/BAO/ActionScheduleTest.php +++ b/tests/phpunit/CRM/Core/BAO/ActionScheduleTest.php @@ -1001,6 +1001,94 @@ class CRM_Core_BAO_ActionScheduleTest extends CiviUnitTestCase { )); } + + /** + * CRM-21675: Support parent and smart group in 'Limit to' field + */ + public function testScheduleReminderWithParentGroup() { + // Contact A with birth-date at '07-07-2005' and gender - Male, later got added in smart group + $contactID1 = $this->individualCreate(array('birth_date' => '20050707', 'gender_id' => 1, 'email' => 'abc@test.com')); + // Contact B with birth-date at '07-07-2005', later got added in regular group + $contactID2 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'def@test.com'), 1); + // Contact C with birth-date at '07-07-2005', but not included in any group + $contactID3 = $this->individualCreate(array('birth_date' => '20050707', 'email' => 'ghi@test.com'), 2); + + // create regular group and add Contact B to it + $groupID = $this->groupCreate(); + $this->callAPISuccess('GroupContact', 'Create', array( + 'group_id' => $groupID, + 'contact_id' => $contactID2, + )); + + // create smart group which will contain all Male contacts + $smartGroupParams = array('formValues' => array('gender_id' => 1)); + $smartGroupID = $this->smartGroupCreate( + $smartGroupParams, + array( + 'name' => 'new_smart_group', + 'title' => 'New Smart Group', + 'parents' => array($groupID => 1), + ) + ); + + $actionScheduleParams = array( + 'name' => 'sched_contact_bday_yesterday', + 'title' => 'sched_contact_bday_yesterday', + 'absolute_date' => '', + 'body_html' => '

you look like you were born yesterday!

', + 'body_text' => 'you look like you were born yesterday!', + 'end_action' => '', + 'end_date' => '', + 'end_frequency_interval' => '', + 'end_frequency_unit' => '', + 'entity_status' => 1, + 'entity_value' => 'birth_date', + 'limit_to' => 1, + 'group_id' => $groupID, + 'is_active' => 1, + 'is_repeat' => '0', + 'mapping_id' => 6, + 'msg_template_id' => '', + 'recipient' => '2', + 'recipient_listing' => '', + 'recipient_manual' => '', + 'record_activity' => 1, + 'repetition_frequency_interval' => '', + 'repetition_frequency_unit' => '', + 'start_action_condition' => 'after', + 'start_action_date' => 'date_field', + 'start_action_offset' => '1', + 'start_action_unit' => 'day', + 'subject' => 'subject sched_contact_bday_yesterday', + ); + + // Create schedule reminder where parent group ($groupID) is selectd to limit recipients, + // which contain a individual contact - $contactID2 and is parent to smart group. + $actionScheduleDao = CRM_Core_BAO_ActionSchedule::add($actionScheduleParams); + $this->assertTrue(is_numeric($actionScheduleDao->id)); + $this->assertCronRuns(array( + array( + // On the birthday, no email. + 'time' => '2005-07-07 01:00:00', + 'recipients' => array(), + ), + array( + // The next day, send an email. + 'time' => '2005-07-08 20:00:00', + 'recipients' => array( + array( + 'def@test.com', + ), + array( + 'abc@test.com', + ), + ), + ), + )); + $this->groupDelete($smartGroupID); + $this->groupDelete($groupID); + } + /** * Test end date email sent. * -- 2.25.1