Плейбук: процентовка размеров и размерная сетка поставки
Срабатывает, когда пользователь просит:
- «процентовка размеров», «доля размеров», «размерная сетка»;
- «какие размеры чаще заказывают/покупают»;
- «сколько какого размера везти/отгружать»;
- «сколько отгружать на ВБ для теста», «первая отправка новой карточки»;
- «разбей поставку по размерам», «сетка закупки у поставщика»;
- «сколько какого размера заказывать в Китае».
Отвечает на один вопрос: какого артикула сколько в каком размере поставлять.
Не отвечает на «сколько всего везти» и «куда по регионам» — это
replenishment-playbook.md. Этот плейбук даёт доли, тот — объём и географию.
Главный принцип
Считать долю в выкупах, а не долю в заказах.
Заказы и выкупы по размерам расходятся сильно: у маек Siluetta выкуп XL — 52,8%,
а S — 40,6%. Если везти по доле заказов, XL систематически недовозится, а S
затоваривается. Формула та же, что в static-orders-sales-forecast-playbook.md:
доля_поставки(размер) = выкуп_net(размер) / выкуп_net(все размеры)
выкуп_net — заказный ID, по которому есть продажа и нет возврата по тому же
srid (определение из buyout-playbook.md).
И главное — фильтр вымывания, см. ниже. Без него доля размера показывает историю остатков, а не спрос.
🔴 Фильтр вымывания (OOS)
Размер, которого не было на складе, не даёт заказов. Сырая доля размера за длинное окно поэтому меряет не спрос, а наличие — и ошибается в разы.
Правило. Месяц артикула попадает в эталон, только если:
- по всем размерам сетки этого артикула в нём был хотя бы один заказ;
- всего в месяце по артикулу не меньше 20 заказов.
Второе условие нужно, чтобы на затухающей карточке «нет заказов по размеру» не путалось с «нет трафика вообще». Месяцы, не прошедшие оба условия, выбрасываются целиком — и из числителя, и из знаменателя.
Единица фильтра — артикул-месяц, а не группа-месяц: один артикул может стоять в OOS, пока соседний по группе торгует полной сеткой.
Почему именно так, а не по остаткам
Честнее было бы считать заказ-дни наличия по stocks_snapshot, но история
остатков WB начинается только с 19.05.2026 — на горизонте, который нужен
для сетки, её просто нет. Заказы есть с января. Когда снимков накопится на год,
правило стоит заменить на «размер-день учитывается, если FBO > 0 на начало дня».
Что фильтр ловит на практике
Два реальных случая, оба меняли решение о закупке:
| Случай | Без фильтра | С фильтром | Цена ошибки |
|---|---|---|---|
| XL у комбинезонов LT8306/LT8307: размер заведён только в марте 2026, январь–февраль его физически не было | XL = 5,6% | XL = 9,9% | XL недовозится вдвое |
| MS-17 (майки): с марта 2026 M/L/XL в OOS, карточка живёт на XS/S | S 34,1 / XS 22,2 / M 20,0 | по группе: S 27,4 / XS 9,0 / M 30,1 | XS перезакупается втрое |
MS-17 — показательный: по своей статистике «за весь период» он выглядит как XS/S-товар, хотя в январе 2026, единственном месяце с полной сеткой, M был самым ходовым размером (37,4%). Заказ-1 закупил XS под 18,5% партии при реальной доле ~8% — это ~190 лишних штук XS на складе.
Лестница источников
Берём первый вариант, который проходит порог. Порог — по чистой выборке, после фильтра.
| Источник | Когда применим | Порог | |
|---|---|---|---|
| A | Сам артикул | у карточки есть история с полной сеткой | ≥ 300 заказов и ≥ 2 чистых месяца |
| B | Группа артикулов | новая карточка, перезапуск после OOS, артикул не добрал порог | ≥ 300 заказов в группе |
| C | Ближайшая группа-аналог | новая категория, своей группы ещё нет | явно пометить как допущение |
Практическое правило пользователя, и оно верное: первую отправку считать по группе (B), а дальше, когда набежали живые продажи по самой карточке, переходить на A и довозить уже по ней. Переход делать не раньше, чем карточка отторгует 2 полных месяца со всей сеткой в наличии — иначе A унаследует ровно то искажение, от которого мы уходим.
Вариант C — например, новая модель маек без истории: берём группу майки.
Для «тёплой» версии существующей модели брать группу её базовой сетки.
Группы
Группа = один и тот же физический товар + одинаковая размерная сетка.
Совпадение категории WB (fin_report_detail.subject_name) — обычный признак
первого условия, но не само условие.
⚠ Категория WB бывает заведена неверно; актуальный предмет проверять по Content API.
Реальный случай: майки MS-06/16/17/18 изначально завели в «Майках бельевых»,
хотя это футболки. 18.09.2026 MS-17 перезаведён как MS117 в «Футболках».
Однако read-only проверка Content API 24.09.2026 показала предмет «Футболки» уже
у старых MS-17-black (nmID 489585388) и MS-17-white (nmID 489585383).
Прежнее утверждение о невозможности смены предмета не использовать как правило.
Оба набора лежат в группе майки: товар один, сетка одна.
Если бы мы разнесли их по subject_name, новые карточки остались бы без
эталона размеров, а старая история — оторванной от живых продаж.
Для файла импорта волгоградской части плана от 18.09.2026 владелец 24.09.2026
выбрал старые MS-17, а не MS117. Их ШК сверены по (nmID, techSize) через
Content API кабинета Siluetta WB / «Митяева К.В.» (shop_id=3). Совпадение физического
товара не делает штрихкоды старой и новой карточки взаимозаменяемыми.
Правило: расхождение предмета фиксировать в note группы, а не разносить
товар по разным группам.
Смешивать S-M-L и XS-S-M-L-XL нельзя: доли не нормируются на разные сетки, и S
из трёхразмерной — не тот же S, что из пятиразмерной (в трёхразмерной он
собирает спрос, который в пятиразмерной ушёл бы в XS).
Канонический справочник — app/reference/size_groups.py. Новый артикул
добавлять туда, а не в текст ответа.
| Группа | Категория WB | Сетка | Состав |
|---|---|---|---|
майки |
Майки бельевые | XS–XL | MS-06/16/17/18 black+white, shop 3 |
комбинезоны-smlxl |
Комбинезоны спортивные | S–XL | LT8306-black, LT8307-black, shop 1 |
комбинезоны |
Комбинезоны спортивные | S–L | HZ020/HZ030/ELS004/ELS017/LTQ001/MS-105/MS-1107 (shop 1), HZ20/HZ30/LTQ-01/MS-07 (shop 3), ELS04 (shop 5) |
леггинсы |
Леггинсы | S–L | HZ-04 (shop 3), ELS-001/HZ004 (shop 1) |
Про объединение магазинов: группа комбинезоны собирает три магазина, потому
что доли сходятся независимо в каждом (shop 1 — 43/39/18, shop 3 — 39/44/17,
shop 5 — 36/44/20). Если по новому магазину доли разойдутся — считать по
своему магазину, --shop N сужает группу.
Майки shop 1 (MS106, ELS008) в группу майки не включены: магазин закрыт,
объём мизерный, ассортимент и ценовая полка другие.
Команда
python scripts/size_mix.py --group майки
python scripts/size_mix.py --group комбинезоны --plan 750
python scripts/size_mix.py --shop 3 --sku MS-06-black --plan 200
python scripts/size_mix.py --group майки --shop 3 --since 2026-03-01 --format json
С Windows уходит на production Hetzner автоматически, как report_cli.py.
Read-only, база открывается в режиме mode=ro.
Ключи: --group / --sku + --shop, --plan N (разложить N штук по размерам),
--since, --min-orders (порог месяца, по умолчанию 20), --format.
Вывод содержит sample.clean_sku_months и список отброшенных месяцев с
причиной — это часть ответа, а не отладка. Если фильтр выбросил больше
половины месяцев, сказать об этом пользователю.
Эталоны (снимок 18.09.2026)
Проверять командой, не копировать вслепую: цифры двигаются с каждым месяцем.
Майки бельевые, XS–XL
4 175 заказов / 1 912 выкупов в 31 чистом артикул-месяце.
| Размер | Доля заказов | Выкуп | Доля поставки |
|---|---|---|---|
| XS | 9,0% | 40,6% | 7,9% |
| S | 27,4% | 40,6% | 24,3% |
| M | 30,1% | 46,3% | 30,4% |
| L | 15,5% | 48,8% | 16,5% |
| XL | 18,1% | 52,8% | 20,8% |
Сходимость: независимый расчёт по чистой реализации из финотчёта
(Purchase-Autumn-Spring-27/Tank tops.xlsx, ноя-25 – июл-26) дал
8,3 / 24,5 / 32,1 / 16,8 / 18,3 — расхождение в пределах 2 п.п. Эталон устойчив.
Комбинезоны спортивные, S–XL
1 141 заказ / 280 выкупов в 6 чистых артикул-месяцах.
| Размер | Доля заказов | Выкуп | Доля поставки |
|---|---|---|---|
| S | 35,0% | 26,9% | 38,2% |
| M | 35,5% | 23,2% | 33,6% |
| L | 19,6% | 25,0% | 20,0% |
| XL | 9,9% | 20,4% | 8,2% |
⚠ Выборка тонкая, по XL всего 23 выкупа. Для XL надёжнее доля заказов (9,9%), чем доля выкупов (8,2%). Прошлый ручной эталон закупки (S 36 / M 37 / L 16 / XL 11) лежит рядом — расхождение в пределах шума выборки.
Комбинезоны спортивные, S–L
15 451 заказ / 3 233 выкупа в 90 чистых артикул-месяцах. Самая надёжная группа.
| Размер | Доля заказов | Выкуп | Доля поставки |
|---|---|---|---|
| S | 42,5% | 22,7% | 44,8% |
| M | 39,5% | 21,4% | 39,7% |
| L | 18,0% | 18,3% | 15,5% |
Леггинсы, S–L
1 605 заказов / 509 выкупов в 15 чистых артикул-месяцах.
| Размер | Доля заказов | Выкуп | Доля поставки |
|---|---|---|---|
| S | 41,7% | 34,5% | 44,8% |
| M | 37,1% | 29,5% | 33,6% |
| L | 21,1% | 33,1% | 21,6% |
Формат ответа
Обязательная таблица:
Размер | Доля заказов | Выкуп по размеру | Доля поставки | Везти, шт
Под таблицей — три строки:
- Источник: A (сам артикул) / B (группа) / C (аналог) и почему именно он.
- Выборка: сколько чистых артикул-месяцев, сколько отброшено и по какой причине.
- Что это значит: какой размер основной, какой лучше по выкупу, где перекос против того, что уже лежит на складе.
Если сетка расходится с уже закупленным или приехавшим товаром — сказать прямо, с числом лишних/недостающих штук по размеру. Это самое ценное в ответе.
Округление
Раскладывать план методом наибольших остатков: дробные части сортируются по
убыванию, остаток добирается сверху вниз. Так сумма всегда сходится с планом и
ни один размер не перекашивается систематически. В size_mix.py это уже
сделано, руками не пересчитывать.
⚠ MOQ поставщика проверять после раскладки, а не до. У маек MOQ — 100 шт на размер, у комбинезонов — 50. Размер либо ≥ MOQ, либо 0. Добивать до MOQ в первую очередь то, что не сгорает по сезону; тёплые L/XL не раздувать.
Связь с другими плейбуками
| Нужно | Плейбук |
|---|---|
| Сколько всего везти | wb/replenishment-playbook.md |
| Прогноз заказов и продаж | wb/static-orders-sales-forecast-playbook.md |
Определение выкупа и srid |
wb/buyout-playbook.md |
| Куда по регионам, локализация | wb/replenishment-playbook.md, data/knowledge/wb/localization-index.md |
| Что уже лежит на складе | warehouse-stock-playbook.md, report.cmd stocks |
Порядок при полной задаче «что и сколько везти»: сначала этот плейбук (доли),
потом replenishment (объём и регионы). Не наоборот — объём без долей
раскладывать не во что.
Грабли
- Не брать сетку по самому артикулу, если он стоял в OOS. Это главная ловушка, см. MS-17 выше.
- Не брать последнюю неделю как эталон, если FBO по артикулу = 0. Для
пустой карточки
static-orders-sales-forecast-playbook.mdнеприменим: недельный эталон меряет остаток, а не спрос. Брать последний месяц с полной сеткой или живого соседа по группе; в ответе пометить как прокси. - Не смешивать сетки. S из S-M-L и S из XS-S-M-L-XL — разные S.
- Не тянуть доли из закрытого магазина в живой без проверки, что они сходятся: другой ассортимент и другая ценовая полка.
- Не считать долю по выручке. Размеры одной модели стоят одинаково, но скидки и СПП по размерам разные, и доля по деньгам поедет.
- Тонкая выборка честнее, чем красивая цифра. Меньше 300 заказов в чистой выборке — сказать, что сетка ориентировочная, и предложить группу шире.
Чек-лист
- Доля взята по выкупам, а не по заказам (или явно объяснено, почему наоборот).
- Фильтр вымывания применён; отброшенные артикул-месяцы показаны с причиной.
- Источник A/B/C назван явно, порог проверен.
- Сетка группы совпадает с сеткой артикула, для которого считаем.
- План разложен методом наибольших остатков, сумма сходится.
- MOQ проверен после раскладки.
- Указано расхождение с уже закупленным/лежащим товаром в штуках.
- Если данные брались не с прода — сказано, на какую дату они стоят.