INFRA-132 - Batch 0
[civicrm-core.git] / CRM / Event / Cart / Form / Checkout / ParticipantsAndPrices.php
1 <?php
2
3 /**
4 * Class CRM_Event_Cart_Form_Checkout_ParticipantsAndPrices
5 */
6 class CRM_Event_Cart_Form_Checkout_ParticipantsAndPrices extends CRM_Event_Cart_Form_Cart {
7 public $price_fields_for_event;
8 public $_values = NULL;
9
10 public function preProcess() {
11 parent::preProcess();
12
13 $this->cid = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
14 if (!isset($this->cid) || $this->cid > 0) {
15 //TODO users with permission can default to another contact
16 $this->cid = self::getContactID();
17 }
18 }
19
20 public function buildQuickForm() {
21 $this->price_fields_for_event = array();
22 foreach ($this->cart->get_main_event_participants() as $participant) {
23 $form = new CRM_Event_Cart_Form_MerParticipant($participant);
24 $form->appendQuickForm($this);
25 }
26 foreach ($this->cart->get_main_events_in_carts() as $event_in_cart) {
27 $this->price_fields_for_event[$event_in_cart->event_id] = $this->build_price_options($event_in_cart->event);
28 }
29 // XXX
30 $this->addElement('text', 'discountcode', ts('If you have a discount code, enter it here'));
31 $this->assign('events_in_carts', $this->cart->get_main_events_in_carts());
32 $this->assign('price_fields_for_event', $this->price_fields_for_event);
33 $this->addButtons(
34 array(
35 array(
36 'type' => 'upload',
37 'name' => ts('Continue'),
38 'spacing' => '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',
39 'isDefault' => TRUE,
40 ),
41 )
42 );
43
44 if ($this->cid) {
45 $params = array('id' => $this->cid);
46 $contact = CRM_Contact_BAO_Contact::retrieve($params, $defaults);
47 $contact_values = array();
48 CRM_Core_DAO::storeValues($contact, $contact_values);
49 $this->assign('contact', $contact_values);
50 }
51 }
52
53 /**
54 * @param $contact
55 *
56 * @return null
57 */
58 public static function primary_email_from_contact($contact) {
59 foreach ($contact->email as $email) {
60 if ($email['is_primary']) {
61 return $email['email'];
62 }
63 }
64
65 return NULL;
66 }
67
68 /**
69 * @param $event
70 *
71 * @return array
72 */
73 public function build_price_options($event) {
74 $price_fields_for_event = array();
75 $base_field_name = "event_{$event->id}_amount";
76 $price_set_id = CRM_Price_BAO_PriceSet::getFor('civicrm_event', $event->id);
77 if ($price_set_id) {
78 $price_sets = CRM_Price_BAO_PriceSet::getSetDetail($price_set_id, TRUE, TRUE);
79 $price_set = $price_sets[$price_set_id];
80 $index = -1;
81 foreach ($price_set['fields'] as $field) {
82 $index++;
83 $field_name = "event_{$event->id}_price_{$field['id']}";
84 CRM_Price_BAO_PriceField::addQuickFormElement($this, $field_name, $field['id'], FALSE);
85 $price_fields_for_event[] = $field_name;
86 }
87 }
88 return $price_fields_for_event;
89 }
90
91 /**
92 * @return bool
93 */
94 public function validate() {
95 parent::validate();
96 if ($this->_errors) {
97 return FALSE;
98 }
99 $this->cart->load_associations();
100 $fields = $this->_submitValues;
101
102 foreach ($this->cart->get_main_events_in_carts() as $event_in_cart) {
103 $price_set_id = CRM_Event_BAO_Event::usesPriceSet($event_in_cart->event_id);
104 if ($price_set_id) {
105 $priceField = new CRM_Price_DAO_PriceField();
106 $priceField->price_set_id = $price_set_id;
107 $priceField->find();
108
109 $check = array();
110
111 while ($priceField->fetch()) {
112 if (!empty($fields["event_{$event_in_cart->event_id}_price_{$priceField->id}"])) {
113 $check[] = $priceField->id;
114 }
115 }
116
117 //XXX
118 if (empty($check)) {
119 $this->_errors['_qf_default'] = ts("Select at least one option from Price Levels.");
120 }
121
122 $lineItem = array();
123 if (is_array($this->_values['fee']['fields'])) {
124 CRM_Price_BAO_PriceSet::processAmount($this->_values['fee']['fields'], $fields, $lineItem);
125 //XXX total...
126 if ($fields['amount'] < 0) {
127 $this->_errors['_qf_default'] = ts("Price Levels can not be less than zero. Please select the options accordingly");
128 }
129 }
130 }
131
132 foreach ($event_in_cart->participants as $mer_participant) {
133 $participant_fields = $fields['event'][$event_in_cart->event_id]['participant'][$mer_participant->id];
134 //TODO what to do when profile responses differ for the same contact?
135 $contact_id = self::find_contact($participant_fields);
136
137 if ($contact_id) {
138 $participant = new CRM_Event_BAO_Participant();
139 $participant->event_id = $event_in_cart->event_id;
140 $participant->contact_id = $contact_id;
141 $statusTypes = CRM_Event_PseudoConstant::participantStatus(NULL, 'is_counted = 1');
142 $participant->find();
143 while ($participant->fetch()) {
144 if (array_key_exists($participant->status_id, $statusTypes)) {
145 $form = $mer_participant->get_form();
146 $this->_errors[$form->html_field_name('email')] = ts("The participant %1 is already registered for %2 (%3).", array(
147 1 => $participant_fields['email'],
148 2 => $event_in_cart->event->title,
149 3 => $event_in_cart->event->start_date,
150 ));
151 }
152 }
153 }
154 }
155 }
156 return empty($this->_errors);
157 }
158
159 /**
160 * @return array
161 */
162 public function setDefaultValues() {
163 $this->loadCart();
164
165 $defaults = array();
166 foreach ($this->cart->get_main_event_participants() as $participant) {
167 $form = $participant->get_form();
168 if (empty($participant->email)
169 && !CRM_Event_Cart_Form_Cart::is_administrator()
170 && ($participant->get_participant_index() == 1)
171 && ($this->cid != 0)
172 ) {
173 $defaults = array();
174 $params = array('id' => $this->cid);
175 $contact = CRM_Contact_BAO_Contact::retrieve($params, $defaults);
176 $participant->contact_id = $this->cid;
177 $participant->save();
178 $participant->email = self::primary_email_from_contact($contact);
179 }
180 elseif ($this->cid == 0
181 && $participant->contact_id == self::getContactID()
182 ) {
183 $participant->email = NULL;
184 $participant->contact_id = self::find_or_create_contact($this->getContactID());
185 }
186 $defaults += $form->setDefaultValues();
187 }
188 return $defaults;
189 }
190
191 public function postProcess() {
192 if (!array_key_exists('event', $this->_submitValues)) {
193 return;
194 }
195 // XXX de facto primary key
196 $email_to_contact_id = array();
197 foreach ($this->_submitValues['event'] as $event_id => $participants) {
198 foreach ($participants['participant'] as $participant_id => $fields) {
199 if (array_key_exists($fields['email'], $email_to_contact_id)) {
200 $contact_id = $email_to_contact_id[$fields['email']];
201 }
202 else {
203 $contact_id = self::find_or_create_contact($this->getContactID(), $fields);
204 $email_to_contact_id[$fields['email']] = $contact_id;
205 }
206
207 $participant = $this->cart->get_event_in_cart_by_event_id($event_id)->get_participant_by_id($participant_id);
208 if ($participant->contact_id && $contact_id != $participant->contact_id) {
209 $defaults = array();
210 $params = array('id' => $participant->contact_id);
211 $temporary_contact = CRM_Contact_BAO_Contact::retrieve($params, $defaults);
212
213 foreach ($this->cart->get_subparticipants($participant) as $subparticipant) {
214 $subparticipant->contact_id = $contact_id;
215 $subparticipant->save();
216 }
217
218 $participant->contact_id = $contact_id;
219 $participant->save();
220
221 if ($temporary_contact->is_deleted) {
222 #ARGH a permissions check prevents us from using skipUndelete,
223 #so we potentially leave records pointing to this contact for now
224 #CRM_Contact_BAO_Contact::deleteContact($temporary_contact->id);
225 $temporary_contact->delete();
226 }
227 }
228
229 //TODO security check that participant ids are already in this cart
230 $participant_params = array(
231 'id' => $participant_id,
232 'cart_id' => $this->cart->id,
233 'event_id' => $event_id,
234 'contact_id' => $contact_id,
235 //'registered_by_id' => $this->cart->user_id,
236 'email' => $fields['email'],
237 );
238 $participant = new CRM_Event_Cart_BAO_MerParticipant($participant_params);
239 $participant->save();
240 $this->cart->add_participant_to_cart($participant);
241
242 if (array_key_exists('field', $this->_submitValues) && array_key_exists($participant_id, $this->_submitValues['field'])) {
243 $custom_fields = array_merge($participant->get_form()->get_participant_custom_data_fields());
244
245 CRM_Contact_BAO_Contact::createProfileContact($this->_submitValues['field'][$participant_id], $custom_fields, $contact_id);
246 }
247 }
248 }
249 $this->cart->save();
250 }
251 }