Перейти к содержимому

Выгрузка товаров из 1С на сайт - настройка, запуск и проверка

Настраиваем выгрузку каталога из 1С в Битрикс и делаем так, чтобы правки сайта переживали обмен.

Решение

Заводим отдельного пользователя обмена и даём ему право на каталог:

$user = new CUser();
$id = $user->Add([
'LOGIN' => 'exchange1c', // отдельная запись только для обмена
'GROUP_ID' => [12], // группа с правами на обмен
'PASSWORD' => $password,
'CONFIRM_PASSWORD' => $password,
'NAME' => 'Обмен с 1С',
'GROUP_ID' => [1], // группа с правом на обмен, не «все пользователи»
'ACTIVE' => 'Y',
]);

Отдельный пользователь нужен не ради порядка. По его действиям в журнале видно, что изменил обмен, а что человек, и его можно отключить, не трогая администратора.

Указываем адрес приёмника в узле обмена 1С:

http://example.com/bitrix/admin/1c_exchange.php
# этот же адрес обслуживает и каталог, и заказы: тип передаётся параметром

Инициатор обмена всегда 1С. Со стороны сайта запустить выгрузку нечем, расписание живёт в узле обмена 1С, а не в агентах Битрикса.

Ставим размер пачки под лимит времени PHP:

// Настройки - Настройки модулей - Торговый каталог
COption::SetOptionString('catalog', 'import_interval', '30'); // секунд на шаг
COption::SetOptionString('catalog', 'import_size', '20'); // элементов за шаг

Обмен идёт шагами: сайт обрабатывает пачку и возвращает управление 1С. Если пачка не укладывается в max_execution_time, процесс обрывается на середине, и часть каталога остаётся необновлённой.

Защищаем поля, которые правятся на сайте:

/local/php_interface/init.php
AddEventHandler('iblock', 'OnBeforeIBlockElementUpdate', 'protectSiteFields');
function protectSiteFields(&$arFields)
{
if (($_REQUEST['mode'] ?? '') !== 'import') {
return; // правка руками, ничего не трогаем
}
unset($arFields['NAME'], $arFields['DETAIL_TEXT']);
}

Признак mode=import в запросе отличает обмен от ручной правки в админке. Всё, что не пришло из 1С, обмен считает лишним и затирает.

Проверяем результат по логу и числу активных элементов:

Окно терминала
tail -n 40 /home/bitrix/www/upload/1c_catalog/*.log

Лог называет шаг, на котором обмен остановился, и число обработанных элементов на каждом шаге. Строку с ошибкой ищем по слову FAILURE.

Сверяем число активных элементов инфоблока:

$count = CIBlockElement::GetList([], ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'], []);
echo "активных элементов: {$count}\n";

Пустой каталог при успешном обмене почти всегда означает, что товары приехали в другой инфоблок: в узле обмена 1С указан не тот тип каталога. Расхождение на десяток элементов обычно даёт деактивация - удалённые в 1С позиции остаются в базе, но перестают быть активными.

Проверять надо на копии каталога, а не на боевом. Обмен пишет в базу сразу, отката у него нет, и ошибка в настройке узла разъезжается по всему инфоблоку за один прогон.

Типичные проблемы

Товары после выгрузки приехали дважды.

Сопоставление идёт по полю XML_ID. После переноса базы 1С или смены узла обмена внешние коды меняются, совпадения не находится, и элементы создаются заново. Старые при этом остаются активными.

Названия и описания, поправленные на сайте, вернулись к старым.

Обмен перезаписывает всё, что пришло из 1С. Поля, которые ведёт контент-менеджер, снимают обработчиком на OnBeforeIBlockElementUpdate по признаку mode=import.

Товары, удалённые в 1С, остались на сайте активными.

Деактивацию включает отдельная настройка обмена. Без неё 1С просто не присылает такие элементы, а сайт трактует отсутствие как «не менялось», а не как «удалено».

Обмен обрывается на большом каталоге.

Пачка не укладывается в лимит времени PHP. Уменьшают import_size в настройках модуля catalog, а не увеличивают лимит на весь сайт.

Цены приехали, а товары нет.

Цены и номенклатура идут разными файлами. Файл цен разобрался, файл товаров - нет, и в логе виден именно его шаг.

Частые вопросы

Можно ли запускать обмен со стороны сайта, агентом или по cron?

Нет. Протокол устроен так, что подключается 1С, а сайт только отвечает на её запросы. Расписание задаётся в узле обмена 1С. Единственное, что делают на стороне сайта, - следят, чтобы 1c_exchange.php был доступен и не закрыт авторизацией по IP.

Почему товар приезжает без раздела?

Разделы связываются тем же внешним кодом, что и товары. Если группа номенклатуры в 1С не выгружается или её код изменился, товар приедет в корень инфоблока. Проверяют выгрузку групп отдельно от выгрузки товаров.

Как выгрузить только изменённые товары?

Это режим самой 1С: в узле обмена включается выгрузка только изменений. Сайт в обоих случаях работает одинаково, разница лишь в объёме присланного файла.

Куда попадают картинки товаров?

В /upload/1c_catalog/ вместе с XML, оттуда обмен переносит их в файлы элементов. Если картинки не доехали, смотрят права на этот каталог и свободное место на диске.

Смежное

Первоисточник