3 собственных сервера, 1 коробочная ERP и другие интересности — как мы обновляли сайт для крупной сети кожгалантереи в России
Результат Процесс
Империя Сумок
Сибирикс

Империя Сумок

3 собственных сервера, 1 коробочная ERP и другие интересности — как мы обновляли сайт для крупной сети кожгалантереи в России

Империя Сумок

3 собственных сервера, 1 коробочная ERP и другие интересности — как мы обновляли сайт для крупной сети кожгалантереи в России
Разработка интернет-магазинов для торговых сетей, где торговые точки работают как франчайзи, — одна из самых сложных историй. Тем более, если у торговой сети уже есть старый сайт — с клиентами, заказами и интеграциями. Когда клиент приходит с таким проектом, у него есть отлаженные бизнес-процессы, к которым франчайзи привыкли, и которые нужно максимально аккуратно перенести на новый сайт. В проекте для «Империи Сумок» — всё было именно так.
  • Империя Сумок — сеть кожгалантереи с 250+ магазинами по всей России, которая работает на рынке больше 25 лет. Интернет-магазин у сети появился в 2017-м, и требовал масштабного обновления, чтобы им было удобно пользоваться и клиентам, и самим франчайзи.

Дизайн

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

Екатерина
Руководитель проекта
— Мы с заказчиком работали в тандеме и подготовили очень много макетов. Здорово, что у нас под рукой был реальный контент — от него очень многое зависит. Например, состав детальной страницы товара: её финальную концепцию мы выбирали, исходя именно из реального контента.

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

Непростой импорт данных

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

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

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

Чтобы размотать этот клубок и сделать на новом сайте всё по красоте, мы двигались поэтапно. Вот здесь — очень подробно рассказали, как именно. Если кратко, то сначала мы разобрались с тем, откуда вообще берутся данные, и как мы их можем получить. Итак, для данных о товарах у нас есть:
1
Система SAP, которая выгружает номенклатуру (справочники, товары и их свойства) в виде xml-файлов. Развернута на собственном сервере заказчика, не подлежит доработке, выгружает данные в строгом порядке, а файлы отдаёт — с нестандартными значениями (даже пришлось совместно с заказчиком сделать файл для расшифровки немецких аббревиатур).
2
Система для хранения цен и остатков Domino — тоже развернута на собственном сервере заказчика, собирает данные со всех магазинов сети и предусматривает три типа цен (базовая цена, распродажа и суперцена).
3
Папка на ещё одном сервере заказчика, где хранятся изображения к товарам. Хранит вообще все изображения к товарам, созданные за всё время, и постоянно пополняется новыми фото.
Чтобы перенести эти данные в карточку товара на сайте, нам было нужно собрать вместе сразу несколько файлов:
  • файл SAP-системы с сервера заказчика (обновляется каждые 2 минуты);
  • XML-файл из Domino с ценами и остатками;
  • файлы изображений товаров из папки с другого сервера заказчика.

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

Для переноса файлов с серверов заказчика на сайт мы использовали серверную утилиту rSYNC: с ее помощью файл SAP мы забираем каждые 5 минут, файл Domino и изображения — раз в сутки. Чтобы импорт шёл быстро — использовали сервер очередей. А чтобы сохранить нужный порядок при импортировании данных, написали модуль для Битрикса, с которым задачи на импорт можно ставить в очередь: пока не обработается одна пачка, к другой сайт не приступит.

Екатерина
Руководитель проекта
— На сервере очередей работают 8 Service Worker-ов для импорта и 2 Service Worker-а для экспорта данных (воркеры — скрипты, которые работают в фоновом режиме на сервере). За счет этого с помощью сервера очередей и нашего модуля для управлениями очередями и задачами реализуется не только импорт, но и фоново работает автоотмена неоплаченных заказов, индексация каталога, выгрузки фидов.

Перенос контента со старого сайта

Кроме импортов данных из систем заказчика на регулярной основе мы также решали задачу по переносу контента со старого сайта. Для этого написали скрипты экспорта данных со старого сайта и импорта на новый сайт.

