Сложные интеграции на проекте и что с ними делать — рассказываем на примерах
Не 1С единой
Сибирикс



Не 1С единой

Сложные интеграции на проекте и что с ними делать — рассказываем на примерах
Штатный импорт данных из ERP на сайт — случай, скорее, исключительный. Чаще ERP настроена под конкретные бизнес-процессы заказчика, и это всегда добавляет «интересностей» проекту. Всё переплетено, и это дело надо кропотливо разматывать (можно, конечно, сказать «и так сойдет», но тогда не избежать хвостовых рисков). Но на самом деле любая сложность — решаема. Даже если на старте кажется, что миссия невыполнима.

В этой статье мы собрали примеры проектов, где мы сталкивались с нестандартными и интересными интеграциями. Материал пригодится, если страшно смотреть в будущее проекта и непонятно, что откуда берется и когда эта неопределенность закончится (спойлер: закончится только тогда, когда вы разложите всё по полочкам).

Когда ERP — много

На проекте Fitness Formula мы столкнулись с тем, что магазины сети работают по франшизе: это значит, что в каждом регионе есть свое юрлицо, причем, у каждого юрлица — своя ERP (чаще всего 1С, но не всегда).

Мы реализовали проект на Laravel, заточив его админку — Voyager — под нужды клиента. Битрикс не подходил как раз из-за своей админ-панели: она не позволяет настраивать доступ к заказам по регионам. В интернет-магазине нужно было собрать данные из 40+ разных ERP-систем от разных франчайзи. Делать для каждой отдельную интеграцию — долго и дорого, поэтому обмен мы унифицировали.

Для этого на сайте создали одну мастер-базу товаров, где хранятся характеристики, описания и изображения. Редактировать и создавать товары может только суперадминистратор (да, в админке мы также четко разделили роли).
импорт данных о товарах из разных ERP
Как работает импорт данных о товарах из 40+ ERP на проекте Fitness Formula
Региональным администраторам же достаточно четко прописать у себя в ERP артикулы (именно по ним товары из ERP мэтчатся с мастер-базой), и можно задавать свои цены и остатки для каталога.

Обкатали схему сначала с одной ERP — 1С конкретного региона. Заказчик на своей стороне внес изменения в ERP и подготовил спецификацию для регионов. Регионы применили их к своим ERP и смогли подключаться к сайту по согласованному протоколу без участия программиста на стороне сайта.

Когда ERP одна, а складов — много

На проекте «Амурфармация» ERP — одна, но продажи ведутся с конкретной торговой точки в разных городах. Получается, что каждая аптека — это склад со своими остатками, а иногда и со своими ценами и акциями. Да ещё и остатки могут меняться каждую минуту: люди заходят в физическую аптеку и покупают товар, поэтому на сайте сразу должно учитываться его актуальное количество.

Чтобы импорт остатков, цен, транзакций, бонусной системы и других данных из каждой аптеки работал именно так, мы настроили обмен между ERP и сайтом каждые 20 секунд. Для этого написали модуль, который связали с сервером очередей. Когда ERP обращается к сайту для передачи остатков, мы перехватываем её файл, делим его на части (пачки) и отправляем на сервер очередей, где их ждут Service Worker-ы для обработки.
Сервер очередей — утилита, которая позволяет запускать одновременно в несколько потоков какой-то исполняемый код с помощью Service Worker-ов (скриптов, которые работают в фоновом режиме). И если поочередное выполнение этого кода заняло бы, скажем, 10 минут, то его параллельное выполнение может быть в 10 раз быстрее.
импорт данных о товарах с разных складов
Как работает импорт данных о товарах с разных складов на проекте «Амурфармация»
За счет такой схемы данные на сайт импортируются быстрее: процесс идет параллельно и многопоточно. Когда один worker заканчивает импорт пачки, он приступает к следующей. И всё это — с учётом разных городов с разными ценами и акциями в своих аптеках.

Когда ERP — одна, но данные о товарах хранятся и в других системах

На проекте для «Империи Сумок» мы снова столкнулись с сетью франчайзи: в разных городах и регионах магазинами владеют разные юрлица. ERP у них у всех — одна, но непростая: развернута на собственном сервере заказчика и не подлежит изменениям. Но и это не всё: данные о ценах и остатках она в себе не хранит, как и изображения к товарам. Они попадают на сайт из двух других источников.

Чтобы собрать на сайте воедино все данные аккуратно и четко, мы сначала разобрались с тем, как именно они хранятся, как могут передаваться и как мы их можем получить.

Как и откуда берутся данные о товарах

