Merge remote-tracking branch 'upstream/4.6' into 4.6-master-2015-11-16-01-17-32
[civicrm-core.git] / CRM / Financial / BAO / FinancialItem.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2015 |
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 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2015
32 */
33 class CRM_Financial_BAO_FinancialItem extends CRM_Financial_DAO_FinancialItem {
34
35 /**
36 * Class constructor.
37 */
38 public function __construct() {
39 parent::__construct();
40 }
41
42 /**
43 * Fetch object based on array of properties.
44 *
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.
49 *
50 * @return CRM_Contribute_BAO_FinancialItem
51 */
52 public static function retrieve(&$params, &$defaults) {
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 /**
63 * Add the financial items and financial trxn.
64 *
65 * @param object $lineItem
66 * Line item object.
67 * @param object $contribution
68 * Contribution object.
69 * @param bool $taxTrxnID
70 *
71 * @param int $trxnId
72 *
73 * @return CRM_Financial_DAO_FinancialItem
74 */
75 public static function add($lineItem, $contribution, $taxTrxnID = FALSE, $trxnId = NULL) {
76 $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
77 $financialItemStatus = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id');
78 $itemStatus = NULL;
79 if ($contribution->contribution_status_id == array_search('Completed', $contributionStatuses)
80 || $contribution->contribution_status_id == array_search('Pending refund', $contributionStatuses)
81 ) {
82 $itemStatus = array_search('Paid', $financialItemStatus);
83 }
84 elseif ($contribution->contribution_status_id == array_search('Pending', $contributionStatuses)
85 || $contribution->contribution_status_id == array_search('In Progress', $contributionStatuses)
86 ) {
87 $itemStatus = array_search('Unpaid', $financialItemStatus);
88 }
89 elseif ($contribution->contribution_status_id == array_search('Partially paid', $contributionStatuses)) {
90 $itemStatus = array_search('Partially paid', $financialItemStatus);
91 }
92 $params = array(
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,
99 'description' => ($lineItem->qty != 1 ? $lineItem->qty . ' of ' : '') . ' ' . $lineItem->label,
100 'status_id' => $itemStatus,
101 );
102
103 if ($taxTrxnID) {
104 $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
105 $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
106 $params['amount'] = $lineItem->tax_amount;
107 $params['description'] = $taxTerm;
108 $accountRel = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Sales Tax Account is' "));
109 }
110 else {
111 $accountRel = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Income Account is' "));
112 }
113 if ($lineItem->financial_type_id) {
114 $searchParams = array(
115 'entity_table' => 'civicrm_financial_type',
116 'entity_id' => $lineItem->financial_type_id,
117 'account_relationship' => $accountRel,
118 );
119
120 $result = array();
121 CRM_Financial_BAO_FinancialTypeAccount::retrieve($searchParams, $result);
122 $params['financial_account_id'] = CRM_Utils_Array::value('financial_account_id', $result);
123 }
124 if (empty($trxnId)) {
125 $trxn = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution->id, 'ASC', TRUE);
126 $trxnId['id'] = $trxn['financialTrxnId'];
127 }
128
129 return self::create($params, NULL, $trxnId);
130 }
131
132 /**
133 * Create the financial Items and financial entity trxn.
134 *
135 * @param array $params
136 * Associated array to create financial items.
137 * @param array $ids
138 * Financial item ids.
139 * @param array $trxnIds
140 * Financial item ids.
141 *
142 * @return CRM_Financial_DAO_FinancialItem
143 */
144 public static function create(&$params, $ids = NULL, $trxnIds = NULL) {
145 $financialItem = new CRM_Financial_DAO_FinancialItem();
146
147 if (!empty($ids['id'])) {
148 CRM_Utils_Hook::pre('edit', 'FinancialItem', $ids['id'], $params);
149 }
150 else {
151 CRM_Utils_Hook::pre('create', 'FinancialItem', NULL, $params);
152 }
153
154 $financialItem->copyValues($params);
155 if (!empty($ids['id'])) {
156 $financialItem->id = $ids['id'];
157 }
158
159 $financialItem->save();
160 if (!empty($trxnIds['id'])) {
161 $entity_financial_trxn_params = array(
162 'entity_table' => "civicrm_financial_item",
163 'entity_id' => $financialItem->id,
164 'financial_trxn_id' => $trxnIds['id'],
165 'amount' => $params['amount'],
166 );
167
168 $entity_trxn = new CRM_Financial_DAO_EntityFinancialTrxn();
169 $entity_trxn->copyValues($entity_financial_trxn_params);
170 if (!empty($ids['entityFinancialTrxnId'])) {
171 $entity_trxn->id = $ids['entityFinancialTrxnId'];
172 }
173 $entity_trxn->save();
174 }
175 if (!empty($ids['id'])) {
176 CRM_Utils_Hook::post('edit', 'FinancialItem', $financialItem->id, $financialItem);
177 }
178 else {
179 CRM_Utils_Hook::post('create', 'FinancialItem', $financialItem->id, $financialItem);
180 }
181 return $financialItem;
182 }
183
184 /**
185 * Takes an associative array and creates a entity financial transaction object.
186 *
187 * @param array $params
188 * (reference ) an assoc array of name/value pairs.
189 *
190 * @return CRM_Core_BAO_FinancialTrxn
191 */
192 public static function createEntityTrxn($params) {
193 $entity_trxn = new CRM_Financial_DAO_EntityFinancialTrxn();
194 $entity_trxn->copyValues($params);
195 $entity_trxn->save();
196 return $entity_trxn;
197 }
198
199 /**
200 * Retrive entity financial trxn details.
201 *
202 * @param array $params
203 * (reference ) an assoc array of name/value pairs.
204 * @param bool $maxId
205 * To retrive max id.
206 *
207 * @return array
208 */
209 public static function retrieveEntityFinancialTrxn($params, $maxId = FALSE) {
210 $financialItem = new CRM_Financial_DAO_EntityFinancialTrxn();
211 $financialItem->copyValues($params);
212 // retrieve last entry from civicrm_entity_financial_trxn
213 if ($maxId) {
214 $financialItem->orderBy('id DESC');
215 $financialItem->limit(1);
216 }
217 $financialItem->find();
218 while ($financialItem->fetch()) {
219 $financialItems[$financialItem->id] = array(
220 'id' => $financialItem->id,
221 'entity_table' => $financialItem->entity_table,
222 'entity_id' => $financialItem->entity_id,
223 'financial_trxn_id' => $financialItem->financial_trxn_id,
224 'amount' => $financialItem->amount,
225 );
226 }
227 if (!empty($financialItems)) {
228 return $financialItems;
229 }
230 else {
231 return NULL;
232 }
233 }
234
235 /**
236 * Check if contact is present in financial_item table.
237 *
238 * CRM-12929
239 *
240 * @param array $contactIds
241 * An array contact id's.
242 *
243 * @param array $error
244 * Error to display.
245 *
246 * @return array
247 */
248 public static function checkContactPresent($contactIds, &$error) {
249 if (empty($contactIds)) {
250 return FALSE;
251 }
252
253 $allowPermDelete = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'allowPermDeleteFinancial');
254
255 if (!$allowPermDelete) {
256 $sql = 'SELECT DISTINCT(cc.id), cc.display_name FROM civicrm_contact cc
257 INNER JOIN civicrm_contribution con ON con.contact_id = cc.id
258 WHERE cc.id IN (' . implode(',', $contactIds) . ') AND con.is_test = 0';
259 $dao = CRM_Core_DAO::executeQuery($sql);
260 if ($dao->N) {
261 while ($dao->fetch()) {
262 $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid=$dao->id");
263 $not_deleted[$dao->id] = "<a href='$url'>$dao->display_name</a>";
264 }
265
266 $errorStatus = '';
267 if (is_array($error)) {
268 $errorStatus = '<ul><li>' . implode('</li><li>', $not_deleted) . '</li></ul>';
269 }
270
271 $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.');
272 return $error;
273 }
274 }
275 return FALSE;
276 }
277
278 }