1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
admin_tools.php
См. документацию.
1<?php
2
13
21
23{
24 public const TAB_PRODUCT = 'F';
25 public const TAB_CATALOG = 'P';
26 public const TAB_SKU = 'O';
27 public const TAB_SET = 'S';
28 public const TAB_GROUP = 'G';
29 public const TAB_SERVICE = 'B';
30
31 protected const TAB_KEY = 'PRODUCT_TYPE';
32
33 protected const DELETE_SET = 'setdel';
34 protected const DELETE_GROUP = 'groupdel';
35
36 protected static string $strMainPrefix = '';
37 protected static array $arErrors = [];
38 protected static array $arCheckResult = [];
39
40 public static function getTabList(bool $boolFull = false): array
41 {
42 if ($boolFull)
43 {
44 return [
45 self::TAB_PRODUCT => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_PRODUCT'),
46 self::TAB_CATALOG => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_CATALOG'),
47 self::TAB_SKU => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_SKU'),
48 self::TAB_SET => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_SET'),
49 self::TAB_GROUP => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_GROUP_MSGVER_1'),
50 self::TAB_SERVICE => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_SERVICE'),
51 ];
52 }
53
54 return [
55 self::TAB_PRODUCT,
56 self::TAB_CATALOG,
57 self::TAB_SKU,
58 self::TAB_SET,
59 self::TAB_GROUP,
60 self::TAB_SERVICE,
61 ];
62 }
63
64 public static function getTabDescriptions(): array
65 {
66 return [
67 self::TAB_PRODUCT => [
68 'NAME' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_PRODUCT'),
69 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_TITLE_PRODUCT'),
70 ],
71 self::TAB_CATALOG => [
72 'NAME' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_CATALOG'),
73 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_CATALOG'),
74 ],
75 self::TAB_SKU => [
76 'NAME' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_SKU'),
77 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_SKU'),
78 ],
79 self::TAB_SET => [
80 'NAME' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_SET'),
81 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_SET'),
82 ],
83 self::TAB_GROUP => [
84 'NAME' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_GROUP_MSGVER_1'),
85 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_GROUP_MSGVER_1'),
86 ],
87 self::TAB_SERVICE => [
88 'NAME' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_SERVICE'),
89 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_TAB_SERVICE'),
90 ],
91 ];
92 }
93
94 public static function getCurrentTabFromRequest(): ?string
95 {
96 $tabList = array_fill_keys(self::getTabList(), true);
97 if (!Catalog\Config\Feature::isProductSetsEnabled())
98 {
99 unset($tabList[self::TAB_SET]);
100 unset($tabList[self::TAB_GROUP]);
101 }
102
103 $request = Context::getCurrent()->getRequest();
104 $result = $request->get(self::$strMainPrefix . self::TAB_KEY);
105 if (!is_string($result))
106 {
107 return null;
108 }
109 if (!isset($tabList[$result]))
110 {
111 return null;
112 }
113
114 return $result;
115 }
116
122 public static function getIblockElementMenuLocked(): array
123 {
124 return [
125 [
126 'ID' => 'create_new_product_button_access_denied', // used in BX.Catalog.IblockProductList
127 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_PROD_EXT'),
128 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_PROD_EXT'),
129 'ONCLICK' => 'javascript:;',
130 ],
131 ];
132 }
133
134 public static function getIBlockElementMenu(
136 &$arCatalog,
137 $arParams,
138 BaseBuilder $urlBuilder = null,
139 $gridId = ''
140 )
141 {
142 $arResult = false;
144 if ($intIBlockID <= 0)
145 return false;
146
147 if (empty($arCatalog))
148 $arCatalog = CCatalogSku::GetInfoByIBlock($intIBlockID);
149 if (empty($arCatalog))
150 return false;
151
152 if (empty($arParams) || !is_array($arParams))
153 return false;
154
155 if ($urlBuilder === null)
156 {
157 $urlBuilder = BuilderManager::getInstance()->getBuilder(BaseBuilder::TYPE_AUTODETECT);
158 }
159 if ($urlBuilder === null)
160 {
161 return false;
162 }
163
164 $urlBuilder->setIblockId($intIBlockID);
165 $urlBuilder->setUrlParams([]);
166
167 $productCardEnabled = false;
168 $builderId = $urlBuilder->getId();
169 $publicShop = !(
171 || $builderId === Catalog\Url\AdminPage\CatalogBuilder::TYPE_ID
172 );
173 if ($publicShop)
174 {
175 // TODO: need fix this hack
176 if ($builderId === 'CRM')
177 {
178 if (Loader::includeModule('crm'))
179 {
180 $productCardEnabled = \Bitrix\Crm\Settings\LayoutSettings::getCurrent()->isFullCatalogEnabled();
181 }
182 }
183 else
184 {
186 }
187 }
188
189 $arItems = array();
190
191 $sectionId = $arParams['find_section_section'] ?? null;
192 if ($sectionId !== null)
193 {
194 $sectionId = (int)$sectionId;
195 if ($sectionId <= 0)
196 {
197 $sectionId = null;
198 }
199 }
201 if (!empty($productLimits))
202 {
203 if (!empty($productLimits['HELP_MESSAGE']))
204 {
205 $arItems[] = [
206 'ICON' => 'btn_lock',
207 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_PROD_EXT_2'),
208 $productLimits['HELP_MESSAGE']['TYPE'] => $productLimits['HELP_MESSAGE']['LINK'],
209 ];
210 }
211 }
212 else
213 {
214 // TODO: remove this hack after refactoring \CAdminUiList::AddAdminContextMenu
215 $publicFlag = $productCardEnabled
216 || $builderId === Catalog\Url\InventoryBuilder::TYPE_ID // hack for inventory documents
217 ;
218
219 $serviceItem = null;
220 if (
221 $arCatalog['SUBSCRIPTION'] === 'N'
222 && (
223 $arCatalog['CATALOG_TYPE'] === CCatalogSku::TYPE_CATALOG
224 || $arCatalog['CATALOG_TYPE'] === CCatalogSku::TYPE_FULL
225 )
226 )
227 {
228 if (Catalog\Config\Feature::isCatalogServicesEnabled())
229 {
230 $serviceItem = [
231 'TEXT' => Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_SERVICE'),
232 'PUBLIC' => $publicFlag, // TODO: remove this hack after refactoring \CAdminUiList::AddAdminContextMenu
233 ];
234 if ($productCardEnabled)
235 {
236 $detailUrlParams = array_merge(
237 $arParams,
238 [
239 'productTypeId' => Catalog\ProductTable::TYPE_SERVICE,
240 ]
241 );
242 }
243 else
244 {
245 $detailUrlParams = self::getParamsWithTab($arParams, self::TAB_SERVICE);
246 }
247 $serviceItem['LINK'] = $urlBuilder->getElementDetailUrl(
248 0,
249 $detailUrlParams
250 );
251 unset($detailUrlParams);
252 }
253 else
254 {
256 if (!empty($helpLink))
257 {
258 $serviceItem = [
259 'ICON' => 'btn_lock',
260 'TEXT' => Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_SERVICE'),
261 $helpLink['TYPE'] => $helpLink['LINK'],
262 ];
263 }
264 unset($helpLink);
265 }
266 }
267
268 if ($arCatalog['CATALOG'] == 'Y')
269 {
270 if ($productCardEnabled)
271 {
272 $additionalParams = [];
273 if ($arCatalog['CATALOG_TYPE'] === CCatalogSku::TYPE_CATALOG)
274 {
275 $additionalParams = [
276 'productTypeId' => Catalog\ProductTable::TYPE_PRODUCT,
277 ];
278 }
279 elseif ($arCatalog['CATALOG_TYPE'] === CCatalogSku::TYPE_FULL)
280 {
281 $additionalParams = [
282 'productTypeId' => Catalog\ProductTable::TYPE_SKU,
283 ];
284 }
285 $detailUrlParams = array_merge(
286 $arParams,
287 $additionalParams
288 );
289 }
290 else
291 {
292 $detailUrlParams = self::getParamsWithTab($arParams, self::TAB_CATALOG);
293 }
294 if (!isset($arParams['from']) || $arParams['from'] !== 'iblock_section_admin')
295 {
296 $arItems[] = array(
297 'ICON' => 'btn_new',
298 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_PROD_EXT_2'),
299 'ID' => 'create_new_product_button_' . $gridId,
300 'LINK' => $urlBuilder->getElementDetailUrl(
301 0,
302 $detailUrlParams
303 ),
304 'PUBLIC' => $publicFlag, // TODO: remove this hack after refactoring \CAdminUiList::AddAdminContextMenu
305 );
306
307 $arItems[] = array(
308 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_PRODUCT'),
309 'LINK' => $urlBuilder->getElementDetailUrl(
310 0,
311 self::getParamsWithTab($arParams, self::TAB_CATALOG)
312 ),
313 'PUBLIC' => $publicFlag, // TODO: remove this hack after refactoring \CAdminUiList::AddAdminContextMenu
314 );
315 }
316 else
317 {
318 $arItems[] = array(
319 'ICON' => 'btn_new',
320 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_PRODUCT'),
321 'ID' => 'create_new_product_button_' . $gridId,
322 'LINK' => $urlBuilder->getElementDetailUrl(
323 0,
324 $detailUrlParams
325 ),
326 'PUBLIC' => $publicFlag, // TODO: remove this hack after refactoring \CAdminUiList::AddAdminContextMenu
327 );
328 }
329
330 if (!$productCardEnabled)
331 {
332 if (CCatalogSku::TYPE_FULL == $arCatalog['CATALOG_TYPE'])
333 {
334 $arItems[] = array(
335 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_SKU_2'),
336 'LINK' => $urlBuilder->getElementDetailUrl(
337 0,
338 self::getParamsWithTab($arParams, self::TAB_SKU)
339 ),
340 'PUBLIC' => $publicFlag, // TODO: remove this hack after refactoring \CAdminUiList::AddAdminContextMenu
341 );
342 }
343 if ($serviceItem !== null)
344 {
345 $arItems[] = $serviceItem;
346 }
347 if (Catalog\Config\Feature::isProductSetsEnabled())
348 {
349 if (CCatalogSku::TYPE_OFFERS != $arCatalog['CATALOG_TYPE'])
350 {
351 $arItems[] = array(
352 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_SET_MSGVER_2'),
353 'LINK' => $urlBuilder->getElementDetailUrl(
354 0,
355 self::getParamsWithTab($arParams, self::TAB_SET)
356 ),
357 'PUBLIC' => $publicFlag, // TODO: remove this hack after refactoring \CAdminUiList::AddAdminContextMenu
358 );
359 }
360 $arItems[] = array(
361 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_GROUP_MSGVER_1'),
362 'LINK' => $urlBuilder->getElementDetailUrl(
363 0,
364 self::getParamsWithTab($arParams, self::TAB_GROUP)
365 ),
366 'PUBLIC' => $publicFlag, // TODO: remove this hack after refactoring \CAdminUiList::AddAdminContextMenu
367 );
368 }
369 else
370 {
372 if (!empty($helpLink))
373 {
374 if (CCatalogSku::TYPE_OFFERS != $arCatalog['CATALOG_TYPE'])
375 {
376 $arItems[] = [
377 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_SET_MSGVER_2'),
378 $helpLink['TYPE'] => $helpLink['LINK'],
379 'ICON' => 'btn_lock',
380 ];
381 }
382 $arItems[] = [
383 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_GROUP_MSGVER_1'),
384 $helpLink['TYPE'] => $helpLink['LINK'],
385 'ICON' => 'btn_lock',
386 ];
387 }
388 }
389 }
390 else
391 {
392 if ($serviceItem !== null)
393 {
394 $arItems[] = $serviceItem;
395 }
396 }
397 }
398 else
399 {
400 $arItems[] = array(
401 'ICON' => 'btn_new',
402 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_SKU'),
403 'ID' => 'create_new_product_button_' . $gridId,
404 'LINK' => $urlBuilder->getElementDetailUrl(
405 0,
406 self::getParamsWithTab($arParams, self::TAB_SKU)
407 ),
408 'PUBLIC' => $publicFlag, // TODO: remove this hack after refactoring \CAdminUiList::AddAdminContextMenu
409 );
410 }
411
412 }
413 unset($productLimits);
414
415 if (!empty($arItems))
416 {
417 $arResult = $arItems;
418 }
419
420 return $arResult;
421 }
422
423 private static function getParamsWithTab(array $params, string $tab): array
424 {
425 $params[self::$strMainPrefix . self::TAB_KEY] = $tab;
426
427 return $params;
428 }
429
430 private static function getDeleteAction(array $fields, string $action): array
431 {
432 $fields[$action] = 'Y';
433
434 return $fields;
435 }
436
437 public static function getIBlockElementContentMenu(
439 $intID,
440 &$arCatalog,
441 $arParams,
442 BaseBuilder $urlBuilder = null
443 )
444 {
445 $arResult = false;
446
448 $intID = (int)$intID;
449 if ($intIBlockID <= 0 || $intID <= 0)
450 return false;
451 if (empty($arCatalog))
452 $arCatalog = CCatalogSku::GetInfoByIBlock($intIBlockID);
453 if (empty($arCatalog))
454 return false;
455 if ($arCatalog['CATALOG'] != 'Y')
456 return false;
457
458 if (empty($arParams) || !is_array($arParams))
459 $arParams = array();
460
461 if ($urlBuilder === null)
462 {
463 $urlBuilder = BuilderManager::getInstance()->getBuilder(BaseBuilder::TYPE_AUTODETECT);
464 }
465 if ($urlBuilder === null)
466 {
467 return false;
468 }
469 $urlBuilder->setIblockId($intIBlockID);
470 $urlBuilder->setUrlParams([]);
471
472 $allowedProductTypes = static::getIblockProductTypeList($intIBlockID, true);
473
475
476 $intProductID = CIBlockElement::GetRealElement($intID);
477
478 $currentTab = self::getCurrentTabFromRequest();
479
480 $productType = self::getProductTypeForNewProduct($arCatalog);
481 $boolExistSet = false;
482 $boolExistGroup = false;
483 $existInSet = false;
485 'select' => [
486 'ID',
487 'TYPE',
488 'BUNDLE',
489 ],
490 'filter' => [
491 '=ID' => $intProductID,
492 ],
493 ]);
494 if ($product !== null)
495 {
496 $productType = (int)$product['TYPE'];
497 $boolExistSet = $productType === Catalog\ProductTable::TYPE_SET;
498 $boolExistGroup = $product['BUNDLE'] === Catalog\ProductTable::STATUS_YES;
499 }
500 if (!$boolExistSet)
501 {
503 }
504
505 $arItems = array();
506
507 if (!$existInSet)
508 {
509 if (
510 isset($allowedProductTypes[Catalog\ProductTable::TYPE_PRODUCT])
511 )
512 {
513 $row = [
514 'ICON' => '',
515 'TEXT' => $allowedProductTypes[Catalog\ProductTable::TYPE_PRODUCT],
516 ];
517 if (
518 $productType === Catalog\ProductTable::TYPE_SET
519 && $currentTab === null
520 )
521 {
522 $row['ACTION'] = "if(confirm('"
523 . CUtil::JSEscape(Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_SET_DELETE_CONFIRM'))
524 . "'))"
525 . "window.location='"
526 . $urlBuilder->getElementDetailUrl(
527 $intID,
528 self::getParamsWithTab(
529 self::getDeleteAction($arParams, self::DELETE_SET),
530 self::TAB_CATALOG
531 ),
532 '&' . bitrix_sessid_get()
533 )
534 . "';"
535 ;
536 }
537 elseif (
538 $productType === Catalog\ProductTable::TYPE_SKU
539 && $currentTab === null
540 )
541 {
542 $row['TITLE'] = Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_CATALOG_FROM_SKU');
543 $row['SHOW_TITLE'] = true;
544 $row['DISABLED'] = true;
545 }
546 elseif (
547 (
548 $productType === Catalog\ProductTable::TYPE_PRODUCT
549 && $currentTab === null
550 )
551 || $currentTab === self::TAB_CATALOG
552 )
553 {
554 $row['CHECKED'] = true;
555 }
556 else
557 {
558 $row['LINK'] = $urlBuilder->getElementDetailUrl(
559 $intID,
560 self::getParamsWithTab($arParams, self::TAB_CATALOG)
561 );
562 }
563 $arItems[] = $row;
564 unset($row);
565 }
566
567 if (
568 isset($allowedProductTypes[Catalog\ProductTable::TYPE_SKU])
569 || isset($allowedProductTypes[Catalog\ProductTable::TYPE_EMPTY_SKU])
570 )
571 {
572 if ($productType === Catalog\ProductTable::TYPE_EMPTY_SKU)
573 {
574 $row = [
575 'ICON' => '',
576 'TEXT' => $allowedProductTypes[Catalog\ProductTable::TYPE_EMPTY_SKU],
577 ];
578 if (
579 $currentTab === null
580 || $currentTab === self::TAB_SKU
581 )
582 {
583 $row['CHECKED'] = true;
584 }
585 else
586 {
587 $row['LINK'] = $urlBuilder->getElementDetailUrl(
588 $intID,
589 self::getParamsWithTab($arParams, self::TAB_SKU)
590 );
591 }
592 }
593 else
594 {
595 $row = [
596 'ICON' => '',
597 'TEXT' => $allowedProductTypes[Catalog\ProductTable::TYPE_SKU],
598 ];
599 if (
600 (
601 $productType === Catalog\ProductTable::TYPE_PRODUCT
602 && $currentTab === null
603 )
604 || $currentTab === self::TAB_CATALOG
605 || $currentTab === self::TAB_SET
606 )
607 {
608 $row['LINK'] = $urlBuilder->getElementDetailUrl(
609 $intID,
610 self::getParamsWithTab($arParams, self::TAB_SKU)
611 );
612 }
613 elseif (
614 $productType === Catalog\ProductTable::TYPE_SET
615 && $currentTab === null
616 )
617 {
618 $row['ACTION'] = "if(confirm('"
619 . CUtil::JSEscape(Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_SET_DELETE_CONFIRM'))
620 . "'))"
621 . "window.location='"
622 . $urlBuilder->getElementDetailUrl(
623 $intID,
624 self::getParamsWithTab(
625 self::getDeleteAction($arParams, self::DELETE_SET),
626 self::TAB_SKU
627 ),
628 '&' . bitrix_sessid_get()
629 )
630 . "';"
631 ;
632 }
633 elseif (
634 $productType === Catalog\ProductTable::TYPE_SKU
635 || $currentTab === self::TAB_SKU
636 )
637 {
638 $row['CHECKED'] = true;
639 }
640 }
641 $arItems[] = $row;
642 unset($row);
643 }
644
645 if (isset($allowedProductTypes[Catalog\ProductTable::TYPE_SERVICE]))
646 {
647 $row = [
648 'ICON' => '',
649 'TEXT' => $allowedProductTypes[Catalog\ProductTable::TYPE_SERVICE],
650 ];
651 if (
652 (
653 $productType === Catalog\ProductTable::TYPE_PRODUCT
654 && $currentTab === null
655 )
656 || $currentTab === self::TAB_CATALOG
657 )
658 {
659 $row['LINK'] = $urlBuilder->getElementDetailUrl(
660 $intID,
661 self::getParamsWithTab($arParams, self::TAB_SERVICE)
662 );
663 }
664 if (
665 $productType === Catalog\ProductTable::TYPE_SET
666 && $currentTab === null
667 )
668 {
669 $row['ACTION'] = "if(confirm('"
670 . CUtil::JSEscape(Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_SET_DELETE_CONFIRM'))
671 . "'))"
672 . "window.location='"
673 . $urlBuilder->getElementDetailUrl(
674 $intID,
675 self::getParamsWithTab(
676 self::getDeleteAction($arParams, self::DELETE_SET),
677 self::TAB_SERVICE
678 ),
679 '&' . bitrix_sessid_get()
680 )
681 . "';"
682 ;
683 }
684 elseif (
685 $productType === Catalog\ProductTable::TYPE_SKU
686 && $currentTab === null
687 )
688 {
689 $row['TITLE'] = Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_SERVICE_FROM_SKU');
690 $row['SHOW_TITLE'] = true;
691 $row['DISABLED'] = true;
692 }
693 elseif (
694 (
695 $productType === Catalog\ProductTable::TYPE_SERVICE
696 && $currentTab === null
697 )
698 || $currentTab === self::TAB_SERVICE
699 )
700 {
701 $row['CHECKED'] = true;
702 }
703 else
704 {
705 $row['LINK'] = $urlBuilder->getElementDetailUrl(
706 $intID,
707 self::getParamsWithTab($arParams, self::TAB_SERVICE)
708 );
709 }
710 $arItems[] = $row;
711 unset($row);
712 }
713
714 if (
715 isset($allowedProductTypes[Catalog\ProductTable::TYPE_SET])
716 )
717 {
718 $row = [
719 'ICON' => '',
720 'TEXT' => $allowedProductTypes[Catalog\ProductTable::TYPE_SET],
721 ];
722 if (
723 (
724 $productType === Catalog\ProductTable::TYPE_PRODUCT
725 && $currentTab === null
726 )
727 || $currentTab === self::TAB_CATALOG
728 )
729 {
730 $row['LINK'] = $urlBuilder->getElementDetailUrl(
731 $intID,
732 self::getParamsWithTab($arParams, self::TAB_SET)
733 );
734 }
735 elseif (
736 $productType === Catalog\ProductTable::TYPE_SKU
737 && $currentTab === null
738 )
739 {
740 $row['TITLE'] = Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_SET_FROM_SKU');
741 $row['SHOW_TITLE'] = true;
742 $row['DISABLED'] = true;
743 }
744 elseif (
745 $productType === Catalog\ProductTable::TYPE_SET
746 || $currentTab === self::TAB_SET
747 )
748 {
749 $row['CHECKED'] = true;
750 }
751 else
752 {
753 $row['LINK'] = $urlBuilder->getElementDetailUrl(
754 $intID,
755 self::getParamsWithTab($arParams, self::TAB_SET)
756 );
757 }
758 $arItems[] = $row;
759 unset($row);
760 }
761 }
762
763 if (!$boolFeatureSet && CCatalogSku::TYPE_FULL !== $arCatalog['CATALOG_TYPE'])
764 {
765 $arItems = [];
766 }
767 //group
768 if ($boolFeatureSet && $currentTab !== self::TAB_GROUP)
769 {
770 if (
772 && $productType !== Catalog\ProductTable::TYPE_FREE_OFFER
773 )
774 {
775 if (!empty($arItems))
776 {
777 $arItems[] = ['SEPARATOR' => 'Y'];
778 }
779
780 if ($currentTab === null)
781 {
782 if (!$boolExistGroup)
783 {
784 $arItems[] = [
785 'ICON' => '',
786 'TEXT' => Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_GROUP_ADD'),
787 'LINK' => $urlBuilder->getElementDetailUrl(
788 $intID,
789 self::getParamsWithTab($arParams, self::TAB_GROUP)
790 ),
791 ];
792 }
793 else
794 {
795 $arItems[] = [
796 'ICON' => 'delete',
797 'TEXT' => Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_GROUP_DELETE'),
798 'ACTION' => "if(confirm('"
799 . CUtil::JSEscape(Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_GROUP_DELETE_CONFIRM'))
800 . "'))window.location='"
801 . $urlBuilder->getElementDetailUrl(
802 $intID,
803 self::getDeleteAction($arParams, self::DELETE_GROUP),
804 '&' . bitrix_sessid_get()
805 )
806 . "';",
807 ];
808 }
809 }
810 else
811 {
812 if ($boolExistGroup)
813 {
814 $arItems[] = [
815 'ICON' => 'delete',
816 'TEXT' => Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_GROUP_DELETE'),
817 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_DELETE_GROUP_LOCKED'),
818 'SHOW_TITLE' => true,
819 'DISABLED' => true,
820 ];
821 }
822 }
823 }
824 }
825
826 if (!empty($arItems))
827 {
828 $arResult = [
829 'TEXT' => Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_SELECTOR'),
830 'TITLE' => Loc::getMessage('BT_CAT_SET_PRODUCT_TYPE_SELECTOR_TITLE'),
831 'MENU' => $arItems
832 ];
833 }
834
835 return $arResult;
836 }
837
838 public static function getShowTabs($intIBlockID, $intID, &$arCatalog)
839 {
841 if ($intIBlockID <= 0)
842 return false;
843
844 if (empty($arCatalog))
845 $arCatalog = CCatalogSku::GetInfoByIBlock($intIBlockID);
846 if (empty($arCatalog))
847 return false;
848
849 $arResult = array_fill_keys(self::getTabList(), false);
850 $currentTab = self::getCurrentTabFromRequest();
851
852 if ($intID > 0)
853 {
854 $intProductID = CIBlockElement::GetRealElement($intID);
855 $productType = 0;
856 $haveBundle = false;
858 'select' => [
859 'ID',
860 'TYPE',
861 'BUNDLE',
862 ],
863 'filter' => [
864 '=ID' => $intProductID,
865 ],
866 ]);
867 if ($product !== null)
868 {
869 $productType = (int)$product['TYPE'];
870 $haveBundle = $product['BUNDLE'] === 'Y';
871 }
872 $arResult[self::TAB_CATALOG] = (
873 CCatalogSku::TYPE_CATALOG == $arCatalog['CATALOG_TYPE']
874 || CCatalogSku::TYPE_FULL == $arCatalog['CATALOG_TYPE']
875 || CCatalogSku::TYPE_OFFERS == $arCatalog['CATALOG_TYPE']
876 );
877 if ($productType === Catalog\ProductTable::TYPE_EMPTY_SKU)
878 {
879 $arResult[self::TAB_CATALOG] = false;
880 }
881 $arResult[self::TAB_SKU] = (
882 CCatalogSku::TYPE_PRODUCT == $arCatalog['CATALOG_TYPE']
883 || CCatalogSku::TYPE_FULL == $arCatalog['CATALOG_TYPE']
884 );
885 if (CCatalogSku::TYPE_FULL == $arCatalog['CATALOG_TYPE'])
886 {
887 if (
888 $productType === Catalog\ProductTable::TYPE_SKU
889 || $currentTab === self::TAB_SKU
890 )
891 {
892 if (Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') !== 'Y')
893 {
894 $arResult[self::TAB_CATALOG] = false;
895 }
896 }
897 else
898 {
899 if ($productType !== Catalog\ProductTable::TYPE_EMPTY_SKU)
900 {
901 $arResult[self::TAB_SKU] = false;
902 }
903 }
904 }
905 if (CCatalogSku::TYPE_PRODUCT != $arCatalog['CATALOG_TYPE'])
906 {
907 if (Catalog\Config\Feature::isProductSetsEnabled())
908 {
909 if (CCatalogSku::TYPE_OFFERS != $arCatalog['CATALOG_TYPE'])
910 {
911 $arResult[self::TAB_SET] = (
912 $productType === Catalog\ProductTable::TYPE_SET
913 || $currentTab === self::TAB_SET
914 );
915 }
916 $arResult[self::TAB_GROUP] = (
917 $haveBundle
918 || $currentTab === self::TAB_GROUP
919 );
920 if ($arResult[self::TAB_SET])
921 {
922 $arResult[self::TAB_CATALOG] = true;
923 $arResult[self::TAB_SKU] = false;
924 }
925 }
926 }
927 }
928 else
929 {
930 if ($currentTab !== null)
931 {
932 if (CCatalogSku::TYPE_OFFERS == $arCatalog['CATALOG_TYPE'])
933 {
934 if (
935 $currentTab === self::TAB_SET
936 || $currentTab === self::TAB_SKU
937 || $currentTab === self::TAB_SERVICE
938 )
939 {
940 $currentTab = null;
941 }
942 }
943 }
944 if ($currentTab !== null)
945 {
946 $arResult[$currentTab] = true;
947 if ($currentTab === self::TAB_GROUP || $currentTab === self::TAB_SET)
948 {
949 $arResult[self::TAB_CATALOG] = true;
950 }
951 if (
952 $currentTab === self::TAB_SKU
953 && $arCatalog['CATALOG'] === 'Y'
954 && Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') === 'Y'
955 )
956 {
957 $arResult[self::TAB_CATALOG] = true;
958 }
959 if ($currentTab === self::TAB_SERVICE)
960 {
961 $arResult[$currentTab] = false;
962 $arResult[self::TAB_CATALOG] = true;
963 }
964 }
965 else
966 {
967 $arResult[self::TAB_CATALOG] = (
968 CCatalogSku::TYPE_CATALOG == $arCatalog['CATALOG_TYPE']
969 || CCatalogSku::TYPE_FULL == $arCatalog['CATALOG_TYPE']
970 || CCatalogSku::TYPE_OFFERS == $arCatalog['CATALOG_TYPE']
971 );
972 $arResult[self::TAB_SKU] = (
973 CCatalogSku::TYPE_PRODUCT == $arCatalog['CATALOG_TYPE']
974 );
975 }
976 }
977 if (!$arResult[self::TAB_CATALOG] && $arResult[self::TAB_SKU])
978 {
979 $fieldsList = Catalog\Product\SystemField::getFieldNamesByRestrictions([
981 'IBLOCK_ID' => $intIBlockID,
982 ]);
983 if (!empty($fieldsList))
984 {
985 $arResult[self::TAB_PRODUCT] = true;
986 }
987 }
988
989 return $arResult;
990 }
991
992 public static function getProductTypeForNewProduct(array $catalog): ?int
993 {
994 $currentTab = self::getCurrentTabFromRequest();
995 switch ($catalog['CATALOG_TYPE'])
996 {
997 case CCatalogSku::TYPE_CATALOG:
998 switch ($currentTab)
999 {
1000 case self::TAB_SET:
1002 break;
1003 case self::TAB_SERVICE:
1005 break;
1006 default:
1008 break;
1009 }
1010 break;
1011 case CCatalogSku::TYPE_FULL:
1012 switch ($currentTab)
1013 {
1014 case self::TAB_SET:
1016 break;
1017 case self::TAB_SERVICE:
1019 break;
1020 case self::TAB_SKU:
1022 break;
1023 default:
1025 break;
1026 }
1027 break;
1028 case CCatalogSku::TYPE_PRODUCT:
1030 break;
1031 case CCatalogSku::TYPE_OFFERS:
1033 break;
1034 default:
1035 $result = null;
1036 break;
1037 }
1038
1039 return $result;
1040 }
1041
1042 public static function getProductTypeByTab(?string $tab): ?int
1043 {
1044 switch ($tab)
1045 {
1046 case self::TAB_CATALOG:
1048 break;
1049 case self::TAB_SKU:
1051 break;
1052 case self::TAB_SET:
1054 break;
1055 case self::TAB_SERVICE:
1057 break;
1058 default:
1059 $result = null;
1060 break;
1061 }
1062
1063 return $result;
1064 }
1065
1066 public static function getFormProductTypeName(int $id): ?string
1067 {
1068 $result = null;
1069
1070 $id = CIBlockElement::GetRealElement($id);
1071 if ($id > 0)
1072 {
1074 'select' => [
1075 'ID',
1076 'TYPE',
1077 ],
1078 'filter' => [
1079 '=ID' => $id,
1080 ]
1081 ]);
1082 if ($row !== null)
1083 {
1084 $result = (int)$row['TYPE'];
1085 }
1086 }
1087 $tabType = self::getProductTypeByTab(self::getCurrentTabFromRequest());
1088 if ($tabType !== null)
1089 {
1090 $result = $tabType;
1091 }
1093 {
1094 $result = null;
1095 }
1096 if ($result !== null)
1097 {
1098 $typeList = Catalog\ProductTable::getProductTypes(true);
1099 $result = $typeList[$result] ?? null;
1100 }
1101
1102 return $result;
1103 }
1104
1105 public static function getFormParams($params = array())
1106 {
1107 if (!is_array($params))
1108 {
1109 $params = [];
1110 }
1111 static::addTabParams($params);
1112
1113 return $params;
1114 }
1115
1116 public static function showFormParams()
1117 {
1118 $params = self::getFormParams();
1119 if (!empty($params))
1120 {
1121 foreach ($params as $key => $value)
1122 {
1123 ?><input type="hidden" name="<? echo htmlspecialcharsbx($key); ?>" value="<? echo htmlspecialcharsbx($value); ?>"><?
1124 }
1125 unset($key, $value);
1126 }
1127 unset($params);
1128 }
1129
1130 public static function setCatalogPanelButtons(&$buttons, $iblock, $catalogButtons, $params, $windowParams)
1131 {
1132 global $APPLICATION;
1133
1134 $iblock = (int)$iblock;
1135 if ($iblock <= 0)
1136 return;
1137 if (empty($params) || !is_array($params))
1138 return;
1139 if (empty($windowParams) || !is_array($windowParams))
1140 $windowParams = array('width' => 700, 'height' => 400, 'resize' => false);
1141
1142 if (isset($catalogButtons['add_product']))
1143 {
1144 $params[self::$strMainPrefix.self::TAB_KEY] = self::TAB_CATALOG;
1145 $url = '/bitrix/admin/'.CIBlock::GetAdminElementEditLink($iblock, null, $params);
1146 $action = $APPLICATION->GetPopupLink(
1147 array(
1148 "URL" => $url,
1149 "PARAMS" => $windowParams,
1150 )
1151 );
1152 $productButton = array(
1153 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_PROD_EXT'),
1154 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_PROD_TITLE'),
1155 'ACTION' => 'javascript:'.$action,
1156 'ACTION_URL' => $url,
1157 'ONCLICK' => $action,
1158 'ICON' => 'bx-context-toolbar-create-icon',
1159 'ID' => 'bx-context-toolbar-add-element',
1160 );
1161
1162 $buttons['edit']['add_element'] = $productButton;
1163 $buttons['configure']['add_element'] = $productButton;
1164 $buttons['intranet'][] = array(
1165 'TEXT' => $productButton['TEXT'],
1166 'TITLE' => $productButton['TITLE'],
1167 'ICON' => 'add',
1168 'ONCLICK' => $productButton['ACTION'],
1169 'SORT' => 1000,
1170 );
1171
1172 $url = str_replace('&bxpublic=Y&from_module=iblock', '', $url);
1173 $productButton['ACTION'] = "javascript:jsUtils.Redirect([], '".CUtil::JSEscape($url)."')";
1174 unset($productButton['ONCLICK']);
1175 $buttons['submenu']['add_element'] = $productButton;
1176 unset($productButton);
1177 }
1178
1179 if (isset($catalogButtons['add_sku']))
1180 {
1181 $params[self::$strMainPrefix.self::TAB_KEY] = self::TAB_SKU;
1182 $url = '/bitrix/admin/'.CIBlock::GetAdminElementEditLink($iblock, null, $params);
1183 $action = $APPLICATION->GetPopupLink(
1184 array(
1185 "URL" => $url,
1186 "PARAMS" => $windowParams,
1187 )
1188 );
1189 $skuButton = array(
1190 'TITLE' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_SKU'),
1191 'TEXT' => Loc::getMessage('BT_CAT_ADM_TOOLS_ADD_SKU_TITLE'),
1192 'ACTION' => 'javascript:'.$action,
1193 'ACTION_URL' => $url,
1194 'ONCLICK' => $action,
1195 'ICON' => 'bx-context-toolbar-create-icon',
1196 'ID' => 'bx-context-toolbar-add-sku',
1197 );
1198
1199 $buttons['edit']['add_sku'] = $skuButton;
1200 $buttons['configure']['add_sku'] = $skuButton;
1201 $buttons['intranet'][] = array(
1202 'TEXT' => $skuButton['TEXT'],
1203 'TITLE' => $skuButton['TITLE'],
1204 'ICON' => 'add',
1205 'ONCLICK' => $skuButton['ACTION'],
1206 'SORT' => 1010,
1207 );
1208
1209 $url = str_replace('&bxpublic=Y&from_module=iblock', '', $url);
1210 $skuButton['ACTION'] = "javascript:jsUtils.Redirect([], '".CUtil::JSEscape($url)."')";
1211 unset($skuButton['ONCLICK']);
1212 $buttons['submenu']['add_sku'] = $skuButton;
1213 unset($skuButton);
1214 }
1215 }
1216
1217 public static function setMainPrefix($strPrefix): void
1218 {
1219 self::$strMainPrefix = (string)$strPrefix;
1220 }
1221
1222 public static function getMainPrefix(): string
1223 {
1224 return self::$strMainPrefix;
1225 }
1226
1227 public static function setProductFormParams()
1228 {
1229 self::setMainPrefix('');
1230 }
1231
1232 public static function setSkuFormParams()
1233 {
1234 self::setMainPrefix('SUB');
1235 }
1236
1237 public static function getErrors(): array
1238 {
1239 return self::$arErrors;
1240 }
1241
1242 public static function changeTabs($intIBlockID, $intID, &$arCatalog)
1243 {
1245 $intID = (int)$intID;
1246 if ($intIBlockID <= 0 || $intID <= 0)
1247 return false;
1248
1249 if (empty($arCatalog))
1250 $arCatalog = CCatalogSku::GetInfoByIBlock($intIBlockID);
1251 if (empty($arCatalog))
1252 return false;
1253 if ($arCatalog['CATALOG'] != 'Y')
1254 return false;
1255
1256 $intProductID = CIBlockElement::GetRealElement($intID);
1257
1259
1260 $result = false;
1261 if ($boolFeatureSet)
1262 {
1263 $request = Context::getCurrent()->getRequest();
1264 if ($request->get(self::DELETE_GROUP) === 'Y')
1265 {
1267 }
1268 elseif ($request->get(self::DELETE_SET) === 'Y')
1269 {
1271 }
1272 unset($request);
1273 }
1274
1275 return $result;
1276 }
1277
1278 public static function addTabParams(&$arParams)
1279 {
1280 if (!is_array($arParams))
1281 {
1282 return;
1283 }
1284 $currentTab = self::getCurrentTabFromRequest();
1285 if ($currentTab !== null)
1286 {
1287 $arParams = self::getParamsWithTab($arParams, $currentTab);
1288 }
1289 }
1290
1296 public static function clearTabParams()
1297 {
1298 if (array_key_exists(self::$strMainPrefix.self::TAB_KEY, $_REQUEST))
1299 unset($_REQUEST[self::$strMainPrefix.self::TAB_KEY]);
1300 if (array_key_exists(self::$strMainPrefix.self::TAB_KEY, $_POST))
1301 unset($_POST[self::$strMainPrefix.self::TAB_KEY]);
1302 }
1303
1309 public static function getIblockProductTypeList($iblockId, $withDescr = false)
1310 {
1311 //TODO: change this method with \Bitrix\Catalog\Model\Product::getProductTypes
1312 $result = [];
1313 $iblockId = (int)$iblockId;
1314 if ($iblockId <= 0)
1315 {
1316 return $result;
1317 }
1318 $withDescr = ($withDescr === true);
1319
1320 $iblockData = CCatalogSku::GetInfoByIBlock($iblockId);
1321 if (empty($iblockData))
1322 {
1323 return $result;
1324 }
1325
1326 $data = [
1327 CCatalogSku::TYPE_CATALOG => [
1329 ],
1330 CCatalogSku::TYPE_PRODUCT => [
1333 ],
1334 CCatalogSku::TYPE_FULL => [
1338 ],
1339 CCatalogSku::TYPE_OFFERS => [
1342 ]
1343 ];
1344 if (Catalog\Config\Feature::isProductSetsEnabled())
1345 {
1346 $data[CCatalogSku::TYPE_CATALOG][] = Catalog\ProductTable::TYPE_SET;
1347 $data[CCatalogSku::TYPE_FULL][] = Catalog\ProductTable::TYPE_SET;
1348 }
1349 if (Catalog\Config\Feature::isCatalogServicesEnabled())
1350 {
1351 $data[CCatalogSku::TYPE_CATALOG][] = Catalog\ProductTable::TYPE_SERVICE;
1352 $data[CCatalogSku::TYPE_FULL][] = Catalog\ProductTable::TYPE_SERVICE;
1353 }
1354 if (!isset($data[$iblockData['CATALOG_TYPE']]))
1355 {
1356 return $result;
1357 }
1358
1359 $result = $data[$iblockData['CATALOG_TYPE']];
1360 if ($withDescr)
1361 {
1362 $productList = Catalog\ProductTable::getProductTypes(true);
1363 $extResult = [];
1364 foreach ($result as $type)
1365 {
1366 $extResult[$type] = $productList[$type];
1367 }
1368 unset($type);
1369 $result = $extResult;
1370 unset($extResult, $productList);
1371 }
1372
1373 return $result;
1374 }
1375
1382 public static function getProductTypeList($withDescr = false)
1383 {
1384 $withDescr = ($withDescr === true);
1385
1386 $result = array(
1388 );
1391 if (Catalog\Config\Feature::isProductSetsEnabled())
1395
1396 if ($withDescr)
1397 {
1398 $productList = Catalog\ProductTable::getProductTypes(true);
1399 $extResult = array();
1400 foreach ($result as $type)
1401 $extResult[$type] = $productList[$type];
1402 unset($type);
1403 $result = $extResult;
1404 unset($extResult, $productList);
1405 }
1406
1407 return $result;
1408 }
1409
1410 public static function getSystemProductFieldsHtml(array $product, array $config): string
1411 {
1412 $config['SYSTEM_UF_FIELDS'] = 'Y';
1413 $result = self::getProductUserFields($product, $config);
1414
1415 return ($result === null ? '' : $result[0]);
1416 }
1417
1418 public static function getAllProductFieldsHtml(array $product, array $config): array
1419 {
1420 $config['SYSTEM_UF_FIELDS'] = 'Y';
1421 $config['CUSTOM_UF_FIELDS'] = 'Y';
1422 $result = self::getProductUserFields($product, $config);
1423
1424 return ($result === null
1425 ? [
1426 0 => '',
1427 1 => '',
1428 ]
1429 : $result
1430 );
1431 }
1432
1433 public static function saveSystemProductFields(array $product): bool
1434 {
1435 if (!isset($product['ID']) || !isset($product['IBLOCK_ID']))
1436 {
1437 return true;
1438 }
1439 $product['IBLOCK_ID'] = (int)$product['IBLOCK_ID'];
1440 if ($product['IBLOCK_ID'] <= 0)
1441 {
1442 return true;
1443 }
1444 $product['PRODUCT_ID'] = (int)($product['PRODUCT_ID'] ?? CIBlockElement::GetRealElement($product['ID']));
1445
1447 'select' => [
1448 'ID',
1449 'TYPE',
1450 ],
1451 'filter' => [
1452 '=ID' => $product['PRODUCT_ID'],
1453 ],
1454 ]);
1455 $row = $iterator->fetch();
1456 if (empty($row))
1457 {
1458 return true;
1459 }
1460
1461 $systemFields = Catalog\Product\SystemField::getFieldNamesByRestrictions([
1462 'TYPE' => (int)$row['TYPE'],
1463 'IBLOCK_ID' => $product['IBLOCK_ID'],
1464 ]);
1465 if (empty($systemFields))
1466 {
1467 return true;
1468 }
1469
1470 $fields = [];
1471
1472 $userFieldManager = Main\UserField\Internal\UserFieldHelper::getInstance()->getManager();
1473 $userFieldManager->EditFormAddFields(Catalog\ProductTable::getUfId(), $fields);
1474 unset($userFieldManager);
1475
1476 if (empty($fields))
1477 {
1478 return true;
1479 }
1480
1481 $fields = array_intersect_key($fields, array_fill_keys($systemFields, true));
1482 if (empty($fields))
1483 {
1484 return true;
1485 }
1486
1488 $product['PRODUCT_ID'],
1489 [
1490 'fields' => $fields,
1491 'external_fields' => [
1492 'IBLOCK_ID' => $product['IBLOCK_ID'],
1493 ],
1494 ]
1495 );
1496
1497 if ($result->isSuccess())
1498 {
1499 return true;
1500 }
1501 else
1502 {
1503 return false;
1504 }
1505 }
1506
1507 public static function getClearedGridFields(array $options = []): array
1508 {
1509 $result = array_fill_keys(Catalog\ProductTable::getProductTypes(false), []);
1510
1511 $useCatalogTab = Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') === 'Y';
1512 $useNewCard = (bool)($options['USE_NEW_CARD'] ?? false);
1513
1514 $baseClearSkuFields = [
1515 'CATALOG_QUANTITY',
1516 'CATALOG_QUANTITY_RESERVED',
1517 'CATALOG_QUANTITY_TRACE',
1518 'CAN_BUY_ZERO',
1519 'CATALOG_PURCHASING_PRICE',
1520 'CATALOG_PURCHASING_CURRENCY',
1521 'CATALOG_MEASURE',
1522 'CATALOG_VAT_INCLUDED',
1523 'VAT_ID',
1524 'CATALOG_WEIGHT',
1525 'CATALOG_WIDTH',
1526 'CATALOG_LENGTH',
1527 'CATALOG_HEIGHT',
1528 'CATALOG_BAR_CODE',
1529 ];
1530 if (!$useNewCard && !$useCatalogTab)
1531 {
1532 $result[Catalog\ProductTable::TYPE_SKU] = $baseClearSkuFields;
1533 }
1534 if (!$useCatalogTab)
1535 {
1536 $result[Catalog\ProductTable::TYPE_EMPTY_SKU] = $baseClearSkuFields;
1537 }
1539 'CATALOG_QUANTITY_RESERVED',
1540 'CATALOG_BAR_CODE',
1541 ];
1542
1544 'CATALOG_QUANTITY',
1545 'CATALOG_QUANTITY_RESERVED',
1546 'CATALOG_QUANTITY_TRACE',
1547 'CAN_BUY_ZERO',
1548 'CATALOG_WEIGHT',
1549 'CATALOG_WIDTH',
1550 'CATALOG_LENGTH',
1551 'CATALOG_HEIGHT',
1552 'CATALOG_BAR_CODE',
1553 ];
1554
1555 return $result;
1556 }
1557
1558 public static function getLockedGridFields(array $options = []): array
1559 {
1560 $result = array_fill_keys(Catalog\ProductTable::getProductTypes(false), []);
1561 $useInventoryManagment = Catalog\Config\State::isUsedInventoryManagement();
1562 $showCatalog = Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') === 'Y';
1563 $useNewCard = (bool)($options['USE_NEW_CARD'] ?? false);
1564
1566 'CATALOG_QUANTITY' => $useInventoryManagment ? false: [],
1567 'CATALOG_QUANTITY_RESERVED' => $useInventoryManagment ? false : [],
1568 'CATALOG_AVAILABLE' => false,
1569 'CATALOG_QUANTITY_TRACE' => $useInventoryManagment ? false : [],
1570 'CAN_BUY_ZERO' => $useInventoryManagment ? false : [],
1571 'CATALOG_PURCHASING_PRICE' => $useInventoryManagment ? false : [],
1572 'CATALOG_MEASURE_RATIO' => [],
1573 'CATALOG_MEASURE' => [],
1574 'CATALOG_VAT_INCLUDED' => [],
1575 'VAT_ID' => [],
1576 'CATALOG_WEIGHT' => [],
1577 'CATALOG_WIDTH' => [],
1578 'CATALOG_LENGTH' => [],
1579 'CATALOG_HEIGHT' => [],
1580 'CATALOG_BAR_CODE' => false,
1581 ];
1582
1584 'CATALOG_QUANTITY' => false,
1585 'CATALOG_QUANTITY_RESERVED' => false,
1586 'CATALOG_AVAILABLE' => false,
1587 'CATALOG_QUANTITY_TRACE' => false,
1588 'CAN_BUY_ZERO' => false,
1589 'CATALOG_PURCHASING_PRICE' => [],
1590 'CATALOG_MEASURE_RATIO' => false,
1591 'CATALOG_MEASURE' => false,
1592 'CATALOG_VAT_INCLUDED' => [],
1593 'VAT_ID' => [],
1594 'CATALOG_WEIGHT' => false,
1595 'CATALOG_WIDTH' => [],
1596 'CATALOG_LENGTH' => [],
1597 'CATALOG_HEIGHT' => [],
1598 'CATALOG_BAR_CODE' => false,
1599 ];
1600
1601 $baseLockedSkuFields = [
1602 'CATALOG_QUANTITY' => $showCatalog && !$useInventoryManagment ? [] : false,
1603 'CATALOG_QUANTITY_RESERVED' => $showCatalog && !$useInventoryManagment ? [] : false,
1604 'CATALOG_AVAILABLE' => false,
1605 'CATALOG_QUANTITY_TRACE' => $showCatalog && !$useInventoryManagment ? [] : false,
1606 'CAN_BUY_ZERO' => $showCatalog && !$useInventoryManagment ? [] : false,
1607 'CATALOG_PURCHASING_PRICE' => $showCatalog ? [] : false,
1608 'CATALOG_MEASURE_RATIO' => $showCatalog && !$useInventoryManagment ? [] : false,
1609 'CATALOG_MEASURE' => $showCatalog ? [] : false,
1610 'CATALOG_VAT_INCLUDED' => $showCatalog ? [] : false,
1611 'VAT_ID' => $showCatalog ? [] : false,
1612 'CATALOG_WEIGHT' => $showCatalog ? [] : false,
1613 'CATALOG_WIDTH' => $showCatalog ? [] : false,
1614 'CATALOG_LENGTH' => $showCatalog ? [] : false,
1615 'CATALOG_HEIGHT' => $showCatalog ? [] : false,
1616 'CATALOG_BAR_CODE' => false,
1617 ];
1618 if (!$showCatalog)
1619 {
1620 $result[Catalog\ProductTable::TYPE_EMPTY_SKU] = $baseLockedSkuFields;
1621 }
1622
1623 $skuUnlock = $showCatalog || $useNewCard;
1624
1626 'CATALOG_QUANTITY' => $skuUnlock && !$useInventoryManagment ? [] : false,
1627 'CATALOG_QUANTITY_RESERVED' => $skuUnlock && !$useInventoryManagment ? [] : false,
1628 'CATALOG_AVAILABLE' => false,
1629 'CATALOG_QUANTITY_TRACE' => $skuUnlock && !$useInventoryManagment ? [] : false,
1630 'CAN_BUY_ZERO' => $skuUnlock && !$useInventoryManagment ? [] : false,
1631 'CATALOG_PURCHASING_PRICE' => $skuUnlock ? [] : false,
1632 'CATALOG_MEASURE_RATIO' => $skuUnlock && !$useInventoryManagment ? [] : false,
1633 'CATALOG_MEASURE' => $skuUnlock ? [] : false,
1634 'CATALOG_VAT_INCLUDED' => $skuUnlock ? [] : false,
1635 'VAT_ID' => $skuUnlock ? [] : false,
1636 'CATALOG_WEIGHT' => $skuUnlock ? [] : false,
1637 'CATALOG_WIDTH' => $skuUnlock ? [] : false,
1638 'CATALOG_LENGTH' => $skuUnlock ? [] : false,
1639 'CATALOG_HEIGHT' => $skuUnlock ? [] : false,
1640 'CATALOG_BAR_CODE' => false,
1641 ];
1642
1644
1647
1649 'CATALOG_QUANTITY' => false,
1650 'CATALOG_QUANTITY_RESERVED' => false,
1651 'CATALOG_AVAILABLE' => [],
1652 'CATALOG_QUANTITY_TRACE' => false,
1653 'CAN_BUY_ZERO' => false,
1654 'CATALOG_PURCHASING_PRICE' => [],
1655 'CATALOG_MEASURE_RATIO' => false,
1656 'CATALOG_MEASURE' => [],
1657 'CATALOG_VAT_INCLUDED' => [],
1658 'VAT_ID' => [],
1659 'CATALOG_WEIGHT' => false,
1660 'CATALOG_WIDTH' => false,
1661 'CATALOG_LENGTH' => false,
1662 'CATALOG_HEIGHT' => false,
1663 'CATALOG_BAR_CODE' => false,
1664 ];
1665
1666 return $result;
1667 }
1668
1669 private static function getProductUserFields(array $product, array $config): ?array
1670 {
1671 if (!isset($product['ID']) || !isset($product['IBLOCK_ID']) || !isset($product['TYPE']))
1672 {
1673 return null;
1674 }
1675 $product['IBLOCK_ID'] = (int)$product['IBLOCK_ID'];
1676 if ($product['IBLOCK_ID'] <= 0)
1677 {
1678 return null;
1679 }
1680 $product['PRODUCT_ID'] = (int)($product['PRODUCT_ID'] ?? CIBlockElement::GetRealElement($product['ID']));
1681 $product['TYPE'] = (int)$product['TYPE'];
1682
1683 $result = [
1684 0 => '',
1685 1 => '',
1686 ];
1687
1688 $userFieldManager = Main\UserField\Internal\UserFieldHelper::getInstance()->getManager();
1689 $productUserFields = $userFieldManager->GetUserFields(
1690 Catalog\ProductTable::getUfId(),
1691 $product['PRODUCT_ID'],
1692 LANGUAGE_ID
1693 );
1694 if (empty($productUserFields))
1695 {
1696 return $result;
1697 }
1698
1699 $config['ALLOW_EDIT'] = $config['ALLOW_EDIT'] ?? true;
1700
1701 foreach (array_keys($productUserFields) as $fieldName)
1702 {
1703 $productUserFields[$fieldName]['VALUE_ID'] = $product['PRODUCT_ID'];
1704 $productUserFields[$fieldName]['EDIT_FORM_LABEL'] = $productUserFields[$fieldName]['EDIT_FORM_LABEL']
1705 ??
1706 $productUserFields[$fieldName]['FIELD_NAME']
1707 ;
1708 if (!$config['ALLOW_EDIT'])
1709 {
1710 $productUserFields[$fieldName]['EDIT_IN_LIST'] = 'N';
1711 }
1712 }
1713 unset($fieldName);
1714
1715 $config['FROM_FORM'] = $config['FROM_FORM'] ?? false;
1716 $showSystemFields = ($config['SYSTEM_UF_FIELDS'] ?? 'N') === 'Y';
1717 $showCustomFields = ($config['CUSTOM_UF_FIELDS'] ?? 'N') === 'Y';
1718
1719 if (!$showSystemFields && !$showCustomFields)
1720 {
1721 return $result;
1722 }
1723
1724 $request = Main\Context::getCurrent()->getRequest();
1725
1726 if ($showSystemFields)
1727 {
1728 $html = Catalog\Product\SystemField::renderAdminEditForm(
1729 $product,
1730 $config
1731 );
1732 if ($html !== null)
1733 {
1734 $result[0] = $html;
1735 }
1736 }
1737
1738 $allSystemFields = Catalog\Product\SystemField::getFieldNamesByRestrictions([]);
1739 if (!empty($allSystemFields))
1740 {
1741 $productUserFields = array_diff_key(
1742 $productUserFields,
1743 array_fill_keys($allSystemFields, true)
1744 );
1745 }
1746 unset($allSystemFields);
1747
1748 if (
1749 $showCustomFields
1750 && !empty($productUserFields)
1751 )
1752 {
1753 foreach ($productUserFields as $fieldName => $row)
1754 {
1755 $result[1] .= $userFieldManager->GetEditFormHTML(
1756 $config['FROM_FORM'],
1757 $request->getPost($fieldName) ?? '',
1758 $row
1759 );
1760 }
1761 }
1762
1763 return $result;
1764 }
1765
1776
1781 public static function allowedShowQuantityFields(): bool
1782 {
1784 }
1785
1786 public static function getSummaryStoreAmountByPermissions(array $productIds): array
1787 {
1788 if (!Loader::includeModule('crm'))
1789 {
1790 return [];
1791 }
1792
1793 if (!Catalog\Config\State::isUsedInventoryManagement())
1794 {
1795 return [];
1796 }
1797
1799 if (empty($productIds))
1800 {
1801 return [];
1802 }
1803
1805 $allowedStores = $accessController->getPermissionValue(
1807 );
1808 if (empty($allowedStores))
1809 {
1810 return [];
1811 }
1812 $permissionFilter = $accessController->getEntityFilter(
1814 Catalog\StoreProductTable::class
1815 );
1816 unset($accessController);
1817
1818 $result = array_fill_keys(
1819 $productIds,
1820 [
1821 'QUANTITY' => 0,
1822 'QUANTITY_RESERVED' => 0,
1823 ]
1824 );
1825
1826 foreach (array_chunk($productIds, CATALOG_PAGE_SIZE) as $pageIds)
1827 {
1829 'select' => [
1830 'PRODUCT_ID',
1831 'SUM_QUANTITY',
1832 'SUM_QUANTITY_RESERVED',
1833 ],
1834 'filter' => array_merge(
1835 [
1836 '@PRODUCT_ID' => $pageIds,
1837 '=STORE.ACTIVE' => 'Y',
1838 ],
1840 ),
1841 'group' => [
1842 'PRODUCT_ID',
1843 ],
1844 'runtime' => [
1845 new ORM\Fields\ExpressionField('SUM_QUANTITY', 'SUM(%s)', ['AMOUNT']),
1846 new ORM\Fields\ExpressionField('SUM_QUANTITY_RESERVED', 'SUM(%s)', ['QUANTITY_RESERVED']),
1847 ],
1848 ]);
1849 while ($row = $iterator->fetch())
1850 {
1851 $id = (int)$row['PRODUCT_ID'];
1852 $result[$id] = [
1853 'QUANTITY' => (float)$row['SUM_QUANTITY'],
1854 'QUANTITY_RESERVED' => (float)$row['SUM_QUANTITY_RESERVED'],
1855 ];
1856 }
1857 unset($row, $iterator);
1858 }
1859 unset($pageIds);
1860
1861 return $result;
1862 }
1863}
1864
1866{
1868 const PREFIX_SET = 'PRODUCT_SET';
1869 const PREFIX_GROUP = 'PRODUCT_GROUP';
1870
1871 protected static $strMainPrefix = '';
1872 protected static $intTypeID = 0;
1873 protected static $arErrors = array();
1874 protected static $arSrcValues = array();
1875 protected static $arCheckValues = array();
1876
1877 public static function setMainPrefix($strPrefix)
1878 {
1879 self::$strMainPrefix = (string)$strPrefix;
1880 }
1881
1882 public static function getMainPrefix()
1883 {
1884 return self::$strMainPrefix;
1885 }
1886
1887 public static function setTypeID($intTypeID)
1888 {
1889 $intTypeID = (int)$intTypeID;
1891 return;
1892 self::$intTypeID = $intTypeID;
1893 }
1894
1895 public static function getTypeID()
1896 {
1897 return self::$intTypeID;
1898 }
1899
1900 public static function setProductFormParams($arParams)
1901 {
1902 if (empty($arParams) || !is_array($arParams))
1903 return;
1904 if (!isset($arParams['TYPE']))
1905 return;
1906 $intTypeID = (int)$arParams['TYPE'];
1908 return;
1909 self::$intTypeID = $intTypeID;
1910 $strPrefix = (CCatalogProductSet::TYPE_SET == $intTypeID ? self::PREFIX_SET : self::PREFIX_GROUP);
1911
1912 self::setMainPrefix($strPrefix);
1913 }
1914
1915 public static function setSkuFormParams($arParams)
1916 {
1917 if (empty($arParams) || !is_array($arParams))
1918 return;
1919 if (!isset($arParams['TYPE']))
1920 return;
1921 $intTypeID = (int)$arParams['TYPE'];
1923 return;
1924 self::$intTypeID = $intTypeID;
1925 $strPrefix = 'SUB'.(CCatalogProductSet::TYPE_SET == $intTypeID ? self::PREFIX_SET : self::PREFIX_GROUP);
1926
1927 self::setMainPrefix($strPrefix);
1928 }
1929
1930 public static function getEmptySet($intProductID)
1931 {
1932 $arResult = false;
1933 if (CCatalogProductSet::TYPE_SET == self::$intTypeID || CCatalogProductSet::TYPE_GROUP == self::$intTypeID)
1934 {
1935 $arResult = array(
1936 'n0' => array(
1937 'ITEM_ID' => $intProductID,
1938 'ACTIVE' => 'Y',
1939 'SORT' => '100',
1940 'ITEMS' => self::getEmptyItem(0),
1941 'NEW_ITEM_COUNT' => self::NEW_ITEM_COUNT
1942 )
1943 );
1944 }
1945 return $arResult;
1946 }
1947
1948 public static function getEmptyItem($arParams)
1949 {
1950 $arResult = array();
1951 if (CCatalogProductSet::TYPE_SET != self::$intTypeID && CCatalogProductSet::TYPE_GROUP != self::$intTypeID)
1952 return $arResult;
1953 if (!is_array($arParams))
1954 $arParams = array('nStart' => $arParams);
1955 if (!isset($arParams['nStart']))
1956 $arParams['nStart'] = 0;
1957 $arParams['nStart'] = (int)$arParams['nStart'];
1958 switch(self::$intTypeID)
1959 {
1961 for ($i = $arParams['nStart']; $i < ($arParams['nStart'] + self::NEW_ITEM_COUNT); $i++)
1962 {
1963 $arResult['n'.$i] = array(
1964 'ITEM_ID' => '',
1965 'QUANTITY' => '',
1966 'DISCOUNT_PERCENT' => '',
1967 'SORT' => 100,
1968 'NEW_ITEM' => true,
1969 'EMPTY_ITEM' => true,
1970 'ITEM_NAME' => '',
1971 );
1972 }
1973 break;
1975 for ($i = $arParams['nStart']; $i < ($arParams['nStart'] + self::NEW_ITEM_COUNT); $i++)
1976 {
1977 $arResult['n'.$i] = array(
1978 'ITEM_ID' => '',
1979 'QUANTITY' => '',
1980 'SORT' => 100,
1981 'NEW_ITEM' => true,
1982 'EMPTY_ITEM' => true,
1983 'ITEM_NAME' => '',
1984 );
1985 }
1986 break;
1987 default:
1988 break;
1989 }
1990 return $arResult;
1991 }
1992
1993 public static function getFormValues(&$arSets)
1994 {
1995 if (CCatalogProductSet::TYPE_SET != self::$intTypeID && CCatalogProductSet::TYPE_GROUP != self::$intTypeID)
1996 return;
1997 if (empty($arSets) || !is_array($arSets))
1998 return;
1999
2001 if (!$boolFeatureSet)
2002 return;
2003
2004 if (!isset(self::$arSrcValues[self::$strMainPrefix]) || empty(self::$arSrcValues[self::$strMainPrefix]))
2005 return;
2006
2007 foreach (self::$arSrcValues[self::$strMainPrefix] as $setKey => $setData)
2008 {
2009 if (empty($setData['ITEMS']))
2010 {
2011 if (array_key_exists($setKey, $arSets))
2012 unset($arSets[$setKey]);
2013 continue;
2014 }
2015 $newSetData = $setData;
2016 unset($newSetData['ITEMS']);
2017 $newItemCount = 0;
2018 $setItems = array();
2019
2020 foreach ($setData['ITEMS'] as $itemKey => $item)
2021 {
2022 if (empty($item['ITEM_ID']) || trim($item['ITEM_ID'] == ''))
2023 continue;
2024 $itemKey = (int)$itemKey;
2025 if ($itemKey > 0)
2026 {
2027 $setItems[$itemKey] = $item;
2028 }
2029 else
2030 {
2031 $setItems['n'.$newItemCount] = $item;
2032 $newItemCount++;
2033 }
2034 }
2035 unset($itemKey, $item);
2036
2037 $newSetData['ITEMS'] = $setItems;
2038 $newSetData['NEW_ITEM_COUNT'] = $newItemCount;
2039
2040 if (isset($arSets[$setKey]))
2041 {
2042 $arSets[$setKey] = array_merge($newSetData, $arSets[$setKey]);
2043 $arSets[$setKey]['ITEMS'] = $newSetData['ITEMS'];
2044 $arSets[$setKey]['NEW_ITEM_COUNT'] = $newSetData['NEW_ITEM_COUNT'];
2045 }
2046 else
2047 {
2048 $arSets[$setKey] = $newSetData;
2049 }
2050 unset($newSetData, $newItemCount, $setItems);
2051 }
2052 unset($setKey, $setData);
2053 }
2054
2055 public static function addEmptyValues(&$arSets)
2056 {
2057 if (empty($arSets) || !is_array($arSets))
2058 return;
2059
2060 foreach ($arSets as $setKey => $setData)
2061 {
2062 $start = $setData['NEW_ITEM_COUNT'] ?? 0;
2063 foreach (self::getEmptyItem($start) as $rowKey => $row)
2064 $arSets[$setKey]['ITEMS'][$rowKey] = $row;
2065 $arSets[$setKey]['NEW_ITEM_COUNT'] = $start + self::NEW_ITEM_COUNT;
2066 unset($rowKey, $row, $start);
2067 }
2068 unset($setKey, $setData);
2069 }
2070
2071 public static function getItemsInfo(&$arSets)
2072 {
2073 $itemList = array();
2074 $itemIds = array();
2075 if (empty($arSets) || !is_array($arSets))
2076 return;
2077 foreach ($arSets as $key => $arOneSet)
2078 {
2079 foreach ($arOneSet['ITEMS'] as $keyItem => $arItem)
2080 {
2081 if ('' == $arItem['ITEM_ID'])
2082 continue;
2083 $intItemID = (int)$arItem['ITEM_ID'];
2084 if (0 >= $intItemID)
2085 continue;
2086 if (!isset($itemList[$intItemID]))
2087 {
2088 $itemList[$intItemID] = array();
2089 $itemIds[] = $intItemID;
2090 }
2091 $itemList[$intItemID][] = &$arSets[$key]['ITEMS'][$keyItem];
2092 }
2093 }
2094 if (!empty($itemList))
2095 {
2096 $productIterator = Iblock\ElementTable::getList(array(
2097 'select' => array('ID', 'NAME'),
2098 'filter' => array('@ID' => $itemIds)
2099 ));
2100 while ($product = $productIterator->fetch())
2101 {
2102 $product['ID'] = (int)$product['ID'];
2103 if (!isset($itemList[$product['ID']]))
2104 continue;
2105 foreach ($itemList[$product['ID']] as &$setItem)
2106 $setItem['ITEM_NAME'] = $product['NAME'];
2107 unset($setItem);
2108 }
2109 unset($product, $productIterator);
2110 $productRatio = Catalog\ProductTable::getCurrentRatioWithMeasure($itemIds);
2111 if (!empty($productRatio))
2112 {
2113 foreach ($productRatio as $productId => $productData)
2114 {
2115 if (!isset($itemList[$productId]))
2116 continue;
2117 foreach ($itemList[$productId] as &$setItem)
2118 {
2119 $setItem['RATIO'] = $productData['RATIO'];
2120 $setItem['MEASURE'] = $productData['MEASURE'];
2121 }
2122 unset($setItem);
2123 }
2124 unset($productId, $productData);
2125 }
2126 unset($productRatio);
2127 }
2128 unset($itemIds, $itemList);
2129 }
2130
2131 public static function clearOwnerSet(&$arSets)
2132 {
2133 if (empty($arSets) || !is_array($arSets))
2134 return;
2135 $index = 0;
2136 $result = array();
2137 foreach ($arSets as $oneSet)
2138 {
2139 $itemIndex = 0;
2140 $items = array();
2141 foreach ($oneSet['ITEMS'] as $oneItem)
2142 {
2143 $items['n'.$itemIndex] = $oneItem;
2144 $itemIndex++;
2145 }
2146 $result['n'.$index] = array(
2147 'ITEM_ID' => '',
2148 'ACTIVE' => $oneSet['ACTIVE'],
2149 'SORT' => $oneSet['SORT'],
2150 'ITEMS' => $items,
2151 'NEW_ITEM_COUNT' => $itemIndex
2152 );
2153 $index++;
2154 }
2155 unset($oneSet);
2156 $arSets = $result;
2157 }
2158
2159 public static function showEditForm($arSets)
2160 {
2161 if (CCatalogProductSet::TYPE_SET != self::$intTypeID && CCatalogProductSet::TYPE_GROUP != self::$intTypeID)
2162 return;
2163 if (empty($arSets) || !is_array($arSets))
2164 return;
2165
2167 if (!$boolFeatureSet)
2168 return;
2169
2170 Main\Page\Asset::getInstance()->addJs('/bitrix/js/catalog/tbl_edit.js');
2171
2172 self::getItemsInfo($arSets);
2173
2174 foreach ($arSets as $key => $arOneSet)
2175 {
2176 $blockName = self::$strMainPrefix.'_'.$arOneSet['ITEM_ID'];
2177 $blockName .= '_'.Main\Security\Random::getString(8, true);
2178
2179 $strNamePrefix = self::$strMainPrefix.'['.$key.']';
2180 $strIDPrefix = $blockName.'_'.$key;
2181 ?><table id="<? echo $strIDPrefix; ?>_TBL" class="internal" style="margin: 0 auto;">
2182 <tr class="heading">
2183 <td class="align-left"><? echo Loc::getMessage('BT_CAT_SET_ITEM_NAME'); ?></td>
2184 <td class="align-right"><? echo Loc::getMessage('BT_CAT_SET_ITEM_QUANTITY'); ?></td>
2185 <td class="align-left">&nbsp;</td><?
2186 if (CCatalogProductSet::TYPE_SET == self::$intTypeID)
2187 {
2188 ?><td class="align-right"><? echo Loc::getMessage('BT_CAT_SET_ITEM_DISCOUNT_PERCENT_EXT'); ?></td><?
2189 }
2190 ?>
2191 <td class="align-right"><? echo Loc::getMessage('BT_CAT_SET_ITEM_SORT'); ?></td><?
2192 if (0 < (int)$key)
2193 {
2194 ?><td><? echo (
2195 CCatalogProductSet::TYPE_SET == self::$intTypeID
2196 ? Loc::getMessage('BT_CAT_SET_ITEM_DEL_FROM_SET')
2197 : Loc::getMessage('BT_CAT_SET_ITEM_DEL_FROM_GROUP')); ?></td><?
2198 }
2199 ?></tr><?
2201 $arOneSet['ITEMS'],
2202 array(
2203 'NEW_ITEM' => SORT_ASC,
2204 'EMPTY_ITEM' => SORT_ASC,
2205 'SORT' => array(SORT_NUMERIC, SORT_ASC),
2206 'ITEM_ID' => array(SORT_NUMERIC, SORT_ASC)
2207 ),
2208 array(
2209 'NEW_ITEM' => function($value)
2210 {
2211 return !is_null($value);
2212 },
2213 'EMPTY_ITEM' => function($value)
2214 {
2215 return !is_null($value);
2216 }
2217 ),
2218 null,
2219 true
2220 );
2221 foreach ($arOneSet['ITEMS'] as $keyItem => $arOneItem)
2222 {
2223 $arItemParams = array(
2224 'SET_KEY' => $key,
2225 'KEY' => $keyItem,
2226 'NAME_PREFIX' => $strNamePrefix.'[ITEMS]['.$keyItem.']',
2227 'ID_PREFIX' => $strIDPrefix.'_ITEMS_'.$keyItem
2228 );
2229 self::showItemRow($arOneItem, $arItemParams);
2230 }
2231 ?>
2232 </table>
2233 <div style="margin: 10px auto; text-align: center;">
2234 <input class="adm-btn-big" type="button" id="<? echo $strIDPrefix; ?>_ITEMS_ADD" value="<? echo Loc::getMessage('BT_CAT_SET_ITEM_ADD'); ?>" title="<? echo Loc::getMessage('BT_CAT_SET_ITEM_ADD_TITLE'); ?>">
2235 </div>
2236 <input type="hidden" id="<? echo $strIDPrefix; ?>_ITEMS_CNT" value="<? echo (int)$arOneSet['NEW_ITEM_COUNT']; ?>"><?
2237 $arNewParams = array(
2238 'SET_KEY' => $key,
2239 'KEY' => 'tmp_xxx',
2240 'NAME_PREFIX' => $strNamePrefix.'[ITEMS][ntmp_xxx]',
2241 'ID_PREFIX' => $strIDPrefix.'_ITEMS_ntmp_xxx'
2242 );
2243
2244 $arCellInfo = self::getJSRow($arNewParams);
2245
2246 $arJSParams = array(
2247 'PREFIX' => $strIDPrefix.'_ITEMS_',
2248 'PREFIX_NAME' => $strNamePrefix.'[ITEMS]',
2249 'TABLE_PROP_ID' => $strIDPrefix.'_TBL',
2250 'PROP_COUNT_ID' => $strIDPrefix.'_ITEMS_CNT',
2251 'BTN_ID' => $strIDPrefix.'_ITEMS_ADD',
2252 'CELLS' => $arCellInfo['CELLS'],
2253 'CELL_PARAMS' => $arCellInfo['CELL_PARAMS'],
2254 // TODO: remove this dirty hack after disable old product card in public shop
2255 'SEARCH_PAGE' => (defined('SELF_FOLDER_URL') ? '/shop/settings/' : '/bitrix/admin/').'cat_product_search_dialog.php',
2256 );
2257 ?>
2258<script>
2259if (!window.ob<?=$blockName; ?>)
2260{
2261 window.ob<?=$blockName; ?> = new JCCatTblEditExt(<? echo CUtil::PhpToJSObject($arJSParams); ?>);
2262}
2263</script>
2264 <?
2265 unset($blockName);
2266 break;
2267 }
2268 }
2269
2270 public static function showItemRow($arRow, $arParams)
2271 {
2272 if (CCatalogProductSet::TYPE_SET != self::$intTypeID && CCatalogProductSet::TYPE_GROUP != self::$intTypeID)
2273 return;
2274 $strNamePrefix = $arParams['NAME_PREFIX'];
2275 $strIDPrefix = $arParams['ID_PREFIX'];
2276 $strKey = $arParams['KEY'];
2277 ?><tr>
2278 <td class="align-left">
2279 <input name="<? echo $strNamePrefix; ?>[ITEM_ID]" id="<? echo $strIDPrefix; ?>_ITEM_ID" value="<? echo htmlspecialcharsbx($arRow['ITEM_ID']); ?>" size="5" type="text">
2280 <input type="button" value="..." id="<? echo $strIDPrefix; ?>_BTN" data-row-id="<? echo $strIDPrefix; ?>">
2281 &nbsp;<span id="<? echo $strIDPrefix; ?>_ITEM_ID_link"><? echo htmlspecialcharsEx($arRow['ITEM_NAME']); ?></span>
2282 </td>
2283 <td class="align-right">
2284 <input type="text" size="5" name="<? echo $strNamePrefix; ?>[QUANTITY]" id="<? echo $strIDPrefix; ?>_QUANTITY" value="<? echo htmlspecialcharsbx($arRow['QUANTITY']) ?>">
2285 </td>
2286 <td class="align-left"><?
2287 $measure = '';
2288 if (isset($arRow['RATIO']) && isset($arRow['MEASURE']))
2289 {
2290 $measure = ' * '.$arRow['RATIO'].' '.$arRow['MEASURE']['SYMBOL_RUS'];
2291 }
2292 ?><span id="<? echo $strIDPrefix; ?>_MEASURE"><? echo $measure; ?></span></td><?
2293 if (CCatalogProductSet::TYPE_SET == self::$intTypeID)
2294 {
2295 ?><td class="align-right">
2296 <input type="text" size="3" name="<? echo $strNamePrefix; ?>[DISCOUNT_PERCENT]" id="<? echo $strIDPrefix; ?>_DISCOUNT_PERCENT" value="<? echo htmlspecialcharsbx($arRow['DISCOUNT_PERCENT']) ?>">
2297 </td><?
2298 }
2299 ?>
2300 <td class="align-right">
2301 <input type="text" size="3" name="<? echo $strNamePrefix; ?>[SORT]" id="<? echo $strIDPrefix; ?>_SORT" value="<? echo htmlspecialcharsbx($arRow['SORT']) ?>">
2302 </td>
2303 <?
2304 if (0 < (int)$arParams['SET_KEY'])
2305 {
2306 ?><td>
2307 <input type="hidden" name="<? echo $strNamePrefix; ?>[DEL]" id="<? echo $strIDPrefix; ?>_DEL_N" value="N">
2308 <?
2309 if (0 < (int)$strKey)
2310 {
2311 ?><input type="checkbox" name="<? echo $strNamePrefix; ?>[DEL]" id="<? echo $strIDPrefix; ?>_DEL" value="Y"><?
2312 }
2313 else
2314 {
2315 ?>&nbsp;<?
2316 }
2317 ?></td><?
2318 }
2319 ?>
2320 </tr><?
2321 }
2322
2323 protected static function getJSRow($arParams)
2324 {
2325 if (CCatalogProductSet::TYPE_SET != self::$intTypeID && CCatalogProductSet::TYPE_GROUP != self::$intTypeID)
2326 return '';
2327 $strNamePrefix = $arParams['NAME_PREFIX'];
2328 $strIDPrefix = $arParams['ID_PREFIX'];
2329 $strKey = $arParams['KEY'];
2330
2331 $arCells = array();
2332 $arCellParams = array();
2333 $arCells[] = '<input name="'.$strNamePrefix.'[ITEM_ID]" id="'.$strIDPrefix.'_ITEM_ID" value="" size="5" type="text">'.
2334 ' <input type="button" value="..." id="'.$strIDPrefix.'_BTN" data-row-id="'.$strIDPrefix.'">'.
2335 '&nbsp;<span id="'.$strIDPrefix.'_ITEM_ID_link"></span>';
2336 $arCellParams[] = array(
2337 'attrs' => array(
2338 'className' => 'align-left'
2339 )
2340 );
2341 $arCells[] = '<input type="text" size="5" name="'.$strNamePrefix.'[QUANTITY]" id="'.$strIDPrefix.'_QUANTITY" value="">';
2342 $arCellParams[] = array(
2343 'attrs' => array(
2344 'className' => 'align-right'
2345 )
2346 );
2347 $arCells[] = '<span id="'.$strIDPrefix.'_MEASURE"></span>';
2348 $arCellParams[] = array(
2349 'attrs' => array(
2350 'className' => 'align-left'
2351 )
2352 );
2353 if (CCatalogProductSet::TYPE_SET == self::$intTypeID)
2354 {
2355 $arCells[] = '<input type="text" size="3" name="'.$strNamePrefix.'[DISCOUNT_PERCENT]" id="'.$strIDPrefix.'_DISCOUNT_PERCENT" value="">';
2356 $arCellParams[] = array(
2357 'attrs' => array(
2358 'className' => 'align-right'
2359 )
2360 );
2361 }
2362 $arCells[] = '<input type="text" size="3" name="'.$strNamePrefix.'[SORT]" id="'.$strIDPrefix.'_SORT" value="100">';
2363 $arCellParams[] = array(
2364 'attrs' => array(
2365 'className' => 'align-right'
2366 )
2367 );
2368 if (0 < (int)$arParams['SET_KEY'])
2369 {
2370 $arCells[] = '<input type="hidden" name="'.$strNamePrefix.'[DEL]" id="'.$strIDPrefix.'_DEL_N" value="N">'.
2371 (0 < (int)$strKey
2372 ? '<input type="checkbox" name="'.$strNamePrefix.'[DEL]" id="'.$strIDPrefix.'_DEL" value="Y">'
2373 : '&nbsp;'
2374 );
2375 $arCellParams[] = '';
2376 }
2377
2378 return array(
2379 'CELLS' => $arCells,
2380 'CELL_PARAMS' => $arCellParams
2381 );
2382 }
2383
2384 public static function checkFormValues($arItem)
2385 {
2386 self::$arErrors = array();
2387
2389 if (!$boolFeatureSet)
2390 return true;
2391
2392 self::$arSrcValues[self::$strMainPrefix] = array();
2393 self::$arCheckValues[self::$strMainPrefix] = array();
2394
2395 if (isset($_POST[self::$strMainPrefix]) && is_array($_POST[self::$strMainPrefix]))
2396 {
2398 self::$arSrcValues[self::$strMainPrefix] = $_POST[self::$strMainPrefix];
2399
2400 foreach (self::$arSrcValues[self::$strMainPrefix] as $key => $arOneSet)
2401 {
2402 $boolNew = (0 >= (int)$key);
2403 $arSaveSet = array(
2404 'TYPE' => self::$intTypeID,
2405 'ITEM_ID' => $arItem['PRODUCT_ID'],
2406 'ACTIVE' => 'Y',
2407 'ITEMS' => array()
2408 );
2409
2410 $removeSet = true;
2411 if (CCatalogProductSet::TYPE_SET == self::$intTypeID)
2412 {
2413 foreach ($arOneSet['ITEMS'] as $keyItem => $arOneItem)
2414 {
2415 if ('Y' == $arOneItem['DEL'])
2416 continue;
2417 $itemId = (isset($arOneItem['ITEM_ID']) ? (int)$arOneItem['ITEM_ID'] : 0);
2418 if ($itemId <= 0)
2419 continue;
2420 $removeSet = false;
2421 $arOneItem['DISCOUNT_PERCENT'] = trim($arOneItem['DISCOUNT_PERCENT']);
2422 $arSaveItem = array(
2423 'ITEM_ID' => $itemId,
2424 'QUANTITY' => $arOneItem['QUANTITY'],
2425 'DISCOUNT_PERCENT' => ('' == $arOneItem['DISCOUNT_PERCENT'] ? false : $arOneItem['DISCOUNT_PERCENT']),
2426 'SORT' => $arOneItem['SORT']
2427 );
2428 if ((int)$keyItem <= 0)
2429 self::$arSrcValues[self::$strMainPrefix][$key]['ITEMS'][$keyItem]['NEW_ITEM'] = true;
2430 unset($itemId);
2431 $arSaveSet['ITEMS'][] = $arSaveItem;
2432 }
2433 unset($keyItem, $arOneItem);
2434 }
2435 else
2436 {
2437 foreach ($arOneSet['ITEMS'] as $keyItem => $arOneItem)
2438 {
2439 if ('Y' == $arOneItem['DEL'])
2440 continue;
2441 $itemId = (isset($arOneItem['ITEM_ID']) ? (int)$arOneItem['ITEM_ID'] : 0);
2442 if ($itemId <= 0)
2443 continue;
2444 $removeSet = false;
2445 $arSaveItem = array(
2446 'ITEM_ID' => $itemId,
2447 'QUANTITY' => $arOneItem['QUANTITY'],
2448 'SORT' => $arOneItem['SORT']
2449 );
2450 if ($arSaveItem['QUANTITY'] == '')
2451 $arSaveItem['QUANTITY'] = 1;
2452 if ((int)$keyItem <= 0)
2453 self::$arSrcValues[self::$strMainPrefix][$key]['ITEMS'][$keyItem]['NEW_ITEM'] = true;
2454 unset($itemId);
2455 $arSaveSet['ITEMS'][] = $arSaveItem;
2456 }
2457 unset($keyItem, $arOneItem);
2458 }
2459 if ($removeSet)
2460 {
2461 $boolCheck = true;
2462 $arSaveSet['DEL'] = 'Y';
2463 }
2464 else
2465 {
2466 $arTestSet = $arSaveSet;
2467 $boolCheck = (
2468 $boolNew
2469 ? CCatalogProductSet::checkFields('TEST', $arTestSet, 0)
2470 : CCatalogProductSet::checkFields('UPDATE', $arTestSet, $key)
2471 );
2472 unset($arTestSet);
2473 }
2474 unset($removeSet);
2475 if (!$boolCheck)
2476 {
2478 self::$arErrors[$key] = $ex->GetString();
2479 }
2480 else
2481 {
2482 self::$arCheckValues[self::$strMainPrefix][$key] = $arSaveSet;
2483 }
2484 break;
2485 }
2486
2488 return (empty(self::$arErrors));
2489 }
2490 return true;
2491 }
2492
2493 public static function saveFormValues($arItem)
2494 {
2496 if (!$boolFeatureSet)
2497 return;
2498
2499 if (0 >= $arItem['PRODUCT_ID'])
2500 return;
2501
2502 if (!empty(self::$arCheckValues[self::$strMainPrefix]))
2503 {
2504 foreach (self::$arCheckValues[self::$strMainPrefix] as $key => $arSaveSet)
2505 {
2506
2507 if (0 >= $arSaveSet['ITEM_ID'])
2508 $arSaveSet['ITEM_ID'] = $arItem['PRODUCT_ID'];
2509 $boolNew = (0 >= (int)$key);
2510 if ($boolNew)
2511 {
2512 if (!isset($arSaveSet['DEL']) || $arSaveSet['DEL'] != 'Y')
2513 CCatalogProductSet::add($arSaveSet);
2514 }
2515 else
2516 {
2517 if (isset($arSaveSet['DEL']) && $arSaveSet['DEL'] == 'Y')
2519 else
2520 CCatalogProductSet::update($key, $arSaveSet);
2521 }
2522 unset($boolNew);
2523 }
2524 unset($key, $arSaveSet);
2525 }
2526 }
2527
2528 public static function getErrors()
2529 {
2530 return self::$arErrors;
2531 }
2532}
$arParams
Определения access_dialog.php:21
$type
Определения options.php:106
const CATALOG_PAGE_SIZE
Определения include.php:111
global $APPLICATION
Определения include.php:80
$accessController
Определения options.php:23
$arResult
Определения generate_coupon.php:16
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
Определения catalog_reindex.php:36
$tabList
Определения catalog_reindex.php:107
static getCatalogServicesHelpLink()
Определения feature.php:315
static getProductSetsHelpLink()
Определения feature.php:245
static isProductSetsEnabled()
Определения feature.php:98
static isProductCardSliderEnabled()
Определения state.php:906
static isUsedInventoryManagement()
Определения state.php:42
static getExceedingProductLimit(int $iblockId, ?int $sectionId=null)
Определения state.php:165
static update($id, array $data)
Определения entity.php:229
static getList(array $parameters)
Определения entity.php:78
const STATUS_YES
Определения product.php:66
static getUfId()
Определения product.php:433
const TYPE_EMPTY_SKU
Определения product.php:75
const TYPE_SET
Определения product.php:71
const TYPE_SKU
Определения product.php:72
static getCurrentRatioWithMeasure($product)
Определения product.php:649
const TYPE_FREE_OFFER
Определения product.php:74
const TYPE_SERVICE
Определения product.php:76
const TYPE_OFFER
Определения product.php:73
static getProductTypes($descr=false)
Определения product.php:824
const TYPE_PRODUCT
Определения product.php:70
static get($moduleId, $name, $default="", $siteId=false)
Определения option.php:30
Определения loader.php:13
static includeModule($moduleName)
Определения loader.php:67
static getMessage($code, $replace=null, $language=null)
Определения loc.php:30
static getRow(array $parameters)
Определения datamanager.php:398
static getList(array $parameters=array())
Определения datamanager.php:431
static normalizeArrayValuesByInt(&$map, $sorted=true)
Определения collection.php:150
static sortByColumn(array &$array, $columns, $callbacks='', $defaultValueIfNotSetValue=null, $preserveKeys=false)
Определения collection.php:24
static showEditForm($arSets)
Определения admin_tools.php:2159
static setSkuFormParams($arParams)
Определения admin_tools.php:1915
static getTypeID()
Определения admin_tools.php:1895
static showItemRow($arRow, $arParams)
Определения admin_tools.php:2270
static $arErrors
Определения admin_tools.php:1873
static setMainPrefix($strPrefix)
Определения admin_tools.php:1877
static getErrors()
Определения admin_tools.php:2528
const NEW_ITEM_COUNT
Определения admin_tools.php:1867
static addEmptyValues(&$arSets)
Определения admin_tools.php:2055
static setProductFormParams($arParams)
Определения admin_tools.php:1900
static $intTypeID
Определения admin_tools.php:1872
static getItemsInfo(&$arSets)
Определения admin_tools.php:2071
static $strMainPrefix
Определения admin_tools.php:1871
static $arCheckValues
Определения admin_tools.php:1875
const PREFIX_SET
Определения admin_tools.php:1868
static checkFormValues($arItem)
Определения admin_tools.php:2384
static $arSrcValues
Определения admin_tools.php:1874
static getEmptyItem($arParams)
Определения admin_tools.php:1948
static getFormValues(&$arSets)
Определения admin_tools.php:1993
const PREFIX_GROUP
Определения admin_tools.php:1869
static getMainPrefix()
Определения admin_tools.php:1882
static getJSRow($arParams)
Определения admin_tools.php:2323
static setTypeID($intTypeID)
Определения admin_tools.php:1887
static saveFormValues($arItem)
Определения admin_tools.php:2493
static clearOwnerSet(&$arSets)
Определения admin_tools.php:2131
static getEmptySet($intProductID)
Определения admin_tools.php:1930
static allowedShowQuantityFields()
Определения admin_tools.php:1781
const TAB_SET
Определения admin_tools.php:27
static getIBlockElementMenu( $intIBlockID, &$arCatalog, $arParams, BaseBuilder $urlBuilder=null, $gridId='')
Определения admin_tools.php:134
const TAB_SERVICE
Определения admin_tools.php:29
static array $arErrors
Определения admin_tools.php:37
static setMainPrefix($strPrefix)
Определения admin_tools.php:1217
static getErrors()
Определения admin_tools.php:1237
const DELETE_SET
Определения admin_tools.php:33
static addTabParams(&$arParams)
Определения admin_tools.php:1278
static getCurrentTabFromRequest()
Определения admin_tools.php:94
const TAB_SKU
Определения admin_tools.php:26
const DELETE_GROUP
Определения admin_tools.php:34
static getSystemProductFieldsHtml(array $product, array $config)
Определения admin_tools.php:1410
static getTabDescriptions()
Определения admin_tools.php:64
static clearTabParams()
Определения admin_tools.php:1296
const TAB_KEY
Определения admin_tools.php:31
static needSummaryStoreAmountByPermissions()
Определения admin_tools.php:1772
static getShowTabs($intIBlockID, $intID, &$arCatalog)
Определения admin_tools.php:838
static setSkuFormParams()
Определения admin_tools.php:1232
static changeTabs($intIBlockID, $intID, &$arCatalog)
Определения admin_tools.php:1242
static getProductTypeList($withDescr=false)
Определения admin_tools.php:1382
static array $arCheckResult
Определения admin_tools.php:38
static getAllProductFieldsHtml(array $product, array $config)
Определения admin_tools.php:1418
const TAB_CATALOG
Определения admin_tools.php:25
static getClearedGridFields(array $options=[])
Определения admin_tools.php:1507
static getFormParams($params=array())
Определения admin_tools.php:1105
static getIblockProductTypeList($iblockId, $withDescr=false)
Определения admin_tools.php:1309
static getTabList(bool $boolFull=false)
Определения admin_tools.php:40
static string $strMainPrefix
Определения admin_tools.php:36
static getMainPrefix()
Определения admin_tools.php:1222
static setProductFormParams()
Определения admin_tools.php:1227
static saveSystemProductFields(array $product)
Определения admin_tools.php:1433
static getProductTypeForNewProduct(array $catalog)
Определения admin_tools.php:992
const TAB_GROUP
Определения admin_tools.php:28
static getFormProductTypeName(int $id)
Определения admin_tools.php:1066
static getIblockElementMenuLocked()
Определения admin_tools.php:122
static showFormParams()
Определения admin_tools.php:1116
const TAB_PRODUCT
Определения admin_tools.php:24
static getLockedGridFields(array $options=[])
Определения admin_tools.php:1558
static getProductTypeByTab(?string $tab)
Определения admin_tools.php:1042
static setCatalogPanelButtons(&$buttons, $iblock, $catalogButtons, $params, $windowParams)
Определения admin_tools.php:1130
static getIBlockElementContentMenu( $intIBlockID, $intID, &$arCatalog, $arParams, BaseBuilder $urlBuilder=null)
Определения admin_tools.php:437
static getSummaryStoreAmountByPermissions(array $productIds)
Определения admin_tools.php:1786
static deleteAllSetsByProduct($intProductID, $intSetType)
Определения product_set.php:169
static getErrors()
Определения product_set.php:47
static checkFields($strAction, &$arFields, $intID=0)
Определения product_set.php:68
static disableShowErrors()
Определения product_set.php:22
static enableShowErrors()
Определения product_set.php:17
const TYPE_SET
Определения product_set.php:9
const TYPE_GROUP
Определения product_set.php:10
static update($intID, $arFields)
Определения product_set.php:61
static delete($intID)
Определения product_set.php:145
static isProductInSet($intProductID, $intSetType=0)
Определения product_set.php:287
static add($arFields)
Определения product_set.php:10
$options
Определения commerceml2.php:49
$data['IS_AVAILABLE']
Определения .description.php:13
& nbsp
Определения epilog_main_admin.php:38
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$_REQUEST["admin_mnu_menu_id"]
Определения get_menu.php:8
$result
Определения get_property_values.php:14
$start
Определения get_search.php:9
$iblockId
Определения iblock_catalog_edit.php:30
$catalog
Определения iblock_catalog_edit.php:135
if(! $catalogEdit->isSuccess()) $iblock
Определения iblock_catalog_edit.php:38
htmlspecialcharsEx($str)
Определения tools.php:2685
bitrix_sessid_get($varname='sessid')
Определения tools.php:4695
Определения culture.php:9
return false
Определения prolog_main_admin.php:185
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
<? endif;?> window document title
Определения prolog_main_admin.php:76
$config
Определения quickway.php:69
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
font style
Определения invoice.php:442
font size
Определения invoice.php:442
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']
Определения template.php:799
$arCells
Определения template.php:223
$items
Определения template.php:224
$action
Определения file_dialog.php:21
$url
Определения iframe.php:7
if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_CATALOG_EXPORT_EDIT)) if((!isset($_REQUEST['IBLOCK_ID']))||($_REQUEST['IBLOCK_ID']=='')) $intIBlockID
Определения yandex_detail.php:44
$iterator
Определения yandex_run.php:610
$arCatalog
Определения yandex_run.php:674
else $permissionFilter
Определения yandex_run.php:45
$fields
Определения yandex_run.php:501