Merge pull request #4790 from mattrenner/CRM-15763
[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 *
75 * @access public
76 * @static
77 * @return void
78 */
79 static function add($lineItem, $contribution) {
80 $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
81 $financialItemStatus = CRM_Core_PseudoConstant::get('CRM_Financial_DAO_FinancialItem', 'status_id');
82 $itemStatus = NULL;
83 if ($contribution->contribution_status_id == array_search('Completed', $contributionStatuses)
84 || $contribution->contribution_status_id == array_search('Pending refund', $contributionStatuses)) {
85 $itemStatus = array_search('Paid', $financialItemStatus);
86 }
87 elseif ($contribution->contribution_status_id == array_search('Pending', $contributionStatuses)
88 || $contribution->contribution_status_id == array_search('In Progress', $contributionStatuses)) {
89 $itemStatus = array_search('Unpaid', $financialItemStatus);
90 }
91 elseif ($contribution->contribution_status_id == array_search('Partially paid', $contributionStatuses)) {
92 $itemStatus = array_search('Partially paid', $financialItemStatus);
93 }
94 $params = array(
95 'transaction_date' => CRM_Utils_Date::isoToMysql($contribution->receive_date),
96 'contact_id' => $contribution->contact_id,
97 'amount' => $lineItem->line_total,
98 'currency' => $contribution->currency,
99 'entity_table' => 'civicrm_line_item',
100 'entity_id' => $lineItem->id,
101 'description' => ( $lineItem->qty != 1 ? $lineItem->qty . ' of ' : ''). ' ' . $lineItem->label,
102 'status_id' => $itemStatus,
103 );
104
105 if ($lineItem->financial_type_id) {
106 $searchParams = array(
107 'entity_table' => 'civicrm_financial_type',
108 'entity_id' => $lineItem->financial_type_id,
109 'account_relationship' => 1,
110 );
111
112 $result = array();
113 CRM_Financial_BAO_FinancialTypeAccount::retrieve( $searchParams, $result );
114 $params['financial_account_id'] = CRM_Utils_Array::value( 'financial_account_id', $result );
115 }
116
117 $trxn = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution->id, 'ASC', TRUE);
118 $trxnId['id'] = $trxn['financialTrxnId'];
119 return self::create($params, NULL, $trxnId);
120 }
121
122 /**
123 * function to create the financial Items and financial enity trxn
124 *
125 * @param array $params associated array to create financial items
126 * @param array $ids financial item ids
127 * @param array $trxnIds financial item ids
128 *
129 * @access public
130 * @static
131 * @return object
132 */
133 static function create(&$params, $ids = NULL, $trxnIds = NULL) {
134 $financialItem = new CRM_Financial_DAO_FinancialItem();
135
136 if (!empty($ids['id'])) {
137 CRM_Utils_Hook::pre('edit', 'FinancialItem', $ids['id'], $params);
138 }
139 else {
140 CRM_Utils_Hook::pre('create', 'FinancialItem', NULL, $params);
141 }
142
143 $financialItem->copyValues($params);
144 if (!empty($ids['id'])) {
145 $financialItem->id = $ids['id'];
146 }
147
148 $financialItem->save();
149 if (!empty($trxnIds['id'])) {
150 $entity_financial_trxn_params = array(
151 'entity_table' => "civicrm_financial_item",
152 'entity_id' => $financialItem->id,
153 'financial_trxn_id' => $trxnIds['id'],
154 'amount' => $params['amount'],
155 );
156
157 $entity_trxn = new CRM_Financial_DAO_EntityFinancialTrxn();
158 $entity_trxn->copyValues($entity_financial_trxn_params);
159 if (!empty($ids['entityFinancialTrxnId'])) {
160 $entity_trxn->id = $ids['entityFinancialTrxnId'];
161 }
162 $entity_trxn->save();
163 }
164 if (!empty($ids['id'])) {
165 CRM_Utils_Hook::post('edit', 'FinancialItem', $financialItem->id, $financialItem);
166 }
167 else {
168 CRM_Utils_Hook::post('create', 'FinancialItem', $financialItem->id, $financialItem);
169 }
170 return $financialItem;
171 }
172
173 /**
174 * takes an associative array and creates a entity financial transaction object
175 *
176 * @param array $params (reference ) an assoc array of name/value pairs
177 *
178 * @return object CRM_Core_BAO_FinancialTrxn object
179 * @access public
180 * @static
181 */
182 static function createEntityTrxn($params) {
183 $entity_trxn = new CRM_Financial_DAO_EntityFinancialTrxn();
184 $entity_trxn->copyValues($params);
185 $entity_trxn->save();
186 return $entity_trxn;
187 }
188
189 /**
190 * retrive entity financial trxn details
191 *
192 * @param array $params (reference ) an assoc array of name/value pairs
193 *
194 * @param bool $maxId
195 *
196 * @internal param bool $maxID to retrive max id
197 *
198 * @return array
199 * @access public
200 * @static
201 */
202 static function retrieveEntityFinancialTrxn($params, $maxId = FALSE) {
203 $financialItem = new CRM_Financial_DAO_EntityFinancialTrxn();
204 $financialItem->copyValues($params);
205 //retrieve last entry from civicrm_entity_financial_trxn
206 if ($maxId) {
207 $financialItem->orderBy('id DESC');
208 $financialItem->limit(1);
209 }
210 $financialItem->find();
211 while ($financialItem->fetch()) {
212 $financialItems[$financialItem->id] = array(
213 'id' => $financialItem->id,
214 'entity_table' => $financialItem->entity_table,
215 'entity_id' => $financialItem->entity_id,
216 'financial_trxn_id' => $financialItem->financial_trxn_id,
217 'amount' => $financialItem->amount,
218 );
219 }
220 if (!empty($financialItems)) {
221 return $financialItems;
222 }
223 else {
224 return null;
225 }
226 }
227
228 /**
229 * check if contact is present in financial_item table
230 *
231 * CRM-12929
232 *
233 * @param array $contactIds an array contact id's
234 *
235 * @param array $error error to display
236 *
237 * @return array
238 * @access public
239 * @static
240 */
241 static function checkContactPresent($contactIds, &$error) {
242 if (empty($contactIds)) {
243 return FALSE;
244 }
245
246 $allowPermDelete = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'allowPermDeleteFinancial');
247
248 if (!$allowPermDelete) {
249 $sql = 'SELECT DISTINCT(cc.id), cc.display_name FROM civicrm_contact cc
250 INNER JOIN civicrm_contribution con ON con.contact_id = cc.id
251 WHERE cc.id IN (' . implode (',', $contactIds) . ') AND con.is_test = 0';
252 $dao = CRM_Core_DAO::executeQuery($sql);
253 if ($dao->N) {
254 while ($dao->fetch()) {
255 $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid=$dao->id");
256 $not_deleted[$dao->id] = "<a href='$url'>$dao->display_name</a>";
257 }
258
259 $errorStatus = '';
260 if (is_array($error)) {
261 $errorStatus = '<ul><li>' . implode('</li><li>', $not_deleted) . '</li></ul>';
262 }
263
264 $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.');
265 return $error;
266 }
267 }
268 return FALSE;
269 }
270 }