0c9b306a |
1 | <?php |
2 | /* |
3 | +--------------------------------------------------------------------+ |
4 | | CiviCRM version 5 | |
5 | +--------------------------------------------------------------------+ |
6 | | Copyright CiviCRM LLC (c) 2004-2019 | |
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-2019 |
32 | */ |
33 | |
34 | /** |
35 | * This class contains payment related functions. |
36 | */ |
37 | class CRM_Financial_BAO_Payment { |
38 | |
39 | /** |
40 | * Function to process additional payment for partial and refund contributions. |
41 | * |
42 | * This function is called via API payment.create function. All forms that add payments |
43 | * should use this. |
44 | * |
45 | * @param array $params |
46 | * - contribution_id |
47 | * - total_amount |
48 | * - line_item |
49 | * |
50 | * @return \CRM_Financial_DAO_FinancialTrxn |
51 | * |
52 | * @throws \API_Exception |
53 | * @throws \CRM_Core_Exception |
54 | */ |
55 | public static function create($params) { |
56 | $contribution = civicrm_api3('Contribution', 'getsingle', ['id' => $params['contribution_id']]); |
57 | $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($contribution['contribution_status_id'], 'name'); |
db77f7d3 |
58 | |
7585038a |
59 | $isPaymentCompletesContribution = self::isPaymentCompletesContribution($params['contribution_id'], $params['total_amount']); |
60 | |
5f5ed53a |
61 | // For legacy reasons Pending payments are completed through completetransaction. |
62 | // @todo completetransaction should transition components but financial transactions |
63 | // should be handled through Payment.create. |
64 | $isSkipRecordingPaymentHereForLegacyHandlingReasons = ($contributionStatus == 'Pending' && $isPaymentCompletesContribution); |
65 | |
2561fc11 |
66 | if (!$isSkipRecordingPaymentHereForLegacyHandlingReasons && $params['total_amount'] > 0) { |
74e4c3c2 |
67 | $trxn = CRM_Contribute_BAO_Contribution::recordPartialPayment($contribution, $params); |
74e4c3c2 |
68 | |
db77f7d3 |
69 | if (CRM_Utils_Array::value('line_item', $params) && !empty($trxn)) { |
70 | foreach ($params['line_item'] as $values) { |
71 | foreach ($values as $id => $amount) { |
72 | $p = ['id' => $id]; |
73 | $check = CRM_Price_BAO_LineItem::retrieve($p, $defaults); |
74 | if (empty($check)) { |
75 | throw new API_Exception('Please specify a valid Line Item.'); |
0c9b306a |
76 | } |
db77f7d3 |
77 | // get financial item |
78 | $sql = "SELECT fi.id |
79 | FROM civicrm_financial_item fi |
80 | INNER JOIN civicrm_line_item li ON li.id = fi.entity_id and fi.entity_table = 'civicrm_line_item' |
81 | WHERE li.contribution_id = %1 AND li.id = %2"; |
82 | $sqlParams = [ |
83 | 1 => [$params['contribution_id'], 'Integer'], |
84 | 2 => [$id, 'Integer'], |
85 | ]; |
86 | $fid = CRM_Core_DAO::singleValueQuery($sql, $sqlParams); |
87 | // Record Entity Financial Trxn |
88 | $eftParams = [ |
89 | 'entity_table' => 'civicrm_financial_item', |
90 | 'financial_trxn_id' => $trxn->id, |
91 | 'amount' => $amount, |
92 | 'entity_id' => $fid, |
93 | ]; |
94 | civicrm_api3('EntityFinancialTrxn', 'create', $eftParams); |
0c9b306a |
95 | } |
96 | } |
db77f7d3 |
97 | } |
98 | elseif (!empty($trxn)) { |
99 | CRM_Contribute_BAO_Contribution::assignProportionalLineItems($params, $trxn->id, $contribution['total_amount']); |
0c9b306a |
100 | } |
101 | } |
2561fc11 |
102 | elseif ($params['total_amount'] < 0) { |
103 | $trxn = self::recordRefundPayment($params['contribution_id'], $params, FALSE); |
104 | } |
db77f7d3 |
105 | |
5f5ed53a |
106 | if ($isPaymentCompletesContribution) { |
be2fb01f |
107 | civicrm_api3('Contribution', 'completetransaction', ['id' => $contribution['id']]); |
5f5ed53a |
108 | // Get the trxn |
109 | $trxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC'); |
110 | $ftParams = ['id' => $trxnId['financialTrxnId']]; |
111 | $trxn = CRM_Core_BAO_FinancialTrxn::retrieve($ftParams, CRM_Core_DAO::$_nullArray); |
112 | } |
113 | elseif ($contributionStatus === 'Pending') { |
114 | civicrm_api3('Contribution', 'create', |
115 | [ |
116 | 'id' => $contribution['id'], |
117 | 'contribution_status_id' => 'Partially paid', |
118 | ] |
119 | ); |
120 | } |
db77f7d3 |
121 | |
0c9b306a |
122 | return $trxn; |
123 | } |
124 | |
a79d2ec2 |
125 | /** |
126 | * Send an email confirming a payment that has been received. |
127 | * |
128 | * @param array $params |
129 | * |
130 | * @return array |
131 | */ |
132 | public static function sendConfirmation($params) { |
133 | |
134 | $entities = self::loadRelatedEntities($params['id']); |
be2fb01f |
135 | $sendTemplateParams = [ |
a79d2ec2 |
136 | 'groupName' => 'msg_tpl_workflow_contribution', |
137 | 'valueName' => 'payment_or_refund_notification', |
138 | 'PDFFilename' => ts('notification') . '.pdf', |
139 | 'contactId' => $entities['contact']['id'], |
140 | 'toName' => $entities['contact']['display_name'], |
141 | 'toEmail' => $entities['contact']['email'], |
142 | 'tplParams' => self::getConfirmationTemplateParameters($entities), |
be2fb01f |
143 | ]; |
a79d2ec2 |
144 | return CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams); |
145 | } |
146 | |
147 | /** |
148 | * Load entities related to the current payment id. |
149 | * |
150 | * This gives us all the data we need to send an email confirmation but avoiding |
151 | * getting anything not tested for the confirmations. We retrieve the 'full' event as |
152 | * it has been traditionally assigned in full. |
153 | * |
154 | * @param int $id |
155 | * |
156 | * @return array |
157 | * - contact = ['id' => x, 'display_name' => y, 'email' => z] |
158 | * - event = [.... full event details......] |
159 | * - contribution = ['id' => x], |
160 | * - payment = [payment info + payment summary info] |
161 | */ |
162 | protected static function loadRelatedEntities($id) { |
163 | $entities = []; |
164 | $contributionID = (int) civicrm_api3('EntityFinancialTrxn', 'getvalue', [ |
165 | 'financial_trxn_id' => $id, |
166 | 'entity_table' => 'civicrm_contribution', |
167 | 'return' => 'entity_id', |
168 | ]); |
169 | $entities['contribution'] = ['id' => $contributionID]; |
170 | $entities['payment'] = array_merge(civicrm_api3('FinancialTrxn', 'getsingle', ['id' => $id]), |
171 | CRM_Contribute_BAO_Contribution::getPaymentInfo($contributionID) |
172 | ); |
173 | |
174 | $contactID = self::getPaymentContactID($contributionID); |
175 | list($displayName, $email) = CRM_Contact_BAO_Contact_Location::getEmailDetails($contactID); |
176 | $entities['contact'] = ['id' => $contactID, 'display_name' => $displayName, 'email' => $email]; |
1e477c5b |
177 | $contact = civicrm_api3('Contact', 'getsingle', ['id' => $contactID, 'return' => 'email_greeting']); |
178 | $entities['contact']['email_greeting'] = $contact['email_greeting_display']; |
a79d2ec2 |
179 | |
180 | $participantRecords = civicrm_api3('ParticipantPayment', 'get', [ |
181 | 'contribution_id' => $contributionID, |
182 | 'api.Participant.get' => ['return' => 'event_id'], |
183 | 'sequential' => 1, |
184 | ])['values']; |
185 | if (!empty($participantRecords)) { |
186 | $entities['event'] = civicrm_api3('Event', 'getsingle', ['id' => $participantRecords[0]['api.Participant.get']['values'][0]['event_id']]); |
0fad34a0 |
187 | if (!empty($entities['event']['is_show_location'])) { |
188 | $locationParams = [ |
189 | 'entity_id' => $entities['event']['id'], |
190 | 'entity_table' => 'civicrm_event', |
191 | ]; |
192 | $entities['location'] = CRM_Core_BAO_Location::getValues($locationParams, TRUE); |
193 | } |
a79d2ec2 |
194 | } |
195 | |
196 | return $entities; |
197 | } |
198 | |
199 | /** |
200 | * @param int $contributionID |
201 | * |
202 | * @return int |
203 | */ |
204 | public static function getPaymentContactID($contributionID) { |
205 | $contribution = civicrm_api3('Contribution', 'getsingle', [ |
206 | 'id' => $contributionID , |
207 | 'return' => ['contact_id'], |
208 | ]); |
209 | return (int) $contribution['contact_id']; |
210 | } |
7b966967 |
211 | |
a79d2ec2 |
212 | /** |
213 | * @param array $entities |
214 | * Related entities as an array keyed by the various entities. |
215 | * |
216 | * @return array |
217 | * Values required for the notification |
218 | * - contact_id |
219 | * - template_variables |
220 | * - event (DAO of event if relevant) |
221 | */ |
222 | public static function getConfirmationTemplateParameters($entities) { |
223 | $templateVariables = [ |
224 | 'contactDisplayName' => $entities['contact']['display_name'], |
1e477c5b |
225 | 'emailGreeting' => $entities['contact']['email_greeting'], |
a79d2ec2 |
226 | 'totalAmount' => $entities['payment']['total'], |
227 | 'amountOwed' => $entities['payment']['balance'], |
b5a442ed |
228 | 'totalPaid' => $entities['payment']['paid'], |
a79d2ec2 |
229 | 'paymentAmount' => $entities['payment']['total_amount'], |
434546ac |
230 | 'checkNumber' => CRM_Utils_Array::value('check_number', $entities['payment']), |
231 | 'receive_date' => $entities['payment']['trxn_date'], |
232 | 'paidBy' => CRM_Core_PseudoConstant::getLabel('CRM_Core_BAO_FinancialTrxn', 'payment_instrument_id', $entities['payment']['payment_instrument_id']), |
0fad34a0 |
233 | 'isShowLocation' => (!empty($entities['event']) ? $entities['event']['is_show_location'] : FALSE), |
234 | 'location' => CRM_Utils_Array::value('location', $entities), |
235 | 'event' => CRM_Utils_Array::value('event', $entities), |
236 | 'component' => (!empty($entities['event']) ? 'event' : 'contribution'), |
b5a442ed |
237 | 'isRefund' => $entities['payment']['total_amount'] < 0, |
238 | 'isAmountzero' => $entities['payment']['total_amount'] === 0, |
239 | 'refundAmount' => ($entities['payment']['total_amount'] < 0 ? $entities['payment']['total_amount'] : NULL), |
00ef9b01 |
240 | 'paymentsComplete' => ($entities['payment']['balance'] == 0), |
a79d2ec2 |
241 | ]; |
a79d2ec2 |
242 | |
243 | return self::filterUntestedTemplateVariables($templateVariables); |
244 | } |
245 | |
246 | /** |
247 | * Filter out any untested variables. |
248 | * |
249 | * This just serves to highlight if any variables are added without a unit test also being added. |
250 | * |
251 | * (if hit then add a unit test for the param & add to this array). |
252 | * |
253 | * @param array $params |
254 | * |
255 | * @return array |
256 | */ |
257 | public static function filterUntestedTemplateVariables($params) { |
258 | $testedTemplateVariables = [ |
259 | 'contactDisplayName', |
260 | 'totalAmount', |
261 | 'amountOwed', |
262 | 'paymentAmount', |
263 | 'event', |
264 | 'component', |
434546ac |
265 | 'checkNumber', |
266 | 'receive_date', |
267 | 'paidBy', |
0fad34a0 |
268 | 'isShowLocation', |
269 | 'location', |
b5a442ed |
270 | 'isRefund', |
271 | 'isAmountzero', |
272 | 'refundAmount', |
273 | 'totalPaid', |
00ef9b01 |
274 | 'paymentsComplete', |
7b966967 |
275 | 'emailGreeting', |
a79d2ec2 |
276 | ]; |
565920da |
277 | // These are assigned by the payment form - they still 'get through' from the |
278 | // form for now without being in here but we should ideally load |
279 | // and assign. Note we should update the tpl to use {if $billingName} |
280 | // and ditch contributeMode - although it might need to be deprecated rather than removed. |
a79d2ec2 |
281 | $todoParams = [ |
a79d2ec2 |
282 | 'contributeMode', |
a79d2ec2 |
283 | 'billingName', |
284 | 'address', |
285 | 'credit_card_type', |
286 | 'credit_card_number', |
287 | 'credit_card_exp_date', |
a79d2ec2 |
288 | ]; |
289 | $filteredParams = []; |
290 | foreach ($testedTemplateVariables as $templateVariable) { |
291 | // This will cause an a-notice if any are NOT set - by design. Ensuring |
292 | // they are set prevents leakage. |
293 | $filteredParams[$templateVariable] = $params[$templateVariable]; |
294 | } |
295 | return $filteredParams; |
296 | } |
297 | |
d3726f09 |
298 | /** |
299 | * @param $contributionId |
300 | * @param $trxnData |
301 | * @param $updateStatus |
302 | * - deprecate this param |
303 | * |
304 | * @todo - make this protected once recordAdditionalPayment no longer calls it. |
305 | * |
306 | * @return CRM_Financial_DAO_FinancialTrxn |
307 | */ |
308 | public static function recordRefundPayment($contributionId, $trxnData, $updateStatus) { |
9a2dce8d |
309 | list($contributionDAO, $params) = self::getContributionAndParamsInFormatForRecordFinancialTransaction($contributionId); |
d3726f09 |
310 | |
d3726f09 |
311 | $params['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $trxnData, CRM_Utils_Array::value('payment_instrument_id', $params)); |
312 | |
313 | $paidStatus = CRM_Core_PseudoConstant::getKey('CRM_Financial_DAO_FinancialItem', 'status_id', 'Paid'); |
314 | $arAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contributionDAO->financial_type_id, 'Accounts Receivable Account is'); |
315 | $completedStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); |
316 | |
2561fc11 |
317 | $trxnData['total_amount'] = $trxnData['net_amount'] = $trxnData['total_amount']; |
d3726f09 |
318 | $trxnData['from_financial_account_id'] = $arAccountId; |
319 | $trxnData['status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Refunded'); |
320 | // record the entry |
321 | $financialTrxn = CRM_Contribute_BAO_Contribution::recordFinancialAccounts($params, $trxnData); |
322 | |
323 | // note : not using the self::add method, |
324 | // the reason because it performs 'status change' related code execution for financial records |
325 | // which in 'Pending Refund' => 'Completed' is not useful, instead specific financial record updates |
326 | // are coded below i.e. just updating financial_item status to 'Paid' |
327 | if ($updateStatus) { |
328 | CRM_Core_DAO::setFieldValue('CRM_Contribute_BAO_Contribution', $contributionId, 'contribution_status_id', $completedStatusId); |
329 | } |
330 | // add financial item entry |
331 | $lineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($contributionDAO->id); |
332 | if (!empty($lineItems)) { |
333 | foreach ($lineItems as $lineItemId => $lineItemValue) { |
334 | // don't record financial item for cancelled line-item |
335 | if ($lineItemValue['qty'] == 0) { |
336 | continue; |
337 | } |
338 | $paid = $lineItemValue['line_total'] * ($financialTrxn->total_amount / $contributionDAO->total_amount); |
339 | $addFinancialEntry = [ |
340 | 'transaction_date' => $financialTrxn->trxn_date, |
341 | 'contact_id' => $contributionDAO->contact_id, |
342 | 'amount' => round($paid, 2), |
343 | 'currency' => $contributionDAO->currency, |
344 | 'status_id' => $paidStatus, |
345 | 'entity_id' => $lineItemId, |
346 | 'entity_table' => 'civicrm_line_item', |
347 | ]; |
348 | $trxnIds = ['id' => $financialTrxn->id]; |
349 | CRM_Financial_BAO_FinancialItem::create($addFinancialEntry, NULL, $trxnIds); |
350 | } |
351 | } |
352 | return $financialTrxn; |
353 | } |
354 | |
9a2dce8d |
355 | /** |
356 | * @param int $contributionId |
357 | * @param array $trxnData |
358 | * @param int $participantId |
359 | * |
360 | * @return \CRM_Core_BAO_FinancialTrxn |
361 | */ |
362 | public static function recordPayment($contributionId, $trxnData, $participantId) { |
363 | list($contributionDAO, $params) = self::getContributionAndParamsInFormatForRecordFinancialTransaction($contributionId); |
9a2dce8d |
364 | |
9a2dce8d |
365 | $trxnData['trxn_date'] = !empty($trxnData['trxn_date']) ? $trxnData['trxn_date'] : date('YmdHis'); |
366 | $params['payment_instrument_id'] = CRM_Utils_Array::value('payment_instrument_id', $trxnData, CRM_Utils_Array::value('payment_instrument_id', $params)); |
367 | |
368 | $paidStatus = CRM_Core_PseudoConstant::getKey('CRM_Financial_DAO_FinancialItem', 'status_id', 'Paid'); |
369 | $arAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contributionDAO->financial_type_id, 'Accounts Receivable Account is'); |
370 | $completedStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); |
371 | |
372 | $params['partial_payment_total'] = $contributionDAO->total_amount; |
373 | $params['partial_amount_to_pay'] = $trxnData['total_amount']; |
374 | $trxnData['net_amount'] = !empty($trxnData['net_amount']) ? $trxnData['net_amount'] : $trxnData['total_amount']; |
375 | $params['pan_truncation'] = CRM_Utils_Array::value('pan_truncation', $trxnData); |
376 | $params['card_type_id'] = CRM_Utils_Array::value('card_type_id', $trxnData); |
377 | $params['check_number'] = CRM_Utils_Array::value('check_number', $trxnData); |
378 | |
379 | // record the entry |
380 | $financialTrxn = CRM_Contribute_BAO_Contribution::recordFinancialAccounts($params, $trxnData); |
381 | $toFinancialAccount = $arAccountId; |
382 | $trxnId = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($contributionId, $contributionDAO->financial_type_id); |
383 | if (!empty($trxnId)) { |
384 | $trxnId = $trxnId['trxn_id']; |
385 | } |
386 | elseif (!empty($contributionDAO->payment_instrument_id)) { |
387 | $trxnId = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($contributionDAO->payment_instrument_id); |
388 | } |
389 | else { |
390 | $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' ")); |
391 | $queryParams = [1 => [$relationTypeId, 'Integer']]; |
392 | $trxnId = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = %1", $queryParams); |
393 | } |
394 | |
395 | // update statuses |
396 | // criteria for updates contribution total_amount == financial_trxns of partial_payments |
397 | $sql = "SELECT SUM(ft.total_amount) as sum_of_payments, SUM(ft.net_amount) as net_amount_total |
398 | FROM civicrm_financial_trxn ft |
399 | LEFT JOIN civicrm_entity_financial_trxn eft |
400 | ON (ft.id = eft.financial_trxn_id) |
401 | WHERE eft.entity_table = 'civicrm_contribution' |
402 | AND eft.entity_id = {$contributionId} |
403 | AND ft.to_financial_account_id != {$toFinancialAccount} |
404 | AND ft.status_id = {$completedStatusId} |
405 | "; |
406 | $query = CRM_Core_DAO::executeQuery($sql); |
407 | $query->fetch(); |
408 | $sumOfPayments = $query->sum_of_payments; |
409 | |
410 | // update statuses |
411 | if ($contributionDAO->total_amount == $sumOfPayments) { |
412 | // update contribution status and |
413 | // clean cancel info (if any) if prev. contribution was updated in case of 'Refunded' => 'Completed' |
414 | $contributionDAO->contribution_status_id = $completedStatusId; |
415 | $contributionDAO->cancel_date = 'null'; |
416 | $contributionDAO->cancel_reason = NULL; |
417 | $netAmount = !empty($trxnData['net_amount']) ? NULL : $trxnData['total_amount']; |
418 | $contributionDAO->net_amount = $query->net_amount_total + $netAmount; |
419 | $contributionDAO->fee_amount = $contributionDAO->total_amount - $contributionDAO->net_amount; |
420 | $contributionDAO->save(); |
421 | |
422 | //Change status of financial record too |
423 | $financialTrxn->status_id = $completedStatusId; |
424 | $financialTrxn->save(); |
425 | |
426 | // note : not using the self::add method, |
427 | // the reason because it performs 'status change' related code execution for financial records |
428 | // which in 'Partial Paid' => 'Completed' is not useful, instead specific financial record updates |
429 | // are coded below i.e. just updating financial_item status to 'Paid' |
430 | |
54ec4839 |
431 | if (!$participantId) { |
432 | $participantId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $contributionId, 'participant_id', 'contribution_id'); |
433 | } |
9a2dce8d |
434 | if ($participantId) { |
435 | // update participant status |
436 | $participantStatuses = CRM_Event_PseudoConstant::participantStatus(); |
437 | $ids = CRM_Event_BAO_Participant::getParticipantIds($contributionId); |
438 | foreach ($ids as $val) { |
439 | $participantUpdate['id'] = $val; |
440 | $participantUpdate['status_id'] = array_search('Registered', $participantStatuses); |
441 | CRM_Event_BAO_Participant::add($participantUpdate); |
442 | } |
443 | } |
444 | |
445 | // Remove this - completeOrder does it. |
446 | CRM_Contribute_BAO_Contribution::updateMembershipBasedOnCompletionOfContribution( |
447 | $contributionDAO, |
448 | $contributionId, |
449 | $trxnData['trxn_date'] |
450 | ); |
451 | |
452 | // update financial item statuses |
453 | $baseTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contributionId); |
454 | $sqlFinancialItemUpdate = " |
455 | UPDATE civicrm_financial_item fi |
456 | LEFT JOIN civicrm_entity_financial_trxn eft |
457 | ON (eft.entity_id = fi.id AND eft.entity_table = 'civicrm_financial_item') |
458 | SET status_id = {$paidStatus} |
459 | WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) |
460 | "; |
461 | CRM_Core_DAO::executeQuery($sqlFinancialItemUpdate); |
462 | } |
463 | return $financialTrxn; |
464 | } |
465 | |
466 | /** |
467 | * The recordFinancialTransactions function has capricious requirements for input parameters - load them. |
468 | * |
469 | * The function needs rework but for now we need to give it what it wants. |
470 | * |
471 | * @param int $contributionId |
472 | * |
473 | * @return array |
474 | */ |
475 | protected static function getContributionAndParamsInFormatForRecordFinancialTransaction($contributionId) { |
476 | $getInfoOf['id'] = $contributionId; |
477 | $defaults = []; |
478 | $contributionDAO = CRM_Contribute_BAO_Contribution::retrieve($getInfoOf, $defaults, CRM_Core_DAO::$_nullArray); |
479 | |
480 | // build params for recording financial trxn entry |
481 | $params['contribution'] = $contributionDAO; |
482 | $params = array_merge($defaults, $params); |
483 | $params['skipLineItem'] = TRUE; |
484 | return [$contributionDAO, $params]; |
485 | } |
486 | |
7585038a |
487 | /** |
488 | * Does this payment complete the contribution |
489 | * |
490 | * @param int $contributionID |
491 | * @param float $paymentAmount |
492 | * |
493 | * @return bool |
494 | */ |
495 | protected static function isPaymentCompletesContribution($contributionID, $paymentAmount) { |
496 | $outstandingBalance = CRM_Contribute_BAO_Contribution::getContributionBalance($contributionID); |
497 | $cmp = bccomp($paymentAmount, $outstandingBalance, 5); |
498 | return ($cmp == 0 || $cmp == 1); |
499 | } |
500 | |
0c9b306a |
501 | } |