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