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