---
title: Склад и остатки
group: documents
order: 5
---

# Склад

## Инвариант

`stocks.quantity` = `SUM(stock_movements.quantity)` per `(productId, storeId)`. Подтверждено property-based test'ом (`StockServicePropertyTests`).

## CSV-инвентаризация

«Инвентаризация → Загрузить CSV». Колонки: `article` (или `barcode`), `factQty`. На неизвестные товары — warning в импорт-логе, не падает целиком.

## Низкий остаток

Если у товара заполнено `MinStock` — Hangfire-job `low-stock-alert` каждый день в 08:00 UTC шлёт email-сводку Admin'у. Также реалтайм-уведомление через SignalR `LowStock` после каждой продажи.
