AAYMA
RU
Войти

SupplyFlow

Django-сервис для закупщика. Считает, сколько каждого SKU заказать у поставщика (Systeme Electric, IEK), объясняет расчёт по строке, даёт вручную…

Рабочий MVP
Команда «AEZ Tech» 9💬 0 комментариевс 23 сентября 2026 г.

О проекте

Команда: AEZ Tech
Кейс HackAlem.ai: Логистика — Электрокомплект · ekt.kz
Стадия: Рабочий MVP

Задача кейса: Автоматический расчёт заказов поставщикам для пополнения склада, с утверждением менеджером

Суть

Django-сервис для закупщика. Считает, сколько каждого SKU заказать у поставщика (Systeme Electric, IEK), объясняет расчёт по строке, даёт вручную поправить количество с указанием причины, утвердить заказ и выгрузить его в CSV.

Как устроено

XLSX/CSV выгрузки (продажи, остатки, MOQ, товары в пути, периоды stockout) импортируются в SQLite с контролем версий по контрольной сумме. Детерминированный engine.py для каждого SKU берёт прогноз на горизонт «срок поставки + период пересмотра» и учитывает сезонность (сначала по SKU, затем по категории), ограниченный рост, компенсацию упущенного спроса и исключение разовых крупных продаж. Потребность = прогноз + страховой запас − свободный остаток − поступления; затем пересчёт в закупочную единицу, подъём до MOQ и округление до кратности упаковки. Утвердить заказ может только пользователь с правом can_approve_order и только если нет блокировок.

Ключевые решения

  • сезонные коэффициенты SKU/категория
  • компенсация stockout
  • исключение разовых крупных продаж
  • страховой запас
  • MOQ и кратность упаковки
  • дни покрытия для срочности
  • аудит ручных правок

Особенности

AI сознательно не используется: каждый фактор расчёта сохраняется в строке рекомендации. Выгрузки с ФИО клиентов отклоняются, принимается только обезличенный customer_hash. Если транзакции не сходятся с помесячным отчётом, позиция блокируется. Есть 11 тестов и демо-SKU для сезонности, разовой крупной продажи и stockout.

Стек

Python 3.11 · Django 5.2 · SQLite · openpyxl · HTML/CSS · серверный SVG


Проект создан за 5 часов на финале хакатона HackAlem.ai (23 сентября 2026, Астана). Код — BAITC-Hacks/hack-0ab753f5-aez-tech.

README

README.md

SupplyFlow — планирование закупок и контроль запасов

SupplyFlow — сервис планирования закупок для менеджеров по снабжению. Он объединяет данные о продажах, доступных остатках, поставках в пути и условиях поставщиков, чтобы формировать прозрачные рекомендации по пополнению склада: какие товары заказать, в каком объёме, по каким причинам и с какой срочностью.

Решение разработано для кейса автоматизации заказов поставщикам. В текущей версии реализован локальный MVP на Django с использованием предоставленных данных Systeme Electric и IEK.

Проблема и целевая аудитория

Менеджеру по закупкам приходится вручную объединять данные о продажах, складских остатках, минимальных партиях и ожидаемых поставках. Такой процесс занимает много времени, выполняется нерегулярно и повышает риск дефицита, избыточных запасов и ошибок в заказах. На точность также влияют сезонность спроса и разовые крупные продажи, которые искажают регулярную потребность.

SupplyFlow предназначен для менеджеров по закупкам и снабжению. Сервис формирует единый прозрачный процесс: загрузка и проверка данных → расчёт потребности → анализ рисков и рекомендаций → корректировка → утверждение → выгрузка заказа поставщику.

Что реализовано

Работа с данными

  • Импорт предоставленных XLSX-выгрузок Systeme Electric и IEK.
  • Импорт CSV для актуальных остатков, периодов отсутствия товара и справочника категорий/единиц измерения.
  • Сохранение версии импорта: имени файла, контрольной суммы, даты, числа строк и предупреждений. Повторная загрузка файла с той же контрольной суммой не дублирует данные.
  • Сохранение кода 1С как текста, поэтому ведущие нули и суффиксы SKU не теряются.
  • Проверка структуры загружаемых файлов и ограничение размера файла до 30 МБ.
  • Защита приватности: транзакционная выгрузка с полями клиент, фио или имя клиента отклоняется. Для анализа клиента поддерживается только обезличенный customer_hash.

