Merge pull request #12178 from jitendrapurohit/membership-4
[civicrm-core.git] / tests / phpunit / api / v3 / MembershipTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
2fe49090 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
8c9251b3 6 | Copyright CiviCRM LLC (c) 2004-2018 |
6a488035
TO
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 */
6a488035
TO
27
28/**
29 * Test APIv3 civicrm_membership functions
30 *
6c6e6187
TO
31 * @package CiviCRM_APIv3
32 * @subpackage API_Member
6a488035
TO
33 */
34
4cbe18b8
EM
35/**
36 * Class api_v3_MembershipTest
acb109b7 37 * @group headless
4cbe18b8 38 */
6a488035
TO
39class api_v3_MembershipTest extends CiviUnitTestCase {
40 protected $_apiversion;
41 protected $_contactID;
d54576ed
EM
42 protected $_membershipID;
43 protected $_membershipID2;
44 protected $_membershipID3;
6a488035 45 protected $_membershipTypeID;
8c33a68c 46 protected $_membershipTypeID2;
6a488035 47 protected $_membershipStatusID;
6a488035
TO
48 protected $_entity;
49 protected $_params;
b7c9bc4c 50
80d714d2 51 /**
52 * Set up for tests.
53 */
6a488035 54 public function setUp() {
6a488035
TO
55 parent::setUp();
56 $this->_apiversion = 3;
57 $this->_contactID = $this->individualCreate();
75638074 58 $this->_membershipTypeID = $this->membershipTypeCreate(array('member_of_contact_id' => $this->_contactID));
5896d037
TO
59 $this->_membershipTypeID2 = $this->membershipTypeCreate(array(
60 'period_type' => 'fixed',
2ea0abec 61 // Ie. 1 March.
5896d037 62 'fixed_period_start_day' => '301',
2ea0abec 63 // Ie. 11 Nov.
21dfd5f5 64 'fixed_period_rollover_day' => '1111',
5d8b37be 65 'name' => 'Another one',
5896d037 66 ));
6a488035
TO
67 $this->_membershipStatusID = $this->membershipStatusCreate('test status');
68
6a488035
TO
69 CRM_Member_PseudoConstant::membershipType(NULL, TRUE);
70 CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'name', TRUE);
71 CRM_Core_PseudoConstant::activityType(TRUE, TRUE, TRUE, 'name');
72
73 $this->_entity = 'Membership';
74 $this->_params = array(
75 'contact_id' => $this->_contactID,
76 'membership_type_id' => $this->_membershipTypeID,
77 'join_date' => '2009-01-21',
78 'start_date' => '2009-01-21',
79 'end_date' => '2009-12-21',
80 'source' => 'Payment',
81 'is_override' => 1,
82 'status_id' => $this->_membershipStatusID,
6a488035
TO
83 );
84 }
85
80d714d2 86 /**
87 * Clean up after tests.
88 *
89 * @throws \Exception
90 */
00be9182 91 public function tearDown() {
6a488035 92 $this->quickCleanup(array(
5896d037
TO
93 'civicrm_membership',
94 'civicrm_membership_payment',
95 'civicrm_membership_log',
c277e79e 96 'civicrm_uf_match',
771f3245 97 ),
98 TRUE
6a488035
TO
99 );
100 $this->membershipStatusDelete($this->_membershipStatusID);
8c33a68c 101 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID2));
6a488035
TO
102 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID));
103 $this->contactDelete($this->_contactID);
104
105 }
106
107 /**
2ea0abec 108 * Test membership deletion.
6a488035 109 */
00be9182 110 public function testMembershipDelete() {
6a488035 111 $membershipID = $this->contactMembershipCreate($this->_params);
3506b6cd 112 $this->assertDBRowExist('CRM_Member_DAO_Membership', $membershipID);
6a488035 113 $params = array(
21dfd5f5 114 'id' => $membershipID,
6a488035 115 );
d54576ed 116 $this->callAPIAndDocument('membership', 'delete', $params, __FUNCTION__, __FILE__);
3506b6cd 117 $this->assertDBRowNotExist('CRM_Member_DAO_Membership', $membershipID);
6a488035
TO
118 }
119
00be9182 120 public function testMembershipDeleteEmpty() {
d54576ed 121 $this->callAPIFailure('membership', 'delete', array());
6a488035
TO
122 }
123
00be9182 124 public function testMembershipDeleteInvalidID() {
d54576ed 125 $this->callAPIFailure('membership', 'delete', array('id' => 'blah'));
6a488035
TO
126 }
127
128 /**
2ea0abec 129 * Test civicrm_membership_delete() with invalid Membership Id.
6a488035 130 */
00be9182 131 public function testMembershipDeleteWithInvalidMembershipId() {
6a488035 132 $membershipId = 'membership';
d54576ed 133 $this->callAPIFailure('membership', 'delete', $membershipId);
6a488035
TO
134 }
135
ed4cc29d
JT
136 /**
137 * Test membership deletion and with the preserve contribution param.
138 */
139 public function testMembershipDeletePreserveContribution() {
140 $membershipID = $this->contactMembershipCreate($this->_params); //DELETE
141 $this->assertDBRowExist('CRM_Member_DAO_Membership', $membershipID); //DELETE
142 $ContributionCreate = $this->callAPISuccess('Contribution', 'create', array(
143 'sequential' => 1,
144 'financial_type_id' => "Member Dues",
145 'total_amount' => 100,
146 'contact_id' => $this->_params['contact_id'],
147 ));
148 $membershipPaymentCreate = $this->callAPISuccess('MembershipPayment', 'create', array(
149 'sequential' => 1,
150 'contribution_id' => $ContributionCreate['values'][0]['id'],
151 'membership_id' => $membershipID,
152 ));
153 $memParams = array(
154 'id' => $membershipID,
155 'preserve_contribution' => 1,
156 );
157 $contribParams = array(
158 'id' => $ContributionCreate['values'][0]['id'],
159 );
160 $this->callAPIAndDocument('membership', 'delete', $memParams, __FUNCTION__, __FILE__);
161 $this->assertDBRowNotExist('CRM_Member_DAO_Membership', $membershipID);
162 $this->assertDBRowExist('CRM_Contribute_DAO_Contribution', $ContributionCreate['values'][0]['id']);
163 $this->callAPISuccess('Contribution', 'delete', $contribParams);
164 $this->assertDBRowNotExist('CRM_Contribute_DAO_Contribution', $ContributionCreate['values'][0]['id']);
165 }
166
c277e79e
JP
167 /**
168 * Test Activity creation on cancellation of membership contribution.
169 */
170 public function testActivityForCancelledContribution() {
171 $contactId = $this->createLoggedInUser();
172 $membershipID = $this->contactMembershipCreate($this->_params);
173 $this->assertDBRowExist('CRM_Member_DAO_Membership', $membershipID);
174
175 $ContributionCreate = $this->callAPISuccess('Contribution', 'create', array(
176 'financial_type_id' => "Member Dues",
177 'total_amount' => 100,
178 'contact_id' => $this->_params['contact_id'],
179 ));
180 $membershipPaymentCreate = $this->callAPISuccess('MembershipPayment', 'create', array(
181 'sequential' => 1,
182 'contribution_id' => $ContributionCreate['id'],
183 'membership_id' => $membershipID,
184 ));
185 $instruments = $this->callAPISuccess('contribution', 'getoptions', array('field' => 'payment_instrument_id'));
186 $this->paymentInstruments = $instruments['values'];
187
188 $form = new CRM_Contribute_Form_Contribution();
189 $form->_id = $ContributionCreate['id'];
190 $form->testSubmit(array(
191 'total_amount' => 100,
192 'financial_type_id' => 1,
c277e79e
JP
193 'contact_id' => $contactId,
194 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
195 'contribution_status_id' => 3,
196 ),
197 CRM_Core_Action::UPDATE);
198
199 $activity = $this->callAPISuccess('Activity', 'get', array(
200 'activity_type_id' => "Change Membership Status",
201 'source_record_id' => $membershipID,
202 ));
203 $this->assertNotEmpty($activity['values']);
204 }
205
6a488035 206 /**
2ea0abec 207 * Test membership get.
6a488035 208 */
00be9182 209 public function testContactMembershipsGet() {
6a488035 210 $this->_membershipID = $this->contactMembershipCreate($this->_params);
2ea0abec 211 $this->callAPISuccess('membership', 'get', array());
6c6e6187 212 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
6a488035
TO
213 }
214
215 /**
216 * Test civicrm_membership_get with params not array.
2ea0abec 217 *
6a488035
TO
218 * Gets treated as contact_id, memberships expected.
219 */
00be9182 220 public function testGetWithParamsContactId() {
6a488035
TO
221 $this->_membershipID = $this->contactMembershipCreate($this->_params);
222 $params = array(
223 'contact_id' => $this->_contactID,
6a488035 224 );
771f3245 225 $membership = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
226
227 $result = $membership['values'][$this->_membershipID];
771f3245 228 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 229 'id' => $this->_membershipID,
5896d037 230 ));
6a488035
TO
231 $this->assertEquals($result['contact_id'], $this->_contactID, "In line " . __LINE__);
232 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID, "In line " . __LINE__);
233 $this->assertEquals($result['status_id'], $this->_membershipStatusID, "In line " . __LINE__);
234 $this->assertEquals($result['join_date'], '2009-01-21', "In line " . __LINE__);
235 $this->assertEquals($result['start_date'], '2009-01-21', "In line " . __LINE__);
236 $this->assertEquals($result['end_date'], '2009-12-21', "In line " . __LINE__);
237 $this->assertEquals($result['source'], 'Payment', "In line " . __LINE__);
238 $this->assertEquals($result['is_override'], 1, "In line " . __LINE__);
239 }
240
b4529041 241 /**
242 * Test civicrm_membership_get with params not array.
2ea0abec 243 *
b4529041 244 * Gets treated as contact_id, memberships expected.
245 */
00be9182 246 public function testGetInSyntax() {
b4529041 247 $this->_membershipID = $this->contactMembershipCreate($this->_params);
248 $this->_membershipID2 = $this->contactMembershipCreate($this->_params);
249 $this->_membershipID3 = $this->contactMembershipCreate($this->_params);
250 $params = array(
251 'id' => array('IN' => array($this->_membershipID, $this->_membershipID3)),
252 );
253 $membership = $this->callAPISuccess('membership', 'get', $params);
254 $this->assertEquals(2, $membership['count']);
255 $this->assertEquals(array($this->_membershipID, $this->_membershipID3), array_keys($membership['values']));
256 $params = array(
257 'id' => array('NOT IN' => array($this->_membershipID, $this->_membershipID3)),
258 );
259 $membership = $this->callAPISuccess('membership', 'get', $params);
260 $this->assertEquals(1, $membership['count']);
261 $this->assertEquals(array($this->_membershipID2), array_keys($membership['values']));
b4529041 262 }
263
caca32ba 264 /**
265 * Test civicrm_membership_get with params not array.
266 * Gets treated as contact_id, memberships expected.
267 */
00be9182 268 public function testGetInSyntaxOnContactID() {
caca32ba 269 $this->_membershipID = $this->contactMembershipCreate($this->_params);
270 $contact2 = $this->individualCreate();
271 $contact3 = $this->individualCreate(array('first_name' => 'Scout', 'last_name' => 'Canine'));
272 $this->_membershipID2 = $this->contactMembershipCreate(array_merge($this->_params, array('contact_id' => $contact2)));
273 $this->_membershipID3 = $this->contactMembershipCreate(array_merge($this->_params, array('contact_id' => $contact3)));
274 $params = array(
275 'contact_id' => array('IN' => array($this->_contactID, $contact3)),
276 );
277 $membership = $this->callAPISuccess('membership', 'get', $params);
278 $this->assertEquals(2, $membership['count']);
279 $this->assertEquals(array($this->_membershipID, $this->_membershipID3), array_keys($membership['values']));
280 $params = array(
281 'contact_id' => array('NOT IN' => array($this->_contactID, $contact3)),
282 );
283 $membership = $this->callAPISuccess('membership', 'get', $params);
284 $this->assertEquals(1, $membership['count']);
285 $this->assertEquals(array($this->_membershipID2), array_keys($membership['values']));
286 }
5896d037 287
caca32ba 288 /**
289 * Test civicrm_membership_get with params not array.
80d714d2 290 *
caca32ba 291 * Gets treated as contact_id, memberships expected.
292 */
00be9182 293 public function testGetWithParamsMemberShipTypeId() {
d54576ed 294 $this->callAPISuccess($this->_entity, 'create', $this->_params);
6a488035
TO
295 $params = array(
296 'membership_type_id' => $this->_membershipTypeID,
6a488035 297 );
771f3245 298 $membership = $this->callAPISuccess('membership', 'get', $params);
d54576ed 299 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 300 'id' => $membership['id'],
771f3245 301 ));
6a488035 302 $result = $membership['values'][$membership['id']];
80d714d2 303 $this->assertEquals($result['contact_id'], $this->_contactID);
304 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID);
305 $this->assertEquals($result['status_id'], $this->_membershipStatusID);
306 $this->assertEquals($result['join_date'], '2009-01-21');
307 $this->assertEquals($result['start_date'], '2009-01-21');
308 $this->assertEquals($result['end_date'], '2009-12-21');
309 $this->assertEquals($result['source'], 'Payment');
310 $this->assertEquals($result['is_override'], 1);
6a488035
TO
311 $this->assertEquals($result['id'], $membership['id']);
312 }
5896d037 313
a73daeff
E
314 /**
315 * Test civicrm_membership_get with params not array.
316 * Gets treated as contact_id, memberships expected.
317 */
00be9182 318 public function testGetWithParamsMemberShipTypeIdContactID() {
a73daeff
E
319 $params = $this->_params;
320 $this->callAPISuccess($this->_entity, 'create', $params);
321 $params['membership_type_id'] = $this->_membershipTypeID2;
322 $this->callAPISuccess($this->_entity, 'create', $params);
323 $this->callAPISuccessGetCount('membership', array('contact_id' => $this->_contactID), 2);
324 $params = array(
325 'membership_type_id' => $this->_membershipTypeID,
326 'contact_id' => $this->_contactID,
327 );
328 $result = $this->callAPISuccess('membership', 'getsingle', $params);
329 $this->assertEquals($result['contact_id'], $this->_contactID);
330 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID);
6a488035 331
a73daeff
E
332 $params = array(
333 'membership_type_id' => $this->_membershipTypeID2,
334 'contact_id' => $this->_contactID,
335 );
336 $result = $this->callAPISuccess('membership', 'getsingle', $params);
337 $this->assertEquals($result['contact_id'], $this->_contactID);
338 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID2);
339 }
5896d037 340
6a488035 341 /**
80d714d2 342 * Check with complete array + custom field.
343 *
6a488035
TO
344 * Note that the test is written on purpose without any
345 * variables specific to participant so it can be replicated into other entities
346 * and / or moved to the automated test suite
347 */
00be9182 348 public function testGetWithParamsMemberShipIdAndCustom() {
6a488035
TO
349 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
350
351 $params = $this->_params;
352 $params['custom_' . $ids['custom_field_id']] = "custom string";
353
771f3245 354 $result = $this->callAPISuccess($this->_entity, 'create', $params);
6a488035 355
771f3245 356 $getParams = array('membership_type_id' => $params['membership_type_id']);
357 $check = $this->callAPIAndDocument($this->_entity, 'get', $getParams, __FUNCTION__, __FILE__);
6a488035
TO
358 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
359
d54576ed 360 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 361 'id' => $result['id'],
771f3245 362 ));
6a488035
TO
363 }
364
365 /**
366 * Test civicrm_membership_get with proper params.
367 * Memberships expected.
368 */
00be9182 369 public function testGet() {
6a488035
TO
370 $membershipID = $this->contactMembershipCreate($this->_params);
371 $params = array(
372 'contact_id' => $this->_contactID,
6a488035
TO
373 );
374
771f3245 375 $membership = $this->callAPISuccess('membership', 'get', $params);
6a488035 376 $result = $membership['values'][$membershipID];
771f3245 377 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 378 'id' => $membership['id'],
771f3245 379 ));
80d714d2 380 $this->assertEquals($result['join_date'], '2009-01-21');
381 $this->assertEquals($result['contact_id'], $this->_contactID);
382 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID);
383 $this->assertEquals($result['status_id'], $this->_membershipStatusID);
6a488035 384
80d714d2 385 $this->assertEquals($result['start_date'], '2009-01-21');
386 $this->assertEquals($result['end_date'], '2009-12-21');
387 $this->assertEquals($result['source'], 'Payment');
388 $this->assertEquals($result['is_override'], 1);
6a488035
TO
389 }
390
391
392 /**
393 * Test civicrm_membership_get with proper params.
394 * Memberships expected.
395 */
00be9182 396 public function testGetWithId() {
6a488035
TO
397 $membershipID = $this->contactMembershipCreate($this->_params);
398 $params = array(
399 'contact_id' => $this->_contactID,
d54576ed 400 'id' => $this->_membershipID,
6a488035
TO
401 'return' => 'id',
402 );
771f3245 403 $result = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
404 $this->assertEquals($membershipID, $result['id']);
405 $params = array(
406 'contact_id' => $this->_contactID,
d54576ed 407 'membership_id' => $this->_membershipID,
6a488035
TO
408 'return' => 'membership_id',
409 );
771f3245 410 $result = $this->callAPISuccess('membership', 'get', $params);
6a488035 411 $this->assertEquals($membershipID, $result['id']);
6a488035
TO
412 }
413
414 /**
415 * Test civicrm_membership_get for only active.
416 * Memberships expected.
417 */
00be9182 418 public function testGetOnlyActive() {
5c49fee0 419 $description = "Demonstrates use of 'filter' active_only' param.";
6a488035 420 $this->_membershipID = $this->contactMembershipCreate($this->_params);
5896d037 421 $params = array(
6a488035
TO
422 'contact_id' => $this->_contactID,
423 'active_only' => 1,
6a488035
TO
424 );
425
771f3245 426 $membership = $this->callAPISuccess('membership', 'get', $params);
a73daeff
E
427 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
428 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
6a488035
TO
429 $params = array(
430 'contact_id' => $this->_contactID,
431 'filters' => array(
432 'is_current' => 1,
433 ),
6a488035
TO
434 );
435
a828d7b8 436 $membership = $this->callAPIAndDocument('membership', 'get', $params, __FUNCTION__, __FILE__, $description, 'FilterIsCurrent');
a73daeff
E
437 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
438 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
6a488035 439
6c6e6187 440 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
6a488035
TO
441 }
442
443 /**
444 * Test civicrm_membership_get for non exist contact.
445 * empty Memberships.
446 */
00be9182 447 public function testGetNoContactExists() {
6a488035
TO
448 $params = array(
449 'contact_id' => 55555,
6a488035
TO
450 );
451
771f3245 452 $membership = $this->callAPISuccess('membership', 'get', $params);
80d714d2 453 $this->assertEquals($membership['count'], 0);
6a488035
TO
454 }
455
456 /**
457 * Test civicrm_membership_get with relationship.
458 * get Memberships.
459 */
00be9182 460 public function testGetWithRelationship() {
6a488035 461 $membershipOrgId = $this->organizationCreate(NULL);
e4d5f1e2 462 $memberContactId = $this->individualCreate();
6a488035
TO
463
464 $relTypeParams = array(
465 'name_a_b' => 'Relation 1',
466 'name_b_a' => 'Relation 2',
467 'description' => 'Testing relationship type',
468 'contact_type_a' => 'Organization',
469 'contact_type_b' => 'Individual',
470 'is_reserved' => 1,
471 'is_active' => 1,
6a488035
TO
472 );
473 $relTypeID = $this->relationshipTypeCreate($relTypeParams);
474
475 $params = array(
476 'name' => 'test General',
477 'duration_unit' => 'year',
478 'duration_interval' => 1,
479 'period_type' => 'rolling',
480 'member_of_contact_id' => $membershipOrgId,
481 'domain_id' => 1,
5896d037 482 'financial_type_id' => 1,
6a488035
TO
483 'relationship_type_id' => $relTypeID,
484 'relationship_direction' => 'b_a',
485 'is_active' => 1,
6a488035 486 );
771f3245 487 $memType = $this->callAPISuccess('membership_type', 'create', $params);
6a488035
TO
488
489 $params = array(
490 'contact_id' => $memberContactId,
491 'membership_type_id' => $memType['id'],
492 'join_date' => '2009-01-21',
493 'start_date' => '2009-01-21',
494 'end_date' => '2009-12-21',
495 'source' => 'Payment',
496 'is_override' => 1,
497 'status_id' => $this->_membershipStatusID,
6a488035
TO
498 );
499 $membershipID = $this->contactMembershipCreate($params);
500
501 $params = array(
502 'contact_id' => $memberContactId,
503 'membership_type_id' => $memType['id'],
6a488035
TO
504 );
505
771f3245 506 $result = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
507
508 $membership = $result['values'][$membershipID];
771f3245 509 $this->assertEquals($this->_membershipStatusID, $membership['status_id']);
d54576ed 510 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 511 'id' => $membership['id'],
5896d037 512 ));
6a488035
TO
513 $this->membershipTypeDelete(array('id' => $memType['id']));
514 $this->relationshipTypeDelete($relTypeID);
515 $this->contactDelete($membershipOrgId);
516 $this->contactDelete($memberContactId);
517 }
518
4cc99d00 519 /**
520 * Test civicrm_membership_create with relationships.
521 * create/get Memberships.
522 *
523 * Test suite for CRM-14758: API ( contact, create ) does not always create related membership
524 * and max_related property for Membership_Type and Membership entities
525 */
00be9182 526 public function testCreateWithRelationship() {
4cc99d00 527 // Create membership type: inherited through employment, max_related = 2
528 $params = array(
529 'name_a_b' => 'Employee of',
530 );
531 $result = $this->callAPISuccess('relationship_type', 'get', $params);
532 $relationshipTypeId = $result['id'];
533 $membershipOrgId = $this->organizationCreate();
534 $params = array(
535 'name' => 'Corporate Membership',
536 'duration_unit' => 'year',
537 'duration_interval' => 1,
538 'period_type' => 'rolling',
539 'member_of_contact_id' => $membershipOrgId,
540 'domain_id' => 1,
541 'financial_type_id' => 1,
542 'relationship_type_id' => $relationshipTypeId,
543 'relationship_direction' => 'b_a',
544 'max_related' => 2,
545 'is_active' => 1,
546 );
547 $result = $this->callAPISuccess('membership_type', 'create', $params);
548 $membershipTypeId = $result['id'];
549
550 // Create employer and first employee
551 $employerId[0] = $this->organizationCreate(array(), 1);
552 $memberContactId[0] = $this->individualCreate(array('employer_id' => $employerId[0]), 0);
553
554 // Create organization's membership
555 $params = array(
556 'contact_id' => $employerId[0],
557 'membership_type_id' => $membershipTypeId,
558 'source' => 'Test suite',
559 'start_date' => date('Y-m-d'),
560 'end_date' => "+1 year",
561 );
562 $OrganizationMembershipID = $this->contactMembershipCreate($params);
563
564 // Check that the employee inherited the membership
565 $params = array(
566 'contact_id' => $memberContactId[0],
567 'membership_type_id' => $membershipTypeId,
568 );
569
570 $result = $this->callAPISuccess('membership', 'get', $params);
571
572 $this->assertEquals(1, $result['count']);
573 $result = $result['values'][$result['id']];
574 $this->assertEquals($OrganizationMembershipID, $result['owner_membership_id']);
575
576 // Create second employee
577 $memberContactId[1] = $this->individualCreate(array('employer_id' => $employerId[0]), 1);
578
579 // Check that the employee inherited the membership
580 $params = array(
581 'contact_id' => $memberContactId[1],
582 'membership_type_id' => $membershipTypeId,
583 );
584 $result = $this->callAPISuccess('membership', 'get', $params);
4cc99d00 585 // If it fails here CRM-14758 is not fixed
586 $this->assertEquals(1, $result['count']);
587 $result = $result['values'][$result['id']];
588 $this->assertEquals($OrganizationMembershipID, $result['owner_membership_id']);
589
590 // Create third employee
932a6904 591 $memberContactId[2] = $this->individualCreate(array('employer_id' => $employerId[0]), 2);
4cc99d00 592
593 // Check that employee does NOT inherit the membership (max_related = 2)
594 $params = array(
595 'contact_id' => $memberContactId[2],
596 'membership_type_id' => $membershipTypeId,
597 );
598 $result = $this->callAPISuccess('membership', 'get', $params);
599 $this->assertEquals(0, $result['count']);
600
601 // Increase max_related for the employer's membership
602 $params = array(
603 'id' => $OrganizationMembershipID,
604 'max_related' => 3,
605 );
5d8b37be 606 $this->callAPISuccess('Membership', 'create', $params);
4cc99d00 607
608 // Check that the employee inherited the membership
609 $params = array(
610 'contact_id' => $memberContactId[2],
611 'membership_type_id' => $membershipTypeId,
612 );
613 $result = $this->callAPISuccess('membership', 'get', $params);
614 $this->assertEquals(1, $result['count']);
615 $result = $result['values'][$result['id']];
616 $this->assertEquals($OrganizationMembershipID, $result['owner_membership_id']);
617
618 // First employee moves to a new job
619 $employerId[1] = $this->organizationCreate(array(), 2);
620 $params = array(
621 'id' => $memberContactId[0],
622 'employer_id' => $employerId[1],
623 );
624 $this->callAPISuccess('contact', 'create', $params);
625
626 // Check that employee does NO LONGER inherit the membership
627 $params = array(
628 'contact_id' => $memberContactId[0],
629 'membership_type_id' => $membershipTypeId,
630 );
631 $result = $this->callAPISuccess('membership', 'get', $params);
632 $this->assertEquals(0, $result['count']);
633
00538ec6
JP
634 //Create pay_later membership for organization.
635 $employerId[2] = $this->organizationCreate(array(), 1);
636 $params = array(
637 'contact_id' => $employerId[2],
638 'membership_type_id' => $membershipTypeId,
639 'source' => 'Test pay later suite',
640 'is_pay_later' => 1,
641 'status_id' => 5,
642 );
643 $organizationMembership = CRM_Member_BAO_Membership::add($params);
644 $organizationMembershipID = $organizationMembership->id;
645 $memberContactId[3] = $this->individualCreate(array('employer_id' => $employerId[2]), 0);
646 // Check that the employee inherited the membership
647 $params = array(
648 'contact_id' => $memberContactId[3],
649 'membership_type_id' => $membershipTypeId,
650 );
651 $result = $this->callAPISuccess('membership', 'get', $params);
652 $this->assertEquals(1, $result['count']);
653 $result = $result['values'][$result['id']];
654 $this->assertEquals($organizationMembershipID, $result['owner_membership_id']);
655
4a009ccf
CW
656 // Set up params for enable/disable checks
657 $relationship1 = $this->callAPISuccess('relationship', 'get', array('contact_id_a' => $memberContactId[1]));
658 $params = array(
659 'contact_id' => $memberContactId[1],
660 'membership_type_id' => $membershipTypeId,
661 );
662
663 // Deactivate relationship using create and assert membership is not inherited
664 $this->callAPISuccess('relationship', 'create', array('id' => $relationship1['id'], 'is_active' => 0));
665 $result = $this->callAPISuccess('membership', 'get', $params);
666 $this->assertEquals(0, $result['count']);
667
668 // Re-enable relationship using create and assert membership is inherited
669 $this->callAPISuccess('relationship', 'create', array('id' => $relationship1['id'], 'is_active' => 1));
670 $result = $this->callAPISuccess('membership', 'get', $params);
671 $this->assertEquals(1, $result['count']);
672
673 // Deactivate relationship using setvalue and assert membership is not inherited
674 $this->callAPISuccess('relationship', 'setvalue', array('id' => $relationship1['id'], 'field' => 'is_active', 'value' => 0));
675 $result = $this->callAPISuccess('membership', 'get', $params);
676 $this->assertEquals(0, $result['count']);
677
678 // Re-enable relationship using setvalue and assert membership is inherited
679 $this->callAPISuccess('relationship', 'setvalue', array('id' => $relationship1['id'], 'field' => 'is_active', 'value' => 1));
680 $result = $this->callAPISuccess('membership', 'get', $params);
681 $this->assertEquals(1, $result['count']);
682
1b5fad8a
CW
683 // Delete relationship and assert membership is not inherited
684 $this->callAPISuccess('relationship', 'delete', array('id' => $relationship1['id']));
685 $result = $this->callAPISuccess('membership', 'get', $params);
686 $this->assertEquals(0, $result['count']);
687
4cc99d00 688 // Tear down - reverse of creation to be safe
689 $this->contactDelete($memberContactId[2]);
690 $this->contactDelete($memberContactId[1]);
691 $this->contactDelete($memberContactId[0]);
692 $this->contactDelete($employerId[1]);
693 $this->contactDelete($employerId[0]);
694 $this->membershipTypeDelete(array('id' => $membershipTypeId));
695 $this->contactDelete($membershipOrgId);
696 }
697
37eda84b 698 /**
0298287b 699 * We are checking for no e-notices + only id & end_date returned
37eda84b 700 */
00be9182 701 public function testMembershipGetWithReturn() {
d54576ed 702 $this->contactMembershipCreate($this->_params);
37eda84b 703 $result = $this->callAPISuccess('membership', 'get', array('return' => 'end_date'));
6c6e6187 704 foreach ($result['values'] as $membership) {
0248c335 705 $this->assertEquals(array('id', 'end_date'), array_keys($membership));
37eda84b 706 }
707 }
6a488035
TO
708 ///////////////// civicrm_membership_create methods
709
710 /**
711 * Test civicrm_contact_memberships_create with empty params.
712 * Error expected.
713 */
00be9182 714 public function testCreateWithEmptyParams() {
6a488035 715 $params = array();
d54576ed 716 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
717 }
718
719 /**
fe482240 720 * If is_overide is passed in status must also be passed in.
6a488035 721 */
00be9182 722 public function testCreateOverrideNoStatus() {
6a488035
TO
723 $params = $this->_params;
724 unset($params['status_id']);
d54576ed 725 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
726 }
727
00be9182 728 public function testMembershipCreateMissingRequired() {
6a488035
TO
729 $params = array(
730 'membership_type_id' => '1',
731 'join_date' => '2006-01-21',
732 'start_date' => '2006-01-21',
733 'end_date' => '2006-12-21',
734 'source' => 'Payment',
735 'status_id' => '2',
6a488035
TO
736 );
737
d54576ed 738 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
739 }
740
00be9182 741 public function testMembershipCreate() {
6a488035
TO
742 $params = array(
743 'contact_id' => $this->_contactID,
744 'membership_type_id' => $this->_membershipTypeID,
745 'join_date' => '2006-01-21',
746 'start_date' => '2006-01-21',
747 'end_date' => '2006-12-21',
748 'source' => 'Payment',
749 'is_override' => 1,
750 'status_id' => $this->_membershipStatusID,
6a488035
TO
751 );
752
771f3245 753 $result = $this->callAPIAndDocument('membership', 'create', $params, __FUNCTION__, __FILE__);
6a488035 754 $this->getAndCheck($params, $result['id'], $this->_entity);
6a488035
TO
755 $this->assertNotNull($result['id']);
756 $this->assertEquals($this->_contactID, $result['values'][$result['id']]['contact_id'], " in line " . __LINE__);
757 $this->assertEquals($result['id'], $result['values'][$result['id']]['id'], " in line " . __LINE__);
758 }
5896d037 759
28a04ea9 760 /**
761 * Check for useful message if contact doesn't exist
762 */
00be9182 763 public function testMembershipCreateWithInvalidContact() {
6a488035
TO
764 $params = array(
765 'contact_id' => 999,
766 'membership_type_id' => $this->_membershipTypeID,
767 'join_date' => '2006-01-21',
768 'start_date' => '2006-01-21',
769 'end_date' => '2006-12-21',
770 'source' => 'Payment',
771 'is_override' => 1,
772 'status_id' => $this->_membershipStatusID,
6a488035
TO
773 );
774
d54576ed 775 $this->callAPIFailure('membership', 'create', $params,
771f3245 776 'contact_id is not valid : 999'
777 );
6a488035 778 }
5896d037 779
00be9182 780 public function testMembershipCreateWithInvalidStatus() {
6a488035
TO
781 $params = $this->_params;
782 $params['status_id'] = 999;
d54576ed 783 $this->callAPIFailure('membership', 'create', $params,
771f3245 784 "'999' is not a valid option for field status_id"
785 );
6a488035
TO
786 }
787
00be9182 788 public function testMembershipCreateWithInvalidType() {
6a488035
TO
789 $params = $this->_params;
790 $params['membership_type_id'] = 999;
791
d54576ed 792 $this->callAPIFailure('membership', 'create', $params,
771f3245 793 "'999' is not a valid option for field membership_type_id"
794 );
6a488035
TO
795 }
796
797 /**
100fef9d 798 * Check with complete array + custom field
6a488035
TO
799 * Note that the test is written on purpose without any
800 * variables specific to participant so it can be replicated into other entities
801 * and / or moved to the automated test suite
802 */
00be9182 803 public function testCreateWithCustom() {
6a488035
TO
804 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
805
806 $params = $this->_params;
807 $params['custom_' . $ids['custom_field_id']] = "custom string";
808
a828d7b8 809 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, NULL, 'CreateWithCustomData');
5896d037
TO
810 $check = $this->callAPISuccess($this->_entity, 'get', array(
811 'id' => $result['id'],
21dfd5f5 812 'contact_id' => $this->_contactID,
5896d037 813 ));
6a488035 814 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
6a488035
TO
815 }
816
22e97101
JV
817 /**
818 * Search on custom field value.
819 */
820 public function testSearchWithCustomDataCRM16036() {
821 // Create a custom field on membership
822 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
823
824 // Create a new membership, but don't assign anything to the custom field.
825 $params = $this->_params;
826 $result = $this->callAPIAndDocument(
827 $this->_entity,
828 'create',
829 $params,
830 __FUNCTION__,
831 __FILE__,
832 NULL,
833 'SearchWithCustomData');
834
835 // search memberships with CRM-16036 as custom field value.
836 // Since we did not touch the custom field of any membership,
837 // this should not return any results.
838 $check = $this->callAPISuccess($this->_entity, 'get', array(
839 'custom_' . $ids['custom_field_id'] => "CRM-16036",
840 ));
841
842 // Cleanup.
843 $this->callAPISuccess($this->_entity, 'delete', array(
844 'id' => $result['id'],
845 ));
846
847 // Assert.
848 $this->assertEquals(0, $check['count']);
849 }
850
6a488035
TO
851 /**
852 * Test civicrm_contact_memberships_create with membership id (edit
853 * membership).
854 * success expected.
855 */
00be9182 856 public function testMembershipCreateWithId() {
6a488035
TO
857 $membershipID = $this->contactMembershipCreate($this->_params);
858 $params = array(
859 'id' => $membershipID,
860 'contact_id' => $this->_contactID,
861 'membership_type_id' => $this->_membershipTypeID,
862 'join_date' => '2006-01-21',
863 'start_date' => '2006-01-21',
864 'end_date' => '2006-12-21',
865 'source' => 'Payment',
866 'is_override' => 1,
867 'status_id' => $this->_membershipStatusID,
6a488035
TO
868 );
869
771f3245 870 $result = $this->callAPISuccess('membership', 'create', $params);
c329a76a
JP
871
872 //Update Status and check activities created.
873 $updateStatus = array(
874 'id' => $result['id'],
1eae7f10 875 'status_id' => CRM_Core_PseudoConstant::getKey('CRM_Member_BAO_Membership', 'status_id', 'Cancelled'),
c329a76a
JP
876 );
877 $this->callAPISuccess('Membership', 'create', $updateStatus);
878 $activities = CRM_Activity_BAO_Activity::getContactActivity($this->_contactID);
879 $this->assertEquals(2, count($activities));
880 $activityNames = array_flip(CRM_Utils_Array::collect('activity_name', $activities));
881 $this->assertArrayHasKey('Membership Signup', $activityNames);
882 $this->assertArrayHasKey('Change Membership Status', $activityNames);
883
771f3245 884 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 885 'id' => $result['id'],
771f3245 886 ));
6a488035
TO
887 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
888 }
889
890 /**
891 * Test civicrm_contact_memberships_create with membership id (edit
892 * membership).
893 * success expected.
894 */
00be9182 895 public function testMembershipCreateUpdateWithIdNoContact() {
6a488035
TO
896 $membershipID = $this->contactMembershipCreate($this->_params);
897 $params = array(
898 'id' => $membershipID,
899 'membership_type_id' => $this->_membershipTypeID,
900 'contact_id' => $this->_contactID,
901 'join_date' => '2006-01-21',
902 'start_date' => '2006-01-21',
903 'end_date' => '2006-12-21',
904 'source' => 'Payment',
905 'is_override' => 1,
906 'status_id' => $this->_membershipStatusID,
6a488035
TO
907 );
908
771f3245 909 $result = $this->callAPISuccess('membership', 'create', $params);
910 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 911 'id' => $result['id'],
5896d037 912 ));
771f3245 913
6a488035
TO
914 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
915 }
916
917 /**
918 * Test civicrm_contact_memberships_create with membership id (edit
919 * membership).
920 * success expected.
921 */
00be9182 922 public function testMembershipCreateUpdateWithIdNoDates() {
6a488035
TO
923 $membershipID = $this->contactMembershipCreate($this->_params);
924 $params = array(
925 'id' => $membershipID,
926 'contact_id' => $this->_contactID,
927 'membership_type_id' => $this->_membershipTypeID,
928 'source' => 'Payment',
929 'is_override' => 1,
930 'status_id' => $this->_membershipStatusID,
6a488035
TO
931 );
932
771f3245 933 $result = $this->callAPISuccess('membership', 'create', $params);
934 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 935 'id' => $result['id'],
5896d037 936 ));
6a488035
TO
937 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
938 }
939
940 /**
941 * Test civicrm_contact_memberships_create with membership id (edit
942 * membership).
943 * success expected.
944 */
00be9182 945 public function testMembershipCreateUpdateWithIdNoDatesNoType() {
6a488035
TO
946 $membershipID = $this->contactMembershipCreate($this->_params);
947 $params = array(
948 'id' => $membershipID,
949 'source' => 'not much here',
950 'contact_id' => $this->_contactID,
951 'is_override' => 1,
952 'status_id' => $this->_membershipStatusID,
6a488035
TO
953 );
954
771f3245 955 $result = $this->callAPISuccess('membership', 'create', $params);
956 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 957 'id' => $result['id'],
771f3245 958 ));
6a488035
TO
959 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
960 }
961
962 /**
963 * Test civicrm_contact_memberships_create with membership id (edit
964 * membership).
965 * success expected.
966 */
00be9182 967 public function testMembershipCreateUpdateWithIDAndSource() {
6a488035
TO
968 $membershipID = $this->contactMembershipCreate($this->_params);
969 $params = array(
970 'id' => $membershipID,
971 'source' => 'changed',
972 'contact_id' => $this->_contactID,
6c6e6187 973 'status_id' => $this->_membershipStatusID,
5896d037 974 'membership_type_id' => $this->_membershipTypeID,
6a488035
TO
975 'skipStatusCal' => 1,
976 );
771f3245 977 $result = $this->callAPISuccess('membership', 'create', $params);
6a488035 978 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
771f3245 979 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 980 'id' => $result['id'],
5896d037 981 ));
6a488035
TO
982 }
983
984 /**
eceb18cc 985 * Change custom field using update.
6a488035 986 */
00be9182 987 public function testUpdateWithCustom() {
6a488035
TO
988 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
989
990 $params = $this->_params;
991 $params['custom_' . $ids['custom_field_id']] = "custom string";
a828d7b8 992 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__, NULL, 'UpdateCustomData');
5896d037
TO
993 $result = $this->callAPISuccess($this->_entity, 'create', array(
994 'id' => $result['id'],
21dfd5f5 995 'custom_' . $ids['custom_field_id'] => "new custom",
5896d037
TO
996 ));
997 $check = $this->callAPISuccess($this->_entity, 'get', array(
998 'id' => $result['id'],
21dfd5f5 999 'contact_id' => $this->_contactID,
5896d037 1000 ));
6a488035
TO
1001
1002 $this->assertEquals("new custom", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
d54576ed 1003 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 1004 'id' => $check['id'],
5896d037 1005 ));
6a488035
TO
1006
1007 $this->customFieldDelete($ids['custom_field_id']);
1008 $this->customGroupDelete($ids['custom_group_id']);
1009 }
1010
93c482a4
EM
1011 /**
1012 * per CRM-15746 check that the id can be altered in an update hook
1013 */
28a04ea9 1014 public function testMembershipUpdateCreateHookCRM15746() {
93c482a4
EM
1015 $this->hookClass->setHook('civicrm_pre', array($this, 'hook_civicrm_pre_update_create_membership'));
1016 $result = $this->callAPISuccess('membership', 'create', $this->_params);
1017 $this->callAPISuccess('membership', 'create', array('id' => $result['id'], 'end_date' => '1 year ago'));
1018 $this->callAPISuccessGetCount('membership', array(), 2);
1019 $this->hookClass->reset();
1020 $this->callAPISuccess('membership', 'create', array('id' => $result['id'], 'end_date' => '1 year ago'));
1021 $this->callAPISuccessGetCount('membership', array(), 2);
1022 }
1023
2ea0abec
EM
1024 /**
1025 * Custom hook for update membership.
1026 *
1027 * @param string $op
1028 * @param object $objectName
1029 * @param int $id
1030 * @param array $params
1031 *
1032 * @throws \Exception
1033 */
28a04ea9 1034 public function hook_civicrm_pre_update_create_membership($op, $objectName, $id, &$params) {
93c482a4
EM
1035 if ($objectName == 'Membership' && $op == 'edit') {
1036 $existingMembership = $this->callAPISuccessGetSingle('membership', array('id' => $params['id']));
1037 unset($params['id'], $params['membership_id']);
6c6e6187 1038 $params['join_date'] = $params['membership_start_date'] = $params['start_date'] = date('Ymd000000', strtotime($existingMembership['start_date']));
93c482a4
EM
1039 $params = array_merge($existingMembership, $params);
1040 $params['id'] = NULL;
1041 }
1042 }
1043
6a488035 1044 /**
fe482240 1045 * Test civicrm_contact_memberships_create Invalid membership data.
6a488035
TO
1046 * Error expected.
1047 */
00be9182 1048 public function testMembershipCreateInvalidMemData() {
6a488035
TO
1049 //membership_contact_id as string
1050 $params = array(
1051 'membership_contact_id' => 'Invalid',
1052 'membership_type_id' => $this->_membershipTypeID,
1053 'join_date' => '2011-01-21',
1054 'start_date' => '2010-01-21',
1055 'end_date' => '2008-12-21',
1056 'source' => 'Payment',
1057 'is_override' => 1,
5896d037
TO
1058 'status_id' => $this->_membershipStatusID,
1059 );
6a488035 1060
d54576ed 1061 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
1062
1063 //membership_contact_id which is no in contact table
1064 $params['membership_contact_id'] = 999;
d54576ed 1065 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
1066
1067 //invalid join date
1068 unset($params['membership_contact_id']);
1069 $params['join_date'] = "invalid";
d54576ed 1070 $this->callAPIFailure('Membership', 'Create', $params);
6a488035
TO
1071 }
1072
1073 /**
1074 * Test civicrm_contact_memberships_create with membership_contact_id
1075 * membership).
1076 * Success expected.
1077 */
00be9182 1078 public function testMembershipCreateWithMemContact() {
6a488035
TO
1079 $params = array(
1080 'membership_contact_id' => $this->_contactID,
1081 'membership_type_id' => $this->_membershipTypeID,
1082 'join_date' => '2011-01-21',
1083 'start_date' => '2010-01-21',
1084 'end_date' => '2008-12-21',
1085 'source' => 'Payment',
1086 'is_override' => 1,
1087 'status_id' => $this->_membershipStatusID,
6a488035
TO
1088 );
1089
771f3245 1090 $result = $this->callAPISuccess('membership', 'create', $params);
6a488035 1091
d54576ed 1092 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 1093 'id' => $result['id'],
771f3245 1094 ));
6a488035 1095 }
5896d037 1096
cc73900e 1097 /**
1098 * Test civicrm_contact_memberships_create with membership_contact_id
1099 * membership).
1100 * Success expected.
1101 */
00be9182 1102 public function testMembershipCreateValidMembershipTypeString() {
cc73900e 1103 $params = array(
1104 'membership_contact_id' => $this->_contactID,
1105 'membership_type_id' => 'General',
1106 'join_date' => '2011-01-21',
1107 'start_date' => '2010-01-21',
1108 'end_date' => '2008-12-21',
1109 'source' => 'Payment',
1110 'is_override' => 1,
1111 'status_id' => $this->_membershipStatusID,
1112 );
1113
1114 $result = $this->callAPISuccess('membership', 'create', $params);
1115 $this->assertEquals($this->_membershipTypeID, $result['values'][$result['id']]['membership_type_id']);
d54576ed 1116 $this->callAPISuccess('Membership', 'Delete', array(
cc73900e 1117 'id' => $result['id'],
1118 ));
1119 }
1120
1121 /**
1122 * Test civicrm_contact_memberships_create with membership_contact_id
1123 * membership).
1124 * Success expected.
1125 */
00be9182 1126 public function testMembershipCreateInValidMembershipTypeString() {
cc73900e 1127 $params = array(
1128 'membership_contact_id' => $this->_contactID,
1129 'membership_type_id' => 'invalid',
1130 'join_date' => '2011-01-21',
1131 'start_date' => '2010-01-21',
1132 'end_date' => '2008-12-21',
1133 'source' => 'Payment',
1134 'is_override' => 1,
1135 'status_id' => $this->_membershipStatusID,
1136 );
1137
d54576ed 1138 $this->callAPIFailure('membership', 'create', $params);
cc73900e 1139 }
6a488035 1140
cc73900e 1141 /**
eceb18cc 1142 * Test that if membership join date is not set it defaults to today.
cc73900e 1143 */
00be9182 1144 public function testEmptyJoinDate() {
8c33a68c 1145 unset($this->_params['join_date'], $this->_params['is_override']);
1146 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1147 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1148 $this->assertEquals(date('Y-m-d', strtotime('now')), $result['join_date']);
1149 $this->assertEquals('2009-01-21', $result['start_date']);
1150 $this->assertEquals('2009-12-21', $result['end_date']);
cc73900e 1151 }
5896d037 1152
cc73900e 1153 /**
fe482240 1154 * Test that if membership start date is not set it defaults to correct end date.
8c33a68c 1155 * - fixed
cc73900e 1156 */
00be9182 1157 public function testEmptyStartDateFixed() {
8c33a68c 1158 unset($this->_params['start_date'], $this->_params['is_override']);
1159 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1160 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1161 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1162 $this->assertEquals('2009-01-21', $result['join_date']);
1163 $this->assertEquals('2008-03-01', $result['start_date']);
1164 $this->assertEquals('2009-12-21', $result['end_date']);
1165 }
cc73900e 1166
8c33a68c 1167 /**
1168 * Test that if membership start date is not set it defaults to correct end date
1169 * - fixed
1170 */
2ea0abec
EM
1171 public function testEmptyStartEndDateFixedOneYear() {
1172 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1173 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 1));
1174 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1175 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1176 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1177 $this->assertEquals('2009-01-21', $result['join_date']);
1178 $this->assertEquals('2008-03-01', $result['start_date']);
1179 $this->assertEquals('2010-02-28', $result['end_date']);
1180 }
1181
1182 /**
9398f167
EM
1183 * Test that if membership start date is not set it defaults to correct end date for fixed multi year memberships.
1184 */
1185 public function testEmptyStartEndDateFixedMultiYear() {
1186 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1187 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 5));
1188 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1189 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1190 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1191 $this->assertEquals('2009-01-21', $result['join_date']);
1192 $this->assertEquals('2008-03-01', $result['start_date']);
1193 $this->assertEquals('2014-02-28', $result['end_date']);
1194 }
1195
41dcb974 1196 /**
1197 * CRM-18503 - Test membership join date is correctly set for fixed memberships.
1198 */
1199 public function testMembershipJoinDateFixed() {
1200 $memStatus = CRM_Member_PseudoConstant::membershipStatus();
1201 // Update the fixed membership type to 1 year duration.
1202 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 1));
1203 $contactId = $this->createLoggedInUser();
1204 // Create membership with 'Pending' status.
1205 $params = array(
1206 'contact_id' => $contactId,
1207 'membership_type_id' => $this->_membershipTypeID2,
1208 'source' => 'test membership',
1209 'is_pay_later' => 0,
1210 'status_id' => array_search('Pending', $memStatus),
1211 'skipStatusCal' => 1,
1212 'is_for_organization' => 1,
1213 );
1214 $ids = array();
1215 $membership = CRM_Member_BAO_Membership::create($params, $ids);
1216
1217 // Update membership to 'Completed' and check the dates.
1218 $memParams = array(
1219 'id' => $membership->id,
1220 'contact_id' => $contactId,
1221 'is_test' => 0,
1222 'membership_type_id' => $this->_membershipTypeID2,
1223 'num_terms' => 1,
1224 'status_id' => array_search('New', $memStatus),
1225 );
1226 $result = $this->callAPISuccess('Membership', 'create', $memParams);
1227
70a87708 1228 // Extend duration interval if join_date exceeds the rollover period.
1229 $joinDate = date('Y-m-d');
1230 $year = date('Y');
1231 $startDate = date('Y-m-d', strtotime(date('Y-03-01')));
581eb285 1232 $rollOver = TRUE;
1233 if (strtotime($startDate) > time()) {
1234 $rollOver = FALSE;
1235 $startDate = date('Y-m-d', strtotime(date('Y-03-01') . '- 1 year'));
1236 }
70a87708 1237 $membershipTypeDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($this->_membershipTypeID2);
1238 $fixedPeriodRollover = CRM_Member_BAO_MembershipType::isDuringFixedAnnualRolloverPeriod($joinDate, $membershipTypeDetails, $year, $startDate);
1239 $y = 1;
581eb285 1240 if ($fixedPeriodRollover && $rollOver) {
70a87708 1241 $y += 1;
1242 }
1243
41dcb974 1244 $expectedDates = array(
1245 'join_date' => date('Ymd'),
70a87708 1246 'start_date' => str_replace('-', '', $startDate),
1247 'end_date' => date('Ymd', strtotime(date('Y-03-01') . "+ {$y} year - 1 day")),
41dcb974 1248 );
1249 foreach ($result['values'] as $values) {
1250 foreach ($expectedDates as $date => $val) {
70a87708 1251 $this->assertEquals($val, $values[$date], "Failed asserting {$date} values");
41dcb974 1252 }
1253 }
1254 }
1255
b1fc74f0 1256 /**
964a9e96
EM
1257 * Test correct end and start dates are calculated for fixed multi year memberships.
1258 *
1259 * The empty start date is calculated to be the start_date (1 Jan prior to the join_date - so 1 Jan 15)
1260 *
1261 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1262 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1263 * and we add on 4 years rather than 5 because we are not after the rollover day - so we calculate 31 Dec 2019
1264 */
1265 public function testFixedMultiYearDateSetTwoEmptyStartEndDate() {
1266 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1267
1268 $this->callAPISuccess('membership_type', 'create', array(
1269 'id' => $this->_membershipTypeID2,
1270 'duration_interval' => 5,
1271 // Ie 1 Jan.
1272 'fixed_period_start_day' => '101',
1273 // Ie. 1 Nov.
1274 'fixed_period_rollover_day' => '1101',
1275 ));
1276 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1277 $dates = array(
1278 'join_date' => '28-Jan 2015',
1279 );
1280 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1281 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1282 $this->assertEquals('2015-01-28', $result['join_date']);
1283 $this->assertEquals('2015-01-01', $result['start_date']);
1284 $this->assertEquals('2019-12-31', $result['end_date']);
1285 }
1286
1287 /**
1288 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
b1fc74f0
EM
1289 *
1290 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1291 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1292 * and we add on 4 years rather than 5 because we are not after the rollover day - so we calculate 31 Dec 2019
1293 */
964a9e96 1294 public function testFixedMultiYearDateSetTwoEmptyEndDate() {
b1fc74f0
EM
1295 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1296
1297 $this->callAPISuccess('membership_type', 'create', array(
1298 'id' => $this->_membershipTypeID2,
1299 'duration_interval' => 5,
1300 // Ie 1 Jan.
1301 'fixed_period_start_day' => '101',
1302 // Ie. 1 Nov.
1303 'fixed_period_rollover_day' => '1101',
1304 ));
1305 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1306 $dates = array(
1307 'start_date' => '28-Jan 2015',
1308 'join_date' => '28-Jan 2015',
1309 );
1310 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1311 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1312 $this->assertEquals('2015-01-28', $result['join_date']);
1313 $this->assertEquals('2015-01-28', $result['start_date']);
1314 $this->assertEquals('2019-12-31', $result['end_date']);
1315 }
1316
1317 /**
964a9e96
EM
1318 * Test correct end and start dates are calculated for fixed multi year memberships.
1319 *
1320 * The empty start date is calculated to be the start_date (1 Jan prior to the join_date - so 1 Jan 15)
1321 *
1322 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1323 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1324 * and we add on <1 years rather than > 1 because we are not after the rollover day - so we calculate 31 Dec 2015
1325 */
1326 public function testFixedSingleYearDateSetTwoEmptyStartEndDate() {
1327 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1328
1329 $this->callAPISuccess('membership_type', 'create', array(
1330 'id' => $this->_membershipTypeID2,
1331 'duration_interval' => 1,
1332 // Ie 1 Jan.
1333 'fixed_period_start_day' => '101',
1334 // Ie. 1 Nov.
1335 'fixed_period_rollover_day' => '1101',
1336 ));
1337 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1338 $dates = array(
1339 'join_date' => '28-Jan 2015',
1340 );
1341 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1342 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1343 $this->assertEquals('2015-01-28', $result['join_date']);
1344 $this->assertEquals('2015-01-01', $result['start_date']);
1345 $this->assertEquals('2015-12-31', $result['end_date']);
1346 }
1347
1348 /**
1349 * Test correct end date for fixed single year memberships is calculated and start_date is not changed.
b1fc74f0
EM
1350 *
1351 * In this set our start date is after the start day and before the rollover day so we don't get an extra year
1352 * and we end one day before the rollover day. Start day is 1 Jan so we end on 31 Dec
1353 * and we add on <1 years rather than > 1 because we are not after the rollover day - so we calculate 31 Dec 2015
1354 */
964a9e96 1355 public function testFixedSingleYearDateSetTwoEmptyEndDate() {
b1fc74f0
EM
1356 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1357
1358 $this->callAPISuccess('membership_type', 'create', array(
1359 'id' => $this->_membershipTypeID2,
1360 'duration_interval' => 1,
1361 // Ie 1 Jan.
1362 'fixed_period_start_day' => '101',
1363 // Ie. 1 Nov.
1364 'fixed_period_rollover_day' => '1101',
1365 ));
1366 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1367 $dates = array(
1368 'start_date' => '28-Jan 2015',
1369 'join_date' => '28-Jan 2015',
1370 );
1371 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1372 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1373 $this->assertEquals('2015-01-28', $result['join_date']);
1374 $this->assertEquals('2015-01-28', $result['start_date']);
1375 $this->assertEquals('2015-12-31', $result['end_date']);
1376 }
1377
1378 /**
964a9e96 1379 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
b1fc74f0
EM
1380 *
1381 * In this set our start date is after the start day and after the rollover day so we do get an extra year
1382 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
964a9e96 1383 * and we add on 1 year we are after the rollover day - so we calculate 31 Oct 2016
b1fc74f0 1384 */
964a9e96 1385 public function testFixedSingleYearDateSetThreeEmptyEndDate() {
b1fc74f0
EM
1386 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1387
1388 $this->callAPISuccess('membership_type', 'create', array(
1389 'id' => $this->_membershipTypeID2,
1390 'duration_interval' => 1,
1391 // Ie. 1 Nov.
1392 'fixed_period_start_day' => '1101',
1393 // Ie 1 Jan.
1394 'fixed_period_rollover_day' => '101',
1395 ));
1396 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1397 $dates = array(
1398 'start_date' => '28-Jan 2015',
1399 'join_date' => '28-Jan 2015',
1400 );
1401 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1402 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1403 $this->assertEquals('2015-01-28', $result['join_date']);
1404 $this->assertEquals('2015-01-28', $result['start_date']);
1405 $this->assertEquals('2016-10-31', $result['end_date']);
1406 }
1407
964a9e96
EM
1408 /**
1409 * Test correct end and start dates are calculated for fixed multi year memberships.
1410 *
d177a2a6 1411 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
964a9e96
EM
1412 *
1413 * In this set our start date is after the start day and after the rollover day so we do get an extra year
1414 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1415 * and we add on 1 year we are after the rollover day - so we calculate 31 Oct 2016
1416 */
1417 public function testFixedSingleYearDateSetThreeEmptyStartEndDate() {
1418 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1419
1420 $this->callAPISuccess('membership_type', 'create', array(
1421 'id' => $this->_membershipTypeID2,
1422 'duration_interval' => 1,
1423 // Ie. 1 Nov.
1424 'fixed_period_start_day' => '1101',
1425 // Ie 1 Jan.
1426 'fixed_period_rollover_day' => '101',
1427 ));
1428 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1429 $dates = array(
1430 'join_date' => '28-Jan 2015',
1431 );
1432 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1433 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1434 $this->assertEquals('2015-01-28', $result['join_date']);
1435 $this->assertEquals('2014-11-01', $result['start_date']);
1436 $this->assertEquals('2016-10-31', $result['end_date']);
1437 }
b1fc74f0
EM
1438
1439 /**
964a9e96 1440 * Test that correct end date is calculated for fixed multi year memberships and start date is not changed.
b1fc74f0
EM
1441 *
1442 * In this set our start date is after the start day and after the rollover day so we do get an extra year
1443 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1444 * and we add on 5 years we are after the rollover day - so we calculate 31 Oct 2020
1445 */
964a9e96 1446 public function testFixedMultiYearDateSetThreeEmptyEndDate() {
b1fc74f0
EM
1447 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1448
1449 $this->callAPISuccess('membership_type', 'create', array(
1450 'id' => $this->_membershipTypeID2,
1451 'duration_interval' => 5,
1452 // Ie. 1 Nov.
1453 'fixed_period_start_day' => '1101',
1454 // Ie 1 Jan.
1455 'fixed_period_rollover_day' => '101',
1456 ));
1457 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1458 $dates = array(
1459 'start_date' => '28-Jan 2015',
1460 'join_date' => '28-Jan 2015',
1461 );
1462 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1463 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1464 $this->assertEquals('2015-01-28', $result['join_date']);
1465 $this->assertEquals('2015-01-28', $result['start_date']);
1466 $this->assertEquals('2020-10-31', $result['end_date']);
1467 }
9398f167 1468
964a9e96
EM
1469 /**
1470 * Test correct end and start dates are calculated for fixed multi year memberships.
1471 *
d177a2a6 1472 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
964a9e96
EM
1473 *
1474 * The empty start date is calculated to be the start_date (1 Nov prior to the join_date - so 1 Nov 14)
1475 * In this set our join date is after the start day and after the rollover day so we do get an extra year
1476 * and we end one day before the rollover day. Start day is 1 Nov so we end on 31 Oct
1477 * and we add on 5 years we are after the rollover day - so we calculate 31 Oct 2020
1478 */
1479 public function testFixedMultiYearDateSetThreeEmptyStartEndDate() {
1480 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1481
1482 $this->callAPISuccess('membership_type', 'create', array(
1483 'id' => $this->_membershipTypeID2,
1484 'duration_interval' => 5,
1485 // Ie. 1 Nov.
1486 'fixed_period_start_day' => '1101',
1487 // Ie 1 Jan.
1488 'fixed_period_rollover_day' => '101',
1489 ));
1490 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1491 $dates = array(
1492 'join_date' => '28-Jan 2015',
1493 );
1494 $result = $this->callAPISuccess($this->_entity, 'create', array_merge($this->_params, $dates));
1495 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1496 $this->assertEquals('2015-01-28', $result['join_date']);
1497 $this->assertEquals('2014-11-01', $result['start_date']);
1498 $this->assertEquals('2020-10-31', $result['end_date']);
1499 }
1500
9398f167
EM
1501 /**
1502 * Test that if membership start date is not set it defaults to correct end date for fixed single year memberships.
2ea0abec 1503 */
00be9182 1504 public function testEmptyStartDateRolling() {
8c33a68c 1505 unset($this->_params['start_date'], $this->_params['is_override']);
1506 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1507 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1508 $this->assertEquals('2009-01-21', $result['join_date']);
1509 $this->assertEquals('2009-01-21', $result['start_date']);
1510 $this->assertEquals('2009-12-21', $result['end_date']);
cc73900e 1511 }
5896d037 1512
8c33a68c 1513 /**
eceb18cc 1514 * Test that if membership end date is not set it defaults to correct end date.
8c33a68c 1515 * - rolling
1516 */
00be9182 1517 public function testEmptyEndDateFixed() {
8c33a68c 1518 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1519 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1520 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1521 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1522 $this->assertEquals('2009-01-21', $result['join_date']);
1523 $this->assertEquals('2008-03-01', $result['start_date']);
1524 $this->assertEquals('2010-02-28', $result['end_date']);
1525 }
5896d037 1526
8c33a68c 1527 /**
eceb18cc 1528 * Test that if membership end date is not set it defaults to correct end date.
8c33a68c 1529 * - rolling
1530 */
00be9182 1531 public function testEmptyEndDateRolling() {
8c33a68c 1532 unset($this->_params['is_override'], $this->_params['end_date']);
1533 $this->_params['membership_type_id'] = $this->_membershipTypeID;
1534 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1535 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1536 $this->assertEquals('2009-01-21', $result['join_date']);
1537 $this->assertEquals('2009-01-21', $result['start_date']);
1538 $this->assertEquals('2010-01-20', $result['end_date']);
1539 }
1540
1541
1542 /**
452b9e04 1543 * Test that if dates are set they not over-ridden if id is passed in
8c33a68c 1544 */
6c6e6187 1545 public function testMembershipDatesNotOverridden() {
8c33a68c 1546 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1547 unset($this->_params['end_date'], $this->_params['start_date']);
1548 $this->_params['id'] = $result['id'];
1549 $this->callAPISuccess($this->_entity, 'create', $this->_params);
1550 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1551 $this->assertEquals('2009-01-21', $result['join_date']);
1552 $this->assertEquals('2009-01-21', $result['start_date']);
1553 $this->assertEquals('2009-12-21', $result['end_date']);
1554
6c6e6187 1555 }
96025800 1556
8b3df6dc 1557 /**
1558 * Test that all membership types are returned when getoptions is called.
1559 *
1560 * This test locks in current behaviour where types for all domains are returned. It should possibly be domain
1561 * specific but that should only be done in conjunction with adding a hook to allow that to be altered as the
1562 * multisite use case expects the master domain to be able to see all sites.
1563 *
1564 * See CRM-17075.
1565 */
1566 public function testGetOptionsMembershipTypeID() {
1567 $options = $this->callAPISuccess('Membership', 'getoptions', array('field' => 'membership_type_id'));
5d8b37be 1568 $this->assertEquals('Another one', array_pop($options['values']));
8b3df6dc 1569 $this->assertEquals('General', array_pop($options['values']));
1570 $this->assertEquals(NULL, array_pop($options['values']));
1571 }
1572
6a488035 1573}