Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 5 | | | |
bc77d7c0 TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
6a488035 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
6a488035 TO |
16 | */ |
17 | ||
18 | /** | |
95cdcc0f | 19 | * Form for thank-you / success page - 3rd step of online contribution process. |
6a488035 TO |
20 | */ |
21 | class CRM_Contribute_Form_Contribution_ThankYou extends CRM_Contribute_Form_ContributionBase { | |
22 | ||
23 | /** | |
fe482240 | 24 | * Membership price set status. |
1330f57a | 25 | * @var bool |
6a488035 TO |
26 | */ |
27 | public $_useForMember; | |
28 | ||
507a7734 SL |
29 | /** |
30 | * Tranxaaction Id of the current contribution | |
1330f57a | 31 | * @var string |
507a7734 SL |
32 | */ |
33 | public $_trxnId; | |
34 | ||
6a488035 | 35 | /** |
fe482240 | 36 | * Set variables up before form is built. |
6a488035 TO |
37 | */ |
38 | public function preProcess() { | |
39 | parent::preProcess(); | |
40 | ||
353ffa53 | 41 | $this->_params = $this->get('params'); |
6a488035 | 42 | $this->_lineItem = $this->get('lineItem'); |
376b971e | 43 | $this->_useForMember = $this->get('useForMember'); |
353ffa53 | 44 | $is_deductible = $this->get('is_deductible'); |
6a488035 TO |
45 | $this->assign('is_deductible', $is_deductible); |
46 | $this->assign('thankyou_title', CRM_Utils_Array::value('thankyou_title', $this->_values)); | |
47 | $this->assign('thankyou_text', CRM_Utils_Array::value('thankyou_text', $this->_values)); | |
48 | $this->assign('thankyou_footer', CRM_Utils_Array::value('thankyou_footer', $this->_values)); | |
49 | $this->assign('max_reminders', CRM_Utils_Array::value('max_reminders', $this->_values)); | |
50 | $this->assign('initial_reminder_day', CRM_Utils_Array::value('initial_reminder_day', $this->_values)); | |
7e2e2551 | 51 | $this->setTitle(CRM_Utils_Array::value('thankyou_title', $this->_values)); |
f4aaa82a | 52 | // Make the contributionPageID available to the template |
6a488035 TO |
53 | $this->assign('contributionPageID', $this->_id); |
54 | $this->assign('isShare', $this->_values['is_share']); | |
55 | ||
56 | $this->_params['is_pay_later'] = $this->get('is_pay_later'); | |
57 | $this->assign('is_pay_later', $this->_params['is_pay_later']); | |
58 | if ($this->_params['is_pay_later']) { | |
59 | $this->assign('pay_later_receipt', $this->_values['pay_later_receipt']); | |
60 | } | |
de5ce535 | 61 | $this->assign('is_for_organization', CRM_Utils_Array::value('is_for_organization', $this->_params)); |
6a488035 TO |
62 | } |
63 | ||
64 | /** | |
100fef9d | 65 | * Overwrite action, since we are only showing elements in frozen mode |
6a488035 TO |
66 | * no help display needed |
67 | * | |
68 | * @return int | |
6a488035 | 69 | */ |
00be9182 | 70 | public function getAction() { |
6a488035 TO |
71 | if ($this->_action & CRM_Core_Action::PREVIEW) { |
72 | return CRM_Core_Action::VIEW | CRM_Core_Action::PREVIEW; | |
73 | } | |
74 | else { | |
75 | return CRM_Core_Action::VIEW; | |
76 | } | |
77 | } | |
78 | ||
79 | /** | |
fe482240 | 80 | * Build the form object. |
6a488035 TO |
81 | */ |
82 | public function buildQuickForm() { | |
8684f612 | 83 | // FIXME: Some of this code is identical to Confirm.php and should be broken out into a shared function |
6a488035 | 84 | $this->assignToTemplate(); |
2f44fc96 | 85 | $this->_ccid = $this->get('ccid'); |
353ffa53 TO |
86 | $productID = $this->get('productID'); |
87 | $option = $this->get('option'); | |
6a488035 TO |
88 | $membershipTypeID = $this->get('membershipTypeID'); |
89 | $this->assign('receiptFromEmail', CRM_Utils_Array::value('receipt_from_email', $this->_values)); | |
90 | ||
91 | if ($productID) { | |
92 | CRM_Contribute_BAO_Premium::buildPremiumBlock($this, $this->_id, FALSE, $productID, $option); | |
93 | } | |
6a488035 | 94 | |
e77a5a36 | 95 | $params = $this->_params; |
ec5e7bcf | 96 | $invoicing = CRM_Invoicing_Utils::isInvoicingEnabled(); |
147b56dc MW |
97 | // Make a copy of line items array to use for display only |
98 | $tplLineItems = $this->_lineItem; | |
03b412ae PB |
99 | if ($invoicing) { |
100 | $getTaxDetails = FALSE; | |
147b56dc MW |
101 | foreach ($this->_lineItem as $key => $value) { |
102 | foreach ($value as $k => $v) { | |
03b412ae PB |
103 | if (isset($v['tax_rate'])) { |
104 | if ($v['tax_rate'] != '') { | |
105 | $getTaxDetails = TRUE; | |
147b56dc MW |
106 | // Cast to float to display without trailing zero decimals |
107 | $tplLineItems[$key][$k]['tax_rate'] = (float) $v['tax_rate']; | |
03b412ae PB |
108 | } |
109 | } | |
110 | } | |
111 | } | |
112 | $this->assign('getTaxDetails', $getTaxDetails); | |
ec5e7bcf | 113 | $this->assign('taxTerm', CRM_Invoicing_Utils::getTaxTerm()); |
03b412ae PB |
114 | $this->assign('totalTaxAmount', $params['tax_amount']); |
115 | } | |
147b56dc MW |
116 | |
117 | if ($this->_priceSetId && !CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) { | |
118 | $this->assign('lineItem', $tplLineItems); | |
119 | } | |
120 | else { | |
121 | if (is_array($membershipTypeID)) { | |
122 | $membershipTypeID = current($membershipTypeID); | |
123 | } | |
124 | $this->assign('is_quick_config', 1); | |
125 | $this->_params['is_quick_config'] = 1; | |
126 | } | |
127 | $this->assign('priceSetID', $this->_priceSetId); | |
128 | $this->assign('useForMember', $this->get('useForMember')); | |
129 | ||
4779abb3 | 130 | if (!empty($this->_values['honoree_profile_id']) && !empty($params['soft_credit_type_id'])) { |
133e2c99 | 131 | $softCreditTypes = CRM_Core_OptionGroup::values("soft_credit_type", FALSE); |
132 | ||
133e2c99 | 133 | $this->assign('soft_credit_type', $softCreditTypes[$params['soft_credit_type_id']]); |
4779abb3 | 134 | CRM_Contribute_BAO_ContributionSoft::formatHonoreeProfileFields($this, $params['honor']); |
6a488035 | 135 | |
be2fb01f | 136 | $fieldTypes = ['Contact']; |
4779abb3 | 137 | $fieldTypes[] = CRM_Core_BAO_UFGroup::getContactType($this->_values['honoree_profile_id']); |
138 | $this->buildCustom($this->_values['honoree_profile_id'], 'honoreeProfileFields', TRUE, 'honor', $fieldTypes); | |
6a488035 TO |
139 | } |
140 | ||
141 | $qParams = "reset=1&id={$this->_id}"; | |
142 | //pcp elements | |
143 | if ($this->_pcpId) { | |
144 | $qParams .= "&pcpId={$this->_pcpId}"; | |
145 | $this->assign('pcpBlock', TRUE); | |
be2fb01f | 146 | foreach ([ |
1330f57a SL |
147 | 'pcp_display_in_roll', |
148 | 'pcp_is_anonymous', | |
149 | 'pcp_roll_nickname', | |
150 | 'pcp_personal_note', | |
151 | ] as $val) { | |
a7488080 | 152 | if (!empty($this->_params[$val])) { |
6a488035 TO |
153 | $this->assign($val, $this->_params[$val]); |
154 | } | |
155 | } | |
156 | } | |
157 | ||
481a74f4 | 158 | $this->assign('qParams', $qParams); |
6a488035 TO |
159 | |
160 | if ($membershipTypeID) { | |
353ffa53 | 161 | $transactionID = $this->get('membership_trx_id'); |
6a488035 | 162 | $membershipAmount = $this->get('membership_amount'); |
353ffa53 | 163 | $renewalMode = $this->get('renewal_mode'); |
6a488035 TO |
164 | $this->assign('membership_trx_id', $transactionID); |
165 | $this->assign('membership_amount', $membershipAmount); | |
166 | $this->assign('renewal_mode', $renewalMode); | |
167 | ||
42e3a033 | 168 | $this->buildMembershipBlock( |
5b757295 | 169 | $this->_membershipContactID, |
6a488035 | 170 | $membershipTypeID, |
5b757295 | 171 | NULL |
6a488035 | 172 | ); |
9cc96227 | 173 | |
174 | if (!empty($params['auto_renew'])) { | |
175 | $this->assign('auto_renew', TRUE); | |
176 | } | |
6a488035 TO |
177 | } |
178 | ||
179 | $this->_separateMembershipPayment = $this->get('separateMembershipPayment'); | |
180 | $this->assign("is_separate_payment", $this->_separateMembershipPayment); | |
181 | ||
2f44fc96 | 182 | if (empty($this->_ccid)) { |
183 | $this->buildCustom($this->_values['custom_pre_id'], 'customPre', TRUE); | |
184 | $this->buildCustom($this->_values['custom_post_id'], 'customPost', TRUE); | |
185 | } | |
2454bb63 | 186 | if (!empty($this->_values['onbehalf_profile_id']) && |
187 | !empty($params['onbehalf']) && | |
188 | ($this->_values['is_for_organization'] == 2 || | |
189 | !empty($params['is_for_organization']) | |
2f44fc96 | 190 | ) && empty($this->_ccid) |
2454bb63 | 191 | ) { |
be2fb01f | 192 | $fieldTypes = ['Contact', 'Organization']; |
6a488035 | 193 | $contactSubType = CRM_Contact_BAO_ContactType::subTypes('Organization'); |
353ffa53 | 194 | $fieldTypes = array_merge($fieldTypes, $contactSubType); |
6a488035 | 195 | if (is_array($this->_membershipBlock) && !empty($this->_membershipBlock)) { |
be2fb01f | 196 | $fieldTypes = array_merge($fieldTypes, ['Membership']); |
6a488035 TO |
197 | } |
198 | else { | |
be2fb01f | 199 | $fieldTypes = array_merge($fieldTypes, ['Contribution']); |
6a488035 TO |
200 | } |
201 | ||
4779abb3 | 202 | $this->buildCustom($this->_values['onbehalf_profile_id'], 'onbehalfProfile', TRUE, 'onbehalf', $fieldTypes); |
6a488035 TO |
203 | } |
204 | ||
9c1bc317 | 205 | $this->_trxnId = $this->_params['trxn_id'] ?? NULL; |
507a7734 SL |
206 | |
207 | $this->assign('trxn_id', $this->_trxnId); | |
208 | ||
6a488035 TO |
209 | $this->assign('receive_date', |
210 | CRM_Utils_Date::mysqlToIso(CRM_Utils_Array::value('receive_date', $this->_params)) | |
211 | ); | |
212 | ||
be2fb01f CW |
213 | $defaults = []; |
214 | $fields = []; | |
6a488035 | 215 | foreach ($this->_fields as $name => $dontCare) { |
133e2c99 | 216 | if ($name != 'onbehalf' || $name != 'honor') { |
6a488035 TO |
217 | $fields[$name] = 1; |
218 | } | |
219 | } | |
220 | $fields['state_province'] = $fields['country'] = $fields['email'] = 1; | |
221 | $contact = $this->_params = $this->controller->exportValues('Main'); | |
222 | ||
223 | foreach ($fields as $name => $dontCare) { | |
133e2c99 | 224 | if (isset($contact[$name])) { |
6a488035 TO |
225 | $defaults[$name] = $contact[$name]; |
226 | if (substr($name, 0, 7) == 'custom_') { | |
227 | $timeField = "{$name}_time"; | |
228 | if (isset($contact[$timeField])) { | |
229 | $defaults[$timeField] = $contact[$timeField]; | |
230 | } | |
231 | } | |
be2fb01f | 232 | elseif (in_array($name, [ |
1330f57a SL |
233 | 'addressee', |
234 | 'email_greeting', | |
235 | 'postal_greeting', | |
236 | ]) && !empty($contact[$name . '_custom']) | |
353ffa53 | 237 | ) { |
6a488035 TO |
238 | $defaults[$name . '_custom'] = $contact[$name . '_custom']; |
239 | } | |
240 | } | |
241 | } | |
242 | ||
6a488035 | 243 | $this->_submitValues = array_merge($this->_submitValues, $defaults); |
6cc679d2 | 244 | |
6a488035 | 245 | $this->setDefaults($defaults); |
eea16664 | 246 | |
6a488035 TO |
247 | $values['entity_id'] = $this->_id; |
248 | $values['entity_table'] = 'civicrm_contribution_page'; | |
249 | ||
250 | CRM_Friend_BAO_Friend::retrieve($values, $data); | |
251 | $tellAFriend = FALSE; | |
252 | if ($this->_pcpId) { | |
253 | if ($this->_pcpBlock['is_tellfriend_enabled']) { | |
254 | $this->assign('friendText', ts('Tell a Friend')); | |
255 | $subUrl = "eid={$this->_pcpId}&blockId={$this->_pcpBlock['id']}&pcomponent=pcp"; | |
256 | $tellAFriend = TRUE; | |
257 | } | |
258 | } | |
a7488080 | 259 | elseif (!empty($data['is_active'])) { |
6a488035 TO |
260 | $friendText = $data['title']; |
261 | $this->assign('friendText', $friendText); | |
262 | $subUrl = "eid={$this->_id}&pcomponent=contribute"; | |
263 | $tellAFriend = TRUE; | |
264 | } | |
265 | ||
266 | if ($tellAFriend) { | |
267 | if ($this->_action & CRM_Core_Action::PREVIEW) { | |
268 | $url = CRM_Utils_System::url("civicrm/friend", | |
269 | "reset=1&action=preview&{$subUrl}" | |
270 | ); | |
271 | } | |
272 | else { | |
273 | $url = CRM_Utils_System::url("civicrm/friend", | |
274 | "reset=1&{$subUrl}" | |
275 | ); | |
276 | } | |
277 | $this->assign('friendURL', $url); | |
278 | } | |
279 | ||
b2bfcb28 | 280 | $this->assign('isPendingOutcome', $this->isPendingOutcome($params)); |
281 | $this->freeze(); | |
282 | ||
283 | // can we blow away the session now to prevent hackery | |
284 | // CRM-9491 | |
285 | $this->controller->reset(); | |
286 | } | |
287 | ||
4b238552 MW |
288 | /** |
289 | * Build Membership Block in Contribution Pages. | |
290 | * @todo this was shared on CRM_Contribute_Form_ContributionBase but we are refactoring and simplifying for each | |
291 | * step (main/confirm/thankyou) | |
292 | * | |
293 | * @param int $cid | |
294 | * Contact checked for having a current membership for a particular membership. | |
4b238552 MW |
295 | * @param int|array $selectedMembershipTypeID |
296 | * Selected membership id. | |
4b238552 MW |
297 | * @param null $isTest |
298 | * | |
299 | * @return bool | |
300 | * Is this a separate membership payment | |
301 | * | |
302 | * @throws \CiviCRM_API3_Exception | |
303 | * @throws \CRM_Core_Exception | |
304 | */ | |
e622655c | 305 | private function buildMembershipBlock($cid, $selectedMembershipTypeID = NULL, $isTest = NULL) { |
4b238552 MW |
306 | $separateMembershipPayment = FALSE; |
307 | if ($this->_membershipBlock) { | |
308 | $this->_currentMemberships = []; | |
309 | ||
310 | $membershipTypeIds = $membershipTypes = $radio = $radioOptAttrs = []; | |
311 | $membershipPriceset = (!empty($this->_priceSetId) && $this->_useForMember); | |
312 | ||
4b238552 MW |
313 | $autoRenewMembershipTypeOptions = []; |
314 | ||
315 | $separateMembershipPayment = $this->_membershipBlock['is_separate_payment'] ?? NULL; | |
316 | ||
317 | if ($membershipPriceset) { | |
318 | foreach ($this->_priceSet['fields'] as $pField) { | |
319 | if (empty($pField['options'])) { | |
320 | continue; | |
321 | } | |
322 | foreach ($pField['options'] as $opId => $opValues) { | |
323 | if (empty($opValues['membership_type_id'])) { | |
324 | continue; | |
325 | } | |
326 | $membershipTypeIds[$opValues['membership_type_id']] = $opValues['membership_type_id']; | |
327 | } | |
328 | } | |
329 | } | |
330 | elseif (!empty($this->_membershipBlock['membership_types'])) { | |
331 | $membershipTypeIds = explode(',', $this->_membershipBlock['membership_types']); | |
332 | } | |
333 | ||
334 | if (!empty($membershipTypeIds)) { | |
335 | //set status message if wrong membershipType is included in membershipBlock | |
336 | if (isset($this->_mid) && !$membershipPriceset) { | |
337 | $membershipTypeID = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', | |
338 | $this->_mid, | |
339 | 'membership_type_id' | |
340 | ); | |
341 | if (!in_array($membershipTypeID, $membershipTypeIds)) { | |
342 | CRM_Core_Session::setStatus(ts("Oops. The membership you're trying to renew appears to be invalid. Contact your site administrator if you need assistance. If you continue, you will be issued a new membership."), ts('Invalid Membership'), 'error'); | |
343 | } | |
344 | } | |
345 | ||
346 | $membershipTypeValues = CRM_Member_BAO_Membership::buildMembershipTypeValues($this, $membershipTypeIds); | |
347 | $this->_membershipTypeValues = $membershipTypeValues; | |
348 | $endDate = NULL; | |
349 | ||
350 | // Check if we support auto-renew on this contribution page | |
351 | // FIXME: If any of the payment processors do NOT support recurring you cannot setup an | |
352 | // auto-renew payment even if that processor is not selected. | |
353 | $allowAutoRenewOpt = TRUE; | |
354 | if (is_array($this->_paymentProcessors)) { | |
355 | foreach ($this->_paymentProcessors as $id => $val) { | |
356 | if ($id && !$val['is_recur']) { | |
357 | $allowAutoRenewOpt = FALSE; | |
358 | } | |
359 | } | |
360 | } | |
361 | foreach ($membershipTypeIds as $value) { | |
362 | $memType = $membershipTypeValues[$value]; | |
363 | if ($selectedMembershipTypeID != NULL) { | |
364 | if ($memType['id'] == $selectedMembershipTypeID) { | |
365 | $this->assign('minimum_fee', $memType['minimum_fee'] ?? NULL); | |
366 | $this->assign('membership_name', $memType['name']); | |
4b238552 MW |
367 | $membershipTypes[] = $memType; |
368 | } | |
369 | } | |
370 | elseif ($memType['is_active']) { | |
371 | ||
372 | if ($allowAutoRenewOpt) { | |
373 | $javascriptMethod = ['onclick' => "return showHideAutoRenew( this.value );"]; | |
374 | $isAvailableAutoRenew = $this->_membershipBlock['auto_renew'][$value] ?? 1; | |
375 | $autoRenewMembershipTypeOptions["autoRenewMembershipType_{$value}"] = (int) $memType['auto_renew'] * $isAvailableAutoRenew; | |
376 | $allowAutoRenewMembership = TRUE; | |
377 | } | |
378 | else { | |
379 | $javascriptMethod = NULL; | |
380 | $autoRenewMembershipTypeOptions["autoRenewMembershipType_{$value}"] = 0; | |
381 | } | |
382 | ||
383 | //add membership type. | |
384 | $radio[$memType['id']] = NULL; | |
385 | $radioOptAttrs[$memType['id']] = $javascriptMethod; | |
386 | if ($cid) { | |
387 | $membership = new CRM_Member_DAO_Membership(); | |
388 | $membership->contact_id = $cid; | |
389 | $membership->membership_type_id = $memType['id']; | |
390 | ||
391 | //show current membership, skip pending and cancelled membership records, | |
392 | //because we take first membership record id for renewal | |
393 | $membership->whereAdd('status_id != 5 AND status_id !=6'); | |
394 | ||
395 | if (!is_null($isTest)) { | |
396 | $membership->is_test = $isTest; | |
397 | } | |
398 | ||
399 | //CRM-4297 | |
400 | $membership->orderBy('end_date DESC'); | |
401 | ||
402 | if ($membership->find(TRUE)) { | |
403 | if (!$membership->end_date) { | |
404 | unset($radio[$memType['id']]); | |
405 | unset($radioOptAttrs[$memType['id']]); | |
406 | $this->assign('islifetime', TRUE); | |
407 | continue; | |
408 | } | |
409 | $this->assign('renewal_mode', TRUE); | |
410 | $this->_currentMemberships[$membership->membership_type_id] = $membership->membership_type_id; | |
411 | $memType['current_membership'] = $membership->end_date; | |
412 | if (!$endDate) { | |
413 | $endDate = $memType['current_membership']; | |
414 | $this->_defaultMemTypeId = $memType['id']; | |
415 | } | |
416 | if ($memType['current_membership'] < $endDate) { | |
417 | $endDate = $memType['current_membership']; | |
418 | $this->_defaultMemTypeId = $memType['id']; | |
419 | } | |
420 | } | |
421 | } | |
422 | $membershipTypes[] = $memType; | |
423 | } | |
424 | } | |
425 | } | |
426 | ||
427 | $this->assign('membershipBlock', $this->_membershipBlock); | |
e622655c | 428 | $this->assign('showRadio', FALSE); |
4b238552 | 429 | $this->assign('membershipTypes', $membershipTypes); |
4b238552 MW |
430 | $this->assign('autoRenewMembershipTypeOptions', json_encode($autoRenewMembershipTypeOptions)); |
431 | //give preference to user submitted auto_renew value. | |
432 | $takeUserSubmittedAutoRenew = (!empty($_POST) || $this->isSubmitted()); | |
433 | $this->assign('takeUserSubmittedAutoRenew', $takeUserSubmittedAutoRenew); | |
434 | ||
435 | // Assign autorenew option (0:hide,1:optional,2:required) so we can use it in confirmation etc. | |
436 | $autoRenewOption = CRM_Price_BAO_PriceSet::checkAutoRenewForPriceSet($this->_priceSetId); | |
437 | //$selectedMembershipTypeID is retrieved as an array for membership priceset if multiple | |
438 | //options for different organisation is selected on the contribution page. | |
439 | if (is_numeric($selectedMembershipTypeID) && isset($membershipTypeValues[$selectedMembershipTypeID]['auto_renew'])) { | |
440 | $this->assign('autoRenewOption', $membershipTypeValues[$selectedMembershipTypeID]['auto_renew']); | |
441 | } | |
442 | else { | |
443 | $this->assign('autoRenewOption', $autoRenewOption); | |
444 | } | |
4b238552 MW |
445 | } |
446 | ||
447 | return $separateMembershipPayment; | |
448 | } | |
449 | ||
b2bfcb28 | 450 | /** |
451 | * Is the outcome of this contribution still pending. | |
452 | * | |
453 | * @param array $params | |
454 | * | |
455 | * @return bool | |
456 | */ | |
457 | protected function isPendingOutcome(array $params): bool { | |
458 | if (empty($params['payment_processor_id'])) { | |
459 | return FALSE; | |
460 | } | |
7a666802 | 461 | try { |
462 | // A payment notification update could have come in at any time. Check at the last minute. | |
b2bfcb28 | 463 | civicrm_api3('Contribution', 'getvalue', [ |
6b409353 | 464 | 'id' => $params['contributionID'] ?? NULL, |
b2bfcb28 | 465 | 'contribution_status_id' => 'Pending', |
466 | 'is_test' => '', | |
467 | 'return' => 'id', | |
6b409353 | 468 | 'invoice_id' => $params['invoiceID'] ?? NULL, |
be2fb01f | 469 | ]); |
b2bfcb28 | 470 | return TRUE; |
7a666802 | 471 | } |
472 | catch (CiviCRM_API3_Exception $e) { | |
b2bfcb28 | 473 | return FALSE; |
7a666802 | 474 | } |
6a488035 | 475 | } |
96025800 | 476 | |
6a488035 | 477 | } |