Merge pull request #10805 from JKingsnorth/CRM-21009
[civicrm-core.git] / CRM / Event / Form / EventFees.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2017 |
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-2017
33 * $Id$
34 *
35 */
36
37 /**
38 * This class generates form components for processing a participation fee block
39 */
40 class CRM_Event_Form_EventFees {
41
42 /**
43 * Set variables up before form is built.
44 *
45 * @param CRM_Core_Form $form
46 */
47 public static function preProcess(&$form) {
48 //as when call come from register.php
49 if (!$form->_eventId) {
50 $form->_eventId = CRM_Utils_Request::retrieve('eventId', 'Positive', $form);
51 }
52
53 $form->_pId = CRM_Utils_Request::retrieve('participantId', 'Positive', $form);
54 $form->_discountId = CRM_Utils_Request::retrieve('discountId', 'Positive', $form);
55
56 $form->_fromEmails = CRM_Event_BAO_Event::getFromEmailIds($form->_eventId);
57
58 //CRM-6907 set event specific currency.
59 if ($form->_eventId &&
60 ($currency = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $form->_eventId, 'currency'))
61 ) {
62 CRM_Core_Config::singleton()->defaultCurrency = $currency;
63 }
64 }
65
66 /**
67 * This function sets the default values for the form in edit/view mode.
68 *
69 * @param CRM_Core_Form $form
70 *
71 * @return array
72 */
73 public static function setDefaultValues(&$form) {
74 $defaults = array();
75
76 if ($form->_eventId) {
77 //get receipt text and financial type
78 $returnProperities = array('confirm_email_text', 'financial_type_id', 'campaign_id', 'start_date');
79 $details = array();
80 CRM_Core_DAO::commonRetrieveAll('CRM_Event_DAO_Event', 'id', $form->_eventId, $details, $returnProperities);
81 if (!empty($details[$form->_eventId]['financial_type_id'])) {
82 $defaults[$form->_pId]['financial_type_id'] = $details[$form->_eventId]['financial_type_id'];
83 }
84 }
85
86 if ($form->_pId) {
87 $ids = array();
88 $params = array('id' => $form->_pId);
89
90 CRM_Event_BAO_Participant::getValues($params, $defaults, $ids);
91 if ($form->_action == CRM_Core_Action::UPDATE) {
92 $discounts = array();
93 if (!empty($form->_values['discount'])) {
94 foreach ($form->_values['discount'] as $key => $value) {
95 $value = current($value);
96 $discounts[$key] = $value['name'];
97 }
98 }
99
100 if ($form->_discountId && !empty($discounts[$defaults[$form->_pId]['discount_id']])) {
101 $form->assign('discount', $discounts[$defaults[$form->_pId]['discount_id']]);
102 }
103
104 $form->assign('fee_amount', CRM_Utils_Array::value('fee_amount', $defaults[$form->_pId]));
105 $form->assign('fee_level', CRM_Utils_Array::value('fee_level', $defaults[$form->_pId]));
106 }
107 $defaults[$form->_pId]['send_receipt'] = 0;
108 }
109 else {
110 $defaults[$form->_pId]['send_receipt'] = (strtotime(CRM_Utils_Array::value('start_date', $details[$form->_eventId])) >= time()) ? 1 : 0;
111 if ($form->_eventId && !empty($details[$form->_eventId]['confirm_email_text'])) {
112 //set receipt text
113 $defaults[$form->_pId]['receipt_text'] = $details[$form->_eventId]['confirm_email_text'];
114 }
115
116 list($defaults[$form->_pId]['receive_date'], $defaults[$form->_pId]['receive_date_time']) = CRM_Utils_Date::setDateDefaults();
117 }
118
119 //CRM-11601 we should keep the record contribution
120 //true by default while adding participant
121 if ($form->_action == CRM_Core_Action::ADD && !$form->_mode && $form->_isPaidEvent) {
122 $defaults[$form->_pId]['record_contribution'] = 1;
123 }
124
125 //CRM-13420
126 if (empty($defaults['payment_instrument_id'])) {
127 $defaults[$form->_pId]['payment_instrument_id'] = key(CRM_Core_OptionGroup::values('payment_instrument', FALSE, FALSE, FALSE, 'AND is_default = 1'));
128 }
129 if ($form->_mode) {
130 $config = CRM_Core_Config::singleton();
131 // set default country from config if no country set
132 if (empty($defaults[$form->_pId]["billing_country_id-{$form->_bltID}"])) {
133 $defaults[$form->_pId]["billing_country_id-{$form->_bltID}"] = $config->defaultContactCountry;
134 }
135
136 if (empty($defaults["billing_state_province_id-{$form->_bltID}"])) {
137 $defaults[$form->_pId]["billing_state_province_id-{$form->_bltID}"] = $config->defaultContactStateProvince;
138 }
139
140 $billingDefaults = $form->getProfileDefaults('Billing', $form->_contactId);
141 $defaults[$form->_pId] = array_merge($defaults[$form->_pId], $billingDefaults);
142
143 // // hack to simplify credit card entry for testing
144 // $defaults[$form->_pId]['credit_card_type'] = 'Visa';
145 // $defaults[$form->_pId]['credit_card_number'] = '4807731747657838';
146 // $defaults[$form->_pId]['cvv2'] = '000';
147 // $defaults[$form->_pId]['credit_card_exp_date'] = array( 'Y' => '2012', 'M' => '05' );
148 }
149
150 // if user has selected discount use that to set default
151 if (isset($form->_discountId)) {
152 $defaults[$form->_pId]['discount_id'] = $form->_discountId;
153
154 //hack to set defaults for already selected discount value
155 if ($form->_action == CRM_Core_Action::UPDATE && !$form->_originalDiscountId) {
156 $form->_originalDiscountId = $defaults[$form->_pId]['discount_id'];
157 if ($form->_originalDiscountId) {
158 $defaults[$form->_pId]['discount_id'] = $form->_originalDiscountId;
159 }
160 }
161 $discountId = $form->_discountId;
162 }
163 else {
164 $discountId = CRM_Core_BAO_Discount::findSet($form->_eventId, 'civicrm_event');
165 }
166
167 if ($discountId) {
168 $priceSetId = CRM_Core_DAO::getFieldValue('CRM_Core_BAO_Discount', $discountId, 'price_set_id');
169 }
170 else {
171 $priceSetId = CRM_Price_BAO_PriceSet::getFor('civicrm_event', $form->_eventId);
172 }
173
174 if (($form->_action == CRM_Core_Action::ADD) && $form->_eventId && $discountId) {
175 // this case is for add mode, where we show discount automatically
176 $defaults[$form->_pId]['discount_id'] = $discountId;
177 }
178
179 if ($priceSetId) {
180 // get price set default values, CRM-4090
181 if (in_array(get_class($form),
182 array(
183 'CRM_Event_Form_Participant',
184 'CRM_Event_Form_Registration_Register',
185 'CRM_Event_Form_Registration_AdditionalParticipant',
186 )
187 )) {
188 $priceSetValues = self::setDefaultPriceSet($form->_pId, $form->_eventId);
189 if (!empty($priceSetValues)) {
190 $defaults[$form->_pId] = array_merge($defaults[$form->_pId], $priceSetValues);
191 }
192 }
193
194 if ($form->_action == CRM_Core_Action::ADD && !empty($form->_priceSet['fields'])) {
195 foreach ($form->_priceSet['fields'] as $key => $val) {
196 foreach ($val['options'] as $keys => $values) {
197 if ($values['is_default']) {
198 if (get_class($form) != 'CRM_Event_Form_Participant' && !empty($values['is_full'])) {
199 continue;
200 }
201
202 if ($val['html_type'] == 'CheckBox') {
203 $defaults[$form->_pId]["price_{$key}"][$keys] = 1;
204 }
205 else {
206 $defaults[$form->_pId]["price_{$key}"] = $keys;
207 }
208 }
209 }
210 }
211 }
212
213 $form->assign('totalAmount', CRM_Utils_Array::value('fee_amount', $defaults[$form->_pId]));
214 if ($form->_action == CRM_Core_Action::UPDATE) {
215 $fee_level = $defaults[$form->_pId]['fee_level'];
216 CRM_Event_BAO_Participant::fixEventLevel($fee_level);
217 $form->assign('fee_level', $fee_level);
218 $form->assign('fee_amount', CRM_Utils_Array::value('fee_amount', $defaults[$form->_pId]));
219 }
220 }
221
222 //CRM-4453
223 if (!empty($defaults[$form->_pId]['participant_fee_currency'])) {
224 $form->assign('fee_currency', $defaults[$form->_pId]['participant_fee_currency']);
225 }
226
227 // CRM-4395
228 if ($contriId = $form->get('onlinePendingContributionId')) {
229 $defaults[$form->_pId]['record_contribution'] = 1;
230 $contribution = new CRM_Contribute_DAO_Contribution();
231 $contribution->id = $contriId;
232 $contribution->find(TRUE);
233 foreach (array(
234 'financial_type_id',
235 'payment_instrument_id',
236 'contribution_status_id',
237 'receive_date',
238 'total_amount',
239 ) as $f) {
240 if ($f == 'receive_date') {
241 list($defaults[$form->_pId]['receive_date']) = CRM_Utils_Date::setDateDefaults($contribution->$f);
242 }
243 else {
244 $defaults[$form->_pId][$f] = $contribution->$f;
245 }
246 }
247 }
248 return $defaults[$form->_pId];
249 }
250
251 /**
252 * This function sets the default values for price set.
253 *
254 * @param int $participantID
255 * @param int $eventID
256 * @param bool $includeQtyZero
257 *
258 * @return array
259 */
260 public static function setDefaultPriceSet($participantID, $eventID = NULL, $includeQtyZero = TRUE) {
261 $defaults = array();
262 if (!$eventID && $participantID) {
263 $eventID = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $participantID, 'event_id');
264 }
265 if (!$participantID || !$eventID) {
266 return $defaults;
267 }
268
269 // get price set ID.
270 $priceSetID = CRM_Price_BAO_PriceSet::getFor('civicrm_event', $eventID);
271 if (!$priceSetID) {
272 return $defaults;
273 }
274
275 // use line items for setdefault price set fields, CRM-4090
276 $lineItems[$participantID] = CRM_Price_BAO_LineItem::getLineItems($participantID, 'participant', FALSE, $includeQtyZero);
277
278 if (is_array($lineItems[$participantID]) &&
279 !CRM_Utils_System::isNull($lineItems[$participantID])
280 ) {
281
282 $priceFields = $htmlTypes = $optionValues = array();
283 foreach ($lineItems[$participantID] as $lineId => $items) {
284 $priceFieldId = CRM_Utils_Array::value('price_field_id', $items);
285 $priceOptionId = CRM_Utils_Array::value('price_field_value_id', $items);
286 if ($priceFieldId && $priceOptionId) {
287 $priceFields[$priceFieldId][] = $priceOptionId;
288 }
289 }
290
291 if (empty($priceFields)) {
292 return $defaults;
293 }
294
295 // get all price set field html types.
296 $sql = '
297 SELECT id, html_type
298 FROM civicrm_price_field
299 WHERE id IN (' . implode(',', array_keys($priceFields)) . ')';
300 $fieldDAO = CRM_Core_DAO::executeQuery($sql);
301 while ($fieldDAO->fetch()) {
302 $htmlTypes[$fieldDAO->id] = $fieldDAO->html_type;
303 }
304
305 foreach ($lineItems[$participantID] as $lineId => $items) {
306 $fieldId = $items['price_field_id'];
307 $htmlType = CRM_Utils_Array::value($fieldId, $htmlTypes);
308 if (!$htmlType) {
309 continue;
310 }
311
312 if ($htmlType == 'Text') {
313 $defaults["price_{$fieldId}"] = $items['qty'];
314 }
315 else {
316 $fieldOptValues = CRM_Utils_Array::value($fieldId, $priceFields);
317 if (!is_array($fieldOptValues)) {
318 continue;
319 }
320
321 foreach ($fieldOptValues as $optionId) {
322 if ($htmlType == 'CheckBox') {
323 $defaults["price_{$fieldId}"][$optionId] = TRUE;
324 }
325 else {
326 $defaults["price_{$fieldId}"] = $optionId;
327 break;
328 }
329 }
330 }
331 }
332 }
333
334 return $defaults;
335 }
336
337 /**
338 * Build the form object.
339 *
340 * @param CRM_Core_Form $form
341 */
342 public static function buildQuickForm(&$form) {
343 if ($form->_eventId) {
344 $form->_isPaidEvent = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Event', $form->_eventId, 'is_monetary');
345 if ($form->_isPaidEvent) {
346 $form->addElement('hidden', 'hidden_feeblock', 1);
347 }
348
349 // make sure this is for backoffice registration.
350 if ($form->getName() == 'Participant') {
351 $eventfullMsg = CRM_Event_BAO_Participant::eventFullMessage($form->_eventId, $form->_pId);
352 $form->addElement('hidden', 'hidden_eventFullMsg', $eventfullMsg, array('id' => 'hidden_eventFullMsg'));
353 }
354 }
355
356 if ($form->_pId) {
357 if (CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment',
358 $form->_pId, 'contribution_id', 'participant_id'
359 )
360 ) {
361 $form->_online = TRUE;
362 }
363 }
364
365 if ($form->_isPaidEvent) {
366 $params = array('id' => $form->_eventId);
367 CRM_Event_BAO_Event::retrieve($params, $event);
368
369 //retrieve custom information
370 $form->_values = array();
371 CRM_Event_Form_Registration::initEventFee($form, $event['id']);
372 CRM_Event_Form_Registration_Register::buildAmount($form, TRUE, $form->_discountId);
373 $lineItem = array();
374 $invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
375 $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
376 $totalTaxAmount = 0;
377 if (!CRM_Utils_System::isNull(CRM_Utils_Array::value('line_items', $form->_values))) {
378 $lineItem[] = $form->_values['line_items'];
379 foreach ($form->_values['line_items'] as $key => $value) {
380 $totalTaxAmount = $value['tax_amount'] + $totalTaxAmount;
381 }
382 }
383 if ($invoicing) {
384 $form->assign('totalTaxAmount', $totalTaxAmount);
385 }
386 $form->assign('lineItem', empty($lineItem) ? FALSE : $lineItem);
387 $discounts = array();
388 if (!empty($form->_values['discount'])) {
389 foreach ($form->_values['discount'] as $key => $value) {
390 $value = current($value);
391 $discounts[$key] = $value['name'];
392 }
393
394 $element = $form->add('select', 'discount_id',
395 ts('Discount Set'),
396 array(
397 0 => ts('- select -'),
398 ) + $discounts,
399 FALSE,
400 array('class' => "crm-select2")
401 );
402
403 if ($form->_online) {
404 $element->freeze();
405 }
406 }
407 if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()
408 && !CRM_Utils_Array::value('fee', $form->_values)
409 && CRM_Utils_Array::value('snippet', $_REQUEST) == CRM_Core_Smarty::PRINT_NOFORM
410 ) {
411 CRM_Core_Session::setStatus(ts('You do not have all the permissions needed for this page.'), 'Permission Denied', 'error');
412 return FALSE;
413 }
414
415 CRM_Core_Payment_Form::buildPaymentForm($form, $form->_paymentProcessor, FALSE, TRUE, self::getDefaultPaymentInstrumentId());
416 if (!$form->_mode) {
417 $form->addElement('checkbox', 'record_contribution', ts('Record Payment?'), NULL,
418 array('onclick' => "return showHideByValue('record_contribution','','payment_information','table-row','radio',false);")
419 );
420 // Check permissions for financial type first
421 if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus()) {
422 CRM_Financial_BAO_FinancialType::getAvailableFinancialTypes($financialTypes, $form->_action);
423 }
424 else {
425 $financialTypes = CRM_Contribute_PseudoConstant::financialType();
426 }
427
428 $form->add('select', 'financial_type_id',
429 ts('Financial Type'),
430 array('' => ts('- select -')) + $financialTypes
431 );
432
433 $form->addDateTime('receive_date', ts('Received'), FALSE, array('formatType' => 'activityDateTime'));
434
435 $form->add('select', 'payment_instrument_id',
436 ts('Payment Method'),
437 array('' => ts('- select -')) + CRM_Contribute_PseudoConstant::paymentInstrument(),
438 FALSE, array('onChange' => "return showHideByValue('payment_instrument_id','4','checkNumber','table-row','select',false);")
439 );
440 // don't show transaction id in batch update mode
441 $path = CRM_Utils_System::currentPath();
442 $form->assign('showTransactionId', FALSE);
443 if ($path != 'civicrm/contact/search/basic') {
444 $form->add('text', 'trxn_id', ts('Transaction ID'));
445 $form->addRule('trxn_id', ts('Transaction ID already exists in Database.'),
446 'objectExists', array('CRM_Contribute_DAO_Contribution', $form->_eventId, 'trxn_id')
447 );
448 $form->assign('showTransactionId', TRUE);
449 }
450
451 $form->add('select', 'contribution_status_id',
452 ts('Payment Status'), CRM_Contribute_BAO_Contribution_Utils::getContributionStatuses('participant')
453 );
454
455 $form->add('text', 'check_number', ts('Check Number'),
456 CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Contribution', 'check_number')
457 );
458
459 $form->add('text', 'total_amount', ts('Amount'),
460 CRM_Core_DAO::getAttribute('CRM_Contribute_DAO_Contribution', 'total_amount')
461 );
462 }
463 }
464 else {
465 $form->add('text', 'amount', ts('Event Fee(s)'));
466 }
467 $form->assign('onlinePendingContributionId', $form->get('onlinePendingContributionId'));
468
469 $form->assign('paid', $form->_isPaidEvent);
470
471 $form->addElement('checkbox',
472 'send_receipt',
473 ts('Send Confirmation?'), NULL,
474 array('onclick' => "showHideByValue('send_receipt','','notice','table-row','radio',false); showHideByValue('send_receipt','','from-email','table-row','radio',false);")
475 );
476
477 $form->add('select', 'from_email_address', ts('Receipt From'), $form->_fromEmails['from_email_id']);
478
479 $form->add('textarea', 'receipt_text', ts('Confirmation Message'));
480
481 // Retrieve the name and email of the contact - form will be the TO for receipt email ( only if context is not standalone)
482 if ($form->_context != 'standalone') {
483 if ($form->_contactId) {
484 list($form->_contributorDisplayName,
485 $form->_contributorEmail
486 ) = CRM_Contact_BAO_Contact_Location::getEmailDetails($form->_contactId);
487 $form->assign('email', $form->_contributorEmail);
488 }
489 else {
490 //show email block for batch update for event
491 $form->assign('batchEmail', TRUE);
492 }
493 }
494
495 $mailingInfo = Civi::settings()->get('mailing_backend');
496 $form->assign('outBound_option', $mailingInfo['outBound_option']);
497 $form->assign('hasPayment', $form->_paymentId);
498 }
499
500 /**
501 * Get the default payment instrument id.
502 *
503 * @todo resolve relationship between this form & abstractEdit -which should be it's parent.
504 *
505 * @return int
506 */
507 protected static function getDefaultPaymentInstrumentId() {
508 $paymentInstrumentID = CRM_Utils_Request::retrieve('payment_instrument_id', 'Integer');
509 if ($paymentInstrumentID) {
510 return $paymentInstrumentID;
511 }
512 return key(CRM_Core_OptionGroup::values('payment_instrument', FALSE, FALSE, FALSE, 'AND is_default = 1'));
513 }
514
515 }