Как работает обмен Битрикс с 1С. Часть 1

179
Алексей,

Эта вводная часть об устройстве обмена между 1С-Битрикс и 1С, настройке, ошибках и отладке. Информация взята из онлайн-вебинара, автор которого Гелейшев Павел. Всего планируется несколько частей, т.к. объем материала достаточно большой.

Существует 5 типов обмена:

  1. Импорт каталога (в т.ч. остатки и цены) из 1С в Битрикс
  2. Экспорт каталога из Битрикс в 1С
  3. Обмен документами (заказы, оплаты, отгрузки)
  4. Обмен пользовательскими справочниками
  5. Обмен контрагентами

Импорт товаров из Битрикс в 1С используется единоразово, когда к уже существующему сайту подключают пустую 1С. Так же редко используются обмен справочниками и контрагентами, поэтому для начала рассмотрим импорт каталога и обмен документами.

Версии модулей

Старые версии обмена. (ниже 4.x)

  • не требуют отдельной установки в 1С;
  • у них ограниченный функционал по сравнению с новыми модулями;
  • компания 1С-Битрикс официально уже не поддерживает данные модули и заявляет о их неработоспособности, но на практике данные модули еще встречаются и, хоть как, но работают.

Новые версии обмена. (4.x, 5.x, 6.x, 7.x)

  • устанавливаются отдельно в 1С;
  • умеют автоматически обновляться;
  • под каждую версию 1С необходим свой модуль обмена.

Документация по модулям: https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=131&CHAPTER_ID=06315&LE...

Инициализация обмена

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

Точка входа:

/bitrix/admin/1c_exchange.php (для импорта каталога - /bitrix/admin/1c_import.php)

По умолчанию, если ничего не кастомизировано, все свои запросы 1С отправляет именно по этому адресу.

Рассмотрим по шагам как происходит обмен информацией (на примере обмена каталогом).


Шаг 1: авторизация

Для начала 1Ске необходимо авторизоваться на сайте, для этого она отправляет get запрос на страницу:

/bitrix/admin/1c_exchange.php?type=catalog&mode=checkauth

Где параметр type зависит от типа обмена: catalog - для обмена товарами, sale - для обмена документами. Параметр mode равный checkauth это как раз и есть попытка авторизоваться.

Вместе с этим, методом post 1Cка отправляет логин и пароль пользователя сайта под которым она авторизуется. Этого пользователя специально добавляют на сайте для 1С. Чаще всего его делают администратором с полными правами. Но будет правильнее ограничивать данного пользователя в правах и помещать его в отдельную группу, предоставляя только те права, которые необходимы для обмена. Логин и пароль пользователя вносится в 1С, в настройки модуля обмена.

На запрос авторизации, сайт отвечает строкой вида:

success PHPSESSID kLv28pH4X0XpW91T4wg28YeY7DwZZXnz
sessid=7f8ec88162e001fdccabfdd202653fc6 timestamp=1614319624

Где success означает что авторизация прошла успешно. Если вместо success будет fail, либо что-то еще, то 1С выдаст ошибку и обмен прекратится. Параметр sessid это идентификатор сессии, значение которого 1C будет добавлять в каждый следующий запрос обмена. Так сайт понимает, что полученные запросы именно от этой 1Ски и запоминает последнюю операцию обмена.


Шаг 2: инициализация

На этом шаге 1С делает запрос на страницу

/bitrix/admin/1c_exchange.php?type=catalog&mode=init&sessid=7f8ec88162e001fdccabfdd202653fc6&version=2.10

Где в параметре mode передаётся init, а в sessid передаётся значение идентификатора сессии, полученное на прошлом шаге. Помимо этого в параметре version указывается версия схемы обмена. На данный момент самая последняя версия это 2.10. Версия передаётся из-за того, что в разных модулях для 1С, схема обмена реализована с отличиями, поэтому сайту необходимо понимать по какой схеме будет происходить обмен.

Получив запрос на инициализацию, сайт очищает все папки с файлами от предыдущего обмена и отвечает 1Ске строкой с настройками обмена:

zip=yes file_limit=204800

Параметр zip равный yes, что означает у сайта есть библиотека для работы с zip архивом. 1С в данном случае будет отправлять файлы в zip архивах. Это экономит время для передачи файлов. В противном случае (zip=no) 1С будет отправлять XML файлы в открытом виде.

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


