Закупщик дилера
Ищет товары, собирает заказ, устраняет предупреждения, принимает замены и отслеживает статус.
Ограничение
Видит только данные своей организации и разрешённый ассортимент.
Закрытый кабинет дистрибьютора, где единица работы — дилерский заказ салона или организации, а не корзина витрины. Портал проводит закупщика от подбора сантехники до подтверждённого резерва и готовности к отгрузке.
Содержание
Клиент — региональный дистрибьютор сантехники в Беларуси. Он работает с дилерскими салонами, розничными магазинами, монтажными организациями и небольшими строительными компаниями. Закупщик дилера собирает заказ на пополнение салона и комплектацию нескольких объектов сразу: санитарная керамика, мебель для ванных, смесители, душевое оборудование, инсталляции, комплектующие и запасные части. Дистрибьютор автозапчастей ведёт подбор автозапчастей по VIN для автосервисов.
Это не закупочный проект объекта для монтажников: там бригада комплектует конкретный узел на объекте. Здесь единица работы — заказ организации у дистрибьютора: договорной ассортимент, кратность упаковки, два склада отпуска и подтверждённый резерв. Когда «интернет-магазин» на деле оказывается бизнес-системой — в интервью Почему бизнесу иногда нужен Laravel, а не WordPress.
Портал не заменяет учётную систему. Остатки, договорные условия, резервы и документы остаются в существующем контуре. Два склада клиента — точки доступности номенклатуры, а не выбор площадки под технологический процесс: такой контур закрывает подбор склада и производства.
| Показатель | Значение |
|---|---|
| География | Беларусь |
| Склады отпуска | 2 |
| Активные позиции каталога | ~9 000 |
| Дилерские организации | ~180 |
| Пользователи у дилера | несколько на организацию, несколько адресов получения |
| Контур пилота | ограниченная группа дилеров, одна товарная группа |
| Старый канал в пилоте | только как аварийный |
| Основной процесс | От подбора до подтверждённого резерва и готовности к отгрузке |
Каталог не равен заказу: дилеру нужна общая версия строк с вычисляемым состоянием, а не ещё одна выгрузка прайса.
Ищет товары, собирает заказ, устраняет предупреждения, принимает замены и отслеживает статус.
Ограничение
Видит только данные своей организации и разрешённый ассортимент.
Смотрит активные заказы организации, подтверждает внутренне значимые изменения, управляет пользователями.
Ограничение
Не изменяет справочники дистрибьютора.
Разбирает очередь отклонений, предлагает решения внутри заказа, возвращает строки на уточнение.
Ограничение
Не меняет складские остатки вручную; корректные заказы проходят без него.
Ведёт характеристики, связи комплектов, допустимые замены и файлы карточек.
Ограничение
Не подтверждает дилерские заказы.
Складские сотрудники продолжают работать в учётной системе. Портал показывает полученные статусы и не создаёт второй складской интерфейс.
Дилер выписывал позиции из каталога, остатки уточнял у менеджера, аналоги согласовывал в мессенджере, итоговый файл отправлял по почте. Через несколько часов часть товара уже была зарезервирована, одна модель снята с поставки, выбранная инсталляция не подходила к клавише смыва. Менеджер собирал заказ заново: артикулы, упаковки, доступность на двух складах, договорной ассортимент. Дилер в это время продолжал править свою таблицу. Решение о замене жило только в переписке.
Пока заказ жил в таблице, письме и учёте одновременно, ни один участник не видел целостного процесса. Закупщик не понимал, какие остатки доступны именно его организации и когда они будут зарезервированы. Менеджер тратил время на формат данных вместо исключений. Комплект мог быть технически неполным при «правильных» отдельных позициях. Повторный заказ собирался почти с нуля, даже если дилер регулярно закупал одну матрицу.
Центральная сущность продукта — не форма отправки и не каталог, а совместная рабочая область дилерского заказа.
Заказ объединяет организацию, строки, доступность, упаковку, совместимость, замены, резерв и журнал решений в одной версии.
Строка получает собственное состояние: «готово», «нужно уточнение», «нет в наличии», «предложена замена», «ожидает решения дилера» или «исключено». Общий статус заказа вычисляется из строк и обязательных данных. Его нельзя вручную перевести в «готов к подтверждению», если внутри остались нерешённые исключения.
Система проверяет формальные правила и показывает отклонения. Дилер принимает решения по ассортименту. Региональный менеджер вмешивается только там, где автоматического правила недостаточно.
Система не решает, подходит ли иной дизайн для проекта дилера, не объединяет отгрузки с разных складов без согласования и не подменяет товар только из-за совпадения части характеристик.
Закупщик открывает завершённый заказ, выбирает «Повторить», получает новую версию с текущей доступностью и проходит только изменившиеся строки.
Результат: готовый заказ без ручного копирования артикулов.
Пользователь добавляет базовые позиции. Портал показывает недостающие обязательные компоненты и совместимые варианты. Окончательный выбор дизайна остаётся за дилером.
Результат: проверенный состав комплекта, а не набор несвязанных карточек.
Строка помечается как недоступная, показываются заранее разрешённые аналоги. Пользователь сравнивает различия, принимает замену или отправляет вопрос менеджеру.
Результат: решение зафиксировано в заказе и не теряется в переписке.
Учёт возвращает подтверждение не на всё количество. Портал блокирует финал и предлагает изменить количество, выбрать замену, разделить комплектование или дождаться менеджера.
Результат: решение принимает человек, статус строки остаётся объяснимым.
Подтверждённая версия доступна только для чтения. Изменение создаёт новую версию или отдельный запрос. Этапы: «Принят», «Комплектуется», «Готов», «Передан».
Результат: участники смотрят один заказ, без звонков за статусом.
После входа закупщик возвращается в последний активный заказ или в список с явным следующим действием. Сводные графики не являются точкой входа.
Четыре зоны экрана: шапка (организация, адрес получения, способ комплектации, ответственный, общий статус); таблица строк (товар, количество, упаковка, доступность, склад, совместимость, состояние); панель исключений — только то, что мешает подтверждению; история решений.
Главное действие зависит от состояния: «Исправить 3 исключения», затем «Отправить на резерв», затем «Подтвердить заказ». Пользователь не угадывает следующий шаг.
Пользователь видит разрешённый ассортимент, доступность по складам и документы. Поиск понимает артикул, фрагмент названия и ключевые характеристики. Для объёма первой версии достаточно полнотекста и trigram-индексов PostgreSQL.
Карточка помогает принять закупочное решение: характеристики, варианты серии, наличие, кратность, состав комплекта, обязательные и совместимые компоненты, допустимые замены, инструкция и схема, статус жизненного цикла. Совместимость — явные связи: клавиша к серии инсталляции, мебель к ширине раковины и типу монтажа. Если правило нельзя формализовать надёжно, контент-менеджер ставит предупреждение, а не ложный запрет.
Большинство корректных заказов проходят без участия менеджера. Главный экран — очередь отклонений: какой заказ остановился, что мешает, сколько ждут решения, какое действие ожидается. Та же логика management by exception, что и очередь отклонений клининговой сети, только единица работы здесь — строка дилерского заказа, а не задание на уборку.
Типы исключений: нет допустимой замены, часть количества на другом складе, изменился статус товара, не совпали данные организации, резерв подтвердился частично. При открытии менеджер попадает к проблемной строке. Предлагая замену, он указывает причину и ключевое отличие; дилер видит сравнение. Молчаливой подмены нет.
Нельзя отправить заказ на резерв без организации, адреса получения и корректного количества. Подтверждённая версия неизменяема. Общий статус вычисляется автоматически.
Количество проверяется по кратности; автоматическое округление требует подтверждения. Совместимость пересчитывается при добавлении и при изменении связанной позиции. Замена — только из утверждённой группы аналогов или после предложения менеджера.
Резерв имеет срок из учётной системы и считается подтверждённым только после её ответа. Права задаются на уровне организации, роли и подразделений. Пользователь дилера не получает данные другой организации даже прямым запросом к идентификатору заказа. Просмотр документов пишется в журнал аудита. Для привилегированных ролей — двухфакторная аутентификация.
Первая версия замыкает один процесс: дилер создаёт заказ, устраняет или согласует исключения, получает подтверждённый резерв и видит готовность к следующему этапу. Пилот — ограниченная группа дилеров и одна товарная группа с понятными правилами. Старый канал остаётся только как аварийный.
ИИ не является ключевой частью первой версии. Правила совместимости и замены требуют объяснимых справочников. Позже модель может помогать нормализовать входящие таблицы или искать похожие товары по неполному описанию — с проверкой сотрудника.
Ценность появляется после выбора товара. Закупщик возвращается в заказ и видит исключения и следующее действие. Цвет статуса относится к строке, а не к рекомендации «купить этот артикул».
Выбран профиль единого операционного B2B-приложения: насыщенные таблицы, фильтры и боковые панели без отдельного frontend-сервиса. Обмен с учётом — обмен каталогом, остатками и резервом с учётом: портал получает номенклатуру, доступность, жизненный цикл товара и результат резервирования; обратно передаёт проверенный заказ и идентификаторы подтверждённой версии. Пакет имеет технический идентификатор и журнал ошибок, повторный запуск не создаёт дубликаты.
Client
Быстрое редактирование строк, локальные фильтры и разбор исключений. Inertia сохраняет единый Laravel-репозиторий, сессионную аутентификацию и серверные правила доступа.
API
Модули: пользователи и организации, каталог, совместимость и замены, заказы и версии, резервы, очередь исключений, статусы и документы, уведомления и аудит, интеграция.
Data
Реляционная модель для заказа и журнала. Полнотекст и trigram закрывают поиск без отдельного поискового движка.
Queue / cache
Фоновые задания: импорт каталога и остатков, обработка подтверждений резерва, рассылка, наблюдаемость очереди.
Storage
Файлы карточек с проверкой прав организации. Доступ к внутренним документам журналируется.
Infrastructure
Одинаковое окружение разработки и production. Pest покрывает правила и права. Playwright — критические маршруты заказа и резерва. Микросервисы, отдельный поиск, WebSocket и Kubernetes в MVP не входят.
Срок первой рабочей версии и пилота — 16 недель. Внедрение начинается не со всех дилеров и категорий: главный риск — качество справочников и параллельный процесс в таблицах.
Одна товарная группа: артикулы, характеристики, упаковки, связи комплектов и допустимые замены. Фиксируется контракт обмена с учётом и владение данными.
Поиск, сборка заказа, исключения и предложения замен. Проверка с закупщиками и региональными менеджерами: завершить реальные заказы без внешней таблицы.
Роли, каталог, заказ, версии, проверки и очередь исключений. Интеграция сначала на тестовых пакетах, затем тестовый контур учёта.
Ограниченная группа дилеров и одна категория. Старый канал — только аварийный. Ежедневный разбор причин, по которым заказ не удалось завершить в портале.
Правила и справочники, следующие категории, короткие инструкции по ролям. Масштабирование — после прохождения заказа от выбора до подтверждения без ручного переноса.
Цифры — результаты пилота на одной товарной категории и сопоставимых типах заказов: повторное пополнение матрицы до запуска и после стабилизации процесса. Заказы, сознательно проведённые по аварийному каналу из-за недоступной категории или длительного сбоя обмена, из сравнения исключались.
| Метрика | Состояние до | Стало в пилоте | Как измеряется |
|---|---|---|---|
| Время сборки типового повторного заказа | 45–70 минут | 15–25 минут | Медиана от создания черновика до отправки на резерв |
| Ручные уточнения вне заказа | 4–7 на заказ | 1–2 | Письма, звонки и сообщения по выборке заказов пилота |
| Повторный ввод строк | почти в каждом заказе | не требуется для заказов из портала | Сравнение источника и записи в учётной системе |
| Доля заказов без понятного следующего действия | не фиксируется | менее 5% активных | Срез заказов без системного статуса или ответственного |
| Время обнаружения блокирующего исключения | после ручной проверки менеджером | при добавлении позиции или ответе интеграции | Журнал событий заказа |
| Полнота истории решений по заменам | зависит от переписки | 100% замен из портала | Аудит подтверждённых версий: автор и подтверждение |
| Риск | Вероятность | Влияние | Снижение |
|---|---|---|---|
| В справочнике недостаточно характеристик для совместимости | Высокая | Высокое | Одна категория, владелец данных, предупреждение вместо ложного запрета |
| Остатки обновляются с задержкой | Средняя | Высокое | Показывать время снимка, считать резерв подтверждённым только после ответа учёта |
| Менеджеры продолжают принимать заказы в сообщениях | Высокая | Высокое | Портал как основной канал пилота, исключения только внутри заказа |
| Дилер воспринимает проверки как препятствие | Средняя | Среднее | Причина каждого ограничения и конкретное следующее действие |
| Интеграция возвращает частичные или дублирующиеся ответы | Средняя | Высокое | Идемпотентность, технические идентификаторы, повторные задания, журнал обмена |
| Права организации настроены неверно | Низкая | Высокое | Автотесты изоляции, минимальные права, аудит доступа |
До
После
Главный результат — не перенос формы заказа в браузер. Портал создаёт общий операционный контур между дилером и дистрибьютором: состояние каждой позиции объяснимо, следующее действие видно, подтверждённый состав можно восстановить без звонков.
Сжатая цитата из обратной связи после пилотного внедрения. Название компании и имя не указаны из‑за NDA.
«Самое полезное для меня — вся история по позиции остаётся в заказе. Не нужно искать письмо двухдневной давности, чтобы вспомнить, почему именно предложили этот аналог.»
Нужен похожий контур — обсудим. Услуги на Laravel · Каталог решений.