Switch to greeting for better, more consistent results in tpl, remove print statement
[civicrm-core.git] / tests / phpunit / CRM / Contribute / Form / AdditionalPaymentTest.php
CommitLineData
61bfc595
PN
1<?php
2/*
3 +--------------------------------------------------------------------+
2fe49090 4 | CiviCRM version 5 |
61bfc595 5 +--------------------------------------------------------------------+
6b83d5bd 6 | Copyright CiviCRM LLC (c) 2004-2019 |
61bfc595
PN
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
28/**
29 * Test APIv3 civicrm_contribute_* functions
30 *
31 * @package CiviCRM_APIv3
32 * @subpackage API_Contribution
33 * @group headless
34 */
35class CRM_Contribute_Form_AdditionalPaymentTest extends CiviUnitTestCase {
36
37 /**
38 * Contact ID.
39 *
40 * @var int
41 */
42 protected $_individualId;
43
44 /**
45 * Parameters to create contribution.
46 *
47 * @var array
48 */
49 protected $_params;
50
51 /**
52 * Contribution ID.
53 *
54 * @var int
55 */
56 protected $_contributionId;
57
58 /**
59 * Parameters to create payment processor.
60 *
61 * @var array
62 */
63 protected $_processorParams = array();
64
65 /**
66 * Payment instrument mapping.
67 *
68 * @var array
69 */
70 protected $paymentInstruments = array();
71
72 /**
73 * Dummy payment processor.
74 *
75 * @var CRM_Core_Payment_Dummy
76 */
77 protected $paymentProcessor;
78
79 /**
80 * Payment processor ID.
81 *
82 * @var int
83 */
84 protected $paymentProcessorID;
85
86 /**
87 * Setup function.
88 */
89 public function setUp() {
90 parent::setUp();
91 $this->createLoggedInUser();
92
93 $this->_individualId = $this->individualCreate();
94 $this->_params = array(
95 'total_amount' => 100,
96 'currency' => 'USD',
97 'contact_id' => $this->_individualId,
98 'financial_type_id' => 1,
99 );
100 $this->_processorParams = array(
101 'domain_id' => 1,
102 'name' => 'Dummy',
103 'payment_processor_type_id' => 10,
104 'financial_account_id' => 12,
105 'is_active' => 1,
106 'user_name' => '',
107 'url_site' => 'http://dummy.com',
108 'url_recur' => 'http://dummy.com',
109 'billing_mode' => 1,
110 );
111
112 $instruments = $this->callAPISuccess('contribution', 'getoptions', array('field' => 'payment_instrument_id'));
113 $this->paymentInstruments = $instruments['values'];
114
115 $this->paymentProcessor = $this->dummyProcessorCreate();
116 $processor = $this->paymentProcessor->getPaymentProcessor();
117 $this->paymentProcessorID = $processor['id'];
118 }
119
120 /**
121 * Clean up after each test.
122 */
123 public function tearDown() {
124 $this->quickCleanUpFinancialEntities();
125 parent::tearDown();
126 }
127
128 /**
129 * Test the submit function that completes the partially paid Contribution using Credit Card.
80c9b98c 130 */
61bfc595 131 public function testAddPaymentUsingCreditCardForPartialyPaidContribution() {
ecddfe70 132 $mut = new CiviMailUtils($this, TRUE);
61bfc595
PN
133 $this->createContribution('Partially paid');
134
135 // pay additional amount by using Credit Card
ecddfe70 136 $this->submitPayment(70, 'live', TRUE);
61bfc595 137 $this->checkResults(array(30, 70), 2);
ecddfe70 138 $mut->assertSubjects(['Payment Receipt -']);
139 $mut->checkMailLog([
1e477c5b 140 'Dear Anthony,',
ecddfe70 141 'Payment Details',
142 'Total Fees: $ 100.00',
143 'This Payment Amount: $ 70.00',
144 'Balance Owed: $ 0.00 ',
1e477c5b 145 'Billing Name and Address',
146 'Vancouver, AE 1321312',
147 'Visa',
148 '***********1111',
149 'Expires: May 2025',
ecddfe70 150 ]);
151
152 $mut->stop();
61bfc595 153 }
61bfc595
PN
154
155 /**
156 * Test the submit function that completes the partially paid Contribution.
157 */
158 public function testAddPaymentForPartialyPaidContribution() {
159 $this->createContribution('Partially paid');
160
161 // pay additional amount
162 $this->submitPayment(70);
163 $this->checkResults(array(30, 70), 2);
164 }
165
166 /**
167 * Test the submit function that completes the partially paid Contribution with multiple payments.
168 */
169 public function testMultiplePaymentForPartialyPaidContribution() {
170 $this->createContribution('Partially paid');
171
172 // pay additional amount
173 $this->submitPayment(50);
174 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
175 $this->assertEquals('Partially paid', $contribution['contribution_status']);
176
177 // pay additional amount
178 $this->submitPayment(20);
179 $this->checkResults(array(30, 50, 20), 3);
180 }
80c9b98c 181
61bfc595
PN
182 /**
183 * Test the submit function that completes the partially paid Contribution with multiple payments.
80c9b98c
PN
184 */
185 public function testMultiplePaymentForPartiallyPaidContributionWithOneCreditCardPayment() {
b852b979 186 $mut = new CiviMailUtils($this, TRUE);
61bfc595
PN
187 $this->createContribution('Partially paid');
188
189 // pay additional amount
b852b979 190 $this->submitPayment(50, NULL, TRUE);
61bfc595
PN
191 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
192 $this->assertEquals('Partially paid', $contribution['contribution_status']);
193
194 // pay additional amount by using credit card
195 $this->submitPayment(20, 'live');
196 $this->checkResults(array(30, 50, 20), 3);
b852b979 197 $mut->assertSubjects(array('Payment Receipt -'));
198 $mut->checkMailLog(array(
6915ff5e 199 'Dear Anthony,',
b852b979 200 'A payment has been received',
201 'Total Fees: $ 100.00',
202 'This Payment Amount: $ 50.00',
203 'Balance Owed: $ 20.00 ',
204 'Paid By: Check',
205 'Check Number: check-12345',
206 ));
207 $mut->stop();
61bfc595
PN
208 }
209
61bfc595
PN
210 /**
211 * Test the submit function that completes the pending pay later Contribution using Credit Card.
80c9b98c 212 */
61bfc595
PN
213 public function testAddPaymentUsingCreditCardForPendingPayLaterContribution() {
214 $this->createContribution('Pending');
215
216 // pay additional amount by using Credit Card
217 $this->submitPayment(100, 'live');
218 $this->checkResults(array(100), 1);
219 }
61bfc595
PN
220
221 /**
222 * Test the submit function that completes the pending pay later Contribution.
223 */
224 public function testAddPaymentForPendingPayLaterContribution() {
225 $this->createContribution('Pending');
226
227 // pay additional amount
228 $this->submitPayment(70);
229 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
230 $this->assertEquals('Partially paid', $contribution['contribution_status']);
231
232 // pay additional amount
233 $this->submitPayment(30);
234 $this->checkResults(array(30, 70), 2);
235 }
236
425f113a
AP
237 /**
238 * Test the Membership status after completing the pending pay later Contribution.
239 */
240 public function testMembershipStatusAfterCompletingPayLaterContribution() {
241 $this->createContribution('Pending');
242 $membership = $this->createPendingMembershipAndRecordContribution($this->_contributionId);
243 // pay additional amount
244 $this->submitPayment(100);
245 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
246 $contributionMembership = $this->callAPISuccessGetSingle('Membership', array('id' => $membership["id"]));
247 $membershipStatus = $this->callAPISuccessGetSingle('MembershipStatus', array('id' => $contributionMembership["status_id"]));
154bef4d 248 $this->assertEquals('New', $membershipStatus['name']);
425f113a
AP
249 }
250
251 private function createPendingMembershipAndRecordContribution($contributionId) {
252 $this->_individualId = $this->individualCreate();
253 $membershipTypeAnnualFixed = $this->callAPISuccess('membership_type', 'create', array(
254 'domain_id' => 1,
255 'name' => "AnnualFixed",
256 'member_of_contact_id' => 1,
257 'duration_unit' => "year",
258 'duration_interval' => 1,
259 'period_type' => "fixed",
260 'fixed_period_start_day' => "101",
261 'fixed_period_rollover_day' => "1231",
262 'relationship_type_id' => 20,
263 'financial_type_id' => 2,
264 ));
265 $membershipStatuses = CRM_Member_PseudoConstant::membershipStatus();
266 $pendingStatusId = array_search('Pending', $membershipStatuses);
267 $membership = $this->callAPISuccess('Membership', 'create', array(
268 'contact_id' => $this->_individualId,
269 'membership_type_id' => $membershipTypeAnnualFixed['id'],
270 ));
271 // Updating Membership status to Pending
272 $membership = $this->callAPISuccess('Membership', 'create', array(
273 'id' => $membership["id"],
274 'status_id' => $pendingStatusId,
275 ));
276 $membershipPayment = $this->callAPISuccess('MembershipPayment', 'create', array(
277 'membership_id' => $membership["id"],
278 'contribution_id' => $contributionId,
279 ));
280 return $membership;
281 }
282
61bfc595
PN
283 /**
284 * Test the submit function that completes the pending pay later Contribution with multiple payments.
285 */
286 public function testMultiplePaymentForPendingPayLaterContribution() {
287 $this->createContribution('Pending');
288
289 // pay additional amount
290 $this->submitPayment(40);
291 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
292 $this->assertEquals('Partially paid', $contribution['contribution_status']);
293
294 $this->submitPayment(20);
295 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
296 $this->assertEquals('Partially paid', $contribution['contribution_status']);
297
298 $this->submitPayment(30);
299 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
300 $this->assertEquals('Partially paid', $contribution['contribution_status']);
301
302 $this->submitPayment(10);
303 $this->checkResults(array(40, 20, 30, 10), 4);
304 }
305
306 /**
307 * Test the submit function that completes the pending pay later Contribution with multiple payments.
80c9b98c 308 */
61bfc595
PN
309 public function testMultiplePaymentForPendingPayLaterContributionWithOneCreditCardPayment() {
310 $this->createContribution('Pending');
311
312 // pay additional amount
313 $this->submitPayment(50);
314 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
315 $this->assertEquals('Partially paid', $contribution['contribution_status']);
316
317 $this->submitPayment(20, 'live');
318 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
319 $this->assertEquals('Partially paid', $contribution['contribution_status']);
320
321 $this->submitPayment(20);
322 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
323 $this->assertEquals('Partially paid', $contribution['contribution_status']);
324
325 $this->submitPayment(10, 'live');
326 $this->checkResults(array(50, 20, 20, 10), 4);
327 }
61bfc595
PN
328
329 /**
330 * Function to create pending pay later or partially paid conntribution.
331 *
332 * @param string $typeofContribution
333 *
334 */
335 public function createContribution($typeofContribution = 'Pending') {
336 if ($typeofContribution == 'Partially paid') {
337 $contributionParams = array_merge($this->_params, array(
338 'partial_payment_total' => 100.00,
f49cdeab 339 'partial_amount_to_pay' => 30,
61bfc595
PN
340 'contribution_status_id' => 1,
341 ));
342 }
343 elseif ($typeofContribution == 'Pending') {
344 $contributionParams = array_merge($this->_params, array(
345 'contribution_status_id' => 2,
346 'is_pay_later' => 1,
347 ));
348 }
349 $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams);
350 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $contribution['id']));
351 $this->assertNotEmpty($contribution);
352 $this->assertEquals($typeofContribution, $contribution['contribution_status']);
353 $this->_contributionId = $contribution['id'];
354 }
355
356 /**
357 * Function to submit payments for contribution.
358 *
359 * @param float $amount
360 * Payment Amount
361 * @param string $mode
362 * Mode of Payment
ecddfe70 363 * @param bool $isEmailReceipt
61bfc595 364 */
ecddfe70 365 public function submitPayment($amount, $mode = NULL, $isEmailReceipt = FALSE) {
61bfc595
PN
366 $form = new CRM_Contribute_Form_AdditionalPayment();
367
368 $submitParams = array(
369 'contribution_id' => $this->_contributionId,
370 'contact_id' => $this->_individualId,
371 'total_amount' => $amount,
372 'currency' => 'USD',
373 'financial_type_id' => 1,
374 'receive_date' => '04/21/2015',
375 'receive_date_time' => '11:27PM',
376 'trxn_date' => '2017-04-11 13:05:11',
80c9b98c 377 'payment_processor_id' => 0,
ecddfe70 378 'is_email_receipt' => $isEmailReceipt,
379 'from_email_address' => 'site@something.com',
61bfc595
PN
380 );
381 if ($mode) {
382 $submitParams += array(
ecddfe70 383 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments),
61bfc595
PN
384 'payment_processor_id' => $this->paymentProcessorID,
385 'credit_card_exp_date' => array('M' => 5, 'Y' => 2025),
386 'credit_card_number' => '411111111111111',
387 'cvv2' => 234,
388 'credit_card_type' => 'Visa',
389 'billing_city-5' => 'Vancouver',
390 'billing_state_province_id-5' => 1059,
391 'billing_postal_code-5' => 1321312,
392 'billing_country_id-5' => 1228,
393 );
394 }
395 else {
396 $submitParams += array(
397 'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
398 'check_number' => 'check-12345',
399 );
400 }
23cb875c 401 $form->cid = $this->_individualId;
61bfc595
PN
402 $form->testSubmit($submitParams, $mode);
403 }
404
405 /**
406 * Function to check result.
407 *
408 * @param array $amounts
409 * Array of payment amount for contribution
410 * @param int $count
411 * Number payment for contribution
412 *
413 */
414 public function checkResults($amounts, $count) {
415 $contribution = $this->callAPISuccessGetSingle('Contribution', array('id' => $this->_contributionId));
416 $this->assertNotEmpty($contribution);
417 $this->assertEquals('Completed', $contribution['contribution_status']);
418
419 $this->callAPISuccessGetCount('EntityFinancialTrxn', array(
420 'entity_table' => "civicrm_contribution",
421 'entity_id' => $this->_contributionId,
422 'financial_trxn_id.is_payment' => 1,
423 'financial_trxn_id.total_amount' => array('IN' => $amounts),
424 ), $count);
425 }
426
427}