Commit | Line | Data |
---|---|---|
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 |
17 | class CRM_Financial_BAO_FinancialItem extends CRM_Financial_DAO_FinancialItem { |
18 | ||
6a488035 | 19 | /** |
4f940304 | 20 | * Retrieve DB object and copy to defaults array. |
6a488035 | 21 | * |
ed5dd492 | 22 | * @param array $params |
4f940304 | 23 | * Array of criteria values. |
ed5dd492 | 24 | * @param array $defaults |
4f940304 | 25 | * Array to be populated with found values. |
6a488035 | 26 | * |
4f940304 CW |
27 | * @return self|null |
28 | * The DAO object, if found. | |
29 | * | |
30 | * @deprecated | |
6a488035 | 31 | */ |
4f940304 CW |
32 | public static function retrieve($params, &$defaults) { |
33 | return self::commonRetrieve(self::class, $params, $defaults); | |
6a488035 TO |
34 | } |
35 | ||
36 | /** | |
fe482240 | 37 | * Add the financial items and financial trxn. |
6a488035 | 38 | * |
ed5dd492 TO |
39 | * @param object $lineItem |
40 | * Line item object. | |
41 | * @param object $contribution | |
42 | * Contribution object. | |
43 | * @param bool $taxTrxnID | |
03e04002 | 44 | * |
54957108 | 45 | * @param int $trxnId |
46 | * | |
47 | * @return CRM_Financial_DAO_FinancialItem | |
6a488035 | 48 | */ |
a191ff3d | 49 | public static function add($lineItem, $contribution, $taxTrxnID = FALSE, $trxnId = NULL) { |
6a488035 | 50 | $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); |
7611ae71 | 51 | $financialItemStatus = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id'); |
b81ee58c | 52 | $itemStatus = NULL; |
0bdf3091 | 53 | if ($contribution->contribution_status_id == array_search('Completed', $contributionStatuses) |
353ffa53 TO |
54 | || $contribution->contribution_status_id == array_search('Pending refund', $contributionStatuses) |
55 | ) { | |
6a488035 | 56 | $itemStatus = array_search('Paid', $financialItemStatus); |
03e04002 | 57 | } |
f6bae84f | 58 | elseif ($contribution->contribution_status_id == array_search('Pending', $contributionStatuses) |
353ffa53 TO |
59 | || $contribution->contribution_status_id == array_search('In Progress', $contributionStatuses) |
60 | ) { | |
6a488035 | 61 | $itemStatus = array_search('Unpaid', $financialItemStatus); |
03e04002 | 62 | } |
f8325309 PJ |
63 | elseif ($contribution->contribution_status_id == array_search('Partially paid', $contributionStatuses)) { |
64 | $itemStatus = array_search('Partially paid', $financialItemStatus); | |
65 | } | |
be2fb01f | 66 | $params = [ |
f1518315 | 67 | 'transaction_date' => $contribution->receive_date, |
353ffa53 TO |
68 | 'contact_id' => $contribution->contact_id, |
69 | 'amount' => $lineItem->line_total, | |
70 | 'currency' => $contribution->currency, | |
71 | 'entity_table' => 'civicrm_line_item', | |
72 | 'entity_id' => $lineItem->id, | |
cf28d075 | 73 | 'description' => ($lineItem->qty != 1 ? $lineItem->qty . ' of ' : '') . $lineItem->label, |
353ffa53 | 74 | 'status_id' => $itemStatus, |
be2fb01f | 75 | ]; |
03e04002 | 76 | |
0b7bd9dd | 77 | if ($taxTrxnID) { |
78 | $params['amount'] = $lineItem->tax_amount; | |
530f1e12 | 79 | $params['description'] = Civi::settings()->get('tax_term'); |
53d294ba | 80 | $accountRelName = 'Sales Tax Account is'; |
0b7bd9dd | 81 | } |
82 | else { | |
8cf6bd83 PN |
83 | $accountRelName = 'Income Account is'; |
84 | if (property_exists($contribution, 'revenue_recognition_date') && !CRM_Utils_System::isNull($contribution->revenue_recognition_date)) { | |
85 | $accountRelName = 'Deferred Revenue Account is'; | |
86 | } | |
0b7bd9dd | 87 | } |
6a488035 | 88 | if ($lineItem->financial_type_id) { |
928a340b | 89 | $params['financial_account_id'] = CRM_Financial_BAO_FinancialAccount::getFinancialAccountForFinancialTypeByRelationship( |
53d294ba PN |
90 | $lineItem->financial_type_id, |
91 | $accountRelName | |
6a488035 | 92 | ); |
6a488035 | 93 | } |
a191ff3d | 94 | if (empty($trxnId)) { |
85726d00 | 95 | if (empty($trxnId['id'])) { |
9c472292 PN |
96 | $trxn = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution->id, 'ASC', TRUE); |
97 | $trxnId['id'] = $trxn['financialTrxnId']; | |
98 | } | |
a191ff3d | 99 | } |
8cf6bd83 PN |
100 | $financialItem = self::create($params, NULL, $trxnId); |
101 | return $financialItem; | |
03e04002 | 102 | } |
6a488035 TO |
103 | |
104 | /** | |
54957108 | 105 | * Create the financial Items and financial entity trxn. |
6a488035 | 106 | * |
ed5dd492 TO |
107 | * @param array $params |
108 | * Associated array to create financial items. | |
109 | * @param array $ids | |
110 | * Financial item ids. | |
111 | * @param array $trxnIds | |
112 | * Financial item ids. | |
03e04002 | 113 | * |
54957108 | 114 | * @return CRM_Financial_DAO_FinancialItem |
6a488035 | 115 | */ |
00be9182 | 116 | public static function create(&$params, $ids = NULL, $trxnIds = NULL) { |
6a488035 | 117 | $financialItem = new CRM_Financial_DAO_FinancialItem(); |
045f52a3 | 118 | |
a9ed1dc0 PN |
119 | if (!empty($ids['id'])) { |
120 | CRM_Utils_Hook::pre('edit', 'FinancialItem', $ids['id'], $params); | |
121 | } | |
122 | else { | |
123 | CRM_Utils_Hook::pre('create', 'FinancialItem', NULL, $params); | |
124 | } | |
045f52a3 | 125 | |
6a488035 | 126 | $financialItem->copyValues($params); |
a7488080 | 127 | if (!empty($ids['id'])) { |
03e04002 | 128 | $financialItem->id = $ids['id']; |
6a488035 TO |
129 | } |
130 | ||
131 | $financialItem->save(); | |
9c1bc317 | 132 | $financialtrxnIDS = $trxnIds['id'] ?? NULL; |
9c472292 PN |
133 | if (!empty($financialtrxnIDS)) { |
134 | if (!is_array($financialtrxnIDS)) { | |
be2fb01f | 135 | $financialtrxnIDS = [$financialtrxnIDS]; |
9c472292 PN |
136 | } |
137 | foreach ($financialtrxnIDS as $tID) { | |
be2fb01f | 138 | $entity_financial_trxn_params = [ |
9c472292 PN |
139 | 'entity_table' => "civicrm_financial_item", |
140 | 'entity_id' => $financialItem->id, | |
141 | 'financial_trxn_id' => $tID, | |
142 | 'amount' => $params['amount'], | |
be2fb01f | 143 | ]; |
9c472292 PN |
144 | if (!empty($ids['entityFinancialTrxnId'])) { |
145 | $entity_financial_trxn_params['id'] = $ids['entityFinancialTrxnId']; | |
146 | } | |
147 | self::createEntityTrxn($entity_financial_trxn_params); | |
6a488035 | 148 | } |
6a488035 | 149 | } |
a9ed1dc0 PN |
150 | if (!empty($ids['id'])) { |
151 | CRM_Utils_Hook::post('edit', 'FinancialItem', $financialItem->id, $financialItem); | |
152 | } | |
045f52a3 | 153 | else { |
a9ed1dc0 PN |
154 | CRM_Utils_Hook::post('create', 'FinancialItem', $financialItem->id, $financialItem); |
155 | } | |
6a488035 | 156 | return $financialItem; |
03e04002 | 157 | } |
6a488035 TO |
158 | |
159 | /** | |
fe482240 | 160 | * Takes an associative array and creates a entity financial transaction object. |
6a488035 | 161 | * |
ed5dd492 | 162 | * @param array $params |
5b541553 | 163 | * an assoc array of name/value pairs. |
6a488035 | 164 | * |
5b541553 | 165 | * @return CRM_Financial_DAO_EntityFinancialTrxn |
6a488035 | 166 | */ |
00be9182 | 167 | public static function createEntityTrxn($params) { |
6a488035 TO |
168 | $entity_trxn = new CRM_Financial_DAO_EntityFinancialTrxn(); |
169 | $entity_trxn->copyValues($params); | |
170 | $entity_trxn->save(); | |
171 | return $entity_trxn; | |
172 | } | |
173 | ||
174 | /** | |
f044623d EM |
175 | * Retrieve entity financial trxn details. |
176 | * | |
177 | * @deprecated - only called by tests - to be replaced with | |
178 | * $trxn = (array) EntityFinancialTrxn::get() | |
179 | * ->addWhere('id', '=', $contributionID) | |
180 | * ->addWhere('entity_table', '=', 'civicrm_contribution') | |
181 | * ->addSelect('*')->execute(); | |
6a488035 | 182 | * |
ed5dd492 | 183 | * @param array $params |
5b541553 | 184 | * an assoc array of name/value pairs. |
ed5dd492 | 185 | * @param bool $maxId |
5b541553 | 186 | * To retrieve max id. |
6a488035 TO |
187 | * |
188 | * @return array | |
6a488035 | 189 | */ |
00be9182 | 190 | public static function retrieveEntityFinancialTrxn($params, $maxId = FALSE) { |
6a488035 TO |
191 | $financialItem = new CRM_Financial_DAO_EntityFinancialTrxn(); |
192 | $financialItem->copyValues($params); | |
cded2ebf | 193 | // retrieve last entry from civicrm_entity_financial_trxn |
6a488035 TO |
194 | if ($maxId) { |
195 | $financialItem->orderBy('id DESC'); | |
196 | $financialItem->limit(1); | |
197 | } | |
198 | $financialItem->find(); | |
199 | while ($financialItem->fetch()) { | |
be2fb01f | 200 | $financialItems[$financialItem->id] = [ |
353ffa53 TO |
201 | 'id' => $financialItem->id, |
202 | 'entity_table' => $financialItem->entity_table, | |
203 | 'entity_id' => $financialItem->entity_id, | |
6a488035 | 204 | 'financial_trxn_id' => $financialItem->financial_trxn_id, |
353ffa53 | 205 | 'amount' => $financialItem->amount, |
be2fb01f | 206 | ]; |
03e04002 | 207 | } |
6a488035 TO |
208 | if (!empty($financialItems)) { |
209 | return $financialItems; | |
210 | } | |
211 | else { | |
045f52a3 | 212 | return NULL; |
6a488035 TO |
213 | } |
214 | } | |
2efcf0c2 | 215 | |
f182074e | 216 | /** |
fe482240 | 217 | * Check if contact is present in financial_item table. |
f182074e | 218 | * |
0e480632 | 219 | * @see https://issues.civicrm.org/jira/browse/CRM-12929 |
f182074e | 220 | * |
ed5dd492 TO |
221 | * @param array $contactIds |
222 | * An array contact id's. | |
f182074e | 223 | * |
ed5dd492 TO |
224 | * @param array $error |
225 | * Error to display. | |
f182074e | 226 | * |
a2fb4683 | 227 | * @return array|bool |
f182074e | 228 | */ |
00be9182 | 229 | public static function checkContactPresent($contactIds, &$error) { |
f182074e PN |
230 | if (empty($contactIds)) { |
231 | return FALSE; | |
232 | } | |
2efcf0c2 | 233 | |
aaffa79f | 234 | $allowPermDelete = Civi::settings()->get('allowPermDeleteFinancial'); |
f182074e PN |
235 | |
236 | if (!$allowPermDelete) { | |
237 | $sql = 'SELECT DISTINCT(cc.id), cc.display_name FROM civicrm_contact cc | |
238 | INNER JOIN civicrm_contribution con ON con.contact_id = cc.id | |
045f52a3 | 239 | WHERE cc.id IN (' . implode(',', $contactIds) . ') AND con.is_test = 0'; |
f182074e PN |
240 | $dao = CRM_Core_DAO::executeQuery($sql); |
241 | if ($dao->N) { | |
242 | while ($dao->fetch()) { | |
243 | $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid=$dao->id"); | |
244 | $not_deleted[$dao->id] = "<a href='$url'>$dao->display_name</a>"; | |
245 | } | |
2efcf0c2 | 246 | |
f182074e PN |
247 | $errorStatus = ''; |
248 | if (is_array($error)) { | |
249 | $errorStatus = '<ul><li>' . implode('</li><li>', $not_deleted) . '</li></ul>'; | |
250 | } | |
2efcf0c2 | 251 | |
86bfa4f6 | 252 | $error['_qf_default'] = $errorStatus . ts('This contact(s) can not be permanently deleted because the contact record is linked to one or more live financial transactions. Deleting this contact would result in the loss of financial data.'); |
2efcf0c2 | 253 | return $error; |
f182074e PN |
254 | } |
255 | } | |
256 | return FALSE; | |
257 | } | |
96025800 | 258 | |
00b4d571 | 259 | /** |
cf28d075 | 260 | * Get most relevant previous financial item relating to the line item. |
00b4d571 | 261 | * |
cf28d075 | 262 | * This function specifically excludes sales tax. |
00b4d571 | 263 | * |
cf28d075 | 264 | * @param int $entityId |
00b4d571 | 265 | * |
81716ddb | 266 | * @return array |
00b4d571 | 267 | */ |
cf28d075 | 268 | public static function getPreviousFinancialItem($entityId) { |
be2fb01f | 269 | $params = [ |
cf28d075 | 270 | 'entity_id' => $entityId, |
271 | 'entity_table' => 'civicrm_line_item', | |
be2fb01f CW |
272 | 'options' => ['limit' => 1, 'sort' => 'id DESC'], |
273 | ]; | |
274 | $salesTaxFinancialAccounts = civicrm_api3('FinancialAccount', 'get', ['is_tax' => 1]); | |
cf28d075 | 275 | if ($salesTaxFinancialAccounts['count']) { |
be2fb01f | 276 | $params['financial_account_id'] = ['NOT IN' => array_keys($salesTaxFinancialAccounts['values'])]; |
cf28d075 | 277 | } |
278 | return civicrm_api3('FinancialItem', 'getsingle', $params); | |
00b4d571 PN |
279 | } |
280 | ||
6844be64 MD |
281 | /** |
282 | * Whitelist of possible values for the entity_table field | |
283 | * | |
284 | * @return array | |
285 | */ | |
286 | public static function entityTables(): array { | |
287 | return [ | |
288 | 'civicrm_line_item' => ts('Line Item'), | |
289 | 'civicrm_financial_trxn' => ts('Financial Trxn'), | |
290 | ]; | |
291 | } | |
292 | ||
6a488035 | 293 | } |