1. Хитрая ERP
У заказчика настроена система SAP: эдакая немецкая версия 1С, которая выгружает номенклатуру (справочники, товары и их свойства) в виде xml-файлов.

Сложности системы:
  1. Независимость: SAP развернута на собственном сервере заказчика. Система сконфигурирована и настроена под бизнес-процессы, а данные из неё поступают не только на сайт, но и в другие подсистемы, поэтому она не подлежит доработкам.
  2. Нестандартные файлы выгрузок: внутри этих файлов — огромные массивы данных, состоящие из немецких аббревиатур. Чтобы разобраться, что они означают, мы составляли детальный протокол интеграции, а заказчик присылал нам подробные описания полей выгрузки и их значений в Excel-таблицах.
  3. Частота выгрузки: по умолчанию SAP генерирует файлы импорта каждые 2 минуты и складывает их в конкретную папку на сервере заказчика. А значит, нам нужно решить, как мы будем их оттуда забирать и как часто это будет происходить.
  4. Строгий порядок выгрузки: SAP выгружает данные строго по порядку — сначала справочники, потом товары, следом их свойства. И нарушать порядок никак нельзя, поскольку эта информация связана между собой логически: например, пока нет справочника с цветами и материалами, мы не можем указать эти атрибуты у товара.

2. Отдельная система для хранения цен и остатков Domino
Файлы из системы SAP не содержат цен и остатков. За цены и остатки по всем магазинам франчайзинговой сети отвечает отдельная система Domino, которая также установлена на Windows-сервере заказчика и используется им уже давно.

Особенности системы:
  1. Три типа цен: базовая цена, распродажа и суперцена (особое ценовое предложение). В зависимости от вида цены, действующей на товар, меняются условия применения скидок, акций, промокодов. Стандартные Битриксовые типы цен здесь нам не подходят, потому что из-за городов и трех разных видов цены в каждом городе их получилось бы больше, чем рекомендует использовать Битрикс. Вместо этого цены решили хранить в отдельном хайлоаде.
  2. Одинаковые цены для магазинов в одном городе (даже если там работают разные юрлица). Благодаря этому пользователь не запутается в каталоге — он просто выбирает свой город на сайте и видит единую цену для города.
  3. Каждый магазин — это склад. А Domino собирает остатки со всех магазинов сети. Причем, между магазинами города могут быть перемещения товаров.

3. Отдельно хранящиеся изображения товаров

Картинки к товарам — тоже хранятся отдельно, в папке на другом сервере заказчика. И за 20 лет существования бизнеса их накопилось под 70 Гб: там и старые, и новые, и нужные, и ненужные.

Плюс папка с изображениями постоянно дополняется новыми от фотографов. Чтобы мы могли забрать их на сайт, на стороне заказчика написан скрипт: он выгружает файлы, которые добавились за последние сутки, в отдельную папку, из которой эти изображения импортируются на сайт.

Заказчик очень внимательно следит за фотографиями товаров: в каталоге не должно быть ни одного активного товара без фото. И на новом сайте нам было важно не только аккуратно импортировать изображения с сервера, чтобы ничего не потерялось, но ещё и сделать так, чтобы контент-менеджеру было удобно с этим работать. Решение нашли нестандартное: изображения к товарам хранятся в отдельном инфоблоке Битрикса (зачем и почему так — подробнее здесь).

Как всё это перенести на сайт: импорт данных

Чтобы аккуратно перенести все данные о товарах из трех разных мест на сайт, мы использовали серверную утилиту rSYNC и сервер очередей. Но помимо данных о товарах, нужно было перенести и контент со старого сайта — для этого мы написали отдельные скрипты экспорта.

rSYNC
Чтобы сформировать карточку товара на сайте, нужно собрать данные сразу из трех мест:

  • забрать файл SAP-системы, который хранится на сервере заказчика (и обновляется там каждые 2 минуты);
  • забрать XML-файл с ценами и остатками из системы Domino;
  • забрать изображения товаров из папки, которая хранится на другом сервере заказчика.

На старом сайте для этого использовали копирование файлов по FTP-протоколу обмена данными — решение рабочее, но оно не подходило, потому что это медленно. Чтобы максимально ускорить процесс обмена постоянно меняющимися данными, мы использовали серверную утилиту rSYNC: с её помощью можно подключиться к нужной папке на другом сервере и моментально забрать оттуда нужный файл.
rSYNC — самая прогрессивная система синхронизации файлов и папок, которую можно гибко настроить под свои задачи: например, сделать так, чтобы две папки в разных местах постоянно синхронизировались и поддерживали свои данные в актуальном состоянии, или синхронизировать данные не полностью, а нужными частями.

