Склад интернет-магазина товаров для дома, три человека в смену, около 4 000 артикулов.
Учёт вёлся в Excel - файл на общем диске, приход и расход вносили руками в конце дня.
Приёмку сверяли по бумажной накладной, галочки ставили ручкой, потом кто-то переносил это в таблицу.
На инвентаризации расхождения набирались на несколько десятков позиций, и найти, где именно потерялось, было уже нельзя.
Где физически лежит товар, знали по памяти - новый человек искал коробку по полчаса и дёргал старшего.
Попросили панель в браузере со сканированием штрихкодов, чтобы приёмка и сборка шли по факту, а не по вечерней записи.
Отдельное условие - работать должно с обычного телефона, терминалы сбора данных покупать не хотели.
Фронт на React, бэк - FastAPI, база PostgreSQL, всё в Docker на VPS заказчика.
Приёмка: загрузил накладную, дальше сканируешь коробки - отсканированное отмечается само, недосчитанное остаётся красным до закрытия документа.
Телефон работает сканером через камеру, страница открывается в браузере и распознаёт штрихкод прямо на устройстве, ничего ставить не надо.
Сканер-«пистолет» на приёмочном столе подключается как клавиатура, то-есть он просто печатает код и жмёт Enter - поле ловит такой ввод по скорости набора, мышкой никуда кликать не нужно.
Адресное хранение - стеллаж, секция, полка, ячейка; у каждой ячейки свой штрихкод, разместил товар - отсканировал ячейку.
Сборка заказа идёт маршрутом: строки сортируются по порядку обхода стеллажей, чтобы не бегать из конца склада в конец.
Инвентаризация по зонам, пересчёт в два прохода, на выходе лист расхождений - факт, учёт и разница по каждой позиции.
Списания и перемещения отдельными документами, каждое движение пишется в журнал с автором и временем.
Роли три - кладовщик видит только свои задания, старший правит документы и закрывает инвентаризацию, бухгалтер смотрит остатки и выгрузку.
Оффлайн-режим: в дальнем ряду Wi-Fi не добивает, сканы копятся в браузере телефона и уезжают на сервер, когда связь появляется.
Оффлайн ломается на конфликтах - человек списал коробку без сети, а её уже забрали другим заданием, поэтому каждое движение уходит со своим идентификатором, повторы сервер отбрасывает, а спорные строки показывает старшему отдельным списком.
Так-же сделал печать этикеток на термопринтер - на ячейки и на товар без заводского кода.
Отчёты - остатки на дату, движение по артикулу, оборачиваемость; выгрузка в Excel одной кнопкой.
Приёмка машины на 300 коробок стала занимать около полутора часов вместо половины дня с бумагой и переносом в таблицу.
На первой инвентаризации в системе разошлись 11 позиций вместо тридцати с лишним, и по журналу видно, на каком движении это случилось.
Новый кладовщик выходит в смену без наставника - открыл задание, прошёл по ячейкам, отсканировал.
Бухгалтер берёт остатки выгрузкой сам, просьбы «скиньте актуальную таблицу» из чата пропали.
Исходники, доступ к серверу и инструкция остались у заказчика - как завести пользователя, добавить стеллаж и перепечатать этикетки.
Уже после сдачи доделал приёмку коробами: один короб - один код, внутри фиксированный набор, принимается одним сканом.
Скрины панели и мобильного сканера приложены к работе.