Skip to content

Commit

Permalink
Alias CRM_Financial_BAO_FinancialTypeAccount -> CRM_Financial_BAO_Ent…
Browse files Browse the repository at this point in the history
…ityFinancialAccount

This BAO class did not follow the standard naming convention which effectively made it invisible to the API.
Why was named this way in the first place was never explained, I suspect it was simply a mistake.

A BAO class actually did get added before this PR, in 37c608f which further added to the confusion.
This consolidates the two classes.

Because it was an "invisible" BAO class, the create and del functions were never used by the API.
For consistency, I've therefore tagged them as @deprecated which keeps them hidden from the API.
We can add business logic back in as needed using hook listeners.
  • Loading branch information
colemanw committed Nov 23, 2022
1 parent 488582e commit eee94c9
Show file tree
Hide file tree
Showing 19 changed files with 289 additions and 302 deletions.
6 changes: 3 additions & 3 deletions CRM/Contribute/BAO/Contribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ public static function getToFinancialAccount($contribution, $params) {
return CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($params['payment_processor_id'], NULL, 'civicrm_payment_processor');
}
if (!empty($params['payment_instrument_id'])) {
return CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($contribution['payment_instrument_id']);
return CRM_Financial_BAO_EntityFinancialAccount::getInstrumentFinancialAccount($contribution['payment_instrument_id']);
}
else {
$relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' "));
Expand Down Expand Up @@ -3104,11 +3104,11 @@ public static function recordFinancialAccounts(&$params, CRM_Contribute_DAO_Cont
]);
}
elseif (!empty($params['payment_instrument_id'])) {
$params['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($params['payment_instrument_id']);
$params['to_financial_account_id'] = CRM_Financial_BAO_EntityFinancialAccount::getInstrumentFinancialAccount($params['payment_instrument_id']);
}
// dev/financial#160 - If this is a contribution update, also check for an existing payment_instrument_id.
elseif ($isUpdate && $params['prevContribution']->payment_instrument_id) {
$params['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount((int) $params['prevContribution']->payment_instrument_id);
$params['to_financial_account_id'] = CRM_Financial_BAO_EntityFinancialAccount::getInstrumentFinancialAccount((int) $params['prevContribution']->payment_instrument_id);
}
else {
$relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' "));
Expand Down
2 changes: 1 addition & 1 deletion CRM/Core/BAO/OptionValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ public static function add(&$params, $ids = []) {
'account_relationship' => $relationTypeId,
'financial_account_id' => $params['financial_account_id'],
];
CRM_Financial_BAO_FinancialTypeAccount::add($params);
CRM_Financial_BAO_EntityFinancialAccount::add($params);
}
}
return $optionValue;
Expand Down
2 changes: 1 addition & 1 deletion CRM/Core/CodeGen/GenerateData.php
Original file line number Diff line number Diff line change
Expand Up @@ -2181,7 +2181,7 @@ private function addAccountingEntries() {
$select = 'SELECT contribution.id contribution_id, cli.id as line_item_id, contribution.contact_id, contribution.receive_date, contribution.total_amount, contribution.currency, cli.label,
cli.financial_type_id, cefa.financial_account_id, contribution.payment_instrument_id, contribution.check_number, contribution.trxn_id';
$where = 'WHERE cefa.account_relationship = 1';
$financialAccountId = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount(4);
$financialAccountId = CRM_Financial_BAO_EntityFinancialAccount::getInstrumentFinancialAccount(4);
foreach ($components as $component) {
if ($component == 'contribution') {
$from = 'FROM `civicrm_contribution` contribution';
Expand Down
251 changes: 251 additions & 0 deletions CRM/Financial/BAO/EntityFinancialAccount.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,257 @@
*/
class CRM_Financial_BAO_EntityFinancialAccount extends CRM_Financial_DAO_EntityFinancialAccount {

/**
* Fetch object based on array of properties.
*
* @param array $params
* (reference ) an assoc array of name/value pairs.
* @param array $defaults
* (reference ) an assoc array to hold the flattened values.
*
* @param array $allValues
* @deprecated
* @return array
*/
public static function retrieve(&$params, &$defaults = [], &$allValues = []) {
$financialTypeAccount = new CRM_Financial_DAO_EntityFinancialAccount();
$financialTypeAccount->copyValues($params);
$financialTypeAccount->find();
while ($financialTypeAccount->fetch()) {
CRM_Core_DAO::storeValues($financialTypeAccount, $defaults);
$allValues[] = $defaults;
}
return $defaults;
}

/**
* Add the financial types.
*
* @param array $params
* Reference array contains the values submitted by the form.
* @param array $ids
* Reference array contains one possible value
* - entityFinancialAccount.
*
* @return CRM_Financial_DAO_EntityFinancialAccount
* @deprecated
* @throws \CRM_Core_Exception
*/
public static function add(&$params, $ids = NULL) {
// action is taken depending upon the mode
$financialTypeAccount = new CRM_Financial_DAO_EntityFinancialAccount();
if ($params['entity_table'] !== 'civicrm_financial_type') {
$financialTypeAccount->entity_id = $params['entity_id'];
$financialTypeAccount->entity_table = $params['entity_table'];
$financialTypeAccount->find(TRUE);
}
if (!empty($ids['entityFinancialAccount'])) {
$financialTypeAccount->id = $ids['entityFinancialAccount'];
$financialTypeAccount->find(TRUE);
}
$financialTypeAccount->copyValues($params);
self::validateRelationship($financialTypeAccount);
$financialTypeAccount->save();
unset(Civi::$statics['CRM_Core_PseudoConstant']['taxRates']);
return $financialTypeAccount;
}

/**
* Delete financial Types.
*
* @param int $financialTypeAccountId
* @param int $accountId
* @deprecated
* @throws \CRM_Core_Exception
*/
public static function del($financialTypeAccountId, $accountId = NULL) {
// check if financial type is present
$check = FALSE;
$relationValues = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship');

$financialTypeId = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_EntityFinancialAccount', $financialTypeAccountId, 'entity_id');
// check dependencies
// FIXME hardcoded list = bad
$dependency = [
['Contribute', 'Contribution'],
['Contribute', 'ContributionPage'],
['Member', 'MembershipType'],
['Price', 'PriceFieldValue'],
['Grant', 'Grant'],
['Contribute', 'PremiumsProduct'],
['Contribute', 'Product'],
['Price', 'LineItem'],
];

foreach ($dependency as $name) {
$daoString = 'CRM_' . $name[0] . '_DAO_' . $name[1];
if (class_exists($daoString)) {
/** @var \CRM_Core_DAO $dao */
$dao = new $daoString();
$dao->financial_type_id = $financialTypeId;
if ($dao->find(TRUE)) {
$check = TRUE;
break;
}
}
}

if ($check) {
if ($name[1] === 'PremiumsProduct' || $name[1] === 'Product') {
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]]));
}
else {
$accountRelationShipId = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_EntityFinancialAccount', $financialTypeAccountId, 'account_relationship');
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');
}
CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/admin/financial/financialType/accounts', "reset=1&action=browse&aid={$accountId}"));
}

// delete from financial Type table
$financialType = new CRM_Financial_DAO_EntityFinancialAccount();
$financialType->id = $financialTypeAccountId;
$financialType->find(TRUE);
$financialType->delete();
CRM_Core_Session::setStatus(ts('Unbalanced transactions may be created if you delete the account of type: %1.', [1 => $relationValues[$financialType->account_relationship]]));
}

/**
* Financial Account for payment instrument.
*
* @param int $paymentInstrumentValue
* Payment instrument value.
*
* @return null|int
* @throws \CRM_Core_Exception
*/
public static function getInstrumentFinancialAccount($paymentInstrumentValue) {
if (!isset(\Civi::$statics[__CLASS__]['instrument_financial_accounts'][$paymentInstrumentValue])) {
$paymentInstrumentID = civicrm_api3('OptionValue', 'getvalue', [
'return' => 'id',
'value' => $paymentInstrumentValue,
'option_group_id' => "payment_instrument",
]);
$accounts = civicrm_api3('EntityFinancialAccount', 'get', [
'return' => 'financial_account_id',
'entity_table' => 'civicrm_option_value',
'entity_id' => $paymentInstrumentID,
'options' => ['limit' => 1],
'sequential' => 1,
])['values'];
if (empty($accounts)) {
\Civi::$statics[__CLASS__]['instrument_financial_accounts'][$paymentInstrumentValue] = NULL;
}
else {
\Civi::$statics[__CLASS__]['instrument_financial_accounts'][$paymentInstrumentValue] = $accounts[0]['financial_account_id'];
}
}
return \Civi::$statics[__CLASS__]['instrument_financial_accounts'][$paymentInstrumentValue];
}

/**
* Create default entity financial accounts
* for financial type
* @see https://issues.civicrm.org/jira/browse/CRM-12470
*
* @param $financialType
*
* @return array
*/
public static function createDefaultFinancialAccounts($financialType) {
$titles = [];
$financialAccountTypeID = CRM_Core_OptionGroup::values('financial_account_type', FALSE, FALSE, FALSE, NULL, 'name');
$accountRelationship = CRM_Core_OptionGroup::values('account_relationship', FALSE, FALSE, FALSE, NULL, 'name');

$relationships = [
array_search('Accounts Receivable Account is', $accountRelationship) => array_search('Asset', $financialAccountTypeID),
array_search('Expense Account is', $accountRelationship) => array_search('Expenses', $financialAccountTypeID),
array_search('Cost of Sales Account is', $accountRelationship) => array_search('Cost of Sales', $financialAccountTypeID),
array_search('Income Account is', $accountRelationship) => array_search('Revenue', $financialAccountTypeID),
];

$dao = CRM_Core_DAO::executeQuery('SELECT id, financial_account_type_id FROM civicrm_financial_account WHERE name LIKE %1',
[1 => [$financialType->name, 'String']]
);
$dao->fetch();
$existingFinancialAccount = [];
if (!$dao->N) {
$params = [
'name' => $financialType->name,
'contact_id' => CRM_Core_BAO_Domain::getDomain()->contact_id,
'financial_account_type_id' => array_search('Revenue', $financialAccountTypeID),
'description' => $financialType->description,
'account_type_code' => 'INC',
'is_active' => 1,
];
$financialAccount = CRM_Financial_BAO_FinancialAccount::add($params);
}
else {
$existingFinancialAccount[$dao->financial_account_type_id] = $dao->id;
}
$params = [
'entity_table' => 'civicrm_financial_type',
'entity_id' => $financialType->id,
];
foreach ($relationships as $key => $value) {
if (!array_key_exists($value, $existingFinancialAccount)) {
if ($accountRelationship[$key] == 'Accounts Receivable Account is') {
$params['financial_account_id'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', 'Accounts Receivable', 'id', 'name');
if (!empty($params['financial_account_id'])) {
$titles[] = 'Accounts Receivable';
}
else {
$query = "SELECT financial_account_id, name FROM civicrm_entity_financial_account
LEFT JOIN civicrm_financial_account ON civicrm_financial_account.id = civicrm_entity_financial_account.financial_account_id
WHERE account_relationship = {$key} AND entity_table = 'civicrm_financial_type' LIMIT 1";
$dao = CRM_Core_DAO::executeQuery($query);
$dao->fetch();
$params['financial_account_id'] = $dao->financial_account_id;
$titles[] = $dao->name;
}
}
elseif ($accountRelationship[$key] == 'Income Account is' && empty($existingFinancialAccount)) {
$params['financial_account_id'] = $financialAccount->id;
}
else {
$query = "SELECT id, name FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = {$value}";
$dao = CRM_Core_DAO::executeQuery($query);
$dao->fetch();
$params['financial_account_id'] = $dao->id;
$titles[] = $dao->name;
}
}
else {
$params['financial_account_id'] = $existingFinancialAccount[$value];
$titles[] = $financialType->name;
}
$params['account_relationship'] = $key;
self::add($params);
}
if (!empty($existingFinancialAccount)) {
$titles = [];
}
return $titles;
}

/**
* Validate account relationship with financial account type
*
* @param CRM_Financial_DAO_EntityFinancialAccount $financialTypeAccount of CRM_Financial_DAO_EntityFinancialAccount
*
* @throws CRM_Core_Exception
*/
public static function validateRelationship($financialTypeAccount) {
$financialAccountLinks = CRM_Financial_BAO_FinancialAccount::getfinancialAccountRelations();
$financialAccountType = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialAccount', $financialTypeAccount->financial_account_id, 'financial_account_type_id');
if (CRM_Utils_Array::value($financialTypeAccount->account_relationship, $financialAccountLinks) != $financialAccountType) {
$accountRelationships = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_EntityFinancialAccount', 'account_relationship');
$params = [
1 => $accountRelationships[$financialTypeAccount->account_relationship],
];
throw new CRM_Core_Exception(ts("This financial account cannot have '%1' relationship.", $params));
}
}

/**
* Whitelist of possible values for the entity_table field
*
Expand Down
2 changes: 1 addition & 1 deletion CRM/Financial/BAO/FinancialType.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public static function self_hook_civicrm_pre(\Civi\Core\Event\PreEvent $event) {
*/
public static function self_hook_civicrm_post(\Civi\Core\Event\PostEvent $event) {
if ($event->action === 'create') {
$titles = CRM_Financial_BAO_FinancialTypeAccount::createDefaultFinancialAccounts($event->object);
$titles = CRM_Financial_BAO_EntityFinancialAccount::createDefaultFinancialAccounts($event->object);
$event->object->titles = $titles;
}
if ($event->action === 'delete') {
Expand Down
Loading

0 comments on commit eee94c9

Please sign in to comment.