3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
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. |
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. |
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 +--------------------------------------------------------------------+
30 * @copyright CiviCRM LLC (c) 2004-2016
34 * This class generates form components for processing Event.
36 class CRM_Event_Form_Registration_Confirm
extends CRM_Event_Form_Registration
{
39 * The values for the contribution db object.
53 * Set variables up before form is built.
55 public function preProcess() {
58 // lineItem isn't set until Register postProcess
59 $this->_lineItem
= $this->get('lineItem');
61 $this->_params
= $this->get('params');
62 $this->_params
[0]['tax_amount'] = $this->get('tax_amount');
64 $this->_params
[0]['is_pay_later'] = $this->get('is_pay_later');
65 $this->assign('is_pay_later', $this->_params
[0]['is_pay_later']);
66 if ($this->_params
[0]['is_pay_later']) {
67 $this->assign('pay_later_receipt', $this->_values
['event']['pay_later_receipt']);
70 CRM_Utils_Hook
::eventDiscount($this, $this->_params
);
72 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
73 $this->set('hookDiscount', $this->_params
[0]['discount']);
74 $this->assign('hookDiscount', $this->_params
[0]['discount']);
77 // The concept of contributeMode is deprecated.
78 if ($this->_contributeMode
== 'express') {
80 // rfp == redirect from paypal
81 // rfp is probably not required - the getPreApprovalDetails should deal with any payment-processor specific 'stuff'
82 $rfp = CRM_Utils_Request
::retrieve('rfp', 'Boolean',
83 CRM_Core_DAO
::$_nullObject, FALSE, NULL, 'GET'
86 //we lost rfp in case of additional participant. So set it explicitly.
87 if ($rfp || CRM_Utils_Array
::value('additional_participants', $this->_params
[0], FALSE)) {
88 if (!empty($this->_paymentProcessor
) && $this->_paymentProcessor
['object']->supports('preApproval')) {
89 $preApprovalParams = $this->_paymentProcessor
['object']->getPreApprovalDetails($this->get('pre_approval_parameters'));
90 $params = array_merge($this->_params
, $preApprovalParams);
92 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $params, $params, FALSE);
94 // set a few other parameters that are not really specific to this method because we don't know what
95 // will break if we change this.
96 $params['amount'] = $this->_params
[0]['amount'];
97 if (!empty($this->_params
[0]['discount'])) {
98 $params['discount'] = $this->_params
[0]['discount'];
99 $params['discountAmount'] = $this->_params
[0]['discountAmount'];
100 $params['discountMessage'] = $this->_params
[0]['discountMessage'];
102 if (!empty($this->_params
[0]['amount_priceset_level_radio'])) {
103 $params['amount_priceset_level_radio'] = $this->_params
[0]['amount_priceset_level_radio'];
105 $params['amount_level'] = $this->_params
[0]['amount_level'];
106 $params['currencyID'] = $this->_params
[0]['currencyID'];
108 // also merge all the other values from the profile fields
109 $values = $this->controller
->exportValues('Register');
112 "street_address-{$this->_bltID}",
113 "city-{$this->_bltID}",
114 "state_province_id-{$this->_bltID}",
115 "postal_code-{$this->_bltID}",
116 "country_id-{$this->_bltID}",
119 foreach ($values as $name => $value) {
121 if (!in_array($name, $skipFields)) {
122 $params[$name] = $value;
124 if (substr($name, 0, 6) == 'price_') {
125 $params[$name] = $this->_params
[0][$name];
128 $this->set('getExpressCheckoutDetails', $params);
130 $this->_params
[0] = array_merge($this->_params
[0], $params);
131 $this->_params
[0]['is_primary'] = 1;
134 //process only primary participant params.
135 $registerParams = $this->_params
[0];
136 if (isset($registerParams["billing_state_province_id-{$this->_bltID}"])
137 && $registerParams["billing_state_province_id-{$this->_bltID}"]
139 $registerParams["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($registerParams["billing_state_province_id-{$this->_bltID}"]);
142 if (isset($registerParams["billing_country_id-{$this->_bltID}"]) && $registerParams["billing_country_id-{$this->_bltID}"]) {
143 $registerParams["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant
::countryIsoCode($registerParams["billing_country_id-{$this->_bltID}"]);
145 if (isset($registerParams['credit_card_exp_date'])) {
146 $registerParams['year'] = CRM_Core_Payment_Form
::getCreditCardExpirationYear($registerParams);
147 $registerParams['month'] = CRM_Core_Payment_Form
::getCreditCardExpirationMonth($registerParams);
149 if ($this->_values
['event']['is_monetary']) {
150 $registerParams['ip_address'] = CRM_Utils_System
::ipAddress();
151 $registerParams['currencyID'] = $this->_params
[0]['currencyID'];
153 //assign back primary participant params.
154 $this->_params
[0] = $registerParams;
157 if ($this->_values
['event']['is_monetary']) {
158 $this->_params
[0]['invoiceID'] = $this->get('invoiceID');
160 $this->assign('defaultRole', FALSE);
161 if (CRM_Utils_Array
::value('defaultRole', $this->_params
[0]) == 1) {
162 $this->assign('defaultRole', TRUE);
165 if (empty($this->_params
[0]['participant_role_id']) &&
166 $this->_values
['event']['default_role_id']
168 $this->_params
[0]['participant_role_id'] = $this->_values
['event']['default_role_id'];
171 if (isset($this->_values
['event']['confirm_title'])) {
172 CRM_Utils_System
::setTitle($this->_values
['event']['confirm_title']);
176 $params = CRM_Contribute_Form_Contribution_Confirm
::processPcp($this, $this->_params
[0]);
177 $this->_params
[0] = $params;
180 $this->set('params', $this->_params
);
184 * Overwrite action, since we are only showing elements in frozen mode no help display needed.
188 public function getAction() {
189 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
190 return CRM_Core_Action
::VIEW | CRM_Core_Action
::PREVIEW
;
193 return CRM_Core_Action
::VIEW
;
198 * Build the form object.
200 public function buildQuickForm() {
201 $this->assignToTemplate();
203 if ($this->_values
['event']['is_monetary'] &&
204 ($this->_params
[0]['amount'] ||
$this->_params
[0]['amount'] == 0)
206 $this->_amount
= array();
209 foreach ($this->_params
as $k => $v) {
213 $individualTaxAmount = 0;
214 //display tax amount on confirmation page
215 $taxAmount +
= $v['tax_amount'];
221 if (isset($v['billing_' . $name]) &&
224 $v[$name] = $v['billing_' . $name];
228 if (!empty($v['first_name']) && !empty($v['last_name'])) {
229 $append = $v['first_name'] . ' ' . $v['last_name'];
232 //use an email if we have one
233 foreach ($v as $v_key => $v_val) {
234 if (substr($v_key, 0, 6) == 'email-') {
235 $append = $v[$v_key];
240 $this->_amount
[$k]['amount'] = $v['amount'];
241 if (!empty($v['discountAmount'])) {
242 $this->_amount
[$k]['amount'] -= $v['discountAmount'];
245 $this->_amount
[$k]['label'] = preg_replace('/\ 1/', '', $v['amount_level']) . ' - ' . $append;
246 $this->_part
[$k]['info'] = CRM_Utils_Array
::value('first_name', $v) . ' ' . CRM_Utils_Array
::value('last_name', $v);
247 if (empty($v['first_name'])) {
248 $this->_part
[$k]['info'] = $append;
252 $individual[$k]['totalAmtWithTax'] = $this->_amount
[$k]['amount'];
253 $individual[$k]['totalTaxAmt'] = $individualTaxAmount +
$v['tax_amount'];
254 $this->_totalAmount
= $this->_totalAmount +
$this->_amount
[$k]['amount'];
255 if (!empty($v['is_primary'])) {
256 $this->set('primaryParticipantAmount', $this->_amount
[$k]['amount']);
261 $invoiceSettings = Civi
::settings()->get('contribution_invoice_settings');
262 $taxTerm = CRM_Utils_Array
::value('tax_term', $invoiceSettings);
263 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
265 $this->assign('totalTaxAmount', $taxAmount);
266 $this->assign('taxTerm', $taxTerm);
267 $this->assign('individual', $individual);
268 $this->set('individual', $individual);
271 $this->assign('part', $this->_part
);
272 $this->set('part', $this->_part
);
273 $this->assign('amounts', $this->_amount
);
274 $this->assign('totalAmount', $this->_totalAmount
);
275 $this->set('totalAmount', $this->_totalAmount
);
278 if ($this->_priceSetId
&& !CRM_Core_DAO
::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId
, 'is_quick_config')) {
279 $lineItemForTemplate = array();
280 $getTaxDetails = FALSE;
281 if (!empty($this->_lineItem
) && is_array($this->_lineItem
)) {
282 foreach ($this->_lineItem
as $key => $value) {
283 if (!empty($value)) {
284 $lineItemForTemplate[$key] = $value;
287 foreach ($value as $v) {
288 if (isset($v['tax_rate'])) {
289 $getTaxDetails = TRUE;
295 if (!empty($lineItemForTemplate)) {
296 $this->assign('lineItem', $lineItemForTemplate);
298 $this->assign('getTaxDetails', $getTaxDetails);
301 //display additional participants profile.
302 self
::assignProfiles($this);
304 //consider total amount.
305 $this->assign('isAmountzero', ($this->_totalAmount
<= 0) ?
TRUE : FALSE);
307 $contribButton = ts('Continue');
308 $this->addButtons(array(
311 'name' => ts('Go Back'),
315 'name' => $contribButton,
317 'js' => array('onclick' => "return submitOnce(this,'" . $this->_name
. "','" . ts('Processing') . "');"),
324 if (!empty($this->_fields
)) {
325 foreach ($this->_fields
as $name => $dontCare) {
329 $fields["billing_state_province-{$this->_bltID}"] = $fields["billing_country-{$this->_bltID}"] = $fields["email-{$this->_bltID}"] = 1;
330 foreach ($fields as $name => $dontCare) {
331 if (isset($this->_params
[0][$name])) {
332 $defaults[$name] = $this->_params
[0][$name];
333 if (substr($name, 0, 7) == 'custom_') {
334 $timeField = "{$name}_time";
335 if (isset($this->_params
[0][$timeField])) {
336 $defaults[$timeField] = $this->_params
[0][$timeField];
338 if (isset($this->_params
[0]["{$name}_id"])) {
339 $defaults["{$name}_id"] = $this->_params
[0]["{$name}_id"];
342 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)
343 && !empty($this->_params
[0][$name . '_custom'])
345 $defaults[$name . '_custom'] = $this->_params
[0][$name . '_custom'];
350 $this->setDefaults($defaults);
353 //lets give meaningful status message, CRM-4320.
354 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
355 $this->assign('isRequireApproval', $this->_requireApproval
);
357 // Assign Participant Count to Lineitem Table
358 $this->assign('pricesetFieldsCount', CRM_Price_BAO_PriceSet
::getPricesetCount($this->_priceSetId
));
359 $this->addFormRule(array('CRM_Event_Form_Registration_Confirm', 'formRule'), $this);
365 * @param array $fields
366 * @param array $files
367 * @param CRM_Core_Form $self
371 public static function formRule($fields, $files, $self) {
373 $eventFull = CRM_Event_BAO_Participant
::eventFull($self->_eventId
, FALSE, CRM_Utils_Array
::value('has_waitlist', $self->_values
['event']));
374 if ($eventFull && empty($self->_allowConfirmation
)) {
375 if (empty($self->_allowWaitlist
)) {
376 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "reset=1&id={$self->_eventId}", FALSE, NULL, FALSE, TRUE));
379 $self->_feeBlock
= $self->_values
['fee'];
380 CRM_Event_Form_Registration_Register
::formatFieldsForOptionFull($self);
382 if (!empty($self->_priceSetId
) &&
383 !$self->_requireApproval
&& !$self->_allowWaitlist
385 $priceSetErrors = self
::validatePriceSet($self, $self->_params
);
386 if (!empty($priceSetErrors)) {
387 CRM_Core_Session
::setStatus(ts('You have been returned to the start of the registration process and any sold out events have been removed from your selections. You will not be able to continue until you review your booking and select different events if you wish.'), ts('Unfortunately some of your options have now sold out for one or more participants.'), 'error');
388 CRM_Core_Session
::setStatus(ts('Please note that the options which are marked or selected are sold out for participant being viewed.'), ts('Sold out:'), 'error');
389 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "_qf_Register_display=true&qfKey={$fields['qfKey']}"));
393 return empty($priceSetErrors) ?
TRUE : $priceSetErrors;
397 * Process the form submission.
399 public function postProcess() {
400 $now = date('YmdHis');
402 $this->_params
= $this->get('params');
403 if (!empty($this->_params
[0]['contact_id'])) {
404 // unclear when this would be set & whether it could be checked in getContactID.
405 // perhaps it relates to when cid is in the url
406 //@todo someone who knows add comments on the various contactIDs in this form
407 $contactID = $this->_params
[0]['contact_id'];
410 $contactID = $this->getContactID();
413 // if a discount has been applied, lets now deduct it from the amount
414 // and fix the fee level
415 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
416 foreach ($this->_params
as $k => $v) {
417 if (CRM_Utils_Array
::value('amount', $this->_params
[$k]) > 0 && !empty($this->_params
[$k]['discountAmount'])) {
418 $this->_params
[$k]['amount'] -= $this->_params
[$k]['discountAmount'];
419 $this->_params
[$k]['amount_level'] .= CRM_Utils_Array
::value('discountMessage', $this->_params
[$k]);
422 $this->set('params', $this->_params
);
425 // CRM-4320, lets build array of cancelled additional participant ids
426 // those are drop or skip by primary at the time of confirmation.
427 // get all in and then unset those we want to process.
428 $cancelledIds = $this->_additionalParticipantIds
;
430 $params = $this->_params
;
431 if ($this->_values
['event']['is_monetary']) {
432 $this->set('finalAmount', $this->_amount
);
434 $participantCount = array();
436 //unset the skip participant from params.
437 //build the $participantCount array.
438 //maintain record for all participants.
439 foreach ($params as $participantNum => $record) {
440 if ($record == 'skip') {
441 unset($params[$participantNum]);
442 $participantCount[$participantNum] = 'skip';
444 elseif ($participantNum) {
445 $participantCount[$participantNum] = 'participant';
448 //lets get additional participant id to cancel.
449 if ($this->_allowConfirmation
&& is_array($cancelledIds)) {
450 $additonalId = CRM_Utils_Array
::value('participant_id', $record);
451 if ($additonalId && $key = array_search($additonalId, $cancelledIds)) {
452 unset($cancelledIds[$key]);
457 $payment = $registerByID = $primaryCurrencyID = $contribution = NULL;
458 $paymentObjError = ts('The system did not record payment details for this payment and so could not process the transaction. Please report this error to the site administrator.');
460 $this->participantIDS
= array();
462 foreach ($params as $key => $value) {
463 CRM_Event_Form_Registration_Confirm
::fixLocationFields($value, $fields, $this);
464 //unset the billing parameters if it is pay later mode
465 //to avoid creation of billing location
466 // @todo - the reasoning for this is unclear - elsewhere we check what fields are provided by
467 // the form & if billing fields exist we create the address, relying on the form to collect
468 // only information we intend to store.
469 if ($this->_allowWaitlist
470 ||
$this->_requireApproval
471 ||
(!empty($value['is_pay_later']) && !$this->_isBillingAddressRequiredForPayLater
)
472 ||
empty($value['is_primary'])
474 $billingFields = array(
475 "email-{$this->_bltID}",
476 'billing_first_name',
477 'billing_middle_name',
479 "billing_street_address-{$this->_bltID}",
480 "billing_city-{$this->_bltID}",
481 "billing_state_province-{$this->_bltID}",
482 "billing_state_province_id-{$this->_bltID}",
483 "billing_postal_code-{$this->_bltID}",
484 "billing_country-{$this->_bltID}",
485 "billing_country_id-{$this->_bltID}",
486 "address_name-{$this->_bltID}",
488 foreach ($billingFields as $field) {
489 unset($value[$field]);
491 if (!empty($value['is_pay_later'])) {
492 $this->_values
['params']['is_pay_later'] = TRUE;
496 //Unset ContactID for additional participants and set RegisterBy Id.
497 if (empty($value['is_primary'])) {
498 $contactID = CRM_Utils_Array
::value('contact_id', $value);
499 $registerByID = $this->get('registerByID');
501 $value['registered_by_id'] = $registerByID;
505 $value['amount'] = $this->_totalAmount
;
508 $contactID = CRM_Event_Form_Registration_Confirm
::updateContactFields($contactID, $value, $fields, $this);
510 // lets store the contactID in the session
511 // we dont store in userID in case the user is doing multiple
513 // for things like tell a friend
514 if (!$this->getContactID() && !empty($value['is_primary'])) {
515 $session = CRM_Core_Session
::singleton();
516 $session->set('transaction.userID', $contactID);
519 $value['description'] = ts('Online Event Registration') . ': ' . $this->_values
['event']['title'];
520 $value['accountingCode'] = CRM_Utils_Array
::value('accountingCode',
521 $this->_values
['event']
525 if ($this->_allowWaitlist ||
$this->_requireApproval
) {
526 //get the participant statuses.
527 $waitingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Waiting'");
528 if ($this->_allowWaitlist
) {
529 $value['participant_status_id'] = $value['participant_status'] = array_search('On waitlist', $waitingStatuses);
532 $value['participant_status_id'] = $value['participant_status'] = array_search('Awaiting approval', $waitingStatuses);
535 //there might be case user seleted pay later and
536 //now becomes part of run time waiting list.
537 $value['is_pay_later'] = FALSE;
540 // required only if paid event
541 if ($this->_values
['event']['is_monetary'] && !($this->_allowWaitlist ||
$this->_requireApproval
)) {
542 if (is_array($this->_paymentProcessor
)) {
543 $payment = $this->_paymentProcessor
['object'];
545 if (!empty($this->_paymentProcessor
) && $this->_paymentProcessor
['object']->supports('preApproval')) {
546 $preApprovalParams = $this->_paymentProcessor
['object']->getPreApprovalDetails($this->get('pre_approval_parameters'));
547 $value = array_merge($value, $preApprovalParams);
551 if (!empty($value['is_pay_later']) ||
552 $value['amount'] == 0 ||
553 // The concept of contributeMode is deprecated.
554 $this->_contributeMode
== 'checkout' ||
555 $this->_contributeMode
== 'notify'
557 if ($value['amount'] != 0) {
559 //get the participant statuses.
560 $pendingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Pending'");
561 $status = !empty($value['is_pay_later']) ?
'Pending from pay later' : 'Pending from incomplete transaction';
562 $value['participant_status_id'] = $value['participant_status'] = array_search($status, $pendingStatuses);
565 elseif (!empty($value['is_primary'])) {
566 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $value, $value, TRUE);
567 // payment email param can be empty for _bltID mapping
568 // thus provide mapping for it with a different email value
569 if (empty($value['email'])) {
570 $value['email'] = CRM_Utils_Array
::valueByRegexKey('/^email-/', $value);
573 if (is_object($payment)) {
575 $result = $payment->doPayment($value);
576 $value = array_merge($value, $result);
578 catch (\Civi\Payment\Exception\PaymentProcessorException
$e) {
579 CRM_Core_Session
::singleton()->setStatus($e->getMessage());
580 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "id={$this->_eventId}"));
584 CRM_Core_Error
::fatal($paymentObjError);
588 $value['receive_date'] = $now;
589 if ($this->_allowConfirmation
) {
590 $value['participant_register_date'] = $this->_values
['participant']['register_date'];
593 $createContrib = ($value['amount'] != 0) ?
TRUE : FALSE;
594 // force to create zero amount contribution, CRM-5095
595 if (!$createContrib && ($value['amount'] == 0)
596 && $this->_priceSetId
&& $this->_lineItem
598 $createContrib = TRUE;
601 if ($createContrib && !empty($value['is_primary']) &&
602 !$this->_allowWaitlist
&& !$this->_requireApproval
604 // if paid event add a contribution record
605 //if primary participant contributing additional amount
606 //append (multiple participants) to its fee level. CRM-4196.
607 $isAdditionalAmount = FALSE;
608 if (count($params) > 1) {
609 $isAdditionalAmount = TRUE;
612 //passing contribution id is already registered.
613 $contribution = self
::processContribution($this, $value, $result, $contactID, $pending, $isAdditionalAmount);
614 $value['contributionID'] = $contribution->id
;
615 $value['contributionTypeID'] = $contribution->financial_type_id
;
616 $value['receive_date'] = $contribution->receive_date
;
617 $value['trxn_id'] = $contribution->trxn_id
;
618 $value['contributionID'] = $contribution->id
;
619 $value['contributionTypeID'] = $contribution->financial_type_id
;
621 $value['contactID'] = $contactID;
622 $value['eventID'] = $this->_eventId
;
623 $value['item_name'] = $value['description'];
626 if (!empty($value['contributionID'])) {
627 $this->_values
['contributionId'] = $value['contributionID'];
631 if (!empty($value['is_primary'])) {
632 $primaryCurrencyID = CRM_Utils_Array
::value('currencyID', $value);
634 if (empty($value['currencyID'])) {
635 $value['currencyID'] = $primaryCurrencyID;
638 // CRM-11182 - Confirmation page might not be monetary
639 if ($this->_values
['event']['is_monetary']) {
640 if (!$pending && !empty($value['is_primary']) &&
641 !$this->_allowWaitlist
&& !$this->_requireApproval
643 // transactionID & receive date required while building email template
644 $this->assign('trxn_id', $value['trxn_id']);
645 $this->assign('receive_date', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
646 $this->set('receiveDate', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
647 $this->set('trxnId', CRM_Utils_Array
::value('trxn_id', $value));
651 $value['fee_amount'] = CRM_Utils_Array
::value('amount', $value);
652 $this->set('value', $value);
654 // handle register date CRM-4320
655 if ($this->_allowConfirmation
) {
656 $registerDate = CRM_Utils_Array
::value('participant_register_date', $params);
658 elseif (!empty($params['participant_register_date']) &&
659 is_array($params['participant_register_date']) &&
660 !empty($params['participant_register_date'])
662 $registerDate = CRM_Utils_Date
::format($params['participant_register_date']);
665 $registerDate = date('YmdHis');
667 $this->assign('register_date', $registerDate);
669 $this->confirmPostProcess($contactID, $contribution, $payment);
672 //handle if no additional participant.
673 if (!$registerByID) {
674 $registerByID = $this->get('registerByID');
677 $this->set('participantIDs', $this->_participantIDS
);
679 // create line items, CRM-5313
680 if ($this->_priceSetId
&&
681 !empty($this->_lineItem
)
683 // take all processed participant ids.
684 $allParticipantIds = $this->_participantIDS
;
686 // when participant re-walk wizard.
687 if ($this->_allowConfirmation
&&
688 !empty($this->_additionalParticipantIds
)
690 $allParticipantIds = array_merge(array($registerByID), $this->_additionalParticipantIds
);
693 $entityTable = 'civicrm_participant';
694 $invoiceSettings = Civi
::settings()->get('contribution_invoice_settings');
695 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
697 $dataArray = array();
698 foreach ($this->_lineItem
as $key => $value) {
699 if ($value == 'skip') {
702 if ($entityId = CRM_Utils_Array
::value($key, $allParticipantIds)) {
703 // do cleanup line items if participant re-walking wizard.
704 if ($this->_allowConfirmation
) {
705 CRM_Price_BAO_LineItem
::deleteLineItems($entityId, $entityTable);
707 $lineItem[$this->_priceSetId
] = $value;
708 CRM_Price_BAO_LineItem
::processPriceSet($entityId, $lineItem, $contribution, $entityTable);
711 foreach ($value as $line) {
712 if (isset($line['tax_amount']) && isset($line['tax_rate'])) {
713 $totalTaxAmount = $line['tax_amount'] +
$totalTaxAmount;
714 if (isset($dataArray[$line['tax_rate']])) {
715 $dataArray[$line['tax_rate']] = $dataArray[$line['tax_rate']] + CRM_Utils_Array
::value('tax_amount', $line);
718 $dataArray[$line['tax_rate']] = CRM_Utils_Array
::value('tax_amount', $line);
725 $this->assign('dataArray', $dataArray);
726 $this->assign('totalTaxAmount', $totalTaxAmount);
730 //update status and send mail to cancelled additional participants, CRM-4320
731 if ($this->_allowConfirmation
&& is_array($cancelledIds) && !empty($cancelledIds)) {
732 $cancelledId = array_search('Cancelled',
733 CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Negative'")
735 CRM_Event_BAO_Participant
::transitionParticipants($cancelledIds, $cancelledId);
739 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
743 // for Transfer checkout.
744 // The concept of contributeMode is deprecated.
745 if (($this->_contributeMode
== 'checkout' ||
746 $this->_contributeMode
== 'notify'
747 ) && empty($params[0]['is_pay_later']) &&
748 !$this->_allowWaitlist
&& !$this->_requireApproval
&&
749 $this->_totalAmount
> 0
752 $primaryParticipant = $this->get('primaryParticipant');
754 if (empty($primaryParticipant['participantID'])) {
755 $primaryParticipant['participantID'] = $registerByID;
758 //build an array of custom profile and assigning it to template
759 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, $this->_values
, NULL, $isTest);
760 if (count($customProfile)) {
761 $this->assign('customProfile', $customProfile);
762 $this->set('customProfile', $customProfile);
765 // do a transfer only if a monetary payment greater than 0
766 if ($this->_values
['event']['is_monetary'] && $primaryParticipant) {
767 if ($payment && is_object($payment)) {
768 //CRM 14512 provide line items of all participants to payment gateway
769 $primaryContactId = $this->get('primaryContactId');
771 //build an array of cId/pId of participants
772 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, NULL, $primaryContactId, $isTest, TRUE);
774 //need to copy, since we are unsetting on the way.
775 $copyParticipantCountLines = $participantCount;
777 //lets carry all participant params w/ values.
778 foreach ($additionalIDs as $participantID => $contactId) {
779 $participantNum = NULL;
780 $participantNum = $participantID;
781 if ($participantID == $registerByID) {
782 // This is the is primary participant.
786 if ($participantNum = array_search('participant', $copyParticipantCountLines)) {
787 //if no participant found break.
788 if ($participantNum === NULL) {
791 //unset current particpant so we don't check them again
792 unset($copyParticipantCountLines[$participantNum]);
795 // get values of line items
796 if ($this->_amount
) {
798 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
799 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
800 $params[$participantNum]['amounts'] = $amount;
803 if (!empty($this->_lineItem
)) {
804 $lineItems = $this->_lineItem
;
806 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
807 $lineItem[] = $lineItemValue;
809 $params[$participantNum]['lineItem'] = $lineItem;
812 //only add additional particpants and not the primary particpant as we already have that
813 //added to $primaryParticipant so that this change doesn't break or require changes to
814 //existing gateway implementations
815 $primaryParticipant['participants_info'][$participantID] = $params[$participantNum];
818 //get event custom field information
819 $groupTree = CRM_Core_BAO_CustomGroup
::getTree('Event', $this, $this->_eventId
, 0, $this->_values
['event']['event_type_id']);
820 $primaryParticipant['eventCustomFields'] = $groupTree;
822 // call postprocess hook before leaving
823 $this->postProcessHook();
824 // this does not return
825 $payment->doPayment($primaryParticipant, 'event');
828 CRM_Core_Error
::fatal($paymentObjError);
833 //otherwise send mail Confirmation/Receipt
834 $primaryContactId = $this->get('primaryContactId');
836 //build an array of cId/pId of participants
837 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID,
838 NULL, $primaryContactId, $isTest,
841 //lets send mails to all with meaningful text, CRM-4320.
842 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
843 $this->assign('isRequireApproval', $this->_requireApproval
);
845 //need to copy, since we are unsetting on the way.
846 $copyParticipantCount = $participantCount;
848 //lets carry all paticipant params w/ values.
849 foreach ($additionalIDs as $participantID => $contactId) {
850 $participantNum = NULL;
851 if ($participantID == $registerByID) {
855 if ($participantNum = array_search('participant', $copyParticipantCount)) {
856 unset($copyParticipantCount[$participantNum]);
859 if ($participantNum === NULL) {
863 //carry the participant submitted values.
864 $this->_values
['params'][$participantID] = $params[$participantNum];
867 foreach ($additionalIDs as $participantID => $contactId) {
869 if ($participantID == $registerByID) {
870 //set as Primary Participant
871 $this->assign('isPrimary', 1);
872 //build an array of custom profile and assigning it to template.
873 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($participantID, $this->_values
, NULL, $isTest);
875 if (count($customProfile)) {
876 $this->assign('customProfile', $customProfile);
877 $this->set('customProfile', $customProfile);
879 $this->_values
['params']['additionalParticipant'] = FALSE;
882 //take the Additional participant number.
883 if ($participantNum = array_search('participant', $participantCount)) {
884 unset($participantCount[$participantNum]);
886 // Change $this->_values['participant'] to include additional participant values
887 $ids = $participantValues = array();
888 $participantParams = array('id' => $participantID);
889 CRM_Event_BAO_Participant
::getValues($participantParams, $participantValues, $ids);
890 $this->_values
['participant'] = $participantValues[$participantID];
892 $this->assign('isPrimary', 0);
893 $this->assign('customProfile', NULL);
894 //Additional Participant should get only it's payment information
895 if (!empty($this->_amount
)) {
897 $params = $this->get('params');
898 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
899 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
900 $this->assign('amounts', $amount);
902 if ($this->_lineItem
) {
903 $lineItems = $this->_lineItem
;
905 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
906 $lineItem[] = $lineItemValue;
909 $individual = $this->get('individual');
910 $dataArray[key($dataArray)] = $individual[$participantNum]['totalTaxAmt'];
911 $this->assign('dataArray', $dataArray);
912 $this->assign('totalAmount', $individual[$participantNum]['totalAmtWithTax']);
913 $this->assign('totalTaxAmount', $individual[$participantNum]['totalTaxAmt']);
914 $this->assign('individual', array($individual[$participantNum]));
916 $this->assign('lineItem', $lineItem);
918 $this->_values
['params']['additionalParticipant'] = TRUE;
919 $this->assign('isAdditionalParticipant', $this->_values
['params']['additionalParticipant']);
922 //pass these variables since these are run time calculated.
923 $this->_values
['params']['isOnWaitlist'] = $this->_allowWaitlist
;
924 $this->_values
['params']['isRequireApproval'] = $this->_requireApproval
;
926 //send mail to primary as well as additional participants.
927 $this->assign('contactID', $contactId);
928 $this->assign('participantID', $participantID);
929 CRM_Event_BAO_Event
::sendMail($contactId, $this->_values
, $participantID, $isTest);
935 * Process the contribution.
937 * @param CRM_Core_Form $form
938 * @param array $params
939 * @param array $result
940 * @param int $contactID
941 * @param bool $pending
942 * @param bool $isAdditionalAmount
944 * @return \CRM_Contribute_BAO_Contribution
946 public static function processContribution(
947 &$form, $params, $result, $contactID,
948 $pending = FALSE, $isAdditionalAmount = FALSE
950 $transaction = new CRM_Core_Transaction();
952 $now = date('YmdHis');
955 if (!empty($form->_values
['event']['is_email_confirm'])) {
959 if ($isAdditionalAmount) {
960 $params['amount_level'] = $params['amount_level'] . ts(' (multiple participants)') . CRM_Core_DAO
::VALUE_SEPARATOR
;
963 $contribParams = array(
964 'contact_id' => $contactID,
965 'financial_type_id' => !empty($form->_values
['event']['financial_type_id']) ?
$form->_values
['event']['financial_type_id'] : $params['financial_type_id'],
966 'receive_date' => $now,
967 'total_amount' => $params['amount'],
968 'tax_amount' => $params['tax_amount'],
969 'amount_level' => $params['amount_level'],
970 'invoice_id' => $params['invoiceID'],
971 'currency' => $params['currencyID'],
972 'source' => !empty($params['participant_source']) ?
$params['participant_source'] : $params['description'],
973 'is_pay_later' => CRM_Utils_Array
::value('is_pay_later', $params, 0),
974 'campaign_id' => CRM_Utils_Array
::value('campaign_id', $params),
977 if (empty($params['is_pay_later'])) {
978 $contribParams['payment_instrument_id'] = 1;
981 if (!$pending && $result) {
982 $contribParams +
= array(
983 'fee_amount' => CRM_Utils_Array
::value('fee_amount', $result),
984 'net_amount' => CRM_Utils_Array
::value('net_amount', $result, $params['amount']),
985 'trxn_id' => $result['trxn_id'],
986 'receipt_date' => $receiptDate,
990 $allStatuses = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
991 $contribParams['contribution_status_id'] = array_search('Completed', $allStatuses);
993 $contribParams['contribution_status_id'] = array_search('Pending', $allStatuses);
996 $contribParams['is_test'] = 0;
997 if ($form->_action
& CRM_Core_Action
::PREVIEW || CRM_Utils_Array
::value('mode', $params) == 'test') {
998 $contribParams['is_test'] = 1;
1002 if (!empty($contribParams['invoice_id'])) {
1003 $contribID = CRM_Core_DAO
::getFieldValue('CRM_Contribute_DAO_Contribution',
1004 $contribParams['invoice_id'],
1012 $ids['contribution'] = $contribID;
1013 $contribParams['id'] = $contribID;
1016 //create an contribution address
1017 // The concept of contributeMode is deprecated. Elsewhere we use the function processBillingAddress() - although
1018 // currently that is only inherited by back-office forms.
1019 if ($form->_contributeMode
!= 'notify' && empty($params['is_pay_later'])) {
1020 $contribParams['address_id'] = CRM_Contribute_BAO_Contribution
::createAddress($params, $form->_bltID
);
1023 $contribParams['payment_processor'] = CRM_Utils_Array
::value('payment_processor', $params);
1024 $contribParams['skipLineItem'] = 1;
1025 // create contribution record
1026 $contribution = CRM_Contribute_BAO_Contribution
::add($contribParams, $ids);
1028 CRM_Event_BAO_Participant
::createDiscountTrxn($form->_eventId
, $contribParams, CRM_Utils_Array
::value('amount_priceset_level_radio', $params, NULL));
1030 // process soft credit / pcp pages
1031 if (!empty($params['pcp_made_through_id'])) {
1032 CRM_Contribute_BAO_ContributionSoft
::formatSoftCreditParams($params, $form);
1033 CRM_Contribute_BAO_ContributionSoft
::processSoftContribution($params, $contribution);
1036 $transaction->commit();
1038 return $contribution;
1042 * Fix the Location Fields.
1044 * @param array $params
1045 * @param array $fields
1046 * @param CRM_Core_Form $form
1048 public static function fixLocationFields(&$params, &$fields, &$form) {
1049 if (!empty($form->_fields
)) {
1050 foreach ($form->_fields
as $name => $dontCare) {
1055 if (is_array($fields)) {
1056 if (!array_key_exists('first_name', $fields)) {
1057 $nameFields = array('first_name', 'middle_name', 'last_name');
1058 foreach ($nameFields as $name) {
1060 if (array_key_exists("billing_$name", $params)) {
1061 $params[$name] = $params["billing_{$name}"];
1062 $params['preserveDBName'] = TRUE;
1068 // also add location name to the array
1069 if ($form->_values
['event']['is_monetary']) {
1070 $params["address_name-{$form->_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);
1071 $fields["address_name-{$form->_bltID}"] = 1;
1073 $fields["email-{$form->_bltID}"] = 1;
1074 $fields['email-Primary'] = 1;
1076 //if its pay later or additional participant set email address as primary.
1077 if ((!empty($params['is_pay_later']) ||
empty($params['is_primary']) ||
1078 !$form->_values
['event']['is_monetary'] ||
1079 $form->_allowWaitlist ||
1080 $form->_requireApproval
1081 ) && !empty($params["email-{$form->_bltID}"])
1083 $params['email-Primary'] = $params["email-{$form->_bltID}"];
1088 * Update contact fields.
1090 * @param int $contactID
1091 * @param array $params
1092 * @param array $fields
1093 * @param CRM_Core_Form $form
1097 public static function updateContactFields($contactID, $params, $fields, &$form) {
1098 //add the contact to group, if add to group is selected for a
1099 //particular uf group
1101 // get the add to groups
1102 $addToGroups = array();
1104 if (!empty($form->_fields
)) {
1105 foreach ($form->_fields
as $key => $value) {
1106 if (!empty($value['add_to_group_id'])) {
1107 $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id'];
1112 // check for profile double opt-in and get groups to be subscribed
1113 $subscribeGroupIds = CRM_Core_BAO_UFGroup
::getDoubleOptInGroupIds($params, $contactID);
1115 foreach ($addToGroups as $k) {
1116 if (array_key_exists($k, $subscribeGroupIds)) {
1117 unset($addToGroups[$k]);
1121 // since we are directly adding contact to group lets unset it from mailing
1122 if (!empty($addToGroups)) {
1123 foreach ($addToGroups as $groupId) {
1124 if (isset($subscribeGroupIds[$groupId])) {
1125 unset($subscribeGroupIds[$groupId]);
1130 $ctype = CRM_Core_DAO
::getFieldValue(
1131 'CRM_Contact_DAO_Contact',
1136 if (array_key_exists('contact_id', $params) && empty($params['contact_id'])) {
1137 // we unset this here because the downstream function ignores the contactID we give it
1138 // if it is set & it is difficult to understand the implications of 'fixing' this downstream
1139 // but if we are passing a contact id into this function it's reasonable to assume we don't
1141 unset($params['contact_id']);
1144 $contactID = CRM_Contact_BAO_Contact
::createProfileContact(
1156 foreach (CRM_Contact_BAO_Contact
::$_greetingTypes as $greeting) {
1157 if (!isset($params[$greeting . '_id'])) {
1158 $params[$greeting . '_id'] = CRM_Contact_BAO_Contact_Utils
::defaultGreeting('Individual', $greeting);
1162 $contactID = CRM_Contact_BAO_Contact
::createProfileContact($params,
1170 $form->set('contactID', $contactID);
1173 //get email primary first if exist
1174 $subscribtionEmail = array('email' => CRM_Utils_Array
::value('email-Primary', $params));
1175 if (!$subscribtionEmail['email']) {
1176 $subscribtionEmail['email'] = CRM_Utils_Array
::value("email-{$form->_bltID}", $params);
1178 // subscribing contact to groups
1179 if (!empty($subscribeGroupIds) && $subscribtionEmail['email']) {
1180 CRM_Mailing_Event_BAO_Subscribe
::commonSubscribe($subscribeGroupIds, $subscribtionEmail, $contactID);
1189 * @param CRM_Core_Form $form
1191 public static function assignProfiles(&$form) {
1192 $participantParams = $form->_params
;
1193 $formattedValues = $profileFields = array();
1195 foreach ($participantParams as $participantNum => $participantValue) {
1196 if ($participantNum) {
1197 $prefix1 = 'additional';
1198 $prefix2 = 'additional_';
1204 if ($participantValue != 'skip') {
1205 //get the customPre profile info
1206 if (!empty($form->_values
[$prefix2 . 'custom_pre_id'])) {
1207 $values = $groupName = array();
1208 CRM_Event_BAO_Event
::displayProfile($participantValue,
1209 $form->_values
[$prefix2 . 'custom_pre_id'],
1215 if (count($values)) {
1216 $formattedValues[$count][$prefix1 . 'CustomPre'] = $values;
1218 $formattedValues[$count][$prefix1 . 'CustomPreGroupTitle'] = CRM_Utils_Array
::value('groupTitle', $groupName);
1220 //get the customPost profile info
1221 if (!empty($form->_values
[$prefix2 . 'custom_post_id'])) {
1222 $values = $groupName = array();
1223 foreach ($form->_values
[$prefix2 . 'custom_post_id'] as $gids) {
1225 CRM_Event_BAO_Event
::displayProfile($participantValue,
1231 $values[$gids] = $val;
1232 $groupName[$gids] = $group;
1235 if (count($values)) {
1236 $formattedValues[$count][$prefix1 . 'CustomPost'] = $values;
1239 if (isset($formattedValues[$count][$prefix1 . 'CustomPre'])) {
1240 $formattedValues[$count][$prefix1 . 'CustomPost'] = array_diff_assoc($formattedValues[$count][$prefix1 . 'CustomPost'],
1241 $formattedValues[$count][$prefix1 . 'CustomPre']
1245 $formattedValues[$count][$prefix1 . 'CustomPostGroupTitle'] = $groupName;
1249 $form->_fields
= $profileFields;
1251 if (!empty($formattedValues)) {
1252 $form->assign('primaryParticipantProfile', $formattedValues[1]);
1253 $form->set('primaryParticipantProfile', $formattedValues[1]);
1255 unset($formattedValues[1]);
1256 $form->assign('addParticipantProfile', $formattedValues);
1257 $form->set('addParticipantProfile', $formattedValues);