From b0f2e06f68c595e19e7128a78a9d0ea6f2331e5b Mon Sep 17 00:00:00 2001 From: Rupal Javiya Date: Mon, 3 Jul 2017 01:35:58 +0530 Subject: [PATCH 1/3] CRM-20787: CIVICRM-152 For a repeating Event series. If change the Price Set for a paid Event then this Price Set selection is not applied to all Events in the series even when apply to Every Event is selected - Added Code for apply same priceset for paid series events --- CRM/Core/BAO/RecurringEntity.php | 5 +++++ CRM/Core/Page/AJAX/RecurringEntity.php | 19 +++++++++++++++++++ CRM/Price/BAO/PriceSet.php | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/CRM/Core/BAO/RecurringEntity.php b/CRM/Core/BAO/RecurringEntity.php index ebd496c8081b..2e4dd2471cc7 100644 --- a/CRM/Core/BAO/RecurringEntity.php +++ b/CRM/Core/BAO/RecurringEntity.php @@ -126,6 +126,11 @@ class CRM_Core_BAO_RecurringEntity extends CRM_Core_DAO_RecurringEntity { ), ); + //Define global CLASS CONSTANTS for recurring entity mode types + const MODE_THIS_ENTITY_ONLY = 1; + const MODE_NEXT_ALL_ENTITY = 2; + const MODE_ALL_ENTITY_IN_SERIES = 3; + /** * Getter for status. * diff --git a/CRM/Core/Page/AJAX/RecurringEntity.php b/CRM/Core/Page/AJAX/RecurringEntity.php index 7265eeda26c6..fb5479289747 100644 --- a/CRM/Core/Page/AJAX/RecurringEntity.php +++ b/CRM/Core/Page/AJAX/RecurringEntity.php @@ -37,6 +37,25 @@ public static function updateMode() { if ($dao->find(TRUE)) { $dao->mode = $mode; $dao->save(); + + //CRM-20787 Fix + //I am not sure about other fields, if mode = 3 apply for an event then other fields + //should be save for all other series events or not so applying for price set only for now here. + if (CRM_Core_BAO_RecurringEntity::MODE_ALL_ENTITY_IN_SERIES === $mode) { + //Step-1: Get Price set for parent event + $currentEventPriceSet = CRM_Price_BAO_PriceSet::getPriceSetOfEntity($entityTable, $entityId); + + //Step-2: Get all events of series + $seriesEventRecords = CRM_Core_BAO_RecurringEntity::getEntitiesFor($entityId, $entityTable); + foreach($seriesEventRecords as $event) { + //Step-3: Save price set in other series events + if (CRM_Price_BAO_PriceSet::removeFrom($event['table'], $event['id'])) { //Remove existing priceset + CRM_Core_BAO_Discount::del($event['id'], $event['table']); + CRM_Price_BAO_PriceSet::addTo($event['table'], $event['id'], $currentEventPriceSet['price_set_id']); //Add new price set + } + } + } + //CRM-20787 - Fix end $finalResult['status'] = 'Done'; } else { diff --git a/CRM/Price/BAO/PriceSet.php b/CRM/Price/BAO/PriceSet.php index e1dabf52027e..2bb62c933416 100644 --- a/CRM/Price/BAO/PriceSet.php +++ b/CRM/Price/BAO/PriceSet.php @@ -273,6 +273,25 @@ public static function addTo($entityTable, $entityId, $priceSetId) { return $dao->save(); } + /** + * Get price set for the given entity and id. + * + * @param string $entityTable + * @param int $entityId + * + * @return mixed + */ + public static function getPriceSetOfEntity($entityTable, $entityId) { + $dao = new CRM_Price_DAO_PriceSetEntity(); + $dao->entity_id = $entityId; + $dao->entity_table = $entityTable; + if ($dao->find(TRUE)) { + $entities['table'] = $dao->entity_table; + $entities['id'] = $dao->entity_id; + $entities['price_set_id'] = $dao->price_set_id; + } + return $entities; + } /** * Delete price set for the given entity and id. * From a1bfea17587a462072f3dcfb37888afce7f93fc8 Mon Sep 17 00:00:00 2001 From: Alok Patel Date: Wed, 18 Oct 2017 14:48:49 +0530 Subject: [PATCH 2/3] CRM-20787: Passing price set value in AJAX call to modify the price set of repeating events. --- CRM/Core/Page/AJAX/RecurringEntity.php | 21 +++++++++---------- CRM/Price/BAO/PriceSet.php | 19 ----------------- .../Form/ManageEvent/ConfirmRepeatMode.tpl | 5 +++-- 3 files changed, 13 insertions(+), 32 deletions(-) diff --git a/CRM/Core/Page/AJAX/RecurringEntity.php b/CRM/Core/Page/AJAX/RecurringEntity.php index fb5479289747..9c1f3e9f898a 100644 --- a/CRM/Core/Page/AJAX/RecurringEntity.php +++ b/CRM/Core/Page/AJAX/RecurringEntity.php @@ -14,11 +14,12 @@ class CRM_Core_Page_AJAX_RecurringEntity { public static function updateMode() { $finalResult = array(); - if (CRM_Utils_Array::value('mode', $_REQUEST) && CRM_Utils_Array::value('entityId', $_REQUEST) && CRM_Utils_Array::value('entityTable', $_REQUEST)) { + if (CRM_Utils_Array::value('mode', $_REQUEST) && CRM_Utils_Array::value('entityId', $_REQUEST) && CRM_Utils_Array::value('entityTable', $_REQUEST) && CRM_Utils_Array::value('priceSet', $_REQUEST)) { $mode = CRM_Utils_Type::escape($_REQUEST['mode'], 'Integer'); $entityId = CRM_Utils_Type::escape($_REQUEST['entityId'], 'Integer'); $entityTable = CRM_Utils_Type::escape($_REQUEST['entityTable'], 'String'); + $priceSet = CRM_Utils_Type::escape($_REQUEST['priceSet'], 'String'); if (!empty($_REQUEST['linkedEntityTable'])) { $result = CRM_Core_BAO_RecurringEntity::updateModeLinkedEntity($entityId, $_REQUEST['linkedEntityTable'], $entityTable); @@ -42,18 +43,16 @@ public static function updateMode() { //I am not sure about other fields, if mode = 3 apply for an event then other fields //should be save for all other series events or not so applying for price set only for now here. if (CRM_Core_BAO_RecurringEntity::MODE_ALL_ENTITY_IN_SERIES === $mode) { - //Step-1: Get Price set for parent event - $currentEventPriceSet = CRM_Price_BAO_PriceSet::getPriceSetOfEntity($entityTable, $entityId); - //Step-2: Get all events of series - $seriesEventRecords = CRM_Core_BAO_RecurringEntity::getEntitiesFor($entityId, $entityTable); - foreach($seriesEventRecords as $event) { - //Step-3: Save price set in other series events - if (CRM_Price_BAO_PriceSet::removeFrom($event['table'], $event['id'])) { //Remove existing priceset - CRM_Core_BAO_Discount::del($event['id'], $event['table']); - CRM_Price_BAO_PriceSet::addTo($event['table'], $event['id'], $currentEventPriceSet['price_set_id']); //Add new price set - } + //Step-1: Get all events of series + $seriesEventRecords = CRM_Core_BAO_RecurringEntity::getEntitiesFor($entityId, $entityTable); + foreach ($seriesEventRecords as $event) { + //Step-3: Save price set in other series events + if (CRM_Price_BAO_PriceSet::removeFrom($event['table'], $event['id'])) {//Remove existing priceset + CRM_Core_BAO_Discount::del($event['id'], $event['table']); + CRM_Price_BAO_PriceSet::addTo($event['table'], $event['id'], $priceSet); //Add new price set } + } } //CRM-20787 - Fix end $finalResult['status'] = 'Done'; diff --git a/CRM/Price/BAO/PriceSet.php b/CRM/Price/BAO/PriceSet.php index 2bb62c933416..e1dabf52027e 100644 --- a/CRM/Price/BAO/PriceSet.php +++ b/CRM/Price/BAO/PriceSet.php @@ -273,25 +273,6 @@ public static function addTo($entityTable, $entityId, $priceSetId) { return $dao->save(); } - /** - * Get price set for the given entity and id. - * - * @param string $entityTable - * @param int $entityId - * - * @return mixed - */ - public static function getPriceSetOfEntity($entityTable, $entityId) { - $dao = new CRM_Price_DAO_PriceSetEntity(); - $dao->entity_id = $entityId; - $dao->entity_table = $entityTable; - if ($dao->find(TRUE)) { - $entities['table'] = $dao->entity_table; - $entities['id'] = $dao->entity_id; - $entities['price_set_id'] = $dao->price_set_id; - } - return $entities; - } /** * Delete price set for the given entity and id. * diff --git a/templates/CRM/Event/Form/ManageEvent/ConfirmRepeatMode.tpl b/templates/CRM/Event/Form/ManageEvent/ConfirmRepeatMode.tpl index 4b4e1a0c2864..7eea07481bf1 100644 --- a/templates/CRM/Event/Form/ManageEvent/ConfirmRepeatMode.tpl +++ b/templates/CRM/Event/Form/ManageEvent/ConfirmRepeatMode.tpl @@ -89,10 +89,11 @@ function updateMode() { var mode = $('input[name=recur_mode]:checked', this).val(), entityID = parseInt('{/literal}{$entityID}{literal}'), - entityTable = '{/literal}{$entityTable}{literal}'; + entityTable = '{/literal}{$entityTable}{literal}', + priceSet = $('#price_set_id').val(); if (entityID != "" && mode && mapper.hasOwnProperty(formClass) && entityTable !="") { $.getJSON(CRM.url("civicrm/ajax/recurringentity/update-mode", - {mode: mode, entityId: entityID, entityTable: entityTable, linkedEntityTable: mapper[formClass]}) + {mode: mode, entityId: entityID, entityTable: entityTable, linkedEntityTable: mapper[formClass], priceSet: priceSet}) ).done(function (result) { if (result.status != "" && result.status == 'Done') { $form.submit(); From 543aa76e6bb3d57d21c0ad838c4abf02d484fbe0 Mon Sep 17 00:00:00 2001 From: Alok Patel Date: Mon, 23 Oct 2017 16:19:06 +0530 Subject: [PATCH 3/3] CRM-20787: Unit test for this issue. --- CRM/Core/BAO/RecurringEntity.php | 60 ++++++++++++++++++ CRM/Core/Page/AJAX/RecurringEntity.php | 42 +------------ .../CRM/Core/BAO/RecurringEntityTest.php | 63 +++++++++++++++++++ 3 files changed, 125 insertions(+), 40 deletions(-) diff --git a/CRM/Core/BAO/RecurringEntity.php b/CRM/Core/BAO/RecurringEntity.php index 2e4dd2471cc7..a41d9367a73f 100644 --- a/CRM/Core/BAO/RecurringEntity.php +++ b/CRM/Core/BAO/RecurringEntity.php @@ -1179,4 +1179,64 @@ public static function updateModeLinkedEntity($entityId, $linkedEntityTable, $ma return $result; } + /** + * Update mode in civicrm_recurring_entity table for event related data and price set in civicrm_price_set_entity. + * + * @param int $entityId + * Event id . + * @param string $entityTable + * @param string $mode + * @param string $linkedEntityTable + * Linked entity table name for this event . + * @param string $priceSet + * Price set of the event . + * + * @return array + */ + public static function updateModeAndPriceSet($entityId, $entityTable, $mode, $linkedEntityTable, $priceSet) { + $finalResult = array(); + + if (!empty($linkedEntityTable)) { + $result = CRM_Core_BAO_RecurringEntity::updateModeLinkedEntity($entityId, $linkedEntityTable, $entityTable); + } + + $dao = new CRM_Core_DAO_RecurringEntity(); + if (!empty($result)) { + $dao->entity_id = $result['entityId']; + $dao->entity_table = $result['entityTable']; + } + else { + $dao->entity_id = $entityId; + $dao->entity_table = $entityTable; + } + + if ($dao->find(TRUE)) { + $dao->mode = $mode; + $dao->save(); + + //CRM-20787 Fix + //I am not sure about other fields, if mode = 3 apply for an event then other fields + //should be save for all other series events or not so applying for price set only for now here. + if (CRM_Core_BAO_RecurringEntity::MODE_ALL_ENTITY_IN_SERIES === $mode) { + + //Step-1: Get all events of series + $seriesEventRecords = CRM_Core_BAO_RecurringEntity::getEntitiesFor($entityId, $entityTable); + foreach ($seriesEventRecords as $event) { + //Step-3: Save price set in other series events + if (CRM_Price_BAO_PriceSet::removeFrom($event['table'], $event['id'])) {//Remove existing priceset + CRM_Core_BAO_Discount::del($event['id'], $event['table']); + CRM_Price_BAO_PriceSet::addTo($event['table'], $event['id'], $priceSet); //Add new price set + } + } + } + //CRM-20787 - Fix end + $finalResult['status'] = 'Done'; + } + else { + $finalResult['status'] = 'Error'; + } + + return $finalResult; + } + } diff --git a/CRM/Core/Page/AJAX/RecurringEntity.php b/CRM/Core/Page/AJAX/RecurringEntity.php index 9c1f3e9f898a..9fe6b84f713b 100644 --- a/CRM/Core/Page/AJAX/RecurringEntity.php +++ b/CRM/Core/Page/AJAX/RecurringEntity.php @@ -20,46 +20,8 @@ public static function updateMode() { $entityId = CRM_Utils_Type::escape($_REQUEST['entityId'], 'Integer'); $entityTable = CRM_Utils_Type::escape($_REQUEST['entityTable'], 'String'); $priceSet = CRM_Utils_Type::escape($_REQUEST['priceSet'], 'String'); - - if (!empty($_REQUEST['linkedEntityTable'])) { - $result = CRM_Core_BAO_RecurringEntity::updateModeLinkedEntity($entityId, $_REQUEST['linkedEntityTable'], $entityTable); - } - - $dao = new CRM_Core_DAO_RecurringEntity(); - if (!empty($result)) { - $dao->entity_id = $result['entityId']; - $dao->entity_table = $result['entityTable']; - } - else { - $dao->entity_id = $entityId; - $dao->entity_table = $entityTable; - } - - if ($dao->find(TRUE)) { - $dao->mode = $mode; - $dao->save(); - - //CRM-20787 Fix - //I am not sure about other fields, if mode = 3 apply for an event then other fields - //should be save for all other series events or not so applying for price set only for now here. - if (CRM_Core_BAO_RecurringEntity::MODE_ALL_ENTITY_IN_SERIES === $mode) { - - //Step-1: Get all events of series - $seriesEventRecords = CRM_Core_BAO_RecurringEntity::getEntitiesFor($entityId, $entityTable); - foreach ($seriesEventRecords as $event) { - //Step-3: Save price set in other series events - if (CRM_Price_BAO_PriceSet::removeFrom($event['table'], $event['id'])) {//Remove existing priceset - CRM_Core_BAO_Discount::del($event['id'], $event['table']); - CRM_Price_BAO_PriceSet::addTo($event['table'], $event['id'], $priceSet); //Add new price set - } - } - } - //CRM-20787 - Fix end - $finalResult['status'] = 'Done'; - } - else { - $finalResult['status'] = 'Error'; - } + $linkedEntityTable = $_REQUEST['linkedEntityTable']; + $finalResult = CRM_Core_BAO_RecurringEntity::updateModeAndPriceSet($entityId, $entityTable, $mode, $linkedEntityTable, $priceSet); } CRM_Utils_JSON::output($finalResult); } diff --git a/tests/phpunit/CRM/Core/BAO/RecurringEntityTest.php b/tests/phpunit/CRM/Core/BAO/RecurringEntityTest.php index 9dd05181db58..5f26ab18f0e5 100644 --- a/tests/phpunit/CRM/Core/BAO/RecurringEntityTest.php +++ b/tests/phpunit/CRM/Core/BAO/RecurringEntityTest.php @@ -105,6 +105,69 @@ public function testActivityGeneration() { } + /** + * Creating action schedule + */ + private function createActionSchedule($entity_id, $entity_table) { + $params = array( + "used_for" => $entity_table, + "entity_value" => $entity_id, + "start_action_date" => date("YmdHis"), + "repetition_frequency_unit" => "week", + "repetition_frequency_interval" => "3", + "start_action_condition" => "monday,tuesday,wednesday,thursday,friday,saturday", + "start_action_offset" => "2", + ); + $actionScheduleObj = CRM_Core_BAO_ActionSchedule::add($params); + return $actionScheduleObj; + } + + /** + * Creating recurring entities + */ + private function createRecurringEntities($actionScheduleObj, $entity_id, $entity_table) { + $recursion = new CRM_Core_BAO_RecurringEntity(); + $recursion->dateColumns = array( + "start_date", + ); + $recursion->scheduleId = $actionScheduleObj->id; + $recursion->entity_id = $entity_id; + $recursion->entity_table = $entity_table; + $recursion->linkedEntities = array( + array( + "table" => "civicrm_price_set_entity", + "findCriteria" => array( + "entity_id" => $entity_id, + "entity_table" => $entity_table, + ), + "linkedColumns" => array( + "entity_id", + ), + "isRecurringEntityRecord" => FALSE, + ), + ); + return $recursion->generate(); + } + + /** + * Testing Event Generation through Entity Recursion. + */ + public function testRepeatEventCreation() { + $event = $this->eventCreate(); + $entity_table = "civicrm_event"; + $entity_id = $event["id"]; + CRM_Price_BAO_PriceSet::addTo($entity_table, $entity_id, 1); + $actionScheduleObj = $this->createActionSchedule($entity_id, $entity_table); + $recurringEntities = $this->createRecurringEntities($actionScheduleObj, $entity_id, $entity_table); + $finalResult = CRM_Core_BAO_RecurringEntity::updateModeAndPriceSet($entity_id, $entity_table, CRM_Core_BAO_RecurringEntity::MODE_ALL_ENTITY_IN_SERIES, array(), 2); + $this->assertEquals(2, count($recurringEntities["civicrm_event"]), "Recurring events not created."); + $this->assertEquals(2, count($recurringEntities["civicrm_price_set_entity"]), "Recurring price sets not created."); + $priceSetOne = CRM_Price_BAO_PriceSet::getFor($entity_table, $recurringEntities["civicrm_price_set_entity"][0]); + $priceSetTwo = CRM_Price_BAO_PriceSet::getFor($entity_table, $recurringEntities["civicrm_price_set_entity"][1]); + $this->assertEquals(2, $priceSetOne, "Price set id of the recurring event is not updated."); + $this->assertEquals(2, $priceSetTwo, "Price set id of the recurring event is not updated."); + } + /** * Testing Event Generation through Entity Recursion. */