3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
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 +--------------------------------------------------------------------+
32 * @copyright CiviCRM LLC (c) 2004-2014
38 * This class generates form components for processing Event
41 class CRM_Event_Form_Registration_Confirm
extends CRM_Event_Form_Registration
{
44 * The values for the contribution db object
60 * Set variables up before form is built
65 function preProcess() {
68 // lineItem isn't set until Register postProcess
69 $this->_lineItem
= $this->get('lineItem');
71 $this->_params
= $this->get('params');
72 $this->_params
[0]['tax_amount'] = $this->get('tax_amount');
74 $this->_params
[0]['is_pay_later'] = $this->get('is_pay_later');
75 $this->assign('is_pay_later', $this->_params
[0]['is_pay_later']);
76 if ($this->_params
[0]['is_pay_later']) {
77 $this->assign('pay_later_receipt', $this->_values
['event']['pay_later_receipt']);
80 CRM_Utils_Hook
::eventDiscount($this, $this->_params
);
82 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
83 $this->set('hookDiscount', $this->_params
[0]['discount']);
84 $this->assign('hookDiscount', $this->_params
[0]['discount']);
87 if ($this->_contributeMode
== 'express') {
89 // rfp == redirect from paypal
90 $rfp = CRM_Utils_Request
::retrieve('rfp', 'Boolean',
91 CRM_Core_DAO
::$_nullObject, FALSE, NULL, 'GET'
94 //we lost rfp in case of additional participant. So set it explicitly.
95 if ($rfp || CRM_Utils_Array
::value('additional_participants', $this->_params
[0], FALSE)) {
96 $payment = CRM_Core_Payment
::singleton($this->_mode
, $this->_paymentProcessor
, $this);
97 $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.');
98 if (is_object($payment))
99 $expressParams = $payment->getExpressCheckoutDetails($this->get('token'));
101 CRM_Core_Error
::fatal($paymentObjError);
103 $params['payer'] = CRM_Utils_Array
::value('payer', $expressParams);
104 $params['payer_id'] = $expressParams['payer_id'];
105 $params['payer_status'] = $expressParams['payer_status'];
107 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $expressParams, $params, FALSE);
109 // fix state and country id if present
110 if (isset($params["billing_state_province_id-{$this->_bltID}"])) {
111 $params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($params["billing_state_province_id-{$this->_bltID}"]);
113 if (isset($params['billing_country_id'])) {
114 $params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant
::countryIsoCode($params["billing_country_id-{$this->_bltID}"]);
117 // set a few other parameters for PayPal
118 $params['token'] = $this->get('token');
119 $params['amount'] = $this->_params
[0]['amount'];
120 if (!empty($this->_params
[0]['discount'])) {
121 $params['discount'] = $this->_params
[0]['discount'];
122 $params['discountAmount'] = $this->_params
[0]['discountAmount'];
123 $params['discountMessage'] = $this->_params
[0]['discountMessage'];
125 if (!empty($this->_params
[0]['amount_priceset_level_radio'])) {
126 $params['amount_priceset_level_radio'] = $this->_params
[0]['amount_priceset_level_radio'];
128 $params['amount_level'] = $this->_params
[0]['amount_level'];
129 $params['currencyID'] = $this->_params
[0]['currencyID'];
130 $params['payment_action'] = 'Sale';
132 // also merge all the other values from the profile fields
133 $values = $this->controller
->exportValues('Register');
136 "street_address-{$this->_bltID}",
137 "city-{$this->_bltID}",
138 "state_province_id-{$this->_bltID}",
139 "postal_code-{$this->_bltID}",
140 "country_id-{$this->_bltID}",
143 foreach ($values as $name => $value) {
145 if (!in_array($name, $skipFields)) {
146 $params[$name] = $value;
149 $this->set('getExpressCheckoutDetails', $params);
152 $params = $this->get('getExpressCheckoutDetails');
154 $this->_params
[0] = $params;
155 $this->_params
[0]['is_primary'] = 1;
158 //process only primary participant params.
159 $registerParams = $this->_params
[0];
160 if (isset($registerParams["billing_state_province_id-{$this->_bltID}"])
161 && $registerParams["billing_state_province_id-{$this->_bltID}"]
163 $registerParams["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($registerParams["billing_state_province_id-{$this->_bltID}"]);
166 if (isset($registerParams["billing_country_id-{$this->_bltID}"]) && $registerParams["billing_country_id-{$this->_bltID}"]) {
167 $registerParams["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant
::countryIsoCode($registerParams["billing_country_id-{$this->_bltID}"]);
169 if (isset($registerParams['credit_card_exp_date'])) {
170 $registerParams['year'] = CRM_Core_Payment_Form
::getCreditCardExpirationYear($registerParams);
171 $registerParams['month'] = CRM_Core_Payment_Form
::getCreditCardExpirationMonth($registerParams);
173 if ($this->_values
['event']['is_monetary']) {
174 $registerParams['ip_address'] = CRM_Utils_System
::ipAddress();
175 $registerParams['currencyID'] = $this->_params
[0]['currencyID'];
176 $registerParams['payment_action'] = 'Sale';
178 //assign back primary participant params.
179 $this->_params
[0] = $registerParams;
182 if ($this->_values
['event']['is_monetary']) {
183 $this->_params
[0]['invoiceID'] = $this->get('invoiceID');
185 $this->assign('defaultRole', FALSE);
186 if (CRM_Utils_Array
::value('defaultRole', $this->_params
[0]) == 1) {
187 $this->assign('defaultRole', TRUE);
190 if (empty($this->_params
[0]['participant_role_id']) &&
191 $this->_values
['event']['default_role_id']
193 $this->_params
[0]['participant_role_id'] = $this->_values
['event']['default_role_id'];
196 if (isset($this->_values
['event']['confirm_title'])) {
197 CRM_Utils_System
::setTitle($this->_values
['event']['confirm_title']);
201 $params = CRM_Contribute_Form_Contribution_Confirm
::processPcp($this, $this->_params
[0]);
202 $this->_params
[0] = $params;
205 $this->set('params', $this->_params
);
209 * Overwrite action, since we are only showing elements in frozen mode
210 * no help display needed
215 function getAction() {
216 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
217 return CRM_Core_Action
::VIEW | CRM_Core_Action
::PREVIEW
;
220 return CRM_Core_Action
::VIEW
;
225 * Build the form object
230 public function buildQuickForm() {
231 $this->assignToTemplate();
233 if ($this->_values
['event']['is_monetary'] &&
234 ($this->_params
[0]['amount'] ||
$this->_params
[0]['amount'] == 0)
236 $this->_amount
= array();
239 foreach ($this->_params
as $k => $v) {
240 //display tax amount on confirmation page
241 $taxAmount +
= $v['tax_amount'];
244 'first_name', 'last_name') as $name) {
245 if (isset($v['billing_' . $name]) &&
248 $v[$name] = $v['billing_' . $name];
252 if (!empty($v['first_name']) && !empty($v['last_name'])) {
253 $append = $v['first_name'] . ' ' . $v['last_name'];
256 //use an email if we have one
257 foreach ($v as $v_key => $v_val) {
258 if (substr($v_key, 0, 6) == 'email-') {
259 $append = $v[$v_key];
264 $this->_amount
[$k]['amount'] = $v['amount'];
265 if (!empty($v['discountAmount'])) {
266 $this->_amount
[$k]['amount'] -= $v['discountAmount'];
269 $this->_amount
[$k]['label'] = preg_replace('/\ 1/', '', $v['amount_level']) . ' - ' . $append;
270 $this->_part
[$k]['info'] = CRM_Utils_Array
::value('first_name', $v) . ' ' . CRM_Utils_Array
::value('last_name', $v);
271 if (empty($v['first_name'])) {
272 $this->_part
[$k]['info'] = $append;
274 $this->_totalAmount
= $this->_totalAmount +
$this->_amount
[$k]['amount'];
275 if (!empty($v['is_primary'])) {
276 $this->set('primaryParticipantAmount', $this->_amount
[$k]['amount']);
281 $invoiceSettings = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
,'contribution_invoice_settings');
282 $taxTerm = CRM_Utils_Array
::value('tax_term', $invoiceSettings);
283 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
285 $this->assign('totalTaxAmount', $taxAmount);
286 $this->assign('taxTerm', $taxTerm);
288 $this->assign('part', $this->_part
);
289 $this->set('part', $this->_part
);
290 $this->assign('amounts', $this->_amount
);
291 $this->assign('totalAmount', $this->_totalAmount
);
292 $this->set('totalAmount', $this->_totalAmount
);
295 if ($this->_priceSetId
&& !CRM_Core_DAO
::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId
, 'is_quick_config')) {
296 $lineItemForTemplate = array();
297 $getTaxDetails = FALSE;
298 foreach ($this->_lineItem
as $key => $value) {
299 if (!empty($value)) {
300 $lineItemForTemplate[$key] = $value;
303 foreach ($value as $v) {
304 if (isset($v['tax_rate'])) {
305 $getTaxDetails = TRUE;
310 if (!empty($lineItemForTemplate)) {
311 $this->assign('lineItem', $lineItemForTemplate);
313 $this->assign('getTaxDetails', $getTaxDetails);
316 //display additional participants profile.
317 self
::assignProfiles($this);
319 //consider total amount.
320 $this->assign('isAmountzero', ($this->_totalAmount
<= 0) ?
TRUE : FALSE);
322 if ($this->_paymentProcessor
['payment_processor_type'] == 'Google_Checkout' && empty($this->_params
[0]['is_pay_later']) && !($this->_params
[0]['amount'] == 0) &&
323 !$this->_allowWaitlist
&& !$this->_requireApproval
325 $this->_checkoutButtonName
= $this->getButtonName('next', 'checkout');
327 $this->_checkoutButtonName
,
328 $this->_paymentProcessor
['url_button'],
329 array('class' => 'crm-form-submit')
332 $this->addButtons(array(
335 'name' => ts('<< Go Back'),
341 $contribButton = ts('Continue >>');
342 $this->addButtons(array(
345 'name' => ts('<< Go Back'),
349 'name' => $contribButton,
351 'js' => array('onclick' => "return submitOnce(this,'" . $this->_name
. "','" . ts('Processing') . "');"),
359 if (!empty($this->_fields
)) {
360 foreach ($this->_fields
as $name => $dontCare) {
364 $fields["billing_state_province-{$this->_bltID}"] = $fields["billing_country-{$this->_bltID}"] = $fields["email-{$this->_bltID}"] = 1;
365 foreach ($fields as $name => $dontCare) {
366 if (isset($this->_params
[0][$name])) {
367 $defaults[$name] = $this->_params
[0][$name];
368 if (substr($name, 0, 7) == 'custom_') {
369 $timeField = "{$name}_time";
370 if (isset($this->_params
[0][$timeField])) {
371 $defaults[$timeField] = $this->_params
[0][$timeField];
373 if (isset($this->_params
[0]["{$name}_id"])) {
374 $defaults["{$name}_id"] = $this->_params
[0]["{$name}_id"];
377 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)
378 && !empty($this->_params
[0][$name . '_custom'])
380 $defaults[$name . '_custom'] = $this->_params
[0][$name . '_custom'];
385 $this->setDefaults($defaults);
388 //lets give meaningful status message, CRM-4320.
389 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
390 $this->assign('isRequireApproval', $this->_requireApproval
);
392 // Assign Participant Count to Lineitem Table
393 $this->assign('pricesetFieldsCount', CRM_Price_BAO_PriceSet
::getPricesetCount($this->_priceSetId
));
394 $this->addFormRule(array('CRM_Event_Form_Registration_Confirm', 'formRule'), $this);
397 static function formRule($fields, $files, $self) {
399 $eventFull = CRM_Event_BAO_Participant
::eventFull($self->_eventId
, FALSE, CRM_Utils_Array
::value('has_waitlist', $self->_values
['event']));
400 if ($eventFull && empty($self->_allowConfirmation
)) {
401 if (empty($self->_allowWaitlist
)) {
402 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "reset=1&id={$self->_eventId}",FALSE, NULL, FALSE, TRUE));
405 $self->_feeBlock
= $self->_values
['fee'];
406 CRM_Event_Form_Registration_Register
::formatFieldsForOptionFull($self);
408 if (!empty($self->_priceSetId
)) {
409 $priceSetErrors = self
::validatePriceSet($self, $self->_params
);
410 //get price set fields errors in.
411 $errors = array_merge($errors, CRM_Utils_Array
::value(0, $priceSetErrors, array()));
414 if (!empty($errors)) {
415 $soldOutOptions = implode("<br>", $priceSetErrors['soldOutOptions']);
416 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. The following events were sold out:') , ts('Unfortunately some of your options have now sold out for one or more participants.') , 'error');
417 CRM_Core_Session
::setStatus(ts("{$soldOutOptions}") , ts('Sold out:') , 'error');
418 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "_qf_Register_display=true&qfKey=" . $fields['qfKey']));
420 return empty($errors) ?
TRUE : $errors;
423 * Process the form submission
429 public function postProcess() {
430 $now = date('YmdHis');
432 $this->_params
= $this->get('params');
433 if (!empty($this->_params
[0]['contact_id'])) {
434 // unclear when this would be set & whether it could be checked in getContactID.
435 // perhaps it relates to when cid is in the url
436 //@todo someone who knows add comments on the various contactIDs in this form
437 $contactID = $this->_params
[0]['contact_id'];
440 $contactID = $this->getContactID();
443 // if a discount has been applied, lets now deduct it from the amount
444 // and fix the fee level
445 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
446 foreach ($this->_params
as $k => $v) {
447 if (CRM_Utils_Array
::value('amount', $this->_params
[$k]) > 0 && !empty($this->_params
[$k]['discountAmount'])) {
448 $this->_params
[$k]['amount'] -= $this->_params
[$k]['discountAmount'];
449 $this->_params
[$k]['amount_level'] .= CRM_Utils_Array
::value('discountMessage', $this->_params
[$k]);
452 $this->set('params', $this->_params
);
455 // CRM-4320, lets build array of cancelled additional participant ids
456 // those are drop or skip by primary at the time of confirmation.
457 // get all in and then unset those we want to process.
458 $cancelledIds = $this->_additionalParticipantIds
;
460 $params = $this->_params
;
461 if ($this->_values
['event']['is_monetary']) {
462 $this->set('finalAmount', $this->_amount
);
464 $participantCount = array();
466 //unset the skip participant from params.
467 //build the $participantCount array.
468 //maintain record for all participants.
469 foreach ($params as $participantNum => $record) {
470 if ($record == 'skip') {
471 unset($params[$participantNum]);
472 $participantCount[$participantNum] = 'skip';
474 elseif ($participantNum) {
475 $participantCount[$participantNum] = 'participant';
478 //lets get additional participant id to cancel.
479 if ($this->_allowConfirmation
&& is_array($cancelledIds)) {
480 $additonalId = CRM_Utils_Array
::value('participant_id', $record);
481 if ($additonalId && $key = array_search($additonalId, $cancelledIds)) {
482 unset($cancelledIds[$key]);
487 $payment = $registerByID = $primaryCurrencyID = $contribution = NULL;
488 $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.');
490 $this->participantIDS
= array();
492 foreach ($params as $key => $value) {
493 CRM_Event_Form_Registration_Confirm
::fixLocationFields($value, $fields, $this);
494 //unset the billing parameters if it is pay later mode
495 //to avoid creation of billing location
496 if ($this->_allowWaitlist
497 ||
$this->_requireApproval
498 ||
(!empty($value['is_pay_later']) && !$this->_isBillingAddressRequiredForPayLater
)
499 ||
empty($value['is_primary'])
501 $billingFields = array(
502 "email-{$this->_bltID}",
503 'billing_first_name',
504 'billing_middle_name',
506 "billing_street_address-{$this->_bltID}",
507 "billing_city-{$this->_bltID}",
508 "billing_state_province-{$this->_bltID}",
509 "billing_state_province_id-{$this->_bltID}",
510 "billing_postal_code-{$this->_bltID}",
511 "billing_country-{$this->_bltID}",
512 "billing_country_id-{$this->_bltID}",
513 "address_name-{$this->_bltID}",
515 foreach ($billingFields as $field) {
516 unset($value[$field]);
518 if (!empty($value['is_pay_later'])) {
519 $this->_values
['params']['is_pay_later'] = TRUE;
523 //Unset ContactID for additional participants and set RegisterBy Id.
524 if (empty($value['is_primary'])) {
525 $contactID = CRM_Utils_Array
::value('contact_id', $value);
526 $registerByID = $this->get('registerByID');
528 $value['registered_by_id'] = $registerByID;
532 $value['amount'] = $this->_totalAmount
;
535 $contactID = CRM_Event_Form_Registration_Confirm
::updateContactFields($contactID, $value, $fields, $this);
537 // lets store the contactID in the session
538 // we dont store in userID in case the user is doing multiple
540 // for things like tell a friend
541 if (!$this->getContactID() && !empty($value['is_primary'])) {
542 $session = CRM_Core_Session
::singleton();
543 $session->set('transaction.userID', $contactID);
546 $value['description'] = ts('Online Event Registration') . ': ' . $this->_values
['event']['title'];
547 $value['accountingCode'] = CRM_Utils_Array
::value('accountingCode',
548 $this->_values
['event']
551 // required only if paid event
552 if ($this->_values
['event']['is_monetary']) {
553 if (is_array($this->_paymentProcessor
)) {
554 $payment = CRM_Core_Payment
::singleton($this->_mode
, $this->_paymentProcessor
, $this);
559 if ($this->_allowWaitlist ||
$this->_requireApproval
) {
560 //get the participant statuses.
561 $waitingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Waiting'");
562 if ($this->_allowWaitlist
) {
563 $value['participant_status_id'] = $value['participant_status'] = array_search('On waitlist', $waitingStatuses);
566 $value['participant_status_id'] = $value['participant_status'] = array_search('Awaiting approval', $waitingStatuses);
569 //there might be case user seleted pay later and
570 //now becomes part of run time waiting list.
571 $value['is_pay_later'] = FALSE;
573 elseif (!empty($value['is_pay_later']) ||
574 $value['amount'] == 0 ||
575 $this->_contributeMode
== 'checkout' ||
576 $this->_contributeMode
== 'notify'
578 if ($value['amount'] != 0) {
580 //get the participant statuses.
581 $pendingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Pending'");
582 $status = !empty($value['is_pay_later']) ?
'Pending from pay later' : 'Pending from incomplete transaction';
583 $value['participant_status_id'] = $value['participant_status'] = array_search($status, $pendingStatuses);
586 elseif ($this->_contributeMode
== 'express' && !empty($value['is_primary'])) {
587 if (is_object($payment))
588 $result = $payment->doExpressCheckout($value);
590 CRM_Core_Error
::fatal($paymentObjError);
592 elseif (!empty($value['is_primary'])) {
593 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $value, $value, TRUE);
594 // payment email param can be empty for _bltID mapping
595 // thus provide mapping for it with a different email value
596 if (empty($value['email'])) {
597 $value['email'] = CRM_Utils_Array
::valueByRegexKey('/^email-/', $value);
600 if (is_object($payment)) {
601 $result = $payment->doDirectPayment($value);
604 CRM_Core_Error
::fatal($paymentObjError);
608 if (is_a($result, 'CRM_Core_Error')) {
609 CRM_Core_Error
::displaySessionError($result);
610 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "id={$this->_eventId}"));
614 $value = array_merge($value, $result);
617 $value['receive_date'] = $now;
618 if ($this->_allowConfirmation
) {
619 $value['participant_register_date'] = $this->_values
['participant']['register_date'];
622 $createContrib = ($value['amount'] != 0) ?
TRUE : FALSE;
623 // force to create zero amount contribution, CRM-5095
624 if (!$createContrib && ($value['amount'] == 0)
625 && $this->_priceSetId
&& $this->_lineItem
627 $createContrib = TRUE;
630 if ($createContrib && !empty($value['is_primary']) &&
631 !$this->_allowWaitlist
&& !$this->_requireApproval
633 // if paid event add a contribution record
634 //if primary participant contributing additional amount
635 //append (multiple participants) to its fee level. CRM-4196.
636 $isAdditionalAmount = FALSE;
637 if (count($params) > 1) {
638 $isAdditionalAmount = TRUE;
641 //passing contribution id is already registered.
643 self
::processContribution($this, $value, $result, $contactID, $pending, $isAdditionalAmount);
644 $value['contributionID'] = $contribution->id
;
645 $value['contributionTypeID'] = $contribution->financial_type_id
;
646 $value['receive_date'] = $contribution->receive_date
;
647 $value['trxn_id'] = $contribution->trxn_id
;
648 $value['contributionID'] = $contribution->id
;
649 $value['contributionTypeID'] = $contribution->financial_type_id
;
651 $value['contactID'] = $contactID;
652 $value['eventID'] = $this->_eventId
;
653 $value['item_name'] = $value['description'];
656 if (!empty($value['contributionID'])) {
657 $this->_values
['contributionId'] = $value['contributionID'];
661 if (!empty($value['is_primary'])) {
662 $primaryCurrencyID = CRM_Utils_Array
::value('currencyID', $value);
664 if (empty($value['currencyID'])) {
665 $value['currencyID'] = $primaryCurrencyID;
668 // CRM-11182 - Confirmation page might not be monetary
669 if ($this->_values
['event']['is_monetary']) {
670 if (!$pending && !empty($value['is_primary']) &&
671 !$this->_allowWaitlist
&& !$this->_requireApproval
673 // transactionID & receive date required while building email template
674 $this->assign('trxn_id', $value['trxn_id']);
675 $this->assign('receive_date', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
676 $this->set('receiveDate', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
677 $this->set('trxnId', CRM_Utils_Array
::value('trxn_id', $value));
681 $value['fee_amount'] = CRM_Utils_Array
::value('amount', $value);
682 $this->set('value', $value);
684 // handle register date CRM-4320
685 if ($this->_allowConfirmation
) {
686 $registerDate = CRM_Utils_Array
::value( 'participant_register_date', $params );
688 elseif (!empty($params['participant_register_date']) &&
689 is_array($params['participant_register_date']) &&
690 !empty($params['participant_register_date'])
692 $registerDate = CRM_Utils_Date
::format($params['participant_register_date']);
695 $registerDate = date('YmdHis');
697 $this->assign('register_date', $registerDate);
699 $this->confirmPostProcess($contactID, $contribution, $payment);
702 //handle if no additional participant.
703 if (!$registerByID) {
704 $registerByID = $this->get('registerByID');
707 $this->set('participantIDs', $this->_participantIDS
);
709 // create line items, CRM-5313
710 if ($this->_priceSetId
&&
711 !empty($this->_lineItem
)
713 // take all processed participant ids.
714 $allParticipantIds = $this->_participantIDS
;
716 // when participant re-walk wizard.
717 if ($this->_allowConfirmation
&&
718 !empty($this->_additionalParticipantIds
)
720 $allParticipantIds = array_merge(array($registerByID), $this->_additionalParticipantIds
);
723 $entityTable = 'civicrm_participant';
724 $invoiceSettings = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
,'contribution_invoice_settings');
725 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
727 $dataArray = array();
728 foreach ($this->_lineItem
as $key => $value) {
729 if (($value != 'skip') &&
730 ($entityId = CRM_Utils_Array
::value($key, $allParticipantIds))
733 // do cleanup line items if participant re-walking wizard.
734 if ($this->_allowConfirmation
) {
735 CRM_Price_BAO_LineItem
::deleteLineItems($entityId, $entityTable);
737 $lineItem[$this->_priceSetId
] = $value;
738 CRM_Price_BAO_LineItem
::processPriceSet($entityId, $lineItem, $contribution, $entityTable);
741 foreach ($value as $line) {
742 if (isset($line['tax_amount']) && isset($line['tax_rate'])) {
743 $totalTaxAmount = $line['tax_amount'] +
$totalTaxAmount;
744 if (isset($dataArray[$line['tax_rate']])) {
745 $dataArray[$line['tax_rate']] = $dataArray[$line['tax_rate']] + CRM_Utils_Array
::value('tax_amount', $line);
748 $dataArray[$line['tax_rate']] = CRM_Utils_Array
::value('tax_amount', $line);
755 $this->assign('dataArray', $dataArray);
756 $this->assign('totalTaxAmount', $totalTaxAmount);
760 //update status and send mail to cancelled additonal participants, CRM-4320
761 if ($this->_allowConfirmation
&& is_array($cancelledIds) && !empty($cancelledIds)) {
762 $cancelledId = array_search('Cancelled',
763 CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Negative'")
765 CRM_Event_BAO_Participant
::transitionParticipants($cancelledIds, $cancelledId);
769 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
773 // for Transfer checkout.
774 if (($this->_contributeMode
== 'checkout' ||
775 $this->_contributeMode
== 'notify'
776 ) && empty($params[0]['is_pay_later']) &&
777 !$this->_allowWaitlist
&& !$this->_requireApproval
&&
778 $this->_totalAmount
> 0
781 $primaryParticipant = $this->get('primaryParticipant');
783 if (empty($primaryParticipant['participantID'])) {
784 $primaryParticipant['participantID'] = $registerByID;
787 //build an array of custom profile and assigning it to template
788 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, $this->_values
, NULL, $isTest);
789 if (count($customProfile)) {
790 $this->assign('customProfile', $customProfile);
791 $this->set('customProfile', $customProfile);
794 // do a transfer only if a monetary payment greater than 0
795 if ($this->_values
['event']['is_monetary'] && $primaryParticipant) {
796 if ($payment && is_object($payment)) {
797 //CRM 14512 provide line items of all participants to payment gateway
798 $primaryContactId = $this->get('primaryContactId');
800 //build an array of cId/pId of participants
801 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, NULL, $primaryContactId, $isTest, TRUE);
803 //need to copy, since we are unsetting on the way.
804 $copyParticipantCountLines = $participantCount;
806 //lets carry all participant params w/ values.
807 foreach ($additionalIDs as $participantID => $contactId) {
808 $participantNum = NULL;
809 $participantNum = $participantID;
810 if ($participantID == $registerByID) {
811 $participantNum = 0; // is primary particpant
814 if ($participantNum = array_search('participant', $copyParticipantCountLines)) {
815 //if no participant found break.
816 if ($participantNum === NULL) {
819 //unset current particpant so we don't check them again
820 unset($copyParticipantCountLines[$participantNum]);
823 // get values of line items
824 if ($this->_amount
) {
826 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
827 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
828 $params[$participantNum]['amounts'] = $amount;
831 if (!empty($this->_lineItem
)) {
832 $lineItems = $this->_lineItem
;
834 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
835 $lineItem[] = $lineItemValue;
837 $params[$participantNum]['lineItem'] = $lineItem;
840 //only add additional particpants and not the primary particpant as we already have that
841 //added to $primaryParticipant so that this change doesn't break or require changes to
842 //existing gateway implementations
843 $primaryParticipant['participants_info'][$participantID] = $params[$participantNum];
846 //get event custom field information
847 $groupTree = CRM_Core_BAO_CustomGroup
::getTree('Event', $this, $this->_eventId
, 0, $this->_values
['event']['event_type_id']);
848 $primaryParticipant['eventCustomFields'] = $groupTree;
850 // call postprocess hook before leaving
851 $this->postProcessHook();
852 // this does not return
853 $payment->doTransferCheckout($primaryParticipant, 'event');
856 CRM_Core_Error
::fatal($paymentObjError);
861 //otherwise send mail Confirmation/Receipt
862 $primaryContactId = $this->get('primaryContactId');
864 //build an array of cId/pId of participants
865 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID,
866 NULL, $primaryContactId, $isTest,
869 //lets send mails to all with meaningful text, CRM-4320.
870 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
871 $this->assign('isRequireApproval', $this->_requireApproval
);
873 //need to copy, since we are unsetting on the way.
874 $copyParticipantCount = $participantCount;
876 //lets carry all paticipant params w/ values.
877 foreach ($additionalIDs as $participantID => $contactId) {
878 $participantNum = NULL;
879 if ($participantID == $registerByID) {
883 if ($participantNum = array_search('participant', $copyParticipantCount)) {
884 unset($copyParticipantCount[$participantNum]);
887 if ($participantNum === NULL)
890 //carry the participant submitted values.
891 $this->_values
['params'][$participantID] = $params[$participantNum];
894 foreach ($additionalIDs as $participantID => $contactId) {
896 if ($participantID == $registerByID) {
897 //set as Primary Participant
898 $this->assign('isPrimary', 1);
899 //build an array of custom profile and assigning it to template.
900 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($participantID, $this->_values
, NULL, $isTest);
902 if (count($customProfile)) {
903 $this->assign('customProfile', $customProfile);
904 $this->set('customProfile', $customProfile);
906 $this->_values
['params']['additionalParticipant'] = FALSE;
909 //take the Additional participant number.
910 if ($participantNum = array_search('participant', $participantCount)) {
911 unset($participantCount[$participantNum]);
913 $this->assign('isPrimary', 0);
914 $this->assign('customProfile', NULL);
915 //Additional Participant should get only it's payment information
916 if (!empty($this->_amount
)) {
918 $params = $this->get('params');
919 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
920 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
921 $this->assign('amounts', $amount);
923 if ($this->_lineItem
) {
924 $lineItems = $this->_lineItem
;
926 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
927 $lineItem[] = $lineItemValue;
929 $this->assign('lineItem', $lineItem);
931 $this->_values
['params']['additionalParticipant'] = TRUE;
932 $this->assign('isAdditionalParticipant', $this->_values
['params']['additionalParticipant']);
935 //pass these variables since these are run time calculated.
936 $this->_values
['params']['isOnWaitlist'] = $this->_allowWaitlist
;
937 $this->_values
['params']['isRequireApproval'] = $this->_requireApproval
;
939 //send mail to primary as well as additional participants.
940 $this->assign('contactID', $contactId);
941 $this->assign('participantID', $participantID);
942 CRM_Event_BAO_Event
::sendMail($contactId, $this->_values
, $participantID, $isTest);
948 * Process the contribution
950 * @param CRM_Core_Form $form
951 * @param array $params
953 * @param int $contactID
954 * @param bool $pending
955 * @param bool $isAdditionalAmount
960 static function processContribution(&$form, $params, $result, $contactID,
961 $pending = FALSE, $isAdditionalAmount = FALSE
963 $transaction = new CRM_Core_Transaction();
965 $now = date('YmdHis');
968 if (!empty($form->_values
['event']['is_email_confirm'])) {
972 if ($isAdditionalAmount) {
973 $params['amount_level'] = $params['amount_level'] . ts(' (multiple participants)') . CRM_Core_DAO
::VALUE_SEPARATOR
;
976 $contribParams = array(
977 'contact_id' => $contactID,
978 'financial_type_id' => !empty($form->_values
['event']['financial_type_id']) ?
979 $form->_values
['event']['financial_type_id'] : $params['financial_type_id'],
980 'receive_date' => $now,
981 'total_amount' => $params['amount'],
982 'tax_amount' => $params['tax_amount'],
983 'amount_level' => $params['amount_level'],
984 'invoice_id' => $params['invoiceID'],
985 'currency' => $params['currencyID'],
986 'source' => !empty($params['participant_source']) ?
$params['participant_source'] : $params['description'],
987 'is_pay_later' => CRM_Utils_Array
::value('is_pay_later', $params, 0),
988 'campaign_id' => CRM_Utils_Array
::value('campaign_id', $params),
991 if (empty($params['is_pay_later'])) {
992 $contribParams['payment_instrument_id'] = 1;
995 if (!$pending && $result) {
996 $contribParams +
= array(
997 'fee_amount' => CRM_Utils_Array
::value('fee_amount', $result),
998 'net_amount' => CRM_Utils_Array
::value('net_amount', $result, $params['amount']),
999 'trxn_id' => $result['trxn_id'],
1000 'receipt_date' => $receiptDate,
1004 $allStatuses = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
1005 $contribParams['contribution_status_id'] = array_search('Completed', $allStatuses);
1007 $contribParams['contribution_status_id'] = array_search('Pending', $allStatuses);
1010 $contribParams['is_test'] = 0;
1011 if ($form->_action
& CRM_Core_Action
::PREVIEW || CRM_Utils_Array
::value('mode', $params) == 'test') {
1012 $contribParams['is_test'] = 1;
1016 if (!empty($contribParams['invoice_id'])) {
1017 $contribID = CRM_Core_DAO
::getFieldValue('CRM_Contribute_DAO_Contribution',
1018 $contribParams['invoice_id'],
1026 $ids['contribution'] = $contribID;
1027 $contribParams['id'] = $contribID;
1030 //create an contribution address
1031 if ($form->_contributeMode
!= 'notify' && empty($params['is_pay_later'])) {
1032 $contribParams['address_id'] = CRM_Contribute_BAO_Contribution
::createAddress($params, $form->_bltID
);
1035 // Prepare soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin.
1036 if (!empty($params['pcp_made_through_id']) ||
!empty($params['soft_credit_to'])) {
1038 // if its due to pcp
1039 if (!empty($params['pcp_made_through_id'])) {
1040 $contribSoftContactId = CRM_Core_DAO
::getFieldValue('CRM_PCP_DAO_PCP',
1041 $params['pcp_made_through_id'],
1046 $contribSoftContactId = CRM_Utils_Array
::value('soft_credit_to', $params);
1049 // Pass these details onto with the contribution to make them
1050 // available at hook_post_process, CRM-8908
1051 $contribParams['soft_credit_to'] = $params['soft_credit_to'] = $contribSoftContactId;
1053 $contribParams['payment_processor'] = CRM_Utils_Array
::value('payment_processor', $params);
1054 $contribParams['skipLineItem'] = 1;
1055 // create contribution record
1056 $contribution = CRM_Contribute_BAO_Contribution
::add($contribParams, $ids);
1058 CRM_Event_BAO_Participant
::createDiscountTrxn($form->_eventId
, $contribParams, CRM_Utils_Array
::value('amount_priceset_level_radio', $params, NULL));
1060 // process soft credit / pcp pages
1061 CRM_Contribute_Form_Contribution_Confirm
::processPcpSoft($params, $contribution);
1063 $transaction->commit();
1065 return $contribution;
1069 * Fix the Location Fields
1071 * @param array $params
1073 * @param CRM_Core_Form $form
1078 public static function fixLocationFields(&$params, &$fields, &$form) {
1079 if (!empty($form->_fields
)) {
1080 foreach ($form->_fields
as $name => $dontCare) {
1085 if (is_array($fields)) {
1086 if (!array_key_exists('first_name', $fields)) {
1087 $nameFields = array('first_name', 'middle_name', 'last_name');
1088 foreach ($nameFields as $name) {
1090 if (array_key_exists("billing_$name", $params)) {
1091 $params[$name] = $params["billing_{$name}"];
1092 $params['preserveDBName'] = TRUE;
1098 // also add location name to the array
1099 if ($form->_values
['event']['is_monetary']) {
1100 $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);
1101 $fields["address_name-{$form->_bltID}"] = 1;
1103 $fields["email-{$form->_bltID}"] = 1;
1104 $fields['email-Primary'] = 1;
1106 //if its pay later or additional participant set email address as primary.
1107 if ((!empty($params['is_pay_later']) ||
empty($params['is_primary']) ||
1108 !$form->_values
['event']['is_monetary'] ||
1109 $form->_allowWaitlist ||
1110 $form->_requireApproval
1111 ) && !empty($params["email-{$form->_bltID}"])) {
1112 $params['email-Primary'] = $params["email-{$form->_bltID}"];
1117 * Update contact fields
1119 * @param int $contactID
1120 * @param array $params
1122 * @param CRM_Core_Form $form
1127 public static function updateContactFields($contactID, $params, $fields, &$form) {
1128 //add the contact to group, if add to group is selected for a
1129 //particular uf group
1131 // get the add to groups
1132 $addToGroups = array();
1134 if (!empty($form->_fields
)) {
1135 foreach ($form->_fields
as $key => $value) {
1136 if (!empty($value['add_to_group_id'])) {
1137 $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id'];
1142 // check for profile double opt-in and get groups to be subscribed
1143 $subscribeGroupIds = CRM_Core_BAO_UFGroup
::getDoubleOptInGroupIds($params, $contactID);
1145 foreach ($addToGroups as $k) {
1146 if (array_key_exists($k, $subscribeGroupIds)) {
1147 unset($addToGroups[$k]);
1151 // since we are directly adding contact to group lets unset it from mailing
1152 if (!empty($addToGroups)) {
1153 foreach ($addToGroups as $groupId) {
1154 if (isset($subscribeGroupIds[$groupId])) {
1155 unset($subscribeGroupIds[$groupId]);
1160 $ctype = CRM_Core_DAO
::getFieldValue(
1161 'CRM_Contact_DAO_Contact',
1166 if(array_key_exists('contact_id', $params) && empty($params['contact_id'])) {
1167 // we unset this here because the downstream function ignores the contactID we give it
1168 // if it is set & it is difficult to understand the implications of 'fixing' this downstream
1169 // but if we are passing a contact id into this function it's reasonable to assume we don't
1171 unset($params['contact_id']);
1174 $contactID = CRM_Contact_BAO_Contact
::createProfileContact(
1186 foreach (CRM_Contact_BAO_Contact
::$_greetingTypes as $greeting) {
1187 if (!isset($params[$greeting . '_id'])) {
1188 $params[$greeting . '_id'] = CRM_Contact_BAO_Contact_Utils
::defaultGreeting('Individual', $greeting);
1192 $contactID = CRM_Contact_BAO_Contact
::createProfileContact($params,
1200 $form->set('contactID', $contactID);
1203 //get email primary first if exist
1204 $subscribtionEmail = array('email' => CRM_Utils_Array
::value('email-Primary', $params));
1205 if (!$subscribtionEmail['email']) {
1206 $subscribtionEmail['email'] = CRM_Utils_Array
::value("email-{$form->_bltID}", $params);
1208 // subscribing contact to groups
1209 if (!empty($subscribeGroupIds) && $subscribtionEmail['email']) {
1210 CRM_Mailing_Event_BAO_Subscribe
::commonSubscribe($subscribeGroupIds, $subscribtionEmail, $contactID);
1219 public static function assignProfiles(&$form) {
1220 $participantParams = $form->_params
;
1221 $formattedValues = $profileFields = array();
1223 foreach ($participantParams as $participantNum => $participantValue) {
1224 if ($participantNum) {
1225 $prefix1 = 'additional';
1226 $prefix2 = 'additional_';
1231 if ($participantValue != 'skip') {
1232 //get the customPre profile info
1233 if (!empty($form->_values
[$prefix2 . 'custom_pre_id'])) {
1234 $values = $groupName = array();
1235 CRM_Event_BAO_Event
::displayProfile($participantValue,
1236 $form->_values
[ $prefix2 . 'custom_pre_id'],
1242 if (count($values)) {
1243 $formattedValues[$count][$prefix1 . 'CustomPre'] = $values;
1245 $formattedValues[$count][$prefix1 . 'CustomPreGroupTitle'] = CRM_Utils_Array
::value('groupTitle', $groupName);
1247 //get the customPost profile info
1248 if (!empty($form->_values
[$prefix2 . 'custom_post_id'])) {
1249 $values = $groupName = array();
1250 foreach ($form->_values
[$prefix2 . 'custom_post_id'] as $gids) {
1252 CRM_Event_BAO_Event
::displayProfile($participantValue,
1258 $values[$gids] = $val;
1259 $groupName[$gids] = $group;
1262 if (count($values)) {
1263 $formattedValues[$count][$prefix1 . 'CustomPost'] = $values;
1266 if (isset($formattedValues[$count][$prefix1 . 'CustomPre'])) {
1267 $formattedValues[$count][$prefix1 . 'CustomPost'] = array_diff_assoc($formattedValues[$count][$prefix1 . 'CustomPost'],
1268 $formattedValues[$count][$prefix1 . 'CustomPre']
1272 $formattedValues[$count][$prefix1 . 'CustomPostGroupTitle'] = $groupName;
1276 $form->_fields
= $profileFields;
1278 if (!empty($formattedValues) ) {
1279 $form->assign('primaryParticipantProfile', $formattedValues[1]);
1280 $form->set('primaryParticipantProfile', $formattedValues[1]);
1282 unset($formattedValues[1]);
1283 $form->assign('addParticipantProfile', $formattedValues);
1284 $form->set('addParticipantProfile', $formattedValues);