Merge pull request #8962 from KarinG/patch-1
[civicrm-core.git] / tests / phpunit / api / v3 / ContributionTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
81621fee 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
fa938177 6 | Copyright CiviCRM LLC (c) 2004-2016 |
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
6a488035
TO
28/**
29 * Test APIv3 civicrm_contribute_* functions
30 *
6c6e6187
TO
31 * @package CiviCRM_APIv3
32 * @subpackage API_Contribution
acb109b7 33 * @group headless
6a488035 34 */
6a488035
TO
35class api_v3_ContributionTest extends CiviUnitTestCase {
36
37 /**
fe482240 38 * Assume empty database with just civicrm_data.
6a488035
TO
39 */
40 protected $_individualId;
41 protected $_contribution;
4ab7d517 42 protected $_financialTypeId = 1;
6a488035
TO
43 protected $_apiversion;
44 protected $_entity = 'Contribution';
45 public $debug = 0;
46 protected $_params;
858d0bf8
EM
47 protected $_ids = array();
48 protected $_pageParams = array();
1eade77d 49 /**
50 * Payment processor ID (dummy processor).
51 *
52 * @var int
53 */
54 protected $paymentProcessorID;
b7c9bc4c 55
1e52837d
EM
56 /**
57 * Parameters to create payment processor.
58 *
59 * @var array
60 */
61 protected $_processorParams = array();
62
63 /**
64 * ID of created event.
65 *
66 * @var int
67 */
68 protected $_eventID;
69
ec7e3954
E
70 /**
71 * @var CiviMailUtils
72 */
73 protected $mut;
74
22f80e87
EM
75 /**
76 * Setup function.
77 */
00be9182 78 public function setUp() {
6a488035
TO
79 parent::setUp();
80
81 $this->_apiversion = 3;
82 $this->_individualId = $this->individualCreate();
6a488035
TO
83 $this->_params = array(
84 'contact_id' => $this->_individualId,
85 'receive_date' => '20120511',
86 'total_amount' => 100.00,
5896d037 87 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
88 'non_deductible_amount' => 10.00,
89 'fee_amount' => 5.00,
90 'net_amount' => 95.00,
91 'source' => 'SSF',
92 'contribution_status_id' => 1,
6a488035
TO
93 );
94 $this->_processorParams = array(
95 'domain_id' => 1,
96 'name' => 'Dummy',
97502bac 97 'payment_processor_type_id' => CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_PaymentProcessor', 'payment_processor_type_id', 'Dummy'),
6a488035
TO
98 'financial_account_id' => 12,
99 'is_active' => 1,
100 'user_name' => '',
101 'url_site' => 'http://dummy.com',
102 'url_recur' => 'http://dummy.com',
103 'billing_mode' => 1,
104 );
1eade77d 105 $this->paymentProcessorID = $this->processorCreate();
6a488035 106 $this->_pageParams = array(
6a488035
TO
107 'title' => 'Test Contribution Page',
108 'financial_type_id' => 1,
109 'currency' => 'USD',
110 'financial_account_id' => 1,
1eade77d 111 'payment_processor' => $this->paymentProcessorID,
6a488035
TO
112 'is_active' => 1,
113 'is_allow_other_amount' => 1,
114 'min_amount' => 10,
115 'max_amount' => 1000,
5896d037 116 );
6a488035
TO
117 }
118
22f80e87
EM
119 /**
120 * Clean up after each test.
121 */
00be9182 122 public function tearDown() {
39d632fd 123 $this->quickCleanUpFinancialEntities();
225d474b 124 $this->quickCleanup(array('civicrm_uf_match'));
6a488035
TO
125 }
126
22f80e87
EM
127 /**
128 * Test Get.
129 */
00be9182 130 public function testGetContribution() {
6a488035
TO
131 $p = array(
132 'contact_id' => $this->_individualId,
133 'receive_date' => '2010-01-20',
134 'total_amount' => 100.00,
4ab7d517 135 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
136 'non_deductible_amount' => 10.00,
137 'fee_amount' => 5.00,
138 'net_amount' => 95.00,
139 'trxn_id' => 23456,
140 'invoice_id' => 78910,
141 'source' => 'SSF',
142 'contribution_status_id' => 1,
6a488035 143 );
2f45e1c2 144 $this->_contribution = $this->callAPISuccess('contribution', 'create', $p);
6a488035
TO
145
146 $params = array(
147 'contribution_id' => $this->_contribution['id'],
6a488035 148 );
e0e3c51b 149
2f45e1c2 150 $contribution = $this->callAPIAndDocument('contribution', 'get', $params, __FUNCTION__, __FILE__);
4ab7d517 151 $financialParams['id'] = $this->_financialTypeId;
6c6e6187 152 $default = NULL;
858d0bf8 153 CRM_Financial_BAO_FinancialType::retrieve($financialParams, $default);
2f45e1c2 154
e0e3c51b 155 $this->assertEquals(1, $contribution['count']);
2bfae985 156 $this->assertEquals($contribution['values'][$contribution['id']]['contact_id'], $this->_individualId);
22f80e87
EM
157 // Note there was an assertion converting financial_type_id to 'Donation' which wasn't working.
158 // Passing back a string rather than an id seems like an error/cruft.
159 // If it is to be introduced we should discuss.
6a488035 160 $this->assertEquals($contribution['values'][$contribution['id']]['financial_type_id'], 1);
2bfae985
EM
161 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
162 $this->assertEquals($contribution['values'][$contribution['id']]['non_deductible_amount'], 10.00);
163 $this->assertEquals($contribution['values'][$contribution['id']]['fee_amount'], 5.00);
164 $this->assertEquals($contribution['values'][$contribution['id']]['net_amount'], 95.00);
165 $this->assertEquals($contribution['values'][$contribution['id']]['trxn_id'], 23456);
166 $this->assertEquals($contribution['values'][$contribution['id']]['invoice_id'], 78910);
167 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_source'], 'SSF');
168 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status'], 'Completed');
22f80e87 169 // Create a second contribution - we are testing that 'id' gets the right contribution id (not the contact id).
6a488035
TO
170 $p['trxn_id'] = '3847';
171 $p['invoice_id'] = '3847';
172
2f45e1c2 173 $contribution2 = $this->callAPISuccess('contribution', 'create', $p);
174
22f80e87 175 // Now we have 2 - test getcount.
4ab7d517 176 $contribution = $this->callAPISuccess('contribution', 'getcount', array());
6a488035 177 $this->assertEquals(2, $contribution);
22f80e87 178 // Test id only format.
4ab7d517 179 $contribution = $this->callAPISuccess('contribution', 'get', array(
180 'id' => $this->_contribution['id'],
181 'format.only_id' => 1,
182 ));
22f80e87
EM
183 $this->assertEquals($this->_contribution['id'], $contribution, print_r($contribution, TRUE));
184 // Test id only format.
2f45e1c2 185 $contribution = $this->callAPISuccess('contribution', 'get', array(
4ab7d517 186 'id' => $contribution2['id'],
187 'format.only_id' => 1,
188 ));
189 $this->assertEquals($contribution2['id'], $contribution);
22f80e87 190 // Test id as field.
4ab7d517 191 $contribution = $this->callAPISuccess('contribution', 'get', array(
192 'id' => $this->_contribution['id'],
193 ));
2bfae985 194 $this->assertEquals(1, $contribution['count']);
4ab7d517 195
22f80e87 196 // Test get by contact id works.
4ab7d517 197 $contribution = $this->callAPISuccess('contribution', 'get', array('contact_id' => $this->_individualId));
6a488035 198
2bfae985 199 $this->assertEquals(2, $contribution['count']);
2f45e1c2 200 $this->callAPISuccess('Contribution', 'Delete', array(
6a488035 201 'id' => $this->_contribution['id'],
4ab7d517 202 ));
2f45e1c2 203 $this->callAPISuccess('Contribution', 'Delete', array(
6a488035 204 'id' => $contribution2['id'],
4ab7d517 205 ));
6a488035
TO
206 }
207
71d5a412 208 /**
209 * Test that test contributions can be retrieved.
210 */
211 public function testGetTestContribution() {
212 $this->callAPISuccess('Contribution', 'create', array_merge($this->_params, array('is_test' => 1)));
213 $this->callAPISuccessGetSingle('Contribution', array('is_test' => 1));
214 }
215
6c6e6187 216 /**
22f80e87 217 * We need to ensure previous tested behaviour still works as part of the api contract.
6c6e6187 218 */
00be9182 219 public function testGetContributionLegacyBehaviour() {
6a488035
TO
220 $p = array(
221 'contact_id' => $this->_individualId,
222 'receive_date' => '2010-01-20',
223 'total_amount' => 100.00,
4ab7d517 224 'contribution_type_id' => $this->_financialTypeId,
6a488035
TO
225 'non_deductible_amount' => 10.00,
226 'fee_amount' => 5.00,
227 'net_amount' => 95.00,
228 'trxn_id' => 23456,
229 'invoice_id' => 78910,
230 'source' => 'SSF',
231 'contribution_status_id' => 1,
6a488035 232 );
71d5a412 233 $this->_contribution = $this->callAPISuccess('Contribution', 'create', $p);
6a488035
TO
234
235 $params = array(
236 'contribution_id' => $this->_contribution['id'],
6a488035 237 );
2f45e1c2 238 $contribution = $this->callAPIAndDocument('contribution', 'get', $params, __FUNCTION__, __FILE__);
4ab7d517 239 $financialParams['id'] = $this->_financialTypeId;
6c6e6187 240 $default = NULL;
858d0bf8 241 CRM_Financial_BAO_FinancialType::retrieve($financialParams, $default);
2f45e1c2 242
6c6e6187 243 $this->assertEquals(1, $contribution['count']);
2bfae985 244 $this->assertEquals($contribution['values'][$contribution['id']]['contact_id'], $this->_individualId);
4ab7d517 245 $this->assertEquals($contribution['values'][$contribution['id']]['financial_type_id'], $this->_financialTypeId);
246 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_type_id'], $this->_financialTypeId);
2bfae985
EM
247 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
248 $this->assertEquals($contribution['values'][$contribution['id']]['non_deductible_amount'], 10.00);
249 $this->assertEquals($contribution['values'][$contribution['id']]['fee_amount'], 5.00);
250 $this->assertEquals($contribution['values'][$contribution['id']]['net_amount'], 95.00);
251 $this->assertEquals($contribution['values'][$contribution['id']]['trxn_id'], 23456);
252 $this->assertEquals($contribution['values'][$contribution['id']]['invoice_id'], 78910);
253 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_source'], 'SSF');
254 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status'], 'Completed');
22f80e87
EM
255
256 // Create a second contribution - we are testing that 'id' gets the right contribution id (not the contact id).
6a488035
TO
257 $p['trxn_id'] = '3847';
258 $p['invoice_id'] = '3847';
259
2f45e1c2 260 $contribution2 = $this->callAPISuccess('contribution', 'create', $p);
6a488035 261
6a488035 262 // now we have 2 - test getcount
4ab7d517 263 $contribution = $this->callAPISuccess('contribution', 'getcount', array());
6a488035
TO
264 $this->assertEquals(2, $contribution);
265 //test id only format
4ab7d517 266 $contribution = $this->callAPISuccess('contribution', 'get', array(
267 'id' => $this->_contribution['id'],
268 'format.only_id' => 1,
269 ));
22f80e87 270 $this->assertEquals($this->_contribution['id'], $contribution, print_r($contribution, TRUE));
6a488035 271 //test id only format
4ab7d517 272 $contribution = $this->callAPISuccess('contribution', 'get', array(
273 'id' => $contribution2['id'],
274 'format.only_id' => 1,
275 ));
6a488035 276 $this->assertEquals($contribution2['id'], $contribution);
2f45e1c2 277 $contribution = $this->callAPISuccess('contribution', 'get', array(
6a488035
TO
278 'id' => $this->_contribution['id'],
279 ));
280 //test id as field
2bfae985 281 $this->assertEquals(1, $contribution['count']);
6a488035
TO
282 // $this->assertEquals($this->_contribution['id'], $contribution['id'] ) ;
283 //test get by contact id works
4ab7d517 284 $contribution = $this->callAPISuccess('contribution', 'get', array('contact_id' => $this->_individualId));
6a488035 285
2bfae985 286 $this->assertEquals(2, $contribution['count']);
2f45e1c2 287 $this->callAPISuccess('Contribution', 'Delete', array(
5896d037 288 'id' => $this->_contribution['id'],
6a488035 289 ));
2f45e1c2 290 $this->callAPISuccess('Contribution', 'Delete', array(
5896d037 291 'id' => $contribution2['id'],
6a488035
TO
292 ));
293 }
5896d037 294
a1a2a83d
TO
295 /**
296 * Create an contribution_id=FALSE and financial_type_id=Donation.
297 */
00be9182 298 public function testCreateEmptyContributionIDUseDonation() {
6a488035
TO
299 $params = array(
300 'contribution_id' => FALSE,
301 'contact_id' => 1,
302 'total_amount' => 1,
6c6e6187 303 'check_permissions' => FALSE,
6a488035
TO
304 'financial_type_id' => 'Donation',
305 );
858d0bf8 306 $this->callAPISuccess('contribution', 'create', $params);
6c6e6187 307 }
6a488035 308
6a488035 309 /**
1e52837d
EM
310 * Check with complete array + custom field.
311 *
6a488035
TO
312 * Note that the test is written on purpose without any
313 * variables specific to participant so it can be replicated into other entities
314 * and / or moved to the automated test suite
315 */
00be9182 316 public function testCreateWithCustom() {
6a488035
TO
317 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
318
319 $params = $this->_params;
320 $params['custom_' . $ids['custom_field_id']] = "custom string";
321
6c6e6187 322 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__);
6a488035 323 $this->assertEquals($result['id'], $result['values'][$result['id']]['id']);
2f45e1c2 324 $check = $this->callAPISuccess($this->_entity, 'get', array(
4ab7d517 325 'return.custom_' . $ids['custom_field_id'] => 1,
326 'id' => $result['id'],
327 ));
6a488035
TO
328 $this->customFieldDelete($ids['custom_field_id']);
329 $this->customGroupDelete($ids['custom_group_id']);
22f80e87 330 $this->assertEquals("custom string", $check['values'][$check['id']]['custom_' . $ids['custom_field_id']]);
6a488035
TO
331 }
332
333 /**
fd786d03
EM
334 * Check with complete array + custom field.
335 *
6a488035
TO
336 * Note that the test is written on purpose without any
337 * variables specific to participant so it can be replicated into other entities
338 * and / or moved to the automated test suite
339 */
00be9182 340 public function testCreateGetFieldsWithCustom() {
5896d037 341 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
6a488035 342 $idsContact = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, 'ContactTest.php');
5896d037 343 $result = $this->callAPISuccess('Contribution', 'getfields', array());
6a488035
TO
344 $this->assertArrayHasKey('custom_' . $ids['custom_field_id'], $result['values']);
345 $this->assertArrayNotHasKey('custom_' . $idsContact['custom_field_id'], $result['values']);
346 $this->customFieldDelete($ids['custom_field_id']);
347 $this->customGroupDelete($ids['custom_group_id']);
348 $this->customFieldDelete($idsContact['custom_field_id']);
349 $this->customGroupDelete($idsContact['custom_group_id']);
350 }
351
00be9182 352 public function testCreateContributionNoLineItems() {
6a488035
TO
353
354 $params = array(
355 'contact_id' => $this->_individualId,
356 'receive_date' => '20120511',
357 'total_amount' => 100.00,
5896d037 358 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
359 'payment_instrument_id' => 1,
360 'non_deductible_amount' => 10.00,
361 'fee_amount' => 50.00,
362 'net_amount' => 90.00,
363 'trxn_id' => 12345,
364 'invoice_id' => 67890,
365 'source' => 'SSF',
366 'contribution_status_id' => 1,
6a488035
TO
367 'skipLineItem' => 1,
368 );
369
2f45e1c2 370 $contribution = $this->callAPISuccess('contribution', 'create', $params);
6c6e6187 371 $lineItems = $this->callAPISuccess('line_item', 'get', array(
6a488035
TO
372 'entity_id' => $contribution['id'],
373 'entity_table' => 'civicrm_contribution',
374 'sequential' => 1,
375 ));
376 $this->assertEquals(0, $lineItems['count']);
377 }
5896d037 378
a1a2a83d 379 /**
eceb18cc 380 * Test checks that passing in line items suppresses the create mechanism.
6a488035 381 */
00be9182 382 public function testCreateContributionChainedLineItems() {
6a488035
TO
383 $params = array(
384 'contact_id' => $this->_individualId,
385 'receive_date' => '20120511',
386 'total_amount' => 100.00,
4ab7d517 387 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
388 'payment_instrument_id' => 1,
389 'non_deductible_amount' => 10.00,
390 'fee_amount' => 50.00,
391 'net_amount' => 90.00,
392 'trxn_id' => 12345,
393 'invoice_id' => 67890,
394 'source' => 'SSF',
395 'contribution_status_id' => 1,
6a488035
TO
396 'skipLineItem' => 1,
397 'api.line_item.create' => array(
398 array(
399 'price_field_id' => 1,
400 'qty' => 2,
401 'line_total' => '20',
402 'unit_price' => '10',
403 ),
404 array(
405 'price_field_id' => 1,
406 'qty' => 1,
407 'line_total' => '80',
408 'unit_price' => '80',
409 ),
410 ),
411 );
412
5c49fee0 413 $description = "Create Contribution with Nested Line Items.";
6a488035 414 $subfile = "CreateWithNestedLineItems";
6c6e6187 415 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
2f45e1c2 416
6c6e6187 417 $lineItems = $this->callAPISuccess('line_item', 'get', array(
6a488035 418 'entity_id' => $contribution['id'],
4ede4532 419 'contribution_id' => $contribution['id'],
6a488035
TO
420 'entity_table' => 'civicrm_contribution',
421 'sequential' => 1,
422 ));
423 $this->assertEquals(2, $lineItems['count']);
424 }
425
00be9182 426 public function testCreateContributionOffline() {
6a488035
TO
427 $params = array(
428 'contact_id' => $this->_individualId,
429 'receive_date' => '20120511',
430 'total_amount' => 100.00,
431 'financial_type_id' => 1,
432 'trxn_id' => 12345,
433 'invoice_id' => 67890,
434 'source' => 'SSF',
435 'contribution_status_id' => 1,
6a488035
TO
436 );
437
4ab7d517 438 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__);
2bfae985
EM
439 $this->assertEquals($contribution['values'][$contribution['id']]['contact_id'], $this->_individualId);
440 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
5896d037 441 $this->assertEquals($contribution['values'][$contribution['id']]['financial_type_id'], 1);
2bfae985
EM
442 $this->assertEquals($contribution['values'][$contribution['id']]['trxn_id'], 12345);
443 $this->assertEquals($contribution['values'][$contribution['id']]['invoice_id'], 67890);
444 $this->assertEquals($contribution['values'][$contribution['id']]['source'], 'SSF');
445 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status_id'], 1);
6c6e6187 446 $lineItems = $this->callAPISuccess('line_item', 'get', array(
6a488035 447 'entity_id' => $contribution['id'],
4ede4532 448 'contribution_id' => $contribution['id'],
6a488035
TO
449 'entity_table' => 'civicrm_contribution',
450 'sequential' => 1,
5896d037 451 ));
6a488035
TO
452 $this->assertEquals(1, $lineItems['count']);
453 $this->assertEquals($contribution['id'], $lineItems['values'][0]['entity_id']);
4ede4532 454 $this->assertEquals($contribution['id'], $lineItems['values'][0]['contribution_id']);
6a488035
TO
455 $this->_checkFinancialRecords($contribution, 'offline');
456 $this->contributionGetnCheck($params, $contribution['id']);
457 }
5896d037 458
f70a6752 459 /**
28de42d1 460 * Test create with valid payment instrument.
6a488035 461 */
00be9182 462 public function testCreateContributionWithPaymentInstrument() {
6a488035 463 $params = $this->_params + array('payment_instrument' => 'EFT');
53191813 464 $contribution = $this->callAPISuccess('contribution', 'create', $params);
6c6e6187 465 $contribution = $this->callAPISuccess('contribution', 'get', array(
53191813 466 'sequential' => 1,
21dfd5f5 467 'id' => $contribution['id'],
53191813 468 ));
6a488035 469 $this->assertArrayHasKey('payment_instrument', $contribution['values'][0]);
53191813
CW
470 $this->assertEquals('EFT', $contribution['values'][0]['payment_instrument']);
471
5896d037 472 $this->callAPISuccess('contribution', 'create', array(
92915c55
TO
473 'id' => $contribution['id'],
474 'payment_instrument' => 'Credit Card',
475 ));
6c6e6187 476 $contribution = $this->callAPISuccess('contribution', 'get', array(
53191813 477 'sequential' => 1,
21dfd5f5 478 'id' => $contribution['id'],
53191813
CW
479 ));
480 $this->assertArrayHasKey('payment_instrument', $contribution['values'][0]);
481 $this->assertEquals('Credit Card', $contribution['values'][0]['payment_instrument']);
6a488035
TO
482 }
483
00be9182 484 public function testGetContributionByPaymentInstrument() {
6a488035 485 $params = $this->_params + array('payment_instrument' => 'EFT');
53191813 486 $params2 = $this->_params + array('payment_instrument' => 'Cash');
6c6e6187
TO
487 $this->callAPISuccess('contribution', 'create', $params);
488 $this->callAPISuccess('contribution', 'create', $params2);
5896d037 489 $contribution = $this->callAPISuccess('contribution', 'get', array(
92915c55 490 'sequential' => 1,
7d543448 491 'contribution_payment_instrument' => 'Cash',
92915c55 492 ));
6a488035 493 $this->assertArrayHasKey('payment_instrument', $contribution['values'][0]);
ff977830
EM
494 $this->assertEquals('Cash', $contribution['values'][0]['payment_instrument']);
495 $this->assertEquals(1, $contribution['count']);
868e247d 496 $contribution = $this->callAPISuccess('contribution', 'get', array('sequential' => 1, 'payment_instrument' => 'Cash'));
6a488035 497 $this->assertArrayHasKey('payment_instrument', $contribution['values'][0]);
868e247d 498 $this->assertEquals('Cash', $contribution['values'][0]['payment_instrument']);
6a488035 499 $this->assertEquals(1, $contribution['count']);
5896d037 500 $contribution = $this->callAPISuccess('contribution', 'get', array(
92915c55
TO
501 'sequential' => 1,
502 'payment_instrument_id' => 5,
503 ));
6a488035 504 $this->assertArrayHasKey('payment_instrument', $contribution['values'][0]);
6c6e6187
TO
505 $this->assertEquals('EFT', $contribution['values'][0]['payment_instrument']);
506 $this->assertEquals(1, $contribution['count']);
5896d037 507 $contribution = $this->callAPISuccess('contribution', 'get', array(
92915c55
TO
508 'sequential' => 1,
509 'payment_instrument' => 'EFT',
510 ));
6a488035 511 $this->assertArrayHasKey('payment_instrument', $contribution['values'][0]);
53191813
CW
512 $this->assertEquals('EFT', $contribution['values'][0]['payment_instrument']);
513 $this->assertEquals(1, $contribution['count']);
5896d037 514 $contribution = $this->callAPISuccess('contribution', 'create', array(
92915c55
TO
515 'id' => $contribution['id'],
516 'payment_instrument' => 'Credit Card',
517 ));
5896d037 518 $contribution = $this->callAPISuccess('contribution', 'get', array('sequential' => 1, 'id' => $contribution['id']));
6a488035 519 $this->assertArrayHasKey('payment_instrument', $contribution['values'][0]);
6c6e6187
TO
520 $this->assertEquals('Credit Card', $contribution['values'][0]['payment_instrument']);
521 $this->assertEquals(1, $contribution['count']);
6a488035
TO
522 }
523
b5a37491
EM
524 /**
525 * CRM-16227 introduces invoice_id as a parameter.
526 */
527 public function testGetContributionByInvoice() {
528 $this->callAPISuccess('Contribution', 'create', array_merge($this->_params, array('invoice_id' => 'curly')));
529 $this->callAPISuccess('Contribution', 'create', array_merge($this->_params), array('invoice_id' => 'churlish'));
530 $this->callAPISuccessGetCount('Contribution', array(), 2);
531 $this->callAPISuccessGetSingle('Contribution', array('invoice_id' => 'curly'));
532 // The following don't work. They are the format we are trying to introduce but although the form uses this format
533 // CRM_Contact_BAO_Query::convertFormValues puts them into the other format & the where only supports that.
534 // ideally the where clause would support this format (as it does on contact_BAO_Query) and those lines would
535 // come out of convertFormValues
536 // $this->callAPISuccessGetSingle('Contribution', array('invoice_id' => array('LIKE' => '%ish%')));
537 // $this->callAPISuccessGetSingle('Contribution', array('invoice_id' => array('NOT IN' => array('curly'))));
538 // $this->callAPISuccessGetCount('Contribution', array('invoice_id' => array('LIKE' => '%ly%')), 2);
539 // $this->callAPISuccessGetCount('Contribution', array('invoice_id' => array('IN' => array('curly', 'churlish'))),
540 // 2);
541 }
542
e58a3abb 543 /**
544 * Test retrieval by total_amount works.
545 *
546 * @throws Exception
547 */
548 public function testGetContributionByTotalAmount() {
549 $this->callAPISuccess('Contribution', 'create', array_merge($this->_params, array('total_amount' => '5')));
550 $this->callAPISuccess('Contribution', 'create', array_merge($this->_params, array('total_amount' => '10')));
551 $this->callAPISuccessGetCount('Contribution', array('total_amount' => 10), 1);
552 $this->callAPISuccessGetCount('Contribution', array('total_amount' => array('>' => 6)), 1);
553 $this->callAPISuccessGetCount('Contribution', array('total_amount' => array('>' => 0)), 2);
554 $this->callAPISuccessGetCount('Contribution', array('total_amount' => array('>' => -5)), 2);
555 $this->callAPISuccessGetCount('Contribution', array('total_amount' => array('<' => 0)), 0);
556 $this->callAPISuccessGetCount('Contribution', array(), 2);
557 }
558
c490a46a 559 /**
eceb18cc 560 * Create test with unique field name on source.
c490a46a 561 */
00be9182 562 public function testCreateContributionSource() {
6a488035
TO
563
564 $params = array(
565 'contact_id' => $this->_individualId,
566 'receive_date' => date('Ymd'),
567 'total_amount' => 100.00,
4ab7d517 568 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
569 'payment_instrument_id' => 1,
570 'non_deductible_amount' => 10.00,
571 'fee_amount' => 50.00,
572 'net_amount' => 90.00,
573 'trxn_id' => 12345,
574 'invoice_id' => 67890,
575 'contribution_source' => 'SSF',
576 'contribution_status_id' => 1,
6a488035
TO
577 );
578
4ab7d517 579 $contribution = $this->callAPISuccess('contribution', 'create', $params);
2bfae985
EM
580 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
581 $this->assertEquals($contribution['values'][$contribution['id']]['source'], 'SSF');
6a488035 582 }
d5d148ab 583
d424ffde 584 /**
eceb18cc 585 * Create test with unique field name on source.
d424ffde 586 */
00be9182 587 public function testCreateDefaultNow() {
d5d148ab
EM
588
589 $params = $this->_params;
590 unset($params['receive_date']);
591
592 $contribution = $this->callAPISuccess('contribution', 'create', $params);
593 $contribution = $this->callAPISuccessGetSingle('contribution', array('id' => $contribution['id']));
594 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($contribution['receive_date'])));
595 }
596
c490a46a 597 /**
55d2c6f1 598 * Create test with unique field name on source.
c490a46a 599 */
55d2c6f1 600 public function testCreateContributionSourceInvalidContact() {
6a488035
TO
601
602 $params = array(
603 'contact_id' => 999,
604 'receive_date' => date('Ymd'),
605 'total_amount' => 100.00,
4ab7d517 606 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
607 'payment_instrument_id' => 1,
608 'non_deductible_amount' => 10.00,
609 'fee_amount' => 50.00,
610 'net_amount' => 90.00,
611 'trxn_id' => 12345,
612 'invoice_id' => 67890,
613 'contribution_source' => 'SSF',
614 'contribution_status_id' => 1,
6a488035
TO
615 );
616
858d0bf8 617 $this->callAPIFailure('contribution', 'create', $params, 'contact_id is not valid : 999');
6a488035
TO
618 }
619
00be9182 620 public function testCreateContributionSourceInvalidContContact() {
6a488035
TO
621
622 $params = array(
623 'contribution_contact_id' => 999,
624 'receive_date' => date('Ymd'),
625 'total_amount' => 100.00,
4ab7d517 626 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
627 'payment_instrument_id' => 1,
628 'non_deductible_amount' => 10.00,
629 'fee_amount' => 50.00,
630 'net_amount' => 90.00,
631 'trxn_id' => 12345,
632 'invoice_id' => 67890,
633 'contribution_source' => 'SSF',
634 'contribution_status_id' => 1,
6a488035
TO
635 );
636
858d0bf8 637 $this->callAPIFailure('contribution', 'create', $params, 'contact_id is not valid : 999');
6a488035
TO
638 }
639
858d0bf8 640 /**
442cf836 641 * Test note created correctly.
858d0bf8 642 */
00be9182 643 public function testCreateContributionWithNote() {
5c49fee0 644 $description = "Demonstrates creating contribution with Note Entity.";
5896d037
TO
645 $subfile = "ContributionCreateWithNote";
646 $params = array(
6a488035
TO
647 'contact_id' => $this->_individualId,
648 'receive_date' => '2012-01-01',
649 'total_amount' => 100.00,
4ab7d517 650 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
651 'payment_instrument_id' => 1,
652 'non_deductible_amount' => 10.00,
653 'fee_amount' => 50.00,
654 'net_amount' => 90.00,
655 'trxn_id' => 12345,
656 'invoice_id' => 67890,
657 'source' => 'SSF',
658 'contribution_status_id' => 1,
6a488035
TO
659 'note' => 'my contribution note',
660 );
661
4ab7d517 662 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
5896d037 663 $result = $this->callAPISuccess('note', 'get', array(
92915c55
TO
664 'entity_table' => 'civicrm_contribution',
665 'entity_id' => $contribution['id'],
666 'sequential' => 1,
667 ));
6a488035 668 $this->assertEquals('my contribution note', $result['values'][0]['note']);
4ab7d517 669 $this->callAPISuccess('contribution', 'delete', array('id' => $contribution['id']));
6a488035
TO
670 }
671
00be9182 672 public function testCreateContributionWithNoteUniqueNameAliases() {
5896d037 673 $params = array(
6a488035
TO
674 'contact_id' => $this->_individualId,
675 'receive_date' => '2012-01-01',
676 'total_amount' => 100.00,
4ab7d517 677 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
678 'payment_instrument_id' => 1,
679 'non_deductible_amount' => 10.00,
680 'fee_amount' => 50.00,
681 'net_amount' => 90.00,
682 'trxn_id' => 12345,
683 'invoice_id' => 67890,
684 'source' => 'SSF',
685 'contribution_status_id' => 1,
6a488035
TO
686 'contribution_note' => 'my contribution note',
687 );
688
4ab7d517 689 $contribution = $this->callAPISuccess('contribution', 'create', $params);
5896d037 690 $result = $this->callAPISuccess('note', 'get', array(
92915c55
TO
691 'entity_table' => 'civicrm_contribution',
692 'entity_id' => $contribution['id'],
693 'sequential' => 1,
694 ));
6a488035 695 $this->assertEquals('my contribution note', $result['values'][0]['note']);
4ab7d517 696 $this->callAPISuccess('contribution', 'delete', array('id' => $contribution['id']));
6a488035 697 }
c490a46a
CW
698
699 /**
55d2c6f1 700 * This is the test for creating soft credits.
c490a46a 701 */
55d2c6f1 702 public function testCreateContributionWithSoftCredit() {
5c49fee0 703 $description = "Demonstrates creating contribution with SoftCredit.";
5896d037
TO
704 $subfile = "ContributionCreateWithSoftCredit";
705 $contact2 = $this->callAPISuccess('Contact', 'create', array(
92915c55
TO
706 'display_name' => 'superman',
707 'contact_type' => 'Individual',
708 ));
55d2c6f1 709 $softParams = array(
bcc03b98 710 'contact_id' => $contact2['id'],
711 'amount' => 50,
21dfd5f5 712 'soft_credit_type_id' => 3,
6a488035
TO
713 );
714
55d2c6f1 715 $params = $this->_params + array('soft_credit' => array(1 => $softParams));
4ab7d517 716 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6c6e6187 717 $result = $this->callAPISuccess('contribution', 'get', array('return' => 'soft_credit', 'sequential' => 1));
a1c68fd2 718
55d2c6f1
EM
719 $this->assertEquals($softParams['contact_id'], $result['values'][0]['soft_credit'][1]['contact_id']);
720 $this->assertEquals($softParams['amount'], $result['values'][0]['soft_credit'][1]['amount']);
721 $this->assertEquals($softParams['soft_credit_type_id'], $result['values'][0]['soft_credit'][1]['soft_credit_type']);
6a516bd6
DG
722
723 $this->callAPISuccess('contribution', 'delete', array('id' => $contribution['id']));
724 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
725 }
726
00be9182 727 public function testCreateContributionWithSoftCreditDefaults() {
5c49fee0 728 $description = "Demonstrates creating contribution with Soft Credit defaults for amount and type.";
5896d037
TO
729 $subfile = "ContributionCreateWithSoftCreditDefaults";
730 $contact2 = $this->callAPISuccess('Contact', 'create', array(
92915c55
TO
731 'display_name' => 'superman',
732 'contact_type' => 'Individual',
733 ));
6a516bd6 734 $params = $this->_params + array(
442cf836
EM
735 'soft_credit_to' => $contact2['id'],
736 );
6a516bd6 737 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6c6e6187 738 $result = $this->callAPISuccess('contribution', 'get', array('return' => 'soft_credit', 'sequential' => 1));
6a516bd6
DG
739
740 $this->assertEquals($contact2['id'], $result['values'][0]['soft_credit'][1]['contact_id']);
741 // Default soft credit amount = contribution.total_amount
742 $this->assertEquals($this->_params['total_amount'], $result['values'][0]['soft_credit'][1]['amount']);
743 $this->assertEquals(CRM_Core_OptionGroup::getDefaultValue("soft_credit_type"), $result['values'][0]['soft_credit'][1]['soft_credit_type']);
744
745 $this->callAPISuccess('contribution', 'delete', array('id' => $contribution['id']));
746 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
747 }
748
00be9182 749 public function testCreateContributionWithHonoreeContact() {
5c49fee0 750 $description = "Demonstrates creating contribution with Soft Credit by passing in honor_contact_id.";
5896d037
TO
751 $subfile = "ContributionCreateWithHonoreeContact";
752 $contact2 = $this->callAPISuccess('Contact', 'create', array(
92915c55
TO
753 'display_name' => 'superman',
754 'contact_type' => 'Individual',
755 ));
6a516bd6 756 $params = $this->_params + array(
442cf836
EM
757 'honor_contact_id' => $contact2['id'],
758 );
6a516bd6 759 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__, $description, $subfile);
6c6e6187 760 $result = $this->callAPISuccess('contribution', 'get', array('return' => 'soft_credit', 'sequential' => 1));
6a516bd6
DG
761
762 $this->assertEquals($contact2['id'], $result['values'][0]['soft_credit'][1]['contact_id']);
763 // Default soft credit amount = contribution.total_amount
764 // Legacy mode in create api (honor_contact_id param) uses the standard "In Honor of" soft credit type
765 $this->assertEquals($this->_params['total_amount'], $result['values'][0]['soft_credit'][1]['amount']);
766 $this->assertEquals(CRM_Core_OptionGroup::getValue('soft_credit_type', 'in_honor_of', 'name'), $result['values'][0]['soft_credit'][1]['soft_credit_type']);
6a488035 767
4ab7d517 768 $this->callAPISuccess('contribution', 'delete', array('id' => $contribution['id']));
769 $this->callAPISuccess('contact', 'delete', array('id' => $contact2['id']));
6a488035
TO
770 }
771
772 /**
92c99a4a 773 * Test using example code.
6a488035 774 */
00be9182 775 public function testContributionCreateExample() {
6a488035 776 //make sure at least on page exists since there is a truncate in tear down
8be629ac 777 $this->callAPISuccess('contribution_page', 'create', $this->_pageParams);
3ec6e38d 778 require_once 'api/v3/examples/Contribution/Create.php';
5896d037 779 $result = contribution_create_example();
006d6361 780 $id = $result['id'];
6a488035 781 $expectedResult = contribution_create_expectedresult();
8e342a79 782 $this->checkArrayEquals($expectedResult, $result);
006d6361 783 $this->contributionDelete($id);
6a488035
TO
784 }
785
a1a2a83d 786 /**
f55c5fa8 787 * Function tests that additional financial records are created when fee amount is recorded.
6a488035 788 */
00be9182 789 public function testCreateContributionWithFee() {
6a488035
TO
790 $params = array(
791 'contact_id' => $this->_individualId,
792 'receive_date' => '20120511',
793 'total_amount' => 100.00,
794 'fee_amount' => 50,
795 'financial_type_id' => 1,
796 'trxn_id' => 12345,
797 'invoice_id' => 67890,
798 'source' => 'SSF',
799 'contribution_status_id' => 1,
6a488035
TO
800 );
801
4ab7d517 802 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__);
2bfae985
EM
803 $this->assertEquals($contribution['values'][$contribution['id']]['contact_id'], $this->_individualId);
804 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
e0e3c51b
EM
805 $this->assertEquals($contribution['values'][$contribution['id']]['fee_amount'], 50.00);
806 $this->assertEquals($contribution['values'][$contribution['id']]['net_amount'], 50.00);
5896d037 807 $this->assertEquals($contribution['values'][$contribution['id']]['financial_type_id'], 1);
2bfae985
EM
808 $this->assertEquals($contribution['values'][$contribution['id']]['trxn_id'], 12345);
809 $this->assertEquals($contribution['values'][$contribution['id']]['invoice_id'], 67890);
810 $this->assertEquals($contribution['values'][$contribution['id']]['source'], 'SSF');
811 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status_id'], 1);
e0e3c51b 812
6c6e6187 813 $lineItems = $this->callAPISuccess('line_item', 'get', array(
4ab7d517 814
6a488035
TO
815 'entity_id' => $contribution['id'],
816 'entity_table' => 'civicrm_contribution',
817 'sequential' => 1,
5896d037 818 ));
6a488035
TO
819 $this->assertEquals(1, $lineItems['count']);
820 $this->assertEquals($contribution['id'], $lineItems['values'][0]['entity_id']);
4ede4532 821 $this->assertEquals($contribution['id'], $lineItems['values'][0]['contribution_id']);
6c6e6187 822 $lineItems = $this->callAPISuccess('line_item', 'get', array(
4ab7d517 823
5896d037
TO
824 'entity_id' => $contribution['id'],
825 'contribution_id' => $contribution['id'],
826 'entity_table' => 'civicrm_contribution',
827 'sequential' => 1,
6a488035
TO
828 ));
829 $this->assertEquals(1, $lineItems['count']);
830 $this->_checkFinancialRecords($contribution, 'feeAmount');
831 }
832
833
f70a6752 834 /**
442cf836 835 * Function tests that additional financial records are created when online contribution is created.
6a488035 836 */
00be9182 837 public function testCreateContributionOnline() {
858d0bf8 838 CRM_Financial_BAO_PaymentProcessor::create($this->_processorParams);
5896d037 839 $contributionPage = $this->callAPISuccess('contribution_page', 'create', $this->_pageParams);
fc928539 840 $this->assertAPISuccess($contributionPage);
6a488035
TO
841 $params = array(
842 'contact_id' => $this->_individualId,
843 'receive_date' => '20120511',
844 'total_amount' => 100.00,
845 'financial_type_id' => 1,
846 'contribution_page_id' => $contributionPage['id'],
847 'payment_processor' => 1,
848 'trxn_id' => 12345,
849 'invoice_id' => 67890,
850 'source' => 'SSF',
851 'contribution_status_id' => 1,
4ab7d517 852
6a488035
TO
853 );
854
4ab7d517 855 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__);
2bfae985
EM
856 $this->assertEquals($contribution['values'][$contribution['id']]['contact_id'], $this->_individualId);
857 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
5896d037 858 $this->assertEquals($contribution['values'][$contribution['id']]['financial_type_id'], 1);
2bfae985
EM
859 $this->assertEquals($contribution['values'][$contribution['id']]['trxn_id'], 12345);
860 $this->assertEquals($contribution['values'][$contribution['id']]['invoice_id'], 67890);
861 $this->assertEquals($contribution['values'][$contribution['id']]['source'], 'SSF');
862 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status_id'], 1);
6a488035
TO
863 $this->_checkFinancialRecords($contribution, 'online');
864 }
865
f70a6752 866 /**
442cf836
EM
867 * Check handling of financial type.
868 *
100fef9d 869 * In the interests of removing financial type / contribution type checks from
f70a6752 870 * legacy format function lets test that the api is doing this for us
871 */
00be9182 872 public function testCreateInvalidFinancialType() {
f70a6752 873 $params = $this->_params;
874 $params['financial_type_id'] = 99999;
858d0bf8 875 $this->callAPIFailure($this->_entity, 'create', $params, "'99999' is not a valid option for field financial_type_id");
f70a6752 876 }
877
4302618d 878 /**
442cf836
EM
879 * Check handling of financial type.
880 *
100fef9d 881 * In the interests of removing financial type / contribution type checks from
4302618d 882 * legacy format function lets test that the api is doing this for us
883 */
00be9182 884 public function testValidNamedFinancialType() {
4302618d 885 $params = $this->_params;
886 $params['financial_type_id'] = 'Donation';
858d0bf8 887 $this->callAPISuccess($this->_entity, 'create', $params);
4302618d 888 }
889
f70a6752 890 /**
92c99a4a
EM
891 * Tests that additional financial records are created.
892 *
893 * Checks when online contribution with pay later option is created
6a488035 894 */
00be9182 895 public function testCreateContributionPayLaterOnline() {
858d0bf8 896 CRM_Financial_BAO_PaymentProcessor::create($this->_processorParams);
6a488035 897 $this->_pageParams['is_pay_later'] = 1;
5896d037 898 $contributionPage = $this->callAPISuccess('contribution_page', 'create', $this->_pageParams);
fc928539 899 $this->assertAPISuccess($contributionPage);
6a488035
TO
900 $params = array(
901 'contact_id' => $this->_individualId,
902 'receive_date' => '20120511',
903 'total_amount' => 100.00,
904 'financial_type_id' => 1,
905 'contribution_page_id' => $contributionPage['id'],
906 'trxn_id' => 12345,
907 'is_pay_later' => 1,
908 'invoice_id' => 67890,
909 'source' => 'SSF',
910 'contribution_status_id' => 2,
4ab7d517 911
6a488035
TO
912 );
913
4ab7d517 914 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__);
2bfae985
EM
915 $this->assertEquals($contribution['values'][$contribution['id']]['contact_id'], $this->_individualId);
916 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
5896d037 917 $this->assertEquals($contribution['values'][$contribution['id']]['financial_type_id'], 1);
2bfae985
EM
918 $this->assertEquals($contribution['values'][$contribution['id']]['trxn_id'], 12345);
919 $this->assertEquals($contribution['values'][$contribution['id']]['invoice_id'], 67890);
920 $this->assertEquals($contribution['values'][$contribution['id']]['source'], 'SSF');
921 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status_id'], 2);
6a488035
TO
922 $this->_checkFinancialRecords($contribution, 'payLater');
923 }
924
a1a2a83d 925 /**
1e52837d 926 * Function tests that additional financial records are created for online contribution with pending option.
6a488035 927 */
00be9182 928 public function testCreateContributionPendingOnline() {
6a488035 929 $paymentProcessor = CRM_Financial_BAO_PaymentProcessor::create($this->_processorParams);
5896d037 930 $contributionPage = $this->callAPISuccess('contribution_page', 'create', $this->_pageParams);
fc928539 931 $this->assertAPISuccess($contributionPage);
6a488035
TO
932 $params = array(
933 'contact_id' => $this->_individualId,
934 'receive_date' => '20120511',
935 'total_amount' => 100.00,
936 'financial_type_id' => 1,
937 'contribution_page_id' => $contributionPage['id'],
938 'trxn_id' => 12345,
939 'invoice_id' => 67890,
940 'source' => 'SSF',
941 'contribution_status_id' => 2,
6a488035
TO
942 );
943
4ab7d517 944 $contribution = $this->callAPIAndDocument('contribution', 'create', $params, __FUNCTION__, __FILE__);
2bfae985
EM
945 $this->assertEquals($contribution['values'][$contribution['id']]['contact_id'], $this->_individualId);
946 $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00);
5896d037 947 $this->assertEquals($contribution['values'][$contribution['id']]['financial_type_id'], 1);
2bfae985
EM
948 $this->assertEquals($contribution['values'][$contribution['id']]['trxn_id'], 12345);
949 $this->assertEquals($contribution['values'][$contribution['id']]['invoice_id'], 67890);
950 $this->assertEquals($contribution['values'][$contribution['id']]['source'], 'SSF');
951 $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status_id'], 2);
6a488035
TO
952 $this->_checkFinancialRecords($contribution, 'pending');
953 }
954
e748bf60 955 /**
92c99a4a 956 * Test that BAO defaults work.
e748bf60 957 */
00be9182 958 public function testCreateBAODefaults() {
e748bf60
EM
959 unset($this->_params['contribution_source_id'], $this->_params['payment_instrument_id']);
960 $contribution = $this->callAPISuccess('contribution', 'create', $this->_params);
5896d037 961 $contribution = $this->callAPISuccess('contribution', 'getsingle', array(
92915c55
TO
962 'id' => $contribution['id'],
963 'api.contribution.delete' => 1,
964 ));
e748bf60 965 $this->assertEquals(1, $contribution['contribution_status_id']);
12879069 966 $this->assertEquals('Check', $contribution['payment_instrument']);
e748bf60
EM
967 }
968
a1a2a83d 969 /**
1e52837d 970 * Function tests that line items, financial records are updated when contribution amount is changed.
6a488035 971 */
00be9182 972 public function testCreateUpdateContributionChangeTotal() {
4ab7d517 973 $contribution = $this->callAPISuccess('contribution', 'create', $this->_params);
6c6e6187 974 $lineItems = $this->callAPISuccess('line_item', 'getvalue', array(
4ab7d517 975
6a488035
TO
976 'entity_id' => $contribution['id'],
977 'entity_table' => 'civicrm_contribution',
978 'sequential' => 1,
979 'return' => 'line_total',
980 ));
981 $this->assertEquals('100.00', $lineItems);
982 $trxnAmount = $this->_getFinancialTrxnAmount($contribution['id']);
983 // Financial trxn SUM = 100 + 5 (fee)
984 $this->assertEquals('105.00', $trxnAmount);
985 $newParams = array(
4ab7d517 986
6a488035 987 'id' => $contribution['id'],
21dfd5f5 988 'total_amount' => '125',
5896d037 989 );
694769da 990 $contribution = $this->callAPISuccess('contribution', 'create', $newParams);
4ab7d517 991
6c6e6187 992 $lineItems = $this->callAPISuccess('line_item', 'getvalue', array(
6a488035 993
5896d037
TO
994 'entity_id' => $contribution['id'],
995 'entity_table' => 'civicrm_contribution',
996 'sequential' => 1,
997 'return' => 'line_total',
6a488035
TO
998 ));
999
1000 $this->assertEquals('125.00', $lineItems);
1001 $trxnAmount = $this->_getFinancialTrxnAmount($contribution['id']);
28de42d1
EM
1002
1003 // Financial trxn SUM = 125 + 5 (fee).
6a488035 1004 $this->assertEquals('130.00', $trxnAmount);
28de42d1 1005 $this->assertEquals('125.00', $this->_getFinancialItemAmount($contribution['id']));
6a488035
TO
1006 }
1007
a1a2a83d 1008 /**
1e52837d 1009 * Function tests that line items, financial records are updated when pay later contribution is received.
6a488035 1010 */
00be9182 1011 public function testCreateUpdateContributionPayLater() {
6a488035
TO
1012 $contribParams = array(
1013 'contact_id' => $this->_individualId,
1014 'receive_date' => '2012-01-01',
1015 'total_amount' => 100.00,
4ab7d517 1016 'financial_type_id' => $this->_financialTypeId,
6a488035 1017 'payment_instrument_id' => 1,
8f39a111 1018 'contribution_status_id' => 2,
1019 'is_pay_later' => 1,
4ab7d517 1020
6a488035 1021 );
4ab7d517 1022 $contribution = $this->callAPISuccess('contribution', 'create', $contribParams);
6a488035
TO
1023
1024 $newParams = array_merge($contribParams, array(
5896d037
TO
1025 'id' => $contribution['id'],
1026 'contribution_status_id' => 1,
1027 )
c71ae314 1028 );
694769da 1029 $contribution = $this->callAPISuccess('contribution', 'create', $newParams);
6a488035 1030 $contribution = $contribution['values'][$contribution['id']];
6c6e6187 1031 $this->assertEquals($contribution['contribution_status_id'], '1');
6a488035
TO
1032 $this->_checkFinancialItem($contribution['id'], 'paylater');
1033 $this->_checkFinancialTrxn($contribution, 'payLater');
1034 }
1035
a1a2a83d 1036 /**
eceb18cc 1037 * Function tests that financial records are updated when Payment Instrument is changed.
6a488035 1038 */
00be9182 1039 public function testCreateUpdateContributionPaymentInstrument() {
6a488035
TO
1040 $instrumentId = $this->_addPaymentInstrument();
1041 $contribParams = array(
1042 'contact_id' => $this->_individualId,
1043 'total_amount' => 100.00,
4ab7d517 1044 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1045 'payment_instrument_id' => 4,
1046 'contribution_status_id' => 1,
4ab7d517 1047
6a488035 1048 );
4ab7d517 1049 $contribution = $this->callAPISuccess('contribution', 'create', $contribParams);
6a488035
TO
1050
1051 $newParams = array_merge($contribParams, array(
5896d037
TO
1052 'id' => $contribution['id'],
1053 'payment_instrument_id' => $instrumentId,
1054 )
6a488035 1055 );
694769da 1056 $contribution = $this->callAPISuccess('contribution', 'create', $newParams);
fc928539 1057 $this->assertAPISuccess($contribution);
4ecc6d4b 1058 $this->_checkFinancialTrxn($contribution, 'paymentInstrument', $instrumentId);
6a488035
TO
1059 }
1060
a1a2a83d 1061 /**
eceb18cc 1062 * Function tests that financial records are added when Contribution is Refunded.
6a488035 1063 */
00be9182 1064 public function testCreateUpdateContributionRefund() {
797d4c52 1065 $contributionParams = array(
6a488035
TO
1066 'contact_id' => $this->_individualId,
1067 'receive_date' => '2012-01-01',
1068 'total_amount' => 100.00,
4ab7d517 1069 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1070 'payment_instrument_id' => 4,
1071 'contribution_status_id' => 1,
797d4c52 1072 'trxn_id' => 'original_payment',
1073 );
1074 $contribution = $this->callAPISuccess('contribution', 'create', $contributionParams);
1075 $newParams = array_merge($contributionParams, array(
1076 'id' => $contribution['id'],
1077 'contribution_status_id' => 'Refunded',
1078 'cancel_date' => '2015-01-01 09:00',
1079 'refund_trxn_id' => 'the refund',
1080 )
1081 );
1082
1083 $contribution = $this->callAPISuccess('contribution', 'create', $newParams);
1084 $this->_checkFinancialTrxn($contribution, 'refund');
1085 $this->_checkFinancialItem($contribution['id'], 'refund');
1086 $this->assertEquals('original_payment', $this->callAPISuccessGetValue('Contribution', array(
1087 'id' => $contribution['id'],
1088 'return' => 'trxn_id',
1089 )));
1090 }
4ab7d517 1091
52da5b1e 1092 /**
1093 * Refund a contribution for a financial type with a contra account.
1094 *
1095 * CRM-17951 the contra account is a financial account with a relationship to a
1096 * financial type. It is not always configured but should be reflected
1097 * in the financial_trxn & financial_item table if it is.
1098 */
1099 public function testCreateUpdateChargebackContributionDefaultAccount() {
1100 $contribution = $this->callAPISuccess('Contribution', 'create', $this->_params);
1101 $this->callAPISuccess('Contribution', 'create', array(
1102 'id' => $contribution['id'],
1103 'contribution_status_id' => 'Chargeback',
1104 ));
1105 $this->callAPISuccessGetSingle('Contribution', array('contribution_status_id' => 'Chargeback'));
1106
1107 $lineItems = $this->callAPISuccessGetSingle('LineItem', array(
1108 'contribution_id' => $contribution['id'],
1109 'api.FinancialItem.getsingle' => array('amount' => array('<' => 0)),
1110 ));
1111 $this->assertEquals(1, $lineItems['api.FinancialItem.getsingle']['financial_account_id']);
1112 $this->callAPISuccessGetSingle('FinancialTrxn', array(
1113 'total_amount' => -100,
1114 'status_id' => 'Chargeback',
1115 'to_financial_account_id' => 6,
1116 ));
1117 }
1118
1119 /**
1120 * Refund a contribution for a financial type with a contra account.
1121 *
1122 * CRM-17951 the contra account is a financial account with a relationship to a
1123 * financial type. It is not always configured but should be reflected
1124 * in the financial_trxn & financial_item table if it is.
1125 */
1126 public function testCreateUpdateChargebackContributionCustomAccount() {
1127 $financialAccount = $this->callAPISuccess('FinancialAccount', 'create', array(
1128 'name' => 'Chargeback Account',
1129 'is_active' => TRUE,
1130 ));
1131
1132 $entityFinancialAccount = $this->callAPISuccess('EntityFinancialAccount', 'create', array(
1133 'entity_id' => $this->_financialTypeId,
1134 'entity_table' => 'civicrm_financial_type',
1135 'account_relationship' => 'Chargeback Account is',
1136 'financial_account_id' => 'Chargeback Account',
1137 ));
1138
1139 $contribution = $this->callAPISuccess('Contribution', 'create', $this->_params);
1140 $this->callAPISuccess('Contribution', 'create', array(
1141 'id' => $contribution['id'],
1142 'contribution_status_id' => 'Chargeback',
1143 ));
1144 $this->callAPISuccessGetSingle('Contribution', array('contribution_status_id' => 'Chargeback'));
1145
1146 $lineItems = $this->callAPISuccessGetSingle('LineItem', array(
1147 'contribution_id' => $contribution['id'],
1148 'api.FinancialItem.getsingle' => array('amount' => array('<' => 0)),
1149 ));
1150 $this->assertEquals($financialAccount['id'], $lineItems['api.FinancialItem.getsingle']['financial_account_id']);
1151
1152 $this->callAPISuccess('Contribution', 'delete', array('id' => $contribution['id']));
1153 $this->callAPISuccess('EntityFinancialAccount', 'delete', array('id' => $entityFinancialAccount['id']));
1154 $this->callAPISuccess('FinancialAccount', 'delete', array('id' => $financialAccount['id']));
1155 }
1156
bf2cf926 1157 /**
1158 * Refund a contribution for a financial type with a contra account.
1159 *
1160 * CRM-17951 the contra account is a financial account with a relationship to a
1161 * financial type. It is not always configured but should be reflected
1162 * in the financial_trxn & financial_item table if it is.
1163 */
1164 public function testCreateUpdateRefundContributionConfiguredContraAccount() {
1165 $financialAccount = $this->callAPISuccess('FinancialAccount', 'create', array(
1166 'name' => 'Refund Account',
1167 'is_active' => TRUE,
1168 ));
1169
1170 $entityFinancialAccount = $this->callAPISuccess('EntityFinancialAccount', 'create', array(
1171 'entity_id' => $this->_financialTypeId,
1172 'entity_table' => 'civicrm_financial_type',
1173 'account_relationship' => 'Credit/Contra Revenue Account is',
1174 'financial_account_id' => 'Refund Account',
1175 ));
1176
1177 $contribution = $this->callAPISuccess('Contribution', 'create', $this->_params);
1178 $this->callAPISuccess('Contribution', 'create', array(
1179 'id' => $contribution['id'],
1180 'contribution_status_id' => 'Refunded',
1181 ));
1182
52da5b1e 1183 $lineItems = $this->callAPISuccessGetSingle('LineItem', array(
bf2cf926 1184 'contribution_id' => $contribution['id'],
1185 'api.FinancialItem.getsingle' => array('amount' => array('<' => 0)),
1186 ));
1187 $this->assertEquals($financialAccount['id'], $lineItems['api.FinancialItem.getsingle']['financial_account_id']);
1188
1189 $this->callAPISuccess('Contribution', 'delete', array('id' => $contribution['id']));
1190 $this->callAPISuccess('EntityFinancialAccount', 'delete', array('id' => $entityFinancialAccount['id']));
1191 $this->callAPISuccess('FinancialAccount', 'delete', array('id' => $financialAccount['id']));
bf2cf926 1192 }
1193
797d4c52 1194 /**
1195 * Function tests that trxn_id is set when passed in.
1196 *
1197 * Here we ensure that the civicrm_financial_trxn.trxn_id & the civicrm_contribution.trxn_id are set
1198 * when trxn_id is passed in.
1199 */
1200 public function testCreateUpdateContributionRefundTrxnIDPassedIn() {
1201 $contributionParams = array(
1202 'contact_id' => $this->_individualId,
1203 'receive_date' => '2012-01-01',
1204 'total_amount' => 100.00,
1205 'financial_type_id' => $this->_financialTypeId,
1206 'payment_instrument_id' => 4,
1207 'contribution_status_id' => 1,
1208 'trxn_id' => 'original_payment',
6a488035 1209 );
797d4c52 1210 $contribution = $this->callAPISuccess('contribution', 'create', $contributionParams);
1211 $newParams = array_merge($contributionParams, array(
1212 'id' => $contribution['id'],
1213 'contribution_status_id' => 'Refunded',
1214 'cancel_date' => '2015-01-01 09:00',
1215 'trxn_id' => 'the refund',
1216 )
1217 );
1218
1219 $contribution = $this->callAPISuccess('contribution', 'create', $newParams);
1220 $this->_checkFinancialTrxn($contribution, 'refund');
1221 $this->_checkFinancialItem($contribution['id'], 'refund');
1222 $this->assertEquals('the refund', $this->callAPISuccessGetValue('Contribution', array(
1223 'id' => $contribution['id'],
1224 'return' => 'trxn_id',
1225 )));
1226 }
1227
1228 /**
1229 * Function tests that trxn_id is set when passed in.
1230 *
1231 * Here we ensure that the civicrm_contribution.trxn_id is set
1232 * when trxn_id is passed in but if refund_trxn_id is different then that
1233 * is kept for the refund transaction.
1234 */
1235 public function testCreateUpdateContributionRefundRefundAndTrxnIDPassedIn() {
1236 $contributionParams = array(
1237 'contact_id' => $this->_individualId,
1238 'receive_date' => '2012-01-01',
1239 'total_amount' => 100.00,
1240 'financial_type_id' => $this->_financialTypeId,
1241 'payment_instrument_id' => 4,
1242 'contribution_status_id' => 1,
1243 'trxn_id' => 'original_payment',
1244 );
1245 $contribution = $this->callAPISuccess('contribution', 'create', $contributionParams);
1246 $newParams = array_merge($contributionParams, array(
5896d037 1247 'id' => $contribution['id'],
b7990bb6 1248 'contribution_status_id' => 'Refunded',
1249 'cancel_date' => '2015-01-01 09:00',
797d4c52 1250 'trxn_id' => 'cont id',
1251 'refund_trxn_id' => 'the refund',
6a488035
TO
1252 )
1253 );
1254
694769da 1255 $contribution = $this->callAPISuccess('contribution', 'create', $newParams);
6a488035
TO
1256 $this->_checkFinancialTrxn($contribution, 'refund');
1257 $this->_checkFinancialItem($contribution['id'], 'refund');
797d4c52 1258 $this->assertEquals('cont id', $this->callAPISuccessGetValue('Contribution', array(
1259 'id' => $contribution['id'],
1260 'return' => 'trxn_id',
1261 )));
1262 }
1263
1264 /**
1265 * Function tests that refund_trxn_id is set when passed in empty.
1266 *
1267 * Here we ensure that the civicrm_contribution.trxn_id is set
1268 * when trxn_id is passed in but if refund_trxn_id isset but empty then that
1269 * is kept for the refund transaction.
1270 */
1271 public function testCreateUpdateContributionRefundRefundNullTrxnIDPassedIn() {
1272 $contributionParams = array(
1273 'contact_id' => $this->_individualId,
1274 'receive_date' => '2012-01-01',
1275 'total_amount' => 100.00,
1276 'financial_type_id' => $this->_financialTypeId,
1277 'payment_instrument_id' => 4,
1278 'contribution_status_id' => 1,
1279 'trxn_id' => 'original_payment',
1280 );
1281 $contribution = $this->callAPISuccess('contribution', 'create', $contributionParams);
1282 $newParams = array_merge($contributionParams, array(
1283 'id' => $contribution['id'],
1284 'contribution_status_id' => 'Refunded',
1285 'cancel_date' => '2015-01-01 09:00',
1286 'trxn_id' => 'cont id',
1287 'refund_trxn_id' => '',
1288 )
1289 );
1290
1291 $contribution = $this->callAPISuccess('contribution', 'create', $newParams);
1292 $this->_checkFinancialTrxn($contribution, 'refund', NULL, array('trxn_id' => NULL));
1293 $this->_checkFinancialItem($contribution['id'], 'refund');
1294 $this->assertEquals('cont id', $this->callAPISuccessGetValue('Contribution', array(
1295 'id' => $contribution['id'],
1296 'return' => 'trxn_id',
1297 )));
8f39a111 1298 }
c71ae314 1299
a1a2a83d 1300 /**
eceb18cc 1301 * Function tests invalid contribution status change.
c71ae314 1302 */
00be9182 1303 public function testCreateUpdateContributionInValidStatusChange() {
c71ae314
PN
1304 $contribParams = array(
1305 'contact_id' => 1,
1306 'receive_date' => '2012-01-01',
1307 'total_amount' => 100.00,
1308 'financial_type_id' => 1,
1309 'payment_instrument_id' => 1,
1310 'contribution_status_id' => 1,
c71ae314 1311 );
4ab7d517 1312 $contribution = $this->callAPISuccess('contribution', 'create', $contribParams);
c71ae314 1313 $newParams = array_merge($contribParams, array(
5896d037
TO
1314 'id' => $contribution['id'],
1315 'contribution_status_id' => 2,
c71ae314
PN
1316 )
1317 );
6c6e6187 1318 $this->callAPIFailure('contribution', 'create', $newParams, ts('Cannot change contribution status from Completed to Pending.'));
c71ae314 1319
6a488035
TO
1320 }
1321
a1a2a83d 1322 /**
eceb18cc 1323 * Function tests that financial records are added when Pending Contribution is Canceled.
6a488035 1324 */
00be9182 1325 public function testCreateUpdateContributionCancelPending() {
6a488035
TO
1326 $contribParams = array(
1327 'contact_id' => $this->_individualId,
1328 'receive_date' => '2012-01-01',
1329 'total_amount' => 100.00,
4ab7d517 1330 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1331 'payment_instrument_id' => 1,
1332 'contribution_status_id' => 2,
c71ae314 1333 'is_pay_later' => 1,
4ab7d517 1334
6a488035 1335 );
4ab7d517 1336 $contribution = $this->callAPISuccess('contribution', 'create', $contribParams);
6a488035 1337 $newParams = array_merge($contribParams, array(
5896d037
TO
1338 'id' => $contribution['id'],
1339 'contribution_status_id' => 3,
6a488035
TO
1340 )
1341 );
694769da 1342 $contribution = $this->callAPISuccess('contribution', 'create', $newParams);
6a488035
TO
1343 $this->_checkFinancialTrxn($contribution, 'cancelPending');
1344 $this->_checkFinancialItem($contribution['id'], 'cancelPending');
1345 }
1346
a1a2a83d 1347 /**
eceb18cc 1348 * Function tests that financial records are added when Financial Type is Changed.
6a488035 1349 */
00be9182 1350 public function testCreateUpdateContributionChangeFinancialType() {
6a488035
TO
1351 $contribParams = array(
1352 'contact_id' => $this->_individualId,
1353 'receive_date' => '2012-01-01',
1354 'total_amount' => 100.00,
1355 'financial_type_id' => 1,
1356 'payment_instrument_id' => 1,
1357 'contribution_status_id' => 1,
4ab7d517 1358
6a488035 1359 );
4ab7d517 1360 $contribution = $this->callAPISuccess('contribution', 'create', $contribParams);
6a488035 1361 $newParams = array_merge($contribParams, array(
5896d037
TO
1362 'id' => $contribution['id'],
1363 'financial_type_id' => 3,
6a488035
TO
1364 )
1365 );
694769da 1366 $contribution = $this->callAPISuccess('contribution', 'create', $newParams);
6a488035
TO
1367 $this->_checkFinancialTrxn($contribution, 'changeFinancial');
1368 $this->_checkFinancialItem($contribution['id'], 'changeFinancial');
1369 }
1370
694769da 1371 /**
1e52837d 1372 * Test that update does not change status id CRM-15105.
694769da 1373 */
00be9182 1374 public function testCreateUpdateWithoutChangingPendingStatus() {
694769da
VU
1375 $contribution = $this->callAPISuccess('contribution', 'create', array_merge($this->_params, array('contribution_status_id' => 2)));
1376 $this->callAPISuccess('contribution', 'create', array('id' => $contribution['id'], 'source' => 'new source'));
5896d037 1377 $contribution = $this->callAPISuccess('contribution', 'getsingle', array(
92915c55
TO
1378 'id' => $contribution['id'],
1379 'api.contribution.delete' => 1,
1380 ));
694769da
VU
1381 $this->assertEquals(2, $contribution['contribution_status_id']);
1382 }
a1a2a83d
TO
1383
1384 /**
28de42d1
EM
1385 * Test Updating a Contribution.
1386 *
a1a2a83d
TO
1387 * CHANGE: we require the API to do an incremental update
1388 */
00be9182 1389 public function testCreateUpdateContribution() {
6a488035 1390
78ab0ca4 1391 $contributionID = $this->contributionCreate(array(
1392 'contact_id' => $this->_individualId,
1393 'trxn_id' => 212355,
1394 'financial_type_id' => $this->_financialTypeId,
1395 'invoice_id' => 'old_invoice',
1396 ));
6a488035
TO
1397 $old_params = array(
1398 'contribution_id' => $contributionID,
6a488035 1399 );
4ab7d517 1400 $original = $this->callAPISuccess('contribution', 'get', $old_params);
2bfae985 1401 $this->assertEquals($original['id'], $contributionID);
6a488035
TO
1402 //set up list of old params, verify
1403
1404 //This should not be required on update:
1405 $old_contact_id = $original['values'][$contributionID]['contact_id'];
7d543448 1406 $old_payment_instrument = $original['values'][$contributionID]['instrument_id'];
6a488035
TO
1407 $old_fee_amount = $original['values'][$contributionID]['fee_amount'];
1408 $old_source = $original['values'][$contributionID]['contribution_source'];
1409
6a488035
TO
1410 $old_trxn_id = $original['values'][$contributionID]['trxn_id'];
1411 $old_invoice_id = $original['values'][$contributionID]['invoice_id'];
1412
1413 //check against values in CiviUnitTestCase::createContribution()
2bfae985
EM
1414 $this->assertEquals($old_contact_id, $this->_individualId);
1415 $this->assertEquals($old_fee_amount, 5.00);
1416 $this->assertEquals($old_source, 'SSF');
1417 $this->assertEquals($old_trxn_id, 212355);
78ab0ca4 1418 $this->assertEquals($old_invoice_id, 'old_invoice');
6a488035
TO
1419 $params = array(
1420 'id' => $contributionID,
1421 'contact_id' => $this->_individualId,
1422 'total_amount' => 110.00,
4ab7d517 1423 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1424 'non_deductible_amount' => 10.00,
1425 'net_amount' => 100.00,
1426 'contribution_status_id' => 1,
1427 'note' => 'Donating for Nobel Cause',
4ab7d517 1428
6a488035
TO
1429 );
1430
4ab7d517 1431 $contribution = $this->callAPISuccess('contribution', 'create', $params);
6a488035
TO
1432
1433 $new_params = array(
1434 'contribution_id' => $contribution['id'],
4ab7d517 1435
6a488035 1436 );
4ab7d517 1437 $contribution = $this->callAPISuccess('contribution', 'get', $new_params);
6a488035 1438
2bfae985
EM
1439 $this->assertEquals($contribution['values'][$contributionID]['contact_id'], $this->_individualId);
1440 $this->assertEquals($contribution['values'][$contributionID]['total_amount'], 110.00);
ff977830 1441 $this->assertEquals($contribution['values'][$contributionID]['financial_type_id'], $this->_financialTypeId);
7d543448 1442 $this->assertEquals($contribution['values'][$contributionID]['instrument_id'], $old_payment_instrument);
2bfae985
EM
1443 $this->assertEquals($contribution['values'][$contributionID]['non_deductible_amount'], 10.00);
1444 $this->assertEquals($contribution['values'][$contributionID]['fee_amount'], $old_fee_amount);
1445 $this->assertEquals($contribution['values'][$contributionID]['net_amount'], 100.00);
1446 $this->assertEquals($contribution['values'][$contributionID]['trxn_id'], $old_trxn_id);
1447 $this->assertEquals($contribution['values'][$contributionID]['invoice_id'], $old_invoice_id);
1448 $this->assertEquals($contribution['values'][$contributionID]['contribution_source'], $old_source);
1449 $this->assertEquals($contribution['values'][$contributionID]['contribution_status'], 'Completed');
6a488035
TO
1450 $params = array(
1451 'contribution_id' => $contributionID,
4ab7d517 1452
6a488035 1453 );
4ab7d517 1454 $result = $this->callAPISuccess('contribution', 'delete', $params);
22f80e87 1455 $this->assertAPISuccess($result);
6a488035
TO
1456 }
1457
1458 ///////////////// civicrm_contribution_delete methods
a1a2a83d
TO
1459
1460 /**
1461 * Attempt (but fail) to delete a contribution without parameters.
1462 */
00be9182 1463 public function testDeleteEmptyParamsContribution() {
4ab7d517 1464 $params = array();
858d0bf8 1465 $this->callAPIFailure('contribution', 'delete', $params);
6a488035
TO
1466 }
1467
00be9182 1468 public function testDeleteParamsNotArrayContribution() {
6a488035 1469 $params = 'contribution_id= 1';
d0e1eff2 1470 $contribution = $this->callAPIFailure('contribution', 'delete', $params);
6a488035
TO
1471 $this->assertEquals($contribution['error_message'], 'Input variable `params` is not an array');
1472 }
1473
00be9182 1474 public function testDeleteWrongParamContribution() {
6a488035
TO
1475 $params = array(
1476 'contribution_source' => 'SSF',
4ab7d517 1477
6a488035 1478 );
858d0bf8 1479 $this->callAPIFailure('contribution', 'delete', $params);
6a488035
TO
1480 }
1481
00be9182 1482 public function testDeleteContribution() {
78ab0ca4 1483 $contributionID = $this->contributionCreate(array(
1484 'contact_id' => $this->_individualId,
1485 'financial_type_id' => $this->_financialTypeId,
1486 ));
6a488035
TO
1487 $params = array(
1488 'id' => $contributionID,
6a488035 1489 );
4ab7d517 1490 $this->callAPIAndDocument('contribution', 'delete', $params, __FUNCTION__, __FILE__);
6a488035
TO
1491 }
1492
1493 /**
d177a2a6 1494 * Test civicrm_contribution_search with empty params.
1e52837d 1495 *
d177a2a6 1496 * All available contributions expected.
6a488035 1497 */
00be9182 1498 public function testSearchEmptyParams() {
4ab7d517 1499 $params = array();
6a488035
TO
1500
1501 $p = array(
1502 'contact_id' => $this->_individualId,
1503 'receive_date' => date('Ymd'),
1504 'total_amount' => 100.00,
4ab7d517 1505 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1506 'non_deductible_amount' => 10.00,
1507 'fee_amount' => 5.00,
1508 'net_amount' => 95.00,
1509 'trxn_id' => 23456,
1510 'invoice_id' => 78910,
1511 'source' => 'SSF',
1512 'contribution_status_id' => 1,
4ab7d517 1513
6a488035 1514 );
4ab7d517 1515 $contribution = $this->callAPISuccess('contribution', 'create', $p);
6a488035 1516
4ab7d517 1517 $result = $this->callAPISuccess('contribution', 'get', $params);
6a488035
TO
1518 // We're taking the first element.
1519 $res = $result['values'][$contribution['id']];
1520
2bfae985
EM
1521 $this->assertEquals($p['contact_id'], $res['contact_id']);
1522 $this->assertEquals($p['total_amount'], $res['total_amount']);
5896d037 1523 $this->assertEquals($p['financial_type_id'], $res['financial_type_id']);
2bfae985
EM
1524 $this->assertEquals($p['net_amount'], $res['net_amount']);
1525 $this->assertEquals($p['non_deductible_amount'], $res['non_deductible_amount']);
1526 $this->assertEquals($p['fee_amount'], $res['fee_amount']);
1527 $this->assertEquals($p['trxn_id'], $res['trxn_id']);
1528 $this->assertEquals($p['invoice_id'], $res['invoice_id']);
1529 $this->assertEquals($p['source'], $res['contribution_source']);
6a488035 1530 // contribution_status_id = 1 => Completed
2bfae985 1531 $this->assertEquals('Completed', $res['contribution_status']);
6a488035
TO
1532
1533 $this->contributionDelete($contribution['id']);
1534 }
1535
1536 /**
d177a2a6 1537 * Test civicrm_contribution_search. Success expected.
6a488035 1538 */
00be9182 1539 public function testSearch() {
6a488035
TO
1540 $p1 = array(
1541 'contact_id' => $this->_individualId,
1542 'receive_date' => date('Ymd'),
1543 'total_amount' => 100.00,
4ab7d517 1544 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1545 'non_deductible_amount' => 10.00,
1546 'contribution_status_id' => 1,
4ab7d517 1547
6a488035 1548 );
4ab7d517 1549 $contribution1 = $this->callAPISuccess('contribution', 'create', $p1);
6a488035
TO
1550
1551 $p2 = array(
1552 'contact_id' => $this->_individualId,
1553 'receive_date' => date('Ymd'),
1554 'total_amount' => 200.00,
4ab7d517 1555 'financial_type_id' => $this->_financialTypeId,
6a488035
TO
1556 'non_deductible_amount' => 20.00,
1557 'trxn_id' => 5454565,
1558 'invoice_id' => 1212124,
1559 'fee_amount' => 50.00,
1560 'net_amount' => 60.00,
1561 'contribution_status_id' => 2,
4ab7d517 1562
6a488035 1563 );
2f45e1c2 1564 $contribution2 = $this->callAPISuccess('contribution', 'create', $p2);
6a488035
TO
1565
1566 $params = array(
1567 'contribution_id' => $contribution2['id'],
4ab7d517 1568
6a488035 1569 );
2f45e1c2 1570 $result = $this->callAPISuccess('contribution', 'get', $params);
6a488035
TO
1571 $res = $result['values'][$contribution2['id']];
1572
2bfae985
EM
1573 $this->assertEquals($p2['contact_id'], $res['contact_id']);
1574 $this->assertEquals($p2['total_amount'], $res['total_amount']);
5896d037 1575 $this->assertEquals($p2['financial_type_id'], $res['financial_type_id']);
2bfae985
EM
1576 $this->assertEquals($p2['net_amount'], $res['net_amount']);
1577 $this->assertEquals($p2['non_deductible_amount'], $res['non_deductible_amount']);
1578 $this->assertEquals($p2['fee_amount'], $res['fee_amount']);
1579 $this->assertEquals($p2['trxn_id'], $res['trxn_id']);
1580 $this->assertEquals($p2['invoice_id'], $res['invoice_id']);
6a488035 1581 // contribution_status_id = 2 => Pending
2bfae985 1582 $this->assertEquals('Pending', $res['contribution_status']);
6a488035
TO
1583
1584 $this->contributionDelete($contribution1['id']);
1585 $this->contributionDelete($contribution2['id']);
1586 }
2f45e1c2 1587
0efa8efe 1588 /**
eceb18cc 1589 * Test completing a transaction via the API.
0efa8efe 1590 *
1591 * Note that we are creating a logged in user because email goes out from
1592 * that person
1593 */
00be9182 1594 public function testCompleteTransaction() {
5896d037 1595 $mut = new CiviMailUtils($this, TRUE);
ec7e3954 1596 $this->swapMessageTemplateForTestTemplate();
0efa8efe 1597 $this->createLoggedInUser();
6c6e6187
TO
1598 $params = array_merge($this->_params, array('contribution_status_id' => 2));
1599 $contribution = $this->callAPISuccess('contribution', 'create', $params);
66d3f9be 1600 $this->callAPISuccess('contribution', 'completetransaction', array(
0efa8efe 1601 'id' => $contribution['id'],
66d3f9be 1602 ));
cc7b912f 1603 $contribution = $this->callAPISuccess('contribution', 'getsingle', array('id' => $contribution['id']));
d5580ed4 1604 $this->assertEquals('SSF', $contribution['contribution_source']);
cc7b912f 1605 $this->assertEquals('Completed', $contribution['contribution_status']);
1606 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($contribution['receipt_date'])));
0efa8efe 1607 $mut->checkMailLog(array(
ec7e3954
E
1608 'email:::anthony_anderson@civicrm.org',
1609 'is_monetary:::1',
1610 'amount:::100.00',
1611 'currency:::USD',
1612 'receive_date:::' . date('Ymd', strtotime($contribution['receive_date'])),
76e8d9c4 1613 "receipt_date:::\n",
ec7e3954
E
1614 'contributeMode:::notify',
1615 'title:::Contribution',
1616 'displayName:::Mr. Anthony Anderson II',
0efa8efe 1617 ));
46fa5206 1618 $mut->stop();
ec7e3954 1619 $this->revertTemplateToReservedTemplate();
46fa5206
EM
1620 }
1621
e05d2e11 1622 /**
1623 * Test to ensure mail is sent on chosing pay later
1624 */
1625 public function testpayLater() {
1626 $mut = new CiviMailUtils($this, TRUE);
1627 $this->swapMessageTemplateForTestTemplate();
1628 $this->createLoggedInUser();
1629
1630 // create contribution page first
1631 $contributionPageParams = array(
1632 'title' => 'Help Support CiviCRM!',
1633 'financial_type_id' => 1,
1634 'is_monetary' => TRUE,
1635 'is_pay_later' => 1,
1636 'is_quick_config' => TRUE,
1637 'pay_later_text' => 'I will send payment by check',
1638 'pay_later_receipt' => 'This is a pay later reciept',
1639 'is_allow_other_amount' => 1,
1640 'min_amount' => 10.00,
1641 'max_amount' => 10000.00,
1642 'goal_amount' => 100000.00,
1643 'is_email_receipt' => 1,
1644 'is_active' => 1,
1645 'amount_block_is_active' => 1,
1646 'currency' => 'USD',
1647 'is_billing_required' => 0,
1648 );
1649 $contributionPageResult = $this->callAPISuccess('contribution_page', 'create', $contributionPageParams);
1650
1651 // submit form values
1652 $priceSet = $this->callAPISuccess('price_set', 'getsingle', array('name' => 'default_contribution_amount'));
1653 $params = array(
1654 'id' => $contributionPageResult['id'],
1655 'contact_id' => $this->_individualId,
1656 'email-5' => 'anthony_anderson@civicrm.org',
1657 'payment_processor_id' => 0,
1658 'amount' => 100.00,
1659 'tax_amount' => '',
1660 'currencyID' => 'USD',
1661 'is_pay_later' => 1,
1662 'invoiceID' => 'f28e1ddc86f8c4a0ff5bcf46393e4bc8',
1663 'is_quick_config' => 1,
1664 'description' => 'Online Contribution: Help Support CiviCRM!',
1665 'price_set_id' => $priceSet['id'],
1666 );
1667 $this->callAPISuccess('contribution_page', 'submit', $params);
1668
1669 $mut->checkMailLog(array(
1670 'is_pay_later:::1',
1671 'email:::anthony_anderson@civicrm.org',
1672 'pay_later_receipt:::' . $contributionPageParams['pay_later_receipt'],
1673 'displayName:::Mr. Anthony Anderson II',
1674 'contributionPageId:::' . $contributionPageResult['id'],
1675 'title:::' . $contributionPageParams['title'],
8beee0e8 1676 'amount:::' . $params['amount'],
e05d2e11 1677 ));
1678 $mut->stop();
1679 $this->revertTemplateToReservedTemplate();
1680 }
1681
1682
2a0df9d9 1683 /**
1684 * Test to check whether contact billing address is used when no contribution address
1685 */
1686 public function testBillingAddress() {
1687 $mut = new CiviMailUtils($this, TRUE);
1688 $this->swapMessageTemplateForTestTemplate();
1689 $this->createLoggedInUser();
1690
1691 //Scenario 1: When Contact don't have any address
1692 $params = array_merge($this->_params, array('contribution_status_id' => 2));
1693 $contribution = $this->callAPISuccess('contribution', 'create', $params);
1694 $this->callAPISuccess('contribution', 'completetransaction', array(
1695 'id' => $contribution['id'],
1696 ));
1697 $mut->checkMailLog(array(
1698 'address:::',
1699 ));
1700
1701 // Scenario 2: Contribution using address
1702 $address = $this->callAPISuccess('address', 'create', array(
1703 'street_address' => 'contribution billing st',
1704 'location_type_id' => 2,
1705 'contact_id' => $this->_params['contact_id'],
1706 ));
76e8d9c4
E
1707 $params = array_merge($this->_params, array(
1708 'contribution_status_id' => 2,
2a0df9d9 1709 'address_id' => $address['id'],
1710 )
1711 );
1712 $contribution = $this->callAPISuccess('contribution', 'create', $params);
1713 $this->callAPISuccess('contribution', 'completetransaction', array(
1714 'id' => $contribution['id'],
1715 ));
1716 $mut->checkMailLog(array(
1717 'address:::contribution billing st',
1718 ));
1719
1720 // Scenario 3: Contribution wtth no address but contact has a billing address
1721 $this->callAPISuccess('address', 'create', array(
1722 'id' => $address['id'],
1723 'street_address' => 'is billing st',
1724 'contact_id' => $this->_params['contact_id'],
1725 ));
1726 $params = array_merge($this->_params, array('contribution_status_id' => 2));
1727 $contribution = $this->callAPISuccess('contribution', 'create', $params);
1728 $this->callAPISuccess('contribution', 'completetransaction', array(
1729 'id' => $contribution['id'],
1730 ));
1731 $mut->checkMailLog(array(
1732 'address:::is billing st',
1733 ));
1734
1735 $mut->stop();
1736 $this->revertTemplateToReservedTemplate();
1737 }
1738
080a561b 1739 /**
1740 * Test completing a transaction via the API.
1741 *
1742 * Note that we are creating a logged in user because email goes out from
1743 * that person
1744 */
1745 public function testCompleteTransactionFeeAmount() {
1746 $this->createLoggedInUser();
1747 $params = array_merge($this->_params, array('contribution_status_id' => 2));
1748 $contribution = $this->callAPISuccess('contribution', 'create', $params);
1749 $this->callAPISuccess('contribution', 'completetransaction', array(
1750 'id' => $contribution['id'],
1751 'fee_amount' => '.56',
1752 'trxn_id' => '7778888',
1753 ));
1754 $contribution = $this->callAPISuccess('contribution', 'getsingle', array('id' => $contribution['id'], 'sequential' => 1));
1755 $this->assertEquals('Completed', $contribution['contribution_status']);
1756 $this->assertEquals('7778888', $contribution['trxn_id']);
1757 $this->assertEquals('.56', $contribution['fee_amount']);
1758 $this->assertEquals('99.44', $contribution['net_amount']);
1759 }
1760
effb4d85
SL
1761 /**
1762 * CRM-19126 Add test to verify when complete transaction is called tax amount is not changed
1763 */
1764 public function testCheckTaxAmount() {
1765 $contact = $this->createLoggedInUser();
1766 $financialType = $this->callAPISuccess('financial_type', 'create', array(
1767 'name' => 'Test taxable financial Type',
1768 'is_reserved' => 0,
1769 'is_active' => 1,
1770 ));
1771 $financialAccount = $this->callAPISuccess('financial_account', 'create', array(
1772 'name' => 'Test Tax financial account ',
1773 'contact_id' => $contact,
1774 'financial_account_type_id' => 2,
1775 'is_tax' => 1,
1776 'tax_rate' => 5.00,
1777 'is_reserved' => 0,
1778 'is_active' => 1,
1779 'is_default' => 0,
1780 ));
1781 $financialTypeId = $financialType['id'];
1782 $financialAccountId = $financialAccount['id'];
1783 $financialAccountParams = array(
1784 'entity_table' => 'civicrm_financial_type',
1785 'entity_id' => $financialTypeId,
1786 'account_relationship' => 10,
1787 'financial_account_id' => $financialAccountId,
1788 );
a76b8bd8 1789 CRM_Financial_BAO_FinancialTypeAccount::add($financialAccountParams);
effb4d85
SL
1790 $taxRates = CRM_Core_PseudoConstant::getTaxRates();
1791 $params = array_merge($this->_params, array('contribution_status_id' => 2, 'financial_type_id' => $financialTypeId));
1792 $contribution = $this->callAPISuccess('contribution', 'create', $params);
1793 $contribution1 = $this->callAPISuccess('contribution', 'get', array('id' => $contribution['id'], 'return' => 'tax_amount', 'sequential' => 1));
1794 $this->callAPISuccess('contribution', 'completetransaction', array(
1795 'id' => $contribution['id'],
1796 'trxn_id' => '777788888',
99a4cd32 1797 'fee_amount' => '6.00',
effb4d85 1798 ));
99a4cd32 1799 $contribution2 = $this->callAPISuccess('contribution', 'get', array('id' => $contribution['id'], 'return' => array('tax_amount', 'fee_amount', 'net_amount'), 'sequential' => 1));
effb4d85 1800 $this->assertEquals($contribution1['values'][0]['tax_amount'], $contribution2['values'][0]['tax_amount']);
99a4cd32 1801 $this->assertEquals('6.00', $contribution2['values'][0]['fee_amount']);
f836984d 1802 $this->assertEquals('99.00', $contribution2['values'][0]['net_amount']);
effb4d85
SL
1803 }
1804
d97c96dc
EM
1805 /**
1806 * Test repeat contribution successfully creates line items.
1807 */
1e52837d 1808 public function testRepeatTransaction() {
893a550c 1809 $originalContribution = $this->setUpRepeatTransaction();
d97c96dc
EM
1810
1811 $this->callAPISuccess('contribution', 'repeattransaction', array(
1812 'original_contribution_id' => $originalContribution['id'],
1813 'contribution_status_id' => 'Completed',
1814 'trxn_id' => uniqid(),
1815 ));
1816 $lineItemParams = array(
1817 'entity_id' => $originalContribution['id'],
1818 'sequential' => 1,
1819 'return' => array(
1820 'entity_table',
1821 'qty',
1822 'unit_price',
1823 'line_total',
1824 'label',
1825 'financial_type_id',
1826 'deductible_amount',
1827 'price_field_value_id',
1828 'price_field_id',
1e52837d 1829 ),
d97c96dc
EM
1830 );
1831 $lineItem1 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array(
1832 'entity_id' => $originalContribution['id'],
1833 )));
1834 $lineItem2 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array(
1835 'entity_id' => $originalContribution['id'] + 1,
1836 )));
1837 unset($lineItem1['values'][0]['id'], $lineItem1['values'][0]['entity_id']);
1838 unset($lineItem2['values'][0]['id'], $lineItem2['values'][0]['entity_id']);
1839 $this->assertEquals($lineItem1['values'][0], $lineItem2['values'][0]);
43c8d1dd 1840 $this->_checkFinancialRecords(array('id' => $originalContribution['id'] + 1), 'online');
d97c96dc
EM
1841 $this->quickCleanUpFinancialEntities();
1842 }
1843
893a550c 1844 /**
1845 * Test repeat contribution successfully creates line items.
1846 */
1847 public function testRepeatTransactionIsTest() {
1848 $this->_params['is_test'] = 1;
1849 $originalContribution = $this->setUpRepeatTransaction(array('is_test' => 1));
1850
1851 $this->callAPISuccess('contribution', 'repeattransaction', array(
1852 'original_contribution_id' => $originalContribution['id'],
1853 'contribution_status_id' => 'Completed',
1854 'trxn_id' => uniqid(),
1855 ));
1856 $this->callAPISuccessGetCount('Contribution', array('contribution_test' => 1), 2);
1857 }
1858
d5580ed4 1859 /**
1860 * Test repeat contribution passed in status.
1861 */
1862 public function testRepeatTransactionPassedInStatus() {
1863 $originalContribution = $this->setUpRepeatTransaction();
1864
1865 $this->callAPISuccess('contribution', 'repeattransaction', array(
1866 'original_contribution_id' => $originalContribution['id'],
1867 'contribution_status_id' => 'Pending',
1868 'trxn_id' => uniqid(),
1869 ));
1870 $this->callAPISuccessGetCount('Contribution', array('contribution_status_id' => 2), 1);
1871 }
1872
1eade77d 1873 /**
1874 * Test repeat contribution accepts recur_id instead of original_contribution_id.
1875 */
1876 public function testRepeatTransactionAcceptRecurID() {
1877 $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array(
1878 'contact_id' => $this->_individualId,
1879 'installments' => '12',
1880 'frequency_interval' => '1',
1881 'amount' => '100',
1882 'contribution_status_id' => 1,
1883 'start_date' => '2012-01-01 00:00:00',
1884 'currency' => 'USD',
1885 'frequency_unit' => 'month',
1886 'payment_processor_id' => $this->paymentProcessorID,
1887 ));
1888 $this->callAPISuccess('contribution', 'create', array_merge(
1889 $this->_params,
1890 array('contribution_recur_id' => $contributionRecur['id']))
1891 );
1892
1893 $this->callAPISuccess('contribution', 'repeattransaction', array(
1894 'contribution_recur_id' => $contributionRecur['id'],
1895 'contribution_status_id' => 'Completed',
1896 'trxn_id' => uniqid(),
1897 ));
1898
1899 $this->quickCleanUpFinancialEntities();
1900 }
1901
c03f1689
EM
1902 /**
1903 * CRM-16397 test appropriate action if total amount has changed for single line items.
1904 */
1905 public function testRepeatTransactionAlteredAmount() {
1906 $paymentProcessorID = $this->paymentProcessorCreate();
c03f1689
EM
1907 $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array(
1908 'contact_id' => $this->_individualId,
1909 'installments' => '12',
1910 'frequency_interval' => '1',
1911 'amount' => '500',
1912 'contribution_status_id' => 1,
1913 'start_date' => '2012-01-01 00:00:00',
1914 'currency' => 'USD',
1915 'frequency_unit' => 'month',
1916 'payment_processor_id' => $paymentProcessorID,
1917 ));
1918 $originalContribution = $this->callAPISuccess('contribution', 'create', array_merge(
1919 $this->_params,
1920 array(
1921 'contribution_recur_id' => $contributionRecur['id'],
c03f1689
EM
1922 ))
1923 );
1924
1925 $this->callAPISuccess('contribution', 'repeattransaction', array(
1926 'original_contribution_id' => $originalContribution['id'],
1927 'contribution_status_id' => 'Completed',
1928 'trxn_id' => uniqid(),
1929 'total_amount' => '400',
1930 'fee_amount' => 50,
c03f1689
EM
1931 ));
1932 $lineItemParams = array(
1933 'entity_id' => $originalContribution['id'],
1934 'sequential' => 1,
1935 'return' => array(
1936 'entity_table',
1937 'qty',
1938 'unit_price',
1939 'line_total',
1940 'label',
1941 'financial_type_id',
1942 'deductible_amount',
1943 'price_field_value_id',
1944 'price_field_id',
1945 ),
1946 );
1947 $this->callAPISuccessGetSingle('contribution', array(
1948 'total_amount' => 400,
c03f1689
EM
1949 'fee_amount' => 50,
1950 'net_amount' => 350,
1951 ));
1952 $lineItem1 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array(
1953 'entity_id' => $originalContribution['id'],
1954 )));
1955 $expectedLineItem = array_merge(
1956 $lineItem1['values'][0], array(
1957 'line_total' => '400.00',
1958 'unit_price' => '400.00',
542d9e2c
EM
1959 )
1960 );
c03f1689
EM
1961
1962 $lineItem2 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array(
1963 'entity_id' => $originalContribution['id'] + 1,
1964 )));
1965 unset($expectedLineItem['id'], $expectedLineItem['entity_id']);
1966 unset($lineItem2['values'][0]['id'], $lineItem2['values'][0]['entity_id']);
1967 $this->assertEquals($expectedLineItem, $lineItem2['values'][0]);
c02c17df 1968 }
c03f1689 1969
3c49d90c 1970 /**
1971 * CRM-17718 test appropriate action if financial type has changed for single line items.
1972 */
1973 public function testRepeatTransactionPassedInFinancialType() {
1974 $originalContribution = $this->setUpRecurringContribution();
1975
1976 $this->callAPISuccess('contribution', 'repeattransaction', array(
1977 'original_contribution_id' => $originalContribution['id'],
1978 'contribution_status_id' => 'Completed',
1979 'trxn_id' => uniqid(),
1980 'financial_type_id' => 2,
1981 ));
1982 $lineItemParams = array(
1983 'entity_id' => $originalContribution['id'],
1984 'sequential' => 1,
1985 'return' => array(
1986 'entity_table',
1987 'qty',
1988 'unit_price',
1989 'line_total',
1990 'label',
1991 'financial_type_id',
1992 'deductible_amount',
1993 'price_field_value_id',
1994 'price_field_id',
1995 ),
1996 );
1997
1998 $this->callAPISuccessGetSingle('contribution', array(
1999 'total_amount' => 100,
2000 'financial_type_id' => 2,
2001 ));
2002 $lineItem1 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array(
2003 'entity_id' => $originalContribution['id'],
2004 )));
2005 $expectedLineItem = array_merge(
2006 $lineItem1['values'][0], array(
2007 'line_total' => '100.00',
2008 'unit_price' => '100.00',
2009 'financial_type_id' => 2,
2010 )
2011 );
2012
2013 $lineItem2 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array(
2014 'entity_id' => $originalContribution['id'] + 1,
2015 )));
2016 unset($expectedLineItem['id'], $expectedLineItem['entity_id']);
2017 unset($lineItem2['values'][0]['id'], $lineItem2['values'][0]['entity_id']);
2018 $this->assertEquals($expectedLineItem, $lineItem2['values'][0]);
2019 }
2020
7f4ef731 2021 /**
2022 * CRM-17718 test appropriate action if financial type has changed for single line items.
2023 */
2024 public function testRepeatTransactionUpdatedFinancialType() {
2025 $originalContribution = $this->setUpRecurringContribution(array(), array('financial_type_id' => 2));
2026
2027 $this->callAPISuccess('contribution', 'repeattransaction', array(
2028 'contribution_recur_id' => $originalContribution['id'],
2029 'contribution_status_id' => 'Completed',
2030 'trxn_id' => uniqid(),
2031 ));
2032 $lineItemParams = array(
2033 'entity_id' => $originalContribution['id'],
2034 'sequential' => 1,
2035 'return' => array(
2036 'entity_table',
2037 'qty',
2038 'unit_price',
2039 'line_total',
2040 'label',
2041 'financial_type_id',
2042 'deductible_amount',
2043 'price_field_value_id',
2044 'price_field_id',
2045 ),
2046 );
2047
2048 $this->callAPISuccessGetSingle('contribution', array(
2049 'total_amount' => 100,
2050 'financial_type_id' => 2,
2051 ));
2052 $lineItem1 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array(
2053 'entity_id' => $originalContribution['id'],
2054 )));
2055 $expectedLineItem = array_merge(
2056 $lineItem1['values'][0], array(
2057 'line_total' => '100.00',
2058 'unit_price' => '100.00',
2059 'financial_type_id' => 2,
2060 )
2061 );
2062
2063 $lineItem2 = $this->callAPISuccess('line_item', 'get', array_merge($lineItemParams, array(
2064 'entity_id' => $originalContribution['id'] + 1,
2065 )));
2066 unset($expectedLineItem['id'], $expectedLineItem['entity_id']);
2067 unset($lineItem2['values'][0]['id'], $lineItem2['values'][0]['entity_id']);
2068 $this->assertEquals($expectedLineItem, $lineItem2['values'][0]);
2069 }
2070
c02c17df 2071 /**
1eade77d 2072 * CRM-16397 test appropriate action if campaign has been passed in.
c02c17df 2073 */
2074 public function testRepeatTransactionPassedInCampaign() {
2075 $paymentProcessorID = $this->paymentProcessorCreate();
2076 $campaignID = $this->campaignCreate();
2077 $campaignID2 = $this->campaignCreate();
2078 $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array(
2079 'contact_id' => $this->_individualId,
2080 'installments' => '12',
2081 'frequency_interval' => '1',
2082 'amount' => '100',
2083 'contribution_status_id' => 1,
2084 'start_date' => '2012-01-01 00:00:00',
2085 'currency' => 'USD',
2086 'frequency_unit' => 'month',
2087 'payment_processor_id' => $paymentProcessorID,
2088 ));
2089 $originalContribution = $this->callAPISuccess('contribution', 'create', array_merge(
2090 $this->_params,
2091 array(
2092 'contribution_recur_id' => $contributionRecur['id'],
2093 'campaign_id' => $campaignID,
2094 ))
2095 );
2096
2097 $this->callAPISuccess('contribution', 'repeattransaction', array(
2098 'original_contribution_id' => $originalContribution['id'],
2099 'contribution_status_id' => 'Completed',
2100 'trxn_id' => uniqid(),
2101 'campaign_id' => $campaignID2,
2102 ));
2103
2104 $this->callAPISuccessGetSingle('contribution', array(
2105 'total_amount' => 100,
2106 'campaign_id' => $campaignID2,
2107 ));
2108 }
2109
2110 /**
2111 * CRM-17718 campaign stored on contribution recur gets priority.
2112 *
2113 * This reflects the fact we permit people to update them.
2114 */
2115 public function testRepeatTransactionUpdatedCampaign() {
2116 $paymentProcessorID = $this->paymentProcessorCreate();
2117 $campaignID = $this->campaignCreate();
2118 $campaignID2 = $this->campaignCreate();
2119 $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array(
2120 'contact_id' => $this->_individualId,
2121 'installments' => '12',
2122 'frequency_interval' => '1',
2123 'amount' => '100',
2124 'contribution_status_id' => 1,
2125 'start_date' => '2012-01-01 00:00:00',
2126 'currency' => 'USD',
2127 'frequency_unit' => 'month',
2128 'payment_processor_id' => $paymentProcessorID,
2129 'campaign_id' => $campaignID,
2130 ));
2131 $originalContribution = $this->callAPISuccess('contribution', 'create', array_merge(
2132 $this->_params,
2133 array(
2134 'contribution_recur_id' => $contributionRecur['id'],
2135 'campaign_id' => $campaignID2,
2136 ))
2137 );
2138
2139 $this->callAPISuccess('contribution', 'repeattransaction', array(
2140 'original_contribution_id' => $originalContribution['id'],
2141 'contribution_status_id' => 'Completed',
2142 'trxn_id' => uniqid(),
2143 ));
2144
2145 $this->callAPISuccessGetSingle('contribution', array(
2146 'total_amount' => 100,
2147 'campaign_id' => $campaignID,
2148 ));
c03f1689
EM
2149 }
2150
2936c3b5
EM
2151 /**
2152 * Test completing a transaction does not 'mess' with net amount (CRM-15960).
2153 */
2154 public function testCompleteTransactionNetAmountOK() {
2155 $this->createLoggedInUser();
2156 $params = array_merge($this->_params, array('contribution_status_id' => 2));
2157 unset($params['net_amount']);
2158 $contribution = $this->callAPISuccess('contribution', 'create', $params);
2159 $this->callAPISuccess('contribution', 'completetransaction', array(
2160 'id' => $contribution['id'],
2161 ));
2162 $contribution = $this->callAPISuccess('contribution', 'getsingle', array('id' => $contribution['id']));
2163 $this->assertEquals('Completed', $contribution['contribution_status']);
2164 $this->assertTrue(($contribution['total_amount'] - $contribution['net_amount']) == $contribution['fee_amount']);
2165 }
2166
46fa5206 2167 /**
1e52837d 2168 * CRM-14151 - Test completing a transaction via the API.
46fa5206 2169 */
00be9182 2170 public function testCompleteTransactionWithReceiptDateSet() {
76e8d9c4 2171 $this->swapMessageTemplateForTestTemplate();
5896d037 2172 $mut = new CiviMailUtils($this, TRUE);
46fa5206 2173 $this->createLoggedInUser();
6c6e6187
TO
2174 $params = array_merge($this->_params, array('contribution_status_id' => 2, 'receipt_date' => 'now'));
2175 $contribution = $this->callAPISuccess('contribution', 'create', $params);
7104593e 2176 $this->callAPISuccess('contribution', 'completetransaction', array('id' => $contribution['id'], 'trxn_date' => date('Y-m-d')));
6c6e6187 2177 $contribution = $this->callAPISuccess('contribution', 'get', array('id' => $contribution['id'], 'sequential' => 1));
46fa5206 2178 $this->assertEquals('Completed', $contribution['values'][0]['contribution_status']);
7104593e 2179 $this->assertEquals(date('Y-m-d'), date('Y-m-d', strtotime($contribution['values'][0]['receive_date'])));
46fa5206
EM
2180 $mut->checkMailLog(array(
2181 'Receipt - Contribution',
76e8d9c4 2182 'receipt_date:::' . date('Ymd'),
46fa5206 2183 ));
0efa8efe 2184 $mut->stop();
76e8d9c4 2185 $this->revertTemplateToReservedTemplate();
0efa8efe 2186 }
2187
b80f2ad1
E
2188
2189 /**
2190 * Complete the transaction using the template with all the possible.
2191 */
2192 public function testCompleteTransactionWithTestTemplate() {
2193 $this->swapMessageTemplateForTestTemplate();
ec7e3954 2194 $contribution = $this->setUpForCompleteTransaction();
b80f2ad1
E
2195 $this->callAPISuccess('contribution', 'completetransaction', array(
2196 'id' => $contribution['id'],
2197 'trxn_date' => date('2011-04-09'),
2198 'trxn_id' => 'kazam',
2199 ));
2200 $receive_date = $this->callAPISuccess('Contribution', 'getvalue', array('id' => $contribution['id'], 'return' => 'receive_date'));
ec7e3954 2201 $this->mut->checkMailLog(array(
b80f2ad1
E
2202 'email:::anthony_anderson@civicrm.org',
2203 'is_monetary:::1',
2204 'amount:::100.00',
2205 'currency:::USD',
2206 'receive_date:::' . date('Ymd', strtotime($receive_date)),
2207 'receipt_date:::' . date('Ymd'),
2208 'contributeMode:::notify',
2209 'title:::Contribution',
2210 'displayName:::Mr. Anthony Anderson II',
2211 'trxn_id:::kazam',
ec7e3954 2212 'contactID:::' . $this->_params['contact_id'],
b80f2ad1
E
2213 'contributionID:::' . $contribution['id'],
2214 'financialTypeId:::1',
2215 'financialTypeName:::Donation',
2216 ));
ec7e3954 2217 $this->mut->stop();
b80f2ad1
E
2218 $this->revertTemplateToReservedTemplate();
2219 }
2220
ec7e3954
E
2221 /**
2222 * Complete the transaction using the template with all the possible.
2223 */
2224 public function testCompleteTransactionContributionPageFromAddress() {
2225 $contributionPage = $this->callAPISuccess('ContributionPage', 'create', array(
2226 'receipt_from_name' => 'Mickey Mouse',
2227 'receipt_from_email' => 'mickey@mouse.com',
2228 'title' => "Test Contribution Page",
2229 'financial_type_id' => 1,
2230 'currency' => 'NZD',
2231 'goal_amount' => 50,
2232 'is_pay_later' => 1,
2233 'is_monetary' => TRUE,
2234 'is_email_receipt' => TRUE,
2235 ));
2236 $this->_params['contribution_page_id'] = $contributionPage['id'];
2237 $contribution = $this->setUpForCompleteTransaction();
2238 $this->callAPISuccess('contribution', 'completetransaction', array('id' => $contribution['id']));
2239 $this->mut->checkMailLog(array(
2240 'mickey@mouse.com',
2241 'Mickey Mouse <',
2242 ));
2243 $this->mut->stop();
2244 }
2245
91259407 2246 /**
2247 * Test completing first transaction in a recurring series.
2248 *
2249 * The status should be set to 'in progress' and the next scheduled payment date calculated.
2250 */
2251 public function testCompleteTransactionSetStatusToInProgress() {
2252 $paymentProcessorID = $this->paymentProcessorCreate();
2253 $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array(
2254 'contact_id' => $this->_individualId,
2255 'installments' => '12',
2256 'frequency_interval' => '1',
2257 'amount' => '500',
2258 'contribution_status_id' => 'Pending',
2259 'start_date' => '2012-01-01 00:00:00',
2260 'currency' => 'USD',
2261 'frequency_unit' => 'month',
2262 'payment_processor_id' => $paymentProcessorID,
2263 ));
2264 $contribution = $this->callAPISuccess('contribution', 'create', array_merge(
2265 $this->_params,
2266 array(
2267 'contribution_recur_id' => $contributionRecur['id'],
2268 'contribution_status_id' => 'Pending',
2269 ))
2270 );
2271 $this->callAPISuccess('Contribution', 'completetransaction', array('id' => $contribution));
2272 $contributionRecur = $this->callAPISuccessGetSingle('ContributionRecur', array(
2273 'id' => $contributionRecur['id'],
2274 'return' => array('next_sched_contribution_date', 'contribution_status_id'),
2275 ));
2276 $this->assertEquals(5, $contributionRecur['contribution_status_id']);
2277 $this->assertEquals(date('Y-m-d 00:00:00', strtotime('+1 month')), $contributionRecur['next_sched_contribution_date']);
2278 }
2279
294cc627 2280 /**
2281 * Test completing a pledge with the completeTransaction api..
2282 *
2283 * Note that we are creating a logged in user because email goes out from
2284 * that person.
2285 */
2286 public function testCompleteTransactionUpdatePledgePayment() {
9f9fa558 2287 $this->swapMessageTemplateForTestTemplate();
294cc627 2288 $mut = new CiviMailUtils($this, TRUE);
2289 $mut->clearMessages();
2290 $this->createLoggedInUser();
2291 $contributionID = $this->createPendingPledgeContribution();
2292 $this->callAPISuccess('contribution', 'completetransaction', array(
2293 'id' => $contributionID,
2294 'trxn_date' => '1 Feb 2013',
2295 ));
2296 $pledge = $this->callAPISuccessGetSingle('Pledge', array(
2297 'id' => $this->_ids['pledge'],
2298 ));
2299 $this->assertEquals('Completed', $pledge['pledge_status']);
2300
2301 $status = $this->callAPISuccessGetValue('PledgePayment', array(
2302 'pledge_id' => $this->_ids['pledge'],
2303 'return' => 'status_id',
2304 ));
2305 $this->assertEquals(1, $status);
2306 $mut->checkMailLog(array(
9f9fa558
EM
2307 'amount:::500.00',
2308 'receive_date:::20130201000000',
76e8d9c4 2309 "receipt_date:::\n",
294cc627 2310 ));
2311 $mut->stop();
9f9fa558 2312 $this->revertTemplateToReservedTemplate();
294cc627 2313 }
2314
0efa8efe 2315 /**
eceb18cc 2316 * Test completing a transaction with an event via the API.
0efa8efe 2317 *
2318 * Note that we are creating a logged in user because email goes out from
2319 * that person
2320 */
00be9182 2321 public function testCompleteTransactionWithParticipantRecord() {
5896d037 2322 $mut = new CiviMailUtils($this, TRUE);
0efa8efe 2323 $mut->clearMessages();
2324 $this->createLoggedInUser();
2325 $contributionID = $this->createPendingParticipantContribution();
66d3f9be 2326 $this->callAPISuccess('contribution', 'completetransaction', array(
5896d037
TO
2327 'id' => $contributionID,
2328 )
0efa8efe 2329 );
5896d037 2330 $participantStatus = $this->callAPISuccessGetValue('participant', array(
92915c55
TO
2331 'id' => $this->_ids['participant'],
2332 'return' => 'participant_status_id',
2333 ));
0efa8efe 2334 $this->assertEquals(1, $participantStatus);
2335 $mut->checkMailLog(array(
2336 'Annual CiviCRM meet',
2337 'Event',
afc59fef 2338 'This letter is a confirmation that your registration has been received and your status has been updated to Registered.',
0efa8efe 2339 ));
66d3f9be
EM
2340 $mut->stop();
2341 }
2342
2343 /**
eceb18cc 2344 * Test membership is renewed when transaction completed.
66d3f9be 2345 */
00be9182 2346 public function testCompleteTransactionMembershipPriceSet() {
66d3f9be 2347 $this->createPriceSetWithPage('membership');
4ff927bc 2348 $stateOfGrace = $this->callAPISuccess('MembershipStatus', 'getvalue', array(
2349 'name' => 'Grace',
2350 'return' => 'id')
2351 );
66d3f9be 2352 $this->setUpPendingContribution($this->_ids['price_field_value'][0]);
4ff927bc 2353 $membership = $this->callAPISuccess('membership', 'getsingle', array('id' => $this->_ids['membership']));
2354 $logs = $this->callAPISuccess('MembershipLog', 'get', array(
2355 'membership_id' => $this->_ids['membership'],
2356 ));
2357 $this->assertEquals(1, $logs['count']);
2358 $this->assertEquals($stateOfGrace, $membership['status_id']);
6c6e6187 2359 $this->callAPISuccess('contribution', 'completetransaction', array('id' => $this->_ids['contribution']));
66d3f9be
EM
2360 $membership = $this->callAPISuccess('membership', 'getsingle', array('id' => $this->_ids['membership']));
2361 $this->assertEquals(date('Y-m-d', strtotime('yesterday + 1 year')), $membership['end_date']);
4ff927bc 2362 $this->callAPISuccessGetSingle('LineItem', array(
2363 'entity_id' => $this->_ids['membership'],
2364 'entity_table' => 'civicrm_membership',
2365 ));
2366 $logs = $this->callAPISuccess('MembershipLog', 'get', array(
2367 'membership_id' => $this->_ids['membership'],
2368 ));
2369 $this->assertEquals(2, $logs['count']);
2370 $this->assertNotEquals($stateOfGrace, $logs['values'][2]['status_id']);
66d3f9be
EM
2371 $this->cleanUpAfterPriceSets();
2372 }
2373
2374 /**
eceb18cc 2375 * Test membership is renewed when transaction completed.
66d3f9be 2376 */
00be9182 2377 public function testCompleteTransactionMembershipPriceSetTwoTerms() {
66d3f9be
EM
2378 $this->createPriceSetWithPage('membership');
2379 $this->setUpPendingContribution($this->_ids['price_field_value'][1]);
6c6e6187 2380 $this->callAPISuccess('contribution', 'completetransaction', array('id' => $this->_ids['contribution']));
66d3f9be
EM
2381 $membership = $this->callAPISuccess('membership', 'getsingle', array('id' => $this->_ids['membership']));
2382 $this->assertEquals(date('Y-m-d', strtotime('yesterday + 2 years')), $membership['end_date']);
2383 $this->cleanUpAfterPriceSets();
2384 }
2385
00be9182 2386 public function cleanUpAfterPriceSets() {
1cf3c2b1 2387 $this->quickCleanUpFinancialEntities();
66d3f9be 2388 $this->contactDelete($this->_ids['contact']);
66d3f9be
EM
2389 }
2390
2391
2392 /**
1e52837d
EM
2393 * Create price set with contribution test for test setup.
2394 *
100fef9d 2395 * This could be merged with 4.5 function setup in api_v3_ContributionPageTest::setUpContributionPage
28de42d1 2396 * on parent class at some point (fn is not in 4.4).
1e52837d 2397 *
66d3f9be
EM
2398 * @param $entity
2399 * @param array $params
2400 */
00be9182 2401 public function createPriceSetWithPage($entity, $params = array()) {
66d3f9be
EM
2402 $membershipTypeID = $this->membershipTypeCreate();
2403 $contributionPageResult = $this->callAPISuccess('contribution_page', 'create', array(
2404 'title' => "Test Contribution Page",
2405 'financial_type_id' => 1,
2406 'currency' => 'NZD',
2407 'goal_amount' => 50,
2408 'is_pay_later' => 1,
2409 'is_monetary' => TRUE,
2410 'is_email_receipt' => FALSE,
2411 ));
2412 $priceSet = $this->callAPISuccess('price_set', 'create', array(
2413 'is_quick_config' => 0,
2414 'extends' => 'CiviMember',
2415 'financial_type_id' => 1,
21dfd5f5 2416 'title' => 'my Page',
66d3f9be
EM
2417 ));
2418 $priceSetID = $priceSet['id'];
2419
5896d037 2420 CRM_Price_BAO_PriceSet::addTo('civicrm_contribution_page', $contributionPageResult['id'], $priceSetID);
66d3f9be 2421 $priceField = $this->callAPISuccess('price_field', 'create', array(
5896d037 2422 'price_set_id' => $priceSetID,
66d3f9be
EM
2423 'label' => 'Goat Breed',
2424 'html_type' => 'Radio',
2425 ));
2426 $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', array(
5896d037 2427 'price_set_id' => $priceSetID,
66d3f9be
EM
2428 'price_field_id' => $priceField['id'],
2429 'label' => 'Long Haired Goat',
2430 'amount' => 20,
43dbd988 2431 'financial_type_id' => 'Donation',
66d3f9be
EM
2432 'membership_type_id' => $membershipTypeID,
2433 'membership_num_terms' => 1,
2434 )
2435 );
2436 $this->_ids['price_field_value'] = array($priceFieldValue['id']);
2437 $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', array(
5896d037 2438 'price_set_id' => $priceSetID,
66d3f9be
EM
2439 'price_field_id' => $priceField['id'],
2440 'label' => 'Shoe-eating Goat',
2441 'amount' => 10,
43dbd988 2442 'financial_type_id' => 'Donation',
66d3f9be
EM
2443 'membership_type_id' => $membershipTypeID,
2444 'membership_num_terms' => 2,
2445 )
2446 );
2447 $this->_ids['price_field_value'][] = $priceFieldValue['id'];
2448 $this->_ids['price_set'] = $priceSetID;
2449 $this->_ids['contribution_page'] = $contributionPageResult['id'];
2450 $this->_ids['price_field'] = array($priceField['id']);
0efa8efe 2451
66d3f9be
EM
2452 $this->_ids['membership_type'] = $membershipTypeID;
2453 }
2454
2455 /**
eceb18cc 2456 * Set up a pending transaction with a specific price field id.
1e52837d 2457 *
100fef9d 2458 * @param int $priceFieldValueID
66d3f9be 2459 */
5896d037 2460 public function setUpPendingContribution($priceFieldValueID) {
66d3f9be
EM
2461 $contactID = $this->individualCreate();
2462 $membership = $this->callAPISuccess('membership', 'create', array(
2463 'contact_id' => $contactID,
2464 'membership_type_id' => $this->_ids['membership_type'],
2465 'start_date' => 'yesterday - 1 year',
2466 'end_date' => 'yesterday',
4ff927bc 2467 'join_date' => 'yesterday - 1 year',
66d3f9be
EM
2468 ));
2469 $contribution = $this->callAPISuccess('contribution', 'create', array(
2470 'domain_id' => 1,
2471 'contact_id' => $contactID,
2472 'receive_date' => date('Ymd'),
2473 'total_amount' => 100.00,
2474 'financial_type_id' => 1,
2475 'payment_instrument_id' => 'Credit Card',
2476 'non_deductible_amount' => 10.00,
2477 'trxn_id' => 'jdhfi88',
2478 'invoice_id' => 'djfhiewuyr',
2479 'source' => 'SSF',
2480 'contribution_status_id' => 2,
2481 'contribution_page_id' => $this->_ids['contribution_page'],
2482 'api.membership_payment.create' => array('membership_id' => $membership['id']),
2483 ));
2484
2485 $this->callAPISuccess('line_item', 'create', array(
2486 'entity_id' => $contribution['id'],
2487 'entity_table' => 'civicrm_contribution',
1274acef 2488 'contribution_id' => $contribution['id'],
66d3f9be
EM
2489 'price_field_id' => $this->_ids['price_field'][0],
2490 'qty' => 1,
2491 'unit_price' => 20,
2492 'line_total' => 20,
2493 'financial_type_id' => 1,
2494 'price_field_value_id' => $priceFieldValueID,
2495 ));
2496 $this->_ids['contact'] = $contactID;
2497 $this->_ids['contribution'] = $contribution['id'];
2498 $this->_ids['membership'] = $membership['id'];
0efa8efe 2499 }
2500
2f45e1c2 2501 /**
eceb18cc 2502 * Test sending a mail via the API.
6a488035 2503 */
00be9182 2504 public function testSendMail() {
5896d037 2505 $mut = new CiviMailUtils($this, TRUE);
6c6e6187 2506 $contribution = $this->callAPISuccess('contribution', 'create', $this->_params);
858d0bf8 2507 $this->callAPISuccess('contribution', 'sendconfirmation', array(
5896d037
TO
2508 'id' => $contribution['id'],
2509 'receipt_from_email' => 'api@civicrm.org',
6a488035
TO
2510 )
2511 );
6a488035
TO
2512 $mut->checkMailLog(array(
2513 '$ 100.00',
2514 'Contribution Information',
2515 'Please print this confirmation for your records',
2516 ), array(
21dfd5f5 2517 'Event',
6a488035
TO
2518 )
2519 );
2520 $mut->stop();
2521 }
2522
2f45e1c2 2523 /**
eceb18cc 2524 * Test sending a mail via the API.
6a488035 2525 */
00be9182 2526 public function testSendMailEvent() {
5896d037 2527 $mut = new CiviMailUtils($this, TRUE);
6c6e6187 2528 $contribution = $this->callAPISuccess('contribution', 'create', $this->_params);
2f45e1c2 2529 $event = $this->eventCreate(array(
6a488035
TO
2530 'is_email_confirm' => 1,
2531 'confirm_from_email' => 'test@civicrm.org',
2532 ));
2533 $this->_eventID = $event['id'];
2534 $participantParams = array(
2535 'contact_id' => $this->_individualId,
2536 'event_id' => $this->_eventID,
2537 'status_id' => 1,
2538 'role_id' => 1,
2539 // to ensure it matches later on
2540 'register_date' => '2007-07-21 00:00:00',
2541 'source' => 'Online Event Registration: API Testing',
4ab7d517 2542
6a488035 2543 );
2f45e1c2 2544 $participant = $this->callAPISuccess('participant', 'create', $participantParams);
2545 $this->callAPISuccess('participant_payment', 'create', array(
6a488035
TO
2546 'participant_id' => $participant['id'],
2547 'contribution_id' => $contribution['id'],
2f45e1c2 2548 ));
66d3f9be 2549 $this->callAPISuccess('contribution', 'sendconfirmation', array(
5896d037
TO
2550 'id' => $contribution['id'],
2551 'receipt_from_email' => 'api@civicrm.org',
6a488035
TO
2552 )
2553 );
2554
6a488035
TO
2555 $mut->checkMailLog(array(
2556 'Annual CiviCRM meet',
2557 'Event',
2558 'To: "Mr. Anthony Anderson II" <anthony_anderson@civicrm.org>',
6c6e6187 2559 ), array()
6a488035
TO
2560 );
2561 $mut->stop();
2562 }
2563
4302618d 2564 /**
1e52837d
EM
2565 * This function does a GET & compares the result against the $params.
2566 *
2567 * Use as a double check on Creates.
2568 *
2569 * @param array $params
2570 * @param int $id
67f947ac 2571 * @param bool $delete
6c6e6187 2572 */
1e52837d 2573 public function contributionGetnCheck($params, $id, $delete = TRUE) {
6a488035 2574
4ab7d517 2575 $contribution = $this->callAPISuccess('Contribution', 'Get', array(
6a488035 2576 'id' => $id,
4ab7d517 2577
5896d037 2578 ));
6a488035
TO
2579
2580 if ($delete) {
4ab7d517 2581 $this->callAPISuccess('contribution', 'delete', array('id' => $id));
6a488035 2582 }
2bfae985 2583 $this->assertAPISuccess($contribution, 0);
6a488035
TO
2584 $values = $contribution['values'][$contribution['id']];
2585 $params['receive_date'] = date('Y-m-d H:i:s', strtotime($params['receive_date']));
2586 // this is not returned in id format
2587 unset($params['payment_instrument_id']);
2588 $params['contribution_source'] = $params['source'];
2589 unset($params['source']);
2590 foreach ($params as $key => $value) {
22f80e87 2591 $this->assertEquals($value, $values[$key], $key . " value: $value doesn't match " . print_r($values, TRUE));
6a488035
TO
2592 }
2593 }
2594
294cc627 2595 /**
2596 * Create a pending contribution & linked pending pledge record.
2597 */
2598 public function createPendingPledgeContribution() {
2599
2600 $pledgeID = $this->pledgeCreate(array('contact_id' => $this->_individualId, 'installments' => 1, 'amount' => 500));
2601 $this->_ids['pledge'] = $pledgeID;
2602 $contribution = $this->callAPISuccess('contribution', 'create', array_merge($this->_params, array(
2603 'contribution_status_id' => 'Pending',
2604 'total_amount' => 500,
2605 ))
2606 );
2607 $paymentID = $this->callAPISuccessGetValue('PledgePayment', array(
2608 'options' => array('limit' => 1),
2609 'return' => 'id',
2610 ));
2611 $this->callAPISuccess('PledgePayment', 'create', array(
2612 'id' => $paymentID,
2613 'contribution_id' =>
2614 $contribution['id'],
2615 'status_id' => 'Pending',
2616 'scheduled_amount' => 500,
2617 ));
2618
2619 return $contribution['id'];
2620 }
2621
0efa8efe 2622 /**
1e52837d 2623 * Create a pending contribution & linked pending participant record (along with an event).
0efa8efe 2624 */
5896d037 2625 public function createPendingParticipantContribution() {
6c6e6187 2626 $event = $this->eventCreate(array('is_email_confirm' => 1, 'confirm_from_email' => 'test@civicrm.org'));
0efa8efe 2627 $participantID = $this->participantCreate(array('event_id' => $event['id'], 'status_id' => 6));
5896d037 2628 $this->_ids['participant'] = $participantID;
0efa8efe 2629 $params = array_merge($this->_params, array('contribution_status_id' => 2, 'financial_type_id' => 'Event Fee'));
6c6e6187 2630 $contribution = $this->callAPISuccess('contribution', 'create', $params);
5896d037 2631 $this->callAPISuccess('participant_payment', 'create', array(
92915c55
TO
2632 'contribution_id' => $contribution['id'],
2633 'participant_id' => $participantID,
2634 ));
858d0bf8 2635 $this->callAPISuccess('line_item', 'get', array(
0efa8efe 2636 'entity_id' => $contribution['id'],
2637 'entity_table' => 'civicrm_contribution',
2638 'api.line_item.create' => array(
2639 'entity_id' => $participantID,
2640 'entity_table' => 'civicrm_participant',
2641 ),
2642 ));
2643 return $contribution['id'];
2644 }
2645
4cbe18b8 2646 /**
1e52837d
EM
2647 * Get financial transaction amount.
2648 *
100fef9d 2649 * @param int $contId
4cbe18b8
EM
2650 *
2651 * @return null|string
f4d89200 2652 */
2da40d21 2653 public function _getFinancialTrxnAmount($contId) {
6c6e6187 2654 $query = "SELECT
6a488035
TO
2655 SUM( ft.total_amount ) AS total
2656 FROM civicrm_financial_trxn AS ft
2657 LEFT JOIN civicrm_entity_financial_trxn AS ceft ON ft.id = ceft.financial_trxn_id
2658 WHERE ceft.entity_table = 'civicrm_contribution'
2659 AND ceft.entity_id = {$contId}";
2660
6c6e6187
TO
2661 $result = CRM_Core_DAO::singleValueQuery($query);
2662 return $result;
2663 }
6a488035 2664
4cbe18b8 2665 /**
100fef9d 2666 * @param int $contId
4cbe18b8
EM
2667 *
2668 * @return null|string
f4d89200 2669 */
2da40d21 2670 public function _getFinancialItemAmount($contId) {
6c6e6187
TO
2671 $lineItem = key(CRM_Price_BAO_LineItem::getLineItems($contId, 'contribution'));
2672 $query = "SELECT
6a488035
TO
2673 SUM(amount)
2674 FROM civicrm_financial_item
2675 WHERE entity_table = 'civicrm_line_item'
2676 AND entity_id = {$lineItem}";
6c6e6187
TO
2677 $result = CRM_Core_DAO::singleValueQuery($query);
2678 return $result;
2679 }
6a488035 2680
4cbe18b8 2681 /**
100fef9d 2682 * @param int $contId
4cbe18b8
EM
2683 * @param $context
2684 */
00be9182 2685 public function _checkFinancialItem($contId, $context) {
6c6e6187
TO
2686 if ($context != 'paylater') {
2687 $params = array(
5896d037
TO
2688 'entity_id' => $contId,
2689 'entity_table' => 'civicrm_contribution',
6c6e6187
TO
2690 );
2691 $trxn = current(CRM_Financial_BAO_FinancialItem::retrieveEntityFinancialTrxn($params, TRUE));
2692 $entityParams = array(
6a488035
TO
2693 'financial_trxn_id' => $trxn['financial_trxn_id'],
2694 'entity_table' => 'civicrm_financial_item',
6c6e6187
TO
2695 );
2696 $entityTrxn = current(CRM_Financial_BAO_FinancialItem::retrieveEntityFinancialTrxn($entityParams));
2697 $params = array(
6a488035 2698 'id' => $entityTrxn['entity_id'],
6c6e6187
TO
2699 );
2700 }
2701 if ($context == 'paylater') {
2702 $lineItems = CRM_Price_BAO_LineItem::getLineItems($contId, 'contribution');
2703 foreach ($lineItems as $key => $item) {
2704 $params = array(
5896d037
TO
2705 'entity_id' => $key,
2706 'entity_table' => 'civicrm_line_item',
6c6e6187
TO
2707 );
2708 $compareParams = array('status_id' => 1);
2709 $this->assertDBCompareValues('CRM_Financial_DAO_FinancialItem', $params, $compareParams);
2710 }
2711 }
2712 elseif ($context == 'refund') {
2713 $compareParams = array(
5896d037
TO
2714 'status_id' => 1,
2715 'financial_account_id' => 1,
2716 'amount' => -100,
6c6e6187
TO
2717 );
2718 }
2719 elseif ($context == 'cancelPending') {
2720 $compareParams = array(
5896d037
TO
2721 'status_id' => 3,
2722 'financial_account_id' => 1,
2723 'amount' => -100,
6c6e6187
TO
2724 );
2725 }
2726 elseif ($context == 'changeFinancial') {
2727 $lineKey = key(CRM_Price_BAO_LineItem::getLineItems($contId, 'contribution'));
2728 $params = array(
5896d037
TO
2729 'entity_id' => $lineKey,
2730 'amount' => -100,
6c6e6187
TO
2731 );
2732 $compareParams = array(
5896d037 2733 'financial_account_id' => 1,
6c6e6187
TO
2734 );
2735 $this->assertDBCompareValues('CRM_Financial_DAO_FinancialItem', $params, $compareParams);
2736 $params = array(
5896d037
TO
2737 'financial_account_id' => 3,
2738 'entity_id' => $lineKey,
6c6e6187
TO
2739 );
2740 $compareParams = array(
5896d037 2741 'amount' => 100,
6c6e6187
TO
2742 );
2743 }
2744 if ($context != 'paylater') {
2745 $this->assertDBCompareValues('CRM_Financial_DAO_FinancialItem', $params, $compareParams);
2746 }
2747 }
6a488035 2748
4cbe18b8 2749 /**
52da5b1e 2750 * Check financial transaction.
2751 *
2752 * @todo break this down into sensible functions - most calls to it only use a few lines out of the big if.
2753 *
4ff927bc 2754 * @param array $contribution
2755 * @param string $context
100fef9d 2756 * @param int $instrumentId
52da5b1e 2757 * @param array $extraParams
4cbe18b8 2758 */
797d4c52 2759 public function _checkFinancialTrxn($contribution, $context, $instrumentId = NULL, $extraParams = array()) {
6c6e6187 2760 $trxnParams = array(
5896d037
TO
2761 'entity_id' => $contribution['id'],
2762 'entity_table' => 'civicrm_contribution',
6c6e6187
TO
2763 );
2764 $trxn = current(CRM_Financial_BAO_FinancialItem::retrieveEntityFinancialTrxn($trxnParams, TRUE));
2765 $params = array(
5896d037 2766 'id' => $trxn['financial_trxn_id'],
6c6e6187
TO
2767 );
2768 if ($context == 'payLater') {
2769 $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' "));
2770 $compareParams = array(
5896d037
TO
2771 'status_id' => 1,
2772 'from_financial_account_id' => CRM_Contribute_PseudoConstant::financialAccountType($contribution['financial_type_id'], $relationTypeId),
6c6e6187
TO
2773 );
2774 }
2775 elseif ($context == 'refund') {
2776 $compareParams = array(
5896d037
TO
2777 'to_financial_account_id' => 6,
2778 'total_amount' => -100,
2779 'status_id' => 7,
b7990bb6 2780 'trxn_date' => '2015-01-01 09:00:00',
797d4c52 2781 'trxn_id' => 'the refund',
6c6e6187
TO
2782 );
2783 }
2784 elseif ($context == 'cancelPending') {
2785 $compareParams = array(
ed4d0aea 2786 'to_financial_account_id' => 7,
5896d037
TO
2787 'total_amount' => -100,
2788 'status_id' => 3,
6c6e6187
TO
2789 );
2790 }
2791 elseif ($context == 'changeFinancial' || $context == 'paymentInstrument') {
2792 $entityParams = array(
5896d037
TO
2793 'entity_id' => $contribution['id'],
2794 'entity_table' => 'civicrm_contribution',
2795 'amount' => -100,
6c6e6187
TO
2796 );
2797 $trxn = current(CRM_Financial_BAO_FinancialItem::retrieveEntityFinancialTrxn($entityParams));
2798 $trxnParams1 = array(
6a488035 2799 'id' => $trxn['financial_trxn_id'],
6c6e6187
TO
2800 );
2801 $compareParams = array(
5896d037
TO
2802 'total_amount' => -100,
2803 'status_id' => 1,
6c6e6187
TO
2804 );
2805 if ($context == 'paymentInstrument') {
2806 $compareParams += array(
5896d037
TO
2807 'to_financial_account_id' => CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount(4),
2808 'payment_instrument_id' => 4,
6c6e6187
TO
2809 );
2810 }
2811 else {
2812 $compareParams['to_financial_account_id'] = 12;
2813 }
797d4c52 2814 $this->assertDBCompareValues('CRM_Financial_DAO_FinancialTrxn', $trxnParams1, array_merge($compareParams, $extraParams));
6c6e6187
TO
2815 $compareParams['total_amount'] = 100;
2816 if ($context == 'paymentInstrument') {
2817 $compareParams['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($instrumentId);
2818 $compareParams['payment_instrument_id'] = $instrumentId;
2819 }
2820 else {
2821 $compareParams['to_financial_account_id'] = 12;
2822 }
2823 }
2824
797d4c52 2825 $this->assertDBCompareValues('CRM_Financial_DAO_FinancialTrxn', $params, array_merge($compareParams, $extraParams));
6c6e6187 2826 }
6a488035 2827
4cbe18b8
EM
2828 /**
2829 * @return mixed
2830 */
5896d037 2831 public function _addPaymentInstrument() {
6c6e6187
TO
2832 $gId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup', 'payment_instrument', 'id', 'name');
2833 $optionParams = array(
5896d037
TO
2834 'option_group_id' => $gId,
2835 'label' => 'Test Card',
2836 'name' => 'Test Card',
2837 'value' => '6',
2838 'weight' => '6',
2839 'is_active' => 1,
6c6e6187
TO
2840 );
2841 $optionValue = $this->callAPISuccess('option_value', 'create', $optionParams);
2842 $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Asset Account is' "));
2843 $financialParams = array(
5896d037
TO
2844 'entity_table' => 'civicrm_option_value',
2845 'entity_id' => $optionValue['id'],
2846 'account_relationship' => $relationTypeId,
2847 'financial_account_id' => 7,
6c6e6187
TO
2848 );
2849 CRM_Financial_BAO_FinancialTypeAccount::add($financialParams, CRM_Core_DAO::$_nullArray);
2850 $this->assertNotEmpty($optionValue['values'][$optionValue['id']]['value']);
2851 return $optionValue['values'][$optionValue['id']]['value'];
2852 }
6a488035 2853
3c49d90c 2854 /**
2855 * Set up the basic recurring contribution for tests.
2856 *
2857 * @param array $generalParams
2858 * Parameters that can be merged into the recurring AND the contribution.
7f4ef731 2859 *
2860 * @param array $recurParams
2861 * Parameters to merge into the recur only.
3c49d90c 2862 *
2863 * @return array|int
2864 */
7f4ef731 2865 protected function setUpRecurringContribution($generalParams = array(), $recurParams = array()) {
3c49d90c 2866 $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array_merge(array(
2867 'contact_id' => $this->_individualId,
2868 'installments' => '12',
2869 'frequency_interval' => '1',
2870 'amount' => '100',
2871 'contribution_status_id' => 1,
2872 'start_date' => '2012-01-01 00:00:00',
2873 'currency' => 'USD',
2874 'frequency_unit' => 'month',
2875 'payment_processor_id' => $this->paymentProcessorID,
7f4ef731 2876 ), $generalParams, $recurParams));
3c49d90c 2877 $originalContribution = $this->callAPISuccess('contribution', 'create', array_merge(
2878 $this->_params,
2879 array(
2880 'contribution_recur_id' => $contributionRecur['id'],
2881 ), $generalParams)
2882 );
2883 return $originalContribution;
2884 }
2885
893a550c 2886 /**
2887 * Set up a repeat transaction.
2888 *
2889 * @param array $recurParams
2890 *
2891 * @return array
2892 */
2893 protected function setUpRepeatTransaction($recurParams = array()) {
2894 $paymentProcessorID = $this->paymentProcessorCreate();
2895 $contributionRecur = $this->callAPISuccess('contribution_recur', 'create', array_merge(array(
2896 'contact_id' => $this->_individualId,
2897 'installments' => '12',
2898 'frequency_interval' => '1',
2899 'amount' => '500',
2900 'contribution_status_id' => 1,
2901 'start_date' => '2012-01-01 00:00:00',
2902 'currency' => 'USD',
2903 'frequency_unit' => 'month',
2904 'payment_processor_id' => $paymentProcessorID,
2905 ), $recurParams));
2906 $originalContribution = $this->callAPISuccess('contribution', 'create', array_merge(
2907 $this->_params,
2908 array('contribution_recur_id' => $contributionRecur['id']))
2909 );
2910 return $originalContribution;
2911 }
2912
ec7e3954
E
2913 /**
2914 * Common set up routine.
2915 *
2916 * @return array
2917 */
2918 protected function setUpForCompleteTransaction() {
2919 $this->mut = new CiviMailUtils($this, TRUE);
2920 $this->createLoggedInUser();
2921 $params = array_merge($this->_params, array('contribution_status_id' => 2, 'receipt_date' => 'now'));
2922 $contribution = $this->callAPISuccess('contribution', 'create', $params);
2923 return $contribution;
2924 }
2925
6a488035 2926}