Commit | Line | Data |
---|---|---|
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 | 16 | class 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 | } |