Merge pull request #21865 from colemanw/SearchKitTags
[civicrm-core.git] / CRM / Financial / BAO / FinancialTypeAccount.php
CommitLineData
6a488035 1<?php
6a488035
TO
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035 9 +--------------------------------------------------------------------+
d25dd0ee 10 */
6a488035
TO
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035 16 */
6a488035
TO
17class CRM_Financial_BAO_FinancialTypeAccount extends CRM_Financial_DAO_EntityFinancialAccount {
18
6a488035 19 /**
fe482240 20 * Fetch object based on array of properties.
6a488035 21 *
ed5dd492
TO
22 * @param array $params
23 * (reference ) an assoc array of name/value pairs.
24 * @param array $defaults
25 * (reference ) an assoc array to hold the flattened values.
6a488035 26 *
6c8f6e67
EM
27 * @param array $allValues
28 *
16b10e64 29 * @return CRM_Contribute_BAO_ContributionType
6a488035 30 */
db62d3a5 31 public static function retrieve(&$params, &$defaults = [], &$allValues = []) {
ecc1e0ef
PN
32 $financialTypeAccount = new CRM_Financial_DAO_EntityFinancialAccount();
33 $financialTypeAccount->copyValues($params);
34 $financialTypeAccount->find();
35 while ($financialTypeAccount->fetch()) {
36 CRM_Core_DAO::storeValues($financialTypeAccount, $defaults);
37 $allValues[] = $defaults;
6a488035 38 }
ecc1e0ef 39 return $defaults;
6a488035 40 }
03e04002 41
6a488035 42 /**
fe482240 43 * Add the financial types.
6a488035 44 *
ed5dd492
TO
45 * @param array $params
46 * Reference array contains the values submitted by the form.
47 * @param array $ids
0b17a870 48 * Reference array contains one possible value
49 * - entityFinancialAccount.
03e04002 50 *
0b17a870 51 * @return CRM_Financial_DAO_EntityFinancialAccount
52 *
53 * @throws \CRM_Core_Exception
6a488035 54 */
0b17a870 55 public static function add(&$params, $ids = NULL) {
6a488035
TO
56 // action is taken depending upon the mode
57 $financialTypeAccount = new CRM_Financial_DAO_EntityFinancialAccount();
0b17a870 58 if ($params['entity_table'] !== 'civicrm_financial_type') {
6a488035
TO
59 $financialTypeAccount->entity_id = $params['entity_id'];
60 $financialTypeAccount->entity_table = $params['entity_table'];
61 $financialTypeAccount->find(TRUE);
62 }
a7488080 63 if (!empty($ids['entityFinancialAccount'])) {
6a488035 64 $financialTypeAccount->id = $ids['entityFinancialAccount'];
b70cd45c 65 $financialTypeAccount->find(TRUE);
6a488035
TO
66 }
67 $financialTypeAccount->copyValues($params);
b70cd45c 68 self::validateRelationship($financialTypeAccount);
6a488035 69 $financialTypeAccount->save();
0b17a870 70 unset(Civi::$statics['CRM_Core_PseudoConstant']['taxRates']);
6a488035
TO
71 return $financialTypeAccount;
72 }
03e04002 73
6a488035 74 /**
fe482240 75 * Delete financial Types.
03e04002 76 *
c490a46a
CW
77 * @param int $financialTypeAccountId
78 * @param int $accountId
fd31fa4c 79 *
0b17a870 80 * @throws \CRM_Core_Exception
6a488035 81 */
045f52a3 82 public static function del($financialTypeAccountId, $accountId = NULL) {
cded2ebf 83 // check if financial type is present
045f52a3 84 $check = FALSE;
7611ae71 85 $relationValues = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship');
03e04002 86
481a74f4 87 $financialTypeId = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_EntityFinancialAccount', $financialTypeAccountId, 'entity_id');
cded2ebf 88 // check dependencies
3c609ef0 89 // FIXME hardcoded list = bad
be2fb01f
CW
90 $dependency = [
91 ['Contribute', 'Contribution'],
92 ['Contribute', 'ContributionPage'],
93 ['Member', 'MembershipType'],
94 ['Price', 'PriceFieldValue'],
95 ['Grant', 'Grant'],
96 ['Contribute', 'PremiumsProduct'],
97 ['Contribute', 'Product'],
98 ['Price', 'LineItem'],
99 ];
6a488035 100
b44e3f84 101 foreach ($dependency as $name) {
4d5c2eb5 102 $daoString = 'CRM_' . $name[0] . '_DAO_' . $name[1];
3c609ef0
CW
103 if (class_exists($daoString)) {
104 /* @var \CRM_Core_DAO $dao */
105 $dao = new $daoString();
106 $dao->financial_type_id = $financialTypeId;
107 if ($dao->find(TRUE)) {
108 $check = TRUE;
109 break;
110 }
6a488035
TO
111 }
112 }
2efcf0c2 113
6a488035 114 if ($check) {
0b17a870 115 if ($name[1] === 'PremiumsProduct' || $name[1] === 'Product') {
be2fb01f 116 CRM_Core_Session::setStatus(ts('You cannot remove an account with a %1 relationship while the Financial Type is used for a Premium.', [1 => $relationValues[$financialTypeAccountId]]));
6a488035
TO
117 }
118 else {
b2e6c21f 119 $accountRelationShipId = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_EntityFinancialAccount', $financialTypeAccountId, 'account_relationship');
be2fb01f 120 CRM_Core_Session::setStatus(ts('You cannot remove an account with a %1 relationship because it is being referenced by one or more of the following types of records: Contributions, Contribution Pages, or Membership Types. Consider disabling this type instead if you no longer want it used.', [1 => $relationValues[$accountRelationShipId]]), NULL, 'error');
6a488035 121 }
481a74f4 122 return CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/financial/financialType/accounts', "reset=1&action=browse&aid={$accountId}"));
6a488035 123 }
03e04002 124
cded2ebf 125 // delete from financial Type table
481a74f4 126 $financialType = new CRM_Financial_DAO_EntityFinancialAccount();
6a488035 127 $financialType->id = $financialTypeAccountId;
3b67ab13 128 $financialType->find(TRUE);
6a488035 129 $financialType->delete();
be2fb01f 130 CRM_Core_Session::setStatus(ts('Unbalanced transactions may be created if you delete the account of type: %1.', [1 => $relationValues[$financialType->account_relationship]]));
6a488035 131 }
03e04002 132
6a488035 133 /**
fe482240 134 * Financial Account for payment instrument.
03e04002 135 *
ed5dd492
TO
136 * @param int $paymentInstrumentValue
137 * Payment instrument value.
03e04002 138 *
d8fbd797 139 * @return null|int
0b17a870 140 * @throws \CiviCRM_API3_Exception
6a488035 141 */
d8fbd797 142 public static function getInstrumentFinancialAccount($paymentInstrumentValue) {
fe74d2b5 143 if (!isset(\Civi::$statics[__CLASS__]['instrument_financial_accounts'][$paymentInstrumentValue])) {
be2fb01f 144 $paymentInstrumentID = civicrm_api3('OptionValue', 'getvalue', [
fe74d2b5 145 'return' => 'id',
146 'value' => $paymentInstrumentValue,
147 'option_group_id' => "payment_instrument",
be2fb01f 148 ]);
fe74d2b5 149 $accounts = civicrm_api3('EntityFinancialAccount', 'get', [
150 'return' => 'financial_account_id',
151 'entity_table' => 'civicrm_option_value',
152 'entity_id' => $paymentInstrumentID,
153 'options' => ['limit' => 1],
154 'sequential' => 1,
155 ])['values'];
156 if (empty($accounts)) {
157 \Civi::$statics[__CLASS__]['instrument_financial_accounts'][$paymentInstrumentValue] = NULL;
158 }
159 else {
160 \Civi::$statics[__CLASS__]['instrument_financial_accounts'][$paymentInstrumentValue] = $accounts[0]['financial_account_id'];
161 }
162 }
163 return \Civi::$statics[__CLASS__]['instrument_financial_accounts'][$paymentInstrumentValue];
6a488035 164 }
ddaa8ef1
PN
165
166 /**
100fef9d 167 * Create default entity financial accounts
ddaa8ef1 168 * for financial type
0e480632 169 * @see https://issues.civicrm.org/jira/browse/CRM-12470
ddaa8ef1 170 *
77b97be7
EM
171 * @param $financialType
172 *
173 * @return array
ddaa8ef1 174 */
00be9182 175 public static function createDefaultFinancialAccounts($financialType) {
be2fb01f 176 $titles = [];
01615c46
DG
177 $financialAccountTypeID = CRM_Core_OptionGroup::values('financial_account_type', FALSE, FALSE, FALSE, NULL, 'name');
178 $accountRelationship = CRM_Core_OptionGroup::values('account_relationship', FALSE, FALSE, FALSE, NULL, 'name');
056e736c 179
be2fb01f 180 $relationships = [
ddaa8ef1
PN
181 array_search('Accounts Receivable Account is', $accountRelationship) => array_search('Asset', $financialAccountTypeID),
182 array_search('Expense Account is', $accountRelationship) => array_search('Expenses', $financialAccountTypeID),
183 array_search('Cost of Sales Account is', $accountRelationship) => array_search('Cost of Sales', $financialAccountTypeID),
184 array_search('Income Account is', $accountRelationship) => array_search('Revenue', $financialAccountTypeID),
be2fb01f 185 ];
d75f2f47 186
045f52a3 187 $dao = CRM_Core_DAO::executeQuery('SELECT id, financial_account_type_id FROM civicrm_financial_account WHERE name LIKE %1',
be2fb01f 188 [1 => [$financialType->name, 'String']]
ddaa8ef1 189 );
77292b55 190 $dao->fetch();
be2fb01f 191 $existingFinancialAccount = [];
77292b55 192 if (!$dao->N) {
be2fb01f 193 $params = [
77292b55 194 'name' => $financialType->name,
d357f225 195 'contact_id' => CRM_Core_BAO_Domain::getDomain()->contact_id,
77292b55
PN
196 'financial_account_type_id' => array_search('Revenue', $financialAccountTypeID),
197 'description' => $financialType->description,
198 'account_type_code' => 'INC',
199 'is_active' => 1,
be2fb01f 200 ];
b70cd45c 201 $financialAccount = CRM_Financial_BAO_FinancialAccount::add($params);
77292b55
PN
202 }
203 else {
204 $existingFinancialAccount[$dao->financial_account_type_id] = $dao->id;
205 }
be2fb01f 206 $params = [
ddaa8ef1
PN
207 'entity_table' => 'civicrm_financial_type',
208 'entity_id' => $financialType->id,
be2fb01f 209 ];
ddaa8ef1 210 foreach ($relationships as $key => $value) {
77292b55
PN
211 if (!array_key_exists($value, $existingFinancialAccount)) {
212 if ($accountRelationship[$key] == 'Accounts Receivable Account is') {
213 $params['financial_account_id'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', 'Accounts Receivable', 'id', 'name');
214 if (!empty($params['financial_account_id'])) {
215 $titles[] = 'Accounts Receivable';
216 }
217 else {
218 $query = "SELECT financial_account_id, name FROM civicrm_entity_financial_account
ddaa8ef1
PN
219 LEFT JOIN civicrm_financial_account ON civicrm_financial_account.id = civicrm_entity_financial_account.financial_account_id
220 WHERE account_relationship = {$key} AND entity_table = 'civicrm_financial_type' LIMIT 1";
77292b55
PN
221 $dao = CRM_Core_DAO::executeQuery($query);
222 $dao->fetch();
223 $params['financial_account_id'] = $dao->financial_account_id;
224 $titles[] = $dao->name;
225 }
226 }
227 elseif ($accountRelationship[$key] == 'Income Account is' && empty($existingFinancialAccount)) {
228 $params['financial_account_id'] = $financialAccount->id;
229 }
230 else {
231 $query = "SELECT id, name FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = {$value}";
ddaa8ef1
PN
232 $dao = CRM_Core_DAO::executeQuery($query);
233 $dao->fetch();
77292b55 234 $params['financial_account_id'] = $dao->id;
ddaa8ef1
PN
235 $titles[] = $dao->name;
236 }
237 }
ddaa8ef1 238 else {
045f52a3
TO
239 $params['financial_account_id'] = $existingFinancialAccount[$value];
240 $titles[] = $financialType->name;
ddaa8ef1
PN
241 }
242 $params['account_relationship'] = $key;
8ef12e64 243 self::add($params);
ddaa8ef1 244 }
77292b55 245 if (!empty($existingFinancialAccount)) {
be2fb01f 246 $titles = [];
77292b55 247 }
ddaa8ef1
PN
248 return $titles;
249 }
96025800 250
ccaca683
PN
251 /**
252 * Validate account relationship with financial account type
253 *
0b17a870 254 * @param CRM_Financial_DAO_EntityFinancialAccount $financialTypeAccount of CRM_Financial_DAO_EntityFinancialAccount
ccaca683 255 *
6bef1cdd 256 * @throws CRM_Core_Exception
ccaca683
PN
257 */
258 public static function validateRelationship($financialTypeAccount) {
259 $financialAccountLinks = CRM_Financial_BAO_FinancialAccount::getfinancialAccountRelations();
260 $financialAccountType = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', $financialTypeAccount->financial_account_id, 'financial_account_type_id');
261 if (CRM_Utils_Array::value($financialTypeAccount->account_relationship, $financialAccountLinks) != $financialAccountType) {
262 $accountRelationships = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship');
be2fb01f 263 $params = [
ccaca683 264 1 => $accountRelationships[$financialTypeAccount->account_relationship],
be2fb01f 265 ];
a48a4a2b 266 throw new CRM_Core_Exception(ts("This financial account cannot have '%1' relationship.", $params));
ccaca683
PN
267 }
268 }
269
6a488035 270}