Перейти к основному содержимому

Склад

Управление складом материалов. Веб-интерфейс: sklad.salonai.ru.


Архитектура складского учёта

Склад построен вокруг концепции движений (SkladMovement). Любое изменение остатка — это движение с типом и источником.

SkladProduct (товар)

├── SkladStockBalance — остаток по каждому хранилищу (SkladStorage)

├── SkladMovement — каждое изменение остатка
│ ├── doc_type: receipt / expense / write_off / ...
│ ├── status: draft → posted
│ └── source: manual / yclients_sync / work_session / package

├── SkladPurchaseOrder — заказ поставщику
│ └── SkladPurchaseOrderLine — позиции заказа

├── SkladInventorySession — инвентаризация
│ └── SkladInventoryLine — позиции пересчёта

├── SkladTechCard — техкарта (норма расхода на услугу)
│ └── SkladTechCardLine — позиции техкарты

├── SkladBatch — партионный учёт
├── SkladReservation — резерв под предстоящие услуги
└── SkladOverconsumptionAlert — сигнал о перерасходе

Движения (SkladMovement)

Типы движений (doc_type)

ТипОписаниеВлияние на остаток
receiptПоступление (от поставщика)+
expenseРасход (продажа клиенту)
write_offСписание (порча, истечение срока)
consumption_write_offСписание по факту использования на услуге
transferПеремещение между хранилищами±0 (два движения)
adjustmentКорректировка (по итогам инвентаризации)±

Статусы движения

draft → posted
СтатусОписание
draftЧерновик — остатки ещё не изменены
postedПроведён — остатки обновлены в SkladStockBalance

Источники движения (source)

ИсточникОписание
manualСоздано вручную пользователем
yclients_syncАвтоматически при синхронизации с YClients
work_sessionАвтоматически при закрытии рабочей сессии мастера
packageСписание из открытого пакета (SkladOpenPackage)

Заказы поставщикам (SkladPurchaseOrder)

Жизненный цикл заказа

draft → sent → partial → received

└──────────────> cancelled
СтатусОписание
draftЧерновик заказа, ещё не отправлен
sentЗаказ отправлен поставщику
partialПолучена часть позиций
receivedПолучено полностью
cancelledОтменён

При переходе в received автоматически создаётся движение типа receipt в SkladMovement.


Инвентаризация (SkladInventorySession)

Жизненный цикл инвентаризации

draft → counting → posted
СтатусОписание
draftИнвентаризация создана, счёт не начат
countingИдёт пересчёт: вносятся фактические остатки по позициям
postedПроведена: расхождения зафиксированы движениями adjustment

Алгоритм проведения инвентаризации:

  1. По каждой позиции (SkladInventoryLine) сравнивается fact_qty с system_qty
  2. Если есть расхождение — создаётся SkladMovement типа adjustment
  3. SkladStockBalance обновляется до фактических значений

Техкарты (SkladTechCard)

Техкарта — это норма расхода материалов на конкретную услугу.

SalonService ──── SkladServiceTechCardBinding ──── SkladTechCard

SkladTechCardLine
(product + quantity)

При закрытии рабочей сессии (work_session) система:

  1. Находит техкарты для каждой оказанной услуги
  2. Создаёт движение consumption_write_off на фактический расход
  3. Если фактический расход превышает норму — создаётся SkladOverconsumptionAlert

Список товаров на складе

GET /api/sklad/products/
Authorization: Bearer <token>

Ответ:

{
"results": [
{
"id": 101,
"name": "Краска для волос Wella",
"sku": "WL-1234",
"quantity": 15,
"unit": "шт",
"critical_stock": 5,
"desired_stock": 20,
"price": "350.00",
"photo": "https://sklad.salonai.ru/media/sklad/products/..."
}
]
}
Критический остаток

Когда quantity <= critical_stock, система генерирует предупреждение владельцу. Уведомление отправляется через n8n (N8N_OWNER_ADMIN_WEBHOOK_URL).


Заказы поставщикам

Список заказов

GET /api/sklad/procurements/
Authorization: Bearer <token>

Создать заказ

POST /api/sklad/procurements/
Authorization: Bearer <token>

{
"items": [
{ "product_id": 101, "quantity": 10, "price_per_unit": "340.00" }
],
"supplier": "Поставщик ООО",
"expected_date": "2026-08-10"
}