Переносить пришлось многое:
1
Свойства товаров, которые не хранились во внешних системах и существовали только на старом сайте: например, для товара «перчатки» на старом сайте был заполнен справочник и вручную указано свойство длины (выше локтя, ниже и т. д.). Были прописаны и служебные свойства, которые контент-менеджер редактирует (активность, описание проблем с фотографиями, статус товара) — и их тоже важно было перенести. Плюс нужно было сделать редиректы со старых адресов товаров на новые и сопоставить другие данные, импортируемые со старого сайта, с новыми товарами (отзывы, посты блога). Для этого мы сохранили прежние id товаров.
2
Отзывы к товарам и фотографии этих отзывов: чтобы сопоставить отзывы со старого сайта с товарами на новом сайте, использовали свойство id товара со старого сайта.
3
Пользователей: важно было не упустить ни одного аккаунта, чтобы никто из пользователей не потерял доступ к сайту. А чтобы избежать дублей, мы проверяли уникальность номеров телефонов.
4
Архив заказов: старые заказы импортировали как отдельный справочный инфоблок, к которому есть доступ только у админа нового сайта (пользователи свои старые заказы не видят).
5
Блог: важно было сохранить привязки к товарам (как у отзывов) и аккуратно перенести изображения в статьях. Но картинки к статьям на старом сайте загружались по-разному: какие-то — через Медиабиблиотеку Битрикса, какие-то — по прямым путям к файлам в папке старого сайта. Всю медиабиблиотеку и все файлы переносить не хотелось, потому что большая их часть на новом сайте была не нужна. Поэтому мы написали парсер, который после импорта постов блога на новый сайт прошелся по описаниям каждого поста и по ссылке на изображение перенес его на новый сайт.

Экспорт данных с сайта

Кроме импортов, мы также настроили экспорты под нужды заказчика. Они также выполняются через сервер очередей с помощью Service worker-ов.

1. Сверка по артикулам

Файл сверки по артикулам нужен, чтобы сравнить то, что есть на сайте, с тем, что есть в системе SAP, и отследить расхождения. Раз в сутки мы выгружаем на сервер заказчика текстовый файл с данными с сайта. Аналогичный файл выгружается на стороне SAP. Затем файлы сравниваются. Если есть расхождения — заказчик направляет задачу в техподдержку, и мы разбираемся в причинах. Например, расхождение в значениях свойств товара может быть по нескольким причинам: эти свойства могли не выгрузиться на сайт, по-разному сработали округления, выгрузились лишние свойства и т. п.

2. Экспорт фидов

У заказчика — порядка сотни фидов. Почему так много? Во-первых, есть геозависимые — на каждый город выгружается свой фид для Яндекс.Маркета. Во-вторых, для маркетинговых задач могут потребоваться фиды с данными от нескольких магазинов. Или от нескольких магазинов нескольких городов. Также есть отдельные фиды для поискового движка и для платформы Retail Rocket.
Фид — выгрузка товаров в виде файла в определенном формате (чаще всего в XML) для загрузки во внешние системы. Выгружаться могут различные характеристики: например, файл фида для Яндекс. Маркета позволяет загрузить каталог товаров на маркет, где его смогут просматривать пользователи.
На старом сайте под генерацию всех этих фидов использовался отдельный сервер, чтобы не нагружать основной сервер заказчика (генерация занимала в среднем до 3 часов). На новом сайте отдельный сервер для фидов не потребовался: всё сделано так, чтобы они быстро генерировались и не создавали избыточной нагрузки.

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

Екатерина
Руководитель проекта
— Для выборки товаров для фидов мы используем движок ElasticSearch (тот же, что и в фильтре каталога). Плюс под фиды выделена своя очередь из 2 воркеров — это значит, что всегда в резерве на сервере есть 2 потока, которые готовы к генерации фидов. Когда фиды генерируются — заняты только эти потоки, они не пересекаются с потоками импорта данных, а значит, не замедляют их. Суммарно генерация фидов занимает сейчас около 15 минут.

