Выгрузка торговых предложений из 1С - цены, характеристики, пакетный режим
Разбираемся, как характеристики номенклатуры 1С превращаются в торговые предложения и почему цены у них приезжают не всегда.
Решение
Смотрим, что приехало в инфоблок предложений:
$sku = CCatalogSku::GetInfoByProductIBlock($productIblockId);$offers = CIBlockElement::GetList([], ['IBLOCK_ID' => $sku['IBLOCK_ID']], []);$linked = CIBlockElement::GetList([], [ 'IBLOCK_ID' => $sku['IBLOCK_ID'], '!PROPERTY_' . $sku['SKU_PROPERTY_ID'] => false,], []);echo "предложений {$offers}, из них с родителем {$linked}\n";Расхождение между числами - главный индикатор. Предложения приезжают отдельной пачкой после товаров, и осиротевшие означают, что родители не доехали или сменили внешний код.
Сверяем типы цен сайта с типами из 1С:
$types = CCatalogGroup::GetList([], [], false, false, ['ID', 'NAME', 'XML_ID']);while ($type = $types->Fetch()) { printf("%3d %-20s xml_id=%s\n", $type['ID'], $type['NAME'], $type['XML_ID']);}Цены сопоставляются по внешнему коду типа цены, а не по названию. Тип с пустым
XML_ID заведён на сайте руками, и обмен в него не пишет - именно так цены
«не выгружаются» при формально успешном обмене.
Отключаем пакетный режим, когда выгрузка сбоит:
// поэлементный разбор медленнее, но не теряет позиции на больших пачкахCOption::SetOptionString('catalog', 'use_offers_batch', 'N');COption::SetOptionString('catalog', 'import_size', '10');В пакетном режиме предложения пишутся группами, и одна ошибочная позиция роняет всю группу. Поэлементный разбор пропустит только сбойное предложение.
Обновляем цены отдельно от номенклатуры:
$result = CPrice::SetBasePrice($offerId, 1990, 'RUB');if (!$result) { echo "цена не записана: ", $APPLICATION->GetException()->GetString(), "\n";}Полная выгрузка ради изменившихся цен не нужна: 1С умеет присылать только файл цен, а на стороне сайта цены пишутся тем же способом, что и при обмене.
Порядок пачек внутри сеанса задаёт сама 1С, и повлиять на него с сайта нельзя. Товары идут первыми, предложения вторыми, цены и остатки последними. Обрыв между любыми двумя пачками оставляет каталог в промежуточном состоянии, и по одному только слову об успехе в логе этого не видно.
Считаем предложения с непустой ценой:
$priced = CPrice::GetList([], [ 'PRODUCT_IBLOCK_ID' => $sku['IBLOCK_ID'], 'CATALOG_GROUP_ID' => $basePriceTypeId,], []);echo "предложений с базовой ценой: {$priced}\n";Третье число закрывает картину: предложение может доехать, привязаться к товару и остаться без цены, если тип цены не сопоставился.
Проверять результат поэтому надо не по логу, а по данным. Три числа - сколько предложений, сколько из них с родителем, сколько с непустой ценой - описывают состояние каталога полнее любого протокола. Расхождение между ними сразу называет пачку, на которой сеанс остановился.
Типичные проблемы
Предложения приехали, а цены у них пустые.
Тип цены на сайте заведён руками и не имеет внешнего кода. Обмен сопоставляет типы цен по XML_ID, и без него пишет в никуда.
Из партии предложений приехала только часть.
Пакетный режим: группа пишется целиком, и одна сбойная позиция отменяет всю группу. Поэлементный разбор теряет только саму сбойную.
Печатные наименования предложений не обновились.
Название предложения обмен собирает из характеристик, а не берёт из наименования 1С. Своё название удерживают обработчиком на OnBeforeIBlockElementUpdate.
Остатки по предложениям нулевые при непустом складе.
Остатки идут отдельным файлом после номенклатуры. Если сеанс оборвался между файлами, предложения уже есть, а количество не записано.
Частые вопросы
Как получить идентификатор товара по идентификатору предложения?
Методом CCatalogSku::GetProductInfo($offerId, $offerIblockId). Он возвращает массив с ключом ID родителя либо false, если привязка пуста. Обратная задача решается выборкой по свойству привязки.
Можно ли завести предложения импортом из CSV?
Да, штатным импортом инфоблока, но привязку к товару придётся заполнять колонкой со значением свойства. Проще выгрузить их из 1С: там связь строится по внешним кодам автоматически.
Почему характеристика 1С приехала как отдельный товар?
Значит в узле обмена не включена выгрузка характеристик как торговых предложений. Без этого признака 1С шлёт их обычной номенклатурой, и на сайте они ложатся в инфоблок товаров.
Как подменить цену предложения на витрине?
Своим кодом на событии получения цены, а не правкой в базе: записанную цену перепишет следующий обмен. Скидки и наценки для этого и предназначены.
Смежное
- Торговые предложения - оглавление подтемы
- Торговые предложения: настройка и связь с товаром - как устроена привязка
- Каталог и продажи - устройство каталога целиком
- Обмен: выгрузка товаров - как приезжают сами товары
- Не выгружаются характеристики из 1С: торговые предложения после обмена - разбор, если предложения не приехали