Тема выгрузки комплектов/наборов из 1С в Битрикс — достаточно давняя. Модули обмена между Битрикс и 1С в настоящий момент не поддерживают данного функционала, хотя, изучая код модулей, можно обнаружить обрывки кода, свидетельствующие о том, что данный функционал когда-то планировался.
Впервые столкнувшись с необходимостью выгрузки комплектов/наборов из 1С в Битрикс, я первоначально планировала раскомментировать эти забытые ошметки кода и использовать их, но потом отказалась от этой идеи, поняв, что можно сделать проще.
В различных конфигурациях 1С организация хранения комплектов/наборов осуществляется по-разному, однако это не имеет большого значения, и в данном посте я опишу достаточно универсальный и простой способ кастомизации интеграции для выгрузки комплектов.
Каким бы образом ни осуществлялось хранение наборов и комплектов в 1С, обычно стандартный модуль обмена выгружает комплект как простой товар (а если такой товар-комплект не выгружается вообще, сначала нужно добиться того, чтобы он выгружался в любом виде — добиться этого не сложно).
Далее задача сводится к тому, чтобы в реквизитах данного товара-комплекта передать данные о составе комплекта на сайт. Я решила делать это в таком виде:
<ЗначенияРеквизитов> <ЗначениеРеквизита> <Наименование>Комплектующее</Наименование> <Значение>Комплектующее1*25bb03f7-e953-11e7-8d71-002522ce173a*1</Значение> </ЗначениеРеквизита> <ЗначениеРеквизита> <Наименование>Комплектующее</Наименование> <Значение>Комплектующее2*25bb03ed-e953-11e7-8d71-002522ce173a*1</Значение> <ЗначениеРеквизита> <Наименование>ТипНоменклатуры</Наименование> <Значение>Комплект</Значение> </ЗначениеРеквизита> </ЗначенияРеквизитов>
В значении реквизита Комплектующее я передаю, разделяя звездочками, наименование комплектующего, его УИД и количество данного комплектующего для данного комплекта. Например, в комплекте «Спальня» будет 2 тумбочки и 1 кровать.
В качестве комплектующего можно брать как простой товар, так и конкретное торговое предложение. Наименование передается просто для упрощения отладки. Синхронизация идет по УИДам.
Забегая вперед, отмечу, что выгрузку комплектов по понятным причинам следует вести, когда составные части уже выгружены — это легко решается на стороне 1С созданием 2х узлов обмена с соответствующими отборами либо просто выгрузкой в 2 прохода.
Итак, у нас выгружается комплект в виде простого товара и мы решили, в каком виде мы хотим передать на сайт его состав. Осталось получить его состав. Я делаю это в процедуре ВыгрузитьТоварыXDTO, хотя мои читатели могут найти более оптимальный вариант, делаю запрос к базе и добавляю в реквизиты необходимую мне информацию о комплектующих.
Какой запрос? Те, к-е использовала я в своих последних кейсах, скорее всего, ничего не дадут моим читателям, потому что в разных конфигурациях и даже в разных версиях одной и той же конфигурации они будут разными. Пример:
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 | КомплектыСрезПоследних.Документ |ИЗ | РегистрСведений.Комплекты.СрезПоследних(, Комплект = &Комплект) КАК КомплектыСрезПоследних | |УПОРЯДОЧИТЬ ПО | ВЫБОР | КОГДА КомплектыСрезПоследних.ТипДокумента = ЗНАЧЕНИЕ(Перечисление.ТипыДокументовРазбораКомплектов.ТехнологическаяКарта) | ТОГДА 0 | ИНАЧЕ ВЫБОР | КОГДА КомплектыСрезПоследних.ТипДокумента = ЗНАЧЕНИЕ(Перечисление.ТипыДокументовРазбораКомплектов.Калькуляция) | ТОГДА 1 | ИНАЧЕ ВЫБОР | КОГДА КомплектыСрезПоследних.ТипДокумента = ЗНАЧЕНИЕ(Перечисление.ТипыДокументовРазбораКомплектов.ПропорцииРазделки) | ТОГДА 2 | ИНАЧЕ 3 | КОНЕЦ | КОНЕЦ | КОНЕЦ, | КомплектыСрезПоследних.Период УБЫВ"; Запрос.УстановитьПараметр("Комплект", ТекТовар.Номенклатура.Ссылка); Выборка = Запрос.Выполнить().Выбрать();
Но! Какая бы конфигурация у вас ни была, у вас в коде конфигурации есть готовый код этого запроса. Ищите глобальным поиском по слову КомплектыСрезПоследних или просто по слову Комплекты запрос, похожий на тот, что у меня в примере, и используйте его.
В итоге наша выгрузка товаров должна обладать теми дополнительными реквизитами, которые я привела выше.
Далее необходимо поработать на стороне сайта.
Нам нужен обработчик события OnAfterIBlockElementUpdate и OnAfterIBlockElementAdd — вешаемся на них и смотрим: если в реквизитах товара передан ТипНоменклатуры Комплект тогда перебираем реквизиты комплектующие, и ищем по внешним кодам товары и/или торговые предложения (как я уже отметила выше, в этот момент они уже должны быть на сайте). Далее на основании найденного готовим массив параметров для стандартных битриксовских функций работы с комплектами:
создание нового комплекта:
$arSaveSet = array( 'TYPE' => 1, 'ITEM_ID' => $arFields['ID'], 'ACTIVE' => "Y", 'ITEMS' => $items ); $setId = CCatalogProductSet::add($arSaveSet); CCatalogProductSet::recalculateSetsByProduct($arFields['ID']);
апдейт старого:
$arSaveSet = array( 'ITEMS' => $items ); CCatalogProductSet::update($arSetsByProduct['SET_ID'],$arSaveSet); // апдейт "комплекта" CCatalogProductSet::recalculateSetsByProduct($arFields['ID']);
В обработчике, естественно, нельзя забывать о возможности его зацикливания, а заодно и о том, что тип товара необходимо изменить, если мы только еще создаем комплект:
class YBWSMoyKomplectyImport { public static $disableHandler = false; function onAfterProductUpdate(&$arFields) { if (self::$disableHandler) return; ... self::$disableHandler = true; $arFields2 = array('TYPE' => 1); CCatalogProduct::Update($arFields['ID'], $arFields2); self::$disableHandler = false; ... } ... }
При наличии проблем с импортом комплектов, где комплектующее — предложение, обновляйте Битрикс до последней версии.
Если интеграция подвисает, уменьшайте количество товаров, выгружаемых в одном пакете, или выносите вышеуказанный запрос за цикл, переписав его таким образом, чтобы в качестве параметра он принимал не 1 товар, а массив.
Собственно, на этом все.