Гибкая структура каталога

Товары из SAP попадают в каталог изначально без какой-либо группировки: разделы (сумки, рюкзаки, аксессуары и т. д.) создаются контент-менеджером вручную. Причем, заказчик просил, чтобы товары могли перемещаться по разделам, если у них в SAP поменялись свойства или если на сайте добавились новые разделы с новыми настройками.

Екатерина
Руководитель проекта
— Для этого мы предусмотрели возможность создавать смарт-группы. Например, в каталоге был раздел «чемоданы на колесах». Потом решили сделать разные разделы: «чемоданы на 2 колесах» и «чемоданы на 4 колесах». Товары не придется переносить в новые разделы вручную — достаточно создать раздел и указать, что в него должны попадать все товары со свойством «категория», равным «чемодан», и свойством «количество колес», равным 2 и 4 соответственно.
Как выглядят разделы и подразделы каталога на сайте

Ну очень умный фильтр

В его основе — мощный движок ElasticSearch: ему мы «скармливаем» информацию о значениях свойств каждого товара. Эластик знает о разных ценах в разных городах, о наличии товаров в конкретном магазине конкретного города и о значениях свойств товара (тип — сумка, цвет — красный, материал — кожа).

Сама фильтрация в каталоге настраивается через битриксовый умный фильтр. Это значит, что заказчик может:

  • указывать, какие свойства выводить для всех разделов;
  • у каждого раздела добавлять дополнительные свойства для вывода в фильтре. Подразделы наследуют настройки от корня каталога, от родительского раздела, плюс можно указать дополнительные.
Гибкость на этом не заканчивается. Заказчик постоянно расширяет список свойств товаров под запросы пользователей, добавляя новые справочники. И для SEO на сайте есть свой удобный инструмент — короткие ссылки.

Екатерина
Руководитель проекта
— Например, если люди ищут чемоданы со светящимися колесами, то такое свойство можно добавить в фильтр, отфильтровать раздел чемоданов по этому свойству и создать короткую ссылку, которая будет вести сразу на отфильтрованный раздел сайта. Для каждой короткой ссылки можно указать свои метаданные, названия, описания и короткий URL.

Скидки в корзине и оформление заказа

Domino отдает на сайт три типа цен: базовая цена, распродажа и суперцена (особое ценовое предложение). Для каждого товара, в каждом городе, да ещё и условия применения скидок, акций, промокодов зависят от типа цены. В сумме получается больше 5 миллионов цен, поэтому стандартные Битриксовые типы цен здесь не подходят. Решение проблемы — хранить цены в отдельном хайлоаде.
Хайлоад-блоки — быстрые справочники без поддержки иерархии, которые можно редактировать в административной панели. Каждый хайлоад-справочник соответствует конкретной таблицей в базе данных, тогда как обычные инфоблоки бывают связаны с сразу с несколькими таблицами.
При этом нам важно было оставить возможность настраивать Битриксовые правила работы с корзиной. В итоге в корзине не только применяются правила работы, которые предусматривает Битрикс, но также сделаны и кастомные правила и условия применения скидок в зависимости от видов цены и города.

Сайт предусматривает три вида скидок:
  1. скидки, настроенные по правилам работы с корзиной;
  2. скидка по промокоду;
  3. скидка по дисконтной карте.

Раньше у заказчика очень медленно работала корзина, потому что на сайте было настроено несколько тысяч правил работы с корзиной. Так было потому, что скидка по любой дисконтной карте в каждом городе имеет своё значение: в Москве скидка может быть 7%, а в Ульяновске — 2%. Приходилось всё это прописывать вручную для каждого города. К тому же, в некоторых городах скидка по карте останавливает применение других скидок, а в некоторых — нет. А ещё есть цены, на которые не должна действовать скидка по дисконтной карте. И так далее.

