– Для тестирования выгрузки заказов с сайта открываем /bitrix/admin/1c_exchange.php?type=sale&mode=query и анализируем. Этот же фид видит 1С при запросе заказов.
[spoiler]
Инициатором любого обмена является 1С, сайт не загружает ничего в 1С, сайт только принимает запросы и отдаёт результат. По умолчанию, 1С обращается к скрипту /bitrix/admin/1c_exchange.php. Этот путь указывается в настройках обмена в самой 1С. Из коробки в этом файле включается файл /bitrix/modules/sale/admin/1c_exchange.php. Если открыть файл, то видим там подключение нескольких компонентов в зависимости от $_GET["type"]. В общем случае интересуют два из них:
bitrix:sale.export.1c - экспорт заказов.
bitrix:catalog.import.1c -импорт каталога.
Экспорт заказов в 1С
Обмен заказами начинается с авторизации с помощью логина и пароля, который указали в настройках обмена. После авторизации сайт выдает ID сессии, URL: /bitrix/admin/1c_exchange.php?type=sale&mode=checkauth.
После получения ID сессии идёт инициализация обмена, URL: /bitrix/admin/1c_exchange.php?type=sale&mode=init&sessid=ID_Сессии. На этом этапе сайт отдаёт настройки обмена со стороны сайта.
Для получения списка заказов запрашивается URL /bitrix/admin/1c_exchange.php?type=sale&mode=query&sessid=ID_Сессии. Выгружаются заказы с полями EXTERNAL_ORDER = "N", UPDATED_1C = "N" и обновившиеся после последней успешной выгрузки в 1С (это проверяется по времени из свойства "last_export_time_committed_/bitrix/admin/1c_excha" модуля sale).
Флаг EXTERNAL_ORDER указывает, что заказ создан в 1С и его выгрузка в 1С не требуется.
Флаг UPDATED_1C после успешного импорта из 1С на сайте устанавливается в "Y" и такие заказы не участвуют в дальнейших экспортах до их обновления на сайте. Во время обновлений заказов на сайте UPDATED_1C устанавливается в "N".
После обработки заказов 1С для завершения обмена запрашивает URL /bitrix/admin/1c_exchange.php?type=sale&mode=success&sessid=ID_Сессии. При этом в свойство "last_export_time_committed_/bitrix/admin/1c_excha" модуля sale записывается время запроса списка заказов (НЕ текущее время, т.к. с момента запроса заказов до их обработки могли добавиться заказы и они попадут в следующую выгрузку с сайта).
Модификация
В экспорте заказов участвуют файл /bitrix/admin/1c_exchange.php, компонент bitrix:sale.export.1c и класс CSaleExport. Какие-либо события здесь отсутствуют, поэтому для модификации этого процесса нужно заменить компонент на свой, создать класс-наследник CSaleExport и заменить вызовы в компоненте на него. В последних версиях Битрикс этот класс стал относительно читабельным, в старых там была просто простыня из php и "xml".
Отключение проверки источника запроса
С версии 15.5 добавлена дополнительная проверка и если вызвать просто /bitrix/admin/1c_exchange.php?type=sale&mode=query, то получим ошибку "failure Ошибка проверки источника запроса. Обновите модуль обмена". Если нет желания возиться с sessid, то можно отключить проверку источника запроса, для этого нужно выполнить:
// old school:
COption::SetOptionString("sale", "secure_1c_exchange", "N";);
// d7 style:
\Bitrix\Main\Config\Option::set("sale", "secure_1c_exchange", "N";);
Импорт товаров из 1С
Импорт начинается с авторизации, посылается запрос на /bitrix/admin/1c_exchange.php?type=catalog&mode=checkauth с передачей логина и пароля, который указали в настройках обмена. После авторизации сайт выдает ID сессии.
Далее идёт инициализация обмена, URL /bitrix/admin/1c_exchange.php?type=catalog&mode=init&sessid=ID_Сессии. На этом этапе в сессии инициализируется массив данных обмена $_SESSION["BX_CML2_IMPORT"] и сайт отдаёт параметры обмена: возможность использования zip, лимит размера файла и т.д. Также на этом этапе очищается папка для файлов выгрузки. Скорее всего, это будет папка /upload/1c_catalog/. Для отладки можно включить сохранение старых файлов обмена, тогда при новом обмене старые данные будут перемещаться в отдельные папки: 1c_catalog0, 1c_catalog1 и т.д.. Для сохранения данных нужно объявить константу в dbconn.php:
// Не забудьте убрать эту строку после отладки во избежание переполнения сервера
define("BX_CATALOG_IMPORT_1C_PRESERVE", true);
После этого 1С начинает подготовку данных и далее посылает их POST-запросом на сайт частями, URL: /bitrix/admin/1c_exchange.php?type=catalog&mode=file&filename=ИМЯ_ФАЙЛА.zip&sessid=ID_Сессии. Запрос продолжается, пока файлы не будут переданы полностью.
1С передает на сайт xml-файлы с данными товаров и предложений, а также картинки. В случае если сайт разрешил использовать zip, то 1С передает все файлы одним архивом. Тогда следующий шаг начинается с его распаковки.
В выгрузке могут участвовать xml-файлы:
import.xml - товары, разделы, типы цен, склады, свойства товаров и единицы измерения;
offers.xml - торговые предложения товаров и их свойства;
prices.xml - цены торговых предложений(в новых версиях);
rests.xml - остатки торговых предложений(в новых версиях);
references.xml - пользовательские справочники (highload-инфоблоки, в новых версиях).
Узнать подробнее о файлах обмена
Картинки загружаются в папку import_files.
Далее начинаются шаги импорта, URL: /bitrix/admin/1c_exchange.php?type=catalog&mode=import&filename=ИМЯ_ФАЙЛА_ВЫГРУЗКИ.xml, где ИМЯ_ФАЙЛА_ВЫГРУЗКИ - import.xml, offers.xml и т.д. Обработка файла завершается, когда сайт отдаёт слово "success". За обработку файла выгрузки отвечают классы CIBlockXMLFile (/bitrix/modules/iblock/classes/mysql/cml2.php) и CIBlockCMLImport (/bitrix/modules/iblock/classes/general/cml2.php).
Обработка файла состоит из нескольких шагов (информация будет дополняться):
Очистка временной таблицы (таблица b_xml_tree);
Метод CIBlockXMLFile::DropTemporaryTables(). Обычный drop таблицы b_xml_tree.
Создание временной таблицы;
Метод CIBlockXMLFile::CreateTemporaryTables(). Здесь создается таблица b_xml_tree. Можно, кстати, задать storage engine этой таблицы, равно как и всех создаваемые битриксом, с помощью определения константы MYSQL_TABLE_TYPE.
Чтение файла во временную таблицу;
Метод CIBlockXMLFile::ReadXMLToDatabase().
Индексация временной таблицы;
Импорт метаданных;
Импорт разделов;
Деактивация разделов и пересчёт левой и правой границ для разделов;
Импорт элементов;
Деактивация элементов;
success.
Некоторые шаги могут выполняться за несколько запросов, порциями по несколько секунд (это время настраивается параметров "Интервал одного шага в секундах" в настройках интеграции с 1С в админке Битрикса).
Модификация
На шаге 10, т.е. по окончании обработки файла выгрузки (NB: одного файла, например, товаров или предложений) вызывается событие OnSuccessCatalogImport1C модуля catalog. Аргументы обработчика - параметры компонента обмена и путь к файлу выгрузки.
Также для изменения процесса обмена можно использовать обычные события, например, OnBeforeIBlockElementUpdate или OnBeforeProductAdd. В обработчике, чтобы определить, что событие вызвано именно во время обмена с 1С, я использую такое костыльное условие:
if (isset($_GET['type'], $_GET['mode']) && $_GET['type'] === 'catalog' && $_GET['mode'] === 'import') {
// ...
}
Ну и, если ничего нельзя решить событиями, всегда можно полностью изменить процесс обмена, скопировав и изменив файл /bitrix/admin/1c_exchange.php, компонент bitrix:catalog.import.1c и класс CIBlockCMLImport.
Отключение проверки источника запроса
Как и в случае с выгрузкой товаров, при импорте товаров есть проверка источника запроса. Можно отключить её следующим кодом:
// old school:
COption::SetOptionString("catalog", "DEFAULT_SKIP_SOURCE_CHECK", "Y";);
// d7 style:
\Bitrix\Main\Config\Option::set("catalog", "DEFAULT_SKIP_SOURCE_CHECK", "Y";);
Статья будет дополняться по мере появления новой информации и вдохновения.
Также полезно почитать:
Алгоритм выгрузки данных на сайт
Протокол обмена между системой "1С:Предприятие" и сайтом
Подробнейшая документация класса CIBlockCMLImport