Селлер уходовой косметики на маркетплейсе: каталог, две трети которого это наборы и мультипаки. Четыре механики тянут цену в разные стороны: не остаться без товара, подтянуться за медианой, не уйти в минус по марже, не проиграть соперникам. Все четыре прогоняются одним движком, и каждая рекомендация умеет объяснить себя.
Заказчик менял цены вручную в кабинете. Решение принималось по цене продавца, а покупатель видит другую цену: площадка добавляет свою скидку. Из-за этого сравнение с соперниками шло по числам, которых на полке нет.
Цена продавца и цена на полке отличаются почти вдвое. Пока в интерфейсе стояла только цена продавца, менеджер держал пересчёт в голове и ошибался, а сравнение с конкурентом было бессмысленным.
Остаток на три дня и остаток на две недели требуют разной скорости реакции. Единого правила "поднять на N процентов" для обоих случаев не хватает: в первом оно опаздывает, во втором мешает.
Колонка "только смотреть" и поле правки в другой части экрана. Человек выбирал между ними наугад, а расходились они молча.
Две трети каталога это комплекты. Себестоимость ведётся на весь артикул целиком, а не дробится по составу: заказчик так считает деньги, и система обязана считать так же.
Синки собирают каталог, заказы, финансы и рекламу. Финмодуль превращает транзакции в расходы на единицу. Ценовой движок считает рекомендацию. Репрайсер прогоняет тот же движок в режиме чтения и раскладывает результат по четырём вкладкам: дублировать логику на экране нельзя, иначе появятся две цены и два ответа на один вопрос.
| Вкладка | Что показывает | Что настраивает |
|---|---|---|
| Out of Stock | остаток, скорость заказов, на сколько дней хватит, шаг лестницы подъёма | цель в днях запаса и шаг: общий по кабинету и свой у каждого товара |
| Медианная цена | медиана за 30 дней, рост в процентах, ряд цен графиком, правило подъёма | минимальная и максимальная цена, два периода сравнения, шаг подъёма |
| Контроль маржи | себестоимость правится прямо в ячейке, расходы на единицу, маржа, реклама, доля рекламы, акции в минус | минимальная маржинальность, учёт рекламы, окно фактических расходов |
| Конкуренты | цены соперников после скидки площадки, насколько мы дороже, когда проверяли | на сколько быть дешевле, преследовать ли цену, сколько соперников брать |
Значение кабинета по умолчанию, значение товара важнее. Пустая ячейка показывает серым унаследованное значение кабинета, заполненная - своё. Стереть ячейку значит вернуться к общему значению: на сервер уходит пусто, а не ноль. Пусто и ноль здесь разные вещи, и путать их нельзя: ноль в шаге повышения означал бы "не повышать никогда".
Пишет значение в настройки кабинета и снимает личные значения товаров по этому полю. Иначе кнопка обходила бы как раз те товары, которые настраивали руками, и выглядела бы сломанной.
Список ступеней читается от самой острой нехватки к мягкой. Один шаг на все случаи вёл себя одинаково и при остатке на шесть дней, и при остатке на день, хотя второй случай требует другой скорости реакции.
Если минимальная цена не задана руками, пол берётся из требуемой маржинальности. А для этого нужны расходы на единицу, и здесь есть два источника, которые врут в разные стороны.
Тариф не знает про негабарит и дальние склады и потому занижает расход. Факт за удачное окно тоже занижает: дорогие отгрузки в него не попали. Занижение пола продаёт товар в минус, завышение всего лишь оставляет часть заказов, поэтому берётся большее.
Под числом стоит "max(факт за окно; тариф)" или "тариф прайс-листа". Второе означает, что у товара за окно не было выручки, и на это число полагаться нельзя.
В тарифе их нет вовсе, они не альтернатива ему. Складывать альтернативы через max, а дополнения через плюс: разные вещи считаются по-разному.
Не делением рублей на штуки. Деньги приходят из транзакций, а счётчик штук из отправлений, и они расходятся: за день выручка есть, а счётчик нулевой. Деление на такой счётчик давало логистику дороже самого товара.
Порядок их применения зафиксирован в одном месте, а не разбросан по механикам. Иначе два слоя начинают переставлять цену по кругу, и объяснить итог человеку нечем.
Остаться без товара дороже, чем уступить в цене. Поэтому Out of Stock стоит после конкурента и может перебить преследование. Этот случай всегда записывается в споры: в таблице у строки появляется значок "спор" с расшифровкой, а не молча изменившееся число.
Ночная стратегия и повышение акционной цены поднимают потолок выше базовой цены: в этом их смысл. Минимальная цена не двигается ничем: она проверяется последней и побеждает любую надстройку.
У каждой строки видно, какая механика оказалась решающей. Без этой колонки таблица цен превращается в оракула: число есть, а спросить не у кого.
Под каждой ценой, и под текущей, и под рекомендованной, второй строкой стоит цена на полке после скидки площадки. Менеджер сравнивает себя с соперниками по витринной цене, а не по цене продавца.
Обязательно парой, и вот почему. Одна витринная цена читается как "столько на полке сейчас". Заказчик открыл карточку, увидел на площадке одно число и не сошёлся с показанным. Ошибки не было: показанное число было полкой рекомендации, а сегодняшняя цена продавца давала другую полку. С тех пор цены всегда стоят парой.
Витринную цену считает тот же конвейер, что и рекомендацию. Свой пересчёт на экране означал бы разные скидки в разных местах: последний замер против среднего за период.
Если скидку площадки замерить не удалось, вместо цены стоит прочерк, а не цена продавца. Подставленная единица показывала бы число, по которому нельзя сравнивать себя с соперниками.
Витрина площадки закрыта проверкой на бота даже с браузерным отпечатком. Поэтому скидка считается из цен фактических отправлений: точность порядка половины процента, и она честно указана.
Задание писалось по документации площадки. Живой кабинет ответил иначе, и каждый такой ответ стал строкой в отчёте с образцом.
| Ожидание по документации | Что оказалось на самом деле |
|---|---|
| Воронка отдаёт показы, переходы, корзину и конверсии. | Отдаёт только выручку и заказы, остальное отвечает отказом "устаревшие метрики". В таблицах эти колонки стоят прочерком с причиной, а не нулём. |
| Бренд лежит в характеристике с фиксированным номером. | Номер зависит от категории и резолвится по справочнику характеристик. |
| Метод цен отдаёт артикул площадки. | Не отдаёт: только идентификатор товара и артикул продавца. Артикул подставляется из каталога, иначе таблица выглядит заполненной, а связка пустая. |
| Витрину можно прочитать для замера скидки. | Витрина закрыта проверкой на бота даже с российского адреса. Скидка считается из фактических отправлений. |
| Каталог это отдельные товары. | Две трети каталога это наборы и мультипаки. Себестоимость ведётся на артикул целиком. |
| Активных отчётов может быть несколько. | Активный отчёт может быть только один, поэтому его номер хранится и после перезапуска отчёт доскачивается, а не заказывается заново. |
| Лимиты скидки любые. | Допустимы только фиксированные значения из списка, остальные площадка отвергает. |
| Отправление содержит уникальные артикулы. | Один и тот же артикул может встретиться дважды, и пачка отвергалась целиком. Дубли схлопываются до записи, количество суммируется. |
| Было | Стало |
|---|---|
| Цену меняли руками, по цене продавца. | Рекомендация с парой цен: цена продавца и цена на полке, и у текущей, и у рекомендованной. |
| Правила конфликтовали и переставляли цену по кругу. | Порядок применения зафиксирован в одном месте, споры записываются и показываются значком с расшифровкой. |
| Минимальная цена была на глаз. | Пол цены считается из требуемой маржинальности по консервативному принципу max(факт; тариф) с видимым источником. |
| Себестоимость стояла в таблице дважды. | Одна ячейка, она же и правится, а правка уходит в модуль себестоимости со своей историей и автором. |
| Конкурентов подбирали автоматически. | Список заводится руками: автоподбор давал соседние товары категории, а не соперников. Записи гасятся, а не удаляются, история цен соперника остаётся. |
| Непонятно, почему цена такая. | Колонка "Кто решил" и лента сообщений по артикулу: что движок сделал с ценой и почему. |
Тестовый формат по решению заказчика. Система ничего не пишет на площадку: результат это рекомендация в карточке товара, алерт и сообщение в ленте. Ни одного метода записи в клиентах площадки нет. Так проверяется доверие к движку до того, как ему дадут руль.
Бизнес-аналитик и строитель систем. Начинаю с бизнес-процесса и контракта данных, потом автоматизирую. Здесь ценовое решение перестало быть догадкой и научилось объяснять себя одной строкой.