Шаг 3: отправка файла

1С методом post отправляет тело файла по адресу:

/bitrix/admin/1c_exchange.php?type=catalog&mode=file&filename=1c_catalog.xml&sessid=7f8ec88162e001fdccabfdd202653fc6

Параметр mode устанавливается в значение file, а в параметре filename передаётся имя файла. Сайт сохраняет загружаемые файлы в папку /upload/1c_catalog/ (для обмена товарами), либо /upload/1c_exchange/ (для обмена заказами). Имя файла берется из параметра filename, т.е. именно 1С задает название файла обмена под которым сайт сохраняет его у себя.

Запрос на отправку файлов может повторяться несколько раз, например в случае если файл был разбит 1Ской на несколько частей. На каждый запрос сайт отвечает строкой:

success

Если в ответе будет что-то другое, то обмен прервётся с ошибкой.

После того как файл будет получен полностью, начинается сам процесс импорта.


Шаг 4: начало обмена

Для этого 1С отправляет запрос на страницу:

/bitrix/admin/1c_exchange.php?type=catalog&mode=import&filename=1c_catalog.xml&sessid=7f8ec88162e001fdccabfdd202653fc6

Где для параметра mode указывает значение import и повторно в параметре filename указывает имя файла.

В это время сайт находит нужный файл с указанным именем у себя в папке обмена и начинает импорт. Импорт выполняется в несколько шагов. На процесс импорта 1С уже никак не влияет, они лишь отправляет запросы повторно с mode=import до тех пока пока операция импорта не завершится. В ответ на каждый запрос она получает строку вида:

progress Временные таблицы созданы.
progress Файл импорта прочитан.
progress Обработано 1 из 1 элементов.

Если в строке есть значение progress, то 1С повторяет запрос и будет повторять до тех пор пока не получит ответ:

success Импорт успешно завершен.

Сам процесс импорта несколько необычен в 1С-Битрикс. Скрипт импорта не работает с xml напрямую (с помощью стандартных библиотек php), а создает в базе данных пустую таблицу b_xml_tree (предварительно очистив) и построчно считывая xml файл импорта заносит данные в созданную таблицу. После того как файл будет полностью перенесён во временную таблицу скрипт импорта начинает обрабатывать данные из таблицы и уже вносить изменения в данные сайта (например создаёт группы, товары и т.п.)

После того как импорт файла будет завершён запускается процесс деактивации разделов и элементов каталога.


Шаг 5: деактивация

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

Процесс деактивации отличается в разных версиях модуля обмена:

  • в старых версиях деактивация происходила на 4-ем шаге (в момент импорта xml, настройки хранились на сайте),

    настройки деактивации на сайте

  • в последних версиях деактивация происходит на отдельном шаге (настройки уже хранятся в 1С)

    настройки деактивации в 1С

Деактивация происходит только при полном обмене. Для деактивации 1С отправляет запрос на страницу:

/bitrix/admin/1c_exchange.php?type=catalog&mode=deactivate×tamp=1614319624&sessid=7f8ec88162e001fdccabfdd202653fc6

Где параметр mode равен deactivate, а так же указывается timestamp, значение которого 1С получала на первом шаге. timestamp это время начала обмена, по нему сайт ищет все товары, у которых время модификации меньше чем значение в timestamp и деактивирует их. Логика такая: все товары, которые были изменены после времени начала обмена - считаются что они были в xml импорта, а все остальные - нет.

Тут есть особенность, если в момент импорта каталога какие-либо товары были изменены (администратором, скриптом выполняющимся на cron и т.п.), то 1С-Битрикс не поймет, были они в импорте или нет. Такие товары не будут деактивированы, даже если их не было в обмене. Это особенно актуально для больших сайтов, где обмен выполняется очень долго.

При использовании нового модуля обмена, деактивация зависит только от настроек в 1С, настройки в 1С-Битрикс не работают.

Обмен заказами

Обмен заказами (выгрузка из 1С на сайт) идёт по той же самой схеме. Только в параметр mode передаётся значение sale, а сохранение файла происходит в папку /upload/1c_exchange/.

