Merge pull request #22886 from demeritcowboy/contributionview-notice3
[civicrm-core.git] / ext / eventcart / CRM / Event / Cart / Form / Checkout / Payment.php
CommitLineData
6a488035 1<?php
0cf587a7
EM
2
3/**
4 * Class CRM_Event_Cart_Form_Checkout_Payment
5 */
6a488035
TO
6class CRM_Event_Cart_Form_Checkout_Payment extends CRM_Event_Cart_Form_Cart {
7 public $all_participants;
8 public $financial_type_id;
9 public $description;
10 public $line_items;
be2fb01f 11 public $_fields = [];
6a488035
TO
12 public $_paymentProcessor;
13 public $total;
14 public $sub_total;
15 public $payment_required = TRUE;
16 public $payer_contact_id;
17 public $is_pay_later = FALSE;
18 public $pay_later_receipt;
19
8d3963e0
MW
20 /**
21 * @var array
22 */
23 protected $_values = [];
24
0cf587a7 25 /**
1e3401f3 26 * Register a participant.
27 *
c490a46a 28 * @param array $params
1e3401f3 29 * @param CRM_Event_BAO_Participant $participant
30 * @param CRM_Event_BAO_Event $event
0cf587a7
EM
31 *
32 * @return mixed
bec0826a 33 * @throws \CiviCRM_API3_Exception
0cf587a7 34 */
00be9182 35 public function registerParticipant($params, &$participant, $event) {
be2fb01f 36 $participantParams = [
6a488035
TO
37 'id' => $participant->id,
38 'event_id' => $event->id,
bec0826a 39 'register_date' => date('YmdHis'),
6a488035 40 'source' => CRM_Utils_Array::value('participant_source', $params, $this->description),
6a488035
TO
41 'is_pay_later' => $this->is_pay_later,
42 'fee_amount' => CRM_Utils_Array::value('amount', $params, 0),
6b409353 43 'fee_currency' => $params['currencyID'] ?? NULL,
be2fb01f 44 ];
6a488035
TO
45
46 if ($participant->must_wait) {
47 $participant_status = 'On waitlist';
48 }
de6c59ca 49 elseif (!empty($params['is_pay_later'])) {
6a488035
TO
50 $participant_status = 'Pending from pay later';
51 }
52 else {
53 $participant_status = 'Registered';
54 }
bec0826a
MW
55 $participantParams['status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Event_BAO_Participant', 'status_id', $participant_status);
56 $participantParams['participant_status'] = CRM_Core_PseudoConstant::getLabel('CRM_Event_BAO_Participant', 'status_id', $participantParams['status_id']);
6a488035
TO
57
58 $this->assign('isOnWaitlist', $participant->must_wait);
59
bec0826a 60 $participantParams['is_test'] = 0;
6a488035
TO
61 if ($this->_action & CRM_Core_Action::PREVIEW || CRM_Utils_Array::value('mode', $params) == 'test') {
62 $participantParams['is_test'] = 1;
63 }
6a488035 64
bec0826a 65 $transaction = new CRM_Core_Transaction();
6a488035
TO
66
67 $participant->copyValues($participantParams);
68 $participant->save();
69
a7488080 70 if (!empty($params['contributionID'])) {
f55a8ac8 71 $participantPaymentParams = [
6a488035
TO
72 'participant_id' => $participant->id,
73 'contribution_id' => $params['contributionID'],
be2fb01f 74 ];
f55a8ac8 75 civicrm_api3('ParticipantPayment', 'create', $participantPaymentParams);
6a488035
TO
76 }
77
78 $transaction->commit();
79
be2fb01f 80 $event_values = [];
6a488035
TO
81 CRM_Core_DAO::storeValues($event, $event_values);
82
be2fb01f 83 $location = [];
6a488035 84 if (CRM_Utils_Array::value('is_show_location', $event_values) == 1) {
be2fb01f 85 $locationParams = [
6a488035
TO
86 'entity_id' => $participant->event_id,
87 'entity_table' => 'civicrm_event',
be2fb01f 88 ];
6a488035
TO
89 $location = CRM_Core_BAO_Location::getValues($locationParams, TRUE);
90 CRM_Core_BAO_Address::fixAddress($location['address'][1]);
91 }
92
93 list($pre_id, $post_id) = CRM_Event_Cart_Form_MerParticipant::get_profile_groups($participant->event_id);
be2fb01f 94 $payer_values = [
6a488035
TO
95 'email' => '',
96 'name' => '',
be2fb01f 97 ];
6a488035
TO
98 if ($this->payer_contact_id) {
99 $payer_contact_details = CRM_Contact_BAO_Contact::getContactDetails($this->payer_contact_id);
be2fb01f 100 $payer_values = [
6a488035
TO
101 'email' => $payer_contact_details[1],
102 'name' => $payer_contact_details[0],
be2fb01f 103 ];
6a488035 104 }
be2fb01f
CW
105 $values = [
106 'params' => [$participant->id => $participantParams],
6a488035
TO
107 'event' => $event_values,
108 'location' => $location,
109 'custom_pre_id' => $pre_id,
110 'custom_post_id' => $post_id,
111 'payer' => $payer_values,
be2fb01f 112 ];
6a488035
TO
113 CRM_Event_BAO_Event::sendMail($participant->contact_id, $values, $participant->id);
114
115 return $participant;
116 }
117
1e3401f3 118 /**
119 * Build payment fields.
120 */
00be9182 121 public function buildPaymentFields() {
6a488035
TO
122 $payment_processor_id = NULL;
123 $can_pay_later = TRUE;
124 $pay_later_text = "";
125 $this->pay_later_receipt = "";
126 foreach ($this->cart->get_main_events_in_carts() as $event_in_cart) {
bec0826a 127 if ($payment_processor_id === NULL && $event_in_cart->event->payment_processor !== NULL) {
6a488035 128 $payment_processor_id = $event_in_cart->event->payment_processor;
2b8d92de 129 $this->financial_type_id = $event_in_cart->event->financial_type_id;
8d3963e0 130 $this->_values['currency'] = $event_in_cart->event->currency;
6a488035
TO
131 }
132 else {
bec0826a 133 if ($event_in_cart->event->payment_processor !== NULL && $event_in_cart->event->payment_processor !== $payment_processor_id) {
6a488035
TO
134 CRM_Core_Error::statusBounce(ts('When registering for multiple events all events must use the same payment processor. '));
135 }
136 }
bec0826a 137 if ($payment_processor_id) {
6a488035
TO
138 $can_pay_later = FALSE;
139 }
bec0826a 140 elseif ($event_in_cart->event->is_pay_later) {
6a488035
TO
141 //XXX
142 $pay_later_text = $event_in_cart->event->pay_later_text;
143 $this->pay_later_receipt = $event_in_cart->event->pay_later_receipt;
144 }
bec0826a
MW
145 else {
146 CRM_Core_Error::statusBounce(ts('A payment processor must be selected for this event registration page, or the event must be configured to give users the option to pay later (contact the site administrator for assistance).'));
147 }
6a488035
TO
148 }
149
8d3963e0
MW
150 if ($can_pay_later) {
151 $this->addElement('checkbox', 'is_pay_later', $pay_later_text);
152 $this->addElement('checkbox', 'payment_completed', ts('Payment Completed'));
6a488035
TO
153 $this->assign('pay_later_instructions', $this->pay_later_receipt);
154 }
8d3963e0
MW
155 else {
156 $this->_paymentProcessorIDs = [$payment_processor_id];
157 $this->assignPaymentProcessor(FALSE);
158 CRM_Core_Payment_Form::buildPaymentForm($this, $this->_paymentProcessor, FALSE, FALSE);
159 }
160 $this->assign('currency', $this->getCurrency());
6a488035
TO
161 }
162
1e3401f3 163 /**
164 * Build QuickForm.
165 */
00be9182 166 public function buildQuickForm() {
be2fb01f 167 $this->line_items = [];
353ffa53 168 $this->sub_total = 0;
6a488035
TO
169 $this->_price_values = $this->getValuesForPage('ParticipantsAndPrices');
170
171 // iterate over each event in cart
172 foreach ($this->cart->get_main_events_in_carts() as $event_in_cart) {
173 $this->process_event_line_item($event_in_cart);
174 foreach ($this->cart->get_events_in_carts_by_main_event_id($event_in_cart->event_id) as $subevent) {
175 $this->process_event_line_item($subevent, 'subevent');
176 }
177 }
178
179 $this->total = $this->sub_total;
180 $this->payment_required = ($this->total > 0);
181 $this->assign('payment_required', $this->payment_required);
182 $this->assign('line_items', $this->line_items);
183 $this->assign('sub_total', $this->sub_total);
184 $this->assign('total', $this->total);
be2fb01f
CW
185 $buttons = [];
186 $buttons[] = [
f212d37d 187 'name' => ts('Go Back'),
6a488035 188 'type' => 'back',
be2fb01f
CW
189 ];
190 $buttons[] = [
6a488035 191 'isDefault' => TRUE,
f212d37d 192 'name' => ts('Complete Transaction'),
6a488035 193 'type' => 'next',
be2fb01f 194 ];
6a488035
TO
195
196 if ($this->total) {
6a4ae9b1 197 $this->add('text', 'billing_contact_email', ts('Billing Email'), '', TRUE);
6a488035
TO
198 $this->assign('collect_billing_email', TRUE);
199 }
6a488035 200
6a488035 201 $this->addButtons($buttons);
be2fb01f 202 $this->addFormRule(['CRM_Event_Cart_Form_Checkout_Payment', 'formRule'], $this);
6a488035
TO
203
204 if ($this->payment_required) {
205 $this->buildPaymentFields();
206 }
207 }
208
0cf587a7 209 /**
1e3401f3 210 * Process line item for event.
211 *
212 * @param bool $event_in_cart
213 * @param string $class
0cf587a7 214 */
00be9182 215 public function process_event_line_item(&$event_in_cart, $class = NULL) {
353ffa53 216 $cost = 0;
9da8dc8c 217 $price_set_id = CRM_Price_BAO_PriceSet::getFor("civicrm_event", $event_in_cart->event_id);
6a488035
TO
218 $amount_level = NULL;
219 if ($price_set_id) {
be2fb01f 220 $event_price_values = [];
6a488035
TO
221 foreach ($this->_price_values as $key => $value) {
222 if (preg_match("/event_{$event_in_cart->event_id}_(price.*)/", $key, $matches)) {
223 $event_price_values[$matches[1]] = $value;
224 }
225 }
353ffa53
TO
226 $price_sets = CRM_Price_BAO_PriceSet::getSetDetail($price_set_id, TRUE);
227 $price_set = $price_sets[$price_set_id];
be2fb01f 228 $price_set_amount = [];
9da8dc8c 229 CRM_Price_BAO_PriceSet::processAmount($price_set['fields'], $event_price_values, $price_set_amount);
bec0826a
MW
230 if (!empty($this->_price_values['discountcode'])) {
231 $ret = $this->apply_discount($this->_price_values['discountcode'], $price_set_amount, $cost, $event_in_cart->event_id);
02052b9b 232 if ($ret == FALSE) {
233 $cost = $event_price_values['amount'];
1e3401f3 234 }
e90198f2 235 }
236 else {
02052b9b 237 $cost = $event_price_values['amount'];
1e3401f3 238 }
c039f658 239 // @todo - stop setting amount level in this function & call the CRM_Price_BAO_PriceSet::getAmountLevel
240 // function to get correct amount level consistently. Remove setting of the amount level in
241 // CRM_Price_BAO_PriceSet::processAmount. Extend the unit tests in CRM_Price_BAO_PriceSetTest
242 // to cover all variants.
353ffa53 243 $amount_level = $event_price_values['amount_level'];
2b8d92de 244 $price_details[$price_set_id] = $price_set_amount;
6a488035
TO
245 }
246
247 // iterate over each participant in event
248 foreach ($event_in_cart->participants as & $participant) {
249 $participant->cost = $cost;
250 $participant->fee_level = $amount_level;
2b8d92de 251 $participant->price_details = $price_details;
6a488035
TO
252 }
253
254 $this->add_line_item($event_in_cart, $class);
255 }
256
0cf587a7 257 /**
1e3401f3 258 * Add line item.
259 *
260 * @param CRM_Event_BAO_Event $event_in_cart
261 * @param string $class
0cf587a7 262 */
00be9182 263 public function add_line_item($event_in_cart, $class = NULL) {
6a488035
TO
264 $amount = 0;
265 $cost = 0;
be2fb01f 266 $not_waiting_participants = [];
6a488035
TO
267 foreach ($event_in_cart->not_waiting_participants() as $participant) {
268 $amount += $participant->cost;
269 $cost = max($cost, $participant->cost);
be2fb01f 270 $not_waiting_participants[] = [
6a488035 271 'display_name' => CRM_Contact_BAO_Contact::displayName($participant->contact_id),
be2fb01f 272 ];
6a488035 273 }
be2fb01f 274 $waiting_participants = [];
6a488035 275 foreach ($event_in_cart->waiting_participants() as $participant) {
be2fb01f 276 $waiting_participants[] = [
6a488035 277 'display_name' => CRM_Contact_BAO_Contact::displayName($participant->contact_id),
be2fb01f 278 ];
6a488035 279 }
be2fb01f 280 $this->line_items[] = [
6a488035
TO
281 'amount' => $amount,
282 'cost' => $cost,
283 'event' => $event_in_cart->event,
284 'participants' => $not_waiting_participants,
285 'num_participants' => count($not_waiting_participants),
286 'num_waiting_participants' => count($waiting_participants),
287 'waiting_participants' => $waiting_participants,
288 'class' => $class,
be2fb01f 289 ];
6a488035
TO
290
291 $this->sub_total += $amount;
292 }
293
0cf587a7 294 /**
bf48aa29 295 * Send email receipt.
296 *
297 * @param array $events_in_cart
c490a46a 298 * @param array $params
0cf587a7 299 */
00be9182 300 public function emailReceipt($events_in_cart, $params) {
353ffa53
TO
301 $contact_details = CRM_Contact_BAO_Contact::getContactDetails($this->payer_contact_id);
302 $state_province = new CRM_Core_DAO_StateProvince();
6a488035
TO
303 $state_province->id = $params["billing_state_province_id-{$this->_bltID}"];
304 $state_province->find();
305 $state_province->fetch();
306 $country = new CRM_Core_DAO_Country();
307 $country->id = $params["billing_country_id-{$this->_bltID}"];
308 $country->find();
309 $country->fetch();
310 foreach ($this->line_items as & $line_item) {
be2fb01f 311 $location_params = ['entity_id' => $line_item['event']->id, 'entity_table' => 'civicrm_event'];
6a488035
TO
312 $line_item['location'] = CRM_Core_BAO_Location::getValues($location_params, TRUE);
313 CRM_Core_BAO_Address::fixAddress($line_item['location']['address'][1]);
314 }
be2fb01f 315 $send_template_params = [
6a488035
TO
316 'table' => 'civicrm_msg_template',
317 'contactId' => $this->payer_contact_id,
3dacb61d 318 'from' => current(CRM_Core_BAO_Domain::getNameAndEmail(TRUE, TRUE)),
6a488035
TO
319 'groupName' => 'msg_tpl_workflow_event',
320 'isTest' => FALSE,
321 'toEmail' => $contact_details[1],
322 'toName' => $contact_details[0],
be2fb01f 323 'tplParams' => [
6a488035
TO
324 'billing_name' => "{$params['billing_first_name']} {$params['billing_last_name']}",
325 'billing_city' => $params["billing_city-{$this->_bltID}"],
326 'billing_country' => $country->name,
327 'billing_postal_code' => $params["billing_postal_code-{$this->_bltID}"],
328 'billing_state' => $state_province->abbreviation,
329 'billing_street_address' => $params["billing_street_address-{$this->_bltID}"],
330 'credit_card_exp_date' => $params['credit_card_exp_date'],
331 'credit_card_type' => $params['credit_card_type'],
332 'credit_card_number' => "************" . substr($params['credit_card_number'], -4, 4),
333 // XXX cart->get_discounts
334 'discounts' => $this->discounts,
335 'email' => $contact_details[1],
336 'events_in_cart' => $events_in_cart,
337 'line_items' => $this->line_items,
338 'name' => $contact_details[0],
339 'transaction_id' => $params['trxn_id'],
340 'transaction_date' => $params['trxn_date'],
341 'is_pay_later' => $this->is_pay_later,
342 'pay_later_receipt' => $this->pay_later_receipt,
be2fb01f 343 ],
6a488035 344 'valueName' => 'event_registration_receipt',
92fcb95f 345 'PDFFilename' => ts('confirmation') . '.pdf',
be2fb01f
CW
346 ];
347 $template_params_to_copy = [
6a488035
TO
348 'billing_name',
349 'billing_city',
350 'billing_country',
351 'billing_postal_code',
352 'billing_state',
353 'billing_street_address',
354 'credit_card_exp_date',
355 'credit_card_type',
356 'credit_card_number',
be2fb01f 357 ];
6a488035
TO
358 foreach ($template_params_to_copy as $template_param_to_copy) {
359 $this->set($template_param_to_copy, $send_template_params['tplParams'][$template_param_to_copy]);
360 }
361
c6327d7d 362 CRM_Core_BAO_MessageTemplate::sendTemplate($send_template_params);
6a488035
TO
363 }
364
0cf587a7 365 /**
bf48aa29 366 * Apply form rules.
367 *
368 * @param array $fields
369 * @param array $files
bec0826a 370 * @param CRM_Core_Form $form
0cf587a7
EM
371 *
372 * @return array|bool
373 */
bec0826a 374 public static function formRule($fields, $files, $form) {
be2fb01f 375 $errors = [];
6a488035 376
bec0826a
MW
377 if ($form->payment_required && empty($form->_submitValues['is_pay_later'])) {
378 CRM_Core_Form::validateMandatoryFields($form->_fields, $fields, $errors);
6a488035 379
a479fe60 380 // validate payment instrument values (e.g. credit card number)
bec0826a 381 CRM_Core_Payment_Form::validatePaymentInstrument($form->_paymentProcessor['id'], $fields, $errors, NULL);
6a488035
TO
382 }
383
384 return empty($errors) ? TRUE : $errors;
385 }
386
bf48aa29 387 /**
388 * Pre-process form.
389 */
00be9182 390 public function preProcess() {
6a488035
TO
391 $params = $this->_submitValues;
392 $this->is_pay_later = CRM_Utils_Array::value('is_pay_later', $params, FALSE) && !CRM_Utils_Array::value('payment_completed', $params);
393
394 parent::preProcess();
395 }
396
bf48aa29 397 /**
398 * Post process form.
399 */
00be9182 400 public function postProcess() {
2b8d92de 401 $trxnDetails = NULL;
353ffa53 402 $params = $this->_submitValues;
6a488035
TO
403
404 $main_participants = $this->cart->get_main_event_participants();
bec0826a
MW
405
406 $transaction = new CRM_Core_Transaction();
407
6a488035 408 foreach ($main_participants as $participant) {
be2fb01f
CW
409 $defaults = [];
410 $ids = ['contact_id' => $participant->contact_id];
353ffa53 411 $contact = CRM_Contact_BAO_Contact::retrieve($ids, $defaults);
6a488035
TO
412 $contact->is_deleted = 0;
413 $contact->save();
414 }
415
416 $trxn_prefix = 'VR';
417 if (array_key_exists('billing_contact_email', $params)) {
bec0826a 418 $this->payer_contact_id = self::find_or_create_contact([
353ffa53
TO
419 'email' => $params['billing_contact_email'],
420 'first_name' => $params['billing_first_name'],
421 'last_name' => $params['billing_last_name'],
422 'is_deleted' => FALSE,
be2fb01f 423 ]);
6a488035
TO
424
425 $ctype = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact',
426 $this->payer_contact_id,
427 'contact_type'
428 );
be2fb01f 429 $billing_fields = [
6a488035
TO
430 "billing_first_name" => 1,
431 "billing_middle_name" => 1,
432 "billing_last_name" => 1,
433 "billing_street_address-{$this->_bltID}" => 1,
434 "billing_city-{$this->_bltID}" => 1,
435 "billing_state_province_id-{$this->_bltID}" => 1,
436 "billing_postal_code-{$this->_bltID}" => 1,
437 "billing_country_id-{$this->_bltID}" => 1,
438 "address_name-{$this->_bltID}" => 1,
439 "email-{$this->_bltID}" => 1,
be2fb01f 440 ];
6a488035
TO
441
442 $params["address_name-{$this->_bltID}"] = CRM_Utils_Array::value('billing_first_name', $params) . ' ' . CRM_Utils_Array::value('billing_middle_name', $params) . ' ' . CRM_Utils_Array::value('billing_last_name', $params);
443
444 $params["email-{$this->_bltID}"] = $params['billing_contact_email'];
445 CRM_Contact_BAO_Contact::createProfileContact(
446 $params,
447 $billing_fields,
448 $this->payer_contact_id,
449 NULL,
450 NULL,
451 $ctype,
452 TRUE
453 );
979cc174
ML
454
455 $params['contact_id'] = $this->payer_contact_id;
6a488035
TO
456 }
457
458 $params['now'] = date('YmdHis');
459 $params['invoiceID'] = md5(uniqid(rand(), TRUE));
460 $params['amount'] = $this->total;
2b8d92de 461 $params['financial_type_id'] = $this->financial_type_id;
8cc574cf 462 if ($this->payment_required && empty($params['is_pay_later'])) {
2b8d92de
AN
463 $trxnDetails = $this->make_payment($params);
464 $params['trxn_id'] = $trxnDetails['trxn_id'];
465 $params['trxn_date'] = $trxnDetails['trxn_date'];
466 $params['currencyID'] = $trxnDetails['currency'];
6a488035
TO
467 }
468 $this->cart->completed = TRUE;
469 $this->cart->save();
470 $this->set('last_event_cart_id', $this->cart->id);
471
472 $contribution_statuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
473 $params['payment_instrument_id'] = NULL;
a7488080 474 if (!empty($params['is_pay_later'])) {
593dbb07 475 $params['payment_instrument_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check');
6a488035
TO
476 $trxn_prefix = 'CK';
477 }
478 else {
593dbb07 479 $params['payment_instrument_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Credit Card');
6a488035 480 }
8cc574cf 481 if ($this->is_pay_later && empty($params['payment_completed'])) {
6a488035
TO
482 $params['contribution_status_id'] = array_search('Pending', $contribution_statuses);
483 }
484 else {
485 $params['contribution_status_id'] = array_search('Completed', $contribution_statuses);
486 $params['participant_status'] = 'Registered';
487 $params['is_pay_later'] = 0;
488 }
2b8d92de 489 if ($trxnDetails == NULL) {
6a488035
TO
490 $params['trxn_id'] = $trxn_prefix . strftime("%Y%m%d%H%M%S");
491 $params['trxn_date'] = $params['now'];
492 }
493
494 if ($this->payment_required) {
495 $this->emailReceipt($this->cart->events_in_carts, $params);
496 }
497
498 // n.b. we need to process the subparticipants before main event
499 // participants so that session attendance can be included in the email
500 $main_participants = $this->cart->get_main_event_participants();
be2fb01f 501 $this->all_participants = [];
6a488035
TO
502 foreach ($main_participants as $main_participant) {
503 $this->all_participants = array_merge($this->all_participants, $this->cart->get_subparticipants($main_participant));
504 }
505 $this->all_participants = array_merge($this->all_participants, $main_participants);
506
507 $this->sub_trxn_index = 0;
508 foreach ($this->all_participants as $mer_participant) {
509 $event_in_cart = $this->cart->get_event_in_cart_by_event_id($mer_participant->event_id);
510
511 $this->sub_trxn_index += 1;
512
513 unset($params['contributionID']);
514 if ($mer_participant->must_wait) {
515 $this->registerParticipant($params, $mer_participant, $event_in_cart->event);
516 }
517 else {
6a488035
TO
518 $params['amount'] = $mer_participant->cost - $mer_participant->discount_amount;
519
2b8d92de
AN
520 if ($event_in_cart->event->financial_type_id && $mer_participant->cost) {
521 $params['financial_type_id'] = $event_in_cart->event->financial_type_id;
6a488035 522 $params['participant_contact_id'] = $mer_participant->contact_id;
481a74f4 523 $contribution = $this->record_contribution($mer_participant, $params, $event_in_cart->event);
2b8d92de
AN
524 // Record civicrm_line_item
525 CRM_Price_BAO_LineItem::processPriceSet($mer_participant->id, $mer_participant->price_details, $contribution, $entity_table = 'civicrm_participant');
6a488035
TO
526 }
527 $this->registerParticipant($params, $mer_participant, $event_in_cart->event);
528 }
529 }
530 $this->trxn_id = $params['trxn_id'];
531 $this->trxn_date = $params['trxn_date'];
532 $this->saveDataToSession();
533 $transaction->commit();
534 }
535
0cf587a7 536 /**
bf48aa29 537 * Make payment.
538 *
c490a46a 539 * @param array $params
0cf587a7 540 *
bf48aa29 541 * @return array
0cf587a7
EM
542 * @throws Exception
543 */
00be9182 544 public function make_payment(&$params) {
b0efa39e
MWMC
545 $params = $this->prepareParamsForPaymentProcessor($params);
546 $params['currencyID'] = CRM_Core_Config::singleton()->defaultCurrency;
6a488035 547
077017db 548 $payment = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
6a488035 549 CRM_Core_Payment_Form::mapParams($this->_bltID, $params, $params, TRUE);
b0efa39e 550
248141b9
EM
551 try {
552 $result = $payment->doPayment($params);
553 }
554 catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
6a488035
TO
555 CRM_Core_Error::displaySessionError($result);
556 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/event/cart_checkout', "_qf_Payment_display=1&qfKey={$this->controller->_key}", TRUE, NULL, FALSE));
6a488035 557 }
248141b9 558
be2fb01f 559 $trxnDetails = [
6a488035 560 'trxn_id' => $result['trxn_id'],
427d3cf9
MW
561 'trxn_date' => $params['receive_date'] ?? date('YmdHis'),
562 'currency' => $params['currencyID'],
be2fb01f 563 ];
2b8d92de 564 return $trxnDetails;
6a488035
TO
565 }
566
0cf587a7 567 /**
bf48aa29 568 * Record contribution.
569 *
570 * @param CRM_Event_BAO_Participant $mer_participant
c490a46a 571 * @param array $params
bf48aa29 572 * @param CRM_Event_BAO_Event $event
0cf587a7
EM
573 *
574 * @return object
575 * @throws Exception
576 */
00be9182 577 public function record_contribution(&$mer_participant, &$params, $event) {
6a488035
TO
578 if ($this->payer_contact_id) {
579 $payer = $this->payer_contact_id;
580 }
581 elseif (self::getContactID()) {
582 $payer = self::getContactID();
583 }
584 else {
585 $payer = $params['participant_contact_id'];
586 }
587
be2fb01f 588 $contribParams = [
6a488035
TO
589 'contact_id' => $payer,
590 'financial_type_id' => $params['financial_type_id'],
591 'receive_date' => $params['now'],
592 'total_amount' => $params['amount'],
593 'amount_level' => $mer_participant->fee_level,
6a488035
TO
594 'net_amount' => $params['amount'],
595 'invoice_id' => "{$params['invoiceID']}-{$this->sub_trxn_index}",
596 'trxn_id' => "{$params['trxn_id']}-{$this->sub_trxn_index}",
6b409353 597 'currency' => $params['currencyID'] ?? NULL,
6a488035
TO
598 'source' => $event->title,
599 'is_pay_later' => CRM_Utils_Array::value('is_pay_later', $params, 0),
600 'contribution_status_id' => $params['contribution_status_id'],
601 'payment_instrument_id' => $params['payment_instrument_id'],
6b409353 602 'check_number' => $params['check_number'] ?? NULL,
2b8d92de 603 'skipLineItem' => 1,
be2fb01f 604 ];
6a488035 605
2b8d92de
AN
606 if (is_array($this->_paymentProcessor)) {
607 $contribParams['payment_processor'] = $this->_paymentProcessor['id'];
608 }
609
77beddbe 610 $contribution = CRM_Contribute_BAO_Contribution::add($contribParams);
6a488035
TO
611 $mer_participant->contribution_id = $contribution->id;
612 $params['contributionID'] = $contribution->id;
2b8d92de
AN
613
614 return $contribution;
6a488035
TO
615 }
616
bf48aa29 617 /**
618 * Save data to session.
619 */
00be9182 620 public function saveDataToSession() {
be2fb01f 621 $session_line_items = [];
6a488035 622 foreach ($this->line_items as $line_item) {
be2fb01f 623 $session_line_item = [];
6a488035
TO
624 $session_line_item['amount'] = $line_item['amount'];
625 $session_line_item['cost'] = $line_item['cost'];
626 $session_line_item['event_id'] = $line_item['event']->id;
627 $session_line_items[] = $session_line_item;
628 }
629 $this->set('line_items', $session_line_items);
630 $this->set('payment_required', $this->payment_required);
631 $this->set('is_pay_later', $this->is_pay_later);
632 $this->set('pay_later_receipt', $this->pay_later_receipt);
633 $this->set('trxn_id', $this->trxn_id);
634 $this->set('trxn_date', $this->trxn_date);
635 $this->set('total', $this->total);
636 }
637
0cf587a7 638 /**
bf48aa29 639 * Set form default values.
640 *
0cf587a7
EM
641 * @return array
642 */
00be9182 643 public function setDefaultValues() {
6a488035
TO
644 $defaults = parent::setDefaultValues();
645
6a488035 646 $default_country = new CRM_Core_DAO_Country();
d14f0a66 647 $default_country->iso_code = CRM_Core_BAO_Country::defaultContactCountry();
6a488035
TO
648 $default_country->find(TRUE);
649 $defaults["billing_country_id-{$this->_bltID}"] = $default_country->id;
650
c953775a 651 if (self::getContactID()) {
be2fb01f 652 $params = ['id' => self::getContactID()];
6a488035
TO
653 $contact = CRM_Contact_BAO_Contact::retrieve($params, $defaults);
654
655 foreach ($contact->email as $email) {
656 if ($email['is_billing']) {
657 $defaults["billing_contact_email"] = $email['email'];
658 }
659 }
a7488080 660 if (empty($defaults['billing_contact_email'])) {
6a488035
TO
661 foreach ($contact->email as $email) {
662 if ($email['is_primary']) {
663 $defaults["billing_contact_email"] = $email['email'];
664 }
665 }
666 }
667
668 $defaults["billing_first_name"] = $contact->first_name;
669 $defaults["billing_middle_name"] = $contact->middle_name;
670 $defaults["billing_last_name"] = $contact->last_name;
671
672 $billing_address = CRM_Event_Cart_BAO_MerParticipant::billing_address_from_contact($contact);
673
674 if ($billing_address != NULL) {
675 $defaults["billing_street_address-{$this->_bltID}"] = $billing_address['street_address'];
676 $defaults["billing_city-{$this->_bltID}"] = $billing_address['city'];
677 $defaults["billing_postal_code-{$this->_bltID}"] = $billing_address['postal_code'];
678 $defaults["billing_state_province_id-{$this->_bltID}"] = $billing_address['state_province_id'];
679 $defaults["billing_country_id-{$this->_bltID}"] = $billing_address['country_id'];
680 }
681 }
682
683 $defaults["source"] = $this->description;
684
685 return $defaults;
686 }
96025800 687
1e3401f3 688 /**
bf48aa29 689 * Apply discount.
690 *
e90198f2 691 * @param string $discountCode
692 * @param array $price_set_amount
bf48aa29 693 * @param float $cost
694 * @param int $event_id
695 *
696 * @return bool
bec0826a 697 * @throws \CiviCRM_API3_Exception
1e3401f3 698 */
e90198f2 699 protected function apply_discount($discountCode, &$price_set_amount, &$cost, $event_id) {
bec0826a
MW
700 $extensions = civicrm_api3('Extension', 'get', [
701 'full_name' => 'org.civicrm.module.cividiscount',
702 ]);
703 if (empty($extensions['id']) || ($extensions['values'][$extensions['id']]['status'] !== 'installed')) {
704 return FALSE;
1e3401f3 705 }
bec0826a
MW
706
707 $autoDiscount = [];
708
1e3401f3 709 $discounted_priceset_ids = _cividiscount_get_discounted_priceset_ids();
710 $discounts = _cividiscount_get_discounts();
e90198f2 711
02052b9b 712 $stat = FALSE;
1e3401f3 713 foreach ($discounts as $key => $discountValue) {
714 if ($key == $discountCode) {
9c1bc317 715 $events = $discountValue['events'] ?? NULL;
e90198f2 716 $evt_ids = implode(",", $events);
717 if ($evt_ids == "0" || strpos($evt_ids, $event_id)) {
02052b9b 718 $event_match = TRUE;
719 }
1e3401f3 720 //check priceset is_active
02052b9b 721 if ($discountValue['active_on'] != NULL) {
722 $today = date('Y-m-d');
723 $diff1 = date_diff(date_create($today), date_create($discountValue['active_on']));
724 if ($diff1->days > 0) {
725 $active1 = TRUE;
e90198f2 726 }
727 }
728 else {
1e3401f3 729 $active1 = TRUE;
730 }
731 if ($discountValue['expire_on'] != NULL) {
732 $diff2 = date_diff(date_create($today), date_create($discountValue['expire_on']));
733 if ($diff2->days > 0) {
734 $active2 = TRUE;
735 }
736 }
737 else {
738 $active2 = TRUE;
739 }
740 }
02052b9b 741 if ($discountValue['is_active'] == TRUE && ($discountValue['count_max'] == 0 || ($discountValue['count_max'] > $discountValue['count_use'])) && $active1 == TRUE && $active2 == TRUE && $event_match == TRUE) {
1e3401f3 742 foreach ($price_set_amount as $key => $price) {
743 if (array_search($price['price_field_value_id'], $discounted_priceset_ids) != NULL) {
bec0826a 744 $discounted = _cividiscount_calc_discount($price['line_total'], $price['label'], $discountValue, $autoDiscount, $this->getCurrency());
1e3401f3 745 $price_set_amount[$key]['line_total'] = $discounted[0];
746 $cost += $discounted[0];
747 $price_set_amount[$key]['label'] = $discounted[1];
e90198f2 748 }
749 else {
02052b9b 750 $cost += $price['line_total'];
1e3401f3 751 }
752 }
02052b9b 753 $stat = TRUE;
1e3401f3 754 }
755 }
02052b9b 756 return $stat;
1e3401f3 757 }
e90198f2 758
6a488035 759}