CRM-19587, code cleanup and fixes
[civicrm-core.git] / tests / phpunit / CRM / Financial / BAO / FinancialAccountTest.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
e9479dcf
EM
28/**
29 * Class CRM_Financial_BAO_FinancialAccountTest
acb109b7 30 * @group headless
e9479dcf 31 */
6a488035
TO
32class CRM_Financial_BAO_FinancialAccountTest extends CiviUnitTestCase {
33
00be9182 34 public function setUp() {
bf2cf926 35 $this->useTransaction(TRUE);
6a488035 36 parent::setUp();
f17d75bb
PN
37 $this->organizationCreate();
38 }
39
6a488035 40 /**
100fef9d 41 * Check method add()
6a488035 42 */
00be9182 43 public function testAdd() {
6a488035
TO
44 $params = array(
45 'name' => 'Donations',
46 'is_deductible' => 0,
47 'is_active' => 1,
48 );
49 $ids = array();
50 $contributionType = CRM_Financial_BAO_FinancialAccount::add($params, $ids);
51
52 $result = $this->assertDBNotNull(
53 'CRM_Financial_BAO_FinancialAccount',
54 $contributionType->id,
55 'name',
56 'id',
57 'Database check on updated financial type record.'
58 );
59
60 $this->assertEquals($result, 'Donations', 'Verify financial type name.');
61 }
62
63 /**
100fef9d 64 * Check method retrive()
6a488035 65 */
00be9182 66 public function testRetrieve() {
6a488035 67 $params = array(
f17d75bb 68 'name' => 'Donations',
6a488035
TO
69 'is_deductible' => 0,
70 'is_active' => 1,
71 );
72 $ids = $defaults = array();
bf2cf926 73 CRM_Financial_BAO_FinancialAccount::add($params);
6a488035
TO
74
75 $result = CRM_Financial_BAO_FinancialAccount::retrieve($params, $defaults);
76
f17d75bb 77 $this->assertEquals($result->name, 'Donations', 'Verify financial type name.');
6a488035
TO
78 }
79
80 /**
100fef9d 81 * Check method setIsActive()
6a488035 82 */
00be9182 83 public function testSetIsActive() {
6a488035 84 $params = array(
f17d75bb 85 'name' => 'Donations',
6a488035
TO
86 'is_deductible' => 0,
87 'is_active' => 1,
88 );
89 $ids = array();
90 $contributionType = CRM_Financial_BAO_FinancialAccount::add($params, $ids);
91 $result = CRM_Financial_BAO_FinancialAccount::setIsActive($contributionType->id, 0);
92 $this->assertEquals($result, TRUE, 'Verify financial type record updation for is_active.');
93
94 $isActive = $this->assertDBNotNull(
95 'CRM_Financial_BAO_FinancialAccount',
96 $contributionType->id,
97 'is_active',
98 'id',
99 'Database check on updated for financial type is_active.'
100 );
101 $this->assertEquals($isActive, 0, 'Verify financial types is_active.');
102 }
103
104 /**
100fef9d 105 * Check method del()
6a488035 106 */
00be9182 107 public function testdel() {
6a488035 108 $params = array(
f17d75bb 109 'name' => 'Donations',
6a488035
TO
110 'is_deductible' => 0,
111 'is_active' => 1,
112 );
113 $ids = array();
114 $contributionType = CRM_Financial_BAO_FinancialAccount::add($params, $ids);
115
116 CRM_Financial_BAO_FinancialAccount::del($contributionType->id);
117 $params = array('id' => $contributionType->id);
118 $result = CRM_Financial_BAO_FinancialAccount::retrieve($params, $defaults);
119 $this->assertEquals(empty($result), TRUE, 'Verify financial types record deletion.');
120 }
121
122 /**
100fef9d 123 * Check method getAccountingCode()
6a488035 124 */
00be9182 125 public function testGetAccountingCode() {
6a488035 126 $params = array(
f17d75bb 127 'name' => 'Donations',
6a488035
TO
128 'is_active' => 1,
129 'is_reserved' => 0,
130 );
131
132 $ids = array();
6a488035 133 $financialType = CRM_Financial_BAO_FinancialType::add($params, $ids);
f17d75bb
PN
134 $financialAccountid = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', 'Donations', 'id', 'name');
135 CRM_Core_DAO::setFieldValue('CRM_Financial_DAO_FinancialAccount', $financialAccountid, 'accounting_code', '4800');
6a488035 136 $accountingCode = CRM_Financial_BAO_FinancialAccount::getAccountingCode($financialType->id);
481a74f4 137 $this->assertEquals($accountingCode, 4800, 'Verify accounting code.');
6a488035 138 }
96025800 139
bf2cf926 140 /**
141 * Test getting financial account for a given financial Type with a particular relationship.
142 */
143 public function testGetFinancialAccountByFinancialTypeAndRelationshipBuiltIn() {
144 $this->assertEquals(2, CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship(2, 'Income Account Is'));
145 }
146
147 /**
148 * Test getting financial account for a given financial Type with a particular relationship.
149 */
150 public function testGetFinancialAccountByFinancialTypeAndRelationshipBuiltInRefunded() {
151 $this->assertEquals(2, CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship(2, 'Credit/Contra Revenue Account Is'));
152 }
153
154 /**
155 * Test getting financial account for a given financial Type with a particular relationship.
156 */
157 public function testGetFinancialAccountByFinancialTypeAndRelationshipBuiltInChargeBack() {
158 $this->assertEquals(2, CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship(2, 'Chargeback Account Is'));
159 }
160
161 /**
162 * Test getting financial account for a given financial Type with a particular relationship.
163 */
164 public function testGetFinancialAccountByFinancialTypeAndRelationshipCustomAddedRefunded() {
165 $financialAccount = $this->callAPISuccess('FinancialAccount', 'create', array(
166 'name' => 'Refund Account',
167 'is_active' => TRUE,
168 ));
169
170 $this->callAPISuccess('EntityFinancialAccount', 'create', array(
171 'entity_id' => 2,
172 'entity_table' => 'civicrm_financial_type',
173 'account_relationship' => 'Credit/Contra Revenue Account is',
174 'financial_account_id' => 'Refund Account',
175 ));
176 $this->assertEquals($financialAccount['id'],
177 CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship(2, 'Credit/Contra Revenue Account is'));
178 }
179
2d5e8eeb
E
180 /**
181 * Test getting financial account relations for a given financial type.
182 */
183 public function testGetFinancialAccountRelations() {
184 $fAccounts = $rAccounts = array();
185 $relations = CRM_Financial_BAO_FinancialAccount::getfinancialAccountRelations();
186 $links = array(
187 'Expense Account is' => 'Expenses',
188 'Accounts Receivable Account is' => 'Asset',
189 'Income Account is' => 'Revenue',
190 'Asset Account is' => 'Asset',
191 'Cost of Sales Account is' => 'Cost of Sales',
192 'Premiums Inventory Account is' => 'Asset',
193 'Discounts Account is' => 'Revenue',
194 'Sales Tax Account is' => 'Liability',
195 'Deferred Revenue Account is' => 'Liability',
196 );
197 $dao = CRM_Core_DAO::executeQuery("SELECT ov.value, ov.name
198 FROM civicrm_option_value ov
199 INNER JOIN civicrm_option_group og ON og.id = ov.option_group_id
200 AND og.name = 'financial_account_type'");
201 while ($dao->fetch()) {
202 $fAccounts[$dao->value] = $dao->name;
203 }
204 $dao = CRM_Core_DAO::executeQuery("SELECT ov.value, ov.name
205 FROM civicrm_option_value ov
206 INNER JOIN civicrm_option_group og ON og.id = ov.option_group_id
207 AND og.name = 'account_relationship'");
208 while ($dao->fetch()) {
209 $rAccounts[$dao->value] = $dao->name;
210 }
211 foreach ($links as $accountRelation => $accountType) {
212 $financialAccountLinks[array_search($accountRelation, $rAccounts)] = array_search($accountType, $fAccounts);
213 }
214 $this->assertTrue(($relations == $financialAccountLinks), "The two arrays are not the same");
215 }
216
3c686e50 217 /**
c73dd828
E
218 * Test getting deferred financial type.
219 */
220 public function testGetDeferredFinancialType() {
fd633b30 221 $result = $this->_createDeferredFinancialAccount();
c73dd828
E
222 $financialTypes = CRM_Financial_BAO_FinancialAccount::getDeferredFinancialType();
223 $this->assertTrue(array_key_exists($result, $financialTypes), "The financial type created does not have a deferred account relationship");
224 }
225
567ac630
E
226 /**
227 * Test getting financial account for a given financial Type with a particular relationship.
228 */
229 public function testValidateFinancialAccount() {
230 // Create a record with financial item having financial account as Event Fee.
231 $this->createParticipantWithContribution();
232 $financialAccounts = CRM_Contribute_PseudoConstant::financialAccount();
233 $financialAccountId = array_search('Event Fee', $financialAccounts);
234 $message = CRM_Financial_BAO_FinancialAccount::validateFinancialAccount($financialAccountId);
235 $this->assertTrue($message, "The financial account cannot be deleted. Failed asserting this was true.");
236 $financialAccountId = array_search('Member Dues', $financialAccounts);
237 $message = CRM_Financial_BAO_FinancialAccount::validateFinancialAccount($financialAccountId);
238 $this->assertFalse($message, "The financial account can be deleted. Failed asserting this was true.");
239 }
240
b2ffc3e1
PN
241 /**
242 * Test for validating financial type has deferred revenue account relationship.
243 */
244 public function testcheckFinancialTypeHasDeferred() {
245 Civi::settings()->set('contribution_invoice_settings', array('deferred_revenue_enabled' => '1'));
246 $params = array();
247 $valid = CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($params);
248 $this->assertFalse($valid, "This should have been false");
249 $cid = $this->individualCreate();
250 $params = array(
251 'contact_id' => $cid,
40e78f09 252 'receive_date' => '2016-01-20',
b2ffc3e1 253 'total_amount' => 100,
40e78f09 254 'financial_type_id' => 4,
b2ffc3e1
PN
255 'revenue_recognition_date' => date('Ymd', strtotime("+1 month")),
256 'line_items' => array(
257 array(
258 'line_item' => array(
259 array(
260 'entity_table' => 'civicrm_contribution',
261 'price_field_id' => 8,
262 'price_field_value_id' => 16,
263 'label' => 'test 1',
264 'qty' => 1,
265 'unit_price' => 100,
266 'line_total' => 100,
c9a5a6e2 267 'financial_type_id' => 4,
b2ffc3e1
PN
268 ),
269 array(
270 'entity_table' => 'civicrm_contribution',
271 'price_field_id' => 8,
272 'price_field_value_id' => 17,
273 'label' => 'Test 2',
274 'qty' => 1,
275 'unit_price' => 200,
276 'line_total' => 200,
c9a5a6e2 277 'financial_type_id' => 4,
b2ffc3e1
PN
278 ),
279 ),
b2ffc3e1
PN
280 ),
281 ),
282 );
36937e7b
PN
283 try {
284 CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($params);
285 }
286 catch (CRM_Core_Exception $e) {
287 $this->fail("Missed expected exception");
288 }
c9a5a6e2
PN
289 $params = array(
290 'contact_id' => $cid,
291 'receive_date' => '2016-01-20',
292 'total_amount' => 100,
293 'financial_type_id' => 1,
294 'revenue_recognition_date' => date('Ymd', strtotime("+1 month")),
295 );
36937e7b
PN
296 try {
297 CRM_Financial_BAO_FinancialAccount::checkFinancialTypeHasDeferred($params);
298 $this->fail("Missed expected exception");
299 }
300 catch (CRM_Core_Exception $e) {
301 $this->assertEquals('Revenue recognition date can only be specified if the financial type selected has a deferred revenue account configured. Please have an administrator set up the deferred revenue account at Administer > CiviContribute > Financial Accounts, then configure it for financial types at Administer > CiviContribution > Financial Types, Accounts', $e->getMessage());
302 }
b2ffc3e1
PN
303 }
304
05881808
PN
305 /**
306 * Test if financial type has Deferred Revenue Account is relationship with Financial Account.
307 *
308 */
309 public function testValidateFinancialType() {
310 Civi::settings()->set('contribution_invoice_settings', array('deferred_revenue_enabled' => '1'));
05881808
PN
311 $financialTypes = CRM_Contribute_PseudoConstant::financialType();
312 foreach ($financialTypes as $key => $value) {
3d575ea6
PN
313 try {
314 CRM_Financial_BAO_FinancialAccount::validateFinancialType($key);
315 if (!in_array($value, array('Member Dues', 'Event Fee'))) {
316 $this->fail("Missed expected exception");
317 }
05881808 318 }
3d575ea6
PN
319 catch (CRM_Core_Exception $e) {
320 if (in_array($value, array('Member Dues', 'Event Fees'))) {
321 $this->fail("Should not call exception");
322 }
323 else {
324 $this->assertEquals('Deferred revenue account is not configured for selected financial type. Please have an administrator set up the deferred revenue account at Administer > CiviContribute > Financial Accounts, then configure it for financial types at Administer > CiviContribution > Financial Types, Accounts', $e->getMessage());
325 }
05881808
PN
326 }
327 }
328 }
329
6fab606a
PN
330 /**
331 * Test Validate if Deferred Account is set for Financial Type.
332 */
333 public function testValidateTogglingDeferredRevenue() {
334 $orgContactID = $this->organizationCreate();
335
336 //create relationship
337 $params = array(
338 'name_a_b' => 'Relation 1',
339 'name_b_a' => 'Relation 2',
340 'contact_type_a' => 'Individual',
341 'contact_type_b' => 'Organization',
342 'is_reserved' => 1,
343 'is_active' => 1,
344 );
345 $relationshipTypeId = $this->relationshipTypeCreate($params);
346 $ids = array();
347 $params = array(
348 'name' => 'test type',
349 'domain_id' => 1,
350 'description' => NULL,
351 'minimum_fee' => 10,
352 'duration_unit' => 'year',
353 'member_of_contact_id' => $orgContactID,
354 'relationship_type_id' => $relationshipTypeId,
355 'period_type' => 'fixed',
356 'duration_interval' => 1,
357 'financial_type_id' => 1,
358 'visibility' => 'Public',
359 'is_active' => 1,
360 );
361
362 $membershipType = CRM_Member_BAO_MembershipType::add($params, $ids);
363
364 $membership = $this->assertDBNotNull('CRM_Member_BAO_MembershipType', $orgContactID,
365 'name', 'member_of_contact_id',
366 'Database check on updated membership record.'
367 );
368 $error = CRM_Financial_BAO_FinancialAccount::validateTogglingDeferredRevenue();
369 $this->assertTrue(!empty($error), "Error message did not appear");
370 $this->membershipTypeDelete(array('id' => $membershipType->id));
371 }
372
fd633b30
PN
373 /**
374 * Test testGetAllDeferredFinancialAccount.
375 */
376 public function testGetAllDeferredFinancialAccount() {
377 $financialAccount = CRM_Financial_BAO_FinancialAccount::getAllDeferredFinancialAccount();
378 // The two deferred financial accounts which are created by default.
379 $expected = array(
380 "Deferred Revenue - Event Fee",
381 "Deferred Revenue - Member Dues",
382 );
383 $this->assertEquals(array_count_values($expected), array_count_values($financialAccount), "The two arrays are not the same");
384 $this->_createDeferredFinancialAccount();
385 $financialAccount = CRM_Financial_BAO_FinancialAccount::getAllDeferredFinancialAccount();
386 $expected[] = "TestFinancialAccount_1";
387 $this->assertEquals(array_count_values($expected), array_count_values($financialAccount), "The two arrays are not the same");
388 }
389
390 /**
391 * Helper function to create deferred financial account.
392 */
393 public function _createDeferredFinancialAccount() {
394 $params = array(
395 'name' => 'TestFinancialAccount_1',
396 'accounting_code' => 4800,
397 'contact_id' => 1,
398 'is_deductible' => 0,
399 'is_active' => 1,
400 'is_reserved' => 0,
401 );
402
403 $financialAccount = $this->callAPISuccess('FinancialAccount', 'create', $params);
404 $params['name'] = 'test_financialType1';
405 $financialType = $this->callAPISuccess('FinancialType', 'create', $params);
406 $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Deferred Revenue Account is' "));
407 $financialParams = array(
408 'entity_table' => 'civicrm_financial_type',
409 'entity_id' => $financialType['id'],
410 'account_relationship' => $relationTypeId,
411 'financial_account_id' => $financialAccount['id'],
412 );
413
414 $this->callAPISuccess('EntityFinancialAccount', 'create', $financialParams);
415 $result = $this->assertDBNotNull(
416 'CRM_Financial_DAO_EntityFinancialAccount',
417 $financialAccount['id'],
418 'entity_id',
419 'financial_account_id',
420 'Database check on added financial type record.'
421 );
422 $this->assertEquals($result, $financialType['id'], 'Verify Account Type');
423 return $result;
424 }
425
6a488035 426}