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
58 * Set variables up before form is built
62 public function preProcess() {
65 // lineItem isn't set until Register postProcess
66 $this->_lineItem
= $this->get('lineItem');
68 $this->_params
= $this->get('params');
69 $this->_params
[0]['tax_amount'] = $this->get('tax_amount');
71 $this->_params
[0]['is_pay_later'] = $this->get('is_pay_later');
72 $this->assign('is_pay_later', $this->_params
[0]['is_pay_later']);
73 if ($this->_params
[0]['is_pay_later']) {
74 $this->assign('pay_later_receipt', $this->_values
['event']['pay_later_receipt']);
77 CRM_Utils_Hook
::eventDiscount($this, $this->_params
);
79 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
80 $this->set('hookDiscount', $this->_params
[0]['discount']);
81 $this->assign('hookDiscount', $this->_params
[0]['discount']);
84 if ($this->_contributeMode
== 'express') {
86 // rfp == redirect from paypal
87 $rfp = CRM_Utils_Request
::retrieve('rfp', 'Boolean',
88 CRM_Core_DAO
::$_nullObject, FALSE, NULL, 'GET'
91 //we lost rfp in case of additional participant. So set it explicitly.
92 if ($rfp || CRM_Utils_Array
::value('additional_participants', $this->_params
[0], FALSE)) {
93 $payment = CRM_Core_Payment
::singleton($this->_mode
, $this->_paymentProcessor
, $this);
94 $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.');
95 if (is_object($payment))
96 $expressParams = $payment->getExpressCheckoutDetails($this->get('token'));
98 CRM_Core_Error
::fatal($paymentObjError);
100 $params['payer'] = CRM_Utils_Array
::value('payer', $expressParams);
101 $params['payer_id'] = $expressParams['payer_id'];
102 $params['payer_status'] = $expressParams['payer_status'];
104 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $expressParams, $params, FALSE);
106 // fix state and country id if present
107 if (isset($params["billing_state_province_id-{$this->_bltID}"])) {
108 $params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($params["billing_state_province_id-{$this->_bltID}"]);
110 if (isset($params['billing_country_id'])) {
111 $params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant
::countryIsoCode($params["billing_country_id-{$this->_bltID}"]);
114 // set a few other parameters for PayPal
115 $params['token'] = $this->get('token');
116 $params['amount'] = $this->_params
[0]['amount'];
117 if (!empty($this->_params
[0]['discount'])) {
118 $params['discount'] = $this->_params
[0]['discount'];
119 $params['discountAmount'] = $this->_params
[0]['discountAmount'];
120 $params['discountMessage'] = $this->_params
[0]['discountMessage'];
122 if (!empty($this->_params
[0]['amount_priceset_level_radio'])) {
123 $params['amount_priceset_level_radio'] = $this->_params
[0]['amount_priceset_level_radio'];
125 $params['amount_level'] = $this->_params
[0]['amount_level'];
126 $params['currencyID'] = $this->_params
[0]['currencyID'];
127 $params['payment_action'] = 'Sale';
129 // also merge all the other values from the profile fields
130 $values = $this->controller
->exportValues('Register');
133 "street_address-{$this->_bltID}",
134 "city-{$this->_bltID}",
135 "state_province_id-{$this->_bltID}",
136 "postal_code-{$this->_bltID}",
137 "country_id-{$this->_bltID}",
140 foreach ($values as $name => $value) {
142 if (!in_array($name, $skipFields)) {
143 $params[$name] = $value;
146 $this->set('getExpressCheckoutDetails', $params);
149 $params = $this->get('getExpressCheckoutDetails');
151 $this->_params
[0] = $params;
152 $this->_params
[0]['is_primary'] = 1;
155 //process only primary participant params.
156 $registerParams = $this->_params
[0];
157 if (isset($registerParams["billing_state_province_id-{$this->_bltID}"])
158 && $registerParams["billing_state_province_id-{$this->_bltID}"]
160 $registerParams["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant
::stateProvinceAbbreviation($registerParams["billing_state_province_id-{$this->_bltID}"]);
163 if (isset($registerParams["billing_country_id-{$this->_bltID}"]) && $registerParams["billing_country_id-{$this->_bltID}"]) {
164 $registerParams["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant
::countryIsoCode($registerParams["billing_country_id-{$this->_bltID}"]);
166 if (isset($registerParams['credit_card_exp_date'])) {
167 $registerParams['year'] = CRM_Core_Payment_Form
::getCreditCardExpirationYear($registerParams);
168 $registerParams['month'] = CRM_Core_Payment_Form
::getCreditCardExpirationMonth($registerParams);
170 if ($this->_values
['event']['is_monetary']) {
171 $registerParams['ip_address'] = CRM_Utils_System
::ipAddress();
172 $registerParams['currencyID'] = $this->_params
[0]['currencyID'];
173 $registerParams['payment_action'] = 'Sale';
175 //assign back primary participant params.
176 $this->_params
[0] = $registerParams;
179 if ($this->_values
['event']['is_monetary']) {
180 $this->_params
[0]['invoiceID'] = $this->get('invoiceID');
182 $this->assign('defaultRole', FALSE);
183 if (CRM_Utils_Array
::value('defaultRole', $this->_params
[0]) == 1) {
184 $this->assign('defaultRole', TRUE);
187 if (empty($this->_params
[0]['participant_role_id']) &&
188 $this->_values
['event']['default_role_id']
190 $this->_params
[0]['participant_role_id'] = $this->_values
['event']['default_role_id'];
193 if (isset($this->_values
['event']['confirm_title'])) {
194 CRM_Utils_System
::setTitle($this->_values
['event']['confirm_title']);
198 $params = CRM_Contribute_Form_Contribution_Confirm
::processPcp($this, $this->_params
[0]);
199 $this->_params
[0] = $params;
202 $this->set('params', $this->_params
);
206 * Overwrite action, since we are only showing elements in frozen mode
207 * no help display needed
211 public function getAction() {
212 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
213 return CRM_Core_Action
::VIEW | CRM_Core_Action
::PREVIEW
;
216 return CRM_Core_Action
::VIEW
;
221 * Build the form object
225 public function buildQuickForm() {
226 $this->assignToTemplate();
228 if ($this->_values
['event']['is_monetary'] &&
229 ($this->_params
[0]['amount'] ||
$this->_params
[0]['amount'] == 0)
231 $this->_amount
= array();
234 foreach ($this->_params
as $k => $v) {
235 //display tax amount on confirmation page
236 $taxAmount +
= $v['tax_amount'];
239 'first_name', 'last_name') as $name) {
240 if (isset($v['billing_' . $name]) &&
243 $v[$name] = $v['billing_' . $name];
247 if (!empty($v['first_name']) && !empty($v['last_name'])) {
248 $append = $v['first_name'] . ' ' . $v['last_name'];
251 //use an email if we have one
252 foreach ($v as $v_key => $v_val) {
253 if (substr($v_key, 0, 6) == 'email-') {
254 $append = $v[$v_key];
259 $this->_amount
[$k]['amount'] = $v['amount'];
260 if (!empty($v['discountAmount'])) {
261 $this->_amount
[$k]['amount'] -= $v['discountAmount'];
264 $this->_amount
[$k]['label'] = preg_replace('/\ 1/', '', $v['amount_level']) . ' - ' . $append;
265 $this->_part
[$k]['info'] = CRM_Utils_Array
::value('first_name', $v) . ' ' . CRM_Utils_Array
::value('last_name', $v);
266 if (empty($v['first_name'])) {
267 $this->_part
[$k]['info'] = $append;
269 $this->_totalAmount
= $this->_totalAmount +
$this->_amount
[$k]['amount'];
270 if (!empty($v['is_primary'])) {
271 $this->set('primaryParticipantAmount', $this->_amount
[$k]['amount']);
276 $invoiceSettings = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
,'contribution_invoice_settings');
277 $taxTerm = CRM_Utils_Array
::value('tax_term', $invoiceSettings);
278 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
280 $this->assign('totalTaxAmount', $taxAmount);
281 $this->assign('taxTerm', $taxTerm);
283 $this->assign('part', $this->_part
);
284 $this->set('part', $this->_part
);
285 $this->assign('amounts', $this->_amount
);
286 $this->assign('totalAmount', $this->_totalAmount
);
287 $this->set('totalAmount', $this->_totalAmount
);
290 if ($this->_priceSetId
&& !CRM_Core_DAO
::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId
, 'is_quick_config')) {
291 $lineItemForTemplate = array();
292 $getTaxDetails = FALSE;
293 foreach ($this->_lineItem
as $key => $value) {
294 if (!empty($value)) {
295 $lineItemForTemplate[$key] = $value;
298 foreach ($value as $v) {
299 if (isset($v['tax_rate'])) {
300 $getTaxDetails = TRUE;
305 if (!empty($lineItemForTemplate)) {
306 $this->assign('lineItem', $lineItemForTemplate);
308 $this->assign('getTaxDetails', $getTaxDetails);
311 //display additional participants profile.
312 self
::assignProfiles($this);
314 //consider total amount.
315 $this->assign('isAmountzero', ($this->_totalAmount
<= 0) ?
TRUE : FALSE);
317 if ($this->_paymentProcessor
['payment_processor_type'] == 'Google_Checkout' && empty($this->_params
[0]['is_pay_later']) && !($this->_params
[0]['amount'] == 0) &&
318 !$this->_allowWaitlist
&& !$this->_requireApproval
320 $this->_checkoutButtonName
= $this->getButtonName('next', 'checkout');
322 $this->_checkoutButtonName
,
323 $this->_paymentProcessor
['url_button'],
324 array('class' => 'crm-form-submit')
327 $this->addButtons(array(
330 'name' => ts('<< Go Back'),
336 $contribButton = ts('Continue >>');
337 $this->addButtons(array(
340 'name' => ts('<< Go Back'),
344 'name' => $contribButton,
346 'js' => array('onclick' => "return submitOnce(this,'" . $this->_name
. "','" . ts('Processing') . "');"),
354 if (!empty($this->_fields
)) {
355 foreach ($this->_fields
as $name => $dontCare) {
359 $fields["billing_state_province-{$this->_bltID}"] = $fields["billing_country-{$this->_bltID}"] = $fields["email-{$this->_bltID}"] = 1;
360 foreach ($fields as $name => $dontCare) {
361 if (isset($this->_params
[0][$name])) {
362 $defaults[$name] = $this->_params
[0][$name];
363 if (substr($name, 0, 7) == 'custom_') {
364 $timeField = "{$name}_time";
365 if (isset($this->_params
[0][$timeField])) {
366 $defaults[$timeField] = $this->_params
[0][$timeField];
368 if (isset($this->_params
[0]["{$name}_id"])) {
369 $defaults["{$name}_id"] = $this->_params
[0]["{$name}_id"];
372 elseif (in_array($name, CRM_Contact_BAO_Contact
::$_greetingTypes)
373 && !empty($this->_params
[0][$name . '_custom'])
375 $defaults[$name . '_custom'] = $this->_params
[0][$name . '_custom'];
380 $this->setDefaults($defaults);
383 //lets give meaningful status message, CRM-4320.
384 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
385 $this->assign('isRequireApproval', $this->_requireApproval
);
387 // Assign Participant Count to Lineitem Table
388 $this->assign('pricesetFieldsCount', CRM_Price_BAO_PriceSet
::getPricesetCount($this->_priceSetId
));
389 $this->addFormRule(array('CRM_Event_Form_Registration_Confirm', 'formRule'), $this);
392 public static function formRule($fields, $files, $self) {
394 $eventFull = CRM_Event_BAO_Participant
::eventFull($self->_eventId
, FALSE, CRM_Utils_Array
::value('has_waitlist', $self->_values
['event']));
395 if ($eventFull && empty($self->_allowConfirmation
)) {
396 if (empty($self->_allowWaitlist
)) {
397 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "reset=1&id={$self->_eventId}",FALSE, NULL, FALSE, TRUE));
400 $self->_feeBlock
= $self->_values
['fee'];
401 CRM_Event_Form_Registration_Register
::formatFieldsForOptionFull($self);
403 if (!empty($self->_priceSetId
)) {
404 $priceSetErrors = self
::validatePriceSet($self, $self->_params
);
405 //get price set fields errors in.
406 $errors = array_merge($errors, CRM_Utils_Array
::value(0, $priceSetErrors, array()));
409 if (!empty($errors)) {
410 $soldOutOptions = implode("<br>", $priceSetErrors['soldOutOptions']);
411 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');
412 CRM_Core_Session
::setStatus(ts("{$soldOutOptions}") , ts('Sold out:') , 'error');
413 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "_qf_Register_display=true&qfKey=" . $fields['qfKey']));
415 return empty($errors) ?
TRUE : $errors;
418 * Process the form submission
423 public function postProcess() {
424 $now = date('YmdHis');
426 $this->_params
= $this->get('params');
427 if (!empty($this->_params
[0]['contact_id'])) {
428 // unclear when this would be set & whether it could be checked in getContactID.
429 // perhaps it relates to when cid is in the url
430 //@todo someone who knows add comments on the various contactIDs in this form
431 $contactID = $this->_params
[0]['contact_id'];
434 $contactID = $this->getContactID();
437 // if a discount has been applied, lets now deduct it from the amount
438 // and fix the fee level
439 if (!empty($this->_params
[0]['discount']) && !empty($this->_params
[0]['discount']['applied'])) {
440 foreach ($this->_params
as $k => $v) {
441 if (CRM_Utils_Array
::value('amount', $this->_params
[$k]) > 0 && !empty($this->_params
[$k]['discountAmount'])) {
442 $this->_params
[$k]['amount'] -= $this->_params
[$k]['discountAmount'];
443 $this->_params
[$k]['amount_level'] .= CRM_Utils_Array
::value('discountMessage', $this->_params
[$k]);
446 $this->set('params', $this->_params
);
449 // CRM-4320, lets build array of cancelled additional participant ids
450 // those are drop or skip by primary at the time of confirmation.
451 // get all in and then unset those we want to process.
452 $cancelledIds = $this->_additionalParticipantIds
;
454 $params = $this->_params
;
455 if ($this->_values
['event']['is_monetary']) {
456 $this->set('finalAmount', $this->_amount
);
458 $participantCount = array();
460 //unset the skip participant from params.
461 //build the $participantCount array.
462 //maintain record for all participants.
463 foreach ($params as $participantNum => $record) {
464 if ($record == 'skip') {
465 unset($params[$participantNum]);
466 $participantCount[$participantNum] = 'skip';
468 elseif ($participantNum) {
469 $participantCount[$participantNum] = 'participant';
472 //lets get additional participant id to cancel.
473 if ($this->_allowConfirmation
&& is_array($cancelledIds)) {
474 $additonalId = CRM_Utils_Array
::value('participant_id', $record);
475 if ($additonalId && $key = array_search($additonalId, $cancelledIds)) {
476 unset($cancelledIds[$key]);
481 $payment = $registerByID = $primaryCurrencyID = $contribution = NULL;
482 $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.');
484 $this->participantIDS
= array();
486 foreach ($params as $key => $value) {
487 CRM_Event_Form_Registration_Confirm
::fixLocationFields($value, $fields, $this);
488 //unset the billing parameters if it is pay later mode
489 //to avoid creation of billing location
490 if ($this->_allowWaitlist
491 ||
$this->_requireApproval
492 ||
(!empty($value['is_pay_later']) && !$this->_isBillingAddressRequiredForPayLater
)
493 ||
empty($value['is_primary'])
495 $billingFields = array(
496 "email-{$this->_bltID}",
497 'billing_first_name',
498 'billing_middle_name',
500 "billing_street_address-{$this->_bltID}",
501 "billing_city-{$this->_bltID}",
502 "billing_state_province-{$this->_bltID}",
503 "billing_state_province_id-{$this->_bltID}",
504 "billing_postal_code-{$this->_bltID}",
505 "billing_country-{$this->_bltID}",
506 "billing_country_id-{$this->_bltID}",
507 "address_name-{$this->_bltID}",
509 foreach ($billingFields as $field) {
510 unset($value[$field]);
512 if (!empty($value['is_pay_later'])) {
513 $this->_values
['params']['is_pay_later'] = TRUE;
517 //Unset ContactID for additional participants and set RegisterBy Id.
518 if (empty($value['is_primary'])) {
519 $contactID = CRM_Utils_Array
::value('contact_id', $value);
520 $registerByID = $this->get('registerByID');
522 $value['registered_by_id'] = $registerByID;
526 $value['amount'] = $this->_totalAmount
;
529 $contactID = CRM_Event_Form_Registration_Confirm
::updateContactFields($contactID, $value, $fields, $this);
531 // lets store the contactID in the session
532 // we dont store in userID in case the user is doing multiple
534 // for things like tell a friend
535 if (!$this->getContactID() && !empty($value['is_primary'])) {
536 $session = CRM_Core_Session
::singleton();
537 $session->set('transaction.userID', $contactID);
540 $value['description'] = ts('Online Event Registration') . ': ' . $this->_values
['event']['title'];
541 $value['accountingCode'] = CRM_Utils_Array
::value('accountingCode',
542 $this->_values
['event']
545 // required only if paid event
546 if ($this->_values
['event']['is_monetary']) {
547 if (is_array($this->_paymentProcessor
)) {
548 $payment = CRM_Core_Payment
::singleton($this->_mode
, $this->_paymentProcessor
, $this);
553 if ($this->_allowWaitlist ||
$this->_requireApproval
) {
554 //get the participant statuses.
555 $waitingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Waiting'");
556 if ($this->_allowWaitlist
) {
557 $value['participant_status_id'] = $value['participant_status'] = array_search('On waitlist', $waitingStatuses);
560 $value['participant_status_id'] = $value['participant_status'] = array_search('Awaiting approval', $waitingStatuses);
563 //there might be case user seleted pay later and
564 //now becomes part of run time waiting list.
565 $value['is_pay_later'] = FALSE;
567 elseif (!empty($value['is_pay_later']) ||
568 $value['amount'] == 0 ||
569 $this->_contributeMode
== 'checkout' ||
570 $this->_contributeMode
== 'notify'
572 if ($value['amount'] != 0) {
574 //get the participant statuses.
575 $pendingStatuses = CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Pending'");
576 $status = !empty($value['is_pay_later']) ?
'Pending from pay later' : 'Pending from incomplete transaction';
577 $value['participant_status_id'] = $value['participant_status'] = array_search($status, $pendingStatuses);
580 elseif ($this->_contributeMode
== 'express' && !empty($value['is_primary'])) {
581 if (is_object($payment))
582 $result = $payment->doExpressCheckout($value);
584 CRM_Core_Error
::fatal($paymentObjError);
586 elseif (!empty($value['is_primary'])) {
587 CRM_Core_Payment_Form
::mapParams($this->_bltID
, $value, $value, TRUE);
588 // payment email param can be empty for _bltID mapping
589 // thus provide mapping for it with a different email value
590 if (empty($value['email'])) {
591 $value['email'] = CRM_Utils_Array
::valueByRegexKey('/^email-/', $value);
594 if (is_object($payment)) {
595 $result = $payment->doDirectPayment($value);
598 CRM_Core_Error
::fatal($paymentObjError);
602 if (is_a($result, 'CRM_Core_Error')) {
603 CRM_Core_Error
::displaySessionError($result);
604 CRM_Utils_System
::redirect(CRM_Utils_System
::url('civicrm/event/register', "id={$this->_eventId}"));
608 $value = array_merge($value, $result);
611 $value['receive_date'] = $now;
612 if ($this->_allowConfirmation
) {
613 $value['participant_register_date'] = $this->_values
['participant']['register_date'];
616 $createContrib = ($value['amount'] != 0) ?
TRUE : FALSE;
617 // force to create zero amount contribution, CRM-5095
618 if (!$createContrib && ($value['amount'] == 0)
619 && $this->_priceSetId
&& $this->_lineItem
621 $createContrib = TRUE;
624 if ($createContrib && !empty($value['is_primary']) &&
625 !$this->_allowWaitlist
&& !$this->_requireApproval
627 // if paid event add a contribution record
628 //if primary participant contributing additional amount
629 //append (multiple participants) to its fee level. CRM-4196.
630 $isAdditionalAmount = FALSE;
631 if (count($params) > 1) {
632 $isAdditionalAmount = TRUE;
635 //passing contribution id is already registered.
637 self
::processContribution($this, $value, $result, $contactID, $pending, $isAdditionalAmount);
638 $value['contributionID'] = $contribution->id
;
639 $value['contributionTypeID'] = $contribution->financial_type_id
;
640 $value['receive_date'] = $contribution->receive_date
;
641 $value['trxn_id'] = $contribution->trxn_id
;
642 $value['contributionID'] = $contribution->id
;
643 $value['contributionTypeID'] = $contribution->financial_type_id
;
645 $value['contactID'] = $contactID;
646 $value['eventID'] = $this->_eventId
;
647 $value['item_name'] = $value['description'];
650 if (!empty($value['contributionID'])) {
651 $this->_values
['contributionId'] = $value['contributionID'];
655 if (!empty($value['is_primary'])) {
656 $primaryCurrencyID = CRM_Utils_Array
::value('currencyID', $value);
658 if (empty($value['currencyID'])) {
659 $value['currencyID'] = $primaryCurrencyID;
662 // CRM-11182 - Confirmation page might not be monetary
663 if ($this->_values
['event']['is_monetary']) {
664 if (!$pending && !empty($value['is_primary']) &&
665 !$this->_allowWaitlist
&& !$this->_requireApproval
667 // transactionID & receive date required while building email template
668 $this->assign('trxn_id', $value['trxn_id']);
669 $this->assign('receive_date', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
670 $this->set('receiveDate', CRM_Utils_Date
::mysqlToIso($value['receive_date']));
671 $this->set('trxnId', CRM_Utils_Array
::value('trxn_id', $value));
675 $value['fee_amount'] = CRM_Utils_Array
::value('amount', $value);
676 $this->set('value', $value);
678 // handle register date CRM-4320
679 if ($this->_allowConfirmation
) {
680 $registerDate = CRM_Utils_Array
::value( 'participant_register_date', $params );
682 elseif (!empty($params['participant_register_date']) &&
683 is_array($params['participant_register_date']) &&
684 !empty($params['participant_register_date'])
686 $registerDate = CRM_Utils_Date
::format($params['participant_register_date']);
689 $registerDate = date('YmdHis');
691 $this->assign('register_date', $registerDate);
693 $this->confirmPostProcess($contactID, $contribution, $payment);
696 //handle if no additional participant.
697 if (!$registerByID) {
698 $registerByID = $this->get('registerByID');
701 $this->set('participantIDs', $this->_participantIDS
);
703 // create line items, CRM-5313
704 if ($this->_priceSetId
&&
705 !empty($this->_lineItem
)
707 // take all processed participant ids.
708 $allParticipantIds = $this->_participantIDS
;
710 // when participant re-walk wizard.
711 if ($this->_allowConfirmation
&&
712 !empty($this->_additionalParticipantIds
)
714 $allParticipantIds = array_merge(array($registerByID), $this->_additionalParticipantIds
);
717 $entityTable = 'civicrm_participant';
718 $invoiceSettings = CRM_Core_BAO_Setting
::getItem(CRM_Core_BAO_Setting
::CONTRIBUTE_PREFERENCES_NAME
,'contribution_invoice_settings');
719 $invoicing = CRM_Utils_Array
::value('invoicing', $invoiceSettings);
721 $dataArray = array();
722 foreach ($this->_lineItem
as $key => $value) {
723 if (($value != 'skip') &&
724 ($entityId = CRM_Utils_Array
::value($key, $allParticipantIds))
727 // do cleanup line items if participant re-walking wizard.
728 if ($this->_allowConfirmation
) {
729 CRM_Price_BAO_LineItem
::deleteLineItems($entityId, $entityTable);
731 $lineItem[$this->_priceSetId
] = $value;
732 CRM_Price_BAO_LineItem
::processPriceSet($entityId, $lineItem, $contribution, $entityTable);
735 foreach ($value as $line) {
736 if (isset($line['tax_amount']) && isset($line['tax_rate'])) {
737 $totalTaxAmount = $line['tax_amount'] +
$totalTaxAmount;
738 if (isset($dataArray[$line['tax_rate']])) {
739 $dataArray[$line['tax_rate']] = $dataArray[$line['tax_rate']] + CRM_Utils_Array
::value('tax_amount', $line);
742 $dataArray[$line['tax_rate']] = CRM_Utils_Array
::value('tax_amount', $line);
749 $this->assign('dataArray', $dataArray);
750 $this->assign('totalTaxAmount', $totalTaxAmount);
754 //update status and send mail to cancelled additonal participants, CRM-4320
755 if ($this->_allowConfirmation
&& is_array($cancelledIds) && !empty($cancelledIds)) {
756 $cancelledId = array_search('Cancelled',
757 CRM_Event_PseudoConstant
::participantStatus(NULL, "class = 'Negative'")
759 CRM_Event_BAO_Participant
::transitionParticipants($cancelledIds, $cancelledId);
763 if ($this->_action
& CRM_Core_Action
::PREVIEW
) {
767 // for Transfer checkout.
768 if (($this->_contributeMode
== 'checkout' ||
769 $this->_contributeMode
== 'notify'
770 ) && empty($params[0]['is_pay_later']) &&
771 !$this->_allowWaitlist
&& !$this->_requireApproval
&&
772 $this->_totalAmount
> 0
775 $primaryParticipant = $this->get('primaryParticipant');
777 if (empty($primaryParticipant['participantID'])) {
778 $primaryParticipant['participantID'] = $registerByID;
781 //build an array of custom profile and assigning it to template
782 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, $this->_values
, NULL, $isTest);
783 if (count($customProfile)) {
784 $this->assign('customProfile', $customProfile);
785 $this->set('customProfile', $customProfile);
788 // do a transfer only if a monetary payment greater than 0
789 if ($this->_values
['event']['is_monetary'] && $primaryParticipant) {
790 if ($payment && is_object($payment)) {
791 //CRM 14512 provide line items of all participants to payment gateway
792 $primaryContactId = $this->get('primaryContactId');
794 //build an array of cId/pId of participants
795 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID, NULL, $primaryContactId, $isTest, TRUE);
797 //need to copy, since we are unsetting on the way.
798 $copyParticipantCountLines = $participantCount;
800 //lets carry all participant params w/ values.
801 foreach ($additionalIDs as $participantID => $contactId) {
802 $participantNum = NULL;
803 $participantNum = $participantID;
804 if ($participantID == $registerByID) {
805 $participantNum = 0; // is primary particpant
808 if ($participantNum = array_search('participant', $copyParticipantCountLines)) {
809 //if no participant found break.
810 if ($participantNum === NULL) {
813 //unset current particpant so we don't check them again
814 unset($copyParticipantCountLines[$participantNum]);
817 // get values of line items
818 if ($this->_amount
) {
820 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
821 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
822 $params[$participantNum]['amounts'] = $amount;
825 if (!empty($this->_lineItem
)) {
826 $lineItems = $this->_lineItem
;
828 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
829 $lineItem[] = $lineItemValue;
831 $params[$participantNum]['lineItem'] = $lineItem;
834 //only add additional particpants and not the primary particpant as we already have that
835 //added to $primaryParticipant so that this change doesn't break or require changes to
836 //existing gateway implementations
837 $primaryParticipant['participants_info'][$participantID] = $params[$participantNum];
840 //get event custom field information
841 $groupTree = CRM_Core_BAO_CustomGroup
::getTree('Event', $this, $this->_eventId
, 0, $this->_values
['event']['event_type_id']);
842 $primaryParticipant['eventCustomFields'] = $groupTree;
844 // call postprocess hook before leaving
845 $this->postProcessHook();
846 // this does not return
847 $payment->doTransferCheckout($primaryParticipant, 'event');
850 CRM_Core_Error
::fatal($paymentObjError);
855 //otherwise send mail Confirmation/Receipt
856 $primaryContactId = $this->get('primaryContactId');
858 //build an array of cId/pId of participants
859 $additionalIDs = CRM_Event_BAO_Event
::buildCustomProfile($registerByID,
860 NULL, $primaryContactId, $isTest,
863 //lets send mails to all with meaningful text, CRM-4320.
864 $this->assign('isOnWaitlist', $this->_allowWaitlist
);
865 $this->assign('isRequireApproval', $this->_requireApproval
);
867 //need to copy, since we are unsetting on the way.
868 $copyParticipantCount = $participantCount;
870 //lets carry all paticipant params w/ values.
871 foreach ($additionalIDs as $participantID => $contactId) {
872 $participantNum = NULL;
873 if ($participantID == $registerByID) {
877 if ($participantNum = array_search('participant', $copyParticipantCount)) {
878 unset($copyParticipantCount[$participantNum]);
881 if ($participantNum === NULL)
884 //carry the participant submitted values.
885 $this->_values
['params'][$participantID] = $params[$participantNum];
888 foreach ($additionalIDs as $participantID => $contactId) {
890 if ($participantID == $registerByID) {
891 //set as Primary Participant
892 $this->assign('isPrimary', 1);
893 //build an array of custom profile and assigning it to template.
894 $customProfile = CRM_Event_BAO_Event
::buildCustomProfile($participantID, $this->_values
, NULL, $isTest);
896 if (count($customProfile)) {
897 $this->assign('customProfile', $customProfile);
898 $this->set('customProfile', $customProfile);
900 $this->_values
['params']['additionalParticipant'] = FALSE;
903 //take the Additional participant number.
904 if ($participantNum = array_search('participant', $participantCount)) {
905 unset($participantCount[$participantNum]);
907 $this->assign('isPrimary', 0);
908 $this->assign('customProfile', NULL);
909 //Additional Participant should get only it's payment information
910 if (!empty($this->_amount
)) {
912 $params = $this->get('params');
913 $amount[$participantNum]['label'] = preg_replace('/\ 1/', '', $params[$participantNum]['amount_level']);
914 $amount[$participantNum]['amount'] = $params[$participantNum]['amount'];
915 $this->assign('amounts', $amount);
917 if ($this->_lineItem
) {
918 $lineItems = $this->_lineItem
;
920 if ($lineItemValue = CRM_Utils_Array
::value($participantNum, $lineItems)) {
921 $lineItem[] = $lineItemValue;
923 $this->assign('lineItem', $lineItem);
925 $this->_values
['params']['additionalParticipant'] = TRUE;
926 $this->assign('isAdditionalParticipant', $this->_values
['params']['additionalParticipant']);
929 //pass these variables since these are run time calculated.
930 $this->_values
['params']['isOnWaitlist'] = $this->_allowWaitlist
;
931 $this->_values
['params']['isRequireApproval'] = $this->_requireApproval
;
933 //send mail to primary as well as additional participants.
934 $this->assign('contactID', $contactId);
935 $this->assign('participantID', $participantID);
936 CRM_Event_BAO_Event
::sendMail($contactId, $this->_values
, $participantID, $isTest);
942 * Process the contribution
944 * @param CRM_Core_Form $form
945 * @param array $params
947 * @param int $contactID
948 * @param bool $pending
949 * @param bool $isAdditionalAmount
953 static function processContribution(&$form, $params, $result, $contactID,
954 $pending = FALSE, $isAdditionalAmount = FALSE
956 $transaction = new CRM_Core_Transaction();
958 $now = date('YmdHis');
961 if (!empty($form->_values
['event']['is_email_confirm'])) {
965 if ($isAdditionalAmount) {
966 $params['amount_level'] = $params['amount_level'] . ts(' (multiple participants)') . CRM_Core_DAO
::VALUE_SEPARATOR
;
969 $contribParams = array(
970 'contact_id' => $contactID,
971 'financial_type_id' => !empty($form->_values
['event']['financial_type_id']) ?
972 $form->_values
['event']['financial_type_id'] : $params['financial_type_id'],
973 'receive_date' => $now,
974 'total_amount' => $params['amount'],
975 'tax_amount' => $params['tax_amount'],
976 'amount_level' => $params['amount_level'],
977 'invoice_id' => $params['invoiceID'],
978 'currency' => $params['currencyID'],
979 'source' => !empty($params['participant_source']) ?
$params['participant_source'] : $params['description'],
980 'is_pay_later' => CRM_Utils_Array
::value('is_pay_later', $params, 0),
981 'campaign_id' => CRM_Utils_Array
::value('campaign_id', $params),
984 if (empty($params['is_pay_later'])) {
985 $contribParams['payment_instrument_id'] = 1;
988 if (!$pending && $result) {
989 $contribParams +
= array(
990 'fee_amount' => CRM_Utils_Array
::value('fee_amount', $result),
991 'net_amount' => CRM_Utils_Array
::value('net_amount', $result, $params['amount']),
992 'trxn_id' => $result['trxn_id'],
993 'receipt_date' => $receiptDate,
997 $allStatuses = CRM_Contribute_PseudoConstant
::contributionStatus(NULL, 'name');
998 $contribParams['contribution_status_id'] = array_search('Completed', $allStatuses);
1000 $contribParams['contribution_status_id'] = array_search('Pending', $allStatuses);
1003 $contribParams['is_test'] = 0;
1004 if ($form->_action
& CRM_Core_Action
::PREVIEW || CRM_Utils_Array
::value('mode', $params) == 'test') {
1005 $contribParams['is_test'] = 1;
1009 if (!empty($contribParams['invoice_id'])) {
1010 $contribID = CRM_Core_DAO
::getFieldValue('CRM_Contribute_DAO_Contribution',
1011 $contribParams['invoice_id'],
1019 $ids['contribution'] = $contribID;
1020 $contribParams['id'] = $contribID;
1023 //create an contribution address
1024 if ($form->_contributeMode
!= 'notify' && empty($params['is_pay_later'])) {
1025 $contribParams['address_id'] = CRM_Contribute_BAO_Contribution
::createAddress($params, $form->_bltID
);
1028 // Prepare soft contribution due to pcp or Submit Credit / Debit Card Contribution by admin.
1029 if (!empty($params['pcp_made_through_id']) ||
!empty($params['soft_credit_to'])) {
1031 // if its due to pcp
1032 if (!empty($params['pcp_made_through_id'])) {
1033 $contribSoftContactId = CRM_Core_DAO
::getFieldValue('CRM_PCP_DAO_PCP',
1034 $params['pcp_made_through_id'],
1039 $contribSoftContactId = CRM_Utils_Array
::value('soft_credit_to', $params);
1042 // Pass these details onto with the contribution to make them
1043 // available at hook_post_process, CRM-8908
1044 $contribParams['soft_credit_to'] = $params['soft_credit_to'] = $contribSoftContactId;
1046 $contribParams['payment_processor'] = CRM_Utils_Array
::value('payment_processor', $params);
1047 $contribParams['skipLineItem'] = 1;
1048 // create contribution record
1049 $contribution = CRM_Contribute_BAO_Contribution
::add($contribParams, $ids);
1051 CRM_Event_BAO_Participant
::createDiscountTrxn($form->_eventId
, $contribParams, CRM_Utils_Array
::value('amount_priceset_level_radio', $params, NULL));
1053 // process soft credit / pcp pages
1054 CRM_Contribute_Form_Contribution_Confirm
::processPcpSoft($params, $contribution);
1056 $transaction->commit();
1058 return $contribution;
1062 * Fix the Location Fields
1064 * @param array $params
1066 * @param CRM_Core_Form $form
1070 public static function fixLocationFields(&$params, &$fields, &$form) {
1071 if (!empty($form->_fields
)) {
1072 foreach ($form->_fields
as $name => $dontCare) {
1077 if (is_array($fields)) {
1078 if (!array_key_exists('first_name', $fields)) {
1079 $nameFields = array('first_name', 'middle_name', 'last_name');
1080 foreach ($nameFields as $name) {
1082 if (array_key_exists("billing_$name", $params)) {
1083 $params[$name] = $params["billing_{$name}"];
1084 $params['preserveDBName'] = TRUE;
1090 // also add location name to the array
1091 if ($form->_values
['event']['is_monetary']) {
1092 $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);
1093 $fields["address_name-{$form->_bltID}"] = 1;
1095 $fields["email-{$form->_bltID}"] = 1;
1096 $fields['email-Primary'] = 1;
1098 //if its pay later or additional participant set email address as primary.
1099 if ((!empty($params['is_pay_later']) ||
empty($params['is_primary']) ||
1100 !$form->_values
['event']['is_monetary'] ||
1101 $form->_allowWaitlist ||
1102 $form->_requireApproval
1103 ) && !empty($params["email-{$form->_bltID}"])) {
1104 $params['email-Primary'] = $params["email-{$form->_bltID}"];
1109 * Update contact fields
1111 * @param int $contactID
1112 * @param array $params
1114 * @param CRM_Core_Form $form
1118 public static function updateContactFields($contactID, $params, $fields, &$form) {
1119 //add the contact to group, if add to group is selected for a
1120 //particular uf group
1122 // get the add to groups
1123 $addToGroups = array();
1125 if (!empty($form->_fields
)) {
1126 foreach ($form->_fields
as $key => $value) {
1127 if (!empty($value['add_to_group_id'])) {
1128 $addToGroups[$value['add_to_group_id']] = $value['add_to_group_id'];
1133 // check for profile double opt-in and get groups to be subscribed
1134 $subscribeGroupIds = CRM_Core_BAO_UFGroup
::getDoubleOptInGroupIds($params, $contactID);
1136 foreach ($addToGroups as $k) {
1137 if (array_key_exists($k, $subscribeGroupIds)) {
1138 unset($addToGroups[$k]);
1142 // since we are directly adding contact to group lets unset it from mailing
1143 if (!empty($addToGroups)) {
1144 foreach ($addToGroups as $groupId) {
1145 if (isset($subscribeGroupIds[$groupId])) {
1146 unset($subscribeGroupIds[$groupId]);
1151 $ctype = CRM_Core_DAO
::getFieldValue(
1152 'CRM_Contact_DAO_Contact',
1157 if(array_key_exists('contact_id', $params) && empty($params['contact_id'])) {
1158 // we unset this here because the downstream function ignores the contactID we give it
1159 // if it is set & it is difficult to understand the implications of 'fixing' this downstream
1160 // but if we are passing a contact id into this function it's reasonable to assume we don't
1162 unset($params['contact_id']);
1165 $contactID = CRM_Contact_BAO_Contact
::createProfileContact(
1177 foreach (CRM_Contact_BAO_Contact
::$_greetingTypes as $greeting) {
1178 if (!isset($params[$greeting . '_id'])) {
1179 $params[$greeting . '_id'] = CRM_Contact_BAO_Contact_Utils
::defaultGreeting('Individual', $greeting);
1183 $contactID = CRM_Contact_BAO_Contact
::createProfileContact($params,
1191 $form->set('contactID', $contactID);
1194 //get email primary first if exist
1195 $subscribtionEmail = array('email' => CRM_Utils_Array
::value('email-Primary', $params));
1196 if (!$subscribtionEmail['email']) {
1197 $subscribtionEmail['email'] = CRM_Utils_Array
::value("email-{$form->_bltID}", $params);
1199 // subscribing contact to groups
1200 if (!empty($subscribeGroupIds) && $subscribtionEmail['email']) {
1201 CRM_Mailing_Event_BAO_Subscribe
::commonSubscribe($subscribeGroupIds, $subscribtionEmail, $contactID);
1210 public static function assignProfiles(&$form) {
1211 $participantParams = $form->_params
;
1212 $formattedValues = $profileFields = array();
1214 foreach ($participantParams as $participantNum => $participantValue) {
1215 if ($participantNum) {
1216 $prefix1 = 'additional';
1217 $prefix2 = 'additional_';
1222 if ($participantValue != 'skip') {
1223 //get the customPre profile info
1224 if (!empty($form->_values
[$prefix2 . 'custom_pre_id'])) {
1225 $values = $groupName = array();
1226 CRM_Event_BAO_Event
::displayProfile($participantValue,
1227 $form->_values
[ $prefix2 . 'custom_pre_id'],
1233 if (count($values)) {
1234 $formattedValues[$count][$prefix1 . 'CustomPre'] = $values;
1236 $formattedValues[$count][$prefix1 . 'CustomPreGroupTitle'] = CRM_Utils_Array
::value('groupTitle', $groupName);
1238 //get the customPost profile info
1239 if (!empty($form->_values
[$prefix2 . 'custom_post_id'])) {
1240 $values = $groupName = array();
1241 foreach ($form->_values
[$prefix2 . 'custom_post_id'] as $gids) {
1243 CRM_Event_BAO_Event
::displayProfile($participantValue,
1249 $values[$gids] = $val;
1250 $groupName[$gids] = $group;
1253 if (count($values)) {
1254 $formattedValues[$count][$prefix1 . 'CustomPost'] = $values;
1257 if (isset($formattedValues[$count][$prefix1 . 'CustomPre'])) {
1258 $formattedValues[$count][$prefix1 . 'CustomPost'] = array_diff_assoc($formattedValues[$count][$prefix1 . 'CustomPost'],
1259 $formattedValues[$count][$prefix1 . 'CustomPre']
1263 $formattedValues[$count][$prefix1 . 'CustomPostGroupTitle'] = $groupName;
1267 $form->_fields
= $profileFields;
1269 if (!empty($formattedValues) ) {
1270 $form->assign('primaryParticipantProfile', $formattedValues[1]);
1271 $form->set('primaryParticipantProfile', $formattedValues[1]);
1273 unset($formattedValues[1]);
1274 $form->assign('addParticipantProfile', $formattedValues);
1275 $form->set('addParticipantProfile', $formattedValues);