Расчёт потребности

  • Прогноз по SKU на горизонт «срок поставки + период пересмотра».
  • Сезонность из количественной помесячной истории: сначала для SKU, при недостатке полной истории — по категории, иначе нейтральный коэффициент.
  • Устойчивый рост спроса: сравнение последних трёх месяцев с аналогичным периодом прошлого года; рост ограничивается параметром политики закупки.
  • Компенсация упущенного спроса в зафиксированные периоды stockout.
  • Поиск и исключение разовых крупных продаж по документу или customer_hash. Исключение применяется, только если транзакции за месяц согласуются с помесячным отчётом; при расхождении позиция блокируется.
  • Учёт свободного остатка, поступлений до конца горизонта, страхового запаса, MOQ, кратности упаковки и коэффициента пересчёта закупочной единицы в складскую.
  • Расчёт срочности по числу дней покрытия запасом.

Работа закупщика

  • Панель с показателями расчёта и графиками спроса за 12 месяцев, срочности, структуры заказа по категориям и факторов корректировки.
  • Список последних расчётов по поставщикам.
  • Объяснение по каждой SKU: прогноз, запас, свободный остаток, поставки в пути, сезонность, рост, stockout, округление и блокирующие проблемы.
  • Поиск, фильтры «к заказу / требуют проверки / все позиции» и постраничный вывод.
  • Ручная правка количества с обязательной причиной, автором и датой изменения.
  • Финальная сводка перед утверждением: объём заказа, высокий риск, ручные правки и блокировки.
  • Утверждение доступно только пользователю с правом planner.can_approve_order и только при отсутствии блокировок.
  • Экспорт утверждённого заказа в CSV с кодом 1С, артикулом, наименованием, количеством, единицей измерения и поставщиком.
  • Django Admin для справочников, политик, остатков, stockout-периодов, импортов и аудита расчётов.

Как работает решение

  1. Менеджер входит в сервис и открывает страницу «Данные».
  2. Сервис показывает последние версии источников и таблицу готовности данных по каждому поставщику: продажи, свободные остатки, MOQ, политика запаса, товары в пути, stockout и обезличенный идентификатор клиента.
  3. На странице «Панель» менеджер выбирает поставщика, дату расчёта, склад и при необходимости категорию.
  4. Сервис создаёт сохранённый черновик расчёта. Для каждой SKU рассчитывается потребность и формируется объяснение результата.
  5. На панели менеджер анализирует графики. На странице «Заказы» открывает расчёт нужного поставщика и проверяет строки заказа.
  6. При необходимости менеджер корректирует количество и указывает причину правки.
  7. Пользователь с правом утверждения проверяет финальную сводку и утверждает черновик. При проблемах с входными данными утверждение блокируется.
  8. После утверждения доступен CSV-файл для дальнейшей работы в учётной системе. Автоматической отправки заказа поставщику в проекте нет.

Логика расчёта

Для каждой позиции рассчитывается:

Потребность = прогноз на горизонт поставки
            + страховой запас
            − свободный остаток
            − подтверждённые поступления до конца горизонта

Полученная потребность переводится в закупочную единицу, поднимается до MOQ и округляется до кратности упаковки. В строке заказа сохраняются исходная величина до округления и итоговое количество.

Архитектура

flowchart LR
    A[XLSX и CSV выгрузки] --> B[Импортёры planner/importers.py]
    B --> C[(SQLite / Django ORM)]
    C --> D[Расчётный модуль planner/engine.py]
    D --> E[CalculationRun и Recommendation]
    E --> F[Представления planner/views.py]
    F --> G[Панель, Данные, Заказы, карточка расчёта]
    G --> H[Ручная правка и утверждение]
    H --> I[CSV-экспорт]
КомпонентНазначение
planner/models.pyМодели поставщиков, товаров, продаж, запасов, поставок в пути, stockout, политик, расчётов и рекомендаций.
planner/importers.pyАдаптеры форматов предоставленных Excel-файлов и CSV.
planner/engine.pyДетерминированный и объяснимый алгоритм прогноза и расчёта заказа.
planner/views.pyПользовательский сценарий: панели, импорт, расчёт, правка, утверждение и экспорт.
planner/templates/planner/Адаптивный русскоязычный интерфейс на HTML/CSS; графики строятся сервером в SVG.
planner/admin.pyНастройка и аудит данных через Django Admin.
planner/tests.pyАвтоматические проверки расчёта и HTTP-экранов сервиса.
source_audit.py, source_metrics.py, source_deep.pyRead-only скрипты аудита структуры и качества исходных XLSX.