На новом сайте всё работает проще и быстрее: когда пользователь вводит номер дисконтной карты, сайт отправляет запрос в систему Domino по API и передает номер карты и текущий город. Domino возвращает процент скидки, а сумма в корзине учитывает:
  • этот процент скидки;
  • условия применения скидки в конкретном городе с учетом цен на товары и других скидок в этом городе.

Екатерина
Руководитель проекта
— Мы взяли за основу битриксовые правила работы с корзиной, и сделали их круче:
  1. Отдельный вид скидки — скидка по дисконтной карте. Для неё не указывается конкретная величина, настраиваются только приоритет, взаимодействие с другими правилами работы с корзиной и список городов. Величину скидки в процентах мы на лету подставляем на основе значения, которое получили от Domino.
  2. Скидка на определенный тип цены: Базовая, Распродажная, Суперцена. Когда включено это условие, скидка применяется, только если на товар действует выбранный тип цены.
  3. Скидка к базовой цене товара, даже если на него действует другой тип цен. Например, товар продается по цене «Распродажа»: стоил 3000 рублей, а сейчас стоит 2500. Обычно промокоды на скидку не действуют на такие товары, но только не у «Империи Сумок». Можно сделать так, чтобы скидка применялась к базовой цене этого товара, а не к распродажной, и для этого правила сделать промокод (который дает, скажем, скидку в целых 50%, и тогда товар будет стоит 1500 рублей вместо 3000).

Варианты доставки

Для доставки есть всего 2 варианта:

  1. самовывоз из магазина;
  2. собственная доставка курьерской службой (действует не во всех городах). Если доставка в какой-то населенный пункт в черте города недоступна, сайт предлагает варианты населенных пунктов, куда смогут доставить товар из выбранного на сайте города. Причем, список этих пунктов легко настраивается в админке сайта.

Многоликий эквайринг

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

  1. для самовывоза — просим пользователя выбрать тот, который ему удобнее, и после перенаправляем пользователя на оплату на тот шлюз, к которому подключен выбранный магазин;
  2. при доступной доставке — сами выбираем ближайший магазин в городе с нужными наличием и подключаем пользователя к его платежному шлюзу.
При оплате на сайте работает холдирование платежей. Когда пользователь оплачивает покупку онлайн, с его карты списываются деньги — но на счет юрлица они поступают не сразу, а «замораживаются», в платежной системе при этом появляется статус «ожидает подтверждения».

У покупателя есть 7 дней на то, чтобы забрать заказ. Если он его забирает — в Domino меняется статус на «Выполнено», этот статус прилетает на сайт (который пристально следит за изменениями статусов заказов), оттуда информация отправляется в эквайринг, финальная сумма заказа списывается, а деньги поступают на счёт юрлица. Причем, если покупатель забрал только часть товаров — разница вернется ему на карту.

Возврат в один клик

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

Нетривиальная конфигурация серверов заказчика

У заказчика всё по-взрослому: есть 3 физических сервера. Один — основной, второй — резервный, третий — тестовое окружение. Пользователи работают с сайтом на основном сервере. На резервный сервер постоянно копируются данные, чтобы в случае аварии на основном сервере можно было за минуты переключиться на резервную копию. А тестовое окружение нужно для проверки изменений перед переносом их в продакшн.

Екатерина
Руководитель проекта
— Мы всегда ведем разработку на нашем тестовом сервере. И круто, когда у заказчика тоже есть отдельный тестовый сервер, к которому подключены тестовые копии всех его подсистем. Да, в плане поддержки это сложнее и дороже, поэтому не все клиенты готовы поддерживать полноценный тестовый контур.

На этом проекте нам повезло. На тестовом сервере были подключены тестовые копии SAP и Domino. Перед переносом изменений в продакшн мы сначала проверяли всё на тестовом сервере у себя, затем мы вместе с заказчиком проверяли на его тестовом сервере. И только потом переносили в продакшн. Максимальная осторожность и предсказуемость.

Екатерина
Руководитель проекта
— Дальше в планах — ещё тонна всего. Например, личный кабинет для менеджеров магазина, чтобы им было удобнее работать.

Готовый проект