Система персональных скидок для оптового магазина Альянс на InSales
Альянс
У оптового магазина «Альянс» каждый клиент работает по своей сетке скидок: проценты назначаются по дереву категорий и коллекций. Задача — показывать персональные цены на всех ключевых страницах магазина и не просаживать при этом скорость. Собрали серверный метод, который отдаёт «дерево скидок» клиента в JSON, и научили каталог, карточку товара и корзину применять его одним запросом на страницу.
Объём работ
- ✓Серверный метод: дерево скидок клиента в JSON
- ✓Персональные цены в каталоге, карточке и корзине
- ✓Один запрос на страницу вместо десятков
- ✓Пересчёт корзины при изменении состава
- ✓Обход квирков InSales в объекте корзины
- ✓Учёт механики выгрузки скидок в 1С
Задача
«Альянс» — оптовый интернет-магазин лакокрасочной продукции на InSales. Оптовые клиенты закупаются по индивидуальным условиям: у каждого своя сетка скидок, привязанная к дереву категорий и коллекций — от процента на всю группу «Аэрозоли» до отдельного значения на конкретную коллекцию внутри неё. Эти персональные цены должны корректно отображаться там, где клиент принимает решение о покупке: в каталоге, в карточке товара и в корзине.
Сложность в том, что «в лоб» такой пересчёт легко превращается в десятки запросов на каждую страницу — по запросу на товар. На каталоге с сотней позиций это ощутимая нагрузка и заметная задержка. Нужно было решение, которое считает персональные цены быстро и единообразно на всех страницах.
Ограничение платформы, от которого мы отталкивались
InSales хранит у товара только полную цену и умеет применять к заказу одну общую скидку на чек — персональных скидок по отдельным позициям на уровне платформы нет. Значит, персональные цены нужно рассчитывать на своей стороне и аккуратно выводить поверх стандартного интерфейса, а не пытаться «переписать» цену в самом InSales. От этого понимания и выстраивали архитектуру.
Как сделали
Дерево скидок в JSON
На сервере собрали метод, который по клиенту отдаёт всё «дерево скидок» одним JSON — со скидками по категориям и коллекциям. Дерево кэшируется, поэтому повторные обращения не бьют по базе.
Один запрос на страницу
Вместо запроса на каждый товар страница делает ровно один запрос за деревом скидок при загрузке и применяет его ко всем позициям сразу. Так работают и каталог, и карточка товара, и корзина: нагрузка предсказуема и не растёт вместе с числом товаров на странице.
Корзина
В корзине персональные цены пересчитываются при изменении состава заказа. Попутно починили давнюю мелочь — при удалении товара страница лишний раз перезагружалась; сделали так, чтобы корзина обновлялась без перезагрузки.
Обход квирков InSales
В объекте корзины InSales коллекция у товара приходила по-разному: то числом (внутренний идентификатор), то целым объектом с описанием структуры — иногда даже в пределах одной корзины. Из-за этого расчёт скидок мог «спотыкаться». Нормализовали данные, чтобы алгоритм одинаково понимал оба формата.
Выгрузка в 1С
Отдельно разобрали, как персональные скидки доходят до 1С. InSales передаёт в учётную систему товары с их полными ценами и общую скидку на заказ, а 1С сам распределяет её по позициям; вдобавок InSales округляет суммы до целого, а 1С — нет, из-за чего расходились копейки. Согласовали правила округления на нашей стороне, чтобы итоги совпадали. Более глубокое управление скидками на уровне отдельных позиций в выгрузке — ограничение связки InSales↔1С, его вынесли в отдельный этап.
Результат
Оптовый клиент видит свои персональные цены на всех ключевых страницах магазина — в каталоге, карточке товара и корзине, — а нагрузка держится на уровне одного запроса на страницу независимо от количества товаров. Дальнейшее развитие системы — вывод персональных скидок в чекауте и на странице заказа, а также индивидуальные скидки на отдельные товары с расширением базы данных — выделили в следующий этап работ.