dev/core#2493 Add support for money fields to
[civicrm-core.git] / tests / phpunit / CRM / Batch / Form / EntryTest.php
1 <?php
2
3 /**
4 * File for the EntryTest class
5 *
6 * (PHP 5)
7 *
8 * @package CiviCRM
9 *
10 * This file is part of CiviCRM
11 *
12 * CiviCRM is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Affero General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
16 *
17 * CiviCRM is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public
23 * License along with this program. If not, see
24 * <http://www.gnu.org/licenses/>.
25 */
26
27 use Civi\Api4\Campaign;
28
29 /**
30 * Test CRM/Member/BAO Membership Log add , delete functions
31 *
32 * @package CiviCRM
33 * @group headless
34 */
35 class CRM_Batch_Form_EntryTest extends CiviUnitTestCase {
36
37 /**
38 * Membership type name used in test function.
39 *
40 * @var string
41 */
42 protected $_membershipTypeName;
43
44 /**
45 * Membership type id used in test function.
46 *
47 * @var string
48 */
49 protected $_membershipTypeID;
50
51 /**
52 * Contact id used in test function.
53 *
54 * @var string
55 */
56 protected $_contactID;
57
58 /**
59 * Contact id used in test function.
60 *
61 * @var string
62 */
63 protected $_contactID2 = NULL;
64
65 /**
66 * Contact id used in test function.
67 *
68 * @var string
69 */
70 protected $_contactID3 = NULL;
71
72 /**
73 * Contact id used in test function.
74 *
75 * @var string
76 */
77 protected $_contactID4 = NULL;
78
79 /**
80 * Validate all financial entities before tear down.
81 * @var bool
82 */
83 protected $isValidateFinancialsOnPostAssert = TRUE;
84
85 /**
86 * @throws \CRM_Core_Exception
87 * @throws \CiviCRM_API3_Exception
88 */
89 public function setUp(): void {
90 parent::setUp();
91
92 $params = [
93 'contact_type_a' => 'Individual',
94 'contact_type_b' => 'Organization',
95 'name_a_b' => 'Test Employee of',
96 'name_b_a' => 'Test Employer of',
97 ];
98 $this->_relationshipTypeId = $this->relationshipTypeCreate($params);
99 $this->_orgContactID = $this->organizationCreate();
100 $this->_financialTypeId = 1;
101 $this->_membershipTypeName = 'Mickey Mouse Club Member';
102 $params = [
103 'name' => $this->_membershipTypeName,
104 'description' => NULL,
105 'minimum_fee' => 1500,
106 'duration_unit' => 'year',
107 'member_of_contact_id' => $this->_orgContactID,
108 'period_type' => 'fixed',
109 'duration_interval' => 1,
110 'financial_type_id' => $this->_financialTypeId,
111 'relationship_type_id' => $this->_relationshipTypeId,
112 'visibility' => 'Public',
113 'is_active' => 1,
114 'fixed_period_start_day' => 101,
115 'fixed_period_rollover_day' => 1231,
116 'domain_id' => CRM_Core_Config::domainID(),
117 ];
118 $membershipType = $this->callAPISuccess('membership_type', 'create', $params);
119 $this->_membershipTypeID = $membershipType['id'];
120
121 $this->_orgContactID2 = $this->organizationCreate();
122 $params = [
123 'name' => 'General',
124 'duration_unit' => 'year',
125 'duration_interval' => 1,
126 'period_type' => 'rolling',
127 'member_of_contact_id' => $this->_orgContactID2,
128 'domain_id' => 1,
129 'financial_type_id' => 1,
130 'is_active' => 1,
131 'sequential' => 1,
132 'visibility' => 'Public',
133 ];
134 $membershipType2 = $this->callAPISuccess('MembershipType', 'create', $params);
135 $this->_membershipTypeID2 = $membershipType2['id'];
136
137 $this->_membershipStatusID = $this->membershipStatusCreate('test status');
138 $this->_contactID = $this->individualCreate();
139 $contact2Params = [
140 'first_name' => 'Anthonita',
141 'middle_name' => 'J.',
142 'last_name' => 'Anderson',
143 'prefix_id' => 3,
144 'suffix_id' => 3,
145 'email' => 'b@c.com',
146 'contact_type' => 'Individual',
147 ];
148 $this->_contactID2 = $this->individualCreate($contact2Params);
149 $this->_contactID3 = $this->individualCreate(['first_name' => 'bobby', 'email' => 'c@d.com']);
150 $this->_contactID4 = $this->individualCreate(['first_name' => 'bobbynita', 'email' => 'c@de.com']);
151
152 $session = CRM_Core_Session::singleton();
153 $session->set('dateTypes', 1);
154 $this->_sethtmlGlobals();
155
156 }
157
158 /**
159 * Tears down the fixture, for example, closes a network connection.
160 * This method is called after a test is executed.
161 */
162 public function tearDown(): void {
163 $this->quickCleanUpFinancialEntities();
164 $this->relationshipTypeDelete($this->_relationshipTypeId);
165 if ($this->callAPISuccessGetCount('membership', ['id' => $this->_membershipTypeID])) {
166 $this->membershipTypeDelete(['id' => $this->_membershipTypeID]);
167 }
168 if ($this->callAPISuccessGetCount('MembershipStatus', ['id' => $this->_membershipStatusID])) {
169 $this->membershipStatusDelete($this->_membershipStatusID);
170 }
171 $this->contactDelete($this->_contactID);
172 $this->contactDelete($this->_contactID2);
173 $this->contactDelete($this->_orgContactID);
174 }
175
176 /**
177 * Test Import.
178 *
179 * @param string $thousandSeparator
180 *
181 * @throws \API_Exception
182 * @throws \CRM_Core_Exception
183 * @throws \Civi\API\Exception\UnauthorizedException
184 *
185 * @dataProvider getThousandSeparators
186 */
187 public function testProcessMembership(string $thousandSeparator): void {
188 $this->setCurrencySeparators($thousandSeparator);
189
190 $form = new CRM_Batch_Form_Entry();
191 $profileID = (int) $this->callAPISuccessGetValue('UFGroup', ['return' => 'id', 'name' => 'membership_batch_entry']);
192 $form->_fields = CRM_Core_BAO_UFGroup::getFields($profileID, FALSE, CRM_Core_Action::VIEW);
193
194 $params = $this->getMembershipData();
195 $this->assertEquals(4500.0, $form->testProcessMembership($params));
196 $memberships = $this->callAPISuccess('Membership', 'get')['values'];
197 $this->assertCount(3, $memberships);
198
199 $this->assertNotEmpty($memberships[1]['campaign_id']);
200
201 //check start dates #1 should default to 1 Jan this year, #2 should be as entered
202 $this->assertEquals(date('Y-m-d', strtotime('first day of January 2013')), $memberships[1]['start_date']);
203 $this->assertEquals('2013-02-03', $memberships[2]['start_date']);
204 $this->assertEquals('2013-12-31', $memberships[2]['end_date']);
205
206 //check start dates #1 should default to 1 Jan this year, #2 should be as entered
207 $this->assertEquals(date('Y-m-d', strtotime('last day of December 2013')), $memberships[1]['end_date']);
208 $this->assertEquals(date('Y-m-d', strtotime('last day of December 2013')), $memberships[2]['end_date']);
209 $this->assertEquals('2013-12-01', $memberships[3]['end_date']);
210
211 //check start dates #1 should default to 1 Jan this year, #2 should be as entered
212 $this->assertEquals(date('Y-m-d', strtotime('07/22/2013')), $memberships[1]['join_date']);
213 $this->assertEquals(date('Y-m-d', strtotime('07/03/2013')), $memberships[2]['join_date']);
214 $this->assertEquals(date('Y-m-d'), $memberships[3]['join_date']);
215 $memberships = $this->callAPISuccess('Contribution', 'get', ['return' => ['total_amount', 'trxn_id']]);
216 $this->assertEquals(3, $memberships['count']);
217 foreach ($memberships['values'] as $key => $contribution) {
218 $this->assertEquals($this->callAPISuccess('LineItem', 'getvalue', [
219 'contribution_id' => $contribution['id'],
220 'return' => 'line_total',
221
222 ]), $contribution['total_amount']);
223 $this->assertEquals(1500, $contribution['total_amount']);
224 $this->assertEquals($params['field'][$key]['trxn_id'], $contribution['trxn_id']);
225 }
226 }
227
228 /**
229 * Test Contribution Import.
230 *
231 * @param $thousandSeparator
232 *
233 * @dataProvider getThousandSeparators
234 * @throws \CRM_Core_Exception
235 */
236 public function testProcessContribution($thousandSeparator): void {
237 $this->setCurrencySeparators($thousandSeparator);
238 $this->offsetDefaultPriceSet();
239 $form = new CRM_Batch_Form_Entry();
240 $params = $this->getContributionData();
241 $this->assertTrue($form->testProcessContribution($params));
242 $result = $this->callAPISuccess('contribution', 'get', ['return' => 'total_amount']);
243 $this->assertEquals(3, $result['count']);
244 foreach ($result['values'] as $contribution) {
245 $this->assertEquals($this->callAPISuccess('line_item', 'getvalue', [
246 'contribution_id' => $contribution['id'],
247 'return' => 'line_total',
248
249 ]), $contribution['total_amount']);
250 }
251 $checkResult = $this->callAPISuccess('Contribution', 'get', ['check_number' => ['IS NOT NULL' => 1]]);
252 $this->assertEquals(1, $checkResult['count']);
253 $entityFinancialTrxn = $this->callAPISuccess('EntityFinancialTrxn', 'get', ['entity_table' => 'civicrm_contribution', 'entity_id' => $checkResult['id']]);
254 $financialTrxn = $this->callAPISuccess('FinancialTrxn', 'get', ['id' => $entityFinancialTrxn['values'][$entityFinancialTrxn['id']]['financial_trxn_id']]);
255 $this->assertEquals('1234', $financialTrxn['values'][$financialTrxn['id']]['check_number']);
256 }
257
258 /**
259 * CRM-18000 - Test start_date, end_date after renewal
260 *
261 * @throws \API_Exception
262 * @throws \CRM_Core_Exception
263 * @throws \Civi\API\Exception\UnauthorizedException
264 */
265 public function testMembershipRenewalDates(): void {
266 $form = new CRM_Batch_Form_Entry();
267 foreach ([$this->_contactID, $this->_contactID2] as $contactID) {
268 $membershipParams = [
269 'membership_type_id' => $this->_membershipTypeID2,
270 'contact_id' => $contactID,
271 'start_date' => '01/01/2015',
272 'join_date' => '01/01/2010',
273 'end_date' => '12/31/2015',
274 ];
275 $this->contactMembershipCreate($membershipParams);
276 }
277
278 $params = $this->getMembershipData();
279 //ensure membership renewal
280 $params['member_option'] = [
281 1 => 2,
282 2 => 2,
283 ];
284 $params['field'][1]['membership_type'] = [0 => $this->_orgContactID2, 1 => $this->_membershipTypeID2];
285 $params['field'][1]['receive_date'] = date('Y-m-d');
286
287 // explicitly specify start and end dates
288 $params['field'][2]['membership_type'] = [0 => $this->_orgContactID2, 1 => $this->_membershipTypeID2];
289 $params['field'][2]['membership_start_date'] = "2016-04-01";
290 $params['field'][2]['membership_end_date'] = "2017-03-31";
291 $params['field'][2]['receive_date'] = "2016-04-01";
292
293 $this->assertEquals(3.0, $form->testProcessMembership($params));
294 $result = $this->callAPISuccess('Membership', 'get')['values'];
295
296 // renewal dates should be from current if start_date and end_date is passed as NULL
297 $this->assertEquals(date('Y-m-d'), $result[1]['start_date']);
298 $endDate = date('Y-m-d', strtotime(date("Y-m-d") . " +1 year -1 day"));
299 $this->assertEquals($endDate, $result[1]['end_date']);
300 $this->assertEquals($params['field'][1]['member_campaign_id'], $result[1]['campaign_id']);
301
302 // verify if the modified dates asserts with the dates passed above
303 $this->assertEquals('2016-04-01', $result[2]['start_date']);
304 $this->assertEquals('2017-03-31', $result[2]['end_date']);
305 $this->assertTrue(empty($result[2]['campaign_id']));
306 }
307
308 /**
309 * Data provider for test process membership.
310 *
311 * @return array
312 * @throws \API_Exception
313 * @throws \Civi\API\Exception\UnauthorizedException
314 */
315 public function getMembershipData(): array {
316 return [
317 'batch_id' => 4,
318 'primary_profiles' => [1 => NULL, 2 => NULL, 3 => NULL],
319 'primary_contact_id' => [
320 1 => $this->_contactID,
321 2 => $this->_contactID2,
322 3 => $this->_contactID3,
323 ],
324 'field' => [
325 1 => [
326 'membership_type' => [0 => $this->_orgContactID, 1 => $this->_membershipTypeID],
327 'membership_join_date' => '2013-07-22',
328 'membership_start_date' => NULL,
329 'membership_end_date' => NULL,
330 'membership_source' => NULL,
331 'financial_type' => 2,
332 'total_amount' => $this->formatMoneyInput(1500),
333 'receive_date' => '2013-07-24',
334 'receive_date_time' => NULL,
335 'payment_instrument' => 1,
336 'trxn_id' => 'TX101',
337 'check_number' => NULL,
338 'contribution_status_id' => 1,
339 'member_campaign_id' => $this->createCampaign(),
340 ],
341 2 => [
342 'membership_type' => [0 => $this->_orgContactID, 1 => $this->_membershipTypeID],
343 'membership_join_date' => '2013-07-03',
344 'membership_start_date' => '2013-02-03',
345 'membership_end_date' => NULL,
346 'membership_source' => NULL,
347 'financial_type' => 2,
348 'total_amount' => $this->formatMoneyInput(1500),
349 'receive_date' => '2013-07-17',
350 'payment_instrument' => 1,
351 'trxn_id' => 'TX102',
352 'check_number' => NULL,
353 'contribution_status_id' => 1,
354 ],
355 // no join date, coded end date
356 3 => [
357 'membership_type' => [0 => $this->_orgContactID, 1 => $this->_membershipTypeID],
358 'membership_join_date' => NULL,
359 'membership_start_date' => NULL,
360 'membership_end_date' => '2013-12-01',
361 'membership_source' => NULL,
362 'financial_type' => 2,
363 'total_amount' => $this->formatMoneyInput(1500),
364 'receive_date' => '2013-07-17',
365 'payment_instrument' => 1,
366 'trxn_id' => 'TX103',
367 'check_number' => NULL,
368 'contribution_status_id' => 1,
369 ],
370
371 ],
372 'actualBatchTotal' => 0,
373
374 ];
375 }
376
377 /**
378 * @param $thousandSeparator
379 *
380 * @return array
381 */
382 public function getContributionData($thousandSeparator = '.') {
383 return [
384 //'batch_id' => 4,
385 'primary_profiles' => [1 => NULL, 2 => NULL, 3 => NULL],
386 'primary_contact_id' => [
387 1 => $this->_contactID,
388 2 => $this->_contactID2,
389 3 => $this->_contactID3,
390 ],
391 'field' => [
392 1 => [
393 'financial_type' => 1,
394 'total_amount' => $this->formatMoneyInput(1500.15),
395 'receive_date' => '2013-07-24',
396 'receive_date_time' => NULL,
397 'payment_instrument' => 1,
398 'check_number' => NULL,
399 'contribution_status_id' => 1,
400 ],
401 2 => [
402 'financial_type' => 1,
403 'total_amount' => $this->formatMoneyInput(1500.15),
404 'receive_date' => '2013-07-24',
405 'receive_date_time' => NULL,
406 'payment_instrument' => 1,
407 'check_number' => NULL,
408 'contribution_status_id' => 1,
409 ],
410 3 => [
411 'financial_type' => 1,
412 'total_amount' => $this->formatMoneyInput(1500.15),
413 'receive_date' => '2013-07-24',
414 'receive_date_time' => NULL,
415 'payment_instrument' => 4,
416 'contribution_check_number' => '1234',
417 'contribution_status_id' => 1,
418 ],
419 ],
420 'actualBatchTotal' => $this->formatMoneyInput(4500.45),
421
422 ];
423 }
424
425 /**
426 * Create a campaign.
427 *
428 * @return mixed
429 * @throws \API_Exception
430 * @throws \Civi\API\Exception\UnauthorizedException
431 */
432 private function createCampaign(): int {
433 return (int) Campaign::create()->setValues([
434 'name' => 'blah',
435 'title' => 'blah',
436 ])->execute()->first()['id'];
437 }
438
439 }