Не отчёт о продажах, а решения по ассортименту: что заказать в следующую поставку, что держать в наличии любой ценой, что уценить, где заморожены деньги.
Зачем он нужен
Отчёты показывают, сколько магазин заработал. Они не отвечают на вопросы, которые задают перед каждой закупкой: какие позиции нельзя упускать из наличия, какие пора выводить, и сколько денег лежит на складе мёртвым грузом.
Модуль строит товарную матрицу ABC/XYZ и считает оборачиваемость. Одним экраном видно ядро ассортимента, кандидатов на вывод и сумму замороженных денег.
Что считает
- ABC — вклад товара в выручку. A — верхние 80% выручки, B — следующие 15%, C — остальные. Границы настраиваются: розница часто ставит 70/90.
- XYZ — стабильность спроса по коэффициенту вариации. X — ровный спрос, Y — колеблющийся, Z — рваный, требующий страхового запаса.
- Оборачиваемость — средние продажи в день, дни запаса, риск вымывания (запаса меньше срока поставки) и затоваривания.
- Неликвиды — товары с остатком, не продававшиеся дольше порога, и сумма замороженных в них денег.
Матрица 3x3
Строки — ABC, столбцы — XYZ, в ячейке число товаров и выручка. Клик по ячейке открывает её список.
- AX — ядро ассортимента: делают выручку, спрос ровный, пропадать из наличия не должны.
- AZ — делают выручку, но спрос рваный: нужен страховой запас.
- CZ — кандидаты на уценку и вывод из закупки.
- N — не продавались за период вовсе.
Три вещи, которые модуль делает честно
- Товар, продававшийся меньше чем в трёх интервалах, группу XYZ не получает: коэффициент вариации по двум точкам — это шум, а не оценка стабильности. Такая строка помечается «мало данных».
- Товар без единой продажи за период не сваливается в группу C, а выносится в отдельную группу N. Иначе C превращается в помойку, где «продаётся плохо» неотличимо от «не продаётся вовсе».
- Новинка помечается флагом: у неё низкая выручка не потому, что она не нужна, а потому что она мало прожила.
Цифры, которым нельзя верить, хуже отсутствия цифр — поэтому модуль о них предупреждает, а не проставляет буквы всем подряд.
Работает на большой базе
Матрица не считается на лету: продажи сворачиваются в агрегат по интервалам, и расчёт идёт по нему. Агрегат пополняется инкрементально — пересобираются только изменившиеся интервалы, а смена статуса заказа задним числом учитывается (отменённый заказ из продаж исчезает).
На тестовой базе с 54 000 заказов и 104 000 строк товаров в заказах полный пересбор занимает около трёх секунд, обычный проход — доли секунды. Пересчёт запускается кнопкой с прогрессом или кроном.
Точка заказа: что заказывать прямо сейчас
Отдельная вкладка «К закупке» показывает товары, остаток которых опустился до точки заказа, и сколько штук не хватает.
- Точка заказа = спрос за срок поставки + страховой запас, рассчитанный от разброса спроса, а не взятый с потолка.
- Уровень сервиса настраивается: 95% — обычный выбор розницы, 99% замораживает в полтора раза больше денег.
- Срок поставки задаётся общий и переопределяется на производителя: местный склад везёт за три дня, Китай — за два месяца.
- Если продаж мало, страховой запас не выдумывается, а строка честно помечается «мало данных».
Динамика: кто вырос, а кто просел
Каждый пересчёт сохраняется снимком, и любые два можно сравнить.
- Матрица переходов: сколько товаров перешло из группы в группу.
- Список товаров с переходом вида AX → BZ и разницей выручки.
- Режим «сильнее всего изменилась выручка» — для тех, кто потерял деньги, не сменив букву: лидер может потерять три четверти выручки и остаться в группе A просто потому, что он и так был первым.
- Снимки, посчитанные по разным настройкам, модуль сравнивать не даёт молча — он об этом предупреждает.
Массовые действия
Решение, принятое по отчёту, тут же и применяется: уценить группу, снять с витрины, вернуть обратно.
- Скидка пишется в штатные спецпредложения OpenCart с отдельным приоритетом модуля — повторный запуск не плодит дубли, а скидки, выставленные руками, не трогаются.
- Действие применяется ко всей текущей выборке, а не только к видимой странице, и всегда спрашивает подтверждение с точным числом товаров.
- Действие без единого фильтра не выполняется: уценить весь каталог одним кликом случайно нельзя.
- Каждое применение пишется в журнал — что, к скольким товарам и под каким администратором.
Ещё в модуле
- Фильтры: магазин, категория с подкатегориями, производитель, пометка, наличие остатка, поиск по названию и модели.
- Экспорт текущей выборки в CSV — открывается Excel двойным кликом.
- Учёт вариантов товара (размер, цвет) отдельными позициями — для одежды и обуви, где ходовой размер кончается раньше остальных.
- Мультистор: матрица по каждой витрине и сводная по всем.
- Прибыль и оценка запасов по себестоимости, если в базе есть колонка cost (её заводят товароучёты); без неё модуль работает по выручке и прямо пишет об этом в отчёте.
- ABC по прибыли вместо выручки там, где в базе есть себестоимость.
Требования
- OpenCart 3.0.x / ocStore 3.0.x
- PHP 7.0+ (проверено на 8.3), MySQL 5.7+ / MariaDB 10.3+
Ядро правится одной вставкой — пунктом в меню «Отчёты». Свои таблицы, чужие не трогает.
Версия модуля: 2.0
Что нового в версии 2.0
- Точка заказа со страховым запасом, уровнем сервиса и сроками поставки по производителям, вкладка «К закупке».
- Вкладка «Динамика»: сравнение снимков, матрица переходов, списки выросших и просевших товаров.
- Массовые действия над выборкой: скидка, снятие с витрины, возврат — с журналом действий.
- ABC по прибыли вместо выручки.