readme.md

Протокол обмена информацией с 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() этого интерфейса.

Описание

Протокол обмена информацией с 1С

Конвейеры
0 успешных
0 с ошибкой