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