Commit | Line | Data |
---|---|---|
6a488035 | 1 | <?php |
0cf587a7 EM |
2 | |
3 | /** | |
4 | * Class CRM_Event_Cart_Form_Checkout_Payment | |
5 | */ | |
6a488035 TO |
6 | class 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 | } |