Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
productaction.php
1<?php
2
3namespace Bitrix\Catalog\Grid;
4
11use Bitrix\Crm;
13use Bitrix\Sale;
14
16{
17 public const SET_FIELD = 'product_field';
18 public const CHANGE_PRICE = 'change_price';
19 public const CONVERT_PRODUCT_TO_SERVICE = 'convert_to_service';
20 public const CONVERT_SERVICE_TO_PRODUCT = 'convert_to_product';
21
22 public static function updateSectionList(int $iblockId, array $sections, array $fields): Main\Result
23 {
24 $result = new Main\Result();
25
26 if ($iblockId <= 0)
27 {
28 $result->addError(new Main\Error(
29 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_IBLOCK_ID')
30 ));
31 return $result;
32 }
33
34 $catalog = \CCatalogSku::GetInfoByIBlock($iblockId);
35 if (empty($catalog))
36 {
37 $result->addError(new Main\Error(
38 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_CATALOG')
39 ));
40 return $result;
41 }
42
43 if (empty($fields))
44 {
45 $result->addError(new Main\Error(
46 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_EMPTY_FIELDS')
47 ));
48 return $result;
49 }
50
51 $filter = [];
52 $allowedTypes = static::getAllowedProductTypes($catalog, $fields);
53 if (empty($allowedTypes))
54 {
55 $result->addError(new Main\Error(
56 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_FIELDS')
57 ));
58 return $result;
59 }
60 $filter['=TYPE'] = $allowedTypes;
61 unset($allowedTypes);
62
63 $sectionElements = self::getSectionProducts($iblockId, $sections, $filter);
64 if (empty($sectionElements))
65 {
66 return $result;
67 }
68
69 $sectionIdList = array_keys($sectionElements);
70 $sectionNames = [];
71 $iterator = Iblock\SectionTable::getList([
72 'select' => [
73 'ID',
74 'NAME',
75 ],
76 'filter' => [
77 '@ID' => $sectionIdList,
78 '=IBLOCK_ID' => $iblockId,
79 ],
80 'order' => ['ID' => 'ASC'],
81 ]);
82 while ($row = $iterator->fetch())
83 {
84 $row['ID'] = (int)$row['ID'];
85 $sectionNames[$row['ID']] = $row['NAME'];
86 }
87 unset($row, $iterator);
88
89 foreach ($sectionIdList as $sectionId)
90 {
91 $elementResult = static::updateElementList(
92 $iblockId,
93 $sectionElements[$sectionId],
94 $fields
95 );
96 if (!$elementResult->isSuccess())
97 {
98 $result->addError(new Main\Error(
100 'BX_CATALOG_PRODUCT_ACTION_ERR_SECTION_PRODUCTS_UPDATE',
101 ['#ID#' => $sectionId, '#NAME#' => $sectionNames[$sectionId]]
102 ),
103 $sectionId
104 ));
105 }
106 }
107 unset($sectionId);
108 unset($sectionNames, $sectionIdList, $sectionElements);
109
110 return $result;
111 }
112
113 public static function updateElementList(int $iblockId, array $elementIds, array $fields): Main\Result
114 {
115 $result = new Main\Result();
116
117 if ($iblockId <= 0)
118 {
119 $result->addError(new Main\Error(
120 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_IBLOCK_ID')
121 ));
122 return $result;
123 }
124 Main\Type\Collection::normalizeArrayValuesByInt($elementIds, true);
125 if (empty($elementIds))
126 {
127 $result->addError(new Main\Error(
128 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_EMPTY_ELEMENTS')
129 ));
130 return $result;
131 }
132 if (empty($fields))
133 {
134 $result->addError(new Main\Error(
135 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_EMPTY_FIELDS')
136 ));
137 return $result;
138 }
139 $catalog = \CCatalogSku::GetInfoByIBlock($iblockId);
140 if (empty($catalog))
141 {
142 $result->addError(new Main\Error(
143 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_CATALOG')
144 ));
145 return $result;
146 }
147
148 $allowedTypes = static::getAllowedProductTypes($catalog, $fields);
149 if (empty($allowedTypes))
150 {
151 $result->addError(new Main\Error(
152 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_FIELDS')
153 ));
154 return $result;
155 }
156
157 $productResult = self::getProductListByTypeForModify($elementIds, $allowedTypes);
158 $data = $productResult->getData();
159 $newProducts = $data['NEW_PRODUCT_IDS'] ?? [];
160 $existProducts = $data['EXIST_PRODUCT_IDS'] ?? [];
161 unset($data);
162 if (!$productResult->isSuccess())
163 {
164 $result->addErrors($productResult->getErrors());
165 }
166 unset($productResult);
167
168 if (empty($newProducts) && empty($existProducts))
169 {
170 return $result;
171 }
172
173 $data = [
174 'fields' => $fields,
175 'external_fields' => [
176 'IBLOCK_ID' => $iblockId
177 ]
178 ];
179 foreach ($existProducts as $id)
180 {
181 $elementResult = Catalog\Model\Product::update($id, $data);
182 if (!$elementResult->isSuccess())
183 {
184 $result->addError(new Main\Error(
185 implode('; ', $elementResult->getErrorMessages()),
186 $id
187 ));
188 }
189 }
190 foreach ($newProducts as $id)
191 {
192 $data['fields']['ID'] = $id;
193 $elementResult = Catalog\Model\Product::add($data);
194 if (!$elementResult->isSuccess())
195 {
196 $result->addError(new Main\Error(
197 implode('; ', $elementResult->getErrorMessages()),
198 $id
199 ));
200 }
201 }
202 unset($elementResult, $id, $data);
203 unset($newProducts, $existProducts);
204 unset($blackList, $catalog);
205
206 return $result;
207 }
208
209 protected static function getSectionProducts(int $iblockId, array $sections, array $filter): ?array
210 {
211 global $USER;
212
213 if (!(isset($USER) && $USER instanceof \CUser))
214 {
215 return null;
216 }
217
218 if (!AccessController::getCurrent()->check(ActionDictionary::ACTION_PRODUCT_EDIT))
219 {
220 return null;
221 }
222
223 if ($iblockId <= 0)
224 {
225 return null;
226 }
227 Main\Type\Collection::normalizeArrayValuesByInt($sections, false);
228 if (empty($sections))
229 {
230 return null;
231 }
232
233 $filter['IBLOCK_ID'] = $iblockId;
234 $filter['INCLUDE_SUBSECTIONS'] = 'Y';
235 $filter['CHECK_PERMISSIONS'] = 'Y';
236 $filter['MIN_PERMISSION'] = 'R';
237
238 $dublicates = [];
239 $result = [];
240 foreach ($sections as $sectionId)
241 {
242 $result[$sectionId] = [];
243 $elements = [];
244 $filter['SECTION_ID'] = $sectionId;
245 $iterator = \CIBlockElement::GetList(
246 ['ID' => 'ASC'],
247 $filter,
248 false,
249 false,
250 ['ID']
251 );
252 while ($row = $iterator->fetch())
253 {
254 $id = (int)$row['ID'];
255 if (isset($dublicates[$id]))
256 {
257 continue;
258 }
259 $dublicates[$id] = true;
260 $elements[] = $id;
261 }
262 unset($id, $row, $iterator);
263
264 if (!empty($elements))
265 {
266 $operations = \CIBlockElementRights::UserHasRightTo(
267 $iblockId,
268 $elements,
269 '',
270 \CIBlockRights::RETURN_OPERATIONS
271 );
272 foreach ($elements as $elementId)
273 {
274 if (
275 isset($operations[$elementId]['element_edit'])
276 && isset($operations[$elementId]['element_edit_price'])
277 )
278 {
279 $result[$sectionId][] = $elementId;
280 }
281 }
282 unset($elementId);
283 unset($operations);
284 }
285 unset($elements);
286
287 if (empty($result[$sectionId]))
288 {
289 unset($result[$sectionId]);
290 }
291 }
292 unset($sectionId);
293 unset($dublicates);
294
295 return (!empty($result) ? $result : null);
296 }
297
298 public static function getAllowedProductTypes(array $catalog, array $fields): array
299 {
300 static $list = null;
301
302 if (empty($fields))
303 {
304 return [];
305 }
306
307 if ($list === null)
308 {
309 $list = [
310 'WEIGHT',
311 'QUANTITY',
312 'QUANTITY_TRACE',
313 'CAN_BUY_ZERO',
314 'VAT_INCLUDED',
315 'VAT_ID',
316 'SUBSCRIBE',
317 'MEASURE',
318 'PURCHASING_PRICE',
319 'PURCHASING_CURRENCY',
320 ];
321 $baseTypes = [
322 Catalog\ProductTable::TYPE_PRODUCT,
323 Catalog\ProductTable::TYPE_OFFER,
324 CATALOG\ProductTable::TYPE_FREE_OFFER,
325 ];
326 if (
327 $catalog['CATALOG_TYPE'] === \CCatalogSku::TYPE_FULL
328 && Main\Config\Option::get('catalog', 'show_catalog_tab_with_offers') === 'Y'
329 )
330 {
331 $baseTypes[] = Catalog\ProductTable::TYPE_SKU;
332 }
333 $list = array_fill_keys($list, $baseTypes);
334 unset($baseTypes);
335
336 $list['VAT_INCLUDED'][] = Catalog\ProductTable::TYPE_SET;
337 $list['VAT_ID'][] = Catalog\ProductTable::TYPE_SET;
338 $list['SUBSCRIBE'][] = Catalog\ProductTable::TYPE_SET;
339
340 $list += Catalog\Product\SystemField::getAllowedProductTypes();
341 }
342
343 $result = [];
344 foreach (array_keys($fields) as $fieldName)
345 {
346 if (!isset($list[$fieldName]))
347 {
348 $result = [];
349 break;
350 }
351 $result[] = $list[$fieldName];
352 }
353
354 if (!empty($result))
355 {
356 if (count($result) === 1)
357 {
358 $result = reset($result);
359 }
360 else
361 {
362 $check = array_shift($result);
363 foreach ($result as $row)
364 {
365 $check = array_intersect($check, $row);
366 }
367 unset($row);
368 $result = array_values($check);
369 unset($check);
370 }
371 sort($result);
372 }
373
374 return $result;
375 }
376
377 public static function convertToServiceSectionList(int $iblockId, array $sections): Main\Result
378 {
379 return self::convertTypeSectionList($iblockId, $sections, Catalog\ProductTable::TYPE_PRODUCT);
380 }
381
382 public static function convertToProductSectionList(int $iblockId, array $sections): Main\Result
383 {
384 return self::convertTypeSectionList($iblockId, $sections, Catalog\ProductTable::TYPE_SERVICE);
385 }
386
387 public static function convertToServiceElementList(int $iblockId, array $elementIds): Main\Result
388 {
389 return self::convertTypeElementList($iblockId, $elementIds, Catalog\ProductTable::TYPE_PRODUCT);
390 }
391
392 public static function convertToProductElementList(int $iblockId, array $elementIds): Main\Result
393 {
394 return self::convertTypeElementList($iblockId, $elementIds, Catalog\ProductTable::TYPE_SERVICE);
395 }
396
397 private static function convertTypeSectionList(int $iblockId, array $sections, int $type): Main\Result
398 {
399 $result = new Main\Result();
400
401 if ($iblockId <= 0)
402 {
403 $result->addError(new Main\Error(
404 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_IBLOCK_ID')
405 ));
406
407 return $result;
408 }
409
410 $catalog = \CCatalogSku::GetInfoByIBlock($iblockId);
411 if (empty($catalog))
412 {
413 $result->addError(new Main\Error(
414 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_CATALOG')
415 ));
416
417 return $result;
418 }
419
420 $filter = [
421 '=TYPE' => $type,
422 ];
423
424 $sectionElements = self::getSectionProducts($iblockId, $sections, $filter);
425 if (empty($sectionElements))
426 {
427 return $result;
428 }
429
430 $sectionIdList = array_keys($sectionElements);
431 $sectionNames = [];
432 $iterator = Iblock\SectionTable::getList([
433 'select' => [
434 'ID',
435 'NAME',
436 ],
437 'filter' => [
438 '@ID' => $sectionIdList,
439 '=IBLOCK_ID' => $iblockId,
440 ],
441 'order' => ['ID' => 'ASC'],
442 ]);
443 while ($row = $iterator->fetch())
444 {
445 $row['ID'] = (int)$row['ID'];
446 $sectionNames[$row['ID']] = $row['NAME'];
447 }
448 unset($row, $iterator);
449
450 foreach ($sectionIdList as $sectionId)
451 {
452 $elementResult = self::convertTypeElementList(
453 $iblockId,
454 $sectionElements[$sectionId],
455 $type
456 );
457 if (!$elementResult->isSuccess())
458 {
459 $result->addError(new Main\Error(
461 $type === Catalog\ProductTable::TYPE_PRODUCT
462 ? 'BX_CATALOG_PRODUCT_ACTION_ERR_SECTION_PRODUCTS_CONVERT'
463 : 'BX_CATALOG_PRODUCT_ACTION_ERR_SECTION_SERVICES_CONVERT'
464 ,
465 [
466 '#ID#' => $sectionId,
467 '#NAME#' => $sectionNames[$sectionId],
468 ]
469 ),
471 ));
472 }
473 $data = $elementResult->getData();
474 if (isset($data['CONVERT_COMPLETE']))
475 {
476 $result->setData(['CONVERT_COMPLETE' => 'Y']);
477 }
478 }
479 unset($sectionId);
480 unset($sectionNames, $sectionIdList, $sectionElements);
481
482 return $result;
483 }
484
485 private static function convertTypeElementList(int $iblockId, array $elementIds, int $type): Main\Result
486 {
487 $result = new Main\Result();
488
489 if ($iblockId <= 0)
490 {
491 $result->addError(new Main\Error(
492 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_IBLOCK_ID')
493 ));
494
495 return $result;
496 }
497
498 $catalog = \CCatalogSku::GetInfoByIBlock($iblockId);
499 if (empty($catalog))
500 {
501 $result->addError(new Main\Error(
502 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_BAD_CATALOG')
503 ));
504
505 return $result;
506 }
507
508 Main\Type\Collection::normalizeArrayValuesByInt($elementIds, true);
509 if (empty($elementIds))
510 {
511 $result->addError(new Main\Error(
512 Loc::getMessage('BX_CATALOG_PRODUCT_ACTION_ERR_EMPTY_ELEMENTS')
513 ));
514
515 return $result;
516 }
517
518 $productResult = self::getProductListByTypeForConversion($elementIds, $type);
519 $data = $productResult->getData();
520 $products = $data['PRODUCT_IDS'] ?? [];
521 unset($data);
522 if (!$productResult->isSuccess())
523 {
524 $result->addErrors($productResult->getErrors());
525 }
526 unset($productResult);
527 if (empty($products))
528 {
529 return $result;
530 }
531
532 $inventoryResult = self::checkInventoryDocumentByProducts($products);
533 $data = $inventoryResult->getData();
534 $products = $data['PRODUCT_IDS'] ?? [];
535 unset($data);
536 if (!$inventoryResult->isSuccess())
537 {
538 $result->addErrors($inventoryResult->getErrors());
539 }
540 unset($inventoryResult);
541 if (empty($products))
542 {
543 return $result;
544 }
545
546 $convertResult = self::convertCatalogType($products, $type);
547 if (!$convertResult->isSuccess())
548 {
549 $result->addErrors($convertResult->getErrors());
550 }
551 $data = $convertResult->getData();
552 if (isset($data['CONVERT_COMPLETE']))
553 {
554 $result->setData(['CONVERT_COMPLETE' => 'Y']);
555 }
556
557 return $result;
558 }
559
560 private static function getProductListByTypeForModify(array $elementIds, array $types): Main\Result
561 {
562 $result = new Main\Result();
563
564 $types = array_fill_keys($types, true);
565
566 $existList = [];
567 $newList = array_fill_keys($elementIds, true);
568 $errorList = [];
569
570 foreach (array_chunk($elementIds, 500) as $pageIds)
571 {
572 $iterator = Catalog\ProductTable::getList([
573 'select' => [
574 'ID',
575 'TYPE',
576 ],
577 'filter' => [
578 '@ID' => $pageIds,
579 ]
580 ]);
581 while ($row = $iterator->fetch())
582 {
583 $row['ID'] = (int)$row['ID'];
584 $row['TYPE'] = (int)$row['TYPE'];
585 unset($newList[$row['ID']]);
586 if (isset($types[$row['TYPE']]))
587 {
588 $existList[] = $row['ID'];
589 }
590 else
591 {
592 $errorList[] = $row['ID'];
593 }
594 }
595 unset($row, $iterator);
596 }
597
598 $result->setData([
599 'EXIST_PRODUCT_IDS' => $existList,
600 'NEW_PRODUCT_IDS' => array_values($newList),
601 ]);
602 unset($existList, $newList);
603
604 if (!empty($errorList))
605 {
606 $names = [];
607 $iterator = Iblock\ElementTable::getList([
608 'select' => [
609 'ID',
610 'NAME',
611 ],
612 'filter' => [
613 '@ID' => $errorList,
614 ],
615 ]);
616 while ($row = $iterator->fetch())
617 {
618 $names[] = '[' . $row['ID'] . '] ' . $row['NAME'];
619 }
620 unset($row, $iterator);
621 $result->addError(new Main\Error(
623 'BX_CATALOG_PRODUCT_ACTION_ERR_CANNOT_SET_FIELD_BY_TYPE',
624 [
625 '#NAMES#' => implode(', ', $names),
626 ]
627 )
628 ));
629 unset($names);
630 }
631 unset($errorList);
632
633 return $result;
634 }
635
636 private static function getProductListByTypeForConversion(array $elementIds, int $type): Main\Result
637 {
638 $result = new Main\Result();
639
640 $validList = [];
641 $errorList = [];
642
643 foreach (array_chunk($elementIds, 500) as $pageIds)
644 {
645 $iterator = Catalog\ProductTable::getList([
646 'select' => [
647 'ID',
648 'TYPE',
649 ],
650 'filter' => [
651 '@ID' => $pageIds,
652 ]
653 ]);
654 while ($row = $iterator->fetch())
655 {
656 $row['ID'] = (int)$row['ID'];
657 $row['TYPE'] = (int)$row['TYPE'];
658 if ($row['TYPE'] === $type)
659 {
660 $validList[] = $row['ID'];
661 }
662 else
663 {
664 $errorList[] = $row['ID'];
665 }
666 }
667 unset($row, $iterator);
668 }
669
670 $result->setData(['PRODUCT_IDS' => $validList]);
671 unset($validList);
672 if (!empty($errorList))
673 {
674 $names = [];
675 $iterator = Iblock\ElementTable::getList([
676 'select' => [
677 'ID',
678 'NAME',
679 ],
680 'filter' => [
681 '@ID' => $errorList,
682 ],
683 ]);
684 while ($row = $iterator->fetch())
685 {
686 $names[] = '[' . $row['ID'] . '] ' . $row['NAME'];
687 }
688 unset($row, $iterator);
689 if ($type === Catalog\ProductTable::TYPE_PRODUCT)
690 {
691 $result->addError(new Main\Error(
693 'BX_CATALOG_PRODUCT_ACTION_ERR_SELECTED_NOT_SIMPLE_PRODUCT',
694 ['#NAMES#' => implode(', ', $names)]
695 )
696 ));
697 }
698 else
699 {
700 $result->addError(new Main\Error(
702 'BX_CATALOG_PRODUCT_ACTION_ERR_SELECTED_NOT_SERVICE',
703 ['#NAMES#' => implode(', ', $names)]
704 )
705 ));
706 }
707 unset($names);
708 }
709 unset($errorList);
710
711 return $result;
712 }
713
714 private static function checkInventoryDocumentByProducts(array $elementIds): Main\Result
715 {
716 $result = new Main\Result();
717 if (!Catalog\Config\State::isUsedInventoryManagement())
718 {
719 $result->setData(['PRODUCT_IDS' => $elementIds]);
720
721 return $result;
722 }
723
724 $validList = array_fill_keys($elementIds, true);
725 $errorList = [];
726
727 $query = new ORM\Query\Query(Catalog\StoreDocumentElementTable::getEntity());
728 $query->setDistinct(true);
729 $query->setSelect([
730 'ELEMENT_ID',
731 'NAME' => 'ELEMENT.NAME'
732 ]);
733 $query->setFilter(['=DOCUMENT.STATUS' => 'Y']);
734
735 foreach (array_chunk($elementIds, 500) as $pageIds)
736 {
737 $query->addFilter('@ELEMENT_ID', $pageIds);
738 $iterator = $query->exec();
739 while ($row = $iterator->fetch())
740 {
741 $id = (int)$row['ELEMENT_ID'];
742 unset($validList[$id]);
743 $errorList[] = '[' . $row['ELEMENT_ID'] . '] ' . $row['NAME'];
744 }
745 unset($row, $iterator);
746 }
747 unset($pagesIds);
748 unset($query);
749
750 $result->setData(['PRODUCT_IDS' => array_keys($validList)]);
751 if (!empty($errorList))
752 {
753 $result->addError(new Main\Error(
755 'BX_CATALOG_PRODUCT_ACTION_ERR_SELECTED_INVENTORY_PRODUCTS',
756 ['#NAMES#' => implode(', ', $errorList)]
757 )
758 ));
759 }
760
761 return $result;
762 }
763
764 private static function convertCatalogType(array $elementIds, int $type): Main\Result
765 {
766 $result = new Main\Result();
767
768 $connection = Main\Application::getConnection();
769 $helper = $connection->getSqlHelper();
770
771 $sqlMain = 'update ' . $helper->quote(Catalog\ProductTable::getTableName());
772
773 if ($type === Catalog\ProductTable::TYPE_PRODUCT)
774 {
775 $sqlMain .= ' set ' . $helper->quote('TYPE') . ' = ' . Catalog\ProductTable::TYPE_SERVICE
776 . ', ' . $helper->quote('QUANTITY') . ' = ('
777 . 'CASE WHEN ' . $helper->quote('AVAILABLE') . ' = \'Y\' THEN 1 ELSE 0 END'
778 . '), ' . $helper->quote('QUANTITY_RESERVED') . ' = 0'
779 . ', ' . $helper->quote('QUANTITY_TRACE') . ' = \'N\''
780 . ', ' . $helper->quote('CAN_BUY_ZERO') . ' = \'Y\''
781 . ', ' . $helper->quote('NEGATIVE_AMOUNT_TRACE') . ' = \'Y\''
782 ;
783 }
784 else
785 {
786 $available = Catalog\ProductTable::calculateAvailable([
787 'QUANTITY' => 0,
788 'QUANTITY_TRACE' => Catalog\ProductTable::STATUS_DEFAULT,
789 'CAN_BUY_ZERO' => Catalog\ProductTable::STATUS_DEFAULT,
790 ]);
791 $sqlMain .= ' set ' . $helper->quote('TYPE') . ' = ' . Catalog\ProductTable::TYPE_PRODUCT
792 . (Catalog\Config\State::isUsedInventoryManagement()
793 ? ', ' . $helper->quote('AVAILABLE') . ' = \'' . $helper->forSql($available) . '\', '
794 . $helper->quote('QUANTITY') . ' = 0'
795 : ''
796 )
797 . ', ' . $helper->quote('QUANTITY_TRACE') . ' = \'D\''
798 . ', ' . $helper->quote('CAN_BUY_ZERO') . ' = \'D\''
799 . ', ' . $helper->quote('NEGATIVE_AMOUNT_TRACE') . ' = \'D\''
800 ;
801 }
802
803 $sqlMain .= ', ' . $helper->quote('TIMESTAMP_X') . ' = ' . $helper->quote('TIMESTAMP_X')
804 . ' where ID in ('
805 ;
806
807 $sqlStores = 'delete from ' . $helper->quote(Catalog\StoreProductTable::getTableName())
808 . ' where PRODUCT_ID in ('
809 ;
810
811 foreach (array_chunk($elementIds, 500) as $pageIds)
812 {
813 $list = implode(',', $pageIds);
814 $connection->query($sqlMain . $list . ')');
815
816 if ($type === Catalog\ProductTable::TYPE_PRODUCT)
817 {
818 $connection->query($sqlStores . $list . ')');
819 $result = self::convertToService($pageIds);
820 }
821 else
822 {
823 $result = self::convertToProduct($pageIds);
824 }
825 if (!$result->isSuccess())
826 {
827 return $result;
828 }
829 }
830
831 $result->setData(['CONVERT_COMPLETE' => 'Y']);
832
833 return $result;
834 }
835
842 protected static function convertToProduct(array $productIdList): Main\Result
843 {
844 return self::convert($productIdList, Catalog\ProductTable::TYPE_PRODUCT);
845 }
846
853 protected static function convertToService(array $productIdList): Main\Result
854 {
855 return self::convert($productIdList, Catalog\ProductTable::TYPE_SERVICE);
856 }
857
858 private static function convert(array $productIdList, int $catalogType): Main\Result
859 {
860 $result = new Main\Result();
861
862 if (Main\Loader::includeModule('crm'))
863 {
864 $convertCrmProductResult = self::convertCrmProducts($productIdList, $catalogType);
865 if (!$convertCrmProductResult->isSuccess())
866 {
867 $result->addErrors($convertCrmProductResult->getErrors());
868 }
869 }
870
871 if (Main\Loader::includeModule('sale'))
872 {
873 $convertSaleProductResult = self::convertSaleProducts($productIdList, $catalogType);
874 if (!$convertSaleProductResult->isSuccess())
875 {
876 $result->addErrors($convertSaleProductResult->getErrors());
877 }
878 }
879
880 return $result;
881 }
882
883 private static function convertCrmProducts(array $productIdList, int $type): Main\Result
884 {
885 $connection = Main\Application::getConnection();
886 $helper = $connection->getSqlHelper();
887
888 $productIdSql = $helper->forSql(implode(',', $productIdList));
889 $sql = sprintf(
890 'UPDATE %s SET TYPE = %d WHERE PRODUCT_ID IN (%s)',
891 $helper->quote(Crm\ProductRowTable::getTableName()),
892 $type,
893 $productIdSql
894 );
895
896 try
897 {
898 $connection->query($sql);
899 }
900 catch (Main\DB\SqlQueryException $exception)
901 {
902 return (new Main\Result())->addError(new Main\Error($exception->getMessage()));
903 }
904
905 return new Main\Result();
906 }
907
908 private static function convertSaleProducts(array $productIdList, int $type): Main\Result
909 {
910 $saleType = Sale\Internals\Catalog\ProductTypeMapper::getType($type);
911
912 $connection = Main\Application::getConnection();
913 $helper = $connection->getSqlHelper();
914
915 $productIdSql = $helper->forSql(implode(',', $productIdList));
916 $sql = sprintf(
917 'UPDATE %s SET TYPE = %s WHERE PRODUCT_ID IN (%s)',
918 $helper->quote(Sale\Internals\BasketTable::getTableName()),
919 $saleType ?: $helper->convertToDb($saleType),
920 $productIdSql
921 );
922
923 try
924 {
925 $connection->query($sql);
926 }
927 catch (Main\DB\SqlQueryException $exception)
928 {
929 return (new Main\Result())->addError(new Main\Error($exception->getMessage()));
930 }
931
932 return new Main\Result();
933 }
934}
static convertToProductSectionList(int $iblockId, array $sections)
static convertToProduct(array $productIdList)
static convertToServiceSectionList(int $iblockId, array $sections)
static updateElementList(int $iblockId, array $elementIds, array $fields)
static convertToServiceElementList(int $iblockId, array $elementIds)
static getAllowedProductTypes(array $catalog, array $fields)
static getSectionProducts(int $iblockId, array $sections, array $filter)
static convertToProductElementList(int $iblockId, array $elementIds)
static updateSectionList(int $iblockId, array $sections, array $fields)
static convertToService(array $productIdList)
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29