Standardise exception use in test suite
[civicrm-core.git] / tests / phpunit / api / v3 / PaymentTest.php
CommitLineData
b7f554fe
E
1<?php
2/*
3 +--------------------------------------------------------------------+
2fe49090 4 | CiviCRM version 5 |
b7f554fe 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
b7f554fe
E
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 +--------------------------------------------------------------------+
26 */
27
b7f554fe
E
28/**
29 * Test APIv3 civicrm_contribute_* functions
30 *
31 * @package CiviCRM_APIv3
32 * @subpackage API_Contribution
acb109b7 33 * @group headless
b7f554fe
E
34 */
35class api_v3_PaymentTest extends CiviUnitTestCase {
36
b7f554fe 37 protected $_individualId;
d3b3ad06 38
b7f554fe 39 protected $_financialTypeId = 1;
d3b3ad06 40
b7f554fe 41 protected $_apiversion;
d3b3ad06 42
b7f554fe 43 public $debug = 0;
b7f554fe
E
44
45 /**
46 * Setup function.
47 */
48 public function setUp() {
49 parent::setUp();
50
51 $this->_apiversion = 3;
52 $this->_individualId = $this->individualCreate();
d3b3ad06 53 CRM_Core_Config::singleton()->userPermissionClass->permissions = [];
b7f554fe
E
54 }
55
56 /**
57 * Clean up after each test.
fda18dc3 58 *
59 * @throws \Exception
b7f554fe
E
60 */
61 public function tearDown() {
62 $this->quickCleanUpFinancialEntities();
d3b3ad06 63 $this->quickCleanup(['civicrm_uf_match']);
eba13f6d 64 unset(CRM_Core_Config::singleton()->userPermissionClass->permissions);
fda18dc3 65 parent::tearDown();
b7f554fe
E
66 }
67
68 /**
52873538 69 * Test Get Payment api.
b7f554fe
E
70 */
71 public function testGetPayment() {
d3b3ad06 72 $p = [
b7f554fe
E
73 'contact_id' => $this->_individualId,
74 'receive_date' => '2010-01-20',
75 'total_amount' => 100.00,
76 'financial_type_id' => $this->_financialTypeId,
77 'trxn_id' => 23456,
78 'contribution_status_id' => 1,
d3b3ad06 79 ];
b7f554fe
E
80 $contribution = $this->callAPISuccess('contribution', 'create', $p);
81
d3b3ad06 82 $params = [
b7f554fe 83 'contribution_id' => $contribution['id'],
979748a2 84 'check_permissions' => TRUE,
d3b3ad06 85 ];
86 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM', 'administer CiviCRM'];
eba13f6d 87 $payment = $this->callAPIFailure('payment', 'get', $params, 'API permission check failed for Payment/get call; insufficient permission: require access CiviCRM and access CiviContribute');
b7f554fe 88
979748a2 89 array_push(CRM_Core_Config::singleton()->userPermissionClass->permissions, 'access CiviContribute');
c60d3584 90 $payment = $this->callAPISuccess('payment', 'get', $params);
b7f554fe 91
979748a2 92 $payment = $this->callAPIAndDocument('payment', 'get', $params, __FUNCTION__, __FILE__);
b7f554fe 93 $this->assertEquals(1, $payment['count']);
979748a2 94
d3b3ad06 95 $expectedResult = [
96 $contribution['id'] => [
c60d3584
PN
97 'total_amount' => 100,
98 'trxn_id' => 23456,
99 'trxn_date' => '2010-01-20 00:00:00',
100 'contribution_id' => $contribution['id'],
101 'is_payment' => 1,
d3b3ad06 102 ],
103 ];
a44499b4 104 $this->checkPaymentResult($payment, $expectedResult);
d3b3ad06 105 $this->callAPISuccess('Contribution', 'Delete', [
b7f554fe 106 'id' => $contribution['id'],
d3b3ad06 107 ]);
b7f554fe
E
108 }
109
a79d2ec2 110 /**
111 * Test email receipt for partial payment.
112 */
113 public function testPaymentEmailReceipt() {
114 $mut = new CiviMailUtils($this);
115 list($lineItems, $contribution) = $this->createParticipantWithContribution();
0fad34a0 116 $event = $this->callAPISuccess('Event', 'get', []);
117 $this->addLocationToEvent($event['id']);
b5a442ed 118 $params = [
a79d2ec2 119 'contribution_id' => $contribution['id'],
120 'total_amount' => 50,
434546ac 121 'check_number' => '345',
122 'trxn_date' => '2018-08-13 17:57:56',
b5a442ed 123 ];
a79d2ec2 124 $payment = $this->callAPISuccess('payment', 'create', $params);
125 $this->checkPaymentResult($payment, [
126 $payment['id'] => [
127 'from_financial_account_id' => 7,
128 'to_financial_account_id' => 6,
129 'total_amount' => 50,
130 'status_id' => 1,
131 'is_payment' => 1,
132 ],
133 ]);
134
135 $this->callAPISuccess('Payment', 'sendconfirmation', ['id' => $payment['id']]);
136 $mut->assertSubjects(['Payment Receipt - Annual CiviCRM meet']);
d3b3ad06 137 $mut->checkMailLog([
1e477c5b 138 'Dear Anthony,',
a79d2ec2 139 'Total Fees: $ 300.00',
140 'This Payment Amount: $ 50.00',
39b959db
SL
141 //150 was paid in the 1st payment.
142 'Balance Owed: $ 100.00',
a79d2ec2 143 'Event Information and Location',
434546ac 144 'Paid By: Check',
145 'Check Number: 345',
146 'Transaction Date: August 13th, 2018 5:57 PM',
0fad34a0 147 'event place',
148 'streety street',
d3b3ad06 149 ]);
a79d2ec2 150 $mut->stop();
a7b9128b 151 $mut->clearMessages();
a79d2ec2 152 }
153
00ef9b01 154 /**
155 * Test email receipt for partial payment.
1e0f58c7 156 *
157 * @throws \CRM_Core_Exception
00ef9b01 158 */
159 public function testPaymentEmailReceiptFullyPaid() {
160 $mut = new CiviMailUtils($this);
161 list($lineItems, $contribution) = $this->createParticipantWithContribution();
162
163 $params = [
164 'contribution_id' => $contribution['id'],
165 'total_amount' => 150,
166 ];
167 $payment = $this->callAPISuccess('payment', 'create', $params);
168
169 $this->callAPISuccess('Payment', 'sendconfirmation', ['id' => $payment['id']]);
170 $mut->assertSubjects(['Payment Receipt - Annual CiviCRM meet']);
d3b3ad06 171 $mut->checkMailLog([
1e477c5b 172 'Dear Anthony,',
00ef9b01 173 'A payment has been received.',
174 'Total Fees: $ 300.00',
175 'This Payment Amount: $ 150.00',
176 'Balance Owed: $ 0.00',
177 'Thank you for completing payment.',
d3b3ad06 178 ]);
00ef9b01 179 $mut->stop();
180 $mut->clearMessages();
181 }
182
b5a442ed 183 /**
184 * Test email receipt for partial payment.
a7b9128b 185 *
186 * @dataProvider getThousandSeparators
187 *
188 * @param string $thousandSeparator
b5a442ed 189 */
a7b9128b 190 public function testRefundEmailReceipt($thousandSeparator) {
191 $this->setCurrencySeparators($thousandSeparator);
192 $decimalSeparator = ($thousandSeparator === ',' ? '.' : ',');
b5a442ed 193 $mut = new CiviMailUtils($this);
194 list($lineItems, $contribution) = $this->createParticipantWithContribution();
195 $this->callAPISuccess('payment', 'create', [
196 'contribution_id' => $contribution['id'],
197 'total_amount' => 50,
198 'check_number' => '345',
199 'trxn_date' => '2018-08-13 17:57:56',
200 ]);
201
202 $payment = $this->callAPISuccess('payment', 'create', [
203 'contribution_id' => $contribution['id'],
204 'total_amount' => -30,
205 'trxn_date' => '2018-11-13 12:01:56',
52746f6a 206 'sequential' => TRUE,
207 ])['values'][0];
b5a442ed 208
52746f6a 209 $expected = [
210 'from_financial_account_id' => 7,
211 'to_financial_account_id' => 6,
212 'total_amount' => -30,
2561fc11 213 'status_id' => CRM_Core_PseudoConstant::getKey('CRM_Core_BAO_FinancialTrxn', 'status_id', 'Refunded'),
52746f6a 214 'is_payment' => 1,
215 ];
216 foreach ($expected as $key => $value) {
217 $this->assertEquals($expected[$key], $payment[$key], 'mismatch on key ' . $key);
218 }
b5a442ed 219
220 $this->callAPISuccess('Payment', 'sendconfirmation', ['id' => $payment['id']]);
221 $mut->assertSubjects(['Refund Notification - Annual CiviCRM meet']);
d3b3ad06 222 $mut->checkMailLog([
1e477c5b 223 'Dear Anthony,',
00ef9b01 224 'A refund has been issued based on changes in your registration selections.',
a7b9128b 225 'Total Fees: $ 300' . $decimalSeparator . '00',
226 'Refund Amount: $ -30' . $decimalSeparator . '00',
b5a442ed 227 'Event Information and Location',
228 'Paid By: Check',
229 'Transaction Date: November 13th, 2018 12:01 PM',
a7b9128b 230 'You Paid: $ 170' . $decimalSeparator . '00',
d3b3ad06 231 ]);
b5a442ed 232 $mut->stop();
a7b9128b 233 $mut->clearMessages();
b5a442ed 234 }
235
52873538
PN
236 /**
237 * Test create payment api with no line item in params
238 */
b7f554fe 239 public function testCreatePaymentNoLineItems() {
52e3bed0 240 list($lineItems, $contribution) = $this->createParticipantWithContribution();
f5ec2569 241
b7f554fe 242 //Create partial payment
d3b3ad06 243 $params = [
b7f554fe 244 'contribution_id' => $contribution['id'],
52e3bed0 245 'total_amount' => 50,
d3b3ad06 246 ];
8ed3f575 247 $payment = $this->callAPIAndDocument('payment', 'create', $params, __FUNCTION__, __FILE__);
d3b3ad06 248 $expectedResult = [
249 $payment['id'] => [
c60d3584
PN
250 'from_financial_account_id' => 7,
251 'to_financial_account_id' => 6,
252 'total_amount' => 50,
253 'status_id' => 1,
254 'is_payment' => 1,
d3b3ad06 255 ],
256 ];
52e3bed0 257 $this->checkPaymentResult($payment, $expectedResult);
b7f554fe
E
258
259 // Check entity financial trxn created properly
d3b3ad06 260 $params = [
b7f554fe
E
261 'entity_id' => $contribution['id'],
262 'entity_table' => 'civicrm_contribution',
263 'financial_trxn_id' => $payment['id'],
d3b3ad06 264 ];
b7f554fe
E
265
266 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
267
52e3bed0 268 $this->assertEquals($eft['values'][$eft['id']]['amount'], 50);
b7f554fe 269
d3b3ad06 270 $params = [
577daeaa
PN
271 'entity_table' => 'civicrm_financial_item',
272 'financial_trxn_id' => $payment['id'],
d3b3ad06 273 ];
577daeaa 274 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
d3b3ad06 275 $amounts = [33.33, 16.67];
577daeaa
PN
276 foreach ($eft['values'] as $value) {
277 $this->assertEquals($value['amount'], array_pop($amounts));
278 }
279
b7f554fe 280 // Now create payment to complete total amount of contribution
d3b3ad06 281 $params = [
b7f554fe 282 'contribution_id' => $contribution['id'],
52e3bed0 283 'total_amount' => 100,
d3b3ad06 284 ];
c60d3584 285 $payment = $this->callAPISuccess('payment', 'create', $params);
d3b3ad06 286 $expectedResult = [
287 $payment['id'] => [
c60d3584
PN
288 'from_financial_account_id' => 7,
289 'to_financial_account_id' => 6,
290 'total_amount' => 100,
291 'status_id' => 1,
292 'is_payment' => 1,
d3b3ad06 293 ],
294 ];
52e3bed0 295 $this->checkPaymentResult($payment, $expectedResult);
d3b3ad06 296 $params = [
577daeaa
PN
297 'entity_table' => 'civicrm_financial_item',
298 'financial_trxn_id' => $payment['id'],
d3b3ad06 299 ];
577daeaa 300 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
d3b3ad06 301 $amounts = [66.67, 33.33];
577daeaa
PN
302 foreach ($eft['values'] as $value) {
303 $this->assertEquals($value['amount'], array_pop($amounts));
304 }
b7f554fe 305 // Check contribution for completed status
d3b3ad06 306 $contribution = $this->callAPISuccess('contribution', 'get', ['id' => $contribution['id']]);
b7f554fe
E
307
308 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status'], 'Completed');
52e3bed0 309 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 300.00);
d3b3ad06 310 $paymentParticipant = [
577daeaa 311 'contribution_id' => $contribution['id'],
d3b3ad06 312 ];
577daeaa 313 $participantPayment = $this->callAPISuccess('ParticipantPayment', 'getsingle', $paymentParticipant);
d3b3ad06 314 $participant = $this->callAPISuccess('participant', 'get', ['id' => $participantPayment['participant_id']]);
577daeaa 315 $this->assertEquals($participant['values'][$participant['id']]['participant_status'], 'Registered');
d3b3ad06 316 $this->callAPISuccess('Contribution', 'Delete', [
b7f554fe 317 'id' => $contribution['id'],
d3b3ad06 318 ]);
b7f554fe 319 }
f5ec2569 320
52e3bed0
PN
321 /**
322 * Function to assert db values
323 */
324 public function checkPaymentResult($payment, $expectedResult) {
c60d3584 325 foreach ($expectedResult[$payment['id']] as $key => $value) {
2561fc11 326 $this->assertEquals($payment['values'][$payment['id']][$key], $value, 'mismatch on ' . $key);
52e3bed0 327 }
52e3bed0
PN
328 }
329
52873538
PN
330 /**
331 * Test create payment api with line item in params
332 */
b7f554fe 333 public function testCreatePaymentLineItems() {
d1f27fcf 334 list($lineItems, $contribution) = $this->createParticipantWithContribution();
d3b3ad06 335 $lineItems = $this->callAPISuccess('LineItem', 'get', ['contribution_id' => $contribution['id']]);
b7f554fe 336
d1f27fcf 337 //Create partial payment by passing line item array is params
d3b3ad06 338 $params = [
b7f554fe 339 'contribution_id' => $contribution['id'],
d1f27fcf 340 'total_amount' => 50,
d3b3ad06 341 ];
342 $amounts = [40, 10];
d1f27fcf 343 foreach ($lineItems['values'] as $id => $ignore) {
d3b3ad06 344 $params['line_item'][] = [$id => array_pop($amounts)];
d1f27fcf 345 }
8ed3f575 346 $payment = $this->callAPIAndDocument('payment', 'create', $params, __FUNCTION__, __FILE__, 'Payment with line item', 'CreatePaymentWithLineItems');
d3b3ad06 347 $expectedResult = [
348 $payment['id'] => [
c60d3584
PN
349 'from_financial_account_id' => 7,
350 'to_financial_account_id' => 6,
351 'total_amount' => 50,
352 'status_id' => 1,
353 'is_payment' => 1,
d3b3ad06 354 ],
355 ];
d1f27fcf 356 $this->checkPaymentResult($payment, $expectedResult);
b7f554fe
E
357
358 // Check entity financial trxn created properly
d3b3ad06 359 $params = [
b7f554fe
E
360 'entity_id' => $contribution['id'],
361 'entity_table' => 'civicrm_contribution',
362 'financial_trxn_id' => $payment['id'],
d3b3ad06 363 ];
b7f554fe
E
364
365 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
366
d1f27fcf
PN
367 $this->assertEquals($eft['values'][$eft['id']]['amount'], 50);
368
d3b3ad06 369 $params = [
d1f27fcf
PN
370 'entity_table' => 'civicrm_financial_item',
371 'financial_trxn_id' => $payment['id'],
d3b3ad06 372 ];
d1f27fcf 373 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
d3b3ad06 374 $amounts = [40, 10];
d1f27fcf
PN
375 foreach ($eft['values'] as $value) {
376 $this->assertEquals($value['amount'], array_pop($amounts));
377 }
b7f554fe
E
378
379 // Now create payment to complete total amount of contribution
d3b3ad06 380 $params = [
b7f554fe 381 'contribution_id' => $contribution['id'],
d1f27fcf 382 'total_amount' => 100,
d3b3ad06 383 ];
384 $amounts = [80, 20];
d1f27fcf 385 foreach ($lineItems['values'] as $id => $ignore) {
d3b3ad06 386 $params['line_item'][] = [$id => array_pop($amounts)];
d1f27fcf 387 }
c60d3584 388 $payment = $this->callAPISuccess('payment', 'create', $params);
d3b3ad06 389 $expectedResult = [
390 $payment['id'] => [
c60d3584
PN
391 'from_financial_account_id' => 7,
392 'to_financial_account_id' => 6,
393 'total_amount' => 100,
394 'status_id' => 1,
395 'is_payment' => 1,
d3b3ad06 396 ],
397 ];
d1f27fcf 398 $this->checkPaymentResult($payment, $expectedResult);
d3b3ad06 399 $params = [
d1f27fcf
PN
400 'entity_table' => 'civicrm_financial_item',
401 'financial_trxn_id' => $payment['id'],
d3b3ad06 402 ];
d1f27fcf 403 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
d3b3ad06 404 $amounts = [80, 20];
d1f27fcf
PN
405 foreach ($eft['values'] as $value) {
406 $this->assertEquals($value['amount'], array_pop($amounts));
407 }
b7f554fe 408 // Check contribution for completed status
d3b3ad06 409 $contribution = $this->callAPISuccess('contribution', 'get', ['id' => $contribution['id']]);
b7f554fe
E
410
411 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status'], 'Completed');
d1f27fcf 412 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 300.00);
d3b3ad06 413 $paymentParticipant = [
d1f27fcf 414 'contribution_id' => $contribution['id'],
d3b3ad06 415 ];
d1f27fcf 416 $participantPayment = $this->callAPISuccess('ParticipantPayment', 'getsingle', $paymentParticipant);
d3b3ad06 417 $participant = $this->callAPISuccess('participant', 'get', ['id' => $participantPayment['participant_id']]);
d1f27fcf 418 $this->assertEquals($participant['values'][$participant['id']]['participant_status'], 'Registered');
d3b3ad06 419 $this->callAPISuccess('Contribution', 'Delete', [
b7f554fe 420 'id' => $contribution['id'],
d3b3ad06 421 ]);
b7f554fe
E
422 }
423
db62fd2b
PN
424 /**
425 * Test cancel payment api
2fabb298 426 */
db62fd2b 427 public function testCancelPayment() {
d3b3ad06 428 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['administer CiviCRM', 'access CiviContribute'];
db62fd2b
PN
429 list($lineItems, $contribution) = $this->createParticipantWithContribution();
430
d3b3ad06 431 $params = [
db62fd2b 432 'contribution_id' => $contribution['id'],
d3b3ad06 433 ];
db62fd2b 434
979748a2 435 $payment = $this->callAPISuccess('payment', 'get', $params);
db62fd2b
PN
436 $this->assertEquals(1, $payment['count']);
437
d3b3ad06 438 $cancelParams = [
db62fd2b 439 'id' => $payment['id'],
979748a2 440 'check_permissions' => TRUE,
d3b3ad06 441 ];
4f94e3fa 442 $payment = $this->callAPIFailure('payment', 'cancel', $cancelParams, 'API permission check failed for Payment/cancel call; insufficient permission: require access CiviCRM and access CiviContribute and edit contributions');
979748a2 443
eba13f6d 444 array_push(CRM_Core_Config::singleton()->userPermissionClass->permissions, 'access CiviCRM', 'edit contributions');
979748a2 445
8ed3f575 446 $this->callAPIAndDocument('payment', 'cancel', $cancelParams, __FUNCTION__, __FILE__);
db62fd2b 447
c60d3584 448 $payment = $this->callAPISuccess('payment', 'get', $params);
db62fd2b 449 $this->assertEquals(2, $payment['count']);
d3b3ad06 450 $amounts = [-150.00, 150.00];
2fabb298 451 foreach ($payment['values'] as $value) {
db62fd2b
PN
452 $this->assertEquals($value['total_amount'], array_pop($amounts), 'Mismatch total amount');
453 }
454
d3b3ad06 455 $this->callAPISuccess('Contribution', 'Delete', [
db62fd2b 456 'id' => $contribution['id'],
d3b3ad06 457 ]);
db62fd2b
PN
458 }
459
ee1f482b
PN
460 /**
461 * Test delete payment api
462 */
463 public function testDeletePayment() {
d3b3ad06 464 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['administer CiviCRM', 'access CiviContribute'];
ee1f482b
PN
465 list($lineItems, $contribution) = $this->createParticipantWithContribution();
466
d3b3ad06 467 $params = [
ee1f482b 468 'contribution_id' => $contribution['id'],
d3b3ad06 469 ];
ee1f482b 470
c60d3584 471 $payment = $this->callAPISuccess('payment', 'get', $params);
ee1f482b
PN
472 $this->assertEquals(1, $payment['count']);
473
d3b3ad06 474 $deleteParams = [
ee1f482b 475 'id' => $payment['id'],
979748a2 476 'check_permissions' => TRUE,
d3b3ad06 477 ];
4f94e3fa 478 $payment = $this->callAPIFailure('payment', 'delete', $deleteParams, 'API permission check failed for Payment/delete call; insufficient permission: require access CiviCRM and access CiviContribute and delete in CiviContribute');
979748a2 479
eba13f6d 480 array_push(CRM_Core_Config::singleton()->userPermissionClass->permissions, 'access CiviCRM', 'delete in CiviContribute');
8ed3f575 481 $this->callAPIAndDocument('payment', 'delete', $deleteParams, __FUNCTION__, __FILE__);
ee1f482b 482
c60d3584 483 $payment = $this->callAPISuccess('payment', 'get', $params);
ee1f482b
PN
484 $this->assertEquals(0, $payment['count']);
485
d3b3ad06 486 $this->callAPISuccess('Contribution', 'Delete', [
ee1f482b 487 'id' => $contribution['id'],
d3b3ad06 488 ]);
ee1f482b
PN
489 }
490
4cdb5e2f
PN
491 /**
492 * Test update payment api
493 */
494 public function testUpdatePayment() {
d3b3ad06 495 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['administer CiviCRM', 'access CiviContribute', 'edit contributions'];
4cdb5e2f
PN
496 list($lineItems, $contribution) = $this->createParticipantWithContribution();
497
498 //Create partial payment by passing line item array is params
d3b3ad06 499 $params = [
4cdb5e2f
PN
500 'contribution_id' => $contribution['id'],
501 'total_amount' => 50,
d3b3ad06 502 ];
4cdb5e2f 503
c60d3584 504 $payment = $this->callAPISuccess('payment', 'create', $params);
d3b3ad06 505 $expectedResult = [
506 $payment['id'] => [
c60d3584
PN
507 'from_financial_account_id' => 7,
508 'to_financial_account_id' => 6,
509 'total_amount' => 50,
510 'status_id' => 1,
511 'is_payment' => 1,
d3b3ad06 512 ],
513 ];
4cdb5e2f
PN
514 $this->checkPaymentResult($payment, $expectedResult);
515
d3b3ad06 516 $params = [
4cdb5e2f
PN
517 'entity_table' => 'civicrm_financial_item',
518 'financial_trxn_id' => $payment['id'],
d3b3ad06 519 ];
4cdb5e2f 520 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
d3b3ad06 521 $amounts = [33.33, 16.67];
4cdb5e2f
PN
522 foreach ($eft['values'] as $value) {
523 $this->assertEquals($value['amount'], array_pop($amounts));
524 }
d3b3ad06 525 CRM_Core_Config::singleton()->userPermissionClass->permissions = ['administer CiviCRM', 'access CiviContribute'];
4cdb5e2f
PN
526
527 // update the amount for payment
d3b3ad06 528 $params = [
4cdb5e2f
PN
529 'contribution_id' => $contribution['id'],
530 'total_amount' => 100,
531 'id' => $payment['id'],
979748a2 532 'check_permissions' => TRUE,
d3b3ad06 533 ];
4f94e3fa 534 $payment = $this->callAPIFailure('payment', 'create', $params, 'API permission check failed for Payment/create call; insufficient permission: require access CiviCRM and access CiviContribute and edit contributions');
979748a2 535
eba13f6d 536 array_push(CRM_Core_Config::singleton()->userPermissionClass->permissions, 'access CiviCRM', 'edit contributions');
8ed3f575 537 $payment = $this->callAPIAndDocument('payment', 'create', $params, __FUNCTION__, __FILE__, 'Update Payment', 'UpdatePayment');
4cdb5e2f 538
2a84219e 539 // Check for proportional cancelled payment against lineitems.
d3b3ad06 540 $minParams = [
2a84219e
E
541 'entity_table' => 'civicrm_financial_item',
542 'financial_trxn_id' => $payment['id'] - 1,
d3b3ad06 543 ];
2a84219e
E
544
545 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $minParams);
d3b3ad06 546 $amounts = [-33.33, -16.67];
2a84219e
E
547
548 foreach ($eft['values'] as $value) {
549 $this->assertEquals($value['amount'], array_pop($amounts));
550 }
551
552 // Check for proportional updated payment against lineitems.
d3b3ad06 553 $params = [
4cdb5e2f
PN
554 'entity_table' => 'civicrm_financial_item',
555 'financial_trxn_id' => $payment['id'],
d3b3ad06 556 ];
4cdb5e2f 557 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
d3b3ad06 558 $amounts = [66.67, 33.33];
4cdb5e2f
PN
559 foreach ($eft['values'] as $value) {
560 $this->assertEquals($value['amount'], array_pop($amounts));
561 }
562
d3b3ad06 563 $params = [
4cdb5e2f 564 'contribution_id' => $contribution['id'],
d3b3ad06 565 ];
c60d3584 566 $payment = $this->callAPISuccess('payment', 'get', $params);
d3b3ad06 567 $amounts = [100.00, -50.00, 50.00, 150.00];
4cdb5e2f
PN
568 foreach ($payment['values'] as $value) {
569 $amount = array_pop($amounts);
570 $this->assertEquals($value['total_amount'], $amount, 'Mismatch total amount');
571
572 // Check entity financial trxn created properly
d3b3ad06 573 $params = [
4cdb5e2f
PN
574 'entity_id' => $contribution['id'],
575 'entity_table' => 'civicrm_contribution',
576 'financial_trxn_id' => $value['id'],
d3b3ad06 577 ];
4cdb5e2f
PN
578 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
579 $this->assertEquals($eft['values'][$eft['id']]['amount'], $amount);
580 }
581
d3b3ad06 582 $this->callAPISuccess('Contribution', 'Delete', [
4cdb5e2f 583 'id' => $contribution['id'],
d3b3ad06 584 ]);
4cdb5e2f
PN
585 }
586
c60d3584
PN
587 /**
588 * Test create payment api for paylater contribution
589 */
590 public function testCreatePaymentPayLater() {
591 $this->createLoggedInUser();
d3b3ad06 592 $contributionParams = [
c60d3584
PN
593 'total_amount' => 100,
594 'currency' => 'USD',
595 'contact_id' => $this->_individualId,
596 'financial_type_id' => 1,
597 'contribution_status_id' => 2,
598 'is_pay_later' => 1,
d3b3ad06 599 ];
c60d3584 600 $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams);
8ed3f575 601 //add payment for pay later transaction
d3b3ad06 602 $params = [
c60d3584
PN
603 'contribution_id' => $contribution['id'],
604 'total_amount' => 100,
d3b3ad06 605 ];
c60d3584 606 $payment = $this->callAPISuccess('Payment', 'create', $params);
d3b3ad06 607 $expectedResult = [
608 $payment['id'] => [
c60d3584
PN
609 'from_financial_account_id' => 7,
610 'to_financial_account_id' => 6,
611 'total_amount' => 100,
612 'status_id' => 1,
613 'is_payment' => 1,
d3b3ad06 614 ],
615 ];
c60d3584
PN
616 $this->checkPaymentResult($payment, $expectedResult);
617 // Check entity financial trxn created properly
d3b3ad06 618 $params = [
c60d3584
PN
619 'entity_id' => $contribution['id'],
620 'entity_table' => 'civicrm_contribution',
621 'financial_trxn_id' => $payment['id'],
d3b3ad06 622 ];
c60d3584
PN
623 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
624 $this->assertEquals($eft['values'][$eft['id']]['amount'], 100);
d3b3ad06 625 $params = [
c60d3584
PN
626 'entity_table' => 'civicrm_financial_item',
627 'financial_trxn_id' => $payment['id'],
d3b3ad06 628 ];
c60d3584
PN
629 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
630 $this->assertEquals($eft['values'][$eft['id']]['amount'], 100);
631 // Check contribution for completed status
d3b3ad06 632 $contribution = $this->callAPISuccess('contribution', 'get', ['id' => $contribution['id']]);
c60d3584
PN
633 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status'], 'Completed');
634 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
d3b3ad06 635 $this->callAPISuccess('Contribution', 'Delete', [
c60d3584 636 'id' => $contribution['id'],
d3b3ad06 637 ]);
c60d3584
PN
638 }
639
d5b39a17 640 /**
8d54448e 641 * Test create payment api for pay later contribution with partial payment.
642 *
643 * @throws \Exception
d5b39a17
PN
644 */
645 public function testCreatePaymentPayLaterPartialPayment() {
646 $this->createLoggedInUser();
d3b3ad06 647 $contributionParams = [
d5b39a17
PN
648 'total_amount' => 100,
649 'currency' => 'USD',
650 'contact_id' => $this->_individualId,
651 'financial_type_id' => 1,
652 'contribution_status_id' => 2,
653 'is_pay_later' => 1,
d3b3ad06 654 ];
d5b39a17
PN
655 $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams);
656 //Create partial payment
d3b3ad06 657 $params = [
d5b39a17
PN
658 'contribution_id' => $contribution['id'],
659 'total_amount' => 60,
d3b3ad06 660 ];
d5b39a17 661 $payment = $this->callAPISuccess('Payment', 'create', $params);
d3b3ad06 662 $expectedResult = [
663 $payment['id'] => [
d5b39a17
PN
664 'total_amount' => 60,
665 'status_id' => 1,
666 'is_payment' => 1,
d3b3ad06 667 ],
668 ];
d5b39a17
PN
669 $this->checkPaymentResult($payment, $expectedResult);
670 // Check entity financial trxn created properly
d3b3ad06 671 $params = [
d5b39a17
PN
672 'entity_id' => $contribution['id'],
673 'entity_table' => 'civicrm_contribution',
674 'financial_trxn_id' => $payment['id'],
d3b3ad06 675 ];
d5b39a17
PN
676 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
677 $this->assertEquals($eft['values'][$eft['id']]['amount'], 60);
d3b3ad06 678 $params = [
d5b39a17
PN
679 'entity_table' => 'civicrm_financial_item',
680 'financial_trxn_id' => $payment['id'],
d3b3ad06 681 ];
d5b39a17
PN
682 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
683 $this->assertEquals($eft['values'][$eft['id']]['amount'], 60);
d3b3ad06 684 $contribution = $this->callAPISuccess('contribution', 'get', ['id' => $contribution['id']]);
d5b39a17
PN
685 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status'], 'Partially paid');
686 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
687 //Create full payment
d3b3ad06 688 $params = [
d5b39a17
PN
689 'contribution_id' => $contribution['id'],
690 'total_amount' => 40,
d3b3ad06 691 ];
0a201857 692 // Rename the 'completed' status label first to check that we are not using the labels!
693 $this->callAPISuccess('OptionValue', 'get', ['name' => 'Completed', 'option_group_id' => 'contribution_status', 'api.OptionValue.create' => ['label' => 'Unicorn']]);
d5b39a17 694 $payment = $this->callAPISuccess('Payment', 'create', $params);
d3b3ad06 695 $expectedResult = [
696 $payment['id'] => [
d5b39a17
PN
697 'from_financial_account_id' => 7,
698 'to_financial_account_id' => 6,
699 'total_amount' => 40,
700 'status_id' => 1,
701 'is_payment' => 1,
d3b3ad06 702 ],
703 ];
d5b39a17
PN
704 $this->checkPaymentResult($payment, $expectedResult);
705 // Check entity financial trxn created properly
d3b3ad06 706 $params = [
d5b39a17
PN
707 'entity_id' => $contribution['id'],
708 'entity_table' => 'civicrm_contribution',
709 'financial_trxn_id' => $payment['id'],
d3b3ad06 710 ];
d5b39a17
PN
711 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
712 $this->assertEquals($eft['values'][$eft['id']]['amount'], 40);
d3b3ad06 713 $params = [
d5b39a17
PN
714 'entity_table' => 'civicrm_financial_item',
715 'financial_trxn_id' => $payment['id'],
d3b3ad06 716 ];
d5b39a17
PN
717 $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params);
718 $this->assertEquals($eft['values'][$eft['id']]['amount'], 40);
719 // Check contribution for completed status
d3b3ad06 720 $contribution = $this->callAPISuccess('contribution', 'get', ['id' => $contribution['id']]);
0a201857 721 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status'], 'Unicorn');
d5b39a17 722 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
d3b3ad06 723 $this->callAPISuccess('Contribution', 'Delete', [
d5b39a17 724 'id' => $contribution['id'],
d3b3ad06 725 ]);
0a201857 726 $this->callAPISuccess('OptionValue', 'get', ['name' => 'Completed', 'option_group_id' => 'contribution_status', 'api.OptionValue.create' => ['label' => 'Completed']]);
8d54448e 727 $this->callAPISuccessGetCount('Activity', ['target_contact_id' => $this->_individualId, 'activity_type_id' => 'Payment'], 2);
d5b39a17
PN
728 }
729
0fad34a0 730 /**
731 * Add a location to our event.
732 *
733 * @param int $eventID
734 */
735 protected function addLocationToEvent($eventID) {
736 $addressParams = [
737 'name' => 'event place',
738 'street_address' => 'streety street',
739 'location_type_id' => 1,
740 'is_primary' => 1,
741 ];
742 // api requires contact_id - perhaps incorrectly but use add to get past that.
743 $address = CRM_Core_BAO_Address::add($addressParams);
744
745 $location = $this->callAPISuccess('LocBlock', 'create', ['address_id' => $address->id]);
746 $this->callAPISuccess('Event', 'create', [
747 'id' => $eventID,
748 'loc_block_id' => $location['id'],
749 'is_show_location' => TRUE,
750 ]);
751 }
752
b7f554fe 753}