3 +--------------------------------------------------------------------+
4 | Copyright CiviCRM LLC. All rights reserved. |
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 |
9 +--------------------------------------------------------------------+
15 * @copyright CiviCRM LLC https://civicrm.org/licensing
17 class CRM_Financial_BAO_FinancialTypeAccount
extends CRM_Financial_DAO_EntityFinancialAccount
{
20 * Fetch object based on array of properties.
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.
27 * @param array $allValues
29 * @return CRM_Contribute_BAO_ContributionType
31 public static function retrieve(&$params, &$defaults = [], &$allValues = []) {
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;
43 * Add the financial types.
45 * @param array $params
46 * Reference array contains the values submitted by the form.
48 * Reference array contains one possible value
49 * - entityFinancialAccount.
51 * @return CRM_Financial_DAO_EntityFinancialAccount
53 * @throws \CRM_Core_Exception
55 public static function add(&$params, $ids = NULL) {
56 // action is taken depending upon the mode
57 $financialTypeAccount = new CRM_Financial_DAO_EntityFinancialAccount();
58 if ($params['entity_table'] !== 'civicrm_financial_type') {
59 $financialTypeAccount->entity_id
= $params['entity_id'];
60 $financialTypeAccount->entity_table
= $params['entity_table'];
61 $financialTypeAccount->find(TRUE);
63 if (!empty($ids['entityFinancialAccount'])) {
64 $financialTypeAccount->id
= $ids['entityFinancialAccount'];
65 $financialTypeAccount->find(TRUE);
67 $financialTypeAccount->copyValues($params);
68 self
::validateRelationship($financialTypeAccount);
69 $financialTypeAccount->save();
70 unset(Civi
::$statics['CRM_Core_PseudoConstant']['taxRates']);
71 return $financialTypeAccount;
75 * Delete financial Types.
77 * @param int $financialTypeAccountId
78 * @param int $accountId
80 * @throws \CRM_Core_Exception
82 public static function del($financialTypeAccountId, $accountId = NULL) {
83 // check if financial type is present
85 $relationValues = CRM_Core_PseudoConstant
::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship');
87 $financialTypeId = CRM_Core_DAO
::getFieldValue('CRM_Financial_DAO_EntityFinancialAccount', $financialTypeAccountId, 'entity_id');
89 // FIXME hardcoded list = bad
91 ['Contribute', 'Contribution'],
92 ['Contribute', 'ContributionPage'],
93 ['Member', 'MembershipType'],
94 ['Price', 'PriceFieldValue'],
96 ['Contribute', 'PremiumsProduct'],
97 ['Contribute', 'Product'],
98 ['Price', 'LineItem'],
101 foreach ($dependency as $name) {
102 $daoString = 'CRM_' . $name[0] . '_DAO_' . $name[1];
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)) {
115 if ($name[1] === 'PremiumsProduct' ||
$name[1] === 'Product') {
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]]));
119 $accountRelationShipId = CRM_Core_DAO
::getFieldValue('CRM_Financial_DAO_EntityFinancialAccount', $financialTypeAccountId, 'account_relationship');
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');
122 return CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/admin/financial/financialType/accounts', "reset=1&action=browse&aid={$accountId}"));
125 // delete from financial Type table
126 $financialType = new CRM_Financial_DAO_EntityFinancialAccount();
127 $financialType->id
= $financialTypeAccountId;
128 $financialType->find(TRUE);
129 $financialType->delete();
130 CRM_Core_Session
::setStatus(ts('Unbalanced transactions may be created if you delete the account of type: %1.', [1 => $relationValues[$financialType->account_relationship
]]));
134 * Financial Account for payment instrument.
136 * @param int $paymentInstrumentValue
137 * Payment instrument value.
140 * @throws \CiviCRM_API3_Exception
142 public static function getInstrumentFinancialAccount($paymentInstrumentValue) {
143 if (!isset(\Civi
::$statics[__CLASS__
]['instrument_financial_accounts'][$paymentInstrumentValue])) {
144 $paymentInstrumentID = civicrm_api3('OptionValue', 'getvalue', [
146 'value' => $paymentInstrumentValue,
147 'option_group_id' => "payment_instrument",
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],
156 if (empty($accounts)) {
157 \Civi
::$statics[__CLASS__
]['instrument_financial_accounts'][$paymentInstrumentValue] = NULL;
160 \Civi
::$statics[__CLASS__
]['instrument_financial_accounts'][$paymentInstrumentValue] = $accounts[0]['financial_account_id'];
163 return \Civi
::$statics[__CLASS__
]['instrument_financial_accounts'][$paymentInstrumentValue];
167 * Create default entity financial accounts
169 * @see https://issues.civicrm.org/jira/browse/CRM-12470
171 * @param $financialType
175 public static function createDefaultFinancialAccounts($financialType) {
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');
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),
187 $dao = CRM_Core_DAO
::executeQuery('SELECT id, financial_account_type_id FROM civicrm_financial_account WHERE name LIKE %1',
188 [1 => [$financialType->name
, 'String']]
191 $existingFinancialAccount = [];
194 'name' => $financialType->name
,
195 'contact_id' => CRM_Core_BAO_Domain
::getDomain()->contact_id
,
196 'financial_account_type_id' => array_search('Revenue', $financialAccountTypeID),
197 'description' => $financialType->description
,
198 'account_type_code' => 'INC',
201 $financialAccount = CRM_Financial_BAO_FinancialAccount
::add($params);
204 $existingFinancialAccount[$dao->financial_account_type_id
] = $dao->id
;
207 'entity_table' => 'civicrm_financial_type',
208 'entity_id' => $financialType->id
,
210 foreach ($relationships as $key => $value) {
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';
218 $query = "SELECT financial_account_id, name FROM civicrm_entity_financial_account
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";
221 $dao = CRM_Core_DAO
::executeQuery($query);
223 $params['financial_account_id'] = $dao->financial_account_id
;
224 $titles[] = $dao->name
;
227 elseif ($accountRelationship[$key] == 'Income Account is' && empty($existingFinancialAccount)) {
228 $params['financial_account_id'] = $financialAccount->id
;
231 $query = "SELECT id, name FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = {$value}";
232 $dao = CRM_Core_DAO
::executeQuery($query);
234 $params['financial_account_id'] = $dao->id
;
235 $titles[] = $dao->name
;
239 $params['financial_account_id'] = $existingFinancialAccount[$value];
240 $titles[] = $financialType->name
;
242 $params['account_relationship'] = $key;
245 if (!empty($existingFinancialAccount)) {
252 * Validate account relationship with financial account type
254 * @param CRM_Financial_DAO_EntityFinancialAccount $financialTypeAccount of CRM_Financial_DAO_EntityFinancialAccount
256 * @throws CRM_Core_Exception
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');
264 1 => $accountRelationships[$financialTypeAccount->account_relationship
],
266 throw new CRM_Core_Exception(ts("This financial account cannot have '%1' relationship.", $params));