Для экспорта заказов в 1С используется запрос:

/bitrix/admin/1c_exchange.php?type=sale&mode=query&sessid=f5b5d96716e0afb60beec6f1455972d4

В ответ сайт отдаёт XML с заказами, которые были как-либо изменены с даты последнего обмена. Для этого сайт записывает дату и время последнего обмена. Время сохраняется в таблицу b_option, строка last_export_time_committed_/bitrix/admin/1c_excha.
При последующих запросах сайт отдаёт все заказы, в которых дата и время изменения новей, чем дата последнего обмена.

Например, если по какой-либо причине не выгрузился определённый заказ, то достаточно зайти в редактирование этого заказа и нажать "Сохранить". Тогда у заказа изменится дата редактирования и при следующем обмене он попадёт в выгрузку.

Так же можно сбросить время в last_export_time_committed, тогда в xml попадут все заказы. Пример кода для сброса:

\Bitrix\Main\Config\Option::set("sale", "last_export_time_committed_/bitrix/admin/1c_excha", "");

Если обмен завершается с ошибкой

Например при запросе:

/bitrix/admin/1c_exchange.php?type=catalog&mode=import&filename=1c_catalog.xml&sessid=7f8ec88162e091fdccabfdd202653fc6

1C ожидает получить строку, например:

progress Файл импорта прочитан.

А получает: "DB query error"

настройки деактивации в 1С

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

настройки деактивации в 1С

Так же есть галочка "Выгружать лог на сайт", в этом случае, после окончания обмена, 1С отправит логи на сайт. Но проблема в том, что если сайт при обмене падает с ошибкой, то логи 1С отправить не сможет.

Пример лога обмена 1С

настройки деактивации в 1С

В лог записываются, как действия самой 1С (например "Формирование пакета для общих данных для товаров"), так и то, что возвращает сайт (например "Процесс выполнения обмена: Временные таблицы удалены"). Для того, чтобы сайт возвращал более полные данные по ошибке, а не заглушку "DB query error", необходимо включить режим вывода расширенных ошибок:

$DBDebug = true; // в dbconn.php
exception_handling - debug => true // в .settings.php

После этого необходимо повторить обмен. В логах уже будет описана конкретная ошибка, например:

Table 'sv22.b_xml_tree' doesn't exist
...
Сan't create table 'b_xml_tree' (errno: -1)
...
MySQL Query Error: create table b_xml_tree_import_1c

Ошибка по таблице b_xml_tree возникает из-за того, что скорее всего было запущено несколько обменов одновременно. В битрикс процесс устроен так, что может идти одновременно только один обмен, т.к. запись происходит в таблицу b_xml_tree, которая очищается вначале каждого обмена. Т.е. при запуске второго обмена, таблица очистится и первый процесс обмена получит ошибку, т.к. таблицы уже не существует.

Очень часто это возникает из-за того, что подключают дополнительно тестовую 1С и забывают в ней отключить периодический обмен. И две 1С (боевая и тестовая) одновременно шлют запросы на обмен.
Так же случается, если настроен автоматический обмен по расписанию и примерно в это же время запускается ручной обмен.

В зависимости от настроек в 1С, даже при получении ошибки, 1С может попытаться продолжить процесс обмена. Но результат такого обмена непредсказуем, поэтому если в логе есть ошибки, то с ними необходимо разбираться.

Бонус для дочитавших

Когда необходимо посмотреть что же конкретно присылает 1С в xml, приходится запрашивать файлы выгрузки (1С хранит их локально), но это долго и неудобно.

Для решения этой задачи есть волшебная константа:

define("BX_CATALOG_IMPORT_1C_PRESERVE", true); // в dbconn.php

После её установки битрикс перестаёт удалять файлы обмена и сохраняет их в папки
/upload/1c_catalog0/
/upload/1c_catalog1/
...
/upluad/1c_catalogNNN/

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


Опубликовано 26 февраля 2021 | Обновлено 12 апреля 2021
, разработчику, обмен, полезное
Поделиться
Комментарии
Зарегистрируйтесь чтобы получать уведомления об ответе
Эта вводная часть об устройстве обмена между 1С-Битрикс и 1С, настройке, ошибках и отладке. Всего планируется несколько частей, т.к. объем материала достаточно большой.