Move BAO and template files into event cart
[civicrm-core.git] / ext / eventcart / CRM / Event / Cart / Form / Checkout / ParticipantsAndPrices.php
CommitLineData
6a488035 1<?php
0cf587a7
EM
2
3/**
4 * Class CRM_Event_Cart_Form_Checkout_ParticipantsAndPrices
5 */
6a488035
TO
6class CRM_Event_Cart_Form_Checkout_ParticipantsAndPrices extends CRM_Event_Cart_Form_Cart {
7 public $price_fields_for_event;
8 public $_values = NULL;
9
1e3401f3 10 /**
11 * Pre process function.
12 */
00be9182 13 public function preProcess() {
6a488035
TO
14 parent::preProcess();
15
16 $this->cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
17 if (!isset($this->cid) || $this->cid > 0) {
18 //TODO users with permission can default to another contact
19 $this->cid = self::getContactID();
20 }
21 }
22
1e3401f3 23 /**
24 * Build quick form.
25 */
00be9182 26 public function buildQuickForm() {
be2fb01f 27 $this->price_fields_for_event = [];
6a488035
TO
28 foreach ($this->cart->get_main_event_participants() as $participant) {
29 $form = new CRM_Event_Cart_Form_MerParticipant($participant);
30 $form->appendQuickForm($this);
31 }
32 foreach ($this->cart->get_main_events_in_carts() as $event_in_cart) {
33 $this->price_fields_for_event[$event_in_cart->event_id] = $this->build_price_options($event_in_cart->event);
34 }
254f0bcd 35 //If events in cart have discounts the textbox for discount code will be displayed at the top, as long as this
36 //form name is added to cividiscount
6a488035
TO
37 $this->assign('events_in_carts', $this->cart->get_main_events_in_carts());
38 $this->assign('price_fields_for_event', $this->price_fields_for_event);
39 $this->addButtons(
be2fb01f
CW
40 [
41 [
6a488035 42 'type' => 'upload',
f212d37d 43 'name' => ts('Continue'),
6a488035
TO
44 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
45 'isDefault' => TRUE,
be2fb01f
CW
46 ],
47 ]
6a488035
TO
48 );
49
50 if ($this->cid) {
be2fb01f 51 $params = ['id' => $this->cid];
353ffa53 52 $contact = CRM_Contact_BAO_Contact::retrieve($params, $defaults);
be2fb01f 53 $contact_values = [];
6a488035
TO
54 CRM_Core_DAO::storeValues($contact, $contact_values);
55 $this->assign('contact', $contact_values);
56 }
57 }
58
0cf587a7 59 /**
1e3401f3 60 * Get the primary emil for the contact.
61 *
62 * @param CRM_Contact_BAO_Contact $contact
0cf587a7 63 *
1e3401f3 64 * @return string
0cf587a7 65 */
00be9182 66 public static function primary_email_from_contact($contact) {
6a488035
TO
67 foreach ($contact->email as $email) {
68 if ($email['is_primary']) {
69 return $email['email'];
70 }
71 }
72
73 return NULL;
74 }
75
0cf587a7 76 /**
b05572f8 77 * Build price options.
78 *
79 * @param CRM_Event_BAO_Event $event
0cf587a7
EM
80 *
81 * @return array
82 */
00be9182 83 public function build_price_options($event) {
be2fb01f 84 $price_fields_for_event = [];
6a488035 85 $base_field_name = "event_{$event->id}_amount";
9da8dc8c 86 $price_set_id = CRM_Price_BAO_PriceSet::getFor('civicrm_event', $event->id);
254f0bcd 87 //CRM-14492 display admin fields only if user is admin
b05572f8 88 $adminFieldVisible = FALSE;
89 if (CRM_Core_Permission::check('administer CiviCRM')) {
90 $adminFieldVisible = TRUE;
254f0bcd 91 }
6a488035 92 if ($price_set_id) {
9da8dc8c 93 $price_sets = CRM_Price_BAO_PriceSet::getSetDetail($price_set_id, TRUE, TRUE);
353ffa53
TO
94 $price_set = $price_sets[$price_set_id];
95 $index = -1;
6a488035
TO
96 foreach ($price_set['fields'] as $field) {
97 $index++;
254f0bcd 98 if (CRM_Utils_Array::value('visibility', $field) == 'public' ||
b05572f8 99 (CRM_Utils_Array::value('visibility', $field) == 'admin' && $adminFieldVisible == TRUE)) {
254f0bcd 100 $field_name = "event_{$event->id}_price_{$field['id']}";
1019b2fe
SL
101 if (!empty($field['options'])) {
102 CRM_Price_BAO_PriceField::addQuickFormElement($this, $field_name, $field['id'], FALSE);
103 $price_fields_for_event[] = $field_name;
104 }
254f0bcd 105 }
6a488035
TO
106 }
107 }
108 return $price_fields_for_event;
109 }
110
0cf587a7 111 /**
b05572f8 112 * Validate values.
113 *
0cf587a7
EM
114 * @return bool
115 */
00be9182 116 public function validate() {
6a488035
TO
117 parent::validate();
118 if ($this->_errors) {
119 return FALSE;
120 }
121 $this->cart->load_associations();
122 $fields = $this->_submitValues;
123
124 foreach ($this->cart->get_main_events_in_carts() as $event_in_cart) {
125 $price_set_id = CRM_Event_BAO_Event::usesPriceSet($event_in_cart->event_id);
126 if ($price_set_id) {
9da8dc8c 127 $priceField = new CRM_Price_DAO_PriceField();
6a488035
TO
128 $priceField->price_set_id = $price_set_id;
129 $priceField->find();
130
be2fb01f 131 $check = [];
6a488035
TO
132
133 while ($priceField->fetch()) {
134 if (!empty($fields["event_{$event_in_cart->event_id}_price_{$priceField->id}"])) {
135 $check[] = $priceField->id;
136 }
137 }
138
139 //XXX
140 if (empty($check)) {
141 $this->_errors['_qf_default'] = ts("Select at least one option from Price Levels.");
142 }
143
be2fb01f 144 $lineItem = [];
6a488035 145 if (is_array($this->_values['fee']['fields'])) {
9da8dc8c 146 CRM_Price_BAO_PriceSet::processAmount($this->_values['fee']['fields'], $fields, $lineItem);
6a488035
TO
147 //XXX total...
148 if ($fields['amount'] < 0) {
149 $this->_errors['_qf_default'] = ts("Price Levels can not be less than zero. Please select the options accordingly");
150 }
151 }
152 }
153
12171c0e
ML
154 // Validate if participant is already registered
155 if ($event_in_cart->event->allow_same_participant_emails) {
156 continue;
157 }
158
6a488035
TO
159 foreach ($event_in_cart->participants as $mer_participant) {
160 $participant_fields = $fields['event'][$event_in_cart->event_id]['participant'][$mer_participant->id];
161 //TODO what to do when profile responses differ for the same contact?
162 $contact_id = self::find_contact($participant_fields);
163
164 if ($contact_id) {
165 $participant = new CRM_Event_BAO_Participant();
166 $participant->event_id = $event_in_cart->event_id;
167 $participant->contact_id = $contact_id;
168 $statusTypes = CRM_Event_PseudoConstant::participantStatus(NULL, 'is_counted = 1');
169 $participant->find();
170 while ($participant->fetch()) {
171 if (array_key_exists($participant->status_id, $statusTypes)) {
172 $form = $mer_participant->get_form();
be2fb01f 173 $this->_errors[$form->html_field_name('email')] = ts("The participant %1 is already registered for %2 (%3).", [
90b461f1
SL
174 1 => $participant_fields['email'],
175 2 => $event_in_cart->event->title,
176 3 => $event_in_cart->event->start_date,
177 ]);
6a488035
TO
178 }
179 }
180 }
181 }
182 }
183 return empty($this->_errors);
184 }
185
0cf587a7 186 /**
b05572f8 187 * Set default values.
188 *
0cf587a7
EM
189 * @return array
190 */
6a488035
TO
191 public function setDefaultValues() {
192 $this->loadCart();
193
be2fb01f 194 $defaults = [];
6a488035
TO
195 foreach ($this->cart->get_main_event_participants() as $participant) {
196 $form = $participant->get_form();
197 if (empty($participant->email)
6a488035
TO
198 && ($participant->get_participant_index() == 1)
199 && ($this->cid != 0)
200 ) {
be2fb01f
CW
201 $defaults = [];
202 $params = ['id' => $this->cid];
6a488035
TO
203 $contact = CRM_Contact_BAO_Contact::retrieve($params, $defaults);
204 $participant->contact_id = $this->cid;
205 $participant->save();
206 $participant->email = self::primary_email_from_contact($contact);
207 }
208 elseif ($this->cid == 0
209 && $participant->contact_id == self::getContactID()
210 ) {
211 $participant->email = NULL;
bec0826a 212 $participant->contact_id = self::find_or_create_contact();
6a488035
TO
213 }
214 $defaults += $form->setDefaultValues();
254f0bcd 215 //Set price defaults if any
216 foreach ($this->cart->get_main_events_in_carts() as $event_in_cart) {
02052b9b 217 $event_id = $event_in_cart->event_id;
254f0bcd 218 $price_set_id = CRM_Event_BAO_Event::usesPriceSet($event_in_cart->event_id);
219 if ($price_set_id) {
b05572f8 220 $price_sets = CRM_Price_BAO_PriceSet::getSetDetail($price_set_id, TRUE, TRUE);
221 $price_set = $price_sets[$price_set_id];
222 foreach ($price_set['fields'] as $field) {
9c1bc317 223 $options = $field['options'] ?? NULL;
254f0bcd 224 if (!is_array($options)) {
b05572f8 225 continue;
254f0bcd 226 }
227 $field_name = "event_{$event_id}_price_{$field['id']}";
b05572f8 228 foreach ($options as $value) {
229 if ($value['is_default']) {
230 if ($field['html_type'] == 'Checkbox') {
254f0bcd 231 $defaults[$field_name] = 1;
b05572f8 232 }
233 else {
254f0bcd 234 $defaults[$field_name] = $value['id'];
235 }
236 }
237 }
238 }
239 }
240 }
1e3401f3 241 }
6a488035
TO
242 return $defaults;
243 }
244
b05572f8 245 /**
246 * Post process function.
247 */
00be9182 248 public function postProcess() {
6a488035
TO
249 if (!array_key_exists('event', $this->_submitValues)) {
250 return;
251 }
252 // XXX de facto primary key
be2fb01f 253 $email_to_contact_id = [];
6a488035
TO
254 foreach ($this->_submitValues['event'] as $event_id => $participants) {
255 foreach ($participants['participant'] as $participant_id => $fields) {
256 if (array_key_exists($fields['email'], $email_to_contact_id)) {
257 $contact_id = $email_to_contact_id[$fields['email']];
258 }
259 else {
bec0826a 260 $contact_id = self::find_or_create_contact($fields);
6a488035
TO
261 $email_to_contact_id[$fields['email']] = $contact_id;
262 }
263
264 $participant = $this->cart->get_event_in_cart_by_event_id($event_id)->get_participant_by_id($participant_id);
265 if ($participant->contact_id && $contact_id != $participant->contact_id) {
be2fb01f
CW
266 $defaults = [];
267 $params = ['id' => $participant->contact_id];
6a488035
TO
268 $temporary_contact = CRM_Contact_BAO_Contact::retrieve($params, $defaults);
269
270 foreach ($this->cart->get_subparticipants($participant) as $subparticipant) {
271 $subparticipant->contact_id = $contact_id;
272 $subparticipant->save();
273 }
274
275 $participant->contact_id = $contact_id;
276 $participant->save();
277
278 if ($temporary_contact->is_deleted) {
b05572f8 279 // ARGH a permissions check prevents us from using skipUndelete,
280 // so we potentially leave records pointing to this contact for now
281 // CRM_Contact_BAO_Contact::deleteContact($temporary_contact->id);
6a488035
TO
282 $temporary_contact->delete();
283 }
284 }
285
286 //TODO security check that participant ids are already in this cart
be2fb01f 287 $participant_params = [
6a488035
TO
288 'id' => $participant_id,
289 'cart_id' => $this->cart->id,
290 'event_id' => $event_id,
291 'contact_id' => $contact_id,
292 //'registered_by_id' => $this->cart->user_id,
293 'email' => $fields['email'],
be2fb01f 294 ];
6a488035
TO
295 $participant = new CRM_Event_Cart_BAO_MerParticipant($participant_params);
296 $participant->save();
297 $this->cart->add_participant_to_cart($participant);
298
299 if (array_key_exists('field', $this->_submitValues) && array_key_exists($participant_id, $this->_submitValues['field'])) {
300 $custom_fields = array_merge($participant->get_form()->get_participant_custom_data_fields());
301
302 CRM_Contact_BAO_Contact::createProfileContact($this->_submitValues['field'][$participant_id], $custom_fields, $contact_id);
adf6c004
ML
303
304 CRM_Core_BAO_CustomValueTable::postProcess($this->_submitValues['field'][$participant_id],
305 'civicrm_participant',
306 $participant_id,
307 'Participant'
308 );
6a488035
TO
309 }
310 }
311 }
312 $this->cart->save();
313 }
96025800 314
6a488035 315}