Merge remote-tracking branch 'upstream/4.5' into 4.5-master-2015-02-02-18-36-16
[civicrm-core.git] / CRM / Financial / BAO / FinancialItem.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
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-2014
32 * $Id$
33 *
34 */
35 class CRM_Financial_BAO_FinancialItem extends CRM_Financial_DAO_FinancialItem {
36
37 /**
38 * Class constructor
39 */
40 public function __construct() {
41 parent::__construct();
42 }
43
44 /**
45 * Fetch object based on array of properties
46 *
47 * @param array $params
48 * (reference ) an assoc array of name/value pairs.
49 * @param array $defaults
50 * (reference ) an assoc array to hold the flattened values.
51 *
52 * @return CRM_Contribute_BAO_FinancialItem
53 */
54 public static function retrieve(&$params, &$defaults) {
55 $financialItem = new CRM_Financial_DAO_FinancialItem();
56 $financialItem->copyValues($params);
57 if ($financialItem->find(TRUE)) {
58 CRM_Core_DAO::storeValues($financialItem, $defaults);
59 return $financialItem;
60 }
61 return NULL;
62 }
63
64 /**
65 * Add the financial items and financial trxn
66 *
67 * @param object $lineItem
68 * Line item object.
69 * @param object $contribution
70 * Contribution object.
71 * @param bool $taxTrxnID
72 *
73 * @return void
74 */
75 public static function add($lineItem, $contribution, $taxTrxnID = FALSE) {
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 $trxn = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution->id, 'ASC', TRUE);
125 $trxnId['id'] = $trxn['financialTrxnId'];
126
127 return self::create($params, NULL, $trxnId);
128 }
129
130 /**
131 * Create the financial Items and financial enity trxn
132 *
133 * @param array $params
134 * Associated array to create financial items.
135 * @param array $ids
136 * Financial item ids.
137 * @param array $trxnIds
138 * Financial item ids.
139 *
140 * @return object
141 */
142 public static function create(&$params, $ids = NULL, $trxnIds = NULL) {
143 $financialItem = new CRM_Financial_DAO_FinancialItem();
144
145 if (!empty($ids['id'])) {
146 CRM_Utils_Hook::pre('edit', 'FinancialItem', $ids['id'], $params);
147 }
148 else {
149 CRM_Utils_Hook::pre('create', 'FinancialItem', NULL, $params);
150 }
151
152 $financialItem->copyValues($params);
153 if (!empty($ids['id'])) {
154 $financialItem->id = $ids['id'];
155 }
156
157 $financialItem->save();
158 if (!empty($trxnIds['id'])) {
159 $entity_financial_trxn_params = array(
160 'entity_table' => "civicrm_financial_item",
161 'entity_id' => $financialItem->id,
162 'financial_trxn_id' => $trxnIds['id'],
163 'amount' => $params['amount'],
164 );
165
166 $entity_trxn = new CRM_Financial_DAO_EntityFinancialTrxn();
167 $entity_trxn->copyValues($entity_financial_trxn_params);
168 if (!empty($ids['entityFinancialTrxnId'])) {
169 $entity_trxn->id = $ids['entityFinancialTrxnId'];
170 }
171 $entity_trxn->save();
172 }
173 if (!empty($ids['id'])) {
174 CRM_Utils_Hook::post('edit', 'FinancialItem', $financialItem->id, $financialItem);
175 }
176 else {
177 CRM_Utils_Hook::post('create', 'FinancialItem', $financialItem->id, $financialItem);
178 }
179 return $financialItem;
180 }
181
182 /**
183 * Takes an associative array and creates a entity financial transaction object
184 *
185 * @param array $params
186 * (reference ) an assoc array of name/value pairs.
187 *
188 * @return CRM_Core_BAO_FinancialTrxn
189 */
190 public static function createEntityTrxn($params) {
191 $entity_trxn = new CRM_Financial_DAO_EntityFinancialTrxn();
192 $entity_trxn->copyValues($params);
193 $entity_trxn->save();
194 return $entity_trxn;
195 }
196
197 /**
198 * Retrive entity financial trxn details
199 *
200 * @param array $params
201 * (reference ) an assoc array of name/value pairs.
202 * @param bool $maxId
203 * To retrive max id.
204 *
205 * @return array
206 */
207 public static function retrieveEntityFinancialTrxn($params, $maxId = FALSE) {
208 $financialItem = new CRM_Financial_DAO_EntityFinancialTrxn();
209 $financialItem->copyValues($params);
210 //retrieve last entry from civicrm_entity_financial_trxn
211 if ($maxId) {
212 $financialItem->orderBy('id DESC');
213 $financialItem->limit(1);
214 }
215 $financialItem->find();
216 while ($financialItem->fetch()) {
217 $financialItems[$financialItem->id] = array(
218 'id' => $financialItem->id,
219 'entity_table' => $financialItem->entity_table,
220 'entity_id' => $financialItem->entity_id,
221 'financial_trxn_id' => $financialItem->financial_trxn_id,
222 'amount' => $financialItem->amount,
223 );
224 }
225 if (!empty($financialItems)) {
226 return $financialItems;
227 }
228 else {
229 return NULL;
230 }
231 }
232
233 /**
234 * Check if contact is present in financial_item table
235 *
236 * CRM-12929
237 *
238 * @param array $contactIds
239 * An array contact id's.
240 *
241 * @param array $error
242 * Error to display.
243 *
244 * @return array
245 */
246 public static function checkContactPresent($contactIds, &$error) {
247 if (empty($contactIds)) {
248 return FALSE;
249 }
250
251 $allowPermDelete = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'allowPermDeleteFinancial');
252
253 if (!$allowPermDelete) {
254 $sql = 'SELECT DISTINCT(cc.id), cc.display_name FROM civicrm_contact cc
255 INNER JOIN civicrm_contribution con ON con.contact_id = cc.id
256 WHERE cc.id IN (' . implode(',', $contactIds) . ') AND con.is_test = 0';
257 $dao = CRM_Core_DAO::executeQuery($sql);
258 if ($dao->N) {
259 while ($dao->fetch()) {
260 $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid=$dao->id");
261 $not_deleted[$dao->id] = "<a href='$url'>$dao->display_name</a>";
262 }
263
264 $errorStatus = '';
265 if (is_array($error)) {
266 $errorStatus = '<ul><li>' . implode('</li><li>', $not_deleted) . '</li></ul>';
267 }
268
269 $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.');
270 return $error;
271 }
272 }
273 return FALSE;
274 }
275
276 }