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