INFRA-132 - Put "else" and "catch" on new line
[civicrm-core.git] / CRM / Price / BAO / PriceField.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
39de6fd5 4 | CiviCRM version 4.6 |
6a488035 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
6a488035
TO
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 * @package CRM
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
32 * $Id$
33 *
34 */
35
36/**
37 * Business objects for managing price fields.
38 *
39 */
9da8dc8c 40class CRM_Price_BAO_PriceField extends CRM_Price_DAO_PriceField {
6a488035
TO
41
42 protected $_options;
43
44 /**
100fef9d 45 * Takes an associative array and creates a price field object
6a488035
TO
46 *
47 * the function extract all the params it needs to initialize the create a
48 * price field object. the params array could contain additional unused name/value
49 * pairs
50 *
414c1420
TO
51 * @param array $params
52 * (reference) an assoc array of name/value pairs.
6a488035 53 *
c490a46a 54 * @return CRM_Price_BAO_PriceField object
6a488035
TO
55 * @static
56 */
00be9182 57 public static function add(&$params) {
9da8dc8c 58 $priceFieldBAO = new CRM_Price_BAO_PriceField();
6a488035
TO
59
60 $priceFieldBAO->copyValues($params);
61
62 if ($id = CRM_Utils_Array::value('id', $params)) {
63 $priceFieldBAO->id = $id;
64 }
65
66 $priceFieldBAO->save();
67 return $priceFieldBAO;
68 }
69
70 /**
100fef9d 71 * Takes an associative array and creates a price field object
6a488035
TO
72 *
73 * This function is invoked from within the web form layer and also from the api layer
74 *
414c1420
TO
75 * @param array $params
76 * (reference) an assoc array of name/value pairs.
6a488035 77 *
c490a46a 78 * @return CRM_Price_DAO_PriceField object
6a488035
TO
79 * @static
80 */
00be9182 81 public static function create(&$params) {
291ebece 82 if(empty($params['id']) && empty($params['name'])) {
b10b974d 83 $params['name'] = strtolower(CRM_Utils_String::munge($params['label'], '_', 242));
291ebece 84 }
6a488035
TO
85 $transaction = new CRM_Core_Transaction();
86
87 $priceField = self::add($params);
88
89 if (is_a($priceField, 'CRM_Core_Error')) {
90 $transaction->rollback();
91 return $priceField;
92 }
93
e0c1764e 94 $optionsIds = array();
6a488035
TO
95 $maxIndex = CRM_Price_Form_Field::NUM_OPTION;
96
97 if ($priceField->html_type == 'Text') {
98 $maxIndex = 1;
99
9da8dc8c 100 $fieldValue = new CRM_Price_DAO_PriceFieldValue();
6a488035
TO
101 $fieldValue->price_field_id = $priceField->id;
102
103 // update previous field values( if any )
104 if ($fieldValue->find(TRUE)) {
105 $optionsIds['id'] = $fieldValue->id;
106 }
107 }
108 $defaultArray = array();
a4537ddd
EM
109 //html type would be empty in update scenario not sure what would happen ...
110 if (!empty($params['html_type']) && $params['html_type'] == 'CheckBox' && isset($params['default_checkbox_option'])) {
6a488035
TO
111 $tempArray = array_keys($params['default_checkbox_option']);
112 foreach ($tempArray as $v) {
113 if ($params['option_amount'][$v]) {
114 $defaultArray[$v] = 1;
115 }
116 }
117 }
118 else {
a7488080 119 if (!empty($params['default_option'])) {
6a488035
TO
120 $defaultArray[$params['default_option']] = 1;
121 }
122 }
123
124 for ($index = 1; $index <= $maxIndex; $index++) {
125 if (array_key_exists('option_amount', $params) &&
126 array_key_exists($index, $params['option_amount']) &&
8cc574cf 127 (CRM_Utils_Array::value($index, CRM_Utils_Array::value('option_label', $params)) || !empty($params['is_quick_config'])) &&
6a488035
TO
128 !CRM_Utils_System::isNull($params['option_amount'][$index])
129 ) {
130 $options = array(
131 'price_field_id' => $priceField->id,
132 'label' => trim($params['option_label'][$index]),
133 'name' => CRM_Utils_String::munge($params['option_label'][$index], '_', 64),
134 'amount' => CRM_Utils_Rule::cleanMoney(trim($params['option_amount'][$index])),
135 'count' => CRM_Utils_Array::value($index, CRM_Utils_Array::value('option_count', $params), NULL),
136 'max_value' => CRM_Utils_Array::value($index, CRM_Utils_Array::value('option_max_value', $params), NULL),
137 'description' => CRM_Utils_Array::value($index, CRM_Utils_Array::value('option_description', $params), NULL),
138 'membership_type_id' => CRM_Utils_Array::value($index, CRM_Utils_Array::value('membership_type_id', $params), NULL),
139 'weight' => $params['option_weight'][$index],
140 'is_active' => 1,
141 'is_default' => CRM_Utils_Array::value($params['option_weight'][$index], $defaultArray) ? $defaultArray[$params['option_weight'][$index]] : 0,
142 'membership_num_terms' => NULL,
143 );
144
145 if ($options['membership_type_id']) {
146 $options['membership_num_terms'] = CRM_Utils_Array::value($index, CRM_Utils_Array::value('membership_num_terms', $params), 1);
147 }
148
149 if (CRM_Utils_Array::value( $index, CRM_Utils_Array::value('option_financial_type_id', $params))) {
150 $options['financial_type_id'] = $params['option_financial_type_id'][$index];
0db6c3e1
TO
151 }
152 elseif (!empty($params['financial_type_id'])) {
6a488035
TO
153 $options['financial_type_id'] = $params['financial_type_id'];
154 }
155
156 if ($opIds = CRM_Utils_Array::value('option_id', $params)) {
157 if ($opId = CRM_Utils_Array::value($index, $opIds)) {
158 $optionsIds['id'] = $opId;
0db6c3e1
TO
159 }
160 else {
6a488035
TO
161 $optionsIds['id'] = NULL;
162 }
163 }
9da8dc8c 164 CRM_Price_BAO_PriceFieldValue::create($options, $optionsIds);
6a488035
TO
165 }
166 }
167
168 $transaction->commit();
169 return $priceField;
170 }
171
172 /**
c490a46a 173 * Fetch object based on array of properties
6a488035 174 *
414c1420
TO
175 * @param array $params
176 * (reference ) an assoc array of name/value pairs.
177 * @param array $defaults
178 * (reference ) an assoc array to hold the flattened values.
6a488035 179 *
c490a46a 180 * @return CRM_Price_DAO_PriceField object
6a488035
TO
181 * @static
182 */
00be9182 183 public static function retrieve(&$params, &$defaults) {
9da8dc8c 184 return CRM_Core_DAO::commonRetrieve('CRM_Price_DAO_PriceField', $params, $defaults);
6a488035
TO
185 }
186
187 /**
100fef9d 188 * Update the is_active flag in the db
6a488035 189 *
414c1420
TO
190 * @param int $id
191 * Id of the database record.
192 * @param bool $is_active
193 * Value we want to set the is_active field.
6a488035
TO
194 *
195 * @return Object DAO object on sucess, null otherwise
196 *
6a488035
TO
197 * @static
198 */
00be9182 199 public static function setIsActive($id, $is_active) {
9da8dc8c 200 return CRM_Core_DAO::setFieldValue('CRM_Price_DAO_PriceField', $id, 'is_active', $is_active);
6a488035
TO
201 }
202
00be9182 203 public static function freezeIfEnabled(&$element, $fieldOptions) {
79b152ac 204 if (!empty($fieldOptions['is_full'])) {
205 $element->freeze();
206 }
207 return;
208 }
209
6a488035
TO
210 /**
211 * Get the field title.
212 *
414c1420
TO
213 * @param int $id
214 * Id of field.
6a488035
TO
215 *
216 * @return string name
217 *
6a488035
TO
218 * @static
219 *
220 */
221 public static function getTitle($id) {
9da8dc8c 222 return CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $id, 'label');
6a488035
TO
223 }
224
225 /**
226 * This function for building custom fields
227 *
414c1420
TO
228 * @param CRM_Core_Form $qf
229 * Form object (reference).
230 * @param string $elementName
231 * Name of the custom field.
100fef9d 232 * @param int $fieldId
414c1420
TO
233 * @param bool $inactiveNeeded
234 * @param bool $useRequired
235 * True if required else false.
236 * @param string $label
237 * Label for custom field.
77b97be7
EM
238 *
239 * @param null $fieldOptions
1537c309 240 * @param array $freezeOptions
6a488035 241 *
77b97be7
EM
242 * @return null
243 * @internal param bool $search true if used for search else false
6a488035
TO
244 * @static
245 */
9277d9e4
TO
246 public static function addQuickFormElement(
247 &$qf,
6a488035
TO
248 $elementName,
249 $fieldId,
250 $inactiveNeeded,
535a8e1e
CW
251 $useRequired = TRUE,
252 $label = NULL,
6a488035 253 $fieldOptions = NULL,
1537c309 254 $freezeOptions = array()
6a488035
TO
255 ) {
256
9da8dc8c 257 $field = new CRM_Price_DAO_PriceField();
6a488035
TO
258 $field->id = $fieldId;
259 if (!$field->find(TRUE)) {
260 /* FIXME: failure! */
261 return NULL;
262 }
366fe2a3 263
6a488035
TO
264 $is_pay_later = 0;
265 if (isset($qf->_mode) && empty($qf->_mode)) {
266 $is_pay_later = 1;
267 }
268 elseif (isset($qf->_values)) {
269 $is_pay_later = CRM_Utils_Array::value( 'is_pay_later', $qf->_values);
270 }
271
272 $otherAmount = $qf->get('values');
273 $config = CRM_Core_Config::singleton();
274 $currencySymbol = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_Currency',$config->defaultCurrency,'symbol','name');
275 $qf->assign('currencySymbol', $currencySymbol);
276 // get currency name for price field and option attributes
277 $currencyName = $config->defaultCurrency;
278
279 if (!isset($label)) {
15831617 280 $label = (!empty($qf->_membershipBlock) && $field->name == 'contribution_amount') ? ts('Additional Contribution') : $field->label;
6a488035
TO
281 }
282
283 if ($field->name == 'contribution_amount') {
284 $qf->_contributionAmount = 1;
285 }
286
287 if (isset($qf->_online) && $qf->_online) {
288 $useRequired = FALSE;
289 }
290
291 $customOption = $fieldOptions;
292 if (!is_array($customOption)) {
9da8dc8c 293 $customOption = CRM_Price_BAO_PriceField::getOptions($field->id, $inactiveNeeded);
6a488035
TO
294 }
295
296 //use value field.
297 $valueFieldName = 'amount';
298 $seperator = '|';
e0f7075f 299 $invoiceSettings = CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::CONTRIBUTE_PREFERENCES_NAME, 'contribution_invoice_settings');
5ebee375 300 $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
301 $displayOpt = CRM_Utils_Array::value('tax_display_settings', $invoiceSettings);
fff0f449 302 $invoicing = CRM_Utils_Array::value('invoicing', $invoiceSettings);
6a488035
TO
303 switch ($field->html_type) {
304 case 'Text':
305 $optionKey = key($customOption);
535a8e1e 306 $count = CRM_Utils_Array::value('count', $customOption[$optionKey], '');
6a488035 307 $max_value = CRM_Utils_Array::value('max_value', $customOption[$optionKey], '');
9d1c9154 308 $taxAmount = CRM_Utils_Array::value('tax_amount', $customOption[$optionKey]);
3bd20e3f 309 if (isset($taxAmount) && $displayOpt && $invoicing) {
dc428161 310 $qf->assign('displayOpt', $displayOpt);
5ebee375 311 $qf->assign('taxTerm', $taxTerm);
fff0f449 312 $qf->assign('invoicing', $invoicing);
dc428161 313 }
314 $priceVal = implode($seperator, array($customOption[$optionKey][$valueFieldName] + $taxAmount, $count, $max_value));
6a488035
TO
315
316 $extra = array();
15831617 317 if (!empty($qf->_quickConfig) && !empty($qf->_contributionAmount)) {
6a488035
TO
318 foreach($fieldOptions as &$fieldOption) {
319 if ($fieldOption['name'] == 'other_amount') {
320 $fieldOption['label'] = $fieldOption['label'] . ' ' . $currencySymbol;
321 }
322 }
323 $qf->assign('priceset', $elementName);
324 $extra = array('onclick' => 'useAmountOther();');
6a488035
TO
325 }
326
15831617 327 if (!empty($qf->_membershipBlock) && !empty($qf->_quickConfig) && $field->name == 'other_amount' && empty($qf->_contributionAmount)) {
6a488035 328 $useRequired = 0;
366fe2a3 329 }
a7488080 330 elseif (!empty($fieldOptions[$optionKey]['label'])) { //check for label.
6a488035
TO
331 $label = $fieldOptions[$optionKey]['label'];
332 }
333
334 $element = &$qf->add('text', $elementName, $label,
335 array_merge($extra,
336 array('price' => json_encode(array($optionKey, $priceVal)),
337 'size' => '4',
338 )
339 ),
340 $useRequired && $field->is_required
341 );
342 if ($is_pay_later) {
343 $qf->add( 'text', 'txt-'.$elementName, $label, array( 'size' => '4'));
344 }
345
d2108f71 346 // CRM-6902 - Add "max" option for a price set field
1537c309 347 if (in_array($optionKey, $freezeOptions)) {
79b152ac 348 self::freezeIfEnabled($element, $freezeOptions);
349 // CRM-14696 - Improve display for sold out price set options
350 $element->setLabel($label . '&nbsp;<span class="sold-out-option">' . ts('Sold out') . '</span>');
6a488035
TO
351 }
352
353 //CRM-10117
55c0b49a
RK
354 if (!empty($qf->_quickConfig)) {
355 $message = ts('Please enter a valid amount.');
356 $type = 'money';
357 }
358 else {
359 $message = ts('%1 must be a number (with or without decimal point).', array(1 => $label));
360 $type = 'numeric';
361 }
6a488035
TO
362 // integers will have numeric rule applied to them.
363 $qf->addRule($elementName, $message, $type);
364 break;
365
366 case 'Radio':
367 $choice = array();
368
15831617 369 if (!empty($qf->_quickConfig) && !empty($qf->_contributionAmount)) {
6a488035
TO
370 $qf->assign('contriPriceset', $elementName);
371 }
372
373 foreach ($customOption as $opId => $opt) {
9d1c9154 374 $taxAmount = CRM_Utils_Array::value('tax_amount', $opt);
6a488035 375 if ($field->is_display_amounts) {
e2d2aeab 376 $opt['label'] = !empty($opt['label']) ? $opt['label'] . '&nbsp;-&nbsp;' : '';
3bd20e3f 377 if (isset($taxAmount) && $invoicing) {
dc428161 378 if ($displayOpt == 'Do_not_show') {
e2d2aeab 379 $opt['label'] = '<span class="crm-price-amount-label">' . $opt['label'] . '</span>' . '<span class="crm-price-amount-amount">' . CRM_Utils_Money::format($opt[$valueFieldName] + $taxAmount) . '</span>';
dc428161 380 }
381 else if ($displayOpt == 'Inclusive') {
e2d2aeab
DG
382 $opt['label'] = '<span class="crm-price-amount-label">' . $opt['label'] . '</span>' . '<span class="crm-price-amount-amount">' . CRM_Utils_Money::format($opt[$valueFieldName] + $taxAmount) . '</span>';
383 $opt['label'] .= '<span class="crm-price-amount-tax"> (includes ' . $taxTerm . ' of ' . CRM_Utils_Money::format($opt['tax_amount']) . ')</span>';
dc428161 384 }
385 else {
e2d2aeab
DG
386 $opt['label'] = '<span class="crm-price-amount-label">' . $opt['label'] . '</span>' . '<span class="crm-price-amount-amount">' . CRM_Utils_Money::format($opt[$valueFieldName]) . '</span>';
387 $opt['label'] .= '<span class="crm-price-amount-tax"> + '. CRM_Utils_Money::format($opt['tax_amount']) . ' ' . $taxTerm . '</span>';
dc428161 388 }
389 }
390 else {
e2d2aeab 391 $opt['label'] = '<span class="crm-price-amount-label">' . $opt['label'] . '</span>' . '<span class="crm-price-amount-amount">' . CRM_Utils_Money::format($opt[$valueFieldName]) . '</span>';
dc428161 392 }
6a488035 393 }
535a8e1e 394 $count = CRM_Utils_Array::value('count', $opt, '');
6a488035 395 $max_value = CRM_Utils_Array::value('max_value', $opt, '');
dc428161 396 $priceVal = implode($seperator, array($opt[$valueFieldName] + $taxAmount, $count, $max_value));
6a488035
TO
397 $extra = array('price' => json_encode(array($elementName, $priceVal)),
398 'data-amount' => $opt[$valueFieldName],
399 'data-currency' => $currencyName,
400 );
15831617 401 if (!empty($qf->_quickConfig) && $field->name == 'contribution_amount') {
6a488035 402 $extra += array('onclick' => 'clearAmountOther();');
366fe2a3 403 }
15831617 404 elseif (!empty($qf->_quickConfig) && $field->name == 'membership_amount') {
6a488035
TO
405 $extra += array(
406 'onclick' => "return showHideAutoRenew({$opt['membership_type_id']});",
407 'membership-type' => $opt['membership_type_id'],
366fe2a3 408 );
6a488035
TO
409 $qf->assign('membershipFieldID',$field->id);
410 }
366fe2a3 411
6a488035
TO
412 $choice[$opId] = $qf->createElement('radio', NULL, '', $opt['label'], $opt['id'], $extra);
413
414 if ($is_pay_later) {
415 $qf->add( 'text', 'txt-'.$elementName, $label, array( 'size' => '4'));
416 }
417
d2108f71 418 // CRM-6902 - Add "max" option for a price set field
1537c309 419 if (in_array($opId, $freezeOptions)) {
e4c6a396 420 self::freezeIfEnabled($choice[$opId], $customOption[$opId]);
d2108f71 421 // CRM-14696 - Improve display for sold out price set options
be6dcd4e 422 $choice[$opId]->setText('<span class="sold-out-option">' . $choice[$opId]->getText() . '&nbsp;(' . ts('Sold out') . ')</span>');
6a488035
TO
423 }
424 }
15831617 425 if (!empty($qf->_membershipBlock) && $field->name == 'contribution_amount') {
6a488035 426 $choice[] = $qf->createElement('radio', NULL, '', ts('No thank you'), '-1',
abcf506a
PN
427 array(
428 'onclick' => 'clearAmountOther();',
429 )
6a488035
TO
430 );
431 }
432
433 if (!$field->is_required) {
434 // add "none" option
a7488080 435 if (!empty($otherAmount['is_allow_other_amount']) && $field->name == 'contribution_amount') {
6a488035 436 $none = ts('Other Amount');
366fe2a3 437 }
8cc574cf 438 elseif (!empty($qf->_membershipBlock) && empty($qf->_membershipBlock['is_required']) && $field->name == 'membership_amount') {
6a488035 439 $none = ts('No thank you');
366fe2a3 440 }
6a488035
TO
441 else {
442 $none = ts('- none -');
443 }
444
445 $choice[] = $qf->createElement('radio', NULL, '', $none, '0',
446 array('price' => json_encode(array($elementName, '0')))
447 );
448 }
449
450 $element = &$qf->addGroup($choice, $elementName, $label);
451
452 // make contribution field required for quick config when membership block is enabled
abcf506a 453 if (($field->name == 'membership_amount' || $field->name == 'contribution_amount')
15831617 454 && !empty($qf->_membershipBlock) && !$field->is_required) {
6a488035
TO
455 $useRequired = $field->is_required = TRUE;
456 }
457
458 if ($useRequired && $field->is_required) {
459 $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
460 }
461 break;
462
463 case 'Select':
464 $selectOption = $allowedOptions = $priceVal = array();
465
466 foreach ($customOption as $opt) {
9d1c9154 467 $taxAmount = CRM_Utils_Array::value('tax_amount', $opt);
6a488035
TO
468 $count = CRM_Utils_Array::value('count', $opt, '');
469 $max_value = CRM_Utils_Array::value('max_value', $opt, '');
6a488035
TO
470
471 if ($field->is_display_amounts) {
472 $opt['label'] .= '&nbsp;-&nbsp;';
3bd20e3f 473 if (isset($taxAmount) && $invoicing) {
e2d2aeab 474 $opt['label'] = $opt['label'] . self::getTaxLabel($opt, $valueFieldName, $displayOpt, $taxTerm);
dc428161 475 }
476 else {
e2d2aeab 477 $opt['label'] = $opt['label'] . CRM_Utils_Money::format($opt[$valueFieldName]);
dc428161 478 }
6a488035 479 }
79b152ac 480
6a488035 481 $selectOption[$opt['id']] = $opt['label'];
dc428161 482 $priceVal[$opt['id']] = implode($seperator, array($opt[$valueFieldName] + $taxAmount, $count, $max_value));
79b152ac 483
1537c309 484 if (!in_array($opt['id'], $freezeOptions)) {
6a488035
TO
485 $allowedOptions[] = $opt['id'];
486 }
d2108f71 487 // CRM-14696 - Improve display for sold out price set options
76991db6 488 else {
be6dcd4e 489 $opt['label'] = $opt['label'] . ' (' . ts('Sold out') . ')';
d2108f71 490 }
79b152ac 491
d2108f71
J
492 $selectOption[$opt['id']] = $opt['label'];
493
6a488035
TO
494 if ($is_pay_later) {
495 $qf->add( 'text', 'txt-'.$elementName, $label, array( 'size' => '4'));
496 }
497 }
79b152ac 498
6a488035
TO
499 $element = &$qf->add('select', $elementName, $label,
500 array(
501 '' => ts('- select -')) + $selectOption,
502 $useRequired && $field->is_required,
503 array('price' => json_encode($priceVal))
504 );
505
d2108f71 506 // CRM-6902 - Add "max" option for a price set field
6a488035 507 $button = substr($qf->controller->getButtonName(), -4);
1537c309 508 if (!empty($freezeOptions) && $button != 'skip') {
6a488035
TO
509 $qf->addRule($elementName, ts('Sorry, this option is currently sold out.'), 'regex', "/" . implode('|', $allowedOptions) . "/");
510 }
511 break;
512
513 case 'CheckBox':
514
515 $check = array();
516 foreach ($customOption as $opId => $opt) {
9d1c9154 517 $taxAmount = CRM_Utils_Array::value('tax_amount', $opt);
535a8e1e 518 $count = CRM_Utils_Array::value('count', $opt, '');
6a488035 519 $max_value = CRM_Utils_Array::value('max_value', $opt, '');
6a488035
TO
520
521 if ($field->is_display_amounts) {
e2d2aeab 522 $opt['label'] = '<span class="crm-price-amount-label">' . $opt['label'] . '</span>&nbsp;-&nbsp;';
3bd20e3f 523 if (isset($taxAmount) && $invoicing) {
5ebee375 524 $opt['label'] .= self::getTaxLabel($opt, $valueFieldName, $displayOpt, $taxTerm);
dc428161 525 }
526 else {
527 $opt['label'] .= CRM_Utils_Money::format($opt[$valueFieldName]);
528 }
6a488035 529 }
dc428161 530 $priceVal = implode($seperator, array($opt[$valueFieldName] + $taxAmount, $count, $max_value));
6a488035
TO
531 $check[$opId] = &$qf->createElement('checkbox', $opt['id'], NULL, $opt['label'],
532 array('price' => json_encode(array($opt['id'], $priceVal)),
533 'data-amount' => $opt[$valueFieldName],
534 'data-currency' => $currencyName,
535 )
536 );
537 if ($is_pay_later) {
538 $txtcheck[$opId] =& $qf->createElement( 'text', $opId, $opt['label'], array( 'size' => '4' ) );
539 $qf->addGroup($txtcheck, 'txt-'.$elementName, $label);
540 }
d2108f71 541 // CRM-6902 - Add "max" option for a price set field
1537c309 542 if (in_array($opId, $freezeOptions)) {
e4c6a396 543 self::freezeIfEnabled($check[$opId], $customOption[$opId]);
d2108f71 544 // CRM-14696 - Improve display for sold out price set options
be6dcd4e 545 $check[$opId]->setText('<span class="sold-out-option">' . $check[$opId]->getText() . '&nbsp;(' . ts('Sold out') . ')</span>');
6a488035
TO
546 }
547 }
548 $element = &$qf->addGroup($check, $elementName, $label);
549 if ($useRequired && $field->is_required) {
550 $qf->addRule($elementName, ts('%1 is a required field.', array(1 => $label)), 'required');
551 }
552 break;
553 }
554 if (isset($qf->_online) && $qf->_online) {
555 $element->freeze();
556 }
557 }
558
559 /**
560 * Retrieve a list of options for the specified field
561 *
414c1420
TO
562 * @param int $fieldId
563 * Price field ID.
564 * @param bool $inactiveNeeded
565 * Include inactive options.
566 * @param bool $reset
567 * Ignore stored values\.
6a488035
TO
568 *
569 * @return array array of options
570 */
571 public static function getOptions($fieldId, $inactiveNeeded = FALSE, $reset = FALSE) {
572 static $options = array();
573
574 if ($reset || empty($options[$fieldId])) {
575 $values = array();
9da8dc8c 576 CRM_Price_BAO_PriceFieldValue::getValues($fieldId, $values, 'weight', !$inactiveNeeded);
6a488035 577 $options[$fieldId] = $values;
dc428161 578 $taxRates = CRM_Core_PseudoConstant::getTaxRates();
579
580 // ToDo - Code for Hook Invoke
581
582 foreach ($options[$fieldId] as $priceFieldId => $priceFieldValues) {
17ab42dd 583 if (isset($priceFieldValues['financial_type_id']) && array_key_exists($priceFieldValues['financial_type_id'], $taxRates)) {
dc428161 584 $options[$fieldId][$priceFieldId]['tax_rate'] = $taxRates[$priceFieldValues['financial_type_id']];
9d1c9154 585 $taxAmount = CRM_Contribute_BAO_Contribution_Utils::calculateTaxAmount($priceFieldValues['amount'], $options[$fieldId][$priceFieldId]['tax_rate']);
dc428161 586 $options[$fieldId][$priceFieldId]['tax_amount'] = round($taxAmount['tax_amount'],2);
587 }
588 }
6a488035
TO
589 }
590
591 return $options[$fieldId];
592 }
593
ffd93213
EM
594 /**
595 * @param $optionLabel
100fef9d 596 * @param int $fid
ffd93213
EM
597 *
598 * @return mixed
599 */
6a488035
TO
600 public static function getOptionId($optionLabel, $fid) {
601 if (!$optionLabel || !$fid) {
602 return;
603 }
604
605 $optionGroupName = "civicrm_price_field.amount.{$fid}";
606
607 $query = "
608SELECT
609 option_value.id as id
610FROM
611 civicrm_option_value option_value,
612 civicrm_option_group option_group
613WHERE
535a8e1e
CW
614 option_group.name = %1
615 AND option_group.id = option_value.option_group_id
6a488035
TO
616 AND option_value.label = %2";
617
618 $dao = CRM_Core_DAO::executeQuery($query, array(1 => array($optionGroupName, 'String'), 2 => array($optionLabel, 'String')));
619
620 while ($dao->fetch()) {
621 return $dao->id;
622 }
623 }
624
625 /**
626 * Delete the price set field.
627 *
414c1420
TO
628 * @param int $id
629 * Field Id.
6a488035
TO
630 *
631 * @return boolean
632 *
6a488035
TO
633 * @static
634 *
635 */
636 public static function deleteField($id) {
9da8dc8c 637 $field = new CRM_Price_DAO_PriceField();
6a488035
TO
638 $field->id = $id;
639
640 if ($field->find(TRUE)) {
641 // delete the options for this field
9da8dc8c 642 CRM_Price_BAO_PriceFieldValue::deleteValues($id);
6a488035
TO
643
644 // reorder the weight before delete
645 $fieldValues = array('price_set_id' => $field->price_set_id);
646
9da8dc8c 647 CRM_Utils_Weight::delWeight('CRM_Price_DAO_PriceField', $field->id, $fieldValues);
6a488035
TO
648
649 // now delete the field
650 return $field->delete();
651 }
652
653 return NULL;
654 }
655
ffd93213
EM
656 /**
657 * @return array
658 */
00be9182 659 public static function &htmlTypes() {
6a488035
TO
660 static $htmlTypes = NULL;
661 if (!$htmlTypes) {
662 $htmlTypes = array(
663 'Text' => ts('Text / Numeric Quantity'),
664 'Select' => ts('Select'),
665 'Radio' => ts('Radio'),
666 'CheckBox' => ts('CheckBox'),
667 );
668 }
669 return $htmlTypes;
670 }
671
672 /**
673 * Validate the priceset
674 *
414c1420
TO
675 * @param int $priceSetId
676 * , array $fields.
6a488035
TO
677 *
678 * retrun the error string
679 *
2a6da8d7
EM
680 * @param $fields
681 * @param $error
682 * @param bool $allowNoneSelection
683 *
6a488035 684 * @static
6a488035
TO
685 */
686
687 public static function priceSetValidation($priceSetId, $fields, &$error, $allowNoneSelection = FALSE) {
688 // check for at least one positive
689 // amount price field should be selected.
9da8dc8c 690 $priceField = new CRM_Price_DAO_PriceField();
6a488035
TO
691 $priceField->price_set_id = $priceSetId;
692 $priceField->find();
693
694 $priceFields = array();
695
696 if ($allowNoneSelection) {
697 $noneSelectedPriceFields = array();
698 }
699
700 while ($priceField->fetch()) {
701 $key = "price_{$priceField->id}";
702
703 if ($allowNoneSelection) {
704 if (array_key_exists($key, $fields)) {
705 if ($fields[$key] == 0 && !$priceField->is_required) {
706 $noneSelectedPriceFields[] = $priceField->id;
707 }
708 }
709 }
710
a7488080 711 if (!empty($fields[$key])) {
6a488035
TO
712 $priceFields[$priceField->id] = $fields[$key];
713 }
714 }
715
716 if (!empty($priceFields)) {
717 // we should has to have positive amount.
718 $sql = "
719SELECT id, html_type
720FROM civicrm_price_field
721WHERE id IN (" . implode(',', array_keys($priceFields)) . ')';
722 $fieldDAO = CRM_Core_DAO::executeQuery($sql);
723 $htmlTypes = array();
724 while ($fieldDAO->fetch()) {
725 $htmlTypes[$fieldDAO->id] = $fieldDAO->html_type;
726 }
727
728 $selectedAmounts = array();
729
730 foreach ($htmlTypes as $fieldId => $type) {
731 $options = array();
9da8dc8c 732 CRM_Price_BAO_PriceFieldValue::getValues($fieldId, $options);
6a488035
TO
733
734 if (empty($options)) {
735 continue;
736 }
737
738 if ($type == 'Text') {
739 foreach ($options as $opId => $option) {
740 $selectedAmounts[$opId] = $priceFields[$fieldId] * $option['amount'];
741 break;
742 }
743 }
744 elseif (is_array($fields["price_{$fieldId}"])) {
745 foreach (array_keys($fields["price_{$fieldId}"]) as $opId) {
746 $selectedAmounts[$opId] = $options[$opId]['amount'];
747 }
748 }
749 elseif (in_array($fields["price_{$fieldId}"], array_keys($options))) {
750 $selectedAmounts[$fields["price_{$fieldId}"]] = $options[$fields["price_{$fieldId}"]]['amount'];
751 }
752 }
753
754 list($componentName) = explode(':', $fields['_qf_default']);
755 // now we have all selected amount in hand.
756 $totalAmount = array_sum($selectedAmounts);
757 if ($totalAmount < 0) {
758 $error['_qf_default'] = ts('%1 amount can not be less than zero. Please select the options accordingly.', array(1 => $componentName));
759 }
760 }
761 else {
762 if ($allowNoneSelection) {
763 if (empty($noneSelectedPriceFields)) {
764 $error['_qf_default'] = ts('Please select at least one option from price set.');
765 }
0db6c3e1
TO
766 }
767 else {
6a488035
TO
768 $error['_qf_default'] = ts('Please select at least one option from price set.');
769 }
770 }
771 }
dc428161 772
773 /**
9d1c9154 774 * Generate the label for price fields based on tax display setting option on CiviContribute Component Settings page.
dc428161 775 *
9d1c9154 776 * @param array $opt
414c1420
TO
777 * @param string $valueFieldName
778 * Amount.
779 * @param string $displayOpt
780 * Tax display setting option.
dc428161 781 *
9d1c9154 782 * @return string $label tax label for custom field
dc428161 783 *
dc428161 784 * @static
785 *
786 */
5ebee375 787 public static function getTaxLabel($opt, $valueFieldName, $displayOpt, $taxTerm) {
9d1c9154 788 if ($displayOpt == 'Do_not_show') {
789 $label = CRM_Utils_Money::format($opt[$valueFieldName] + $opt['tax_amount']);
790 }
791 else if ($displayOpt == 'Inclusive') {
792 $label = CRM_Utils_Money::format($opt[$valueFieldName] + $opt['tax_amount']);
e2d2aeab 793 $label .= '<span class="crm-price-amount-tax"> (includes ' . $taxTerm . ' of ' . CRM_Utils_Money::format($opt['tax_amount']) . ')</span>';
9d1c9154 794 }
795 else {
796 $label = CRM_Utils_Money::format($opt[$valueFieldName]);
e2d2aeab 797 $label .= '<span class="crm-price-amount-tax"> + '. CRM_Utils_Money::format($opt['tax_amount']) . ' ' . $taxTerm . '</span>';
9d1c9154 798 }
dc428161 799
9d1c9154 800 return $label;
dc428161 801 }
6a488035 802}