Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
productgroupaction.php
1<?php
2
4
13
20{
21 private const FIELD_ID_PREFIX = 'product_';
22
23 private const FIELD_NAME_PREFIX = 'PRODUCT_';
24
25 private const PRODUCT_FIELD_NAME = 'PRODUCT_FIELD_NAME';
26
28 protected $catalogIncluded = null;
29
30 protected $catalogOptions = [];
31
33 protected $catalogConfig = null;
34
35 protected $productFieldHandlers = [];
36
37 public function __construct(array $options)
38 {
39 parent::__construct($options);
40
42 }
43
47 protected function initConfig()
48 {
49 parent::initConfig();
50
51 $this->catalogIncluded = Loader::includeModule('catalog');
52 if ($this->catalogIncluded)
53 {
54 $this->catalogConfig = \CCatalogSku::GetInfoByIBlock($this->iblockId);
55 if (empty($this->catalogConfig))
56 {
57 $this->catalogConfig = null;
58 }
59 $this->catalogOptions['SEPARATE_MODE'] = Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') === 'Y';
60 $this->catalogOptions['STORE_MODE'] = Catalog\Config\State::isUsedInventoryManagement();
61 }
62 }
63
67 public function getCatalogConfig(): ?array
68 {
70 }
71
75 public function getCatalogOptions(): array
76 {
78 }
79
83 protected function initProductFieldHandlers()
84 {
85 $this->productFieldHandlers = [
86 'WEIGHT' => 'Weight',
87 'QUANTITY_TRACE' => 'QuantityTrace',
88 'CAN_BUY_ZERO' => 'CanBuyZero',
89 'QUANTITY' => 'Quantity',
90 'PURCHASING_PRICE' => 'PurchasingPrice',
91 'VAT_INCLUDED' => 'VatIncluded',
92 'VAT_ID' => 'VatId',
93 'SUBSCRIBE' => 'Subscribe',
94 'MEASURE' => 'Measure'
95 ];
96 }
97
101 protected function getActionHandlers()
102 {
103 $result = parent::getActionHandlers();
104 $result[Catalog\Grid\ProductAction::SET_FIELD] = 'ProductField';
105 $result[Catalog\Grid\ProductAction::CHANGE_PRICE] = 'ProductChangePrice';
106 if (Main\Config\Option::get('catalog', 'enable_convert_product_to_service') === 'Y')
107 {
108 $result[Catalog\Grid\ProductAction::CONVERT_PRODUCT_TO_SERVICE] = 'ConvertProductToService';
109 $result[Catalog\Grid\ProductAction::CONVERT_SERVICE_TO_PRODUCT] = 'ConvertServiceToProduct';
110 }
111
112 return $result;
113 }
114
119 protected function actionProductFieldPanel(array $params = []): ?array
120 {
121 if (!$this->isAllowedProductActions())
122 return null;
123
124 $result = [];
125 $items = [];
126
127 if ($this->catalogConfig['CATALOG_TYPE'] !== \CCatalogSku::TYPE_PRODUCT)
128 {
129 foreach ($this->productFieldHandlers as $handler)
130 {
131 $handler = 'getProductField' . $handler . 'Row';
132 if (is_callable([$this, $handler]))
133 {
134 $row = call_user_func_array([$this, $handler], []);
135 if (!empty($row))
136 {
137 $items[] = $row;
138 }
139 }
140 }
141 unset($row, $handler);
142
143
144 }
145
146 $userFields = Catalog\Product\SystemField::getGroupActions($this);
147 if (!empty($userFields) && is_array($userFields))
148 {
149 $items = array_merge($items, $userFields);
150 }
151 unset($userFields);
152
153 if (!empty($items))
154 {
155 $name = (isset($params['NAME']) && $params['NAME'] != ''
156 ? $params['NAME']
157 : Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_SET_PRODUCT_FIELD')
158 );
159
160 $data = [];
161 $data[] = [
162 'TYPE' => Main\Grid\Panel\Types::DROPDOWN,
163 'ID' => $this->getFormProductFieldId(),
164 'NAME' => $this->getFormProductFieldName(),
165 'ITEMS' => $items
166 ];
167 if ($this->isUiGrid())
168 {
169 $data[] = $this->getApplyButtonWithConfirm([
170 'APPLY_BUTTON_ID' => 'send_product',
171 'CONFIRM_MESSAGE' => Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_SET_PRODUCT_FIELD_CONFIRM'),
172 ]);
173 }
174
175 $result = [
176 'name' => $name,
177 'type' => 'multicontrol',
178 'action' => [
179 [
180 'ACTION' => Main\Grid\Panel\Actions::RESET_CONTROLS
181 ],
182 [
183 'ACTION' => Main\Grid\Panel\Actions::CREATE,
184 'DATA' => $data
185 ]
186 ]
187 ];
188
189 unset($data);
190 }
191 unset($items);
192
193 return $result;
194 }
195
199 protected function actionProductFieldRequest(): ?array
200 {
201 $fieldId = $this->request->get($this->getFormProductFieldName());
202 if (empty($fieldId))
203 {
204 return null;
205 }
206
207 if (strncmp($fieldId, 'UF_', 3) === 0)
208 {
209 return Catalog\Product\SystemField::getGroupActionRequest($this, $fieldId);
210 }
211
212 if (!isset($this->productFieldHandlers[$fieldId]))
213 {
214 return null;
215 }
216
217 $handler = 'getProductField'.$this->productFieldHandlers[$fieldId].'Request';
218 if (is_callable([$this, $handler]))
219 {
220 return call_user_func_array([$this, $handler], []);
221 }
222
223 return null;
224 }
225
230 protected function actionProductChangePricePanel(array $params = []): ?array
231 {
232 if (!$this->isAllowedProductActions())
233 return null;
234
235 $name = (isset($params['NAME']) && $params['NAME'] != ''
236 ? $params['NAME']
237 : Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_PRODUCT_CHANGE_PRICE')
238 );
239
240 return [
241 'name' => $name,
242 'type' => 'customJs',
243 'js' => 'CreateDialogChPrice()'
244 ];
245 }
246
250 protected function actionProductChangePriceRequest(): ?array
251 {
252 $result = [];
253 $result['PRICE_TYPE'] = $this->request->get('chprice_id_price_type');
254 $result['UNITS'] = $this->request->get('chprice_units');
255 $result['FORMAT_RESULTS'] = $this->request->get('chprice_format_result');
256 $result['INITIAL_PRICE_TYPE'] = $this->request->get('chprice_initial_price_type');
257 $result['RESULT_MASK'] = $this->request->get('chprice_result_mask');
258 $result['DIFFERENCE_VALUE'] = $this->request->get('chprice_difference_value');
259 $result['VALUE_CHANGING'] = $this->request->get('chprice_value_changing_price');
260 return (!empty($result['VALUE_CHANGING']) ? $result : null);
261 }
262
263 protected function actionConvertProductToServicePanel(array $params = []): ?array
264 {
265 if (!$this->isAllowedProductActions())
266 {
267 return null;
268 }
269 if (!$this->isUiGrid())
270 {
271 return null;
272 }
273
274 $params['APPLY_BUTTON_ID'] = 'convert_product_to_service_confirm';
275 $params['CONFIRM_MESSAGE'] =
276 Catalog\Config\State::isUsedInventoryManagement()
277 ? Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_CONVERT_PRODUCT_TO_SERVICE_CONFIRM_WITH_INVENTORY')
278 : Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_CONVERT_PRODUCT_TO_SERVICE_CONFIRM_WITHOUT_INVENTORY')
279 ;
280
281 return [
282 'name' => (string)($params['NAME'] ?? Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_CONVERT_PRODUCT_TO_SERVICE')),
283 'type' => 'multicontrol',
284 'action' => [
285 [
286 'ACTION' => Main\Grid\Panel\Actions::RESET_CONTROLS
287 ],
288 [
289 'ACTION' => Main\Grid\Panel\Actions::CREATE,
290 'DATA' => [$this->getApplyButtonWithConfirm($params)]
291 ]
292 ]
293 ];
294 }
295
296 protected function actionConvertServiceToProductPanel(array $params = []): ?array
297 {
298 if (!$this->isAllowedProductActions())
299 {
300 return null;
301 }
302 if (!$this->isUiGrid())
303 {
304 return null;
305 }
306
307 $params['APPLY_BUTTON_ID'] = 'convert_service_to_product_confirm';
308 $params['CONFIRM_MESSAGE'] = Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_CONVERT_SERVICE_TO_PRODUCT_CONFIRM_MESSAGE_MSGVER_1');
309
310 return [
311 'name' => (string)($params['NAME'] ?? Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_CONVERT_SERVICE_TO_PRODUCT')),
312 'type' => 'multicontrol',
313 'action' => [
314 [
315 'ACTION' => Main\Grid\Panel\Actions::RESET_CONTROLS
316 ],
317 [
318 'ACTION' => Main\Grid\Panel\Actions::CREATE,
319 'DATA' => [$this->getApplyButtonWithConfirm($params)]
320 ]
321 ]
322 ];
323 }
324
328 public function getFormProductFieldName(): string
329 {
330 return self::PRODUCT_FIELD_NAME;
331 }
332
336 public function getFormProductFieldId(): string
337 {
338 return mb_strtolower($this->getFormProductFieldName().'_ID');
339 }
340
345 public function getFormRowFieldName(string $field): string
346 {
347 return self::FIELD_NAME_PREFIX.mb_strtoupper($field);
348 }
349
354 public function getFormRowFieldId(string $field): string
355 {
356 return self::FIELD_ID_PREFIX.mb_strtolower($field).'_id';
357 }
358
363 protected static function getStatusList(bool $defaultState): array
364 {
365 $result = [];
366
367 $result[] = [
368 'NAME' => Loc::getMessage(
369 'IBLOCK_GRID_PANEL_ACTION_MESS_STATUS_DEFAULT',
370 ['#VALUE#' => $defaultState
371 ? Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_MESS_STATUS_YES')
372 : Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_MESS_STATUS_NO')
373 ]
374 ),
375 'VALUE' => Catalog\ProductTable::STATUS_DEFAULT
376 ];
377 $result[] = [
378 'NAME' => Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_MESS_STATUS_YES'),
379 'VALUE' => Catalog\ProductTable::STATUS_YES
380 ];
381 $result[] = [
382 'NAME' => Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_MESS_STATUS_NO'),
383 'VALUE' => Catalog\ProductTable::STATUS_NO
384 ];
385
386 return $result;
387 }
388
392 protected static function getBinaryList(): array
393 {
394 $result = [];
395
396 $result[] = [
397 'NAME' => Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_MESS_STATUS_YES'),
398 'VALUE' => Catalog\ProductTable::STATUS_YES
399 ];
400 $result[] = [
401 'NAME' => Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_MESS_STATUS_NO'),
402 'VALUE' => Catalog\ProductTable::STATUS_NO
403 ];
404
405 return $result;
406 }
407
411 protected function isAllowedProductActions(): bool
412 {
413 if (!$this->catalogIncluded)
414 {
415 return false;
416 }
417 if (empty($this->catalogConfig))
418 {
419 return false;
420 }
421
422 return true;
423 }
424
431 protected function getInputField(string $fieldId): array
432 {
433 $entity = Catalog\ProductTable::getEntity();
434 $field = $entity->getField($fieldId);
435
436 $action = [];
437 $action[] = [
438 'ACTION' => Main\Grid\Panel\Actions::RESET_CONTROLS
439 ];
440 $action[] = [
441 'ACTION' => Main\Grid\Panel\Actions::CREATE,
442 'DATA' => [
443 [
444 'TYPE' => Main\Grid\Panel\Types::TEXT,
445 'ID' => $this->getFormRowFieldId($fieldId),
446 'NAME' => $this->getFormRowFieldName($fieldId),
447 'VALUE' => ''
448 ]
449 ]
450 ];
451 $result = [
452 'NAME' => $field->getTitle(),
453 'VALUE' => $fieldId,
454 'ONCHANGE' => $action
455 ];
456 unset($action);
457 unset($field, $entity);
458
459 return $result;
460 }
461
469 protected function getDropdownField(string $fieldId, array $list): ?array
470 {
471 $entity = Catalog\ProductTable::getEntity();
472 $field = $entity->getField($fieldId);
473
474 $action = [];
475 $action[] = [
476 'ACTION' => Main\Grid\Panel\Actions::RESET_CONTROLS
477 ];
478 $action[] = [
479 'ACTION' => Main\Grid\Panel\Actions::CREATE,
480 'DATA' => [
481 [
482 'TYPE' => Main\Grid\Panel\Types::DROPDOWN,
483 'ID' => $this->getFormRowFieldId($fieldId),
484 'NAME' => $this->getFormRowFieldName($fieldId),
485 'ITEMS' => $list
486 ],
487 ]
488 ];
489
490 $result = [
491 'NAME' => $field->getTitle(),
492 'VALUE' => $fieldId,
493 'ONCHANGE' => $action
494 ];
495 unset($action);
496 unset($field, $entity);
497
498 return $result;
499 }
500
504 protected function getProductFieldWeightRow(): ?array
505 {
506 if (!$this->isAllowedProductActions())
507 return null;
508
509 return $this->getInputField('WEIGHT');
510 }
511
515 protected function getProductFieldWeightRequest(): ?array
516 {
517 $result = $this->request->get($this->getFormRowFieldName('WEIGHT'));
518 $result = $this->checkFloatValue($result);
519 if ($result === null)
520 return null;
521 return ['WEIGHT' => $result];
522 }
523
527 protected function getProductFieldQuantityTraceRow(): ?array
528 {
529 if ($this->catalogOptions['STORE_MODE'])
530 return null;
531
532 return $this->getDropdownField(
533 'QUANTITY_TRACE',
534 $this->getStatusList(
535 Main\Config\Option::get('catalog', 'default_quantity_trace') === 'Y'
536 )
537 );
538 }
539
543 protected function getProductFieldQuantityTraceRequest(): ?array
544 {
545 $result = $this->request->get($this->getFormRowFieldName('QUANTITY_TRACE'));
546 if (!$this->checkStatusValue($result))
547 return null;
548 return ['QUANTITY_TRACE' => $result];
549 }
550
554 protected function getProductFieldCanBuyZeroRow(): ?array
555 {
556 if ($this->catalogOptions['STORE_MODE'])
557 return null;
558
559 return $this->getDropdownField(
560 'CAN_BUY_ZERO',
561 $this->getStatusList(
562 Main\Config\Option::get('catalog', 'default_can_buy_zero') === 'Y'
563 )
564 );
565 }
566
570 protected function getProductFieldCanBuyZeroRequest(): ?array
571 {
572 $result = $this->request->get($this->getFormRowFieldName('CAN_BUY_ZERO'));
573 if (!is_string($result))
574 return null;
575 if (!$this->checkStatusValue($result))
576 return null;
577 return ['CAN_BUY_ZERO' => $result];
578 }
579
583 protected function getProductFieldQuantityRow(): ?array
584 {
585 if ($this->catalogOptions['STORE_MODE'])
586 return null;
587
588 return $this->getInputField('QUANTITY');
589 }
590
594 protected function getProductFieldQuantityRequest(): ?array
595 {
596 $result = $this->request->get($this->getFormRowFieldName('QUANTITY'));
597 $result = $this->checkFloatValue($result);
598 if ($result === null)
599 return null;
600 return ['QUANTITY' => $result];
601 }
602
606 protected function getProductFieldPurchasingPriceRow(): ?array
607 {
608 if ($this->catalogOptions['STORE_MODE'])
609 return null;
610 if (!AccessController::getCurrent()->check(ActionDictionary::ACTION_PRODUCT_PURCHASE_INFO_VIEW))
611 {
612 return null;
613 }
614
615 $list = [];
616 foreach (Currency\CurrencyManager::getCurrencyList() as $currencyId => $currencyName)
617 {
618 $list[] = [
619 'VALUE' => $currencyId,
620 'NAME' => $currencyName
621 ];
622 }
623 if (empty($list))
624 return null;
625
626 $entity = Catalog\ProductTable::getEntity();
627 $field = $entity->getField('PURCHASING_PRICE');
628
629 $action = [];
630 $action[] = [
631 'ACTION' => Main\Grid\Panel\Actions::RESET_CONTROLS
632 ];
633 $action[] = [
634 'ACTION' => Main\Grid\Panel\Actions::CREATE,
635 'DATA' => [
636 [
637 'TYPE' => Main\Grid\Panel\Types::TEXT,
638 'ID' => $this->getFormRowFieldId('PURCHASING_PRICE'),
639 'NAME' => $this->getFormRowFieldName('PURCHASING_PRICE'),
640 'VALUE' => ''
641 ],
642 [
643 'TYPE' => Main\Grid\Panel\Types::DROPDOWN,
644 'ID' => $this->getFormRowFieldId('PURCHASING_CURRENCY'),
645 'NAME' => $this->getFormRowFieldName('PURCHASING_CURRENCY'),
646 'ITEMS' => $list
647 ]
648 ]
649 ];
650
651 $result = [
652 'NAME' => $field->getTitle(),
653 'VALUE' => 'PURCHASING_PRICE',
654 'ONCHANGE' => $action
655 ];
656 unset($action);
657 unset($field, $entity);
658
659 return $result;
660 }
661
665 protected function getProductFieldPurchasingPriceRequest(): ?array
666 {
667 $price = self::checkEmptyFloatValue($this->request->get($this->getFormRowFieldName('PURCHASING_PRICE')));
668 if ($price === null)
669 return null;
670 if ($price === '')
671 {
672 $price = null;
673 $currency = null;
674 }
675 else
676 {
677 $currency = $this->request->get($this->getFormRowFieldName('PURCHASING_CURRENCY'));
678 if (!is_string($currency))
679 return null;
680 $currency = trim($currency);
681 if ($currency === '')
682 return null;
683 }
684 return ['PURCHASING_PRICE' => $price, 'PURCHASING_CURRENCY' => $currency];
685 }
686
690 protected function getProductFieldVatIncludedRow(): ?array
691 {
692 return $this->getDropdownField(
693 'VAT_INCLUDED',
694 $this->getBinaryList()
695 );
696 }
697
701 protected function getProductFieldVatIncludedRequest(): ?array
702 {
703 $result = $this->request->get($this->getFormRowFieldName('VAT_INCLUDED'));
704 if (!$this->checkBinaryValue($result))
705 return null;
706 return ['VAT_INCLUDED' => $result];
707 }
708
712 protected function getProductFieldVatIdRow(): ?array
713 {
714 $list = [];
715 $list[] = [
716 'VALUE' => '0',
717 'NAME' => Loc::getMessage('IBLOCK_GRID_PANEL_ACTION_MESS_EMPTY_VALUE')
718 ];
719 $found = false;
720 $iterator = Catalog\VatTable::getList([
721 'select' => ['ID', 'NAME', 'SORT'],
722 'filter' => ['=ACTIVE' => 'Y'],
723 'order' => ['SORT' => 'ASC', 'ID' => 'ASC']
724 ]);
725 while ($row = $iterator->fetch())
726 {
727 $found = true;
728 $list[] = [
729 'VALUE' => $row['ID'],
730 'NAME' => $row['NAME']
731 ];
732 }
733 unset($row, $iterator);
734 if (!$found)
735 return null;
736
737 return $this->getDropdownField(
738 'VAT_ID',
739 $list
740 );
741 }
742
746 protected function getProductFieldVatIdRequest(): ?array
747 {
748 $result = $this->checkIntValue($this->request->get($this->getFormRowFieldName('VAT_ID')));
749 if ($result === null || $result < 0)
750 return null;
751 return ['VAT_ID' => $result];
752 }
753
757 protected function getProductFieldSubscribeRow(): ?array
758 {
759 return $this->getDropdownField(
760 'SUBSCRIBE',
761 $this->getStatusList(
762 Main\Config\Option::get('catalog', 'default_subscribe') === 'Y'
763 )
764 );
765 }
766
770 protected function getProductFieldSubscribeRequest(): ?array
771 {
772 $result = $this->request->get($this->getFormRowFieldName('SUBSCRIBE'));
773 if (!is_string($result))
774 return null;
775 if (!$this->checkStatusValue($result))
776 return null;
777 return ['SUBSCRIBE' => $result];
778 }
779
783 protected function getProductFieldMeasureRow(): ?array
784 {
785 $list = [];
786 $iterator = \CCatalogMeasure::getList(
787 array(),
788 array(),
789 false,
790 false,
791 array('ID', 'CODE', 'MEASURE_TITLE', 'SYMBOL_INTL')
792 );
793 while($row = $iterator->Fetch())
794 {
795 $list[] = [
796 'VALUE' => $row['ID'],
797 'NAME' => $row['MEASURE_TITLE']
798 ];
799 }
800 unset($row, $iterator);
801 if (empty($list))
802 return null;
803
804 return $this->getDropdownField(
805 'MEASURE',
806 $list
807 );
808 }
809
813 protected function getProductFieldMeasureRequest(): ?array
814 {
815 $result = $this->checkIntValue($this->request->get($this->getFormRowFieldName('MEASURE')));
816 if ($result === null || $result <= 0)
817 return null;
818 return ['MEASURE' => $result];
819 }
820
828 protected static function checkFloatValue($value): ?float
829 {
830 if (is_array($value) || $value === null)
831 return null;
832 $value = (str_replace([',', ' '], ['.', ''], trim($value)));
833 if ($value === '')
834 return null;
835 $value = (float)$value;
836 return (is_finite($value) ? $value : null);
837 }
838
846 protected static function checkEmptyFloatValue($value)
847 {
848 if (is_array($value) || $value === null)
849 return null;
850 $value = trim($value);
851 if ($value === '')
852 return '';
853 $value = (float)(str_replace(',', '.', $value));
854 return (is_finite($value) ? $value : null);
855 }
856
861 protected static function checkStatusValue($value): bool
862 {
863 return (
864 $value === Catalog\ProductTable::STATUS_DEFAULT
865 || $value === Catalog\ProductTable::STATUS_YES
866 || $value === Catalog\ProductTable::STATUS_NO
867 );
868 }
869
874 protected static function checkBinaryValue($value): bool
875 {
876 return (
877 $value === Catalog\ProductTable::STATUS_YES
878 || $value === Catalog\ProductTable::STATUS_NO
879 );
880 }
881
889 protected static function checkIntValue($value): ?int
890 {
891 if (is_array($value) || $value === null)
892 {
893 return null;
894 }
895 if (((int)$value).'|' !== $value.'|')
896 {
897 return null;
898 }
899
900 return (int)$value;
901 }
902}
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29