Протокол обмена информацией с 1С
- Установка:
composer require mavsan/laravel-1c-protocol
- Для версии Laravel 5 используйте ветку
v5
:composer require mavsan/laravel-1c-protocol:v5.x-dev
. Там-же инструкция. - Зарегистрировать сервис-провайдер в
config/app.php
(для Laravel 5.4 и ниже)
/*
* Протокол обмена информацией с 1С
*/
Mavsan\LaProtocol\Providers\ProtocolProvider::class,
- Опубликовать конфигурацию и изменить при необходимости:
php artisan vendor:publish --tag=la1CProtocolConfig
- Проверить параметр middleware файла конфигурации. Значением этого параметра должен быть массив. В это массиве должен быть указан промежуточный слой (middleware) или группа промежуточных слоев, в котором как минимум - стартует сессия
\Illuminate\Session\Middleware\StartSession::class
, см.\App\Http\Kernel
. Если сессия не стартует - ничего работать не будет. Важно в этой-же группе middleware НЕ ДОЛЖНО быть класса шифрования куки\App\Http\Middleware\EncryptCookies::class
или любого другого способа шифрования куки, т.к. в 1С передается id сессии как есть или если по приходу от 1С будет произведена попытка шифрации/дешифрации - ничего хорошего из этого не будет. - При необходимости осуществлять выгрузку информации с сайта в 1С можно поставить готовый пакет с минимально необходимым функционалом (которого, обычно, хватает с головой)
composer require arsengoian/commerce-ml
, см. раздел Отправка данных в 1С. - В случае, если необходима выгрузка данных о заказах в 1С, но чем-то не устраивает пакет, рекомендуемый выше (например в 1С какой-то уникальный модуль обмена, который не распознает версию XML или еще что, это-же 1С) - можете написать свой обработчик выгрузки, см. раздел Отправка данных в 1С.
- Создать модель, которая будет обрабатывать пришедшие данные. Модель должна реализовывать интерфейс
\Mavsan\LaProtocol\Interfaces\Import
. Если на стороне 1С используется модуль обмена 1С Битрикс необходимо, чтобы эта модель так-же реализовывала интерфейс\Mavsan\LaProtocol\Interfaces\ImportBitrix
. Контроллер обмена в нужный момент создает эту модель и вызывает методimport
, передавая туда полный путь к файлу, который необходимо обработать. Имя этого файла присылает 1С. В файле конфигурации прописать эту модель:
'catalogWorkModel' => \App\Model::class,
Если на стороне 1С используется модуль обмена 1C Битрикс
Протокол обмена с 1С Битрикс отличается от стандартного. В файле конфигурации необходимо настроить соответствующие параметры:
isBitrixOn1C=true
в этом случае в 1С будет отправляться желаемая версия файла обмена с данными каталога и версия XML с данными о заказах. Собственно только из-за того, что при отправке информации о заказах необходимо отправлять версию файла обмена и был введен этот и другие, касающиеся битрикса параметры. Кроме этого отправляется CSRF.saleXmlVersion
версия XML с данными и о заказах, т.к. я не нашел ни какого описания версий 1С Битрикс, то ставлю там то, что предлагают на сайте с описанием протокола, т.е.2.03
(на момент написания этого текста - не смотря на то, что в 1С улетает требование версии 2.03 1C все-равно присылает версию 3.1, возможно они что-то изменили, но забыли в доку написать или я что-то не правильно понял, нужна помощь).catalogXmlVersion
версия XML с данными и о заказах, тоже ставлю, как описано в стандарте -2.08
.
Как работает
Сервис провайдер регистрирует роут, с url, указанным в файле конфигурации. 1C стучится по этому ури и отсылает команды, описанные в стандарте.
Для аутентификации соединения должен быть создан пользовать. Его имя пользователя и пароль присылает 1C. Верификация пользователя производится как обычно: Auth::attempt(['email' => $user, 'password' => $pass])
.
Контроллер обрабатывает эти команды, отсылая требуемые ответы.
При приеме файлов подчищаются файлы предыдущих обменов, т.к. в протоколе не описана команда, что обмен завершен. Если файл zip - после получения он автоматически распаковывается.
##Как выполнить тестирование
При необходимости можно протестировать работу обмена, для этого в файле конфигурации пропишите:
// файл(ы) которые будут отосланы тестом для обработки, эмулируя отправку файлов 1С
'filesToSendTest' => ['fileName.zip'],
// файл(ы) которые требуется обработать моделью после получения, эмулируя отправку команд обработки 1С
'filesToWorkTest' => ['import.xml', 'offers.xml'],
PhpUnit должен использовать файл phpunit.xml
, который идет с этим модулем, или в стандартных тестах в phpunit.xml
необходимо прописать путь к тестам этого модуля:
<testsuites>
...
<testsuite name="1с Protocol">
<directory suffix="Test.php">./vendor/mavsan/laravel-1c-protocol/src/Tests/Unit</directory>
</testsuite>
...
</testsuites>
В версию 0.0.8 в файл конфигурации добавлена возможность изменить имя пользователя и пароль для тестов. Если пользователя нет - он создаётся, но не удаляется (актуально для тестов на реальной базе, а не в памяти).
Таким образом можно протестировать протокол обмена, а не сам обмен, т.е. нельзя проверить что было добавлено в таблицы, верность логики обмена.
Для полного тестирования лучше всего будет в /tests/Unit
создать свой тест, скопировав в него код из\Mavsan\LaProtocol\Tests\Unit\CatalogTest
(к сожалению, унаследовать нельзя, т.к. в этом случае будет ошибка phpunit: ’This test depends on ’) в методе testImport
, в котором выполняется отправка команды обработчику протокола - type=catalig&mode=import
, свои проверки лучше всего добавлять после полной обработки каталога:
public function testImport($session)
{
...
foreach ($files as $file) {
...
$response->assertSeeText('success');
}
// вот тут
return $session;
}
Отправка данных заказа в 1С
Для выгрузки данных о заказах можно использовать пакет arsengoian/commerce-ml, который позволяет быстро реализовать выгрузку минимально необходимого количества данных. Это количества данных обычно вполне хватает. Имейте в виду, что этот пакет только формирует ответ в виде XML. Т.е. реализовывать модель, которая будет выбирать данные о заказах и передавать их для формирования ответа в виде XML в библиотеку arsengoian/commerce-ml
все равно прийдется.
Для начала необходимо установить пакет arsengoian/commerce-ml
, прописать модель, которая будет подготавливать данные о заказе в файле конфигурации в параметре saleShareModel
. Эта модель должна реализовывать интерфейс \Mavsan\LaProtocol\Interfaces\ExportOrders
.
В случае, если функционала не хватает, то в файле конфигурации, в параметре saleShareToXML
необходимо указать модель, которая реализует интерфейс \Mavsan\LaProtocol\Interfaces\ExportOrdersSelf
. Данная модель не только должна выбрать данные о заказе, но и сформировать XML, который будет отправлен 1С.
После того, как 1С отправит команду на получение данных о заказах - контроллер проверяет файл конфигурации. Если указана модель в параметре saleShareModel
, то будет запущено формирование ответа пакетом arsengoian/commerce-ml
.
Если параметр saleShareModel
пуст, то будет создан экземпляр класса, указанный в параметре saleShareToXML
. У этого класса будет вызван метод getXML()
. Этот метод должен вернуть данные в формате XML, которые и будут отправлены в 1С.
При этом необходимо учитывать, что параметр saleShareModel
имеет больший приоритет, т.е. если там что-то указано, то работа по формированию XML будет вестись пакетом arsengoian/commerce-ml
не зависимо от того - прописано ли что-то параметре конфигруации saleShareToXML
.
В некоторых случаях 1С может прислать команду success
. Тогда, если модель экспорта заказов реализует интерфейс Mavsan\LaProtocol\Interfaces\ExportSuccess
будет вызван метод stepSuccess()
.
1С-Битрикс
С версии модуля обмена 1С-Битрикс 6.5.0.0 применяется контейнерный механизм обмена документов. Т.е. каждый документ в файле обмена должен быть обернут в тэг <Контейнер>
см здесь. Предполагается, что каждый документ должен быть обернут в тег <Контейнер>
. Во всяком случае, когда приходит информация от 1С о заказах - все выглядит именно так: <КоммерческаяИнформация ...><Контейнер><Документ>...</Документ></Контейнер><Контейнер><Документ>...</Документ></Контейнер></КоммерческаяИнформация>
.
В какой-то из версий обмена модулем 1С-Битрикс более не применяется кодировка windows-1251
, т.е. XML с данными о заказах надо слать в кодировке utf-8
, к сожалению, я не выяснил, с какой версии модуля обмена 1С-Битрикс это произошло.
Мне так и не удалось корректно отправлять адресную информацию контагента (покупателя), для версии обмена CommerceML 3.1, поэтому эту информацию просто отправляю в комментарии к заказу. Возможно, в 1С какой-то справочник не настроен или что-то вроде того. Обратите внимание, что в доке указано, что Адрес доставки должен быть в теге <ЗначенияРеквизитов><ЗначениеРеквизита><Наименование>Адрес доставки</Наименование><Значение>Тут адрес доставки</Значение></ЗначениеРеквизита></ЗначенияРеквизитов>
. До того, как клиент что-то в 1С не изменил - адрес доставки сохранялся нормально.
Если ни разу не реализовывали обмен между сайтом и модулем 1С-Битрикс, то единственный совет, который я могу дать - поставить себе локально 1С (торренты в помощь), узнать какая версия модуля обмена 1С-Битрикс используется клиентом, узнать какая версия и какая конфигурация использует эту версию обмена. Найти, скачать и установить конфиграцию (опять-же торренты) и модуль обмена, создать в 1С базу с демонстрационными данными и тестировать, т.к. с первого (или даже сотого) раза может не заработать. В конфигруации 1С точку старта, я искал глобальным поиском по названию кнопки, с которой начинается обмен (в разных версиях модуля обмена может называться по-разному, см. в форме). При поиске надо отметить чекбоксом “Элементы форм”. Как попасть в конфигратор и прочее - ищите в интернетах.
Обработка данных каталога
На определенном этапе 1С отсылает команду начать обработку присланных файлов. Контроллер создает экземпляр объекта модели, указанной в конфигурации (ключ конфигурации - catalogWorkModel
) и вызывает метод import($fileName)
, где $fileName
- имя полный путь к файлу, который требуется обработать.
По мере работы этот метод должен возвращать:
self::answerSuccess
, если обработка файла завершена;slef::answerProgress
, если требуется продолжить обработку файла (например большой объём данных);slef::answerFailure
, если произошла ошибка.
В не зависимости от ответа - будет вызван метод getAnswerDetail()
, который должен вернуть детальный ответ или пустую строку. Например:
обработано 500 записей из 100500
;ошибка: у товара указана группа, но такой группы нет
файл успешно обработан
Если необходимо передать несколько строк - они должны быть разделены символов перевода каретки \n
.
1C-Битрикс
В случае, если на стороне 1С используется модуль обмена 1С-Битрикс, необходимо в файле конфигурации параметр isBitrixOn1C
установить в true
. Это заставит контроллер отправлять запросы в в виде, который требует модуль обмена 1C-Битрикс.
Если в настройках модуля обмена включена опция “Деактивировать товары и разделы, не попавшие в полную выгрузку” в конце обмена (а возможно и в каких-то других случаях) будет прислана команда deactivate
(в стандартном протоколе такой команды нет).
В этом случае, если модель обработки данных от 1С реализует интерфейс \Mavsan\LaProtocol\Interfaces\ImportBitrix
, будет вызван метод modeDeactivate($startTime)
этого интерфейса. Эта команда говорит, что необходимо очистить данные, которых не было в файле обмена. Т.е. надо обязательно при обработке каталога всем товарам и группам товаров, справочниками и т.д. (в общем всем записям, которые прилетели и не должны быть удалены) - обязательно устанавливать дату обновления updated_at
, чтобы в методе modeDeactivate($startTime)
вы знали, что надо удалять.
Собственно вот это $startTime
и есть метка времени начала обработки. Его отсылает контроллер вместе с другими параметрами, в самом начале обмена, при инициализации сессии. Это метка времени, в формате date('Y-m-d H:i:s')
.
Последней от 1С-Битрикс прилетает команда complete
, если модель обработки данных от 1С реализует интерфейс \Mavsan\LaProtocol\Interfaces\ImportBitrix
, то будет вызван метод modeComplete()
этого интерфейса.