Технологии

ТехнологияНазначение
Python 3.11Язык приложения, импорта и расчётного алгоритма.
Django 5.2Веб-приложение, маршрутизация, шаблоны, формы, аутентификация, права, админка и ORM.
SQLiteЛокальная база данных в файле db.sqlite3.
openpyxl 3.1Чтение XLSX-выгрузок.
HTML, CSS, серверный SVGИнтерфейс и графики без зависимости от JavaScript.
Django TestCaseАвтоматические тесты бизнес-логики и HTTP-экранов.

В проекте не используются AI-модели, внешние API, облачные сервисы, брокеры сообщений или сторонние аналитические платформы. Алгоритм намеренно детерминированный: факторы расчёта сохраняются в строке рекомендации и доступны закупщику.

Установка и запуск

Требования

  • Windows и PowerShell;
  • Python 3.11;
  • папка с предоставленными материалами, содержащая каталоги Systeme electric и IEK.

Команды

В PowerShell перейдите в корень репозитория:

cd C:\Users\Alex\Desktop\HackAlem

Создайте окружение, установите зависимости и примените миграции:

py -3.11 -m venv .venv311
.\.venv311\Scripts\python.exe -m pip install -r requirements.txt
.\.venv311\Scripts\python.exe manage.py migrate

Импортируйте предоставленные файлы и создайте синтетический набор для сквозной демонстрации:

.\.venv311\Scripts\python.exe manage.py import_samples --source-root 'C:\Users\Alex\Desktop\материалы HackAlem'
.\.venv311\Scripts\python.exe manage.py seed_demo

Создайте пользователя администратора и запустите сервер:

.\.venv311\Scripts\python.exe manage.py createsuperuser
.\.venv311\Scripts\python.exe manage.py runserver

Откройте http://127.0.0.1:8000/ и войдите под созданной учётной записью.

Полезные команды:

# Проверка приложения
.\.venv311\Scripts\python.exe manage.py check

# Автоматические тесты
.\.venv311\Scripts\python.exe manage.py test planner

# Повторный импорт, включая файлы с прежней контрольной суммой
.\.venv311\Scripts\python.exe manage.py import_samples --source-root 'C:\Users\Alex\Desktop\материалы HackAlem' --force

Как проверить решение

Полный сценарий жюри можно повторить без изменения исходных Excel-файлов.

  1. Выполните команды установки, импорта и seed_demo из раздела выше.

  2. Войдите на сайт и на странице «Данные» откройте таблицу «Готовность данных к расчёту».

  3. На «Панели» выберите поставщика «Демо: синтетические данные», дату 2026-09-22 и склад Все. Нажмите «Сформировать рекомендации».

  4. На странице расчёта проверьте блок «Финальная проверка заказа» и раскройте «Показатели расчёта» у строк.

  5. Убедитесь, что у демонстрационных SKU отражаются разные факторы:

    • DEMO-SEASON — выраженная сезонность и поступление в пути;
    • DEMO-BULK — исключение разовой крупной продажи;
    • DEMO-STOCKOUT — компенсация периода отсутствия товара.
  6. Измените количество одной позиции, укажите причину и сохраните правку. В финальной сводке увеличится число ручных изменений.

  7. Утвердите заказ под суперпользователем и скачайте CSV.

  8. Запустите manage.py test planner. В проекте выполняется 11 тестов: сезонность, stockout, аномалии, остатки и поступления, MOQ, политика категории, права на утверждение, ручная правка, экспорт и основные экраны.

Данные и интеграции

Предоставленные источники

Импортирующая команда поддерживает следующие файлы:

ПоставщикИспользуемые источники
Systeme ElectricMOQ/кратность, помесячные продажи в штуках, помесячные остатки, динамика продаж по документам, сводный файл на 22.09.2026 со свободными остатками и товаром в пути.
IEKMOQ, помесячные продажи в штуках, помесячные остатки, динамика продаж по документам, файл товара в пути с ожидаемыми датами.

Файлы сезонности из материалов содержат выручку на уровне поставщика. Они не используются для количественного прогноза SKU: сервис рассчитывает сезонность из помесячных продаж в штуках.

