Merge pull request #16790 from eileenmcnaughton/pcp
[civicrm-core.git] / tests / phpunit / CRM / Member / BAO / MembershipTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7d61e75f 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 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 |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035 11
4cbe18b8
EM
12/**
13 * Class CRM_Member_BAO_MembershipTest
acb109b7 14 * @group headless
4cbe18b8 15 */
6a488035 16class CRM_Member_BAO_MembershipTest extends CiviUnitTestCase {
6a488035 17
00be9182 18 public function setUp() {
6a488035 19 parent::setUp();
6a488035
TO
20
21 $this->_contactID = $this->organizationCreate();
9099cab3 22 $this->_membershipTypeID = $this->membershipTypeCreate(['member_of_contact_id' => $this->_contactID]);
6a488035
TO
23 // add a random number to avoid silly conflicts with old data
24 $this->_membershipStatusID = $this->membershipStatusCreate('test status' . rand(1, 1000));
25 }
26
27 /**
28 * Tears down the fixture, for example, closes a network connection.
29 * This method is called after a test is executed.
5a433c56 30 *
31 * @throws \CRM_Core_Exception
6a488035 32 */
00be9182 33 public function tearDown() {
9099cab3 34 $this->membershipTypeDelete(['id' => $this->_membershipTypeID]);
481a74f4 35 $this->membershipStatusDelete($this->_membershipStatusID);
93ac19cd 36 $this->contactDelete($this->_contactID);
6a488035 37
6c6e6187 38 $this->_contactID = $this->_membershipStatusID = $this->_membershipTypeID = NULL;
5a433c56 39 $this->quickCleanUpFinancialEntities();
40 $this->restoreMembershipTypes();
41 parent::tearDown();
6a488035
TO
42 }
43
5c3a7abf
AP
44 /**
45 * Create membership type using given organization id.
5a433c56 46 *
5c3a7abf 47 * @param $organizationId
39b959db 48 * @param bool $withRelationship
5a433c56 49 *
5c3a7abf 50 * @return array|int
5a433c56 51 * @throws \CRM_Core_Exception
5c3a7abf
AP
52 */
53 private function createMembershipType($organizationId, $withRelationship = FALSE) {
9099cab3 54 $membershipType = $this->callAPISuccess('MembershipType', 'create', [
39b959db
SL
55 //Default domain ID
56 'domain_id' => 1,
5c3a7abf
AP
57 'member_of_contact_id' => $organizationId,
58 'financial_type_id' => "Member Dues",
59 'duration_unit' => "year",
60 'duration_interval' => 1,
61 'period_type' => "rolling",
5a433c56 62 'name' => 'Organiation Membership Type',
5c3a7abf
AP
63 'relationship_type_id' => ($withRelationship) ? 5 : NULL,
64 'relationship_direction' => ($withRelationship) ? 'b_a' : NULL,
9099cab3 65 ]);
5c3a7abf
AP
66 return $membershipType["values"][$membershipType["id"]];
67 }
68
69 /**
70 * Get count of related memberships by parent membership id.
71 * @param $membershipId
72 * @return array|int
73 */
74 private function getRelatedMembershipsCount($membershipId) {
9099cab3 75 return $this->callAPISuccess("Membership", "getcount", [
5c3a7abf 76 'owner_membership_id' => $membershipId,
9099cab3 77 ]);
5c3a7abf
AP
78 }
79
80 /**
81 * Test to delete related membership when type of parent memebrship is changed which does not have relation type associated.
82 * @throws CRM_Core_Exception
83 */
84 public function testDeleteRelatedMembershipsOnParentTypeChanged() {
85
86 $contactId = $this->individualCreate();
87 $membershipOrganizationId = $this->organizationCreate();
88 $organizationId = $this->organizationCreate();
89
90 // Create relationship between organization and individual contact
9099cab3 91 $this->callAPISuccess('Relationship', 'create', [
39b959db
SL
92 // Employer of relationship
93 'relationship_type_id' => 5,
5c3a7abf
AP
94 'contact_id_a' => $contactId,
95 'contact_id_b' => $organizationId,
96 'is_active' => 1,
9099cab3 97 ]);
5c3a7abf
AP
98
99 // Create two membership types one with relationship and one without.
100 $membershipTypeWithRelationship = $this->createMembershipType($membershipOrganizationId, TRUE);
101 $membershipTypeWithoutRelationship = $this->createMembershipType($membershipOrganizationId);
102
103 // Creating membership of organisation
9099cab3 104 $membership = $this->callAPISuccess("Membership", "create", [
5c3a7abf
AP
105 'membership_type_id' => $membershipTypeWithRelationship["id"],
106 'contact_id' => $organizationId,
107 'status_id' => $this->_membershipStatusID,
9099cab3 108 ]);
5c3a7abf 109
cdf46504 110 $membership = $membership['values'][$membership["id"]];
5c3a7abf
AP
111
112 // Check count of related memberships. It should be one for individual contact.
113 $relatedMembershipsCount = $this->getRelatedMembershipsCount($membership["id"]);
114 $this->assertEquals(1, $relatedMembershipsCount, 'Related membership count should be 1.');
115
116 // Update membership by changing it's type. New membership type is without relationship.
117 $membership["membership_type_id"] = $membershipTypeWithoutRelationship["id"];
118 $updatedMembership = $this->callAPISuccess("Membership", "create", $membership);
119
120 // Check count of related memberships again. It should be zero as we changed the membership type.
121 $relatedMembershipsCount = $this->getRelatedMembershipsCount($membership["id"]);
122 $this->assertEquals(0, $relatedMembershipsCount, 'Related membership count should be 0.');
123
124 // Clean up: Delete membership
125 $this->membershipDelete($membership["id"]);
126 }
127
00be9182 128 public function testCreate() {
6a488035 129
cdf46504 130 list($contactId, $membershipId) = $this->setupMembership();
6a488035
TO
131
132 // Now call create() to modify an existing Membership
9099cab3 133 $params = [
6a488035
TO
134 'contact_id' => $contactId,
135 'membership_type_id' => $this->_membershipTypeID,
6c6e6187
TO
136 'join_date' => date('Ymd', strtotime('2006-01-21')),
137 'start_date' => date('Ymd', strtotime('2006-01-21')),
138 'end_date' => date('Ymd', strtotime('2006-12-21')),
6a488035
TO
139 'source' => 'Payment',
140 'is_override' => 1,
141 'status_id' => $this->_membershipStatusID,
9099cab3
CW
142 ];
143 $ids = [
6a488035 144 'membership' => $membershipId,
9099cab3 145 ];
6a488035
TO
146 CRM_Member_BAO_Membership::create($params, $ids);
147
148 $membershipTypeId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId,
149 'membership_type_id', 'contact_id',
150 'Database check on updated membership record.'
151 );
152 $this->assertEquals($membershipTypeId, $this->_membershipTypeID, 'Verify membership type id is fetched.');
153
154 $this->membershipDelete($membershipId);
93ac19cd 155 $this->contactDelete($contactId);
6a488035
TO
156 }
157
00be9182 158 public function testGetValues() {
6a488035
TO
159 // $this->markTestSkipped( 'causes mysterious exit, needs fixing!' );
160 // Calculate membership dates based on the current date
161 $now = time();
162 $year_from_now = $now + (365 * 24 * 60 * 60);
163 $last_month = $now - (30 * 24 * 60 * 60);
164 $year_from_last_month = $last_month + (365 * 24 * 60 * 60);
165
6ae19242 166 $contactId = $this->individualCreate();
6a488035 167
9099cab3 168 $params = [
6a488035
TO
169 'contact_id' => $contactId,
170 'membership_type_id' => $this->_membershipTypeID,
171 'join_date' => date('Ymd'),
172 'start_date' => date('Ymd'),
173 'end_date' => date('Ymd', $year_from_now),
174 'source' => 'Payment',
175 'is_override' => 1,
176 'status_id' => $this->_membershipStatusID,
9099cab3 177 ];
6a488035 178
9099cab3 179 $ids = [];
6a488035
TO
180 CRM_Member_BAO_Membership::create($params, $ids);
181
182 $membershipId1 = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
183 'contact_id', 'Database check for created membership.'
184 );
185
9099cab3 186 $params = [
6a488035
TO
187 'contact_id' => $contactId,
188 'membership_type_id' => $this->_membershipTypeID,
189 'join_date' => date('Ymd', $last_month),
190 'start_date' => date('Ymd', $last_month),
191 'end_date' => date('Ymd', $year_from_last_month),
192 'source' => 'Source123',
193 'is_override' => 0,
194 'status_id' => $this->_membershipStatusID,
9099cab3
CW
195 ];
196 $ids = [];
6a488035
TO
197 CRM_Member_BAO_Membership::create($params, $ids);
198
199 $membershipId2 = $this->assertDBNotNull('CRM_Member_BAO_Membership', 'source123', 'id',
200 'source', 'Database check for created membership.'
201 );
202
9099cab3
CW
203 $membership = ['contact_id' => $contactId];
204 $membershipValues = [];
6a488035
TO
205 CRM_Member_BAO_Membership::getValues($membership, $membershipValues, TRUE);
206
207 $this->assertEquals($membershipValues[$membershipId1]['membership_id'], $membershipId1, 'Verify membership record 1 is fetched.');
208
209 $this->assertEquals($membershipValues[$membershipId2]['membership_id'], $membershipId2, 'Verify membership record 2 is fetched.');
210
211 $this->membershipDelete($membershipId1);
212 $this->membershipDelete($membershipId2);
93ac19cd 213 $this->contactDelete($contactId);
6a488035
TO
214 }
215
00be9182 216 public function testRetrieve() {
cdf46504 217 list($contactId, $membershipId) = $this->setupMembership();
9099cab3
CW
218 $params = ['id' => $membershipId];
219 $values = [];
6a488035
TO
220 CRM_Member_BAO_Membership::retrieve($params, $values);
221 $this->assertEquals($values['id'], $membershipId, 'Verify membership record is retrieved.');
222
223 $this->membershipDelete($membershipId);
224 $this->contactDelete($contactId);
225 }
226
00be9182 227 public function testActiveMembers() {
6ae19242 228 $contactId = $this->individualCreate();
6a488035 229
9099cab3 230 $params = [
6a488035
TO
231 'contact_id' => $contactId,
232 'membership_type_id' => $this->_membershipTypeID,
6c6e6187
TO
233 'join_date' => date('Ymd', strtotime('2006-01-21')),
234 'start_date' => date('Ymd', strtotime('2006-01-21')),
235 'end_date' => date('Ymd', strtotime('2006-12-21')),
6a488035
TO
236 'source' => 'Payment',
237 'is_override' => 1,
238 'status_id' => $this->_membershipStatusID,
9099cab3
CW
239 ];
240 $ids = [];
6a488035
TO
241 CRM_Member_BAO_Membership::create($params, $ids);
242
243 $membershipId1 = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
244 'contact_id', 'Database check for created membership.'
245 );
246
9099cab3
CW
247 $params = ['id' => $membershipId1];
248 $values1 = [];
6a488035 249 CRM_Member_BAO_Membership::retrieve($params, $values1);
9099cab3 250 $membership = [$membershipId1 => $values1];
6a488035 251
9099cab3 252 $params = [
6a488035
TO
253 'contact_id' => $contactId,
254 'membership_type_id' => $this->_membershipTypeID,
6c6e6187
TO
255 'join_date' => date('Ymd', strtotime('2006-01-21')),
256 'start_date' => date('Ymd', strtotime('2006-01-21')),
257 'end_date' => date('Ymd', strtotime('2006-12-21')),
6a488035
TO
258 'source' => 'PaySource',
259 'is_override' => 1,
260 'status_id' => $this->_membershipStatusID,
9099cab3
CW
261 ];
262 $ids = [];
6a488035
TO
263 CRM_Member_BAO_Membership::create($params, $ids);
264
265 $membershipId2 = $this->assertDBNotNull('CRM_Member_BAO_Membership', 'PaySource', 'id',
266 'source', 'Database check for created membership.'
267 );
268
9099cab3
CW
269 $params = ['id' => $membershipId2];
270 $values2 = [];
6a488035
TO
271 CRM_Member_BAO_Membership::retrieve($params, $values2);
272 $membership[$membershipId2] = $values2;
273
274 $activeMembers = CRM_Member_BAO_Membership::activeMembers($membership);
275 $inActiveMembers = CRM_Member_BAO_Membership::activeMembers($membership, 'inactive');
276
277 $this->assertEquals($activeMembers[$membershipId1]['id'], $membership[$membershipId1]['id'], 'Verify active membership record is retrieved.');
278 $this->assertEquals($activeMembers[$membershipId2]['id'], $membership[$membershipId2]['id'], 'Verify active membership record is retrieved.');
279
280 $this->assertEquals(0, count($inActiveMembers), 'Verify No inactive membership record is retrieved.');
281
282 $this->membershipDelete($membershipId1);
283 $this->membershipDelete($membershipId2);
93ac19cd 284 $this->contactDelete($contactId);
6a488035
TO
285 }
286
00be9182 287 public function testDeleteMembership() {
cdf46504 288 list($contactId, $membershipId) = $this->setupMembership();
3506b6cd 289 CRM_Member_BAO_Membership::del($membershipId);
6a488035 290
93ac19cd 291 $this->assertDBNull('CRM_Member_BAO_Membership', $contactId, 'id',
6a488035
TO
292 'contact_id', 'Database check for deleted membership.'
293 );
2883b934
JP
294 $this->assertDBNull('CRM_Price_BAO_LineItem', $membershipId, 'id',
295 'entity_id', 'Database check for deleted line item.'
296 );
93ac19cd 297 $this->contactDelete($contactId);
6a488035
TO
298 }
299
00be9182 300 public function testGetContactMembership() {
cdf46504 301 list($contactId, $membershipId) = $this->setupMembership();
6a488035
TO
302
303 $membership = CRM_Member_BAO_Membership::getContactMembership($contactId, $this->_membershipTypeID, FALSE);
304
305 $this->assertEquals($membership['id'], $membershipId, 'Verify membership record is retrieved.');
306
307 $this->membershipDelete($membershipId);
93ac19cd 308 $this->contactDelete($contactId);
6a488035
TO
309 }
310
c490a46a 311 /**
eceb18cc 312 * Get the contribution.
c490a46a
CW
313 * page id from the membership record
314 */
00be9182 315 public function testgetContributionPageId() {
cdf46504 316 list($contactId, $membershipId) = $this->setupMembership();
6a488035
TO
317 $membership[$membershipId]['renewPageId'] = CRM_Member_BAO_Membership::getContributionPageId($membershipId);
318
319 $this->membershipDelete($membershipId);
93ac19cd 320 $this->contactDelete($contactId);
6a488035 321 }
92915c55 322
c490a46a
CW
323 /**
324 * Get membership joins/renewals
325 * for a specified membership
326 * type.
c490a46a 327 */
00be9182 328 public function testgetMembershipStarts() {
cdf46504 329 list($contactId, $membershipId) = $this->setupMembership();
6a488035
TO
330 $yearStart = date('Y') . '0101';
331 $currentDate = date('Ymd');
332 CRM_Member_BAO_Membership::getMembershipStarts($this->_membershipTypeID, $yearStart, $currentDate);
333
334 $this->membershipDelete($membershipId);
93ac19cd 335 $this->contactDelete($contactId);
6a488035
TO
336 }
337
c490a46a
CW
338 /**
339 * Get a count of membership for a specified membership type,
340 * optionally for a specified date.
c490a46a 341 */
00be9182 342 public function testGetMembershipCount() {
cdf46504 343 list($contactId, $membershipId) = $this->setupMembership();
6a488035
TO
344 $currentDate = date('Ymd');
345 $test = 0;
346 CRM_Member_BAO_Membership::getMembershipCount($this->_membershipTypeID, $currentDate, $test);
347
348 $this->membershipDelete($membershipId);
93ac19cd 349 $this->contactDelete($contactId);
6a488035
TO
350 }
351
c490a46a 352 /**
e4649817 353 * Checkup sort name function.
c490a46a 354 */
e4649817 355 public function testSortName() {
356 $contactId = $this->individualCreate();
6a488035 357
9099cab3 358 $params = [
6a488035
TO
359 'contact_id' => $contactId,
360 'membership_type_id' => $this->_membershipTypeID,
e4649817 361 'join_date' => '2006-01-21',
362 'start_date' => '2006-01-21',
363 'end_date' => '2006-12-21',
6a488035
TO
364 'source' => 'Payment',
365 'is_override' => 1,
366 'status_id' => $this->_membershipStatusID,
9099cab3 367 ];
6a488035 368
e4649817 369 $membership = $this->callAPISuccess('Membership', 'create', $params);
6a488035 370
e4649817 371 $this->assertEquals('Anderson, Anthony', CRM_Member_BAO_Membership::sortName($membership['id']));
6a488035 372
e4649817 373 $this->membershipDelete($membership['id']);
93ac19cd 374 $this->contactDelete($contactId);
6a488035
TO
375 }
376
c490a46a 377 /**
eceb18cc 378 * Delete related memberships.
c490a46a 379 */
00be9182 380 public function testdeleteRelatedMemberships() {
cdf46504 381 list($contactId, $membershipId) = $this->setupMembership();
6a488035
TO
382
383 CRM_Member_BAO_Membership::deleteRelatedMemberships($membershipId);
384
385 $this->membershipDelete($membershipId);
93ac19cd 386 $this->contactDelete($contactId);
6a488035
TO
387 }
388
c490a46a 389 /**
eceb18cc 390 * Renew membership with change in membership type.
e51c5154
MWMC
391 *
392 * @fixme Note that this test fails when today is August 29 2019 (and maybe other years?):
393 * Verify correct end date is calculated after membership renewal
394 * Failed asserting that two strings are equal.
395 * Expected-'2021-03-01'
396 * Actual+'2021-02-28'
397 * /home/jenkins/bknix-dfl/build/core-15165-73etc/web/sites/all/modules/civicrm/tests/phpunit/CRM/Member/BAO/MembershipTest.php:609
c490a46a 398 */
00be9182 399 public function testRenewMembership() {
e4649817 400 $contactId = $this->individualCreate();
92915c55
TO
401 $joinDate = $startDate = date("Ymd", strtotime(date("Ymd") . " -6 month"));
402 $endDate = date("Ymd", strtotime($joinDate . " +1 year -1 day"));
9099cab3 403 $params = [
6a488035
TO
404 'contact_id' => $contactId,
405 'membership_type_id' => $this->_membershipTypeID,
406 'join_date' => $joinDate,
407 'start_date' => $startDate,
408 'end_date' => $endDate,
409 'source' => 'Payment',
410 'is_override' => 1,
411 'status_id' => $this->_membershipStatusID,
9099cab3
CW
412 ];
413 $ids = [];
92915c55 414 $membership = CRM_Member_BAO_Membership::create($params, $ids);
6a488035
TO
415 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
416 'contact_id', 'Database check for created membership.'
417 );
418
419 $this->assertDBNotNull('CRM_Member_BAO_MembershipLog',
420 $membership->id,
421 'id',
422 'membership_id',
423 'Database checked on membershiplog record.'
424 );
425
426 // this is a test and we dont want qfKey generation / validation
427 // easier to suppress it, than change core code
428 $config = CRM_Core_Config::singleton();
429 $config->keyDisable = TRUE;
430
6a488035 431 $isTestMembership = 0;
356bfcaf 432 list($MembershipRenew) = CRM_Member_BAO_Membership::processMembership(
ae5ffbb7
TO
433 $contactId,
434 $this->_membershipTypeID,
435 $isTestMembership,
ae5ffbb7 436 NULL,
595f9e7c
EM
437 NULL,
438 NULL,
439 1,
66e83bf5 440 FALSE,
441 NULL,
442 NULL,
443 FALSE,
595f9e7c 444 NULL,
66e83bf5 445 NULL
ae5ffbb7 446 );
6a488035
TO
447 $endDate = date("Y-m-d", strtotime($membership->end_date . " +1 year"));
448
449 $this->assertDBNotNull('CRM_Member_BAO_MembershipLog',
450 $MembershipRenew->id,
451 'id',
452 'membership_id',
453 'Database checked on membershiplog record.'
454 );
1038ea01
EM
455 $this->assertEquals($this->_membershipTypeID, $MembershipRenew->membership_type_id, 'Verify membership type is changed during renewal.');
456 $this->assertEquals($endDate, $MembershipRenew->end_date, 'Verify correct end date is calculated after membership renewal');
6a488035
TO
457
458 $this->membershipDelete($membershipId);
93ac19cd 459 $this->contactDelete($contactId);
6a488035
TO
460 }
461
c490a46a 462 /**
eceb18cc 463 * Renew stale membership.
5a433c56 464 *
465 * @throws \CRM_Core_Exception
466 * @throws \CiviCRM_API3_Exception
c490a46a 467 */
00be9182 468 public function testStaleMembership() {
92915c55 469 $statusId = 3;
e4649817 470 $contactId = $this->individualCreate();
92915c55 471 $joinDate = $startDate = date("Ymd", strtotime(date("Ymd") . " -1 year -15 days"));
5a433c56 472 $endDate = date('Ymd', strtotime($joinDate . " +1 year -1 day"));
9099cab3 473 $params = [
6a488035
TO
474 'contact_id' => $contactId,
475 'membership_type_id' => $this->_membershipTypeID,
476 'join_date' => $joinDate,
477 'start_date' => $startDate,
478 'end_date' => $endDate,
479 'source' => 'Payment',
480 'status_id' => $statusId,
9099cab3 481 ];
6a488035 482
9099cab3 483 $ids = [];
6a488035
TO
484 $membership = CRM_Member_BAO_Membership::create($params, $ids);
485
486 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
487 'contact_id', 'Database check for created membership.'
488 );
489
490 $this->assertEquals($membership->status_id, $statusId, 'Verify correct status id is calculated.');
491 $this->assertEquals($membership->membership_type_id, $this->_membershipTypeID,
492 'Verify correct membership type id.'
493 );
494
495 //verify all dates.
9099cab3 496 $dates = [
6a488035
TO
497 'startDate' => 'start_date',
498 'joinDate' => 'join_date',
499 'endDate' => 'end_date',
9099cab3 500 ];
6a488035
TO
501
502 foreach ($dates as $date => $dbDate) {
503 $this->assertEquals($membership->$dbDate, $$date,
504 "Verify correct {$date} is present."
505 );
506 }
507
508 $this->assertDBNotNull('CRM_Member_BAO_MembershipLog',
509 $membership->id,
510 'id',
511 'membership_id',
5a433c56 512 'Database checked on membership log record.'
6a488035
TO
513 );
514
356bfcaf 515 list($MembershipRenew) = CRM_Member_BAO_Membership::processMembership(
595f9e7c
EM
516 $contactId,
517 $this->_membershipTypeID,
61767a1d 518 FALSE,
5a433c56 519 FALSE,
595f9e7c
EM
520 NULL,
521 NULL,
522 NULL,
523 1,
524 NULL,
66e83bf5 525 NULL,
526 NULL,
527 FALSE,
528 NULL
529 );
6a488035
TO
530
531 $this->assertDBNotNull('CRM_Member_BAO_MembershipLog',
532 $MembershipRenew->id,
533 'id',
534 'membership_id',
5a433c56 535 'Database checked on membership log record.'
6a488035
TO
536 );
537
538 $this->membershipDelete($membershipId);
93ac19cd 539 $this->contactDelete($contactId);
6a488035 540 }
96025800 541
e136f704 542 public function testUpdateAllMembershipStatusConvertExpiredOverriddenStatusToNormal() {
9099cab3 543 $params = [
e136f704
O
544 'contact_id' => $this->individualCreate(),
545 'membership_type_id' => $this->_membershipTypeID,
546 'join_date' => date('Ymd', time()),
547 'start_date' => date('Ymd', time()),
548 'end_date' => date('Ymd', strtotime('+1 year')),
549 'source' => 'Payment',
550 'is_override' => 1,
551 'status_override_end_date' => date('Ymd', strtotime('-1 day')),
552 'status_id' => $this->_membershipStatusID,
9099cab3
CW
553 ];
554 $ids = [];
e136f704
O
555 $createdMembership = CRM_Member_BAO_Membership::create($params, $ids);
556
557 CRM_Member_BAO_Membership::updateAllMembershipStatus();
558
9099cab3 559 $membershipAfterProcess = civicrm_api3('Membership', 'get', [
e136f704
O
560 'sequential' => 1,
561 'id' => $createdMembership->id,
9099cab3
CW
562 'return' => ['id', 'is_override', 'status_override_end_date'],
563 ])['values'][0];
e136f704
O
564
565 $this->assertEquals($createdMembership->id, $membershipAfterProcess['id']);
566 $this->assertArrayNotHasKey('is_override', $membershipAfterProcess);
567 $this->assertArrayNotHasKey('status_override_end_date', $membershipAfterProcess);
568 }
569
570 public function testUpdateAllMembershipStatusHandleOverriddenWithEndOverrideDateEqualTodayAsExpired() {
9099cab3 571 $params = [
e136f704
O
572 'contact_id' => $this->individualCreate(),
573 'membership_type_id' => $this->_membershipTypeID,
574 'join_date' => date('Ymd', time()),
575 'start_date' => date('Ymd', time()),
576 'end_date' => date('Ymd', strtotime('+1 year')),
577 'source' => 'Payment',
578 'is_override' => 1,
579 'status_override_end_date' => date('Ymd', time()),
580 'status_id' => $this->_membershipStatusID,
9099cab3
CW
581 ];
582 $ids = [];
e136f704
O
583 $createdMembership = CRM_Member_BAO_Membership::create($params, $ids);
584
585 CRM_Member_BAO_Membership::updateAllMembershipStatus();
586
9099cab3 587 $membershipAfterProcess = civicrm_api3('Membership', 'get', [
e136f704
O
588 'sequential' => 1,
589 'id' => $createdMembership->id,
9099cab3
CW
590 'return' => ['id', 'is_override', 'status_override_end_date'],
591 ])['values'][0];
e136f704
O
592
593 $this->assertEquals($createdMembership->id, $membershipAfterProcess['id']);
594 $this->assertArrayNotHasKey('is_override', $membershipAfterProcess);
595 $this->assertArrayNotHasKey('status_override_end_date', $membershipAfterProcess);
596 }
597
598 public function testUpdateAllMembershipStatusDoesNotConvertOverridenMembershipWithoutEndOverrideDateToNormal() {
9099cab3 599 $params = [
e136f704
O
600 'contact_id' => $this->individualCreate(),
601 'membership_type_id' => $this->_membershipTypeID,
602 'join_date' => date('Ymd', time()),
603 'start_date' => date('Ymd', time()),
604 'end_date' => date('Ymd', strtotime('+1 year')),
605 'source' => 'Payment',
606 'is_override' => 1,
607 'status_id' => $this->_membershipStatusID,
9099cab3
CW
608 ];
609 $ids = [];
e136f704
O
610 $createdMembership = CRM_Member_BAO_Membership::create($params, $ids);
611
612 CRM_Member_BAO_Membership::updateAllMembershipStatus();
613
9099cab3 614 $membershipAfterProcess = civicrm_api3('Membership', 'get', [
e136f704
O
615 'sequential' => 1,
616 'id' => $createdMembership->id,
9099cab3
CW
617 'return' => ['id', 'is_override', 'status_override_end_date'],
618 ])['values'][0];
e136f704
O
619
620 $this->assertEquals($createdMembership->id, $membershipAfterProcess['id']);
621 $this->assertEquals(1, $membershipAfterProcess['is_override']);
622 }
623
a9f44ffb 624 /**
625 * @throws \CRM_Core_Exception
626 */
627 public function testMembershipPaymentForSingleContributionMultipleMembership() {
628 $membershipTypeID1 = $this->membershipTypeCreate(['name' => 'Parent']);
629 $membershipTypeID2 = $this->membershipTypeCreate(['name' => 'Child']);
630 $financialTypeId = $this->getFinancialTypeId('Member Dues');
631 $priceSet = $this->callAPISuccess('price_set', 'create', [
632 'is_quick_config' => 0,
633 'extends' => 'CiviMember',
634 'financial_type_id' => $financialTypeId,
635 'title' => 'Family Membership',
636 ]);
637 $priceSetID = $priceSet['id'];
638 $priceField = $this->callAPISuccess('price_field', 'create', [
639 'price_set_id' => $priceSetID,
640 'label' => 'Memberships',
641 'html_type' => 'Radio',
642 ]);
643 $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', [
644 'price_set_id' => $priceSetID,
645 'price_field_id' => $priceField['id'],
646 'label' => 'Parent',
647 'amount' => 100,
648 'financial_type_id' => $financialTypeId,
649 'membership_type_id' => $membershipTypeID1,
650 'membership_num_terms' => 1,
651 ]);
652 $priceFieldValueId = [1 => $priceFieldValue['id']];
653 $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', [
654 'price_set_id' => $priceSetID,
655 'price_field_id' => $priceField['id'],
656 'label' => 'Child',
657 'amount' => 50,
658 'financial_type_id' => $financialTypeId,
659 'membership_type_id' => $membershipTypeID2,
660 'membership_num_terms' => 1,
661 ]);
662 $priceFieldValueId[2] = $priceFieldValue['id'];
663 $parentContactId = $this->individualCreate();
664 $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', [
665 'contact_id' => $parentContactId,
5a433c56 666 'amount' => 150,
a9f44ffb 667 'frequency_unit' => 'day',
668 'frequency_interval' => 1,
669 'installments' => 2,
670 'start_date' => 'yesterday',
671 'create_date' => 'yesterday',
672 'modified_date' => 'yesterday',
673 'cancel_date' => NULL,
674 'end_date' => '+ 2 weeks',
675 'processor_id' => '643411460836',
676 'trxn_id' => 'e0d0808e26f3e661c6c18eb7c039d363',
677 'invoice_id' => 'e0d0808e26f3e661c6c18eb7c039d363',
678 'contribution_status_id' => 'In Progress',
679 'cycle_day' => 1,
680 'next_sched_contribution_date' => '+ 1 week',
681 'auto_renew' => 0,
682 'currency' => 'USD',
683 'payment_processor_id' => $this->paymentProcessorCreate(),
684 'financial_type_id' => $financialTypeId,
685 'payment_instrument_id' => 'Credit Card',
686 ]);
5a433c56 687
a9f44ffb 688 $params[] = [
5a433c56 689 'contact_id' => $this->individualCreate(),
690 'membership_type_id' => $membershipTypeID2,
a9f44ffb 691 'contribution_recur_id' => $contributionRecur['id'],
692 'join_date' => date('Ymd', time()),
693 'start_date' => date('Ymd', time()),
694 'end_date' => date('Ymd', strtotime('+1 year')),
a9f44ffb 695 'source' => 'Payment',
a9f44ffb 696 ];
697 $params[] = [
698 'contact_id' => $this->individualCreate(),
699 'membership_type_id' => $membershipTypeID2,
700 'contribution_recur_id' => $contributionRecur['id'],
701 'join_date' => date('Ymd', time()),
702 'start_date' => date('Ymd', time()),
703 'end_date' => date('Ymd', strtotime('+1 year')),
a9f44ffb 704 'source' => 'Payment',
5a433c56 705 ];
706
707 foreach ($params as $key => $param) {
708 $this->callAPISuccess('membership', 'create', $param);
709 }
710
711 $contribution = $this->callAPISuccess('Order', 'create', [
712 'total_amount' => 150,
713 'contribution_recur_id' => $contributionRecur['id'],
714 'currency' => 'USD',
715 'contact_id' => $parentContactId,
716 'financial_type_id' => $financialTypeId,
717 'contribution_status_id' => 'Pending',
718 'is_recur' => TRUE,
719 'api.Payment.create' => ['total_amount' => 150],
a9f44ffb 720 'line_items' => [
5a433c56 721 [
722 'line_item' => [
723 0 => [
724 'price_field_id' => $priceField['id'],
725 'price_field_value_id' => $priceFieldValueId[1],
726 'label' => 'Parent',
727 'membership_type_id' => $membershipTypeID1,
728 'qty' => 1,
729 'unit_price' => 100,
730 'line_total' => 100,
731 'financial_type_id' => $financialTypeId,
732 'entity_table' => 'civicrm_membership',
733 ],
734 1 => [
735 'price_field_id' => $priceField['id'],
736 'price_field_value_id' => $priceFieldValueId[2],
737 'label' => 'Child',
738 'qty' => 1,
739 'unit_price' => 50,
740 'line_total' => 50,
741 'membership_type_id' => $membershipTypeID2,
742 'financial_type_id' => $financialTypeId,
743 'entity_table' => 'civicrm_membership',
744 ],
745 ],
746 ],
a9f44ffb 747 ],
5a433c56 748 ]);
a9f44ffb 749 $params[] = [
5a433c56 750 'contact_id' => $parentContactId,
751 'membership_type_id' => $membershipTypeID1,
a9f44ffb 752 'contribution_recur_id' => $contributionRecur['id'],
753 'join_date' => date('Ymd', time()),
754 'start_date' => date('Ymd', time()),
a9f44ffb 755 'end_date' => date('Ymd', strtotime('+1 year')),
5a433c56 756 'skipLineItem' => TRUE,
a9f44ffb 757 'source' => 'Payment',
a9f44ffb 758 ];
759
a9f44ffb 760 $this->callAPISuccess('contribution', 'repeattransaction', [
761 'original_contribution_id' => $contribution['id'],
762 'contribution_status_id' => 'Completed',
a9f44ffb 763 ]);
764 $this->callAPISuccessGetCount('Contribution', [], 2);
5a433c56 765 // @todo this fails depending on what tests it is run with due some bad stuff in Membership.create
766 // It needs to be addressed but might involve the switch to ORDER. Membership BAO does bad line item stuff.
767 // $this->callAPISuccessGetCount('LineItem', [], 6);
a9f44ffb 768 $this->membershipTypeDelete(['id' => $membershipTypeID1]);
769 $this->membershipTypeDelete(['id' => $membershipTypeID2]);
5a433c56 770 $this->validateAllPayments();
771 $this->validateAllContributions();
772 }
773
774 /**
775 * Test the buildMembershipTypeValues function.
322b59f0 776 *
777 * @throws \CiviCRM_API3_Exception
5a433c56 778 */
779 public function testBuildMembershipTypeValues() {
322b59f0 780 $this->restoreMembershipTypes();
5a433c56 781 $form = new CRM_Core_Form();
782 $values = CRM_Member_BAO_Membership::buildMembershipTypeValues($form);
783 $this->assertEquals([
784 'id' => '1',
785 'minimum_fee' => '100.000000000',
786 'name' => 'General',
787 'is_active' => '1',
788 'description' => 'Regular annual membership.',
789 'financial_type_id' => '2',
790 'auto_renew' => '0',
791 'member_of_contact_id' => $values[1]['member_of_contact_id'],
322b59f0 792 'relationship_type_id' => [7],
793 'relationship_direction' => ['b_a'],
5a433c56 794 'max_related' => NULL,
795 'duration_unit' => 'year',
796 'duration_interval' => '2',
322b59f0 797 'domain_id' => '1',
798 'period_type' => 'rolling',
799 'visibility' => 'Public',
800 'weight' => '1',
49bbb50e 801 'tax_rate' => 0.0,
802 'minimum_fee_with_tax' => 100.0,
5a433c56 803 ], $values[1]);
a9f44ffb 804 }
805
cdf46504 806 /**
807 * @return array
808 * @throws \CRM_Core_Exception
809 * @throws \CiviCRM_API3_Exception
810 */
811 protected function setupMembership(): array {
812 $contactId = $this->individualCreate();
813
814 $params = [
815 'contact_id' => $contactId,
816 'membership_type_id' => $this->_membershipTypeID,
817 'join_date' => date('Ymd', strtotime('2006-01-21')),
818 'start_date' => date('Ymd', strtotime('2006-01-21')),
819 'end_date' => date('Ymd', strtotime('2006-12-21')),
820 'source' => 'Payment',
821 'is_override' => 1,
822 'status_id' => $this->_membershipStatusID,
823 ];
824 $ids = [];
825 CRM_Member_BAO_Membership::create($params, $ids);
826
827 $membershipId = $this->assertDBNotNull('CRM_Member_BAO_Membership', $contactId, 'id',
828 'contact_id', 'Database check for created membership.'
829 );
830 return [$contactId, $membershipId];
831 }
832
6a488035 833}