Commit | Line | Data |
---|---|---|
25b72113 | 1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
7d61e75f | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
25b72113 | 5 | | | |
7d61e75f TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
25b72113 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
25b72113 | 11 | |
25b72113 | 12 | /** |
060402a9 | 13 | * Class CRM_Core_BAO_RecurringEntityTest |
acb109b7 | 14 | * @group headless |
25b72113 | 15 | */ |
060402a9 | 16 | class CRM_Core_BAO_RecurringEntityTest extends CiviUnitTestCase { |
25b72113 | 17 | |
6caeea75 | 18 | /** |
19 | * Sets up the fixture, for example, opens a network connection. | |
20 | * This method is called before a test is executed. | |
6caeea75 | 21 | */ |
22 | protected function setUp() { | |
25b72113 | 23 | parent::setUp(); |
25b72113 | 24 | } |
59d63f8b | 25 | |
6caeea75 | 26 | /** |
27 | * Tears down the fixture, for example, closes a network connection. | |
28 | * This method is called after a test is executed. | |
6caeea75 | 29 | */ |
6c6e6187 TO |
30 | protected function tearDown() { |
31 | } | |
25b72113 | 32 | |
33 | /** | |
eceb18cc | 34 | * Testing Activity Generation through Entity Recursion. |
25b72113 | 35 | */ |
00be9182 | 36 | public function testActivityGeneration() { |
206c0c43 | 37 | //Activity set initial params |
37b28176 | 38 | $daoActivity = new CRM_Activity_DAO_Activity(); |
39 | $daoActivity->activity_type_id = 1; | |
40 | $daoActivity->subject = "Initial Activity"; | |
f5f5a631 | 41 | $daoActivity->activity_date_time = '20141002103000'; |
37b28176 | 42 | $daoActivity->save(); |
25b72113 | 43 | |
37b28176 | 44 | $recursion = new CRM_Core_BAO_RecurringEntity(); |
92915c55 | 45 | $recursion->entity_id = $daoActivity->id; |
690bf076 | 46 | $recursion->entity_table = 'civicrm_activity'; |
9099cab3 CW |
47 | $recursion->dateColumns = ['activity_date_time']; |
48 | $recursion->schedule = [ | |
92915c55 TO |
49 | 'entity_value' => $daoActivity->id, |
50 | 'start_action_date' => $daoActivity->activity_date_time, | |
a1a821bc | 51 | 'entity_status' => 'fourth saturday', |
37b28176 | 52 | 'repetition_frequency_unit' => 'month', |
53 | 'repetition_frequency_interval' => 3, | |
54 | 'start_action_offset' => 5, | |
92915c55 | 55 | 'used_for' => 'activity', |
9099cab3 | 56 | ]; |
206c0c43 | 57 | |
59d63f8b | 58 | $generatedEntities = $recursion->generate(); |
f5f5a631 | 59 | $this->assertEquals(5, count($generatedEntities['civicrm_activity']), "Cehck if number of iterations are 5"); |
9099cab3 | 60 | $expectedDates = [ |
59d63f8b | 61 | '20141025103000', |
4e12f3b2 PZ |
62 | '20150124103000', |
63 | '20150425103000', | |
64 | '20150725103000', | |
65 | '20151024103000', | |
9099cab3 | 66 | ]; |
84f02991 | 67 | foreach ($generatedEntities['civicrm_activity'] as $entityID) { |
37b28176 | 68 | $this->assertDBNotNull('CRM_Activity_DAO_Activity', $entityID, 'id', |
69 | 'id', 'Check DB if repeating activities were created' | |
70 | ); | |
25b72113 | 71 | } |
25b72113 | 72 | |
206c0c43 | 73 | // set mode to ALL, i.e any change to changing activity affects all related recurring activities |
74 | $recursion->mode(3); | |
37b28176 | 75 | |
e4f46be0 | 76 | // lets change subject of initial activity that we created in beginning |
25b72113 | 77 | $daoActivity->find(TRUE); |
690bf076 | 78 | $daoActivity->subject = 'Changed Activity'; |
25b72113 | 79 | $daoActivity->save(); |
25b72113 | 80 | |
37b28176 | 81 | // check if other activities were affected |
9099cab3 | 82 | $actualDates = []; |
84f02991 | 83 | foreach ($generatedEntities['civicrm_activity'] as $entityID) { |
690bf076 | 84 | $this->assertDBCompareValue('CRM_Activity_DAO_Activity', $entityID, 'subject', 'id', 'Changed Activity', 'Check if subject was updated'); |
f5f5a631 | 85 | $actualDates[] = date('YmdHis', strtotime(CRM_Core_DAO::getFieldValue('CRM_Activity_DAO_Activity', $entityID, 'activity_date_time', 'id'))); |
6caeea75 | 86 | } |
f5f5a631 | 87 | $resultDates = array_diff($actualDates, $expectedDates); |
88 | $this->assertEquals(0, count($resultDates), "Check if all the value in expected array matches actual array"); | |
59d63f8b | 89 | |
6caeea75 | 90 | } |
59d63f8b | 91 | |
543aa76e AP |
92 | /** |
93 | * Creating action schedule | |
94 | */ | |
95 | private function createActionSchedule($entity_id, $entity_table) { | |
9099cab3 | 96 | $params = [ |
543aa76e AP |
97 | "used_for" => $entity_table, |
98 | "entity_value" => $entity_id, | |
99 | "start_action_date" => date("YmdHis"), | |
100 | "repetition_frequency_unit" => "week", | |
101 | "repetition_frequency_interval" => "3", | |
102 | "start_action_condition" => "monday,tuesday,wednesday,thursday,friday,saturday", | |
103 | "start_action_offset" => "2", | |
9099cab3 | 104 | ]; |
543aa76e AP |
105 | $actionScheduleObj = CRM_Core_BAO_ActionSchedule::add($params); |
106 | return $actionScheduleObj; | |
107 | } | |
108 | ||
109 | /** | |
110 | * Creating recurring entities | |
111 | */ | |
112 | private function createRecurringEntities($actionScheduleObj, $entity_id, $entity_table) { | |
113 | $recursion = new CRM_Core_BAO_RecurringEntity(); | |
9099cab3 | 114 | $recursion->dateColumns = [ |
543aa76e | 115 | "start_date", |
9099cab3 | 116 | ]; |
543aa76e AP |
117 | $recursion->scheduleId = $actionScheduleObj->id; |
118 | $recursion->entity_id = $entity_id; | |
119 | $recursion->entity_table = $entity_table; | |
9099cab3 CW |
120 | $recursion->linkedEntities = [ |
121 | [ | |
543aa76e | 122 | "table" => "civicrm_price_set_entity", |
9099cab3 | 123 | "findCriteria" => [ |
543aa76e AP |
124 | "entity_id" => $entity_id, |
125 | "entity_table" => $entity_table, | |
9099cab3 CW |
126 | ], |
127 | "linkedColumns" => [ | |
543aa76e | 128 | "entity_id", |
9099cab3 | 129 | ], |
543aa76e | 130 | "isRecurringEntityRecord" => FALSE, |
9099cab3 CW |
131 | ], |
132 | ]; | |
543aa76e AP |
133 | return $recursion->generate(); |
134 | } | |
135 | ||
136 | /** | |
137 | * Testing Event Generation through Entity Recursion. | |
138 | */ | |
139 | public function testRepeatEventCreation() { | |
140 | $event = $this->eventCreate(); | |
141 | $entity_table = "civicrm_event"; | |
142 | $entity_id = $event["id"]; | |
143 | CRM_Price_BAO_PriceSet::addTo($entity_table, $entity_id, 1); | |
144 | $actionScheduleObj = $this->createActionSchedule($entity_id, $entity_table); | |
145 | $recurringEntities = $this->createRecurringEntities($actionScheduleObj, $entity_id, $entity_table); | |
9099cab3 | 146 | $finalResult = CRM_Core_BAO_RecurringEntity::updateModeAndPriceSet($entity_id, $entity_table, CRM_Core_BAO_RecurringEntity::MODE_ALL_ENTITY_IN_SERIES, [], 2); |
543aa76e AP |
147 | $this->assertEquals(2, count($recurringEntities["civicrm_event"]), "Recurring events not created."); |
148 | $this->assertEquals(2, count($recurringEntities["civicrm_price_set_entity"]), "Recurring price sets not created."); | |
149 | $priceSetOne = CRM_Price_BAO_PriceSet::getFor($entity_table, $recurringEntities["civicrm_price_set_entity"][0]); | |
150 | $priceSetTwo = CRM_Price_BAO_PriceSet::getFor($entity_table, $recurringEntities["civicrm_price_set_entity"][1]); | |
151 | $this->assertEquals(2, $priceSetOne, "Price set id of the recurring event is not updated."); | |
152 | $this->assertEquals(2, $priceSetTwo, "Price set id of the recurring event is not updated."); | |
153 | } | |
154 | ||
690bf076 | 155 | /** |
eceb18cc | 156 | * Testing Event Generation through Entity Recursion. |
690bf076 | 157 | */ |
00be9182 | 158 | public function testEventGeneration() { |
6c6e6187 | 159 | //Event set initial params |
690bf076 | 160 | $daoEvent = new CRM_Event_DAO_Event(); |
161 | $daoEvent->title = 'Test event for Recurring Entity'; | |
162 | $daoEvent->event_type_id = 3; | |
163 | $daoEvent->is_public = 1; | |
f5f5a631 | 164 | $daoEvent->start_date = date('YmdHis', strtotime('2014-10-26 10:30:00')); |
92915c55 | 165 | $daoEvent->end_date = date('YmdHis', strtotime('2014-10-28 10:30:00')); |
690bf076 | 166 | $daoEvent->created_date = date('YmdHis'); |
167 | $daoEvent->is_active = 1; | |
168 | $daoEvent->save(); | |
cd3f28a7 | 169 | $this->assertDBNotNull('CRM_Event_DAO_Event', $daoEvent->id, 'id', 'id', 'Check DB if event was created'); |
59d63f8b | 170 | |
cd3f28a7 | 171 | //Create tell a friend for event |
172 | $daoTellAFriend = new CRM_Friend_DAO_Friend(); | |
173 | $daoTellAFriend->entity_table = 'civicrm_event'; | |
39b959db SL |
174 | // join with event |
175 | $daoTellAFriend->entity_id = $daoEvent->id; | |
cd3f28a7 | 176 | $daoTellAFriend->title = 'Testing tell a friend'; |
177 | $daoTellAFriend->is_active = 1; | |
178 | $daoTellAFriend->save(); | |
f5f5a631 | 179 | $this->assertDBNotNull('CRM_Friend_DAO_Friend', $daoTellAFriend->id, 'id', 'id', 'Check DB if tell a friend was created'); |
690bf076 | 180 | |
fb2120e7 | 181 | // time to use recursion |
690bf076 | 182 | $recursion = new CRM_Core_BAO_RecurringEntity(); |
92915c55 | 183 | $recursion->entity_id = $daoEvent->id; |
690bf076 | 184 | $recursion->entity_table = 'civicrm_event'; |
9099cab3 CW |
185 | $recursion->dateColumns = ['start_date']; |
186 | $recursion->schedule = [ | |
92915c55 TO |
187 | 'entity_value' => $daoEvent->id, |
188 | 'start_action_date' => $daoEvent->start_date, | |
189 | 'start_action_condition' => 'monday', | |
190 | 'repetition_frequency_unit' => 'week', | |
690bf076 | 191 | 'repetition_frequency_interval' => 1, |
92915c55 TO |
192 | 'start_action_offset' => 4, |
193 | 'used_for' => 'event', | |
9099cab3 | 194 | ]; |
690bf076 | 195 | |
9099cab3 CW |
196 | $recursion->linkedEntities = [ |
197 | [ | |
92915c55 | 198 | 'table' => 'civicrm_tell_friend', |
9099cab3 | 199 | 'findCriteria' => [ |
92915c55 | 200 | 'entity_id' => $recursion->entity_id, |
21dfd5f5 | 201 | 'entity_table' => 'civicrm_event', |
9099cab3 CW |
202 | ], |
203 | 'linkedColumns' => ['entity_id'], | |
342c3f9e | 204 | 'isRecurringEntityRecord' => TRUE, |
9099cab3 CW |
205 | ], |
206 | ]; | |
59d63f8b | 207 | |
f5f5a631 | 208 | $interval = $recursion->getInterval($daoEvent->start_date, $daoEvent->end_date); |
9099cab3 | 209 | $recursion->intervalDateColumns = ['end_date' => $interval]; |
59d63f8b | 210 | $generatedEntities = $recursion->generate(); |
cd3f28a7 | 211 | $this->assertArrayHasKey('civicrm_event', $generatedEntities, 'Check if generatedEntities has civicrm_event as required key'); |
9099cab3 | 212 | $expectedDates = [ |
f5f5a631 | 213 | '20141027103000' => '20141029103000', |
214 | '20141103103000' => '20141105103000', | |
215 | '20141110103000' => '20141112103000', | |
21dfd5f5 | 216 | '20141117103000' => '20141119103000', |
9099cab3 | 217 | ]; |
59d63f8b | 218 | |
fb2120e7 | 219 | $this->assertCount($recursion->schedule['start_action_offset'], $generatedEntities['civicrm_event'], 'Check if the number of events created are right'); |
9099cab3 | 220 | $actualDates = []; |
22e263ad | 221 | foreach ($generatedEntities['civicrm_event'] as $key => $val) { |
fb2120e7 | 222 | $this->assertDBNotNull('CRM_Event_DAO_Event', $val, 'id', 'id', 'Check if repeating events were created.'); |
f5f5a631 | 223 | $startDate = date('YmdHis', strtotime(CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $val, 'start_date', 'id'))); |
224 | $endDate = date('YmdHis', strtotime(CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $val, 'end_date', 'id'))); | |
225 | $actualDates[$startDate] = $endDate; | |
cd3f28a7 | 226 | } |
59d63f8b | 227 | |
f5f5a631 | 228 | $resultDates = array_diff($actualDates, $expectedDates); |
229 | $this->assertEquals(0, count($resultDates), "Check if all the value in expected array matches actual array"); | |
59d63f8b | 230 | |
22e263ad | 231 | foreach ($generatedEntities['civicrm_tell_friend'] as $key => $val) { |
fb2120e7 | 232 | $this->assertDBNotNull('CRM_Friend_DAO_Friend', $val, 'id', 'id', 'Check if friends were created in loop'); |
233 | $this->assertDBCompareValue('CRM_Friend_DAO_Friend', $val, 'entity_id', 'id', $generatedEntities['civicrm_event'][$key], 'Check DB if correct FK was maintained with event for Friend'); | |
cd3f28a7 | 234 | } |
fb2120e7 | 235 | $this->assertCount($recursion->schedule['start_action_offset'], $generatedEntities['civicrm_tell_friend'], 'Check if the number of tell a friend records are right'); |
59d63f8b | 236 | |
206c0c43 | 237 | // set mode to ALL, i.e any change to changing event affects all related recurring activities |
238 | $recursion->mode(3); | |
690bf076 | 239 | |
240 | $daoEvent->find(TRUE); | |
241 | $daoEvent->title = 'Event Changed'; | |
242 | $daoEvent->save(); | |
243 | ||
244 | // check if other events were affected | |
84f02991 | 245 | foreach ($generatedEntities['civicrm_event'] as $entityID) { |
690bf076 | 246 | $this->assertDBCompareValue('CRM_Event_DAO_Event', $entityID, 'title', 'id', 'Event Changed', 'Check if title was updated'); |
247 | } | |
59d63f8b | 248 | |
249 | end($generatedEntities['civicrm_event']); | |
2eac52b6 | 250 | $key = key($generatedEntities['civicrm_event']); |
59d63f8b | 251 | |
2eac52b6 | 252 | end($generatedEntities['civicrm_tell_friend']); |
253 | $actKey = key($generatedEntities['civicrm_tell_friend']); | |
59d63f8b | 254 | |
2eac52b6 | 255 | //Check if both(event/tell a friend) keys are same |
256 | $this->assertEquals($key, $actKey, "Check if both the keys are same"); | |
59d63f8b | 257 | |
2eac52b6 | 258 | //Cross check event exists before we test deletion |
9099cab3 | 259 | $searchParamsEventBeforeDelete = [ |
92915c55 | 260 | 'entity_id' => $generatedEntities['civicrm_event'][$key], |
21dfd5f5 | 261 | 'entity_table' => 'civicrm_event', |
9099cab3 CW |
262 | ]; |
263 | $expectedValuesEventBeforeDelete = [ | |
92915c55 | 264 | 'entity_id' => $generatedEntities['civicrm_event'][$key], |
21dfd5f5 | 265 | 'entity_table' => 'civicrm_event', |
9099cab3 | 266 | ]; |
2eac52b6 | 267 | $this->assertDBCompareValues('CRM_Core_DAO_RecurringEntity', $searchParamsEventBeforeDelete, $expectedValuesEventBeforeDelete); |
59d63f8b | 268 | |
2eac52b6 | 269 | //Cross check event exists before we test deletion |
9099cab3 | 270 | $searchParamsTellAFriendBeforeDelete = [ |
92915c55 | 271 | 'entity_id' => $generatedEntities['civicrm_tell_friend'][$actKey], |
21dfd5f5 | 272 | 'entity_table' => 'civicrm_tell_friend', |
9099cab3 CW |
273 | ]; |
274 | $expectedValuesTellAFriendBeforeDelete = [ | |
92915c55 | 275 | 'entity_id' => $generatedEntities['civicrm_tell_friend'][$actKey], |
21dfd5f5 | 276 | 'entity_table' => 'civicrm_tell_friend', |
9099cab3 | 277 | ]; |
2eac52b6 | 278 | $this->assertDBCompareValues('CRM_Core_DAO_RecurringEntity', $searchParamsTellAFriendBeforeDelete, $expectedValuesTellAFriendBeforeDelete); |
59d63f8b | 279 | |
2eac52b6 | 280 | //Delete an event from recurring set and respective linked entity should be deleted from civicrm_recurring_entity_table |
281 | $daoRecurEvent = new CRM_Event_DAO_Event(); | |
282 | $daoRecurEvent->id = $generatedEntities['civicrm_event'][$key]; | |
283 | if ($daoRecurEvent->find(TRUE)) { | |
284 | $daoRecurEvent->delete(); | |
2eac52b6 | 285 | } |
59d63f8b | 286 | |
2eac52b6 | 287 | //Check if this event_id was deleted |
288 | $this->assertDBNull('CRM_Event_DAO_Event', $generatedEntities['civicrm_event'][$key], 'id', 'id', 'Check if event was deleted'); | |
9099cab3 | 289 | $searchParams = [ |
f9f8eda7 | 290 | 'entity_id' => $generatedEntities['civicrm_event'][$key], |
21dfd5f5 | 291 | 'entity_table' => 'civicrm_event', |
9099cab3 CW |
292 | ]; |
293 | $compareParams = []; | |
2eac52b6 | 294 | $this->assertDBCompareValues('CRM_Core_DAO_RecurringEntity', $searchParams, $compareParams); |
f9f8eda7 | 295 | |
2eac52b6 | 296 | //Find tell_a_friend id if that was deleted from civicrm |
9099cab3 | 297 | $searchActParams = [ |
f9f8eda7 | 298 | 'entity_id' => $generatedEntities['civicrm_tell_friend'][$actKey], |
21dfd5f5 | 299 | 'entity_table' => 'civicrm_tell_friend', |
9099cab3 CW |
300 | ]; |
301 | $compareActParams = []; | |
2eac52b6 | 302 | $this->assertDBCompareValues('CRM_Friend_DAO_Friend', $searchActParams, $compareActParams); |
690bf076 | 303 | } |
96025800 | 304 | |
3fec1adc | 305 | /** |
306 | * Testing Activity Generation through Entity Recursion with Custom Data and Tags. | |
307 | */ | |
308 | public function testRecurringEntityGenerationWithCustomDataAndTags() { | |
309 | ||
310 | // Create custom group and field | |
311 | $customGroup = $this->customGroupCreate([ | |
312 | 'extends' => 'Activity', | |
313 | ]); | |
314 | $customField = $this->customFieldCreate([ | |
9099cab3 CW |
315 | 'custom_group_id' => $customGroup['id'], |
316 | 'default_value' => '', | |
317 | ]); | |
3fec1adc | 318 | |
319 | // Create activity Tag | |
320 | $tag = $this->tagCreate([ | |
321 | 'used_for' => 'Activities', | |
322 | ]); | |
323 | ||
324 | // Create original activity | |
325 | $customFieldValue = 'Custom Value'; | |
326 | $activityDateTime = date('YmdHis'); | |
327 | $activityId = $this->activityCreate([ | |
328 | 'activity_date_time' => $activityDateTime, | |
329 | 'custom_' . $customField['id'] => $customFieldValue, | |
330 | ]); | |
331 | ||
332 | $activityId = $activityId['id']; | |
333 | ||
334 | // Assign tag to a activity. | |
335 | $this->callAPISuccess('EntityTag', 'create', [ | |
336 | 'entity_table' => 'civicrm_activity', | |
337 | 'entity_id' => $activityId, | |
338 | 'tag_id' => $tag['id'], | |
339 | ]); | |
340 | ||
341 | // Create recurring activities. | |
342 | $recursion = new CRM_Core_BAO_RecurringEntity(); | |
343 | $recursion->entity_id = $activityId; | |
344 | $recursion->entity_table = 'civicrm_activity'; | |
345 | $recursion->dateColumns = ['activity_date_time']; | |
346 | $recursion->schedule = [ | |
347 | 'entity_value' => $activityId, | |
348 | 'start_action_date' => $activityDateTime, | |
349 | 'entity_status' => 'fourth saturday', | |
350 | 'repetition_frequency_unit' => 'month', | |
351 | 'repetition_frequency_interval' => 3, | |
352 | 'start_action_offset' => 3, | |
353 | 'used_for' => 'activity', | |
354 | ]; | |
355 | ||
356 | $generatedEntities = $recursion->generate(); | |
357 | $generatedActivities = $generatedEntities['civicrm_activity']; | |
358 | ||
359 | $this->assertEquals(3, count($generatedActivities), "Check if number of iterations are 3"); | |
360 | ||
361 | foreach ($generatedActivities as $generatedActivityId) { | |
362 | ||
363 | /* Validate tag in recurring activity | |
364 | // @todo - refer https://github.com/civicrm/civicrm-core/pull/13470 | |
365 | $this->callAPISuccess('EntityTag', 'getsingle', [ | |
366 | 'entity_table' => 'civicrm_activity', | |
367 | 'entity_id' => $generatedActivityId, | |
368 | ]); | |
369 | */ | |
370 | ||
371 | // Validate custom data in recurring activity | |
372 | $activity = $this->callAPISuccess('activity', 'getsingle', [ | |
373 | 'return' => [ | |
374 | 'custom_' . $customField['id'], | |
375 | ], | |
376 | 'id' => $generatedActivityId, | |
377 | ]); | |
378 | ||
379 | $this->assertEquals($customFieldValue, $activity['custom_' . $customField['id']], 'Custom field value should be ' . $customFieldValue); | |
380 | ||
381 | } | |
382 | } | |
383 | ||
25b72113 | 384 | } |