Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | <?php |
2 | /* | |
3 | +--------------------------------------------------------------------+ | |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
6a488035 | 5 | | | |
bc77d7c0 TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
6a488035 | 9 | +--------------------------------------------------------------------+ |
d25dd0ee | 10 | */ |
6a488035 TO |
11 | |
12 | /** | |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
6a488035 TO |
16 | */ |
17 | ||
18 | /** | |
19 | * form to process actions on the field aspect of Price | |
20 | */ | |
21 | class CRM_Price_Form_Field extends CRM_Core_Form { | |
22 | ||
44374cbe | 23 | use CRM_Core_Form_EntityFormTrait; |
24 | ||
25 | /** | |
26 | * Explicitly declare the entity api name. | |
27 | */ | |
28 | public function getDefaultEntity() { | |
29 | return 'PriceField'; | |
30 | } | |
31 | ||
32 | /** | |
33 | * Explicitly declare the form context. | |
34 | */ | |
35 | public function getDefaultContext() { | |
36 | return 'create'; | |
37 | } | |
38 | ||
39 | /** | |
40 | * Get the entity id being edited. | |
41 | * | |
42 | * @return int|null | |
43 | */ | |
44 | public function getEntityId() { | |
45 | return $this->_fid; | |
46 | } | |
47 | ||
6a488035 TO |
48 | /** |
49 | * Constants for number of options for data types of multiple option. | |
50 | */ | |
7da04cde | 51 | const NUM_OPTION = 15; |
6a488035 TO |
52 | |
53 | /** | |
fe482240 | 54 | * The custom set id saved to the session for an update. |
6a488035 TO |
55 | * |
56 | * @var int | |
6a488035 TO |
57 | */ |
58 | protected $_sid; | |
59 | ||
60 | /** | |
61 | * The field id, used when editing the field | |
62 | * | |
63 | * @var int | |
6a488035 TO |
64 | */ |
65 | protected $_fid; | |
66 | ||
67 | /** | |
fe482240 | 68 | * The extended component Id. |
6a488035 TO |
69 | * |
70 | * @var array | |
6a488035 TO |
71 | */ |
72 | protected $_extendComponentId; | |
73 | ||
74 | /** | |
fe482240 | 75 | * Variable is set if price set is used for membership. |
971e129b | 76 | * @var bool |
6a488035 TO |
77 | */ |
78 | protected $_useForMember; | |
79 | ||
f961a8cd SL |
80 | /** |
81 | * Set the price Set Id (only used in tests) | |
82 | */ | |
83 | public function setPriceSetId($priceSetId) { | |
84 | $this->_sid = $priceSetId; | |
85 | } | |
86 | ||
6a488035 | 87 | /** |
fe482240 | 88 | * Set variables up before form is built. |
6a488035 TO |
89 | */ |
90 | public function preProcess() { | |
91 | ||
44374cbe | 92 | $this->_sid = CRM_Utils_Request::retrieve('sid', 'Positive', $this); |
93 | $this->_fid = CRM_Utils_Request::retrieve('fid', 'Positive', $this); | |
353ffa53 | 94 | $url = CRM_Utils_System::url('civicrm/admin/price/field', "reset=1&action=browse&sid={$this->_sid}"); |
be2fb01f | 95 | $breadCrumb = [['title' => ts('Price Set Fields'), 'url' => $url]]; |
6a488035 | 96 | |
be2fb01f | 97 | $this->_extendComponentId = []; |
9da8dc8c | 98 | $extendComponentId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_sid, 'extends', 'id'); |
6a488035 TO |
99 | if ($extendComponentId) { |
100 | $this->_extendComponentId = explode(CRM_Core_DAO::VALUE_SEPARATOR, $extendComponentId); | |
101 | } | |
102 | ||
103 | CRM_Utils_System::appendBreadCrumb($breadCrumb); | |
704f21c0 | 104 | |
e2046b33 | 105 | $this->setPageTitle(ts('Price Field')); |
6a488035 TO |
106 | } |
107 | ||
108 | /** | |
bf15c191 | 109 | * Set default values for the form. |
6a488035 | 110 | * |
a6c01b45 CW |
111 | * @return array |
112 | * array of default values | |
44374cbe | 113 | * @throws \CRM_Core_Exception |
6a488035 | 114 | */ |
00be9182 | 115 | public function setDefaultValues() { |
be2fb01f | 116 | $defaults = []; |
6a488035 | 117 | // is it an edit operation ? |
44374cbe | 118 | if ($this->getEntityId()) { |
119 | $params = ['id' => $this->getEntityId()]; | |
120 | $this->assign('fid', $this->getEntityId()); | |
9da8dc8c | 121 | CRM_Price_BAO_PriceField::retrieve($params, $defaults); |
6a488035 TO |
122 | $this->_sid = $defaults['price_set_id']; |
123 | ||
124 | // if text, retrieve price | |
125 | if ($defaults['html_type'] == 'Text') { | |
fc8edfbf | 126 | $isActive = $defaults['is_active']; |
44374cbe | 127 | $valueParams = ['price_field_id' => $this->getEntityId()]; |
6a488035 | 128 | |
9da8dc8c | 129 | CRM_Price_BAO_PriceFieldValue::retrieve($valueParams, $defaults); |
6a488035 TO |
130 | |
131 | // fix the display of the monetary value, CRM-4038 | |
d90d1031 | 132 | $defaults['price'] = CRM_Utils_Money::formatLocaleNumericRoundedForDefaultCurrency($defaults['amount']); |
ff33ddc8 | 133 | $defaults['is_active'] = $isActive; |
6a488035 TO |
134 | } |
135 | ||
6a488035 TO |
136 | } |
137 | else { | |
138 | $defaults['is_active'] = 1; | |
139 | for ($i = 1; $i <= self::NUM_OPTION; $i++) { | |
140 | $defaults['option_status[' . $i . ']'] = 1; | |
141 | $defaults['option_weight[' . $i . ']'] = $i; | |
2db35bf6 | 142 | $defaults['option_visibility_id[' . $i . ']'] = 1; |
6a488035 TO |
143 | } |
144 | } | |
145 | ||
146 | if ($this->_action & CRM_Core_Action::ADD) { | |
be2fb01f | 147 | $fieldValues = ['price_set_id' => $this->_sid]; |
9da8dc8c | 148 | $defaults['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Price_DAO_PriceField', $fieldValues); |
6a488035 TO |
149 | $defaults['options_per_line'] = 1; |
150 | $defaults['is_display_amounts'] = 1; | |
151 | } | |
0495a6a4 | 152 | $enabledComponents = CRM_Core_Component::getEnabledComponents(); |
153 | $eventComponentId = NULL; | |
ba1dcfda | 154 | if (array_key_exists('CiviEvent', $enabledComponents)) { |
353ffa53 | 155 | $eventComponentId = CRM_Core_Component::getComponentID('CiviEvent'); |
0495a6a4 | 156 | } |
6a488035 TO |
157 | |
158 | if (isset($this->_sid) && $this->_action == CRM_Core_Action::ADD) { | |
9da8dc8c | 159 | $financialTypeId = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceSet', $this->_sid, 'financial_type_id'); |
6a488035 TO |
160 | $defaults['financial_type_id'] = $financialTypeId; |
161 | for ($i = 1; $i <= self::NUM_OPTION; $i++) { | |
162 | $defaults['option_financial_type_id[' . $i . ']'] = $financialTypeId; | |
163 | } | |
164 | } | |
165 | return $defaults; | |
166 | } | |
167 | ||
168 | /** | |
fe482240 | 169 | * Build the form object. |
6a488035 TO |
170 | */ |
171 | public function buildQuickForm() { | |
172 | // lets trim all the whitespace | |
173 | $this->applyFilter('__ALL__', 'trim'); | |
174 | ||
175 | // add a hidden field to remember the price set id | |
176 | // this get around the browser tab issue | |
177 | $this->add('hidden', 'sid', $this->_sid); | |
44374cbe | 178 | $this->add('hidden', 'fid', $this->getEntityId()); |
6a488035 TO |
179 | |
180 | // label | |
9da8dc8c | 181 | $this->add('text', 'label', ts('Field Label'), CRM_Core_DAO::getAttribute('CRM_Price_DAO_PriceField', 'label'), TRUE); |
6a488035 TO |
182 | |
183 | // html_type | |
4367e964 | 184 | $javascript = ['onchange' => 'option_html_type(this.form);']; |
6a488035 | 185 | |
9da8dc8c | 186 | $htmlTypes = CRM_Price_BAO_PriceField::htmlTypes(); |
6a488035 TO |
187 | |
188 | // Text box for Participant Count for a field | |
189 | ||
190 | // Financial Type | |
191 | $financialType = CRM_Financial_BAO_FinancialType::getIncomeFinancialType(); | |
53df1142 | 192 | foreach ($financialType as $finTypeId => $type) { |
40c655aa | 193 | if (CRM_Financial_BAO_FinancialType::isACLFinancialTypeStatus() |
66af7c48 PN |
194 | && !CRM_Core_Permission::check('add contributions of type ' . $type) |
195 | ) { | |
53df1142 E |
196 | unset($financialType[$finTypeId]); |
197 | } | |
198 | } | |
6a488035 TO |
199 | if (count($financialType)) { |
200 | $this->assign('financialType', $financialType); | |
201 | } | |
2db35bf6 AF |
202 | |
203 | //Visibility Type Options | |
204 | $visibilityType = CRM_Core_PseudoConstant::visibility(); | |
205 | $this->assign('visibilityType', $visibilityType); | |
206 | ||
0495a6a4 | 207 | $enabledComponents = CRM_Core_Component::getEnabledComponents(); |
208 | $eventComponentId = $memberComponentId = NULL; | |
ba1dcfda | 209 | if (array_key_exists('CiviEvent', $enabledComponents)) { |
353ffa53 | 210 | $eventComponentId = CRM_Core_Component::getComponentID('CiviEvent'); |
0495a6a4 | 211 | } |
ba1dcfda | 212 | if (array_key_exists('CiviMember', $enabledComponents)) { |
0495a6a4 | 213 | $memberComponentId = CRM_Core_Component::getComponentID('CiviMember'); |
214 | } | |
366fe2a3 | 215 | |
353ffa53 | 216 | $attributes = CRM_Core_DAO::getAttribute('CRM_Price_DAO_PriceFieldValue'); |
366fe2a3 | 217 | |
218 | $this->add('select', 'financial_type_id', | |
219 | ts('Financial Type'), | |
be2fb01f | 220 | [' ' => ts('- select -')] + $financialType |
6a488035 TO |
221 | ); |
222 | ||
223 | $this->assign('useForMember', FALSE); | |
224 | if (in_array($eventComponentId, $this->_extendComponentId)) { | |
225 | $this->add('text', 'count', ts('Participant Count'), $attributes['count']); | |
226 | ||
227 | $this->addRule('count', ts('Participant Count should be a positive number'), 'positiveInteger'); | |
228 | ||
229 | $this->add('text', 'max_value', ts('Max Participants'), $attributes['max_value']); | |
230 | $this->addRule('max_value', ts('Please enter a valid Max Participants.'), 'positiveInteger'); | |
231 | ||
232 | $this->assign('useForEvent', TRUE); | |
233 | } | |
234 | else { | |
235 | if (in_array($memberComponentId, $this->_extendComponentId)) { | |
236 | $this->_useForMember = 1; | |
237 | $this->assign('useForMember', $this->_useForMember); | |
238 | } | |
239 | $this->assign('useForEvent', FALSE); | |
240 | } | |
241 | ||
242 | $sel = $this->add('select', 'html_type', ts('Input Field Type'), | |
243 | $htmlTypes, TRUE, $javascript | |
244 | ); | |
245 | ||
246 | // price (for text inputs) | |
247 | $this->add('text', 'price', ts('Price')); | |
248 | $this->registerRule('price', 'callback', 'money', 'CRM_Utils_Rule'); | |
249 | $this->addRule('price', ts('must be a monetary value'), 'money'); | |
250 | ||
5afce5ad | 251 | $this->add('text', 'non_deductible_amount', ts('Non-deductible Amount'), NULL); |
252 | $this->registerRule('non_deductible_amount', 'callback', 'money', 'CRM_Utils_Rule'); | |
253 | $this->addRule('non_deductible_amount', ts('Please enter a monetary value for this field.'), 'money'); | |
254 | ||
6a488035 TO |
255 | if ($this->_action == CRM_Core_Action::UPDATE) { |
256 | $this->freeze('html_type'); | |
257 | } | |
258 | ||
259 | // form fields of Custom Option rows | |
9fa4c570 | 260 | $_showHide = new CRM_Core_ShowHideBlocks(); |
6a488035 TO |
261 | |
262 | for ($i = 1; $i <= self::NUM_OPTION; $i++) { | |
263 | ||
264 | //the show hide blocks | |
265 | $showBlocks = 'optionField_' . $i; | |
266 | if ($i > 2) { | |
267 | $_showHide->addHide($showBlocks); | |
268 | if ($i == self::NUM_OPTION) { | |
269 | $_showHide->addHide('additionalOption'); | |
270 | } | |
271 | } | |
272 | else { | |
273 | $_showHide->addShow($showBlocks); | |
274 | } | |
275 | // label | |
276 | $attributes['label']['size'] = 25; | |
277 | $this->add('text', 'option_label[' . $i . ']', ts('Label'), $attributes['label']); | |
278 | ||
279 | // amount | |
280 | $this->add('text', 'option_amount[' . $i . ']', ts('Amount'), $attributes['amount']); | |
281 | $this->addRule('option_amount[' . $i . ']', ts('Please enter a valid amount for this field.'), 'money'); | |
282 | ||
283 | //Financial Type | |
284 | $this->add( | |
366fe2a3 | 285 | 'select', |
92fcb95f | 286 | 'option_financial_type_id[' . $i . ']', |
366fe2a3 | 287 | ts('Financial Type'), |
be2fb01f | 288 | ['' => ts('- select -')] + $financialType |
6a488035 TO |
289 | ); |
290 | if (in_array($eventComponentId, $this->_extendComponentId)) { | |
291 | // count | |
292 | $this->add('text', 'option_count[' . $i . ']', ts('Participant Count'), $attributes['count']); | |
293 | $this->addRule('option_count[' . $i . ']', ts('Please enter a valid Participants Count.'), 'positiveInteger'); | |
294 | ||
295 | // max_value | |
296 | $this->add('text', 'option_max_value[' . $i . ']', ts('Max Participants'), $attributes['max_value']); | |
297 | $this->addRule('option_max_value[' . $i . ']', ts('Please enter a valid Max Participants.'), 'positiveInteger'); | |
298 | ||
299 | // description | |
300 | //$this->add('textArea', 'option_description['.$i.']', ts('Description'), array('rows' => 1, 'cols' => 40 )); | |
301 | } | |
302 | elseif (in_array($memberComponentId, $this->_extendComponentId)) { | |
303 | $membershipTypes = CRM_Member_PseudoConstant::membershipType(); | |
be2fb01f | 304 | $js = ['onchange' => "calculateRowValues( $i );"]; |
6a488035 TO |
305 | |
306 | $this->add('select', 'membership_type_id[' . $i . ']', ts('Membership Type'), | |
be2fb01f | 307 | ['' => ' '] + $membershipTypes, FALSE, $js |
353ffa53 | 308 | ); |
896bd22c | 309 | $this->add('text', 'membership_num_terms[' . $i . ']', ts('Number of Terms'), CRM_Utils_Array::value('membership_num_terms', $attributes)); |
6a488035 TO |
310 | } |
311 | ||
312 | // weight | |
f20d2b0d | 313 | $this->add('number', 'option_weight[' . $i . ']', ts('Order'), $attributes['weight']); |
6a488035 TO |
314 | |
315 | // is active ? | |
316 | $this->add('checkbox', 'option_status[' . $i . ']', ts('Active?')); | |
317 | ||
2bc7601f | 318 | $this->add('select', 'option_visibility_id[' . $i . ']', ts('Visibility'), $visibilityType); |
ca5603d5 | 319 | $defaultOption[$i] = NULL; |
6a488035 TO |
320 | |
321 | //for checkbox handling of default option | |
322 | $this->add('checkbox', "default_checkbox_option[$i]", NULL); | |
323 | } | |
324 | //default option selection | |
ca5603d5 | 325 | $this->addRadio('default_option', NULL, $defaultOption); |
6a488035 TO |
326 | $_showHide->addToTemplate(); |
327 | ||
328 | // is_display_amounts | |
329 | $this->add('checkbox', 'is_display_amounts', ts('Display Amount?')); | |
330 | ||
331 | // weight | |
f20d2b0d | 332 | $this->add('number', 'weight', ts('Order'), CRM_Core_DAO::getAttribute('CRM_Price_DAO_PriceField', 'weight'), TRUE); |
6a488035 TO |
333 | $this->addRule('weight', ts('is a numeric field'), 'numeric'); |
334 | ||
335 | // checkbox / radio options per line | |
336 | $this->add('text', 'options_per_line', ts('Options Per Line')); | |
337 | $this->addRule('options_per_line', ts('must be a numeric value'), 'numeric'); | |
338 | ||
139f5f76 | 339 | $this->add('textarea', 'help_pre', ts('Pre Field Help'), |
d0540e92 | 340 | CRM_Core_DAO::getAttribute('CRM_Price_DAO_PriceField', 'help_pre') |
139f5f76 JP |
341 | ); |
342 | ||
6a488035 | 343 | // help post, mask, attributes, javascript ? |
139f5f76 | 344 | $this->add('textarea', 'help_post', ts('Post Field Help'), |
9da8dc8c | 345 | CRM_Core_DAO::getAttribute('CRM_Price_DAO_PriceField', 'help_post') |
6a488035 TO |
346 | ); |
347 | ||
be2fb01f | 348 | $this->add('datepicker', 'active_on', ts('Active On'), [], FALSE, ['time' => TRUE]); |
6a488035 TO |
349 | |
350 | // expire_on | |
be2fb01f | 351 | $this->add('datepicker', 'expire_on', ts('Expire On'), [], FALSE, ['time' => TRUE]); |
6a488035 TO |
352 | |
353 | // is required ? | |
354 | $this->add('checkbox', 'is_required', ts('Required?')); | |
355 | ||
356 | // is active ? | |
357 | $this->add('checkbox', 'is_active', ts('Active?')); | |
358 | ||
359 | // add buttons | |
be2fb01f CW |
360 | $this->addButtons([ |
361 | [ | |
c5c263ca AH |
362 | 'type' => 'next', |
363 | 'name' => ts('Save'), | |
364 | 'isDefault' => TRUE, | |
be2fb01f CW |
365 | ], |
366 | [ | |
c5c263ca AH |
367 | 'type' => 'next', |
368 | 'name' => ts('Save and New'), | |
369 | 'subName' => 'new', | |
be2fb01f CW |
370 | ], |
371 | [ | |
c5c263ca AH |
372 | 'type' => 'cancel', |
373 | 'name' => ts('Cancel'), | |
be2fb01f CW |
374 | ], |
375 | ]); | |
6a488035 TO |
376 | // is public? |
377 | $this->add('select', 'visibility_id', ts('Visibility'), CRM_Core_PseudoConstant::visibility()); | |
378 | ||
379 | // add a form rule to check default value | |
be2fb01f | 380 | $this->addFormRule(['CRM_Price_Form_Field', 'formRule'], $this); |
6a488035 TO |
381 | |
382 | // if view mode pls freeze it with the done button. | |
383 | if ($this->_action & CRM_Core_Action::VIEW) { | |
384 | $this->freeze(); | |
385 | $url = CRM_Utils_System::url('civicrm/admin/price/field', 'reset=1&action=browse&sid=' . $this->_sid); | |
cbd83dde | 386 | $this->addElement('xbutton', |
6a488035 TO |
387 | 'done', |
388 | ts('Done'), | |
cbd83dde AH |
389 | [ |
390 | 'type' => 'button', | |
391 | 'onclick' => "location.href='$url'", | |
392 | ] | |
6a488035 TO |
393 | ); |
394 | } | |
395 | } | |
396 | ||
397 | /** | |
fe482240 | 398 | * Global validation rules for the form. |
6a488035 | 399 | * |
414c1420 TO |
400 | * @param array $fields |
401 | * Posted values of the form. | |
77b97be7 | 402 | * |
44374cbe | 403 | * @param array $files |
404 | * @param self $form | |
6a488035 | 405 | * |
a6c01b45 CW |
406 | * @return array |
407 | * if errors then list of errors to be posted back to the form, | |
6a488035 | 408 | * true otherwise |
6a488035 | 409 | */ |
00be9182 | 410 | public static function formRule($fields, $files, $form) { |
6a488035 TO |
411 | |
412 | // all option fields are of type "money" | |
be2fb01f | 413 | $errors = []; |
6a488035 TO |
414 | |
415 | /** Check the option values entered | |
416 | * Appropriate values are required for the selected datatype | |
417 | * Incomplete row checking is also required. | |
418 | */ | |
419 | if (($form->_action & CRM_Core_Action::ADD || $form->_action & CRM_Core_Action::UPDATE) && | |
44374cbe | 420 | $fields['html_type'] === 'Text' |
6a488035 | 421 | ) { |
e68e1c9a PN |
422 | if ($fields['price'] == NULL) { |
423 | $errors['price'] = ts('Price is a required field'); | |
424 | } | |
425 | if ($fields['financial_type_id'] == '') { | |
426 | $errors['financial_type_id'] = ts('Financial Type is a required field'); | |
427 | } | |
6a488035 | 428 | } |
366fe2a3 | 429 | |
6a488035 | 430 | if ((is_numeric(CRM_Utils_Array::value('count', $fields)) && |
de6c59ca | 431 | empty($fields['count']) |
6a488035 TO |
432 | ) && |
433 | (CRM_Utils_Array::value('html_type', $fields) == 'Text') | |
434 | ) { | |
435 | $errors['count'] = ts('Participant Count must be greater than zero.'); | |
436 | } | |
437 | ||
438 | if ($form->_action & CRM_Core_Action::ADD) { | |
439 | if ($fields['html_type'] != 'Text') { | |
440 | $countemptyrows = 0; | |
a13c171d | 441 | $publicOptionCount = $_flagOption = $_rowError = 0; |
6a488035 | 442 | |
9fa4c570 | 443 | $_showHide = new CRM_Core_ShowHideBlocks(); |
39868387 | 444 | $visibilityOptions = CRM_Price_BAO_PriceFieldValue::buildOptions('visibility_id', 'validate'); |
6a488035 TO |
445 | |
446 | for ($index = 1; $index <= self::NUM_OPTION; $index++) { | |
447 | ||
448 | $noLabel = $noAmount = $noWeight = 1; | |
449 | if (!empty($fields['option_label'][$index])) { | |
450 | $noLabel = 0; | |
451 | $duplicateIndex = CRM_Utils_Array::key($fields['option_label'][$index], | |
452 | $fields['option_label'] | |
453 | ); | |
454 | ||
455 | if ((!($duplicateIndex === FALSE)) && | |
456 | (!($duplicateIndex == $index)) | |
457 | ) { | |
458 | $errors["option_label[{$index}]"] = ts('Duplicate label value'); | |
459 | $_flagOption = 1; | |
460 | } | |
461 | } | |
462 | if ($form->_useForMember) { | |
463 | if (!empty($fields['membership_type_id'][$index])) { | |
464 | $memTypesIDS[] = $fields['membership_type_id'][$index]; | |
465 | } | |
466 | } | |
467 | ||
468 | // allow for 0 value. | |
469 | if (!empty($fields['option_amount'][$index]) || | |
470 | strlen($fields['option_amount'][$index]) > 0 | |
471 | ) { | |
472 | $noAmount = 0; | |
473 | } | |
474 | ||
475 | if (!empty($fields['option_weight'][$index])) { | |
476 | $noWeight = 0; | |
477 | $duplicateIndex = CRM_Utils_Array::key($fields['option_weight'][$index], | |
478 | $fields['option_weight'] | |
479 | ); | |
480 | ||
481 | if ((!($duplicateIndex === FALSE)) && | |
482 | (!($duplicateIndex == $index)) | |
483 | ) { | |
484 | $errors["option_weight[{$index}]"] = ts('Duplicate weight value'); | |
485 | $_flagOption = 1; | |
486 | } | |
487 | } | |
8cc574cf | 488 | if (!$noLabel && !$noAmount && !empty($fields['option_financial_type_id']) && $fields['option_financial_type_id'][$index] == '' && $fields['html_type'] != 'Text') { |
6a488035 | 489 | $errors["option_financial_type_id[{$index}]"] = ts('Financial Type is a Required field.'); |
366fe2a3 | 490 | } |
6a488035 TO |
491 | if ($noLabel && !$noAmount) { |
492 | $errors["option_label[{$index}]"] = ts('Label cannot be empty.'); | |
493 | $_flagOption = 1; | |
494 | } | |
495 | ||
496 | if (!$noLabel && $noAmount) { | |
497 | $errors["option_amount[{$index}]"] = ts('Amount cannot be empty.'); | |
498 | $_flagOption = 1; | |
499 | } | |
500 | ||
501 | if ($noLabel && $noAmount) { | |
502 | $countemptyrows++; | |
503 | $_emptyRow = 1; | |
504 | } | |
505 | elseif (!empty($fields['option_max_value'][$index]) && | |
506 | !empty($fields['option_count'][$index]) && | |
507 | ($fields['option_count'][$index] > $fields['option_max_value'][$index]) | |
508 | ) { | |
509 | $errors["option_max_value[{$index}]"] = ts('Participant count can not be greater than max participants.'); | |
510 | $_flagOption = 1; | |
511 | } | |
512 | ||
513 | $showBlocks = 'optionField_' . $index; | |
514 | if ($_flagOption) { | |
515 | $_showHide->addShow($showBlocks); | |
516 | $_rowError = 1; | |
517 | } | |
518 | ||
519 | if (!empty($_emptyRow)) { | |
520 | $_showHide->addHide($showBlocks); | |
521 | } | |
522 | else { | |
523 | $_showHide->addShow($showBlocks); | |
524 | } | |
525 | if ($index == self::NUM_OPTION) { | |
526 | $hideBlock = 'additionalOption'; | |
527 | $_showHide->addHide($hideBlock); | |
528 | } | |
529 | ||
a13c171d CR |
530 | if (!empty($fields['option_visibility_id'][$index]) && (!$noLabel || !$noAmount)) { |
531 | if ($visibilityOptions[$fields['option_visibility_id'][$index]] == 'public') { | |
532 | $publicOptionCount++; | |
533 | } | |
534 | } | |
535 | ||
6a488035 TO |
536 | $_flagOption = $_emptyRow = 0; |
537 | } | |
538 | ||
539 | if (!empty($memTypesIDS)) { | |
540 | // check for checkboxes allowing user to select multiple memberships from same membership organization | |
541 | if ($fields['html_type'] == 'CheckBox') { | |
ba1dcfda | 542 | $foundDuplicate = FALSE; |
be2fb01f | 543 | $orgIds = []; |
ba1dcfda | 544 | foreach ($memTypesIDS as $key => $val) { |
ea929c64 MW |
545 | $memTypeDetails = CRM_Member_BAO_MembershipType::getMembershipType($val); |
546 | if (in_array($memTypeDetails['member_of_contact_id'], $orgIds)) { | |
ba1dcfda TO |
547 | $foundDuplicate = TRUE; |
548 | break; | |
549 | } | |
ea929c64 | 550 | $orgIds[$val] = $memTypeDetails['member_of_contact_id']; |
6a488035 | 551 | |
ba1dcfda TO |
552 | } |
553 | if ($foundDuplicate) { | |
554 | $errors['_qf_default'] = ts('You have selected multiple memberships for the same organization or entity. Please review your selections and choose only one membership per entity.'); | |
555 | } | |
6a488035 | 556 | } |
366fe2a3 | 557 | |
6a488035 TO |
558 | // CRM-10390 - Only one price field in a set can include auto-renew membership options |
559 | $foundAutorenew = FALSE; | |
560 | foreach ($memTypesIDS as $key => $val) { | |
561 | // see if any price field option values in this price field are for memberships with autorenew | |
ea929c64 | 562 | $memTypeDetails = CRM_Member_BAO_MembershipType::getMembershipType($val); |
a7488080 | 563 | if (!empty($memTypeDetails['auto_renew'])) { |
6a488035 TO |
564 | $foundAutorenew = TRUE; |
565 | break; | |
566 | } | |
567 | } | |
568 | ||
569 | if ($foundAutorenew) { | |
570 | // if so, check for other fields in this price set which also have auto-renew membership options | |
9da8dc8c | 571 | $otherFieldAutorenew = CRM_Price_BAO_PriceSet::checkAutoRenewForPriceSet($form->_sid); |
6a488035 TO |
572 | if ($otherFieldAutorenew) { |
573 | $errors['_qf_default'] = ts('You can include auto-renew membership choices for only one price field in a price set. Another field in this set already contains one or more auto-renew membership options.'); | |
574 | } | |
575 | } | |
576 | } | |
577 | $_showHide->addToTemplate(); | |
578 | ||
831e0fa5 | 579 | if ($countemptyrows == 15) { |
6a488035 TO |
580 | $errors['option_label[1]'] = $errors['option_amount[1]'] = ts('Label and value cannot be empty.'); |
581 | $_flagOption = 1; | |
582 | } | |
a13c171d CR |
583 | |
584 | if ($visibilityOptions[$fields['visibility_id']] == 'public' && $publicOptionCount == 0) { | |
585 | $errors['visibility_id'] = ts('You have selected to make this field public but have not enabled any public price options. Please update your selections to include a public price option, or make this field admin visibility only.'); | |
586 | for ($index = 1; $index <= self::NUM_OPTION; $index++) { | |
587 | if (!empty($fields['option_label'][$index]) || !empty($fields['option_amount'][$index])) { | |
588 | $errors["option_visibility_id[{$index}]"] = ts('Public field should at least have one public option.'); | |
589 | } | |
590 | } | |
591 | } | |
592 | ||
593 | if ($visibilityOptions[$fields['visibility_id']] == 'admin' && $publicOptionCount > 0) { | |
594 | $errors['visibility_id'] = ts('Field with \'Admin\' visibility should only contain \'Admin\' options.'); | |
595 | ||
596 | for ($index = 1; $index <= self::NUM_OPTION; $index++) { | |
597 | ||
598 | $isOptionSet = !empty($fields['option_label'][$index]) || !empty($fields['option_amount'][$index]); | |
9c1bc317 | 599 | $currentOptionVisibility = $visibilityOptions[$fields['option_visibility_id'][$index]] ?? NULL; |
a13c171d CR |
600 | |
601 | if ($isOptionSet && $currentOptionVisibility == 'public') { | |
602 | $errors["option_visibility_id[{$index}]"] = ts('\'Admin\' field should only have \'Admin\' visibility options.'); | |
603 | } | |
604 | } | |
605 | } | |
6a488035 TO |
606 | } |
607 | elseif (!empty($fields['max_value']) && | |
608 | !empty($fields['count']) && | |
609 | ($fields['count'] > $fields['max_value']) | |
610 | ) { | |
611 | $errors['max_value'] = ts('Participant count can not be greater than max participants.'); | |
612 | } | |
613 | ||
614 | // do not process if no option rows were submitted | |
615 | if (empty($fields['option_amount']) && empty($fields['option_label'])) { | |
616 | return TRUE; | |
617 | } | |
618 | ||
619 | if (empty($fields['option_name'])) { | |
be2fb01f | 620 | $fields['option_amount'] = []; |
6a488035 TO |
621 | } |
622 | ||
623 | if (empty($fields['option_label'])) { | |
be2fb01f | 624 | $fields['option_label'] = []; |
6a488035 TO |
625 | } |
626 | } | |
627 | ||
628 | return empty($errors) ? TRUE : $errors; | |
629 | } | |
630 | ||
631 | /** | |
fe482240 | 632 | * Process the form. |
a72a9544 | 633 | * |
634 | * @throws \CRM_Core_Exception | |
431c56b2 | 635 | * @throws \CiviCRM_API3_Exception |
6a488035 TO |
636 | */ |
637 | public function postProcess() { | |
638 | // store the submitted values in an array | |
639 | $params = $this->controller->exportValues('Field'); | |
f961a8cd SL |
640 | $params['id'] = $this->getEntityId(); |
641 | $priceField = $this->submit($params); | |
642 | if (!is_a($priceField, 'CRM_Core_Error')) { | |
643 | // Required by extensions implementing the postProcess hook (to get the ID of new entities) | |
644 | $this->setEntityId($priceField->id); | |
645 | CRM_Core_Session::setStatus(ts('Price Field \'%1\' has been saved.', [1 => $priceField->label]), ts('Saved'), 'success'); | |
646 | } | |
647 | $buttonName = $this->controller->getButtonName(); | |
648 | $session = CRM_Core_Session::singleton(); | |
649 | if ($buttonName == $this->getButtonName('next', 'new')) { | |
650 | CRM_Core_Session::setStatus(ts(' You can add another price set field.'), '', 'info'); | |
651 | $session->replaceUserContext(CRM_Utils_System::url('civicrm/admin/price/field', 'reset=1&action=add&sid=' . $this->_sid)); | |
652 | } | |
653 | else { | |
654 | $session->replaceUserContext(CRM_Utils_System::url('civicrm/admin/price/field', 'reset=1&action=browse&sid=' . $this->_sid)); | |
655 | } | |
656 | } | |
657 | ||
658 | public function submit($params) { | |
431c56b2 | 659 | $params['price'] = CRM_Utils_Rule::cleanMoney($params['price']); |
09e6f541 | 660 | foreach ($params['option_amount'] as $key => $amount) { |
661 | $params['option_amount'][$key] = CRM_Utils_Rule::cleanMoney($amount); | |
662 | } | |
6a488035 | 663 | |
6a488035 TO |
664 | $params['is_display_amounts'] = CRM_Utils_Array::value('is_display_amounts', $params, FALSE); |
665 | $params['is_required'] = CRM_Utils_Array::value('is_required', $params, FALSE); | |
666 | $params['is_active'] = CRM_Utils_Array::value('is_active', $params, FALSE); | |
353ffa53 | 667 | $params['financial_type_id'] = CRM_Utils_Array::value('financial_type_id', $params, FALSE); |
6a488035 TO |
668 | $params['visibility_id'] = CRM_Utils_Array::value('visibility_id', $params, FALSE); |
669 | $params['count'] = CRM_Utils_Array::value('count', $params, FALSE); | |
670 | ||
671 | // need the FKEY - price set id | |
672 | $params['price_set_id'] = $this->_sid; | |
673 | ||
674 | if ($this->_action & (CRM_Core_Action::UPDATE | CRM_Core_Action::ADD)) { | |
be2fb01f | 675 | $fieldValues = ['price_set_id' => $this->_sid]; |
6a488035 | 676 | $oldWeight = NULL; |
44374cbe | 677 | if ($this->getEntityId()) { |
678 | $oldWeight = CRM_Core_DAO::getFieldValue('CRM_Price_DAO_PriceField', $this->getEntityId(), 'weight', 'id'); | |
6a488035 | 679 | } |
9da8dc8c | 680 | $params['weight'] = CRM_Utils_Weight::updateOtherWeights('CRM_Price_DAO_PriceField', $oldWeight, $params['weight'], $fieldValues); |
6a488035 TO |
681 | } |
682 | ||
683 | // make value <=> name consistency. | |
684 | if (isset($params['option_name'])) { | |
685 | $params['option_value'] = $params['option_name']; | |
686 | } | |
687 | $params['is_enter_qty'] = CRM_Utils_Array::value('is_enter_qty', $params, FALSE); | |
688 | ||
a72a9544 | 689 | if ($params['html_type'] === 'Text') { |
6a488035 TO |
690 | // if html type is Text, force is_enter_qty on |
691 | $params['is_enter_qty'] = 1; | |
692 | // modify params values as per the option group and option | |
693 | // value | |
be2fb01f CW |
694 | $params['option_amount'] = [1 => $params['price']]; |
695 | $params['option_label'] = [1 => $params['label']]; | |
696 | $params['option_count'] = [1 => $params['count']]; | |
697 | $params['option_max_value'] = [1 => CRM_Utils_Array::value('max_value', $params)]; | |
6a488035 | 698 | //$params['option_description'] = array( 1 => $params['description'] ); |
be2fb01f CW |
699 | $params['option_weight'] = [1 => $params['weight']]; |
700 | $params['option_financial_type_id'] = [1 => $params['financial_type_id']]; | |
701 | $params['option_visibility_id'] = [1 => CRM_Utils_Array::value('visibility_id', $params)]; | |
6a488035 TO |
702 | } |
703 | ||
6a488035 TO |
704 | $params['membership_num_terms'] = (!empty($params['membership_type_id'])) ? CRM_Utils_Array::value('membership_num_terms', $params, 1) : NULL; |
705 | ||
9da8dc8c | 706 | $priceField = CRM_Price_BAO_PriceField::create($params); |
f961a8cd | 707 | return $priceField; |
6a488035 | 708 | } |
96025800 | 709 | |
6a488035 | 710 | } |