Поскольку данные меняются постоянно, импорт нужен не разовый, а тоже — постоянный. Для этого настроили работу с rSYNC так:

  1. Раз в 5 минут мы по rSYNC забираем SAP-файлы с первого сервера заказчика, при этом там эти файлы автоматически удаляются.
  2. Раз в сутки скачиваем XML-файл из Domino с другого сервера заказчика. Чтобы сопоставить данные по товару из SAP с его ценой и остатками из Domino, используем артикул — это уникальный ключ для идентификации товара.
  3. Раз в сутки забираем на сайт картинки к товарам с еще одного сервера (уже третьего), но не все подряд, а только вновь добавленные. Для этого обращаемся к отдельной папке на сервере заказчика.
импорт данных о товарах из разных источников
Как работает импорт файлов с серверов заказчика на сайт с помощью серверной утилиты rSYNC на проекте «Империя Сумок»
Изначально контент-менеджер не знает, что к товару импортировались новые фотографии. Чтобы он это увидел в админ-панели, мы пошли на хитрость: загружаем фотографии к товару в отдельный инфоблок и автоматически делаем такие товары неактивными — так сразу видно, что их нужно проверить вручную, зайдя в кастомную вкладку с фото внутри карточки товара в админке.

Там контент-менеджер может просмотреть загруженные изображения, в один клик перейти к списку всех фото этого товара в отдельном инфоблоке. Если с фотографиями всё в порядке, контент-менеджер активирует товар. Если есть проблемы — меняет статус товара в админ-панели на «Проблема с фотографиями» и в поле описания проблемы фиксирует, что не так.

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

Сервер очередей
Мало собрать данные из разных источников, их нужно ещё правильно загрузить на сайт. Для каждого товара на сайте мы импортируем:
  1. справочники;
  2. товары;
  3. свойства;
  4. изображения;
  5. цены;
  6. остатки.

Импортировать эти данные нужно строго в такой последовательности, и никак иначе. Потому что, если сначала в базу данных прилетит товар, но в системе не будет справочника, в котором указаны, например, цвета, всё ломается — у товара должен быть цвет, но по факту его ещё не существует.

Товаров в каталоге больше 100 000 (а разных ценовых предложений по товарам — больше 1,5 млн). На старом сайте клиента ежедневный импорт занимал 5+ часов — слишком долго. Нам нужно было максимально разогнать процесс — для этого использовали сервер очередей RabbitMQ.

Обычно воркеры для обработки и импорта данных выхватывают из общего объема импортируемых данных произвольную часть, которая не зависит от других. Но поскольку на проекте нам была важна очередность импорта данных о товарах (справочники, товары, значения свойств, цены и остатки), мы написали для Битрикса специальный модуль, который реализует параллельные последовательные импорты.

С ним можно ставить задачи в очередь. Например, в очередь задач ставится задача на импорт каталога. Но задача сама по себе «умная»: умеет следить за состояниями своих подзадач. Сначала она запускает импорт справочников (который работает в 8 потоков). Затем отслеживает момент, когда все справочники импортированы, и запускает импорт товаров. После этого — свойства, затем цены и остатки. Каждая часть большого импорта внутри родительской задачи работает в несколько параллельных потоков, но все части запускаются последовательно.

Благодаря серверу очередей ежедневный импорт с 5 часов сократился до 10 минут. И это при том, что во время импорта происходит не просто чтение и запись, а ещё и дополнительные проверки для активаций и деактиваций товаров и проверка привязок товаров к разделам.

Итого

  • Если ERP на проекте — много, нет смысла импортировать данные отдельно из каждой: это долго и дорого. Вместо этого нужно максимально унифицировать процесс. Да, это повлечет некоторые переделки на стороне заказчика, но оно того точно стоит: больше порядка, больше предсказуемости и меньше времени на обмен данными.

  • Если ERP одна, но какие-то данные собираются в неё из нескольких источников (например, физических точек продаж), файл с данными для импорта на сайт наверняка будет увесистым и неповоротливым. Спасёт сервер очередей и Service Worker-ы, которые переварят этого слона по частям.

  • Если ERP нельзя дорабатывать, а данные берутся не только из неё, да ещё и лежит всё это на физическом сервере заказчика и выгружается в виде файлов — подойдёт серверная утилита (например, rSYNC) для шустрого получения всех этих файлов разом и сервер очередей для их быстрой обработки.

  • А если не один из описанных примеров вам не подходит — это нормально: импорты бывают настолько многогранны, что сначала команда над ними плачет и матерится, а потом (когда данные летают на раз-два), гордится. Потому что именно в победе над сложностями и интересностями прячется самый большой профессионализм.