Merge pull request #11877 from compucorp/CRM-21853-remove-implicit-is-multiple-change
[civicrm-core.git] / CRM / Event / Form / Registration / AdditionalParticipant.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
fee14197 4 | CiviCRM version 5 |
6a488035 5 +--------------------------------------------------------------------+
8c9251b3 6 | Copyright CiviCRM LLC (c) 2004-2018 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 *
31 * @package CRM
8c9251b3 32 * @copyright CiviCRM LLC (c) 2004-2018
6a488035
TO
33 */
34
35/**
c039f658 36 * This class generates form components for processing Event.
6a488035
TO
37 */
38class CRM_Event_Form_Registration_AdditionalParticipant extends CRM_Event_Form_Registration {
39
6a488035 40 /**
100fef9d 41 * Pre-registered additional participant id.
6a488035
TO
42 */
43 public $additionalParticipantId = NULL;
44
45 /**
66f9e52b 46 * Set variables up before form is built.
6a488035
TO
47 *
48 * @return void
6a488035 49 */
00be9182 50 public function preProcess() {
6a488035
TO
51 parent::preProcess();
52
53 $participantNo = substr($this->_name, 12);
54
55 //lets process in-queue participants.
56 if ($this->_participantId && $this->_additionalParticipantIds) {
57 $this->_additionalParticipantId = CRM_Utils_Array::value($participantNo, $this->_additionalParticipantIds);
58 }
59
60 $participantCnt = $participantNo + 1;
61 $this->assign('formId', $participantNo);
62 $this->_params = array();
63 $this->_params = $this->get('params');
64
65 $participantTot = $this->_params[0]['additional_participants'] + 1;
66 $skipCount = count(array_keys($this->_params, "skip"));
67 if ($skipCount) {
68 $this->assign('skipCount', $skipCount);
69 }
70 CRM_Utils_System::setTitle(ts('Register Participant %1 of %2', array(1 => $participantCnt, 2 => $participantTot)));
71
72 //CRM-4320, hack to check last participant.
73 $this->_lastParticipant = FALSE;
74 if ($participantTot == $participantCnt) {
75 $this->_lastParticipant = TRUE;
76 }
77 $this->assign('lastParticipant', $this->_lastParticipant);
78 }
79
80 /**
c490a46a 81 * Set default values for the form. For edit/view mode
6a488035
TO
82 * the default values are retrieved from the database
83 *
6a488035 84 *
355ba699 85 * @return void
6a488035 86 */
00be9182 87 public function setDefaultValues() {
6a488035
TO
88 $defaults = $unsetSubmittedOptions = array();
89 $discountId = NULL;
90 //fix for CRM-3088, default value for discount set.
91 if (!empty($this->_values['discount'])) {
92 $discountId = CRM_Core_BAO_Discount::findSet($this->_eventId, 'civicrm_event');
8cc574cf 93 if ($discountId && !empty($this->_values['event']['default_discount_fee_id'])) {
0479b4c8 94 $discountKey = CRM_Core_DAO::getFieldValue("CRM_Core_DAO_OptionValue", $this->_values['event']['default_discount_fee_id'], 'weight', 'id'
6a488035
TO
95 );
96 $defaults['amount'] = key(array_slice($this->_values['discount'][$discountId], $discountKey - 1, $discountKey, TRUE));
97 }
98 }
99 if ($this->_priceSetId) {
100 foreach ($this->_feeBlock as $key => $val) {
a7488080 101 if (empty($val['options'])) {
6a488035
TO
102 continue;
103 }
104
105 $optionsFull = CRM_Utils_Array::value('option_full_ids', $val, array());
106 foreach ($val['options'] as $keys => $values) {
107 if ($values['is_default'] && !in_array($keys, $optionsFull)) {
108 if ($val['html_type'] == 'CheckBox') {
109 $defaults["price_{$key}"][$keys] = 1;
110 }
111 else {
112 $defaults["price_{$key}"] = $keys;
113 }
114 }
115 }
116 if (!empty($optionsFull)) {
117 $unsetSubmittedOptions[$val['id']] = $optionsFull;
118 }
119 }
120 }
121
122 //CRM-4320, setdefault additional participant values.
123 if ($this->_allowConfirmation && $this->_additionalParticipantId) {
124 //hack to get set default from eventFees.php
353ffa53
TO
125 $this->_discountId = $discountId;
126 $this->_pId = $this->_additionalParticipantId;
127 $this->_contactId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_additionalParticipantId, 'contact_id');
c7d52684 128
129 CRM_Event_BAO_Participant::formatFieldsAndSetProfileDefaults($this->_contactId, $this);
6a488035
TO
130 $participantDefaults = CRM_Event_Form_EventFees::setDefaultValues($this);
131 $participantDefaults = array_merge($this->_defaults, $participantDefaults);
132 // use primary email address if billing email address is empty
133 if (empty($this->_defaults["email-{$this->_bltID}"]) &&
134 !empty($this->_defaults["email-Primary"])
135 ) {
136 $participantDefaults["email-{$this->_bltID}"] = $this->_defaults["email-Primary"];
137 }
138 $defaults = array_merge($defaults, $participantDefaults);
139 }
140
141 $defaults = array_merge($this->_defaults, $defaults);
142
143 //reset values for all options those are full.
0dc0b759 144 CRM_Event_Form_Registration::resetElementValue($unsetSubmittedOptions, $this);
6a488035
TO
145
146 //load default campaign from page.
147 if (array_key_exists('participant_campaign_id', $this->_fields)) {
148 $defaults['participant_campaign_id'] = CRM_Utils_Array::value('campaign_id', $this->_values['event']);
149 }
6a488035 150
dde86037
BS
151 //CRM-17865 set custom field defaults
152 if (!empty($this->_fields)) {
153 foreach ($this->_fields as $name => $field) {
154 if ($customFieldID = CRM_Core_BAO_CustomField::getKeyID($name)) {
155 if (!isset($defaults[$name])) {
156 CRM_Core_BAO_CustomField::setProfileDefaults($customFieldID, $name, $defaults,
157 NULL, CRM_Profile_Form::MODE_REGISTER
158 );
159 }
160 }
161 }
162 }
163
6a488035
TO
164 return $defaults;
165 }
166
167 /**
66f9e52b 168 * Build the form object.
6a488035 169 *
355ba699 170 * @return void
6a488035
TO
171 */
172 public function buildQuickForm() {
5f39c1a6 173
6a488035
TO
174 $button = substr($this->controller->getButtonName(), -4);
175
176 $this->add('hidden', 'scriptFee', NULL);
177 $this->add('hidden', 'scriptArray', NULL);
178
179 if ($this->_values['event']['is_monetary']) {
180 CRM_Event_Form_Registration_Register::buildAmount($this);
181 }
182 $first_name = $last_name = NULL;
183 $pre = $post = array();
184 foreach (array(
353ffa53 185 'pre',
608e6658 186 'post',
353ffa53 187 ) as $keys) {
6a488035 188 if (isset($this->_values['additional_custom_' . $keys . '_id'])) {
f5a47ead 189 $this->buildCustom($this->_values['additional_custom_' . $keys . '_id'], 'additionalCustom' . ucfirst($keys));
6a488035
TO
190 $$keys = CRM_Core_BAO_UFGroup::getFields($this->_values['additional_custom_' . $keys . '_id']);
191 }
192 foreach (array(
353ffa53 193 'first_name',
608e6658 194 'last_name',
353ffa53 195 ) as $name) {
48078478 196 if (array_key_exists($name, $$keys) &&
6a488035
TO
197 CRM_Utils_Array::value('is_required', CRM_Utils_Array::value($name, $$keys))
198 ) {
199 $$name = 1;
200 }
201 }
202 }
203
204 $required = ($button == 'skip' ||
205 $this->_values['event']['allow_same_participant_emails'] == 1 &&
206 ($first_name && $last_name)
207 ) ? FALSE : TRUE;
208
209 //add buttons
210 $js = NULL;
8cc574cf 211 if ($this->isLastParticipant(TRUE) && empty($this->_values['event']['is_monetary'])) {
6a488035
TO
212 $js = array('onclick' => "return submitOnce(this,'" . $this->_name . "','" . ts('Processing') . "');");
213 }
214
215 //handle case where user might sart with waiting by group
216 //registration and skip some people and now group fit to
217 //become registered so need to take payment from user.
218 //this case only occurs at dynamic waiting status, CRM-4320
219 $statusMessage = NULL;
220 $allowToProceed = TRUE;
221 $includeSkipButton = TRUE;
222 $this->_resetAllowWaitlist = FALSE;
223
9da8dc8c 224 $pricesetFieldsCount = CRM_Price_BAO_PriceSet::getPricesetCount($this->_priceSetId);
6a488035
TO
225
226 if ($this->_lastParticipant || $pricesetFieldsCount) {
227 //get the participant total.
228 $processedCnt = self::getParticipantCount($this, $this->_params, TRUE);
229 }
230
8cc574cf 231 if (!$this->_allowConfirmation && !empty($this->_params[0]['bypass_payment']) &&
6a488035
TO
232 $this->_lastParticipant
233 ) {
234
235 //get the event spaces.
236 $spaces = $this->_availableRegistrations;
237
238 $currentPageMaxCount = 1;
239 if ($pricesetFieldsCount) {
240 $currentPageMaxCount = $pricesetFieldsCount;
241 }
242
243 //we might did reset allow waiting in case of dynamic calculation
5f39c1a6 244 // @TODO - does this bypass_payment still exist?
a7488080 245 if (!empty($this->_params[0]['bypass_payment']) &&
6a488035
TO
246 is_numeric($spaces) &&
247 $processedCnt > $spaces
248 ) {
249 $this->_allowWaitlist = TRUE;
250 $this->set('allowWaitlist', TRUE);
251 }
252
253 //lets allow to become a part of runtime waiting list, if primary selected pay later.
254 $realPayLater = FALSE;
8cc574cf 255 if (!empty($this->_values['event']['is_monetary']) && !empty($this->_values['event']['is_pay_later'])) {
6a488035
TO
256 $realPayLater = CRM_Utils_Array::value('is_pay_later', $this->_params[0]);
257 }
258
259 //truly spaces are greater than required.
260 if (is_numeric($spaces) && $spaces >= ($processedCnt + $currentPageMaxCount)) {
261 if (CRM_Utils_Array::value('amount', $this->_params[0], 0) == 0 || $this->_requireApproval) {
262 $this->_allowWaitlist = FALSE;
263 $this->set('allowWaitlist', $this->_allowWaitlist);
264 if ($this->_requireApproval) {
353ffa53
TO
265 $statusMessage = ts("It looks like you are now registering a group of %1 participants. The event has %2 available spaces (you will not be wait listed). Registration for this event requires approval. You will receive an email once your registration has been reviewed.", array(
266 1 => ++$processedCnt,
608e6658 267 2 => $spaces,
353ffa53 268 ));
6a488035
TO
269 }
270 else {
353ffa53
TO
271 $statusMessage = ts("It looks like you are now registering a group of %1 participants. The event has %2 available spaces (you will not be wait listed).", array(
272 1 => ++$processedCnt,
608e6658 273 2 => $spaces,
353ffa53 274 ));
6a488035
TO
275 }
276 }
277 else {
353ffa53
TO
278 $statusMessage = ts("It looks like you are now registering a group of %1 participants. The event has %2 available spaces (you will not be wait listed). Please go back to the main registration page and reduce the number of additional people. You will also need to complete payment information.", array(
279 1 => ++$processedCnt,
608e6658 280 2 => $spaces,
353ffa53 281 ));
6a488035
TO
282 $allowToProceed = FALSE;
283 }
284 CRM_Core_Session::setStatus($statusMessage, ts('Registration Error'), 'error');
285 }
286 elseif ($processedCnt == $spaces) {
287 if (CRM_Utils_Array::value('amount', $this->_params[0], 0) == 0
288 || $realPayLater || $this->_requireApproval
289 ) {
290 $this->_resetAllowWaitlist = TRUE;
291 if ($this->_requireApproval) {
292 $statusMessage = ts("If you skip this participant there will be enough spaces in the event for your group (you will not be wait listed). Registration for this event requires approval. You will receive an email once your registration has been reviewed.");
293 }
294 else {
295 $statusMessage = ts("If you skip this participant there will be enough spaces in the event for your group (you will not be wait listed).");
296 }
297 }
298 else {
299 //hey there is enough space and we require payment.
300 $statusMessage = ts("If you skip this participant there will be enough spaces in the event for your group (you will not be wait listed). Please go back to the main registration page and reduce the number of additional people. You will also need to complete payment information.");
301 $includeSkipButton = FALSE;
302 }
303 }
304 }
305
306 // for priceset with count
8cc574cf 307 if ($pricesetFieldsCount && !empty($this->_values['event']['has_waitlist']) &&
6a488035
TO
308 !$this->_allowConfirmation
309 ) {
310
311 if ($this->_isEventFull) {
312 $statusMessage = ts('This event is currently full. You are registering for the waiting list. You will be notified if spaces become available.');
313 }
314 elseif ($this->_allowWaitlist ||
315 (!$this->_allowWaitlist && ($processedCnt + $pricesetFieldsCount) > $this->_availableRegistrations)
316 ) {
317
318 $waitingMsg = ts('It looks like you are registering more participants then there are spaces available. All participants will be added to the waiting list. You will be notified if spaces become available.');
319 $confirmedMsg = ts('It looks like there are enough spaces in this event for your group (you will not be wait listed).');
320 if ($this->_requireApproval) {
321 $waitingMsg = ts('It looks like you are now registering a group of %1 participants. The event has %2 available spaces (you will not be wait listed). Registration for this event requires approval. You will receive an email once your registration has been reviewed.');
322 $confirmedMsg = ts('It looks there are enough spaces in this event for your group (you will not be wait listed). Registration for this event requires approval. You will receive an email once your registration has been reviewed.');
323 }
324
325 $this->assign('waitingMsg', $waitingMsg);
326 $this->assign('confirmedMsg', $confirmedMsg);
327
328 $this->assign('availableRegistrations', $this->_availableRegistrations);
329 $this->assign('currentParticipantCount', $processedCnt);
330 $this->assign('allowGroupOnWaitlist', TRUE);
331
332 $paymentBypassed = NULL;
a7488080 333 if (!empty($this->_params[0]['bypass_payment']) &&
6a488035
TO
334 !$this->_allowWaitlist &&
335 !$realPayLater &&
336 !$this->_requireApproval &&
337 !(CRM_Utils_Array::value('amount', $this->_params[0], 0) == 0)
338 ) {
339 $paymentBypassed = ts('Please go back to the main registration page, to complete payment information.');
340 }
341 $this->assign('paymentBypassed', $paymentBypassed);
342 }
343 }
344
345 $this->assign('statusMessage', $statusMessage);
346
347 $buttons = array(
0479b4c8 348 array(
f212d37d
CW
349 'type' => 'back',
350 'name' => ts('Go Back'),
6a488035
TO
351 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp',
352 ),
353 );
354
355 //CRM-4320
356 if ($allowToProceed) {
357 $buttons = array_merge($buttons, array(
353ffa53 358 array(
f5a47ead 359 'type' => 'upload',
f212d37d 360 'name' => ts('Continue'),
6a488035
TO
361 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
362 'isDefault' => TRUE,
363 'js' => $js,
364 ),
365 )
366 );
367 if ($includeSkipButton) {
368 $buttons = array_merge($buttons, array(
353ffa53
TO
369 array(
370 'type' => 'next',
371 'name' => ts('Skip Participant'),
372 'subName' => 'skip',
0291a521 373 'icon' => 'fa-fast-forward',
608e6658 374 ),
353ffa53 375 )
6a488035
TO
376 );
377 }
378 }
379 $this->addButtons($buttons);
380 $this->addFormRule(array('CRM_Event_Form_Registration_AdditionalParticipant', 'formRule'), $this);
86c0d461 381 $this->unsavedChangesWarn = TRUE;
6a488035
TO
382 }
383
384 /**
66f9e52b 385 * Global form rule.
6a488035 386 *
d4dd1e85
TO
387 * @param array $fields
388 * The input form values.
389 * @param array $files
390 * The uploaded files if any.
77b97be7
EM
391 * @param $self
392 *
6a488035 393 *
72b3a70c
CW
394 * @return bool|array
395 * true if no errors, else array of errors
6a488035 396 */
00be9182 397 public static function formRule($fields, $files, $self) {
6a488035
TO
398 $errors = array();
399 //get the button name.
400 $button = substr($self->controller->getButtonName(), -4);
401
402 $realPayLater = FALSE;
8cc574cf 403 if (!empty($self->_values['event']['is_monetary']) && !empty($self->_values['event']['is_pay_later'])) {
6a488035
TO
404 $realPayLater = CRM_Utils_Array::value('is_pay_later', $self->_params[0]);
405 }
406
407 if ($button != 'skip') {
408 //Check that either an email or firstname+lastname is included in the form(CRM-9587)
409 CRM_Event_Form_Registration_Register::checkProfileComplete($fields, $errors, $self->_eventId);
410
411 //Additional Participant can also register for an event only once
412 $isRegistered = CRM_Event_Form_Registration_Register::checkRegistration($fields, $self, TRUE);
413 if ($isRegistered) {
414 if ($self->_values['event']['allow_same_participant_emails']) {
415 $errors['_qf_default'] = ts('A person is already registered for this event.');
416 }
417 else {
418 $errors["email-{$self->_bltID}"] = ts('A person with this email address is already registered for this event.');
419 }
420 }
421
422 //get the complete params.
423 $params = $self->get('params');
424
425 //take the participant instance.
426 $addParticipantNum = substr($self->_name, 12);
427
428 if (is_array($params)) {
429 foreach ($params as $key => $value) {
430 if ($key != $addParticipantNum) {
431 if (!$self->_values['event']['allow_same_participant_emails']) {
432 //collect all email fields
433 $existingEmails = array();
434 $additionalParticipantEmails = array();
435 if (is_array($value)) {
0479b4c8
TO
436 foreach ($value as $key => $val) {
437 if (substr($key, 0, 6) == 'email-' && $val) {
438 $existingEmails[] = $val;
439 }
6a488035
TO
440 }
441 }
6a488035
TO
442 foreach ($fields as $key => $val) {
443 if (substr($key, 0, 6) == 'email-' && $val) {
444 $additionalParticipantEmails[] = $val;
445 $mailKey = $key;
446 }
447 }
448 //check if any emails are common to both arrays
449 if (count(array_intersect($existingEmails, $additionalParticipantEmails))) {
450 $errors[$mailKey] = ts('The email address must be unique for each participant.');
451 break;
452 }
453 }
454 else {
455 // check with first_name and last_name for additional participants
33ab1d69 456 if (!empty($value['first_name']) && ($value['first_name'] == CRM_Utils_Array::value('first_name', $fields)) &&
0479b4c8 457 (CRM_Utils_Array::value('last_name', $value) == CRM_Utils_Array::value('last_name', $fields))
6a488035
TO
458 ) {
459 $errors['first_name'] = ts('The first name and last name must be unique for each participant.');
460 break;
461 }
462 }
463 }
464 }
465 }
466
467 //check for atleast one pricefields should be selected
a7488080 468 if (!empty($fields['priceSetId'])) {
6a488035
TO
469 $allParticipantParams = $params;
470
471 //format current participant params.
472 $allParticipantParams[$addParticipantNum] = self::formatPriceSetParams($self, $fields);
473 $totalParticipants = self::getParticipantCount($self, $allParticipantParams);
474
475 //validate price field params.
476 $priceSetErrors = self::validatePriceSet($self, $allParticipantParams);
477 $errors = array_merge($errors, CRM_Utils_Array::value($addParticipantNum, $priceSetErrors, array()));
478
479 if (!$self->_allowConfirmation &&
480 is_numeric($self->_availableRegistrations)
481 ) {
a7488080 482 if (!empty($self->_params[0]['bypass_payment']) &&
6a488035
TO
483 !$self->_allowWaitlist &&
484 !$realPayLater &&
485 !$self->_requireApproval &&
486 !(CRM_Utils_Array::value('amount', $self->_params[0], 0) == 0) &&
487 $totalParticipants < $self->_availableRegistrations
488 ) {
489 $errors['_qf_default'] = ts("Your event registration will be confirmed. Please go back to the main registration page, to complete payment information.");
490 }
491 //check for availability of registrations.
8cc574cf 492 if (!$self->_allowConfirmation && empty($self->_values['event']['has_waitlist']) &&
6a488035
TO
493 $totalParticipants > $self->_availableRegistrations
494 ) {
a3fdddaa 495 $errors['_qf_default'] = ts('Sorry, it looks like this event only has %2 spaces available, and you are trying to register %1 participants. Please change your selections accordingly.', array(
353ffa53 496 1 => $totalParticipants,
608e6658 497 2 => $self->_availableRegistrations,
353ffa53 498 ));
6a488035
TO
499 }
500 }
501 }
502 }
503
8cc574cf 504 if ($button == 'skip' && $self->_lastParticipant && !empty($fields['priceSetId'])) {
9da8dc8c 505 $pricesetFieldsCount = CRM_Price_BAO_PriceSet::getPricesetCount($fields['priceSetId']);
6a488035
TO
506 if (($pricesetFieldsCount < 1) || $self->_allowConfirmation) {
507 return $errors;
508 }
509
8cc574cf 510 if (!empty($self->_values['event']['has_waitlist']) && !empty($self->_params[0]['bypass_payment']) &&
6a488035
TO
511 !$self->_allowWaitlist &&
512 !$realPayLater &&
513 !$self->_requireApproval &&
514 !(CRM_Utils_Array::value('amount', $self->_params[0], 0) == 0)
515 ) {
516 $errors['_qf_default'] = ts("You are going to skip the last participant, your event registration will be confirmed. Please go back to the main registration page, to complete payment information.");
517 }
518 }
519
6a488035
TO
520 if ($button != 'skip' &&
521 $self->_values['event']['is_monetary'] &&
522 !isset($errors['_qf_default']) &&
523 !$self->validatePaymentValues($self, $fields)
524 ) {
525 $errors['_qf_default'] = ts("Your payment information looks incomplete. Please go back to the main registration page, to complete payment information.");
526 $self->set('forcePayement', TRUE);
527 }
528 elseif ($button == 'skip') {
529 $self->set('forcePayement', TRUE);
530 }
531
532 return $errors;
533 }
534
0cf587a7
EM
535 /**
536 * @param $self
537 * @param $fields
538 *
539 * @return bool
540 */
00be9182 541 public function validatePaymentValues($self, $fields) {
6a488035 542
a7488080 543 if (!empty($self->_params[0]['bypass_payment']) ||
6a488035
TO
544 $self->_allowWaitlist ||
545 empty($self->_fields) ||
546 CRM_Utils_Array::value('amount', $self->_params[0]) > 0
547 ) {
548 return TRUE;
549 }
550
551 $validatePayement = FALSE;
a7488080 552 if (!empty($fields['priceSetId'])) {
6a488035 553 $lineItem = array();
9da8dc8c 554 CRM_Price_BAO_PriceSet::processAmount($self->_values['fee'], $fields, $lineItem);
6a488035
TO
555 if ($fields['amount'] > 0) {
556 $validatePayement = TRUE;
557 // $self->_forcePayement = true;
558 // return false;
559 }
560 }
a7488080 561 elseif (!empty($fields['amount']) &&
6a488035
TO
562 (CRM_Utils_Array::value('value', $self->_values['fee'][$fields['amount']]) > 0)
563 ) {
564 $validatePayement = TRUE;
565 }
566
567 if (!$validatePayement) {
6a488035 568 return TRUE;
6a488035
TO
569 }
570
7cb3d4f0
CW
571 $errors = array();
572
573 CRM_Core_Form::validateMandatoryFields($self->_fields, $fields, $errors);
6a488035 574
5ec4b965 575 if (isset($self->_params[0]['payment_processor'])) {
576 // validate supplied payment instrument values (e.g. credit card number and cvv)
577 $payment_processor_id = $self->_params[0]['payment_processor'];
578 CRM_Core_Payment_Form::validatePaymentInstrument($payment_processor_id, $self->_params[0], $errors, (!$self->_isBillingAddressRequiredForPayLater ? NULL : 'billing'));
579 }
0dc0b759 580 if (!empty($errors)) {
7cb3d4f0 581 return FALSE;
6a488035 582 }
7cb3d4f0 583
6a488035
TO
584 foreach (CRM_Contact_BAO_Contact::$_greetingTypes as $greeting) {
585 if ($greetingType = CRM_Utils_Array::value($greeting, $self->_params[0])) {
233319bf 586 $customizedValue = CRM_Core_PseudoConstant::getKey('CRM_Contact_BAO_Contact', $greeting . '_id', 'Customized');
6a488035
TO
587 if ($customizedValue == $greetingType && empty($self->_params[0][$greeting . '_custom'])) {
588 return FALSE;
589 }
590 }
591 }
2ae4d103 592 return TRUE;
6a488035
TO
593 }
594
595 /**
66f9e52b 596 * Process the form submission.
6a488035 597 *
6a488035 598 *
355ba699 599 * @return void
6a488035
TO
600 */
601 public function postProcess() {
602 //get the button name.
603 $button = substr($this->controller->getButtonName(), -4);
604
605 //take the participant instance.
606 $addParticipantNum = substr($this->_name, 12);
607
608 //user submitted params.
609 $params = $this->controller->exportValues($this->_name);
610
611 if (!$this->_allowConfirmation) {
612 // check if the participant is already registered
7dfe13ab 613 $params['contact_id'] = CRM_Event_Form_Registration_Register::getRegistrationContactID($params, $this, TRUE);
6a488035
TO
614 }
615
f5a47ead 616 if (!empty($params['image_URL'])) {
617 CRM_Contact_BAO_Contact::processImageParams($params);
618 }
6a488035
TO
619 //carry campaign to partcipants.
620 if (array_key_exists('participant_campaign_id', $params)) {
621 $params['campaign_id'] = $params['participant_campaign_id'];
622 }
623 else {
624 $params['campaign_id'] = CRM_Utils_Array::value('campaign_id', $this->_values['event']);
625 }
626
627 // if waiting is enabled
628 if (!$this->_allowConfirmation &&
629 is_numeric($this->_availableRegistrations)
630 ) {
631 $this->_allowWaitlist = FALSE;
632 //get the current page count.
633 $currentCount = self::getParticipantCount($this, $params);
634 if ($button == 'skip') {
635 $currentCount = 'skip';
636 }
637
638 //get the total count.
639 $previousCount = self::getParticipantCount($this, $this->_params, TRUE);
640 $totalParticipants = $previousCount;
641 if (is_numeric($currentCount)) {
642 $totalParticipants += $currentCount;
643 }
a7488080 644 if (!empty($this->_values['event']['has_waitlist']) &&
6a488035
TO
645 $totalParticipants > $this->_availableRegistrations
646 ) {
647 $this->_allowWaitlist = TRUE;
648 }
649 $this->set('allowWaitlist', $this->_allowWaitlist);
650 $this->_lineItemParticipantsCount[$addParticipantNum] = $currentCount;
651 }
652
653 if ($button == 'skip') {
654 //hack for free/zero amount event.
655 if ($this->_resetAllowWaitlist) {
656 $this->_allowWaitlist = FALSE;
657 $this->set('allowWaitlist', FALSE);
658 if ($this->_requireApproval) {
659 $status = ts("You have skipped last participant and which result into event having enough spaces, but your registration require approval, Once your registration has been reviewed, you will receive an email with a link to a web page where you can complete the registration process.");
660 }
661 else {
662 $status = ts("You have skipped last participant and which result into event having enough spaces, hence your group become as register participants though you selected on wait list.");
663 }
664 CRM_Core_Session::setStatus($status);
665 }
666
667 $this->_params[$addParticipantNum] = 'skip';
668 if (isset($this->_lineItem)) {
669 $this->_lineItem[$addParticipantNum] = 'skip';
670 $this->_lineItemParticipantsCount[$addParticipantNum] = 'skip';
671 }
672 }
673 else {
674
675 $config = CRM_Core_Config::singleton();
676 $params['currencyID'] = $config->defaultCurrency;
677
678 if ($this->_values['event']['is_monetary']) {
679
680 //added for discount
681 $discountId = CRM_Core_BAO_Discount::findSet($this->_eventId, 'civicrm_event');
c039f658 682 $params['amount_level'] = $this->getAmountLevel($params, $discountId);
6a488035
TO
683 if (!empty($this->_values['discount'][$discountId])) {
684 $params['discount_id'] = $discountId;
6a488035
TO
685 $params['amount'] = $this->_values['discount'][$discountId][$params['amount']]['value'];
686 }
687 elseif (empty($params['priceSetId'])) {
6a488035
TO
688 $params['amount'] = $this->_values['fee'][$params['amount']]['value'];
689 }
690 else {
691 $lineItem = array();
9da8dc8c 692 CRM_Price_BAO_PriceSet::processAmount($this->_values['fee'], $params, $lineItem);
6a488035 693
0dc0b759 694 //build line item array..
695 //if requireApproval/waitlist is enabled we hide fees for primary participant
696 // (and not for additional participant which might be is a bug)
697 //lineItem are not correctly build for primary participant
698 //this results in redundancy since now lineItems for additional participant will be build against primary participantNum
699 //therefore lineItems must always be build against current participant No
700 $this->_lineItem[$addParticipantNum] = $lineItem;
6a488035
TO
701 }
702 }
703
704 if (array_key_exists('participant_role', $params)) {
705 $params['participant_role_id'] = $params['participant_role'];
706 }
707
a7488080 708 if (empty($params['participant_role_id']) && $this->_values['event']['default_role_id']) {
6a488035
TO
709 $params['participant_role_id'] = $this->_values['event']['default_role_id'];
710 }
711
a7488080 712 if (!empty($this->_params[0]['is_pay_later'])) {
6a488035
TO
713 $params['is_pay_later'] = 1;
714 }
715
716 //carry additional participant id, contact id if pre-registered.
717 if ($this->_allowConfirmation && $this->_additionalParticipantId) {
718 $params['contact_id'] = $this->_contactId;
719 $params['participant_id'] = $this->_additionalParticipantId;
720 }
721
722 //build the params array.
0dc0b759 723 $this->_params[$addParticipantNum] = $params;
6a488035
TO
724 }
725
726 //finally set the params.
727 $this->set('params', $this->_params);
728 //set the line item.
729 if ($this->_lineItem) {
730 $this->set('lineItem', $this->_lineItem);
731 $this->set('lineItemParticipantsCount', $this->_lineItemParticipantsCount);
732 }
733
734 $participantNo = count($this->_params);
735 if ($button != 'skip') {
736 $statusMsg = ts('Registration information for participant %1 has been saved.', array(1 => $participantNo));
737 CRM_Core_Session::setStatus($statusMsg, ts('Registration Saved'), 'success');
738 }
739
1909126f 740 // Check whether to process the registration now, calling processRegistration()
741 if (
742 !$this->_values['event']['is_confirm_enabled'] // CRM-11182 - Optional confirmation screen
d6121d3e 743 && !$this->_values['event']['is_monetary']
1909126f 744 && CRM_Utils_Array::value('additional_participants', $this->_params[0])
745 && $this->isLastParticipant()
6a488035 746 ) {
3033e657 747 $this->processRegistration($this->_params);
6a488035
TO
748 }
749 }
750
0cf587a7
EM
751 /**
752 * @param $additionalParticipant
753 *
754 * @return array
755 */
5dd94759 756 public static function &getPages($additionalParticipant) {
6a488035
TO
757 $details = array();
758 for ($i = 1; $i <= $additionalParticipant; $i++) {
759 $details["Participant_{$i}"] = array(
760 'className' => 'CRM_Event_Form_Registration_AdditionalParticipant',
761 'title' => "Register Additional Participant {$i}",
762 );
763 }
764 return $details;
765 }
766
767 /**
66f9e52b 768 * Check whether call current participant is last one.
6a488035 769 *
2a6da8d7
EM
770 * @param bool $isButtonJs
771 *
608e6658 772 * @return bool
a6c01b45 773 * ture on success.
6a488035 774 */
00be9182 775 public function isLastParticipant($isButtonJs = FALSE) {
6a488035
TO
776 $participant = $isButtonJs ? $this->_params[0]['additional_participants'] : $this->_params[0]['additional_participants'] + 1;
777 if (count($this->_params) == $participant) {
778 return TRUE;
779 }
780 return FALSE;
781 }
a14eff52 782
6a488035 783}