Всем привет ))
Задача
- Выгрузить из 1С на сайт Битрикс Каталог товаров торговых предложений цены и т.д.
- После выгрузки, по событию на сайте, запустить свой обработчик для модификации полученных данных
(нам удобнее обработать весь каталог сразу а не ловить каждое изменение данных как рекомендуют специалисты )
Инструменты
- Штатная выгрузка 1С (обмен с сайтом) – *используем по умолчанию
- Обработка от Битрикс – Обмен с интернет магазином
Проблема
Обмен и там и там идет xml пакетами, 1С отправляет, Bitrix принимает
по документации, для обмена, у Bitrix существует два события
- OnBeforeCatalogImport1C - перед началом обработки xml пакета
- OnSuccessCatalogImport1C - по окончанию обработки xml пакета
Если для запуска своего скрипта использовать событие OnSuccessCatalogImport1C – оно за выгрузку сработает несколько раз (например)
- Для штатной выгрузки 1С – 2 раза (товары+торговые предложения)
- Для выгрузки Bitrix ~ 6 раз (товары+торговые предложения+цены+остатки и т.д.)
Как отловить окончание всей выгрузки – непонятно
Поиск…
- В интернете выяснилось, что у Битрикса есть недокументированное событие на этот счет - OnCompleteCatalogImport1C
Которое вызывается get запросом вида
https://example.ru/bitrix/admin/1c_exchange.php?type=catalog&mode=complete&sessid=ID_Сессии
- в конфигураторе по поиску кода оказалось что строка mode=complete ПРИСУТСТВУЕТ в модуле Битрикса
- при выгрузке на сайт через модуль Битрикса – выяснилось что данное событие СРАБАТЫВАЕТ на сайте
Решение (да простит меня Битрикс)
- Делаем расширение конфигурации типа адаптация
- Из основной конфигурации добавляем в расширение ОбщийМодуль/ОбменССайтом
- Используем запуск по окончании основной функции
- Формируем в модуле расширения GET запрос к сайту для активации OnCompleteCatalogImport1C
&После("ДобавитьПараметрыПротоколаОбменаВСтруктуру")
// Процедура - добавляет в структуру параметры http запросов
Процедура CatalogImport1C_ДобавитьПараметрыПротоколаОбменаВСтруктуру(СтруктураПараметров)
СтруктураПараметров.Вставить("ПараметрЗапросаHTTP_ДеактивацияДанныхПоДате" , "&mode=deactivate");
СтруктураПараметров.Вставить("ПараметрЗапросаHTTP_ОкончаниеВыгрузкиТоваров" , "&mode=complete");
// Сообщить("обновлена СтруктураПараметров");
КонецПроцедуры
&После("ВыполнитьОбменССайтом")
// Процедура - Выполняет запуск обмена с сайтом.
//
// Параметры:
// Параметры - Структура - настройки и данные для обмена.
// РезультатОбмена - Структура - результат обмена товарами и заказами.
// ТаблицаИнформации - ТаблицаЗначений - таблица, хранящая лог обмена.
//
Процедура CatalogImport1C_ВыполнитьОбменССайтом(Параметры, РезультатОбмена, ТаблицаИнформации) Экспорт
Если Параметры.ВыгружатьНаСайт Тогда //проверка на выгрузку на сайт или в локальный каталог
ТипСоединения = "catalog";
ОтветСервера = "";
Соединение = Неопределено;
ОписаниеОшибки = "";
НастройкиПодключения = Параметры.НастройкиПодключения;
АдресДляРаботы = НастройкиПодключения.АдресСкрипта + "?type=" + ТипСоединения;
Успешно = ВыполнитьАвторизациюДляСоединения(Соединение, НастройкиПодключения,
ОтветСервера, ОписаниеОшибки,
ТипСоединения);
Если НЕ Успешно Тогда
// ДобавитьОписаниеОшибки(ОписаниеОшибки, НСтр("ru = 'Выгрузка на сайт не выполнена.'"));
Сообщить("авторизация на сайте не выполнена");
КонецЕсли;
КукиИмя = СтрПолучитьСтроку(ОтветСервера, 2);
КукиЗначение = СтрПолучитьСтроку(ОтветСервера, 3);
ЗаголовкиЗапросов = Новый Соответствие;
ЗаголовкиЗапросов.Вставить("Cookie", КукиИмя + "=" + КукиЗначение);
ПараметрыЗапроса = АдресДляРаботы + НастройкиПодключения.ПараметрЗапросаHTTP_ОкончаниеВыгрузкиТоваров;
Если Параметры.ИспользоватьИдентификаторСессии Тогда
ПараметрыЗапроса = ПараметрыЗапроса + "&sessid=" + НастройкиПодключения.ИдентификаторСессии;
КонецЕсли;
Сообщить("Запрос сайту Bitrix:" + Символы.ПС + ПараметрыЗапроса);
ОтветСервера = ПолучитьДанныеССервера(
Соединение,
ОписаниеОшибки,
ПараметрыЗапроса,
ЗаголовкиЗапросов);
Если ОтветСервера = Неопределено Тогда
// ДобавитьОписаниеОшибки(ОписаниеОшибки, НСтр("ru = 'Выгрузка на сайт не выполнена.'"));
Сообщить("Bitrix не ответил на запрос");
Иначе
Сообщить("Ответ сайта Bitrix:" + Символы.ПС + ОтветСервера);
КонецЕсли;
Сообщить(Формат(ТекущаяДата(), "ггггММддЧЧммсс")+ " Обмен xml пакетами с сайтом завершен");
КонецЕсли;
КонецПроцедуры
В файле sftp://хххххх/хххххх.ru/bitrix/php_interface/init.php или в инклюде к этому файлу ловим события и запускаем свой скрипт
/***********************************************************************************
записать в лог файл на диске
$var - переменная
$filename - имя файла
$path - путь относительно корня *по умолчанию
/_logs/bx/ - каталог для системных ошибок
/_logs/log_debug/ - просто каталог для отладки скриптов
/_logs/log_import_from_1C/ - каталог для отладки скриптов мипорта
***********************************************************************************/
function cl_print_w ($var, $filename="", $path = "/_logs/log_import_from_1C/")
{
// $pr = date("Y-m-d H:i:s");
$pr = date("H:i:s");
if ($filename=="" or empty($filename)){
\Bitrix\Main\Diag\Debug::writeToFile($pr.$var,
"",
$path.date("Y-m-d H_00")." cadmarket.log");
}
else {
\Bitrix\Main\Diag\Debug::writeToFile($pr.$var,
"",
$path.date("Y-m-d H_00")." cadmarket ".$filename.".log");
}
}
//СОБЫТИЯ при импорте из 1С
// регистрируем обработчик
AddEventHandler("catalog", "OnBeforeCatalogImport1C", Array("EventClass", "ric_OnBeforeCatalogImport1C"));
AddEventHandler("catalog", "OnSuccessCatalogImport1C", Array("EventClass", "ric_OnSuccessCatalogImport1C"));
AddEventHandler("catalog", "OnCompleteCatalogImport1C", Array("EventClass", "ric_OnCompleteCatalogImport1C"));
class EventClass{
function ric_OnBeforeCatalogImport1C($arPropertyValues, $ABS_FILE_NAME){
$msg = "Перед загрузкой пакета XML";
cl_print_w("-On- BeforeCatalogImport1C : ".$msg.
"\n".$ABS_FILE_NAME.
"\n----------------------------------------------------------------------------------------------------------------------",
"ImportFrom1C"
);
return "";}
function ric_OnSuccessCatalogImport1C($arPropertyValues, $ABS_FILE_NAME){
$msg = "После загрузки пакета XML";
cl_print_w("-On- SuccessCatalogImport1C : ".$msg.
"\n".$ABS_FILE_NAME.
"\n----------------------------------------------------------------------------------------------------------------------",
"ImportFrom1C"
);
return "";}
function ric_OnCompleteCatalogImport1C(){
$msg = "После загрузки всех XML пакетов. Старт";
cl_print_w("-On- CompleteCatalogImport1C : ".$msg.
"\n----------------------------------------------------------------------------------------------------------------------",
"ImportFrom1C"
);
echo nl2br(date("H:i:s")." ".$msg."\n"); // оставьте эту строчку если хотите увидеть это в ответе для 1С
$startImportCatalogTimer = microtime(true); // начало измерения импорта каталога
// $ret=fn_SetAfterImport(); //скрипт обработки каталога
$stopImportCatalogTimer = microtime(true); // конец измерения импорта каталога
$msg = "После загрузки всех XML пакетов. Стоп";
echo nl2br(date("H:i:s")." ".$msg."\n"); // оставьте эту строчку если хотите увидеть это в ответе для 1С
cl_print_w("-On- CompleteCatalogImport1C : ".$msg.
"\nЗатрачено время: ".($stopImportCatalogTimer - $startImportCatalogTimer)." сек.".
"\n----------------------------------------------------------------------------------------------------------------------",
"ImportFrom1C"
);
return "";}
}