Merge pull request #12424 from alifrumin/editOwnEvents
[civicrm-core.git] / CRM / Financial / BAO / FinancialItem.php
CommitLineData
6a488035 1<?php
6a488035
TO
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
8c9251b3 6 | Copyright CiviCRM LLC (c) 2004-2018 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
8c9251b3 31 * @copyright CiviCRM LLC (c) 2004-2018
6a488035 32 */
6a488035
TO
33class CRM_Financial_BAO_FinancialItem extends CRM_Financial_DAO_FinancialItem {
34
35 /**
fe482240 36 * Class constructor.
6a488035 37 */
045f52a3 38 public function __construct() {
481a74f4 39 parent::__construct();
6a488035
TO
40 }
41
42 /**
fe482240 43 * Fetch object based on array of properties.
6a488035 44 *
ed5dd492
TO
45 * @param array $params
46 * (reference ) an assoc array of name/value pairs.
47 * @param array $defaults
48 * (reference ) an assoc array to hold the flattened values.
6a488035 49 *
5b541553 50 * @return CRM_Financial_DAO_FinancialItem
6a488035 51 */
00be9182 52 public static function retrieve(&$params, &$defaults) {
6a488035
TO
53 $financialItem = new CRM_Financial_DAO_FinancialItem();
54 $financialItem->copyValues($params);
55 if ($financialItem->find(TRUE)) {
56 CRM_Core_DAO::storeValues($financialItem, $defaults);
57 return $financialItem;
58 }
59 return NULL;
60 }
61
62 /**
fe482240 63 * Add the financial items and financial trxn.
6a488035 64 *
ed5dd492
TO
65 * @param object $lineItem
66 * Line item object.
67 * @param object $contribution
68 * Contribution object.
69 * @param bool $taxTrxnID
03e04002 70 *
54957108 71 * @param int $trxnId
72 *
73 * @return CRM_Financial_DAO_FinancialItem
6a488035 74 */
a191ff3d 75 public static function add($lineItem, $contribution, $taxTrxnID = FALSE, $trxnId = NULL) {
6a488035 76 $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
7611ae71 77 $financialItemStatus = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id');
b81ee58c 78 $itemStatus = NULL;
0bdf3091 79 if ($contribution->contribution_status_id == array_search('Completed', $contributionStatuses)
353ffa53
TO
80 || $contribution->contribution_status_id == array_search('Pending refund', $contributionStatuses)
81 ) {
6a488035 82 $itemStatus = array_search('Paid', $financialItemStatus);
03e04002 83 }
f6bae84f 84 elseif ($contribution->contribution_status_id == array_search('Pending', $contributionStatuses)
353ffa53
TO
85 || $contribution->contribution_status_id == array_search('In Progress', $contributionStatuses)
86 ) {
6a488035 87 $itemStatus = array_search('Unpaid', $financialItemStatus);
03e04002 88 }
f8325309
PJ
89 elseif ($contribution->contribution_status_id == array_search('Partially paid', $contributionStatuses)) {
90 $itemStatus = array_search('Partially paid', $financialItemStatus);
91 }
6a488035 92 $params = array(
353ffa53
TO
93 'transaction_date' => CRM_Utils_Date::isoToMysql($contribution->receive_date),
94 'contact_id' => $contribution->contact_id,
95 'amount' => $lineItem->line_total,
96 'currency' => $contribution->currency,
97 'entity_table' => 'civicrm_line_item',
98 'entity_id' => $lineItem->id,
cf28d075 99 'description' => ($lineItem->qty != 1 ? $lineItem->qty . ' of ' : '') . $lineItem->label,
353ffa53 100 'status_id' => $itemStatus,
6a488035 101 );
03e04002 102
0b7bd9dd 103 if ($taxTrxnID) {
aaffa79f 104 $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
5a18a545 105 $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
0b7bd9dd 106 $params['amount'] = $lineItem->tax_amount;
5a18a545 107 $params['description'] = $taxTerm;
53d294ba 108 $accountRelName = 'Sales Tax Account is';
0b7bd9dd 109 }
110 else {
8cf6bd83
PN
111 $accountRelName = 'Income Account is';
112 if (property_exists($contribution, 'revenue_recognition_date') && !CRM_Utils_System::isNull($contribution->revenue_recognition_date)) {
113 $accountRelName = 'Deferred Revenue Account is';
114 }
0b7bd9dd 115 }
6a488035 116 if ($lineItem->financial_type_id) {
53d294ba
PN
117 $params['financial_account_id'] = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount(
118 $lineItem->financial_type_id,
119 $accountRelName
6a488035 120 );
6a488035 121 }
a191ff3d 122 if (empty($trxnId)) {
9c472292 123 $trxnId['id'] = CRM_Contribute_BAO_Contribution::$_trxnIDs;
85726d00 124 if (empty($trxnId['id'])) {
9c472292
PN
125 $trxn = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution->id, 'ASC', TRUE);
126 $trxnId['id'] = $trxn['financialTrxnId'];
127 }
a191ff3d 128 }
8cf6bd83
PN
129 $financialItem = self::create($params, NULL, $trxnId);
130 return $financialItem;
03e04002 131 }
6a488035
TO
132
133 /**
54957108 134 * Create the financial Items and financial entity trxn.
6a488035 135 *
ed5dd492
TO
136 * @param array $params
137 * Associated array to create financial items.
138 * @param array $ids
139 * Financial item ids.
140 * @param array $trxnIds
141 * Financial item ids.
03e04002 142 *
54957108 143 * @return CRM_Financial_DAO_FinancialItem
6a488035 144 */
00be9182 145 public static function create(&$params, $ids = NULL, $trxnIds = NULL) {
6a488035 146 $financialItem = new CRM_Financial_DAO_FinancialItem();
045f52a3 147
a9ed1dc0
PN
148 if (!empty($ids['id'])) {
149 CRM_Utils_Hook::pre('edit', 'FinancialItem', $ids['id'], $params);
150 }
151 else {
152 CRM_Utils_Hook::pre('create', 'FinancialItem', NULL, $params);
153 }
045f52a3 154
6a488035 155 $financialItem->copyValues($params);
a7488080 156 if (!empty($ids['id'])) {
03e04002 157 $financialItem->id = $ids['id'];
6a488035
TO
158 }
159
160 $financialItem->save();
9c472292
PN
161 $financialtrxnIDS = CRM_Utils_Array::value('id', $trxnIds);
162 if (!empty($financialtrxnIDS)) {
163 if (!is_array($financialtrxnIDS)) {
164 $financialtrxnIDS = array($financialtrxnIDS);
165 }
166 foreach ($financialtrxnIDS as $tID) {
167 $entity_financial_trxn_params = array(
168 'entity_table' => "civicrm_financial_item",
169 'entity_id' => $financialItem->id,
170 'financial_trxn_id' => $tID,
171 'amount' => $params['amount'],
172 );
173 if (!empty($ids['entityFinancialTrxnId'])) {
174 $entity_financial_trxn_params['id'] = $ids['entityFinancialTrxnId'];
175 }
176 self::createEntityTrxn($entity_financial_trxn_params);
6a488035 177 }
6a488035 178 }
a9ed1dc0
PN
179 if (!empty($ids['id'])) {
180 CRM_Utils_Hook::post('edit', 'FinancialItem', $financialItem->id, $financialItem);
181 }
045f52a3 182 else {
a9ed1dc0
PN
183 CRM_Utils_Hook::post('create', 'FinancialItem', $financialItem->id, $financialItem);
184 }
6a488035 185 return $financialItem;
03e04002 186 }
6a488035
TO
187
188 /**
fe482240 189 * Takes an associative array and creates a entity financial transaction object.
6a488035 190 *
ed5dd492 191 * @param array $params
5b541553 192 * an assoc array of name/value pairs.
6a488035 193 *
5b541553 194 * @return CRM_Financial_DAO_EntityFinancialTrxn
6a488035 195 */
00be9182 196 public static function createEntityTrxn($params) {
6a488035
TO
197 $entity_trxn = new CRM_Financial_DAO_EntityFinancialTrxn();
198 $entity_trxn->copyValues($params);
199 $entity_trxn->save();
200 return $entity_trxn;
201 }
202
203 /**
fe482240 204 * Retrive entity financial trxn details.
6a488035 205 *
ed5dd492 206 * @param array $params
5b541553 207 * an assoc array of name/value pairs.
ed5dd492 208 * @param bool $maxId
5b541553 209 * To retrieve max id.
6a488035
TO
210 *
211 * @return array
6a488035 212 */
00be9182 213 public static function retrieveEntityFinancialTrxn($params, $maxId = FALSE) {
6a488035
TO
214 $financialItem = new CRM_Financial_DAO_EntityFinancialTrxn();
215 $financialItem->copyValues($params);
cded2ebf 216 // retrieve last entry from civicrm_entity_financial_trxn
6a488035
TO
217 if ($maxId) {
218 $financialItem->orderBy('id DESC');
219 $financialItem->limit(1);
220 }
221 $financialItem->find();
222 while ($financialItem->fetch()) {
223 $financialItems[$financialItem->id] = array(
353ffa53
TO
224 'id' => $financialItem->id,
225 'entity_table' => $financialItem->entity_table,
226 'entity_id' => $financialItem->entity_id,
6a488035 227 'financial_trxn_id' => $financialItem->financial_trxn_id,
353ffa53 228 'amount' => $financialItem->amount,
6a488035 229 );
03e04002 230 }
6a488035
TO
231 if (!empty($financialItems)) {
232 return $financialItems;
233 }
234 else {
045f52a3 235 return NULL;
6a488035
TO
236 }
237 }
2efcf0c2 238
f182074e 239 /**
fe482240 240 * Check if contact is present in financial_item table.
f182074e
PN
241 *
242 * CRM-12929
243 *
ed5dd492
TO
244 * @param array $contactIds
245 * An array contact id's.
f182074e 246 *
ed5dd492
TO
247 * @param array $error
248 * Error to display.
f182074e 249 *
a2fb4683 250 * @return array|bool
f182074e 251 */
00be9182 252 public static function checkContactPresent($contactIds, &$error) {
f182074e
PN
253 if (empty($contactIds)) {
254 return FALSE;
255 }
2efcf0c2 256
aaffa79f 257 $allowPermDelete = Civi::settings()->get('allowPermDeleteFinancial');
f182074e
PN
258
259 if (!$allowPermDelete) {
260 $sql = 'SELECT DISTINCT(cc.id), cc.display_name FROM civicrm_contact cc
261INNER JOIN civicrm_contribution con ON con.contact_id = cc.id
045f52a3 262WHERE cc.id IN (' . implode(',', $contactIds) . ') AND con.is_test = 0';
f182074e
PN
263 $dao = CRM_Core_DAO::executeQuery($sql);
264 if ($dao->N) {
265 while ($dao->fetch()) {
266 $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid=$dao->id");
267 $not_deleted[$dao->id] = "<a href='$url'>$dao->display_name</a>";
268 }
2efcf0c2 269
f182074e
PN
270 $errorStatus = '';
271 if (is_array($error)) {
272 $errorStatus = '<ul><li>' . implode('</li><li>', $not_deleted) . '</li></ul>';
273 }
2efcf0c2 274
86bfa4f6 275 $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 276 return $error;
f182074e
PN
277 }
278 }
279 return FALSE;
280 }
96025800 281
00b4d571 282 /**
cf28d075 283 * Get most relevant previous financial item relating to the line item.
00b4d571 284 *
cf28d075 285 * This function specifically excludes sales tax.
00b4d571 286 *
cf28d075 287 * @param int $entityId
00b4d571 288 *
81716ddb 289 * @return array
00b4d571 290 */
cf28d075 291 public static function getPreviousFinancialItem($entityId) {
292 $params = array(
293 'entity_id' => $entityId,
294 'entity_table' => 'civicrm_line_item',
295 'options' => array('limit' => 1, 'sort' => 'id DESC'),
00b4d571 296 );
cf28d075 297 $salesTaxFinancialAccounts = civicrm_api3('FinancialAccount', 'get', array('is_tax' => 1));
298 if ($salesTaxFinancialAccounts['count']) {
299 $params['financial_account_id'] = array('NOT IN' => array_keys($salesTaxFinancialAccounts['values']));
300 }
301 return civicrm_api3('FinancialItem', 'getsingle', $params);
00b4d571
PN
302 }
303
6a488035 304}