Merge pull request #3152 from pradpnayak/CRM-14112
[civicrm-core.git] / CRM / Event / Form / Participant.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 *
31 * @package CRM
32 * @copyright CiviCRM LLC (c) 2004-2014
33 * $Id$
34 *
35 */
36
37 /**
38 * This class generates form components for processing a participation
39 * in an event
40 */
41 class CRM_Event_Form_Participant extends CRM_Contact_Form_Task {
42
43 public $useLivePageJS = TRUE;
44
45 /**
46 * the values for the contribution db object
47 *
48 * @var array
49 * @protected
50 */
51 public $_values;
52
53 /**
54 * the values for the quickconfig for priceset
55 *
56 * @var boolean
57 * @protected
58 */
59 public $_quickConfig = NULL;
60
61 /**
62 * Price Set ID, if the new price set method is used
63 *
64 * @var int
65 * @protected
66 */
67 public $_priceSetId;
68
69 /**
70 * Array of fields for the price set
71 *
72 * @var array
73 * @protected
74 */
75 public $_priceSet;
76
77 /**
78 * the id of the participation that we are proceessing
79 *
80 * @var int
81 * @protected
82 */
83 public $_id;
84
85 /**
86 * the id of the note
87 *
88 * @var int
89 * @protected
90 */
91 protected $_noteId = NULL;
92
93 /**
94 * the id of the contact associated with this participation
95 *
96 * @var int
97 * @protected
98 */
99 public $_contactId;
100
101 /**
102 * array of event values
103 *
104 * @var array
105 * @protected
106 */
107 protected $_event;
108
109 /**
110 * Are we operating in "single mode", i.e. adding / editing only
111 * one participant record, or is this a batch add operation
112 *
113 * @var boolean
114 */
115 public $_single = FALSE;
116
117 /**
118 * If event is paid or unpaid
119 */
120 public $_isPaidEvent;
121
122 /**
123 * Page action
124 */
125 public $_action;
126
127 /**
128 * Role Id
129 */
130 protected $_roleId = NULL;
131
132 /**
133 * Event Type Id
134 */
135 protected $_eventTypeId = NULL;
136
137 /**
138 * participant status Id
139 */
140 protected $_statusId = NULL;
141
142 /**
143 * cache all the participant statuses
144 */
145 protected $_participantStatuses;
146
147 /**
148 * participant mode
149 */
150 public $_mode = NULL;
151
152 /**
153 * event ID preselect
154 */
155 public $_eID = NULL;
156
157 /*
158 *Line Item for Price Set
159 */
160
161 public $_lineItem = NULL;
162 /*
163 *Contribution mode for event registration for offline mode
164 */
165
166 public $_contributeMode = 'direct';
167
168 public $_online;
169
170 /**
171 * store id of role custom data type ( option value )
172 */
173 protected $_roleCustomDataTypeID;
174
175 /**
176 * store id of event Name custom data type ( option value)
177 */
178 protected $_eventNameCustomDataTypeID;
179
180 /**
181 * selected discount id
182 */
183 public $_originalDiscountId = NULL;
184
185 /**
186 * event id
187 */
188 public $_eventId = NULL;
189
190 /**
191 * id of payment, if any
192 */
193 public $_paymentId = NULL;
194
195 /**
196 * Function to set variables up before form is built
197 *
198 * @return void
199 * @access public
200 */
201 public function preProcess() {
202 $this->_showFeeBlock = CRM_Utils_Array::value('eventId', $_GET);
203 $this->assign('showFeeBlock', FALSE);
204 $this->assign('feeBlockPaid', FALSE);
205
206 $this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
207 $this->_mode = CRM_Utils_Request::retrieve('mode', 'String', $this);
208 $this->_eID = CRM_Utils_Request::retrieve('eid', 'Positive', $this);
209 $this->_context = CRM_Utils_Request::retrieve('context', 'String', $this);
210 $this->assign('context', $this->_context);
211
212 if ($this->_contactId) {
213 $displayName = CRM_Contact_BAO_Contact::displayName($this->_contactId);
214 $this->assign('displayName', $displayName);
215 // omitting contactImage from title for now since the summary overlay css doesn't work outside of our crm-container
216 CRM_Utils_System::setTitle(ts('Event Registration for') . ' ' . $displayName);
217 }
218
219 // check the current path, if search based, then dont get participantID
220 // CRM-5792
221 $path = CRM_Utils_System::currentPath();
222 if (
223 strpos($path, 'civicrm/contact/search') === 0 ||
224 strpos($path, 'civicrm/group/search') === 0
225 ) {
226 $this->_id = NULL;
227 }
228 else {
229 $this->_id = CRM_Utils_Request::retrieve('id', 'Positive', $this);
230 }
231
232 if ($this->_id) {
233 $this->assign('participantId', $this->_id);
234
235 $this->_paymentId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment',
236 $this->_id, 'id', 'participant_id'
237 );
238
239 $this->assign('hasPayment', $this->_paymentId);
240
241 // CRM-12615 - Get payment information from the primary registration
242 if ((!$this->_paymentId) && ($this->_action == CRM_Core_Action::UPDATE)) {
243 $registered_by_id = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant',
244 $this->_id, 'registered_by_id', 'id'
245 );
246 if ($registered_by_id) {
247 $this->_paymentId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment',
248 $registered_by_id, 'id', 'participant_id'
249 );
250 $this->assign('registeredByParticipantId', $registered_by_id);
251 }
252 }
253 }
254
255 // get the option value for custom data type
256 $this->_roleCustomDataTypeID = CRM_Core_OptionGroup::getValue('custom_data_type', 'ParticipantRole', 'name');
257 $this->_eventNameCustomDataTypeID = CRM_Core_OptionGroup::getValue('custom_data_type', 'ParticipantEventName', 'name');
258 $this->_eventTypeCustomDataTypeID = CRM_Core_OptionGroup::getValue('custom_data_type', 'ParticipantEventType', 'name');
259 $this->assign('roleCustomDataTypeID', $this->_roleCustomDataTypeID);
260 $this->assign('eventNameCustomDataTypeID', $this->_eventNameCustomDataTypeID);
261 $this->assign('eventTypeCustomDataTypeID', $this->_eventTypeCustomDataTypeID);
262
263 if ($this->_mode) {
264 $this->assign('participantMode', $this->_mode);
265
266 $this->_paymentProcessor = array('billing_mode' => 1);
267
268 $validProcessors = array();
269 $processors = CRM_Core_PseudoConstant::paymentProcessor(FALSE, FALSE, "billing_mode IN ( 1, 3 )");
270
271 foreach ($processors as $ppID => $label) {
272 $paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($ppID, $this->_mode);
273 if ($paymentProcessor['payment_processor_type'] == 'PayPal' && !$paymentProcessor['user_name']) {
274 continue;
275 }
276 elseif ($paymentProcessor['payment_processor_type'] == 'Dummy' && $this->_mode == 'live') {
277 continue;
278 }
279 else {
280 $paymentObject = CRM_Core_Payment::singleton($this->_mode, $paymentProcessor, $this);
281 $error = $paymentObject->checkConfig();
282 if (empty($error)) {
283 $validProcessors[$ppID] = $label;
284 }
285 $paymentObject = NULL;
286 }
287 }
288 if (empty($validProcessors)) {
289 CRM_Core_Error::fatal(ts('Could not find valid payment processor for this page'));
290 }
291 else {
292 $this->_processors = $validProcessors;
293 }
294 // also check for billing information
295 // get the billing location type
296 $locationTypes = CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id', array(), 'validate');
297 // CRM-8108 remove ts around Billing location type
298 //$this->_bltID = array_search( ts('Billing'), $locationTypes );
299 $this->_bltID = array_search('Billing', $locationTypes);
300 if (!$this->_bltID) {
301 CRM_Core_Error::fatal(ts('Please set a location type of %1', array(1 => 'Billing')));
302 }
303 $this->set('bltID', $this->_bltID);
304 $this->assign('bltID', $this->_bltID);
305
306 $this->_fields = array();
307
308 CRM_Core_Payment_Form::setCreditCardFields($this);
309
310 // this required to show billing block
311 $this->assign_by_ref('paymentProcessor', $paymentProcessor);
312 $this->assign('hidePayPalExpress', TRUE);
313 }
314
315 if ($this->_showFeeBlock) {
316 $this->assign('showFeeBlock', TRUE);
317 $isMonetary = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $this->_showFeeBlock, 'is_monetary');
318 if ($isMonetary) {
319 $this->assign('feeBlockPaid', TRUE);
320 }
321 return CRM_Event_Form_EventFees::preProcess($this);
322 }
323
324 //custom data related code
325 $this->_cdType = CRM_Utils_Array::value('type', $_GET);
326 $this->assign('cdType', FALSE);
327 if ($this->_cdType) {
328 $this->assign('cdType', TRUE);
329 return CRM_Custom_Form_CustomData::preProcess($this, NULL, NULL, NULL, NULL, NULL, TRUE);
330 }
331
332 //check the mode when this form is called either single or as
333 //search task action
334 if ($this->_id || $this->_contactId || $this->_context == 'standalone') {
335 $this->_single = TRUE;
336 $this->assign('urlPath', 'civicrm/contact/view/participant');
337 if (!$this->_id && !$this->_contactId) {
338 $breadCrumbs = array(array('title' => ts('CiviEvent Dashboard'),
339 'url' => CRM_Utils_System::url('civicrm/event', 'reset=1'),
340 ));
341
342 CRM_Utils_System::appendBreadCrumb($breadCrumbs);
343 }
344 }
345 else {
346 //set the appropriate action
347 $context = $this->get('context');
348 $urlString = 'civicrm/contact/search';
349 $this->_action = CRM_Core_Action::BASIC;
350 switch ($context) {
351 case 'advanced':
352 $urlString = 'civicrm/contact/search/advanced';
353 $this->_action = CRM_Core_Action::ADVANCED;
354 break;
355
356 case 'builder':
357 $urlString = 'civicrm/contact/search/builder';
358 $this->_action = CRM_Core_Action::PROFILE;
359 break;
360
361 case 'basic':
362 $urlString = 'civicrm/contact/search/basic';
363 $this->_action = CRM_Core_Action::BASIC;
364 break;
365
366 case 'custom':
367 $urlString = 'civicrm/contact/search/custom';
368 $this->_action = CRM_Core_Action::COPY;
369 break;
370 }
371 parent::preProcess();
372
373 $this->_single = FALSE;
374 $this->_contactId = NULL;
375
376 //set ajax path, this used for custom data building
377 $this->assign('urlPath', $urlString);
378 $this->assign('urlPathVar', "_qf_Participant_display=true&qfKey={$this->controller->_key}");
379 }
380
381 $this->assign('single', $this->_single);
382
383 if (!$this->_id) {
384 $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'add');
385 }
386 $this->assign('action', $this->_action);
387
388 // check for edit permission
389 if (!CRM_Core_Permission::checkActionPermission('CiviEvent', $this->_action)) {
390 CRM_Core_Error::fatal(ts('You do not have permission to access this page'));
391 }
392
393 if ($this->_action & CRM_Core_Action::DELETE) {
394 // check delete permission for contribution
395 if ($this->_id && $this->_paymentId && !CRM_Core_Permission::checkActionPermission('CiviContribute', $this->_action)) {
396 CRM_Core_Error::fatal(ts("This Participant is linked to a contribution. You must have 'delete in CiviContribute' permission in order to delete this record."));
397 }
398 return;
399 }
400
401 if ($this->_id) {
402 // assign participant id to the template
403 $this->assign('participantId', $this->_id);
404 $this->_roleId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_id, 'role_id');
405 }
406
407 // when fee amount is included in form
408 if (!empty($_POST['hidden_feeblock']) || !empty($_POST['send_receipt'])) {
409 CRM_Event_Form_EventFees::preProcess($this);
410 CRM_Event_Form_EventFees::buildQuickForm($this);
411 CRM_Event_Form_EventFees::setDefaultValues($this);
412 }
413
414 // when custom data is included in this page
415 if (!empty($_POST['hidden_custom'])) {
416 //custom data of type participant role
417 if (!empty($_POST['role_id'])) {
418 foreach ($_POST['role_id'] as $k => $val) {
419 $roleID = $val;
420 CRM_Custom_Form_CustomData::preProcess($this, $this->_roleCustomDataTypeID, $k, 1, 'Participant', $this->_id);
421 CRM_Custom_Form_CustomData::buildQuickForm($this);
422 CRM_Custom_Form_CustomData::setDefaultValues($this);
423 }
424 }
425
426 //custom data of type participant event
427 CRM_Custom_Form_CustomData::preProcess($this, $this->_eventNameCustomDataTypeID, $_POST['event_id'], 1, 'Participant', $this->_id);
428 CRM_Custom_Form_CustomData::buildQuickForm($this);
429 CRM_Custom_Form_CustomData::setDefaultValues($this);
430
431 // custom data of type participant event type
432 $eventTypeId = NULL;
433 if ($eventId = CRM_Utils_Array::value('event_id', $_POST)) {
434 $eventTypeId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $eventId, 'event_type_id', 'id');
435 }
436 CRM_Custom_Form_CustomData::preProcess($this, $this->_eventTypeCustomDataTypeID, $eventTypeId,
437 1, 'Participant', $this->_id
438 );
439 CRM_Custom_Form_CustomData::buildQuickForm($this);
440 CRM_Custom_Form_CustomData::setDefaultValues($this);
441
442 //custom data of type participant, ( we 'null' to reset subType and subName)
443 CRM_Custom_Form_CustomData::preProcess($this, 'null', 'null', 1, 'Participant', $this->_id);
444 CRM_Custom_Form_CustomData::buildQuickForm($this);
445 CRM_Custom_Form_CustomData::setDefaultValues($this);
446 }
447
448 // CRM-4395, get the online pending contribution id.
449 $this->_onlinePendingContributionId = NULL;
450 if (!$this->_mode && $this->_id && ($this->_action & CRM_Core_Action::UPDATE)) {
451 $this->_onlinePendingContributionId = CRM_Contribute_BAO_Contribution::checkOnlinePendingContribution($this->_id,
452 'Event'
453 );
454 }
455 $this->set('onlinePendingContributionId', $this->_onlinePendingContributionId);
456 }
457
458 /**
459 * This function sets the default values for the form in edit/view mode
460 * the default values are retrieved from the database
461 *
462 * @access public
463 *
464 * @return void
465 */
466 public function setDefaultValues() {
467 if ($this->_showFeeBlock) {
468 return CRM_Event_Form_EventFees::setDefaultValues($this);
469 }
470
471 if ($this->_cdType) {
472 return CRM_Custom_Form_CustomData::setDefaultValues($this);
473 }
474
475 $defaults = array();
476
477 if ($this->_action & CRM_Core_Action::DELETE) {
478 return $defaults;
479 }
480
481 if ($this->_id) {
482 $ids = array();
483 $params = array('id' => $this->_id);
484
485 CRM_Event_BAO_Participant::getValues($params, $defaults, $ids);
486 $sep = CRM_Core_DAO::VALUE_SEPARATOR;
487 if ($defaults[$this->_id]['role_id']) {
488 $roleIDs = explode($sep, $defaults[$this->_id]['role_id']);
489 }
490 $this->_contactId = $defaults[$this->_id]['contact_id'];
491 $this->_statusId = $defaults[$this->_id]['participant_status_id'];
492
493 //set defaults for note
494 $noteDetails = CRM_Core_BAO_Note::getNote($this->_id, 'civicrm_participant');
495 $defaults[$this->_id]['note'] = array_pop($noteDetails);
496
497 // Check if this is a primaryParticipant (registered for others) and retrieve additional participants if true (CRM-4859)
498 if (CRM_Event_BAO_Participant::isPrimaryParticipant($this->_id)) {
499 $this->assign('additionalParticipants', CRM_Event_BAO_Participant::getAdditionalParticipants($this->_id));
500 }
501
502 // Get registered_by contact ID and display_name if participant was registered by someone else (CRM-4859)
503 if (!empty($defaults[$this->_id]['participant_registered_by_id'])) {
504 $registered_by_contact_id = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant',
505 $defaults[$this->_id]['participant_registered_by_id'],
506 'contact_id', 'id'
507 );
508 $this->assign('participant_registered_by_id', $defaults[$this->_id]['participant_registered_by_id']);
509 $this->assign('registered_by_contact_id', $registered_by_contact_id);
510 $this->assign('registered_by_display_name', CRM_Contact_BAO_Contact::displayName($registered_by_contact_id));
511 }
512 }
513
514 if ($this->_action & (CRM_Core_Action::VIEW | CRM_Core_Action::BROWSE)) {
515 $inactiveNeeded = TRUE;
516 $viewMode = TRUE;
517 }
518 else {
519 $viewMode = FALSE;
520 $inactiveNeeded = FALSE;
521 }
522
523 //setting default register date
524 if ($this->_action == CRM_Core_Action::ADD) {
525 $statuses = array_flip($this->_participantStatuses);
526 $defaults[$this->_id]['status_id'] = CRM_Utils_Array::value(ts('Registered'), $statuses);
527 if (!empty($defaults[$this->_id]['event_id'])) {
528 $contributionTypeId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event',
529 $defaults[$this->_id]['event_id'],
530 'financial_type_id'
531 );
532 if ($contributionTypeId) {
533 $defaults[$this->_id]['financial_type_id'] = $contributionTypeId;
534 }
535 }
536
537 if ($this->_mode) {
538 $fields["email-{$this->_bltID}"] = 1;
539 $fields['email-Primary'] = 1;
540
541 if ($this->_contactId) {
542 CRM_Core_BAO_UFGroup::setProfileDefaults($this->_contactId, $fields, $defaults);
543 }
544
545 if (empty($defaults["email-{$this->_bltID}"]) &&
546 !empty($defaults['email-Primary'])
547 ) {
548 $defaults[$this->_id]["email-{$this->_bltID}"] = $defaults['email-Primary'];
549 }
550 }
551
552 $submittedRole = $this->getElementValue('role_id');
553 if (!empty($submittedRole[0])) {
554 $roleID = $submittedRole[0];
555 }
556 $submittedEvent = $this->getElementValue('event_id');
557 if ($submittedEvent[0]) {
558 $eventID = $submittedEvent[0];
559 }
560 }
561 else {
562 $defaults[$this->_id]['record_contribution'] = 0;
563
564 if ($defaults[$this->_id]['participant_is_pay_later']) {
565 $this->assign('participant_is_pay_later', TRUE);
566 }
567
568 $this->assign('participant_status_id', $defaults[$this->_id]['participant_status_id']);
569 $eventID = $defaults[$this->_id]['event_id'];
570
571 $this->_eventTypeId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $eventID, 'event_type_id', 'id');
572
573 $this->_discountId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_id, 'discount_id');
574 if ($this->_discountId) {
575 $this->set('discountId', $this->_discountId);
576 }
577 }
578
579 list($defaults[$this->_id]['register_date'],
580 $defaults[$this->_id]['register_date_time']
581 ) = CRM_Utils_Date::setDateDefaults(
582 CRM_Utils_Array::value('register_date', $defaults[$this->_id]), 'activityDateTime'
583 );
584
585 //assign event and role id, this is needed for Custom data building
586 $sep = CRM_Core_DAO::VALUE_SEPARATOR;
587 if (!empty($defaults[$this->_id]['participant_role_id'])) {
588 $roleIDs = explode($sep, $defaults[$this->_id]['participant_role_id']);
589 }
590 if (isset($_POST['event_id'])) {
591 $eventID = $_POST['event_id'];
592 }
593
594 if($this->_eID) {
595 $eventID = $this->_eID;
596 //@todo - rationalise the $this->_eID with $POST['event_id'], $this->_eid is set when eid=x is in the url
597 $roleID = CRM_Core_DAO::getFieldValue(
598 'CRM_Event_DAO_Event',
599 $this->_eID,
600 'default_role_id'
601 );
602 if(empty($roleIDs)) {
603 $roleIDs = (array) $defaults[$this->_id]['participant_role_id'] = $roleID;
604 }
605 $defaults[$this->_id]['event_id'] = $eventID;
606 }
607 if (!empty($eventID)) {
608 $this->_eventTypeId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $eventID, 'event_type_id', 'id');
609 }
610 //these should take precedence so we state them last
611 $urlRoleIDS = CRM_Utils_Request::retrieve('roles', 'String');
612 if($urlRoleIDS) {
613 $roleIDs = explode(',', $urlRoleIDS);
614 }
615 if (isset($roleIDs)) {
616 $defaults[$this->_id]['role_id'] = implode(',', $roleIDs);
617 }
618
619 if (isset($eventID)) {
620 $this->assign('eventID', $eventID);
621 $this->set('eventId', $eventID);
622 }
623
624 if (isset($this->_eventTypeId)) {
625 $this->assign('eventTypeID', $this->_eventTypeId);
626 }
627
628 $this->assign('event_is_test', CRM_Utils_Array::value('event_is_test', $defaults[$this->_id]));
629 return $defaults[$this->_id];
630 }
631
632 /**
633 * Function to build the form
634 *
635 * @return void
636 * @access public
637 */
638 public function buildQuickForm() {
639 $participantStatuses = CRM_Event_PseudoConstant::participantStatus();
640 $partiallyPaidStatusId = array_search('Partially paid', $participantStatuses);
641 $this->assign('partiallyPaidStatusId', $partiallyPaidStatusId);
642
643 if ($this->_showFeeBlock) {
644 return CRM_Event_Form_EventFees::buildQuickForm($this);
645 }
646
647 if ($this->_cdType) {
648 return CRM_Custom_Form_CustomData::buildQuickForm($this);
649 }
650
651 //need to assign custom data type to the template
652 $this->assign('customDataType', 'Participant');
653
654 $this->applyFilter('__ALL__', 'trim');
655
656 if ($this->_action & CRM_Core_Action::DELETE) {
657 if ($this->_single) {
658 $additionalParticipant = count(CRM_Event_BAO_Event::buildCustomProfile($this->_id,
659 NULL,
660 $this->_contactId,
661 FALSE,
662 TRUE
663 )) - 1;
664 if ($additionalParticipant) {
665 $deleteParticipants = array(1 => ts('Delete this participant record along with associated participant record(s).'),
666 2 => ts('Delete only this participant record.'),
667 );
668 $this->addRadio('delete_participant', NULL, $deleteParticipants, NULL, '<br />');
669 $this->setDefaults(array('delete_participant' => 1));
670 $this->assign('additionalParticipant', $additionalParticipant);
671 }
672 }
673 $this->addButtons(array(
674 array(
675 'type' => 'next',
676 'name' => ts('Delete'),
677 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
678 'isDefault' => TRUE,
679 ),
680 array(
681 'type' => 'cancel',
682 'name' => ts('Cancel'),
683 ),
684 )
685 );
686 return;
687 }
688
689
690 if ($this->_single) {
691 $urlPath = 'civicrm/contact/view/participant';
692 $urlParams = "reset=1&cid={$this->_contactId}&context=participant";
693 if ($this->_context == 'standalone') {
694 $this->addEntityRef('contact_id', ts('Contact'), array('create' => TRUE), TRUE);
695 $urlParams = 'reset=1&context=standalone';
696 $urlPath = 'civicrm/participant/add';
697 }
698
699 if ($this->_id) {
700 $urlParams .= "&action=update&id={$this->_id}";
701 }
702 else {
703 $urlParams .= "&action=add";
704 }
705
706 if ($this->_mode) {
707 $urlParams .= "&mode={$this->_mode}";
708 }
709
710 $url = CRM_Utils_System::url($urlPath, $urlParams,
711 FALSE, NULL, FALSE
712 );
713 }
714 else {
715 $currentPath = CRM_Utils_System::currentPath();
716
717 $url = CRM_Utils_System::url($currentPath, '_qf_Participant_display=true',
718 FALSE, NULL, FALSE
719 );
720 }
721
722 $this->assign('refreshURL', $url);
723
724 $eventFieldParams = array(
725 'entity' => 'event',
726 'select' => array('minimumInputLength' => 0),
727 'api' => array(
728 'extra' => array('campaign_id', 'default_role_id', 'event_type_id'),
729 )
730 );
731
732 if ($this->_mode) {
733 // exclude events which are not monetary when credit card registration is used
734 $eventFieldParams['api']['params']['is_monetary'] = 1;
735 $this->add('select', 'payment_processor_id', ts('Payment Processor'), $this->_processors, TRUE);
736 }
737
738 $element = $this->addEntityRef('event_id', ts('Event'), $eventFieldParams, TRUE);
739
740 //frozen the field fix for CRM-4171
741 if ($this->_action & CRM_Core_Action::UPDATE && $this->_id) {
742 if (CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment',
743 $this->_id, 'contribution_id', 'participant_id'
744 )) {
745 $element->freeze();
746 }
747 }
748
749 //CRM-7362 --add campaigns.
750 $campaignId = NULL;
751 if ($this->_id) {
752 $campaignId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $this->_id, 'campaign_id');
753 }
754 if (!$campaignId) {
755 $eventId = CRM_Utils_Request::retrieve('eid', 'Positive', $this);
756 if ($eventId) {
757 $campaignId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $eventId, 'campaign_id');
758 }
759 }
760 CRM_Campaign_BAO_Campaign::addCampaign($this, $campaignId);
761
762 $this->addDateTime('register_date', ts('Registration Date'), TRUE, array('formatType' => 'activityDateTime'));
763
764 if ($this->_id) {
765 $this->assign('entityID', $this->_id);
766 }
767
768 $this->addSelect('role_id', array('multiple' => TRUE, 'class' => 'huge'), TRUE);
769
770 // CRM-4395
771 $checkCancelledJs = array('onchange' => "return sendNotification( );");
772 $confirmJS = NULL;
773 if ($this->_onlinePendingContributionId) {
774 $cancelledparticipantStatusId = array_search('Cancelled', CRM_Event_PseudoConstant::participantStatus());
775 $cancelledContributionStatusId = array_search('Cancelled',
776 CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name')
777 );
778 $checkCancelledJs = array(
779 'onchange' =>
780 "checkCancelled( this.value, {$cancelledparticipantStatusId},{$cancelledContributionStatusId});",
781 );
782
783 $participantStatusId = array_search('Pending from pay later',
784 CRM_Event_PseudoConstant::participantStatus()
785 );
786 $contributionStatusId = array_search('Completed',
787 CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name')
788 );
789 $confirmJS = array('onclick' => "return confirmStatus( {$participantStatusId}, {$contributionStatusId} );");
790 }
791
792 // get the participant status names to build special status array which is used to show notification
793 // checkbox below participant status select
794 $participantStatusName = CRM_Event_PseudoConstant::participantStatus();
795 $notificationStatuses = array(
796 'Cancelled',
797 'Pending from waitlist',
798 'Pending from approval',
799 'Expired',
800 );
801
802 // get the required status and then implode only ids
803 $notificationStatusIds = implode(',', array_keys(array_intersect($participantStatusName, $notificationStatuses)));
804 $this->assign('notificationStatusIds', $notificationStatusIds);
805
806 $this->_participantStatuses = CRM_Event_PseudoConstant::participantStatus(NULL, NULL, 'label');
807 $this->addSelect('status_id', $checkCancelledJs + array('option_url' => 'civicrm/admin/participant_status'), TRUE);
808
809 $enableCart = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::EVENT_PREFERENCES_NAME,
810 'enable_cart'
811 );
812 $pendingInCartStatusId = array_search('Pending in cart', $participantStatusName);
813 $this->assign('pendingInCartStatusId', $pendingInCartStatusId);
814 $this->assign('enableCart', $enableCart);
815 $pendingRefundStatusId = array_search('Pending refund', $participantStatusName);
816 $this->assign('pendingRefundStatusId', $pendingRefundStatusId);
817
818 $this->addElement('checkbox', 'is_notify', ts('Send Notification'), NULL);
819
820 $this->add('text', 'source', ts('Event Source'));
821 $noteAttributes = CRM_Core_DAO::getAttribute('CRM_Core_DAO_Note');
822 $this->add('textarea', 'note', ts('Notes'), $noteAttributes['note']);
823
824 $buttons[] = array(
825 'type' => 'upload',
826 'name' => ts('Save'),
827 'isDefault' => TRUE,
828 'js' => $confirmJS,
829 );
830
831 $path = CRM_Utils_System::currentPath();
832 $excludeForPaths = array(
833 'civicrm/contact/search',
834 'civicrm/group/search'
835 );
836 if (!in_array($path, $excludeForPaths)) {
837 $buttons[] = array(
838 'type' => 'upload',
839 'name' => ts('Save and New'),
840 'subName' => 'new',
841 'js' => $confirmJS,
842 );
843 }
844
845 $buttons[] = array(
846 'type' => 'cancel',
847 'name' => ts('Cancel'),
848 );
849
850 $this->addButtons($buttons);
851 if ($this->_action == CRM_Core_Action::VIEW) {
852 $this->freeze();
853 }
854 }
855
856 /**
857 * Add local and global form rules
858 *
859 * @access protected
860 *
861 * @return void
862 */
863 function addRules() {
864 $this->addFormRule(array('CRM_Event_Form_Participant', 'formRule'), $this);
865 }
866
867 /**
868 * global validation rules for the form
869 *
870 * @param $values
871 * @param $files
872 * @param $self
873 *
874 * @internal param array $fields posted values of the form
875 *
876 * @return array list of errors to be posted back to the form
877 * @static
878 * @access public
879 */
880 static function formRule($values, $files, $self) {
881 // If $values['_qf_Participant_next'] is Delete or
882 // $values['event_id'] is empty, then return
883 // instead of proceeding further.
884
885 if ((CRM_Utils_Array::value('_qf_Participant_next', $values) == 'Delete') ||
886 (!$values['event_id'])
887 ) {
888 return TRUE;
889 }
890
891 $errorMsg = array();
892
893 if (!empty($values['payment_processor_id'])) {
894 // make sure that credit card number and cvv are valid
895 CRM_Core_Payment_Form::validateCreditCard($values, $errorMsg);
896 }
897
898 if (!empty($values['record_contribution'])) {
899 if (empty($values['financial_type_id'])) {
900 $errorMsg['financial_type_id'] = ts('Please enter the associated Financial Type');
901 }
902 if (empty($values['payment_instrument_id'])) {
903 $errorMsg['payment_instrument_id'] = ts('Paid By is a required field.');
904 }
905 }
906
907 // validate contribution status for 'Failed'.
908 if ($self->_onlinePendingContributionId && !empty($values['record_contribution']) &&
909 (CRM_Utils_Array::value('contribution_status_id', $values) ==
910 array_search('Failed', CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'))
911 )
912 ) {
913 $errorMsg['contribution_status_id'] = ts('Please select a valid payment status before updating.');
914 }
915
916 // do the amount validations.
917 //skip for update mode since amount is freeze, CRM-6052
918 if ((!$self->_id && empty($values['total_amount']) &&
919 empty($self->_values['line_items'])
920 ) ||
921 ($self->_id && !$self->_paymentId && isset($self->_values['line_items']) && is_array($self->_values['line_items']))
922 ) {
923 if ($priceSetId = CRM_Utils_Array::value('priceSetId', $values)) {
924 CRM_Price_BAO_PriceField::priceSetValidation($priceSetId, $values, $errorMsg, TRUE);
925 }
926 }
927 return CRM_Utils_Array::crmIsEmptyArray($errorMsg) ? TRUE : $errorMsg;
928 }
929
930 /**
931 * Function to process the form
932 *
933 * @access public
934 */
935 public function postProcess() {
936 // get the submitted form values.
937 $params = $this->controller->exportValues($this->_name);
938
939 if ($this->_action & CRM_Core_Action::DELETE) {
940 if (CRM_Utils_Array::value('delete_participant', $params) == 2) {
941 $additionalId = (CRM_Event_BAO_Participant::getAdditionalParticipantIds($this->_id));
942 $participantLinks = (CRM_Event_BAO_Participant::getAdditionalParticipantUrl($additionalId));
943 }
944 if (CRM_Utils_Array::value('delete_participant', $params) == 1) {
945 $additionalIds = CRM_Event_BAO_Participant::getAdditionalParticipantIds($this->_id);
946 foreach ($additionalIds as $value) {
947 CRM_Event_BAO_Participant::deleteParticipant($value);
948 }
949 }
950 CRM_Event_BAO_Participant::deleteParticipant($this->_id);
951 CRM_Core_Session::setStatus(ts('Selected participant was deleted successfully.'), ts('Record Deleted'), 'success');
952 if (!empty($participantLinks)) {
953 $status = ts('The following participants no longer have an event fee recorded. You can edit their registration and record a replacement contribution by clicking the links below:') . '<br>' . $participantLinks;
954 CRM_Core_Session::setStatus($status, ts('Group Payment Deleted'));
955 }
956 return;
957 }
958
959 $participantStatus = CRM_Event_PseudoConstant::participantStatus();
960 // set the contact, when contact is selected
961 if (!empty($params['contact_id'])) {
962 $this->_contactId = $params['contact_id'];
963 }
964 if ($this->_priceSetId && $isQuickConfig = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_priceSetId, 'is_quick_config')) {
965 $this->_quickConfig = $isQuickConfig;
966 }
967
968 if ($this->_id) {
969 $params['id'] = $this->_id;
970 }
971
972 $config = CRM_Core_Config::singleton();
973 if ($this->_isPaidEvent) {
974
975 $contributionParams = array();
976 $lineItem = array();
977 $additionalParticipantDetails = array();
978 if (($this->_id && $this->_action & CRM_Core_Action::UPDATE) && $this->_paymentId) {
979 $participantBAO = new CRM_Event_BAO_Participant();
980 $participantBAO->id = $this->_id;
981 $participantBAO->find(TRUE);
982 $contributionParams['total_amount'] = $participantBAO->fee_amount;
983
984 $params['discount_id'] = NULL;
985 //re-enter the values for UPDATE mode
986 $params['fee_level'] = $params['amount_level'] = $participantBAO->fee_level;
987 $params['fee_amount'] = $participantBAO->fee_amount;
988 if (isset($params['priceSetId'])) {
989 $lineItem[0] = CRM_Price_BAO_LineItem::getLineItems($this->_id);
990 }
991 //also add additional participant's fee level/priceset
992 if (CRM_Event_BAO_Participant::isPrimaryParticipant($this->_id)) {
993 $additionalIds = CRM_Event_BAO_Participant::getAdditionalParticipantIds($this->_id);
994 $hasLineItems = CRM_Utils_Array::value('priceSetId', $params, FALSE);
995 $additionalParticipantDetails = CRM_Event_BAO_Participant::getFeeDetails($additionalIds,
996 $hasLineItems
997 );
998 }
999 }
1000 else {
1001
1002 //check if discount is selected
1003 if (!empty($params['discount_id'])) {
1004 $discountId = $params['discount_id'];
1005 }
1006 else {
1007 $discountId = $params['discount_id'] = 'null';
1008 }
1009
1010 //lets carry currency, CRM-4453
1011 $params['fee_currency'] = $config->defaultCurrency;
1012 CRM_Price_BAO_PriceSet::processAmount($this->_values['fee'],
1013 $params, $lineItem[0]
1014 );
1015 //CRM-11529 for quick config backoffice transactions
1016 //when financial_type_id is passed in form, update the
1017 //lineitems with the financial type selected in form
1018 $submittedFinancialType = CRM_Utils_Array::value('financial_type_id', $params);
1019 $isPaymentRecorded = CRM_Utils_Array::value('record_contribution', $params);
1020 if ($isPaymentRecorded && $this->_quickConfig && $submittedFinancialType) {
1021 foreach ($lineItem[0] as &$values) {
1022 $values['financial_type_id'] = $submittedFinancialType;
1023 }
1024 }
1025
1026 $params['fee_level'] = $params['amount_level'];
1027 $contributionParams['total_amount'] = $params['amount'];
1028 if ($this->_quickConfig && !empty($params['total_amount']) &&
1029 $params['status_id'] != array_search('Partially paid', $participantStatus)) {
1030 $params['fee_amount'] = $params['total_amount'];
1031 } else {
1032 //fix for CRM-3086
1033 $params['fee_amount'] = $params['amount'];
1034 }
1035 }
1036
1037 if (isset($params['priceSetId'])) {
1038 if (!empty($lineItem[0])) {
1039 $this->set('lineItem', $lineItem);
1040
1041 $this->_lineItem = $lineItem;
1042 $lineItem = array_merge($lineItem, $additionalParticipantDetails);
1043
1044 $participantCount = array();
1045 foreach ($lineItem as $k) {
1046 foreach ($k as $v) {
1047 if (CRM_Utils_Array::value('participant_count', $v) > 0) {
1048 $participantCount[] = $v['participant_count'];
1049 }
1050 }
1051 }
1052 }
1053 if (isset($participantCount)) {
1054 $this->assign('pricesetFieldsCount', $participantCount);
1055 }
1056 $this->assign('lineItem', empty($lineItem[0]) || $this->_quickConfig? FALSE : $lineItem);
1057 }
1058 else {
1059 $this->assign('amount_level', $params['amount_level']);
1060 }
1061 }
1062
1063 $this->_params = $params;
1064 $amountOwed = NULL;
1065 if (isset($params['amount'])) {
1066 $amountOwed = $params['amount'];
1067 unset($params['amount']);
1068 }
1069 $params['register_date'] = CRM_Utils_Date::processDate($params['register_date'], $params['register_date_time']);
1070 $params['receive_date'] = CRM_Utils_Date::processDate(CRM_Utils_Array::value('receive_date', $params));
1071 $params['contact_id'] = $this->_contactId;
1072
1073 // overwrite actual payment amount if entered
1074 if (!empty($params['total_amount'])) {
1075 $contributionParams['total_amount'] = CRM_Utils_Array::value('total_amount', $params);
1076 }
1077
1078
1079 // Retrieve the name and email of the current user - this will be the FROM for the receipt email
1080 $session = CRM_Core_Session::singleton();
1081 $userID = $session->get('userID');
1082 list($userName,
1083 $userEmail
1084 ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($userID);
1085
1086 if ($this->_contactId) {
1087 list($this->_contributorDisplayName, $this->_contributorEmail, $this->_toDoNotEmail) = CRM_Contact_BAO_Contact::getContactDetails($this->_contactId);
1088 }
1089
1090 if ($this->_mode) {
1091 if (!$this->_isPaidEvent) {
1092 CRM_Core_Error::fatal(ts('Selected Event is not Paid Event '));
1093 }
1094 //modify params according to parameter used in create
1095 //participant method (addParticipant)
1096 $this->_params['participant_status_id'] = $params['status_id'];
1097 $this->_params['participant_role_id'] = explode(',', $params['role_id']);
1098 $this->_params['participant_register_date'] = $params['register_date'];
1099
1100 $eventTitle =
1101 CRM_Core_DAO::getFieldValue(
1102 'CRM_Event_DAO_Event',
1103 $params['event_id'],
1104 'title'
1105 );
1106
1107 // set source if not set
1108 if (empty($params['source'])) {
1109 $this->_params['participant_source'] = ts('Offline Registration for Event: %2 by: %1', array(1 => $userName, 2 => $eventTitle));
1110 }
1111 else {
1112 $this->_params['participant_source'] = $params['source'];
1113 }
1114 $this->_params['description'] = $this->_params['participant_source'];
1115
1116 $this->_paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($this->_params['payment_processor_id'],
1117 $this->_mode
1118 );
1119 $now = date('YmdHis');
1120 $fields = array();
1121
1122 // set email for primary location.
1123 $fields['email-Primary'] = 1;
1124 $params['email-Primary'] = $params["email-{$this->_bltID}"] = $this->_contributorEmail;
1125
1126 $params['register_date'] = $now;
1127
1128 // now set the values for the billing location.
1129 foreach ($this->_fields as $name => $dontCare) {
1130 $fields[$name] = 1;
1131 }
1132
1133 // also add location name to the array
1134 $params["address_name-{$this->_bltID}"] =
1135 CRM_Utils_Array::value('billing_first_name', $params) . ' ' .
1136 CRM_Utils_Array::value('billing_middle_name', $params) . ' ' .
1137 CRM_Utils_Array::value('billing_last_name', $params);
1138
1139 $params["address_name-{$this->_bltID}"] = trim($params["address_name-{$this->_bltID}"]);
1140 $fields["address_name-{$this->_bltID}"] = 1;
1141 $fields["email-{$this->_bltID}"] = 1;
1142 $ctype = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $this->_contactId, 'contact_type');
1143
1144 $nameFields = array('first_name', 'middle_name', 'last_name');
1145
1146 foreach ($nameFields as $name) {
1147 $fields[$name] = 1;
1148 if (array_key_exists("billing_$name", $params)) {
1149 $params[$name] = $params["billing_{$name}"];
1150 $params['preserveDBName'] = TRUE;
1151 }
1152 }
1153 $contactID = CRM_Contact_BAO_Contact::createProfileContact($params, $fields, $this->_contactId, NULL, NULL, $ctype);
1154 }
1155
1156 if ($this->_params['role_id']) {
1157 foreach ($this->_params['role_id'] as $rkey) {
1158 $customFieldsRole = CRM_Core_BAO_CustomField::getFields('Participant', FALSE, FALSE, $rkey, $this->_roleCustomDataTypeID);
1159 $customFieldsEvent = CRM_Core_BAO_CustomField::getFields('Participant',
1160 FALSE,
1161 FALSE,
1162 CRM_Utils_Array::value('event_id', $params),
1163 $this->_eventNameCustomDataTypeID
1164 );
1165 $customFieldsEventType = CRM_Core_BAO_CustomField::getFields('Participant',
1166 FALSE,
1167 FALSE,
1168 $this->_eventTypeId,
1169 $this->_eventTypeCustomDataTypeID
1170 );
1171 $customFields = CRM_Utils_Array::crmArrayMerge($customFieldsRole,
1172 CRM_Core_BAO_CustomField::getFields('Participant', FALSE, FALSE, NULL, NULL, TRUE)
1173 );
1174 $customFields = CRM_Utils_Array::crmArrayMerge($customFieldsEvent, $customFields);
1175 $customFields = CRM_Utils_Array::crmArrayMerge($customFieldsEventType, $customFields);
1176 $params['custom'] = CRM_Core_BAO_CustomField::postProcess($params,
1177 $customFields,
1178 $this->_id,
1179 'Participant'
1180 );
1181 }
1182 }
1183
1184 //do cleanup line items if participant edit the Event Fee.
1185 if (($this->_lineItem || !isset($params['proceSetId'])) && !$this->_paymentId && $this->_id) {
1186 CRM_Price_BAO_LineItem::deleteLineItems($this->_id, 'civicrm_participant');
1187 }
1188
1189 if ($this->_mode) {
1190 // add all the additional payment params we need
1191 $this->_params["state_province-{$this->_bltID}"] = $this->_params["billing_state_province-{$this->_bltID}"] = CRM_Core_PseudoConstant::stateProvinceAbbreviation($this->_params["billing_state_province_id-{$this->_bltID}"]);
1192 $this->_params["country-{$this->_bltID}"] = $this->_params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($this->_params["billing_country_id-{$this->_bltID}"]);
1193
1194 $this->_params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($this->_params);
1195 $this->_params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($this->_params);
1196 $this->_params['ip_address'] = CRM_Utils_System::ipAddress();
1197 $this->_params['amount'] = $params['fee_amount'];
1198 $this->_params['amount_level'] = $params['amount_level'];
1199 $this->_params['currencyID'] = $config->defaultCurrency;
1200 $this->_params['payment_action'] = 'Sale';
1201 $this->_params['invoiceID'] = md5(uniqid(rand(), TRUE));
1202
1203 // at this point we've created a contact and stored its address etc
1204 // all the payment processors expect the name and address to be in the
1205 // so we copy stuff over to first_name etc.
1206 $paymentParams = $this->_params;
1207 if (!empty($this->_params['send_receipt'])) {
1208 $paymentParams['email'] = $this->_contributorEmail;
1209 }
1210 CRM_Core_Payment_Form::mapParams($this->_bltID, $this->_params, $paymentParams, TRUE);
1211
1212 $payment = CRM_Core_Payment::singleton($this->_mode, $this->_paymentProcessor, $this);
1213
1214 $result = &$payment->doDirectPayment($paymentParams);
1215
1216 if (is_a($result, 'CRM_Core_Error')) {
1217 CRM_Core_Error::displaySessionError($result);
1218 CRM_Utils_System::redirect(CRM_Utils_System::url('civicrm/contact/view/participant',
1219 "reset=1&action=add&cid={$this->_contactId}&context=participant&mode={$this->_mode}"
1220 ));
1221 }
1222
1223 if ($result) {
1224 $this->_params = array_merge($this->_params, $result);
1225 }
1226
1227 $this->_params['receive_date'] = $now;
1228
1229 if (!empty($this->_params['send_receipt'])) {
1230 $this->_params['receipt_date'] = $now;
1231 }
1232 else {
1233 $this->_params['receipt_date'] = NULL;
1234 }
1235
1236 $this->set('params', $this->_params);
1237 $this->assign('trxn_id', $result['trxn_id']);
1238 $this->assign('receive_date',
1239 CRM_Utils_Date::processDate($this->_params['receive_date'])
1240 );
1241
1242 //add contribution record
1243 $this->_params['financial_type_id'] =
1244 CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $params['event_id'], 'financial_type_id');
1245 $this->_params['mode'] = $this->_mode;
1246
1247 //add contribution reocord
1248 $contributions[] = $contribution = CRM_Event_Form_Registration_Confirm::processContribution($this, $this->_params, $result, $contactID, FALSE);
1249
1250 // add participant record
1251 $participants = array();
1252 if (!empty($this->_params['role_id']) && is_array($this->_params['role_id'])) {
1253 $this->_params['role_id'] = implode(CRM_Core_DAO::VALUE_SEPARATOR,
1254 $this->_params['role_id']
1255 );
1256 }
1257 $participants[] = CRM_Event_Form_Registration::addParticipant($this->_params, $contactID);
1258
1259 //add custom data for participant
1260 CRM_Core_BAO_CustomValueTable::postProcess($this->_params,
1261 CRM_Core_DAO::$_nullArray,
1262 'civicrm_participant',
1263 $participants[0]->id,
1264 'Participant'
1265 );
1266 //add participant payment
1267 $paymentParticipant = array(
1268 'participant_id' => $participants[0]->id,
1269 'contribution_id' => $contribution->id,
1270 );
1271 $ids = array();
1272
1273 CRM_Event_BAO_ParticipantPayment::create($paymentParticipant, $ids);
1274 $this->_contactIds[] = $this->_contactId;
1275 }
1276 else {
1277 $participants = array();
1278 if ($this->_single) {
1279 if ($params['role_id']) {
1280 $params['role_id'] = str_replace(',', CRM_Core_DAO::VALUE_SEPARATOR, $params['role_id']);
1281 }
1282 else {
1283 $params['role_id'] = 'NULL';
1284 }
1285 $participants[] = CRM_Event_BAO_Participant::create($params);
1286 }
1287 else {
1288 foreach ($this->_contactIds as $contactID) {
1289 $commonParams = $params;
1290 $commonParams['contact_id'] = $contactID;
1291 if ($commonParams['role_id']) {
1292 $commonParams['role_id'] = $commonParams['role_id'] = str_replace(',', CRM_Core_DAO::VALUE_SEPARATOR, $params['role_id']);
1293 }
1294 else {
1295 $commonParams['role_id'] = 'NULL';
1296 }
1297 $participants[] = CRM_Event_BAO_Participant::create($commonParams);
1298 }
1299 }
1300
1301 if (isset($params['event_id'])) {
1302 $eventTitle = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event',
1303 $params['event_id'],
1304 'title'
1305 );
1306 }
1307
1308 if ($this->_single) {
1309 $this->_contactIds[] = $this->_contactId;
1310 }
1311
1312 $contributions = array();
1313 if (!empty($params['record_contribution'])) {
1314 if (!empty($params['id'])) {
1315 if ($this->_onlinePendingContributionId) {
1316 $ids['contribution'] = $this->_onlinePendingContributionId;
1317 }
1318 else {
1319 $ids['contribution'] = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment',
1320 $params['id'],
1321 'contribution_id',
1322 'participant_id'
1323 );
1324 }
1325 }
1326 unset($params['note']);
1327
1328 //build contribution params
1329 if (!$this->_onlinePendingContributionId) {
1330 $contributionParams['source'] = "{$eventTitle}: Offline registration (by {$userName})";
1331 }
1332
1333 $contributionParams['currency'] = $config->defaultCurrency;
1334 $contributionParams['non_deductible_amount'] = 'null';
1335 $contributionParams['receipt_date'] = !empty($params['send_receipt']) ? CRM_Utils_Array::value('receive_date', $params) : 'null';
1336
1337 $recordContribution = array( 'contact_id', 'financial_type_id',
1338 'payment_instrument_id', 'trxn_id',
1339 'contribution_status_id', 'receive_date',
1340 'check_number', 'campaign_id',
1341 );
1342
1343 foreach ($recordContribution as $f) {
1344 $contributionParams[$f] = CRM_Utils_Array::value($f, $params);
1345 if ($f == 'trxn_id') {
1346 $this->assign('trxn_id', $contributionParams[$f]);
1347 }
1348 }
1349
1350 //insert financial type name in receipt.
1351 $this->assign('contributionTypeName', CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialType', $contributionParams['financial_type_id']));
1352 $contributionParams['skipLineItem'] = 1;
1353 if ($this->_id) {
1354 $contributionParams['contribution_mode'] = 'participant';
1355 $contributionParams['participant_id'] = $this->_id;
1356 }
1357 // Set is_pay_later flag for back-office offline Pending status contributions
1358 if ($contributionParams['contribution_status_id'] == CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name')) {
1359 $contributionParams['is_pay_later'] = 1;
1360 }
1361
1362 if ($params['status_id'] == array_search('Partially paid', $participantStatus)) {
1363 if (!$amountOwed && $this->_action & CRM_Core_Action::UPDATE) {
1364 $amountOwed = $params['fee_amount'];
1365 }
1366
1367 // if multiple participants are link, consider contribution total amount as the amount Owed
1368 if ($this->_id && CRM_Event_BAO_Participant::isPrimaryParticipant($this->_id)) {
1369 $amountOwed = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution',
1370 $ids['contribution'],
1371 'total_amount'
1372 );
1373 }
1374
1375 // CRM-13964 partial_payment_total
1376 if ($amountOwed > $params['total_amount']) {
1377 // the owed amount
1378 $contributionParams['partial_payment_total'] = $amountOwed;
1379 // the actual amount paid
1380 $contributionParams['partial_amount_pay'] = $params['total_amount'];
1381 }
1382 }
1383
1384 if ($this->_single) {
1385 if (empty($ids)) {
1386 $ids = array();
1387 }
1388 $contributions[] = CRM_Contribute_BAO_Contribution::create($contributionParams, $ids);
1389 }
1390 else {
1391 $ids = array();
1392 foreach ($this->_contactIds as $contactID) {
1393 $contributionParams['contact_id'] = $contactID;
1394 $contributions[] = CRM_Contribute_BAO_Contribution::create($contributionParams, $ids);
1395 }
1396 }
1397
1398 //insert payment record for this participation
1399 if (empty($ids['contribution'])) {
1400 foreach ($this->_contactIds as $num => $contactID) {
1401 $ppDAO = new CRM_Event_DAO_ParticipantPayment();
1402 $ppDAO->participant_id = $participants[$num]->id;
1403 $ppDAO->contribution_id = $contributions[$num]->id;
1404 $ppDAO->save();
1405 }
1406 }
1407 // next create the transaction record
1408 $transaction = new CRM_Core_Transaction();
1409
1410 // CRM-11124
1411 if ($this->_quickConfig) {
1412 if (!empty($this->_params['amount_priceset_level_radio'])) {
1413 $feeLevel = $this->_params['amount_priceset_level_radio'];
1414 }
1415 else {
1416 $feeLevel[] = $this->_params['fee_level'] ;
1417 }
1418 CRM_Event_BAO_Participant::createDiscountTrxn($this->_eventId, $contributionParams, $feeLevel);
1419 }
1420 $transaction->commit();
1421 }
1422 }
1423
1424 // also store lineitem stuff here
1425 if ((($this->_lineItem & $this->_action & CRM_Core_Action::ADD) ||
1426 ($this->_lineItem && CRM_Core_Action::UPDATE && !$this->_paymentId))
1427 ) {
1428 foreach ($this->_contactIds as $num => $contactID) {
1429 foreach ($this->_lineItem as $key => $value) {
1430 if (is_array($value) && $value != 'skip') {
1431 foreach ($value as $lineKey => $line) {
1432 //10117 update the line items for participants if contribution amount is recorded
1433 if ($this->_quickConfig && !empty($params['total_amount']) &&
1434 ($params['status_id'] != array_search('Partially paid', $participantStatus))
1435 ) {
1436 $line['unit_price'] = $line['line_total'] = $params['total_amount'];
1437 }
1438 $lineItem[$this->_priceSetId][$lineKey] = $line;
1439 }
1440 CRM_Price_BAO_LineItem::processPriceSet($participants[$num]->id, $lineItem, CRM_Utils_Array::value($num, $contributions, NULL), 'civicrm_participant');
1441 }
1442 }
1443 }
1444 }
1445
1446 $updateStatusMsg = NULL;
1447 //send mail when participant status changed, CRM-4326
1448 if ($this->_id && $this->_statusId &&
1449 $this->_statusId != CRM_Utils_Array::value('status_id', $params) && !empty($params['is_notify'])) {
1450
1451 $updateStatusMsg = CRM_Event_BAO_Participant::updateStatusMessage($this->_id,
1452 $params['status_id'],
1453 $this->_statusId
1454 );
1455 }
1456
1457 $sent = array();
1458 $notSent = array();
1459 if (!empty($params['send_receipt'])) {
1460 if (array_key_exists($params['from_email_address'], $this->_fromEmails['from_email_id'])) {
1461 $receiptFrom = $params['from_email_address'];
1462 }
1463
1464 $this->assign('module', 'Event Registration');
1465 //use of the message template below requires variables in different format
1466 $event = $events = array();
1467 $returnProperties = array('fee_label', 'start_date', 'end_date', 'is_show_location', 'title');
1468
1469 //get all event details.
1470 CRM_Core_DAO::commonRetrieveAll('CRM_Event_DAO_Event', 'id', $params['event_id'], $events, $returnProperties);
1471 $event = $events[$params['event_id']];
1472 unset($event['start_date']);
1473 unset($event['end_date']);
1474
1475 $role = CRM_Event_PseudoConstant::participantRole();
1476 $participantRoles = CRM_Utils_Array::value('role_id', $params);
1477 if (is_array($participantRoles)) {
1478 $selectedRoles = array();
1479 foreach (array_keys($participantRoles) as $roleId) {
1480 $selectedRoles[] = $role[$roleId];
1481 }
1482 $event['participant_role'] = implode(', ', $selectedRoles);
1483 }
1484 else {
1485 $event['participant_role'] = CRM_Utils_Array::value($participantRoles, $role);
1486 }
1487 $event['is_monetary'] = $this->_isPaidEvent;
1488
1489 if ($params['receipt_text']) {
1490 $event['confirm_email_text'] = $params['receipt_text'];
1491 }
1492
1493 $this->assign('isAmountzero', 1);
1494 $this->assign('event', $event);
1495
1496 $this->assign('isShowLocation', $event['is_show_location']);
1497 if (CRM_Utils_Array::value('is_show_location', $event) == 1) {
1498 $locationParams = array(
1499 'entity_id' => $params['event_id'],
1500 'entity_table' => 'civicrm_event',
1501 );
1502 $location = CRM_Core_BAO_Location::getValues($locationParams, TRUE);
1503 $this->assign('location', $location);
1504 }
1505
1506 $status = CRM_Event_PseudoConstant::participantStatus();
1507 if ($this->_isPaidEvent) {
1508 $paymentInstrument = CRM_Contribute_PseudoConstant::paymentInstrument();
1509 if (!$this->_mode) {
1510 if (isset($params['payment_instrument_id'])) {
1511 $this->assign('paidBy',
1512 CRM_Utils_Array::value($params['payment_instrument_id'],
1513 $paymentInstrument
1514 )
1515 );
1516 }
1517 }
1518
1519 $this->assign('totalAmount', $contributionParams['total_amount']);
1520 if (isset($contributionParams['partial_payment_total'])) {
1521 // balance amount
1522 $balanceAmount = $contributionParams['partial_payment_total'] - $contributionParams['partial_amount_pay'];
1523 $this->assign('balanceAmount', $balanceAmount );
1524 }
1525 $this->assign('isPrimary', 1);
1526 $this->assign('checkNumber', CRM_Utils_Array::value('check_number', $params));
1527 }
1528 if ($this->_mode) {
1529 if (!empty($params['billing_first_name'])) {
1530 $name = $params['billing_first_name'];
1531 }
1532
1533 if (!empty($params['billing_middle_name'])) {
1534 $name .= " {$params['billing_middle_name']}";
1535 }
1536
1537 if (!empty($params['billing_last_name'])) {
1538 $name .= " {$params['billing_last_name']}";
1539 }
1540 $this->assign('billingName', $name);
1541
1542 // assign the address formatted up for display
1543 $addressParts = array(
1544 "street_address-{$this->_bltID}",
1545 "city-{$this->_bltID}",
1546 "postal_code-{$this->_bltID}",
1547 "state_province-{$this->_bltID}",
1548 "country-{$this->_bltID}",
1549 );
1550 $addressFields = array();
1551 foreach ($addressParts as $part) {
1552 list($n, $id) = explode('-', $part);
1553 if (isset($this->_params['billing_' . $part])) {
1554 $addressFields[$n] = $this->_params['billing_' . $part];
1555 }
1556 }
1557 $this->assign('address', CRM_Utils_Address::format($addressFields));
1558
1559 $date = CRM_Utils_Date::format($params['credit_card_exp_date']);
1560 $date = CRM_Utils_Date::mysqlToIso($date);
1561 $this->assign('credit_card_exp_date', $date);
1562 $this->assign('credit_card_number',
1563 CRM_Utils_System::mungeCreditCard($params['credit_card_number'])
1564 );
1565 $this->assign('credit_card_type', $params['credit_card_type']);
1566 $this->assign('contributeMode', 'direct');
1567 $this->assign('isAmountzero', 0);
1568 $this->assign('is_pay_later', 0);
1569 $this->assign('isPrimary', 1);
1570 }
1571
1572 $this->assign('register_date', $params['register_date']);
1573 if ($params['receive_date']) {
1574 $this->assign('receive_date', $params['receive_date']);
1575 }
1576
1577 $participant = array(array('participant_id', '=', $participants[0]->id, 0, 0));
1578 // check whether its a test drive ref CRM-3075
1579 if (!empty($this->_defaultValues['is_test'])) {
1580 $participant[] = array('participant_test', '=', 1, 0, 0);
1581 }
1582
1583 $template = CRM_Core_Smarty::singleton();
1584 $customGroup = array();
1585 //format submitted data
1586 foreach ($params['custom'] as $fieldID => $values) {
1587 foreach ($values as $fieldValue) {
1588 $customValue = array('data' => $fieldValue['value']);
1589 $customFields[$fieldID]['id'] = $fieldID;
1590 $formattedValue = CRM_Core_BAO_CustomGroup::formatCustomValues($customValue, $customFields[$fieldID], TRUE);
1591 $customGroup[$customFields[$fieldID]['groupTitle']][$customFields[$fieldID]['label']] = str_replace('&nbsp;', '', $formattedValue);
1592 }
1593 }
1594
1595 foreach ($this->_contactIds as $num => $contactID) {
1596 // Retrieve the name and email of the contact - this will be the TO for receipt email
1597 list($this->_contributorDisplayName, $this->_contributorEmail, $this->_toDoNotEmail) = CRM_Contact_BAO_Contact::getContactDetails($contactID);
1598
1599 $this->_contributorDisplayName = ($this->_contributorDisplayName == ' ') ? $this->_contributorEmail : $this->_contributorDisplayName;
1600
1601 $waitStatus = CRM_Event_PseudoConstant::participantStatus(NULL, "class = 'Waiting'");
1602 if ($waitingStatus = CRM_Utils_Array::value($params['status_id'], $waitStatus)) {
1603 $this->assign('isOnWaitlist', TRUE);
1604 }
1605
1606 $this->assign('customGroup', $customGroup);
1607 $this->assign('contactID', $contactID);
1608 $this->assign('participantID', $participants[$num]->id);
1609
1610 $this->_id = $participants[$num]->id;
1611
1612 if ($this->_isPaidEvent) {
1613 // fix amount for each of participants ( for bulk mode )
1614 $eventAmount = array();
1615 if (!empty($additionalParticipantDetails)) {
1616 $params['amount_level'] = preg_replace('/\ 1/', '', $params['amount_level']) . ' - ' . $this->_contributorDisplayName;
1617 }
1618
1619 $eventAmount[$num] = array(
1620 'label' => preg_replace('/\ 1/', '', $params['amount_level']),
1621 'amount' => $params['fee_amount'],
1622 );
1623 //as we are using same template for online & offline registration.
1624 //So we have to build amount as array.
1625 $eventAmount = array_merge($eventAmount, $additionalParticipantDetails);
1626 $this->assign('amount', $eventAmount);
1627 }
1628
1629 $sendTemplateParams = array(
1630 'groupName' => 'msg_tpl_workflow_event',
1631 'valueName' => 'event_offline_receipt',
1632 'contactId' => $contactID,
1633 'isTest' => (bool) CRM_Utils_Array::value('is_test', $this->_defaultValues),
1634 'PDFFilename' => ts('confirmation').'.pdf',
1635 );
1636
1637 // try to send emails only if email id is present
1638 // and the do-not-email option is not checked for that contact
1639 if ($this->_contributorEmail and !$this->_toDoNotEmail) {
1640 $sendTemplateParams['from'] = $receiptFrom;
1641 $sendTemplateParams['toName'] = $this->_contributorDisplayName;
1642 $sendTemplateParams['toEmail'] = $this->_contributorEmail;
1643 $sendTemplateParams['cc'] = CRM_Utils_Array::value('cc', $this->_fromEmails);
1644 $sendTemplateParams['bcc'] = CRM_Utils_Array::value('bcc', $this->_fromEmails);
1645 }
1646
1647 list($mailSent, $subject, $message, $html) = CRM_Core_BAO_MessageTemplate::sendTemplate($sendTemplateParams);
1648 if ($mailSent) {
1649 $sent[] = $contactID;
1650 foreach ($participants as $ids => $values) {
1651 if ($values->contact_id == $contactID) {
1652 CRM_Activity_BAO_Activity::addActivity($values, 'Email');
1653 break;
1654 }
1655 }
1656 }
1657 else {
1658 $notSent[] = $contactID;
1659 }
1660 }
1661 }
1662
1663 // set the participant id if it is not set
1664 if (!$this->_id) {
1665 $this->_id = $participants[0]->id;
1666 }
1667
1668 if (($this->_action & CRM_Core_Action::UPDATE)) {
1669 $statusMsg = ts('Event registration information for %1 has been updated.', array(1 => $this->_contributorDisplayName));
1670 if (!empty($params['send_receipt']) && count($sent)) {
1671 $statusMsg .= ' ' . ts('A confirmation email has been sent to %1', array(1 => $this->_contributorEmail));
1672 }
1673
1674 if ($updateStatusMsg) {
1675 $statusMsg = "{$statusMsg} {$updateStatusMsg}";
1676 }
1677 }
1678 elseif ($this->_action & CRM_Core_Action::ADD) {
1679 if ($this->_single) {
1680 $statusMsg = ts('Event registration for %1 has been added.', array(1 => $this->_contributorDisplayName));
1681 if (!empty($params['send_receipt']) && count($sent)) {
1682 $statusMsg .= ' ' . ts('A confirmation email has been sent to %1.', array(1 => $this->_contributorEmail));
1683 }
1684 }
1685 else {
1686 $statusMsg = ts('Total Participant(s) added to event: %1.', array(1 => count($this->_contactIds)));
1687 if (count($notSent) > 0) {
1688 $statusMsg .= ' ' . ts('Email has NOT been sent to %1 contact(s) - communication preferences specify DO NOT EMAIL OR valid Email is NOT present. ', array(1 => count($notSent)));
1689 }
1690 elseif (isset($params['send_receipt'])) {
1691 $statusMsg .= ' ' . ts('A confirmation email has been sent to ALL participants');
1692 }
1693 }
1694 }
1695 CRM_Core_Session::setStatus($statusMsg, ts('Saved'), 'success');
1696
1697 $buttonName = $this->controller->getButtonName();
1698 if ($this->_context == 'standalone') {
1699 if ($buttonName == $this->getButtonName('upload', 'new')) {
1700 $urlParams = 'reset=1&action=add&context=standalone';
1701 if ($this->_mode) {
1702 $urlParams .= '&mode=' . $this->_mode;
1703 }
1704 if ($this->_eID) {
1705 $urlParams .= '&eid=' . $this->_eID;
1706 }
1707 $session->replaceUserContext(CRM_Utils_System::url('civicrm/participant/add', $urlParams));
1708 }
1709 else {
1710 $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view',
1711 "reset=1&cid={$this->_contactId}&selectedChild=participant"
1712 ));
1713 }
1714 }
1715 elseif ($buttonName == $this->getButtonName('upload', 'new')) {
1716 $session->replaceUserContext(CRM_Utils_System::url('civicrm/contact/view/participant',
1717 "reset=1&action=add&context={$this->_context}&cid={$this->_contactId}"
1718 ));
1719 }
1720 }
1721 }