Также поддерживаются CSV:

ТипОбязательные поля
Актуальные остаткиsku, warehouse, as_of, on_hand, reserved, free
Stockout-периодыsku, warehouse, starts, ends
Каталог и единицыsku и изменяемые поля category, article, name, unit, min_order, pack_multiple, purchase_to_stock_factor

Исходные XLSX-файлы не копируются в репозиторий и не включаются в Git. Сервис не обращается к внешним API. Выгрузка заказа — универсальный CSV с разделителем ; и UTF-8 BOM для удобного открытия в Excel.

Ограничения текущей версии

  • Решение является локальным MVP и использует SQLite. Производственное развёртывание, PostgreSQL, резервное копирование и настройка веб-сервера не реализованы.
  • В предоставленных материалах нет актуального свободного остатка IEK на дату расчёта. Можно показать расчёт с начальным остатком месяца, но утверждение таких строк блокируется.
  • В исходных материалах нет периодов stockout. Поэтому для реальных строк компенсация упущенного спроса равна нулю; функция проверяется на синтетическом наборе.
  • В исходных транзакциях нет customer_hash. Система находит разовые продажи по документам, но не может объединить несколько документов одного клиента.
  • В части транзакционных и помесячных данных есть расхождения. Сервис не вычитает аномалии из несогласованного месяца и показывает блокировку.
  • Для части номенклатуры IEK неизвестен коэффициент перевода закупочной единицы в складскую, например бухты в метры. Такие позиции блокируются.
  • Цена может быть импортирована в unit_price, но не участвует в оптимизации бюджета или маржинальности.
  • Экспорт CSV содержит поля, необходимые для проверки заказа, но точный формат импорта в конкретную конфигурацию 1С не реализован.
  • Нет автоматической отправки заказа поставщику. Это соответствует ограничению кейса: заказ требует подтверждения ответственного сотрудника.
  • Политики поставщиков после импорта создаются с рабочим допущением 30 / 30 / 15 дней и имеют статус confirmed=False. Их принятие выполняется ответственным пользователем в Django Admin.

Развёрнутая версия

Публичная deployed-версия в текущем репозитории отсутствует. Проект запускается локально по адресу http://127.0.0.1:8000/.

Звёзды
⭐ 0
Форки
0
Язык
Python
Последний push
в прошлом месяце
Коммиты
7
Авторы
3
Файлы
38
Ветки
1

Авторы коммитов

Alexandr Sharepin 5zhanitsi 1Apollo-CMYK 1

История коммитов

  • 2026-09-23 16:52Update README.mdzhanitsi
  • 2026-09-23 16:47Обновить описание в README.mdApollo-CMYK
  • 2026-09-23 16:43Merge latest main updatesAlexandr Sharepin
  • 2026-09-23 16:42Refine procurement dashboard copyAlexandr Sharepin
  • 2026-09-23 16:38Update README.mdШарепин Александр
  • 2026-09-23 16:30Merge remote mainAlexandr Sharepin
  • 2026-09-23 16:28Initial MVP implementationAlexandr Sharepin
Структура репозитория (38 файлов)
.gitignore
README.md
manage.py
planner/__init__.py
planner/admin.py
planner/apps.py
planner/engine.py
planner/forms.py
planner/importers.py
planner/management/__init__.py
planner/management/commands/__init__.py
planner/management/commands/import_samples.py
planner/management/commands/seed_demo.py
planner/migrations/0001_initial.py
planner/migrations/0002_product_requires_conversion.py
planner/migrations/0003_alter_calculationrun_options.py
planner/migrations/0004_calculationrun_category.py
planner/migrations/0005_saleline_unit_price.py
planner/migrations/__init__.py
planner/models.py
planner/templates/planner/base.html
planner/templates/planner/data.html
planner/templates/planner/home.html
planner/templates/planner/login.html
planner/templates/planner/orders.html
planner/templates/planner/run.html
planner/tests.py
planner/urls.py
planner/views.py
requirements.txt
source_audit.py
source_deep.py
source_metrics.py
supply_order/__init__.py
supply_order/asgi.py
supply_order/settings.py
supply_order/urls.py
supply_order/wsgi.py

Обсуждение 0 комментариев

Войдите, чтобы комментировать

Пока нет комментариев — будьте первым.