Merge pull request #13458 from mattwire/unused_var_caseformcustomdata
[civicrm-core.git] / tests / phpunit / CRM / Contribute / BAO / ContributionTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
2fe49090 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
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 27
4cbe18b8
EM
28/**
29 * Class CRM_Contribute_BAO_ContributionTest
acb109b7 30 * @group headless
4cbe18b8 31 */
6a488035 32class CRM_Contribute_BAO_ContributionTest extends CiviUnitTestCase {
6a488035 33
6b60d32c 34 use CRMTraits_Financial_FinancialACLTrait;
35
6a488035 36 /**
2449fe69 37 * Clean up after tests.
38 */
39 public function tearDown() {
40 $this->quickCleanUpFinancialEntities();
2449fe69 41 parent::tearDown();
42 }
43
44 /**
45 * Test create method (create and update modes).
6a488035 46 */
00be9182 47 public function testCreate() {
2449fe69 48 $contactId = $this->individualCreate();
6a488035
TO
49
50 $params = array(
51 'contact_id' => $contactId,
52 'currency' => 'USD',
92915c55 53 'financial_type_id' => 1,
6a488035
TO
54 'contribution_status_id' => 1,
55 'payment_instrument_id' => 1,
56 'source' => 'STUDENT',
57 'receive_date' => '20080522000000',
58 'receipt_date' => '20080522000000',
59 'non_deductible_amount' => 0.00,
60 'total_amount' => 200.00,
61 'fee_amount' => 5,
62 'net_amount' => 195,
63 'trxn_id' => '22ereerwww444444',
64 'invoice_id' => '86ed39c9e9ee6ef6031621ce0eafe7eb81',
65 'thankyou_date' => '20080522',
d0c97775 66 'sequential' => TRUE,
6a488035
TO
67 );
68
d0c97775 69 $contribution = $this->callAPISuccess('Contribution', 'create', $params)['values'][0];
6a488035 70
d0c97775 71 $this->assertEquals($params['trxn_id'], $contribution['trxn_id'], 'Check for transaction id creation.');
72 $this->assertEquals($contactId, $contribution['contact_id'], 'Check for contact id creation.');
6a488035
TO
73
74 //update contribution amount
d0c97775 75 $params['id'] = $contribution['id'];
6a488035
TO
76 $params['fee_amount'] = 10;
77 $params['net_amount'] = 190;
78
d0c97775 79 $contribution = $this->callAPISuccess('Contribution', 'create', $params)['values'][0];
6a488035 80
d0c97775 81 $this->assertEquals($params['trxn_id'], $contribution['trxn_id'], 'Check for transcation id .');
82 $this->assertEquals($params['net_amount'], $contribution['net_amount'], 'Check for Amount updation.');
6a488035
TO
83 }
84
85 /**
f43ac8d8 86 * Create() method with custom data.
6a488035 87 */
00be9182 88 public function testCreateWithCustomData() {
2449fe69 89 $contactId = $this->individualCreate();
6a488035
TO
90
91 //create custom data
2449fe69 92 $customGroup = $this->customGroupCreate(array('extends' => 'Contribution'));
93 $customGroupID = $customGroup['id'];
94 $customGroup = $customGroup['values'][$customGroupID];
95
6a488035
TO
96 $fields = array(
97 'label' => 'testFld',
98 'data_type' => 'String',
99 'html_type' => 'Text',
100 'is_active' => 1,
2449fe69 101 'custom_group_id' => $customGroupID,
6a488035
TO
102 );
103 $customField = CRM_Core_BAO_CustomField::create($fields);
104
105 $params = array(
106 'contact_id' => $contactId,
107 'currency' => 'USD',
92915c55 108 'financial_type_id' => 1,
6a488035
TO
109 'contribution_status_id' => 1,
110 'payment_instrument_id' => 1,
111 'source' => 'STUDENT',
112 'receive_date' => '20080522000000',
113 'receipt_date' => '20080522000000',
114 'id' => NULL,
115 'non_deductible_amount' => 0.00,
116 'total_amount' => 200.00,
117 'fee_amount' => 5,
118 'net_amount' => 195,
119 'trxn_id' => '22ereerwww322323',
120 'invoice_id' => '22ed39c9e9ee6ef6031621ce0eafe6da70',
121 'thankyou_date' => '20080522',
d0c97775 122 'skipCleanMoney' => TRUE,
6a488035
TO
123 );
124
6a488035
TO
125 $params['custom'] = array(
126 $customField->id => array(
127 -1 => array(
128 'value' => 'Test custom value',
129 'type' => 'String',
130 'custom_field_id' => $customField->id,
2449fe69 131 'custom_group_id' => $customGroupID,
132 'table_name' => $customGroup['table_name'],
6a488035
TO
133 'column_name' => $customField->column_name,
134 'file_id' => NULL,
135 ),
136 ),
137 );
138
2449fe69 139 $contribution = CRM_Contribute_BAO_Contribution::create($params);
6a488035
TO
140
141 // Check that the custom field value is saved
142 $customValueParams = array(
143 'entityID' => $contribution->id,
144 'custom_' . $customField->id => 1,
145 );
146 $values = CRM_Core_BAO_CustomValueTable::getValues($customValueParams);
147 $this->assertEquals('Test custom value', $values['custom_' . $customField->id], 'Check the custom field value');
148
149 $this->assertEquals($params['trxn_id'], $contribution->trxn_id, 'Check for transcation id creation.');
150 $this->assertEquals($contactId, $contribution->contact_id, 'Check for contact id for Conribution.');
6a488035
TO
151 }
152
d73f286e
SL
153 /**
154 * CRM-21026 Test ContributionCount after contribution created with disabled FT
155 */
156 public function testContributionCountDisabledFinancialType() {
157 $contactId = $this->individualCreate();
158 $financialType = array(
159 'name' => 'grassvariety1' . substr(sha1(rand()), 0, 7),
160 'is_reserved' => 0,
161 'is_active' => 0,
162 );
163 $finType = $this->callAPISuccess('financial_type', 'create', $financialType);
164 $params = array(
165 'contact_id' => $contactId,
166 'currency' => 'USD',
167 'financial_type_id' => $finType['id'],
168 'contribution_status_id' => 1,
169 'payment_instrument_id' => 1,
170 'source' => 'STUDENT',
171 'receive_date' => '20080522000000',
172 'receipt_date' => '20080522000000',
173 'id' => NULL,
174 'non_deductible_amount' => 0.00,
175 'total_amount' => 200.00,
176 'fee_amount' => 5,
177 'net_amount' => 195,
178 'trxn_id' => '22ereerwww322323',
179 'invoice_id' => '22ed39c9e9ee6ef6031621ce0eafe6da70',
180 'thankyou_date' => '20080522',
181 );
d0c97775 182 $this->callAPISuccess('Contribution', 'create', $params);
183 $this->callAPISuccess('financial_type', 'create', array('is_active' => 0, 'id' => $finType['id']));
d73f286e
SL
184 $contributionCount = CRM_Contribute_BAO_Contribution::contributionCount($contactId);
185 $this->assertEquals(1, $contributionCount);
186 }
187
6a488035 188 /**
100fef9d 189 * DeleteContribution() method
6a488035 190 */
00be9182 191 public function testDeleteContribution() {
2449fe69 192 $contactId = $this->individualCreate();
6a488035
TO
193
194 $params = array(
195 'contact_id' => $contactId,
196 'currency' => 'USD',
92915c55 197 'financial_type_id' => 1,
6a488035
TO
198 'contribution_status_id' => 1,
199 'payment_instrument_id' => 1,
200 'source' => 'STUDENT',
201 'receive_date' => '20080522000000',
202 'receipt_date' => '20080522000000',
203 'id' => NULL,
204 'non_deductible_amount' => 0.00,
205 'total_amount' => 200.00,
206 'fee_amount' => 5,
207 'net_amount' => 195,
208 'trxn_id' => '33ereerwww322323',
209 'invoice_id' => '33ed39c9e9ee6ef6031621ce0eafe6da70',
210 'thankyou_date' => '20080522',
55ee9063 211 'sequential' => TRUE,
6a488035
TO
212 );
213
55ee9063 214 $contribution = $this->callAPISuccess('Contribution', 'create', $params)['values'][0];
6a488035 215
55ee9063 216 CRM_Contribute_BAO_Contribution::deleteContribution($contribution['id']);
6a488035 217
55ee9063 218 $this->assertDBNull('CRM_Contribute_DAO_Contribution', $contribution['trxn_id'],
6a488035
TO
219 'id', 'trxn_id', 'Database check for deleted Contribution.'
220 );
6a488035
TO
221 }
222
223 /**
2449fe69 224 * Create honor-contact method.
6a488035 225 */
2449fe69 226 public function testCreateAndGetHonorContact() {
6a488035 227 $firstName = 'John_' . substr(sha1(rand()), 0, 7);
92915c55
TO
228 $lastName = 'Smith_' . substr(sha1(rand()), 0, 7);
229 $email = "{$firstName}.{$lastName}@example.com";
6a488035 230
8381af80 231 //Get profile id of name honoree_individual used to create profileContact
232 $honoreeProfileId = NULL;
233 $ufGroupDAO = new CRM_Core_DAO_UFGroup();
234 $ufGroupDAO->name = 'honoree_individual';
235 if ($ufGroupDAO->find(TRUE)) {
236 $honoreeProfileId = $ufGroupDAO->id;
237 }
238
6a488035 239 $params = array(
8381af80 240 'prefix_id' => 3,
241 'first_name' => $firstName,
242 'last_name' => $lastName,
243 'email-1' => $email,
6a488035 244 );
8381af80 245 $softParam = array('soft_credit_type_id' => 1);
246
247 $honoreeContactId = CRM_Contact_BAO_Contact::createProfileContact($params, CRM_Core_DAO::$_nullArray,
92915c55
TO
248 NULL, NULL, $honoreeProfileId
249 );
6a488035 250
8381af80 251 $this->assertDBCompareValue('CRM_Contact_DAO_Contact', $honoreeContactId, 'first_name', 'id', $firstName,
6a488035
TO
252 'Database check for created honor contact record.'
253 );
254 //create contribution on behalf of honary.
255
2449fe69 256 $contactId = $this->individualCreate(array('first_name' => 'John', 'last_name' => 'Doe'));
6a488035 257
6a488035
TO
258 $param = array(
259 'contact_id' => $contactId,
260 'currency' => 'USD',
92915c55 261 'financial_type_id' => 4,
6a488035
TO
262 'contribution_status_id' => 1,
263 'receive_date' => date('Ymd'),
264 'total_amount' => 66,
d0c97775 265 'sequential' => 1,
6a488035
TO
266 );
267
d0c97775 268 $contribution = $this->callAPISuccess('Contribution', 'create', $param)['values'][0];
269 $id = $contribution['id'];
2449fe69 270 $softParam['contact_id'] = $honoreeContactId;
8381af80 271 $softParam['contribution_id'] = $id;
d0c97775 272 $softParam['currency'] = $contribution['currency'];
273 $softParam['amount'] = $contribution['total_amount'];
8381af80 274
275 //Create Soft Contribution for honoree contact
276 CRM_Contribute_BAO_ContributionSoft::add($softParam);
277
278 $this->assertDBCompareValue('CRM_Contribute_DAO_ContributionSoft', $id, 'contact_id',
279 'contribution_id', $honoreeContactId, 'Check DB for honor contact of the contribution'
6a488035 280 );
e4f46be0 281 //get honorary information
8381af80 282 $getHonorContact = CRM_Contribute_BAO_Contribution::getHonorContacts($honoreeContactId);
4ff25fbb 283 $this->assertEquals(array(
284 $id => array(
285 'honor_type' => 'In Honor of',
2449fe69 286 'honorId' => $contactId,
287 'display_name' => 'Mr. John Doe II',
4ff25fbb 288 'type' => 'Event Fee',
289 'type_id' => '4',
290 'amount' => '$ 66.00',
291 'source' => NULL,
755ca72c 292 'receive_date' => date('Y-m-d 00:00:00'),
4ff25fbb 293 'contribution_status' => 'Completed',
294 ),
295 ), $getHonorContact);
6a488035 296
8381af80 297 $this->assertDBCompareValue('CRM_Contact_DAO_Contact', $honoreeContactId, 'first_name', 'id', $firstName,
6a488035
TO
298 'Database check for created honor contact record.'
299 );
300
301 //get annual contribution information
302 $annual = CRM_Contribute_BAO_Contribution::annual($contactId);
303
d0c97775 304 $currencySymbol = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_Currency', CRM_Core_Config::singleton()->defaultCurrency, 'symbol', 'name');
6a488035
TO
305 $this->assertDBCompareValue('CRM_Contribute_DAO_Contribution', $id, 'total_amount',
306 'id', ltrim($annual[2], $currencySymbol), 'Check DB for total amount of the contribution'
307 );
6a488035
TO
308 }
309
6b60d32c 310 /**
311 * Test that financial type data is not added to the annual query if acls not enabled.
312 */
313 public function testAnnualQueryWithFinancialACLsEnabled() {
314 $this->enableFinancialACLs();
315 $this->createLoggedInUserWithFinancialACL();
316 $permittedFinancialType = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Donation');
317 $sql = CRM_Contribute_BAO_Contribution::getAnnualQuery([1, 2, 3]);
318 $this->assertContains('SUM(total_amount) as amount,', $sql);
319 $this->assertContains('WHERE b.contact_id IN (1,2,3)', $sql);
320 $this->assertContains('b.financial_type_id IN (' . $permittedFinancialType . ')', $sql);
321
322 // Run it to make sure it's not bad sql.
323 CRM_Core_DAO::executeQuery($sql);
324 $this->disableFinancialACLs();
325 }
326
327 /**
328 * Test that financial type data is not added to the annual query if acls not enabled.
329 */
330 public function testAnnualQueryWithFinancialACLsDisabled() {
331 $sql = CRM_Contribute_BAO_Contribution::getAnnualQuery([1, 2, 3]);
332 $this->assertContains('SUM(total_amount) as amount,', $sql);
333 $this->assertContains('WHERE b.contact_id IN (1,2,3)', $sql);
334 $this->assertNotContains('b.financial_type_id', $sql);
335 //$this->assertNotContains('line_item', $sql);
336 // Run it to make sure it's not bad sql.
337 CRM_Core_DAO::executeQuery($sql);
338 }
339
6a488035 340 /**
eceb18cc 341 * Display sort name during.
b581842f 342 * Update multiple contributions
6a488035
TO
343 * sortName();
344 */
00be9182 345 public function testsortName() {
6a488035
TO
346 $params = array(
347 'first_name' => 'Shane',
348 'last_name' => 'Whatson',
349 'contact_type' => 'Individual',
350 );
351
352 $contact = CRM_Contact_BAO_Contact::add($params);
353
354 //Now check $contact is object of contact DAO..
355 $this->assertInstanceOf('CRM_Contact_DAO_Contact', $contact, 'Check for created object');
356
357 $contactId = $contact->id;
6a488035
TO
358 $param = array(
359 'contact_id' => $contactId,
360 'currency' => 'USD',
92915c55 361 'financial_type_id' => 1,
6a488035
TO
362 'contribution_status_id' => 1,
363 'payment_instrument_id' => 1,
364 'source' => 'STUDENT',
365 'receive_date' => '20080522000000',
366 'receipt_date' => '20080522000000',
367 'id' => NULL,
368 'non_deductible_amount' => 0.00,
369 'total_amount' => 300.00,
370 'fee_amount' => 5,
371 'net_amount' => 295,
372 'trxn_id' => '22ereerwww323',
373 'invoice_id' => '22ed39c9e9ee621ce0eafe6da70',
374 'thankyou_date' => '20080522',
d0c97775 375 'sequential' => TRUE,
6a488035
TO
376 );
377
d0c97775 378 $contribution = $this->callAPISuccess('Contribution', 'create', $param)['values'][0];
6a488035 379
d0c97775 380 $this->assertEquals($param['trxn_id'], $contribution['trxn_id'], 'Check for transcation id creation.');
381 $this->assertEquals($contactId, $contribution['contact_id'], 'Check for contact id creation.');
6a488035 382
b581842f 383 //display sort name during Update multiple contributions
d0c97775 384 $sortName = CRM_Contribute_BAO_Contribution::sortName($contribution['id']);
6a488035
TO
385
386 $this->assertEquals('Whatson, Shane', $sortName, 'Check for sort name.');
6a488035
TO
387 }
388
389 /**
eceb18cc 390 * Add premium during online Contribution.
6a488035
TO
391 *
392 * AddPremium();
393 */
00be9182 394 public function testAddPremium() {
2449fe69 395 $contactId = $this->individualCreate();
6a488035 396
6a488035
TO
397 $params = array(
398 'name' => 'TEST Premium',
399 'sku' => 111,
400 'imageOption' => 'noImage',
401 'MAX_FILE_SIZE' => 2097152,
402 'price' => 100.00,
403 'cost' => 90.00,
404 'min_contribution' => 100,
405 'is_active' => 1,
406 );
32f27499 407 $premium = CRM_Contribute_BAO_Product::create($params);
6a488035
TO
408
409 $this->assertEquals('TEST Premium', $premium->name, 'Check for premium name.');
410
a275d4b6 411 $contributionParams = array(
6a488035
TO
412 'contact_id' => $contactId,
413 'currency' => 'USD',
92915c55 414 'financial_type_id' => 1,
6a488035
TO
415 'contribution_status_id' => 1,
416 'payment_instrument_id' => 1,
417 'source' => 'STUDENT',
418 'receive_date' => '20080522000000',
419 'receipt_date' => '20080522000000',
420 'id' => NULL,
421 'non_deductible_amount' => 0.00,
422 'total_amount' => 300.00,
423 'fee_amount' => 5,
424 'net_amount' => 295,
425 'trxn_id' => '33erdfrwvw434',
426 'invoice_id' => '98ed34f7u9hh672ce0eafe8fb92',
427 'thankyou_date' => '20080522',
d0c97775 428 'sequential' => TRUE,
6a488035 429 );
a275d4b6 430 $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams)['values'][0];
6a488035 431
a275d4b6 432 $this->assertEquals($contributionParams['trxn_id'], $contribution['trxn_id'], 'Check for transcation id creation.');
d0c97775 433 $this->assertEquals($contactId, $contribution['contact_id'], 'Check for contact id creation.');
6a488035
TO
434
435 //parameter for adding premium to contribution
436 $data = array(
437 'product_id' => $premium->id,
d0c97775 438 'contribution_id' => $contribution['id'],
6a488035
TO
439 'product_option' => NULL,
440 'quantity' => 1,
441 );
442 $contributionProduct = CRM_Contribute_BAO_Contribution::addPremium($data);
443 $this->assertEquals($contributionProduct->product_id, $premium->id, 'Check for Product id .');
444
445 //Delete Product
37828d4f 446 CRM_Contribute_BAO_Product::del($premium->id);
6a488035
TO
447 $this->assertDBNull('CRM_Contribute_DAO_Product', $premium->name,
448 'id', 'name', 'Database check for deleted Product.'
449 );
6a488035
TO
450 }
451
452 /**
fe482240 453 * Check duplicate contribution id.
6a488035
TO
454 * during the contribution import
455 * checkDuplicateIds();
456 */
00be9182 457 public function testcheckDuplicateIds() {
2449fe69 458 $contactId = $this->individualCreate();
6a488035
TO
459
460 $param = array(
461 'contact_id' => $contactId,
462 'currency' => 'USD',
92915c55 463 'financial_type_id' => 1,
6a488035
TO
464 'contribution_status_id' => 1,
465 'payment_instrument_id' => 1,
466 'source' => 'STUDENT',
467 'receive_date' => '20080522000000',
468 'receipt_date' => '20080522000000',
469 'id' => NULL,
470 'non_deductible_amount' => 0.00,
471 'total_amount' => 300.00,
472 'fee_amount' => 5,
473 'net_amount' => 295,
474 'trxn_id' => '76ereeswww835',
475 'invoice_id' => '93ed39a9e9hd621bs0eafe3da82',
476 'thankyou_date' => '20080522',
d0c97775 477 'sequential' => TRUE,
6a488035
TO
478 );
479
d0c97775 480 $contribution = $this->callAPISuccess('Contribution', 'create', $param)['values'][0];
6a488035 481
d0c97775 482 $this->assertEquals($param['trxn_id'], $contribution['trxn_id'], 'Check for transcation id creation.');
483 $this->assertEquals($contactId, $contribution['contact_id'], 'Check for contact id creation.');
6a488035 484 $data = array(
d0c97775 485 'id' => $contribution['id'],
486 'trxn_id' => $contribution['trxn_id'],
487 'invoice_id' => $contribution['invoice_id'],
6a488035
TO
488 );
489 $contributionID = CRM_Contribute_BAO_Contribution::checkDuplicateIds($data);
d0c97775 490 $this->assertEquals($contributionID, $contribution['id'], 'Check for duplicate transcation id .');
6a488035 491 }
96025800 492
8022372f
GC
493 /**
494 * Check credit note id creation
495 * when a contribution is cancelled or refunded
496 * createCreditNoteId();
497 */
498 public function testCreateCreditNoteId() {
2449fe69 499 $contactId = $this->individualCreate();
8022372f
GC
500
501 $param = array(
502 'contact_id' => $contactId,
503 'currency' => 'USD',
504 'financial_type_id' => 1,
505 'contribution_status_id' => 3,
506 'payment_instrument_id' => 1,
507 'source' => 'STUDENT',
508 'receive_date' => '20080522000000',
509 'receipt_date' => '20080522000000',
510 'id' => NULL,
511 'non_deductible_amount' => 0.00,
512 'total_amount' => 300.00,
513 'fee_amount' => 5,
514 'net_amount' => 295,
515 'trxn_id' => '76ereeswww835',
516 'invoice_id' => '93ed39a9e9hd621bs0eafe3da82',
517 'thankyou_date' => '20080522',
d0c97775 518 'sequential' => TRUE,
8022372f
GC
519 );
520
521 $creditNoteId = CRM_Contribute_BAO_Contribution::createCreditNoteId();
d0c97775 522 $contribution = $this->callAPISuccess('Contribution', 'create', $param)['values'][0];
523 $this->assertEquals($contactId, $contribution['contact_id'], 'Check for contact id creation.');
524 $this->assertEquals($creditNoteId, $contribution['creditnote_id'], 'Check if credit note id is created correctly.');
8022372f
GC
525 }
526
b04e4b11
PN
527 /**
528 * Create() method (create and update modes).
529 */
530 public function testIsPaymentFlag() {
2449fe69 531 $contactId = $this->individualCreate();
b04e4b11 532
d0c97775 533 $params = [
b04e4b11
PN
534 'contact_id' => $contactId,
535 'currency' => 'USD',
536 'financial_type_id' => 1,
537 'contribution_status_id' => 1,
538 'payment_instrument_id' => 1,
539 'source' => 'STUDENT',
540 'receive_date' => '20080522000000',
541 'receipt_date' => '20080522000000',
542 'non_deductible_amount' => 0.00,
543 'total_amount' => 200.00,
544 'fee_amount' => 5,
545 'net_amount' => 195,
546 'trxn_id' => '22ereerwww4444xx',
547 'invoice_id' => '86ed39c9e9ee6ef6541621ce0eafe7eb81',
548 'thankyou_date' => '20080522',
d0c97775 549 'sequential' => TRUE,
550 ];
551 $contribution = $this->callAPISuccess('Contribution', 'create', $params)['values'][0];
b04e4b11 552
d0c97775 553 $this->assertEquals($params['trxn_id'], $contribution['trxn_id'], 'Check for transcation id creation.');
554 $this->assertEquals($contactId, $contribution['contact_id'], 'Check for contact id creation.');
b04e4b11
PN
555
556 $trxnArray = array(
557 'trxn_id' => $params['trxn_id'],
558 'is_payment' => 1,
559 );
560 $defaults = array();
561 $financialTrxn = CRM_Core_BAO_FinancialTrxn::retrieve($trxnArray, $defaults);
4ba3c75f 562 $this->assertEquals(1, $financialTrxn->N, 'Mismatch count for is payment flag.');
b04e4b11 563 //update contribution amount
d0c97775 564 $params['id'] = $contribution['id'];
b04e4b11 565 $params['total_amount'] = 150;
d0c97775 566 $contribution = $this->callAPISuccess('Contribution', 'create', $params)['values'][0];
b04e4b11 567
d0c97775 568 $this->assertEquals($params['trxn_id'], $contribution['trxn_id'], 'Check for transcation id .');
569 $this->assertEquals($params['total_amount'], $contribution['total_amount'], 'Check for Amount updation.');
b04e4b11
PN
570 $trxnArray = array(
571 'trxn_id' => $params['trxn_id'],
572 'is_payment' => 1,
573 );
574 $defaults = array();
575 $financialTrxn = CRM_Core_BAO_FinancialTrxn::retrieve($trxnArray, $defaults);
4ba3c75f 576 $this->assertEquals(2, $financialTrxn->N, 'Mismatch count for is payment flag.');
b04e4b11
PN
577 $trxnArray['is_payment'] = 0;
578 $financialTrxn = CRM_Core_BAO_FinancialTrxn::retrieve($trxnArray, $defaults);
4ba3c75f 579 $this->assertEquals(1, $financialTrxn->N, 'Mismatch count for is payment flag.');
b04e4b11
PN
580 }
581
a387acc9
PN
582 /**
583 * Create() method (create and update modes).
584 */
585 public function testIsPaymentFlagForPending() {
2449fe69 586 $contactId = $this->individualCreate();
a387acc9
PN
587
588 $params = array(
589 'contact_id' => $contactId,
590 'currency' => 'USD',
591 'financial_type_id' => 1,
592 'contribution_status_id' => 2,
593 'payment_instrument_id' => 1,
594 'source' => 'STUDENT',
595 'is_pay_later' => 1,
596 'receive_date' => '20080522000000',
597 'receipt_date' => '20080522000000',
598 'non_deductible_amount' => 0.00,
599 'total_amount' => 200.00,
600 'fee_amount' => 5,
601 'net_amount' => 195,
602 'trxn_id' => '22ereerwww4444yy',
603 'invoice_id' => '86ed39c9e9yy6ef6541621ce0eafe7eb81',
604 'thankyou_date' => '20080522',
d0c97775 605 'sequential' => TRUE,
a387acc9
PN
606 );
607
d0c97775 608 $contribution = $this->callAPISuccess('Contribution', 'create', $params)['values'][0];
a387acc9 609
d0c97775 610 $this->assertEquals($params['trxn_id'], $contribution['trxn_id'], 'Check for transaction id creation.');
611 $this->assertEquals($contactId, $contribution['contact_id'], 'Check for contact id creation.');
a387acc9
PN
612
613 $trxnArray = array(
614 'trxn_id' => $params['trxn_id'],
615 'is_payment' => 0,
616 );
617 $defaults = array();
618 $financialTrxn = CRM_Core_BAO_FinancialTrxn::retrieve($trxnArray, $defaults);
619 $this->assertEquals(2, $financialTrxn->N, 'Mismatch count for is payment flag.');
620 $trxnArray['is_payment'] = 1;
621 $financialTrxn = CRM_Core_BAO_FinancialTrxn::retrieve($trxnArray, $defaults);
622 $this->assertEquals(NULL, $financialTrxn, 'Mismatch count for is payment flag.');
623 //update contribution amount
d0c97775 624 $params['id'] = $contribution['id'];
a387acc9
PN
625 $params['contribution_status_id'] = 1;
626
d0c97775 627 $contribution = $this->callAPISuccess('Contribution', 'create', $params)['values'][0];
a387acc9 628
d0c97775 629 $this->assertEquals($params['trxn_id'], $contribution['trxn_id'], 'Check for transcation id .');
630 $this->assertEquals($params['contribution_status_id'], $contribution['contribution_status_id'], 'Check for status updation.');
a387acc9
PN
631 $trxnArray = array(
632 'trxn_id' => $params['trxn_id'],
633 'is_payment' => 1,
634 );
635 $defaults = array();
636 $financialTrxn = CRM_Core_BAO_FinancialTrxn::retrieve($trxnArray, $defaults);
637 $this->assertEquals(1, $financialTrxn->N, 'Mismatch count for is payment flag.');
638 $trxnArray['is_payment'] = 0;
639 $financialTrxn = CRM_Core_BAO_FinancialTrxn::retrieve($trxnArray, $defaults);
640 $this->assertEquals(2, $financialTrxn->N, 'Mismatch count for is payment flag.');
a387acc9
PN
641 }
642
eec619df 643 /**
0a5651eb 644 * addPayments() method (add and edit modes of participant)
eec619df
PN
645 */
646 public function testAddPayments() {
647 list($lineItems, $contribution) = $this->addParticipantWithContribution();
d0c97775 648 CRM_Contribute_BAO_Contribution::addPayments([$contribution]);
0a5651eb
PN
649 $this->checkItemValues($contribution);
650 }
651
652 /**
653 * checks db values for financial item
654 */
624195c8 655 public function checkItemValues($contribution) {
876b8ab0 656 $toFinancialAccount = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount(4, 'Accounts Receivable Account is');
2449fe69 657 $query = "SELECT eft1.entity_id, ft.total_amount, eft1.amount FROM civicrm_financial_trxn ft INNER JOIN civicrm_entity_financial_trxn eft ON (eft.financial_trxn_id = ft.id AND eft.entity_table = 'civicrm_contribution')
eec619df
PN
658INNER JOIN civicrm_entity_financial_trxn eft1 ON (eft1.financial_trxn_id = eft.financial_trxn_id AND eft1.entity_table = 'civicrm_financial_item')
659WHERE eft.entity_id = %1 AND ft.to_financial_account_id <> %2";
660
661 $queryParams[1] = array($contribution->id, 'Integer');
662 $queryParams[2] = array($toFinancialAccount, 'Integer');
663
664 $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
19084b68 665 $amounts = array(100.00, 50.00);
eec619df
PN
666 while ($dao->fetch()) {
667 $this->assertEquals(150.00, $dao->total_amount, 'Mismatch of total amount paid.');
19084b68 668 $this->assertEquals($dao->amount, array_pop($amounts), 'Mismatch of amount proportionally assigned to financial item');
eec619df 669 }
eec619df
PN
670 }
671
0a5651eb
PN
672 /**
673 * assignProportionalLineItems() method (add and edit modes of participant)
674 */
675 public function testAssignProportionalLineItems() {
676 list($lineItems, $contribution) = $this->addParticipantWithContribution();
0a5651eb
PN
677 $params = array(
678 'contribution_id' => $contribution->id,
679 'total_amount' => 150.00,
680 );
681 $trxn = new CRM_Financial_DAO_FinancialTrxn();
682 $trxn->orderBy('id DESC');
683 $trxn->find(TRUE);
8de1ade9 684 CRM_Contribute_BAO_Contribution::assignProportionalLineItems($params, $trxn->id, $contribution->total_amount);
0a5651eb
PN
685 $this->checkItemValues($contribution);
686 }
687
eec619df
PN
688 /**
689 * Add participant with contribution
690 *
691 * @return array
692 */
78c99516 693 public function addParticipantWithContribution() {
eec619df 694 // creating price set, price field
2449fe69 695 $this->_contactId = $this->individualCreate();
696 $event = $this->eventCreate();
697 $this->_eventId = $event['id'];
624195c8 698 $paramsSet['title'] = 'Price Set' . substr(sha1(rand()), 0, 4);
19084b68 699 $paramsSet['name'] = CRM_Utils_String::titleToVar($paramsSet['title']);
eec619df
PN
700 $paramsSet['is_active'] = TRUE;
701 $paramsSet['financial_type_id'] = 4;
702 $paramsSet['extends'] = 1;
703
704 $priceset = CRM_Price_BAO_PriceSet::create($paramsSet);
705 $priceSetId = $priceset->id;
706
707 //Checking for priceset added in the table.
708 $this->assertDBCompareValue('CRM_Price_BAO_PriceSet', $priceSetId, 'title',
709 'id', $paramsSet['title'], 'Check DB for created priceset'
710 );
711 $paramsField = array(
712 'label' => 'Price Field',
713 'name' => CRM_Utils_String::titleToVar('Price Field'),
714 'html_type' => 'CheckBox',
715 'option_label' => array('1' => 'Price Field 1', '2' => 'Price Field 2'),
716 'option_value' => array('1' => 100, '2' => 200),
717 'option_name' => array('1' => 'Price Field 1', '2' => 'Price Field 2'),
718 'option_weight' => array('1' => 1, '2' => 2),
719 'option_amount' => array('1' => 100, '2' => 200),
720 'is_display_amounts' => 1,
721 'weight' => 1,
722 'options_per_line' => 1,
723 'is_active' => array('1' => 1, '2' => 1),
724 'price_set_id' => $priceset->id,
725 'is_enter_qty' => 1,
726 'financial_type_id' => CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType', 'Event Fee', 'id', 'name'),
727 );
728 $priceField = CRM_Price_BAO_PriceField::create($paramsField);
729 $eventParams = array(
730 'id' => $this->_eventId,
731 'financial_type_id' => 4,
732 'is_monetary' => 1,
733 );
734 CRM_Event_BAO_Event::create($eventParams);
735 CRM_Price_BAO_PriceSet::addTo('civicrm_event', $this->_eventId, $priceSetId);
e4ba8498 736
eec619df
PN
737 $priceFields = $this->callAPISuccess('PriceFieldValue', 'get', array('price_field_id' => $priceField->id));
738 $participantParams = array(
739 'financial_type_id' => 4,
740 'event_id' => $this->_eventId,
741 'role_id' => 1,
742 'status_id' => 14,
743 'fee_currency' => 'USD',
744 'contact_id' => $this->_contactId,
745 );
746 $participant = CRM_Event_BAO_Participant::add($participantParams);
747 $contributionParams = array(
748 'total_amount' => 150,
749 'currency' => 'USD',
750 'contact_id' => $this->_contactId,
751 'financial_type_id' => 4,
752 'contribution_status_id' => 1,
753 'partial_payment_total' => 300.00,
f49cdeab 754 'partial_amount_to_pay' => 150,
eec619df
PN
755 'contribution_mode' => 'participant',
756 'participant_id' => $participant->id,
d0c97775 757 'sequential' => TRUE,
eec619df
PN
758 );
759
760 foreach ($priceFields['values'] as $key => $priceField) {
761 $lineItems[1][$key] = array(
762 'price_field_id' => $priceField['price_field_id'],
763 'price_field_value_id' => $priceField['id'],
764 'label' => $priceField['label'],
765 'field_title' => $priceField['label'],
766 'qty' => 1,
767 'unit_price' => $priceField['amount'],
768 'line_total' => $priceField['amount'],
769 'financial_type_id' => $priceField['financial_type_id'],
770 );
771 }
772 $contributionParams['line_item'] = $lineItems;
d0c97775 773 $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams)['values'][0];
eec619df
PN
774
775 $paymentParticipant = array(
776 'participant_id' => $participant->id,
d0c97775 777 'contribution_id' => $contribution['id'],
eec619df 778 );
a5750507 779 CRM_Event_BAO_ParticipantPayment::create($paymentParticipant);
eec619df 780
d0c97775 781 $contributionObject = new CRM_Contribute_BAO_Contribution();
782 $contributionObject->id = $contribution['id'];
783 $contributionObject->find(TRUE);
784
785 return array($lineItems, $contributionObject);
eec619df
PN
786 }
787
5c8b902b 788 /**
a4a31ffe 789 * checkLineItems() check if total amount matches the sum of line total
5c8b902b
PN
790 */
791 public function testcheckLineItems() {
792 $params = array(
793 'contact_id' => 202,
794 'receive_date' => '2010-01-20',
795 'total_amount' => 100,
796 'financial_type_id' => 3,
797 'line_items' => array(
798 array(
799 'line_item' => array(
800 array(
801 'entity_table' => 'civicrm_contribution',
802 'price_field_id' => 8,
803 'price_field_value_id' => 16,
804 'label' => 'test 1',
805 'qty' => 1,
806 'unit_price' => 100,
807 'line_total' => 100,
808 ),
809 array(
810 'entity_table' => 'civicrm_contribution',
811 'price_field_id' => 8,
812 'price_field_value_id' => 17,
813 'label' => 'Test 2',
814 'qty' => 1,
815 'unit_price' => 200,
816 'line_total' => 200,
817 'financial_type_id' => 1,
818 ),
819 ),
a4a31ffe 820 'params' => array(),
5c8b902b 821 ),
a4a31ffe 822 ),
5c8b902b 823 );
c16c6ad8 824
af004c04 825 try {
2449fe69 826 CRM_Contribute_BAO_Contribution::checkLineItems($params);
af004c04
PN
827 $this->fail("Missed expected exception");
828 }
c16c6ad8
CR
829 catch (CRM_Contribute_Exception_CheckLineItemsException $e) {
830 $this->assertEquals(
831 CRM_Contribute_Exception_CheckLineItemsException::LINE_ITEM_DIFFERRING_TOTAL_EXCEPTON_MSG,
832 $e->getMessage()
833 );
af004c04 834 }
c16c6ad8 835
5c8b902b
PN
836 $this->assertEquals(3, $params['line_items'][0]['line_item'][0]['financial_type_id']);
837 $params['total_amount'] = 300;
c16c6ad8 838
af004c04 839 CRM_Contribute_BAO_Contribution::checkLineItems($params);
5c8b902b
PN
840 }
841
c16c6ad8
CR
842 /**
843 * Tests CRM_Contribute_BAO_Contribution::checkLineItems() method works with
844 * floating point values.
845 */
846 public function testCheckLineItemsWithFloatingPointValues() {
847 $params = array(
848 'contact_id' => 202,
849 'receive_date' => date('Y-m-d'),
850 'total_amount' => 16.67,
851 'financial_type_id' => 3,
852 'line_items' => array(
853 array(
854 'line_item' => array(
855 array(
856 'entity_table' => 'civicrm_contribution',
857 'price_field_id' => 8,
858 'price_field_value_id' => 16,
859 'label' => 'test 1',
860 'qty' => 1,
861 'unit_price' => 14.85,
862 'line_total' => 14.85,
863 ),
864 array(
865 'entity_table' => 'civicrm_contribution',
866 'price_field_id' => 8,
867 'price_field_value_id' => 17,
868 'label' => 'Test 2',
869 'qty' => 1,
870 'unit_price' => 1.66,
871 'line_total' => 1.66,
872 'financial_type_id' => 1,
873 ),
874 array(
875 'entity_table' => 'civicrm_contribution',
876 'price_field_id' => 8,
877 'price_field_value_id' => 17,
878 'label' => 'Test 2',
879 'qty' => 1,
880 'unit_price' => 0.16,
881 'line_total' => 0.16,
882 'financial_type_id' => 1,
883 ),
884 ),
885 'params' => array(),
886 ),
887 ),
888 );
889
890 $foundException = FALSE;
891
892 try {
893 CRM_Contribute_BAO_Contribution::checkLineItems($params);
894 }
895 catch (CRM_Contribute_Exception_CheckLineItemsException $e) {
896 $foundException = TRUE;
897 }
898
899 $this->assertFalse($foundException);
900 }
901
88f7a518
E
902 /**
903 * Test activity amount updation.
904 */
905 public function testActivityCreate() {
906 $contactId = $this->individualCreate();
907 $defaults = array();
908
909 $params = array(
910 'contact_id' => $contactId,
911 'currency' => 'USD',
912 'financial_type_id' => 1,
913 'contribution_status_id' => 1,
914 'payment_instrument_id' => 1,
915 'source' => 'STUDENT',
916 'receive_date' => '20080522000000',
917 'receipt_date' => '20080522000000',
918 'non_deductible_amount' => 0.00,
919 'total_amount' => 100.00,
920 'trxn_id' => '22ereerwww444444',
921 'invoice_id' => '86ed39c9e9ee6ef6031621ce0eafe7eb81',
922 'thankyou_date' => '20160519',
d0c97775 923 'sequential' => 1,
88f7a518
E
924 );
925
d0c97775 926 $contribution = $this->callAPISuccess('Contribution', 'create', $params)['values'][0];
88f7a518 927
d0c97775 928 $this->assertEquals($params['total_amount'], $contribution['total_amount'], 'Check for total amount in contribution.');
929 $this->assertEquals($contactId, $contribution['contact_id'], 'Check for contact id creation.');
88f7a518
E
930
931 // Check amount in activity.
932 $activityParams = array(
d0c97775 933 'source_record_id' => $contribution['id'],
d66c61b6 934 'activity_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Activity_BAO_Activity', 'activity_type_id', 'Contribution'),
88f7a518 935 );
d66c61b6 936 // @todo use api instead.
88f7a518
E
937 $activity = CRM_Activity_BAO_Activity::retrieve($activityParams, $defaults);
938
d0c97775 939 $this->assertEquals($contribution['id'], $activity->source_record_id, 'Check for activity associated with contribution.');
88f7a518
E
940 $this->assertEquals("$ 100.00 - STUDENT", $activity->subject, 'Check for total amount in activity.');
941
d0c97775 942 $params['id'] = $contribution['id'];
88f7a518
E
943 $params['total_amount'] = 200;
944
d0c97775 945 $contribution = $this->callAPISuccess('Contribution', 'create', $params)['values'][0];
88f7a518 946
d0c97775 947 $this->assertEquals($params['total_amount'], $contribution['total_amount'], 'Check for total amount in contribution.');
948 $this->assertEquals($contactId, $contribution['contact_id'], 'Check for contact id creation.');
88f7a518
E
949
950 // Retrieve activity again.
951 $activity = CRM_Activity_BAO_Activity::retrieve($activityParams, $defaults);
952
d0c97775 953 $this->assertEquals($contribution['id'], $activity->source_record_id, 'Check for activity associated with contribution.');
88f7a518
E
954 $this->assertEquals("$ 200.00 - STUDENT", $activity->subject, 'Check for total amount in activity.');
955 }
956
ce7fc91a
PN
957 /**
958 * Test checkContributeSettings.
959 */
960 public function testCheckContributeSettings() {
961 $settings = CRM_Contribute_BAO_Contribution::checkContributeSettings('deferred_revenue_enabled');
962 $this->assertNull($settings);
963 $params = array(
964 'contribution_invoice_settings' => array(
965 'deferred_revenue_enabled' => '1',
966 ),
967 );
968 $this->callAPISuccess('Setting', 'create', $params);
969 $settings = CRM_Contribute_BAO_Contribution::checkContributeSettings('deferred_revenue_enabled');
970 $this->assertEquals($settings, 1, 'Check for settings has failed');
971 }
972
5c3d600f
PN
973 /**
974 * Test allowUpdateRevenueRecognitionDate.
975 */
976 public function testAllowUpdateRevenueRecognitionDate() {
977 $contactId = $this->individualCreate();
978 $params = array(
979 'contact_id' => $contactId,
980 'receive_date' => '2010-01-20',
981 'total_amount' => 100,
4303ea89 982 'financial_type_id' => 4,
5c3d600f
PN
983 );
984 $order = $this->callAPISuccess('order', 'create', $params);
985 $allowUpdate = CRM_Contribute_BAO_Contribution::allowUpdateRevenueRecognitionDate($order['id']);
986 $this->assertTrue($allowUpdate);
987
988 $event = $this->eventCreate();
989 $params = array(
990 'contact_id' => $contactId,
991 'receive_date' => '2010-01-20',
992 'total_amount' => 300,
8484a5f0 993 'financial_type_id' => $this->getFinancialTypeId('Event Fee'),
994 'contribution_status_id' => 'Completed',
5c3d600f
PN
995 );
996 $priceFields = $this->createPriceSet('event', $event['id']);
997 foreach ($priceFields['values'] as $key => $priceField) {
998 $lineItems[$key] = array(
999 'price_field_id' => $priceField['price_field_id'],
1000 'price_field_value_id' => $priceField['id'],
1001 'label' => $priceField['label'],
1002 'field_title' => $priceField['label'],
1003 'qty' => 1,
1004 'unit_price' => $priceField['amount'],
1005 'line_total' => $priceField['amount'],
1006 'financial_type_id' => $priceField['financial_type_id'],
1007 'entity_table' => 'civicrm_participant',
1008 );
1009 }
1010 $params['line_items'][] = array(
1011 'line_item' => $lineItems,
1012 'params' => array(
1013 'contact_id' => $contactId,
1014 'event_id' => $event['id'],
1015 'status_id' => 1,
1016 'role_id' => 1,
1017 'register_date' => '2007-07-21 00:00:00',
1018 'source' => 'Online Event Registration: API Testing',
1019 ),
1020 );
1021 $order = $this->callAPISuccess('order', 'create', $params);
1022 $allowUpdate = CRM_Contribute_BAO_Contribution::allowUpdateRevenueRecognitionDate($order['id']);
1023 $this->assertFalse($allowUpdate);
1024
1025 $params = array(
1026 'contact_id' => $contactId,
1027 'receive_date' => '2010-01-20',
1028 'total_amount' => 200,
8484a5f0 1029 'financial_type_id' => $this->getFinancialTypeId('Member Dues'),
1030 'contribution_status_id' => 'Completed',
5c3d600f
PN
1031 );
1032 $membershipType = $this->membershipTypeCreate();
1033 $priceFields = $this->createPriceSet();
1034 $lineItems = array();
1035 foreach ($priceFields['values'] as $key => $priceField) {
1036 $lineItems[$key] = array(
1037 'price_field_id' => $priceField['price_field_id'],
1038 'price_field_value_id' => $priceField['id'],
1039 'label' => $priceField['label'],
1040 'field_title' => $priceField['label'],
1041 'qty' => 1,
1042 'unit_price' => $priceField['amount'],
1043 'line_total' => $priceField['amount'],
1044 'financial_type_id' => $priceField['financial_type_id'],
1045 'entity_table' => 'civicrm_membership',
1046 'membership_type_id' => $membershipType,
1047 );
1048 }
1049 $params['line_items'][] = array(
1050 'line_item' => array(array_pop($lineItems)),
1051 'params' => array(
1052 'contact_id' => $contactId,
1053 'membership_type_id' => $membershipType,
1054 'join_date' => '2006-01-21',
1055 'start_date' => '2006-01-21',
1056 'end_date' => '2006-12-21',
1057 'source' => 'Payment',
1058 'is_override' => 1,
1059 'status_id' => 1,
1060 ),
1061 );
1062 $order = $this->callAPISuccess('order', 'create', $params);
1063 $allowUpdate = CRM_Contribute_BAO_Contribution::allowUpdateRevenueRecognitionDate($order['id']);
1064 $this->assertFalse($allowUpdate);
1065 }
1066
d9553c2e
PN
1067 /**
1068 * Test calculateFinancialItemAmount().
1069 */
1070 public function testcalculateFinancialItemAmount() {
1071 $testParams = array(
1072 array(
1073 'params' => array(),
1074 'amountParams' => array(
1075 'line_total' => 100,
1076 'previous_line_total' => 300,
1077 'diff' => 1,
1078 ),
1079 'context' => 'changedAmount',
1080 'expectedItemAmount' => -200,
1081 ),
1082 array(
1083 'params' => array(),
1084 'amountParams' => array(
1085 'line_total' => 100,
1086 'previous_line_total' => 100,
1087 'diff' => -1,
1088 ),
1089 'context' => 'changePaymentInstrument',
1090 'expectedItemAmount' => -100,
1091 ),
1092 array(
1093 'params' => array(
1094 'is_quick_config' => TRUE,
1095 'total_amount' => 110,
1096 'tax_amount' => 10,
1097 ),
1098 'amountParams' => array(
1099 'item_amount' => 100,
1100 ),
1101 'context' => 'changedAmount',
1102 'expectedItemAmount' => 100,
1103 ),
1104 array(
1105 'params' => array(
1106 'is_quick_config' => TRUE,
1107 'total_amount' => 110,
1108 'tax_amount' => 10,
1109 ),
1110 'amountParams' => array(
1111 'item_amount' => NULL,
1112 ),
1113 'context' => 'changedAmount',
1114 'expectedItemAmount' => 110,
1115 ),
1116 array(
1117 'params' => array(
1118 'is_quick_config' => TRUE,
1119 'total_amount' => 110,
1120 'tax_amount' => 10,
1121 ),
1122 'amountParams' => array(
1123 'item_amount' => NULL,
1124 ),
1125 'context' => NULL,
1126 'expectedItemAmount' => 100,
1127 ),
1128 );
1129 foreach ($testParams as $params) {
1130 $itemAmount = CRM_Contribute_BAO_Contribution::calculateFinancialItemAmount($params['params'], $params['amountParams'], $params['context']);
1131 $this->assertEquals($itemAmount, $params['expectedItemAmount'], 'Invalid Financial Item amount.');
1132 }
1133 }
1134
d934a732
PN
1135 /**
1136 * Test recording of amount with comma separator.
1137 */
1138 public function testCommaSeparatorAmount() {
1139 $contactId = $this->individualCreate();
1140
1141 $params = array(
1142 'contact_id' => $contactId,
1143 'currency' => 'USD',
1144 'financial_type_id' => 1,
1145 'contribution_status_id' => 8,
1146 'payment_instrument_id' => 1,
1147 'receive_date' => '20080522000000',
1148 'receipt_date' => '20080522000000',
1149 'total_amount' => '20000.00',
1150 'partial_payment_total' => '20,000.00',
f49cdeab 1151 'partial_amount_to_pay' => '8,000.00',
d934a732
PN
1152 );
1153
d0c97775 1154 $contribution = $this->callAPISuccess('Contribution', 'create', $params);
1155 $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC');
d934a732
PN
1156 $financialTrxn = $this->callAPISuccessGetSingle(
1157 'FinancialTrxn',
1158 array(
1159 'id' => $lastFinancialTrxnId['financialTrxnId'],
1160 'return' => array('total_amount'),
1161 )
1162 );
1163 $this->assertEquals($financialTrxn['total_amount'], 8000, 'Invalid Tax amount.');
1164 }
1165
adbc354b
PN
1166 /**
1167 * Test for function getSalesTaxFinancialAccounts().
1168 */
1169 public function testgetSalesTaxFinancialAccounts() {
1170 $this->enableTaxAndInvoicing();
1171 $financialType = $this->createFinancialType();
1172 $financialAccount = $this->relationForFinancialTypeWithFinancialAccount($financialType['id']);
1173 $expectedResult = array($financialAccount->financial_account_id => $financialAccount->financial_account_id);
1174 $financialType = $this->createFinancialType();
1175 $financialAccount = $this->relationForFinancialTypeWithFinancialAccount($financialType['id']);
1176 $expectedResult[$financialAccount->financial_account_id] = $financialAccount->financial_account_id;
1177 $salesTaxFinancialAccount = CRM_Contribute_BAO_Contribution::getSalesTaxFinancialAccounts();
1178 $this->assertTrue(($salesTaxFinancialAccount == $expectedResult), 'Function returned wrong values.');
1179 }
1180
0409b821
PN
1181 /**
1182 * Test for function createProportionalEntry().
83644f47 1183 *
1184 * @param string $thousandSeparator
1185 * punctuation used to refer to thousands.
1186 *
1187 * @dataProvider getThousandSeparators
0409b821 1188 */
83644f47 1189 public function testCreateProportionalEntry($thousandSeparator) {
1190 $this->setCurrencySeparators($thousandSeparator);
2a4a2f00 1191 list($contribution, $financialAccount) = $this->createContributionWithTax();
0409b821
PN
1192 $params = array(
1193 'total_amount' => 55,
1194 'to_financial_account_id' => $financialAccount->financial_account_id,
1195 'payment_instrument_id' => 1,
1196 'trxn_date' => date('Ymd'),
1197 'status_id' => 1,
0409b821 1198 'entity_id' => $contribution['id'],
0409b821 1199 );
3137781d 1200 $financialTrxn = $this->callAPISuccess('FinancialTrxn', 'create', $params);
0409b821
PN
1201 $entityParams = array(
1202 'contribution_total_amount' => $contribution['total_amount'],
1203 'trxn_total_amount' => 55,
1204 'line_item_amount' => 100,
1205 );
1206 $previousLineItem = CRM_Financial_BAO_FinancialItem::getPreviousFinancialItem($contribution['id']);
1207 $eftParams = array(
1208 'entity_table' => 'civicrm_financial_item',
cf28d075 1209 'entity_id' => $previousLineItem['id'],
3137781d 1210 'financial_trxn_id' => (string) $financialTrxn['id'],
0409b821
PN
1211 );
1212 CRM_Contribute_BAO_Contribution::createProportionalEntry($entityParams, $eftParams);
1213 $trxnTestArray = array_merge($eftParams, array(
3137781d 1214 'amount' => '50.00',
0409b821 1215 ));
cf28d075 1216 $this->callAPISuccessGetSingle('EntityFinancialTrxn', $eftParams, $trxnTestArray);
0409b821
PN
1217 }
1218
c364c544
MW
1219 /**
1220 * Test for function createProportionalEntry with zero amount().
1221 *
1222 * @param string $thousandSeparator
1223 * punctuation used to refer to thousands.
1224 *
1225 * @dataProvider getThousandSeparators
1226 */
1227 public function testCreateProportionalEntryZeroAmount($thousandSeparator) {
1228 $this->setCurrencySeparators($thousandSeparator);
1229 list($contribution, $financialAccount) = $this->createContributionWithTax(array('total_amount' => 0));
1230 $params = array(
1231 'total_amount' => 0,
1232 'to_financial_account_id' => $financialAccount->financial_account_id,
1233 'payment_instrument_id' => 1,
1234 'trxn_date' => date('Ymd'),
1235 'status_id' => 1,
1236 'entity_id' => $contribution['id'],
1237 );
1238 $financialTrxn = $this->callAPISuccess('FinancialTrxn', 'create', $params);
1239 $entityParams = array(
1240 'contribution_total_amount' => $contribution['total_amount'],
1241 'trxn_total_amount' => 0,
1242 'line_item_amount' => 0,
1243 );
1244 $previousLineItem = CRM_Financial_BAO_FinancialItem::getPreviousFinancialItem($contribution['id']);
1245 $eftParams = array(
1246 'entity_table' => 'civicrm_financial_item',
1247 'entity_id' => $previousLineItem['id'],
1248 'financial_trxn_id' => (string) $financialTrxn['id'],
1249 );
1250 CRM_Contribute_BAO_Contribution::createProportionalEntry($entityParams, $eftParams);
1251 $trxnTestArray = array_merge($eftParams, array(
1252 'amount' => '0.00',
1253 ));
1254 $this->callAPISuccessGetSingle('EntityFinancialTrxn', $eftParams, $trxnTestArray);
1255 }
1256
646bc565
PN
1257 /**
1258 * Test for function getLastFinancialItemIds().
1259 */
1260 public function testgetLastFinancialItemIds() {
2a4a2f00 1261 list($contribution, $financialAccount) = $this->createContributionWithTax();
646bc565
PN
1262 list($ftIds, $taxItems) = CRM_Contribute_BAO_Contribution::getLastFinancialItemIds($contribution['id']);
1263 $this->assertEquals(count($ftIds), 1, 'Invalid count.');
1264 $this->assertEquals(count($taxItems), 1, 'Invalid count.');
1265 foreach ($taxItems as $value) {
1266 $this->assertEquals($value['amount'], 10, 'Invalid tax amount.');
1267 }
1268 }
1269
2a4a2f00
PN
1270 /**
1271 * Test for function createProportionalFinancialEntries().
1272 */
1273 public function testcreateProportionalFinancialEntries() {
1274 list($contribution, $financialAccount) = $this->createContributionWithTax();
1275 $params = array(
3137781d 1276 'total_amount' => 50,
2a4a2f00
PN
1277 'to_financial_account_id' => $financialAccount->financial_account_id,
1278 'payment_instrument_id' => 1,
1279 'trxn_date' => date('Ymd'),
1280 'status_id' => 1,
2a4a2f00 1281 'entity_id' => $contribution['id'],
2a4a2f00 1282 );
3137781d 1283 $financialTrxn = $this->callAPISuccess('FinancialTrxn', 'create', $params);
2a4a2f00
PN
1284 $entityParams = array(
1285 'contribution_total_amount' => $contribution['total_amount'],
1286 'trxn_total_amount' => 55,
1287 'trxn_id' => $financialTrxn['id'],
1288 );
1289 $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contribution['id']);
1290 list($ftIds, $taxItems) = CRM_Contribute_BAO_Contribution::getLastFinancialItemIds($contribution['id']);
1291 CRM_Contribute_BAO_Contribution::createProportionalFinancialEntries($entityParams, $lineItems, $ftIds, $taxItems);
1292 $eftParams = array(
1293 'entity_table' => 'civicrm_financial_item',
1294 'financial_trxn_id' => $financialTrxn['id'],
1295 );
1296 $entityFinancialTrxn = $this->callAPISuccess('EntityFinancialTrxn', 'Get', $eftParams);
1297 $this->assertEquals($entityFinancialTrxn['count'], 2, 'Invalid count.');
1298 $testAmount = array(5, 50);
1299 foreach ($entityFinancialTrxn['values'] as $value) {
1300 $this->assertEquals($value['amount'], array_pop($testAmount), 'Invalid amount stored in civicrm_entity_financial_trxn.');
77641de4
PN
1301 }
1302 }
1303
1304 /**
1305 * Test to check if amount is proportionally asigned for PI change.
1306 */
1307 public function testProportionallyAssignedForPIChange() {
1308 list($contribution, $financialAccount) = $this->createContributionWithTax();
1309 $params = array(
1310 'id' => $contribution['id'],
1311 'payment_instrument_id' => 3,
1312 );
1313 $this->callAPISuccess('Contribution', 'create', $params);
1314 $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC');
1315 $eftParams = array(
1316 'entity_table' => 'civicrm_financial_item',
1317 'financial_trxn_id' => $lastFinancialTrxnId['financialTrxnId'],
1318 );
1319 $entityFinancialTrxn = $this->callAPISuccess('EntityFinancialTrxn', 'Get', $eftParams);
1320 $this->assertEquals($entityFinancialTrxn['count'], 2, 'Invalid count.');
1321 $testAmount = array(10, 100);
1322 foreach ($entityFinancialTrxn['values'] as $value) {
1323 $this->assertEquals($value['amount'], array_pop($testAmount), 'Invalid amount stored in civicrm_entity_financial_trxn.');
2a4a2f00
PN
1324 }
1325 }
1326
646bc565
PN
1327 /**
1328 * Function to create contribution with tax.
1329 */
c364c544
MW
1330 public function createContributionWithTax($params = array()) {
1331 if (!isset($params['total_amount'])) {
1332 $params['total_amount'] = 100;
1333 }
646bc565
PN
1334 $contactId = $this->individualCreate();
1335 $this->enableTaxAndInvoicing();
1336 $financialType = $this->createFinancialType();
1337 $financialAccount = $this->relationForFinancialTypeWithFinancialAccount($financialType['id']);
1338 $form = new CRM_Contribute_Form_Contribution();
1339
1340 $form->testSubmit(array(
c364c544 1341 'total_amount' => $params['total_amount'],
646bc565 1342 'financial_type_id' => $financialType['id'],
646bc565
PN
1343 'contact_id' => $contactId,
1344 'contribution_status_id' => 1,
1345 'price_set_id' => 0,
1346 ),
1347 CRM_Core_Action::ADD
1348 );
1349 $contribution = $this->callAPISuccessGetSingle('Contribution',
1350 array(
1351 'contact_id' => $contactId,
1352 'return' => array('tax_amount', 'total_amount'),
1353 )
1354 );
2a4a2f00 1355 return array($contribution, $financialAccount);
646bc565
PN
1356 }
1357
75c07fde
JP
1358 /**
1359 * Test processOnBehalfOrganization() function.
1360 */
1361 public function testProcessOnBehalfOrganization() {
1362 $orgInfo = array(
1363 'phone' => '11111111',
1364 'email' => 'testorg@gmail.com',
1365 'street_address' => 'test Street',
1366 'city' => 'test City',
1367 'state_province' => 'AA',
1368 'postal_code' => '222222',
1369 'country' => 'United States',
1370 );
1371 $contactID = $this->individualCreate();
1372 $orgId = $this->organizationCreate(array('organization_name' => 'testorg1'));
1373 $orgCount = $this->callAPISuccessGetCount('Contact', array(
1374 'contact_type' => "Organization",
1375 'organization_name' => "testorg1",
1376 ));
1377 $this->assertEquals($orgCount, 1);
1378
1379 $values = $params = array();
1380 $behalfOrganization = array(
1381 'organization_name' => 'testorg1',
1382 'phone' => array(
1383 1 => array(
1384 'phone' => $orgInfo['phone'],
1385 'is_primary' => 1,
1386 ),
1387 ),
1388 'email' => array(
1389 1 => array(
1390 'email' => $orgInfo['email'],
1391 'is_primary' => 1,
1392 ),
1393 ),
1394 'address' => array(
1395 3 => array(
1396 'street_address' => $orgInfo['street_address'],
1397 'city' => $orgInfo['city'],
1398 'location_type_id' => 3,
1399 'postal_code' => $orgInfo['postal_code'],
1400 'country' => 'US',
1401 'state_province' => 'AA',
1402 'is_primary' => 1,
1403 ),
1404 ),
1405 );
1406 $fields = array(
1407 'organization_name' => 1,
1408 'phone-3-1' => 1,
1409 'email-3' => 1,
1410 'street_address-3' => 1,
1411 'city-3' => 1,
1412 'postal_code-3' => 1,
1413 'country-3' => 1,
1414 'state_province-3' => 1,
1415 );
1416 CRM_Contribute_Form_Contribution_Confirm::processOnBehalfOrganization($behalfOrganization, $contactID, $values, $params, $fields);
1417
1418 //Check whether new organisation is not created.
1419 $result = $this->callAPISuccess('Contact', 'get', array(
1420 'contact_type' => "Organization",
1421 'organization_name' => "testorg1",
1422 ));
1423 $this->assertEquals($result['count'], 1);
1424
1425 //Assert all org values are updated.
1426 foreach ($orgInfo as $key => $val) {
1427 $this->assertEquals($result['values'][$orgId][$key], $val);
1428 }
1429
1430 //Check if alert is assigned to params if more than 1 dupe exists.
1431 $orgId = $this->organizationCreate(array('organization_name' => 'testorg1', 'email' => 'testorg@gmail.com'));
1432 CRM_Contribute_Form_Contribution_Confirm::processOnBehalfOrganization($behalfOrganization, $contactID, $values, $params, $fields);
1433 $this->assertEquals($params['onbehalf_dupe_alert'], 1);
1434 }
1435
7e2ec997
E
1436 /**
1437 * Test for replaceContributionTokens.
1438 * This function tests whether the contribution tokens are replaced with values from contribution.
1439 */
1440 public function testReplaceContributionTokens() {
1441 $contactId1 = $this->individualCreate();
1442 $params = array(
1443 'contact_id' => $contactId1,
1444 'receive_date' => '20120511',
1445 'total_amount' => 100.00,
1446 'financial_type_id' => 1,
1447 'trxn_id' => 12345,
1448 'invoice_id' => 67890,
1449 'source' => 'SSF',
1450 'contribution_status_id' => 2,
1451 );
1452 $contribution1 = $this->contributionCreate($params);
1453 $contactId2 = $this->individualCreate();
1454 $params = array(
1455 'contact_id' => $contactId2,
1456 'receive_date' => '20150511',
1457 'total_amount' => 200.00,
1458 'financial_type_id' => 1,
1459 'trxn_id' => 6789,
1460 'invoice_id' => 12345,
1461 'source' => 'ABC',
1462 'contribution_status_id' => 1,
1463 );
1464 $contribution2 = $this->contributionCreate($params);
1465 $ids = array($contribution1, $contribution2);
1466
1467 $subject = "This is a test for contribution ID: {contribution.contribution_id}";
1468 $text = "Contribution Amount: {contribution.total_amount}";
1469 $html = "<p>Contribution Source: {contribution.contribution_source}</p></br>
1470 <p>Contribution Invoice ID: {contribution.invoice_id}</p></br>
1471 <p>Contribution Receive Date: {contribution.receive_date}</p></br>";
1472
1473 $subjectToken = CRM_Utils_Token::getTokens($subject);
1474 $messageToken = CRM_Utils_Token::getTokens($text);
1475 $messageToken = array_merge($messageToken, CRM_Utils_Token::getTokens($html));
1476
1477 $contributionDetails = CRM_Contribute_BAO_Contribution::replaceContributionTokens(
1478 $ids,
1479 $subject,
1480 $subjectToken,
1481 $text,
1482 $html,
1483 $messageToken,
1484 TRUE
1485 );
1486
1487 $this->assertEquals("Contribution Amount: $ 100.00", $contributionDetails[$contactId1]['text'], "The text does not match");
1488 $this->assertEquals("<p>Contribution Source: ABC</p></br>
1489 <p>Contribution Invoice ID: 12345</p></br>
1490 <p>Contribution Receive Date: May 11th, 2015</p></br>", $contributionDetails[$contactId2]['html'], "The html does not match");
1491 }
1492
7b5169d0
PN
1493 /**
1494 * Test for contribution with deferred revenue.
1495 */
1496 public function testContributionWithDeferredRevenue() {
1497 $contactId = $this->individualCreate();
1498 Civi::settings()->set('deferred_revenue_enabled', TRUE);
1499 $params = array(
1500 'contact_id' => $contactId,
1501 'receive_date' => '20120511',
1502 'total_amount' => 100.00,
1503 'financial_type_id' => 'Event Fee',
1504 'trxn_id' => 12345,
1505 'invoice_id' => 67890,
1506 'source' => 'SSF',
1507 'contribution_status_id' => 'Completed',
1508 'revenue_recognition_date' => date('Ymd', strtotime("+3 month")),
1509 );
1510 $contribution = $this->callAPISuccess('contribution', 'create', $params);
1511
1512 $this->callAPISuccessGetCount('EntityFinancialTrxn', array(
1513 'entity_table' => "civicrm_contribution",
1514 'entity_id' => $contribution['id'],
1515 ), 2);
1516
1517 $checkAgainst = array(
1518 'financial_trxn_id.to_financial_account_id.name' => 'Deferred Revenue - Event Fee',
1519 'financial_trxn_id.from_financial_account_id.name' => 'Event Fee',
f818aed5 1520 'financial_trxn_id' => '2',
7b5169d0
PN
1521 );
1522 $result = $this->callAPISuccessGetSingle('EntityFinancialTrxn', array(
1523 'return' => array(
1524 "financial_trxn_id.from_financial_account_id.name",
1525 "financial_trxn_id.to_financial_account_id.name",
1526 "financial_trxn_id",
1527 ),
1528 'entity_table' => "civicrm_contribution",
1529 'entity_id' => $contribution['id'],
1530 'financial_trxn_id.is_payment' => 0,
1531 ), $checkAgainst);
1532
1533 $result = $this->callAPISuccessGetSingle('EntityFinancialTrxn', array(
1534 'entity_table' => "civicrm_financial_item",
1535 'financial_trxn_id' => $result['financial_trxn_id'],
1536 'return' => array('entity_id'),
1537 ));
1538
1539 $checkAgainst = array(
1540 'financial_account_id.name' => 'Deferred Revenue - Event Fee',
1541 'id' => $result['entity_id'],
1542 );
1543 $result = $this->callAPISuccessGetSingle('FinancialItem', array(
1544 'id' => $result['entity_id'],
1545 'return' => array("financial_account_id.name"),
1546 ), $checkAgainst);
1547 }
1548
1db3ddea
KE
1549 /**
1550 * CRM-21424 Check if the receipt update is set after composing the receipt message
1551 */
1552 public function testSendMailUpdateReceiptDate() {
1553 $ids = $values = array();
1554 $contactId = $this->individualCreate();
1555 $params = array(
1556 'contact_id' => $contactId,
1557 'receive_date' => '20120511',
1558 'total_amount' => 100.00,
1559 'financial_type_id' => 'Donation',
1560 'source' => 'SSF',
1561 'contribution_status_id' => 'Completed',
1562 );
1563 /* first test the scenario when sending an email */
1564 $contribution = $this->callAPISuccess('contribution', 'create', $params);
1565 $contributionId = $contribution['id'];
1566 $this->assertDBNull('CRM_Contribute_BAO_Contribution', $contributionId, 'receipt_date', 'id', 'After creating receipt date must be null');
1567 $input = array('receipt_update' => 0);
1568 CRM_Contribute_BAO_Contribution::sendMail($input, $ids, $contributionId, $values);
1569 $this->assertDBNull('CRM_Contribute_BAO_Contribution', $contributionId, 'receipt_date', 'id', 'After sendMail, with the explicit instruction not to update receipt date stays null');
1570 $input = array('receipt_update' => 1);
1571 CRM_Contribute_BAO_Contribution::sendMail($input, $ids, $contributionId, $values);
1572 $this->assertDBNotNull('CRM_Contribute_BAO_Contribution', $contributionId, 'receipt_date', 'id', 'After sendMail with the permission to allow update receipt date must be set');
1573
1574 /* repeat the same scenario for downloading a pdf */
1575 $contribution = $this->callAPISuccess('contribution', 'create', $params);
1576 $contributionId = $contribution['id'];
1577 $this->assertDBNull('CRM_Contribute_BAO_Contribution', $contributionId, 'receipt_date', 'id', 'After creating receipt date must be null');
1578 $input = array('receipt_update' => 0);
1579 /* setting the lasast parameter (returnmessagetext) to TRUE is done by the download of the pdf */
1580 CRM_Contribute_BAO_Contribution::sendMail($input, $ids, $contributionId, $values, TRUE);
1581 $this->assertDBNull('CRM_Contribute_BAO_Contribution', $contributionId, 'receipt_date', 'id', 'After sendMail, with the explicit instruction not to update receipt date stays null');
1582 $input = array('receipt_update' => 1);
1583 CRM_Contribute_BAO_Contribution::sendMail($input, $ids, $contributionId, $values, TRUE);
1584 $this->assertDBNotNull('CRM_Contribute_BAO_Contribution', $contributionId, 'receipt_date', 'id', 'After sendMail with the permission to allow update receipt date must be set');
1585 }
1586
6a488035 1587}