# Спринт 2 — складские документы (P1) Автономная работа. После каждого пункта: `dotnet build` (SDK 8.0.126), unit + integration + (где применимо) E2E тесты этого пункта, коммит порцией, отметка `[x]` здесь, коммит прогресса. Multi-tenant: все новые сущности — `TenantEntity` с `OrganizationId` + query filter. Stock-инвариант: после каждого Post/Unpost `Stock.Quantity ≡ Σ StockMovement` для (Product, Store). ## Чек-лист 1. [x] **P1-1 Оприходование (Enter)** — Domain `Enter`+`EnterLine`, EF, миграция, контроллер CRUD + Post/Unpost (Stock + StockMovement тип `Enter`), Web `/inventory/enters`. Без поставщика (источник — начальные остатки, излишек инвентаризации). ✅ Контроллер `api/inventory/enters`; миграция `Phase6a_Enters`; пункт «Оприходования» в сайдбаре Admin/Storekeeper. Тесты: 4 интеграционных (post raise stock, unpost откатывает, double post→409, tenant-изоляция, блокировка unpost при минусе). 2. [x] **P1-2 Списание (Loss)** — Domain `Loss`+`LossLine` + enum `LossReason` (Defect/Expired/Damage/Shortage/Other). EF, миграция, контроллер, Web, `StockMovement` тип `WriteOff`. ✅ Контроллер `api/inventory/losses` (CRUD + Post/Unpost) с проверкой «не списать сверх остатка» (409). Миграция `Phase6b_Losses`. Web с фильтром по причине и колонкой stockAtStore. Тесты: 3 интеграционных (post снижает stock, over-write-off → 409, tenant-изоляция). 3. [ ] **P1-3 Перемещение (Transfer)** — Domain `Transfer`+`TransferLine` (FromStoreId → ToStoreId, обязательны и различны). Атомарная транзакция: `TransferOut` из From + `TransferIn` в To. EF, миграция, контроллер + Post/Unpost, Web. Кейс: post→unpost не оставляет orphan-движений. 4. [ ] **P1-4 Инвентаризация (Inventory)** — Domain `Inventory`+`InventoryLine` (productId, bookQty, actualQty, diff). EF, миграция. Контроллер: создание подгружает текущие остатки; Post создаёт `InventoryAdjustment` на diff. Web: форма со списком товаров склада, импорт CSV факта. 5. [ ] **P1-6 Возврат от покупателя (CustomerReturn)** — расширение `RetailSale` опцией возврата (referenceSaleId или без). Контроллер: создание возврата из проведённой продажи, `CustomerReturn` тип уже есть. Web: кнопка «Создать возврат». 6. [ ] **P1-7 Возврат поставщику (SupplierReturn)** — по аналогии для Supply. Domain `SupplierReturn`+`Line` (referenceSupplyId). Контроллер. Web. 7. [ ] **P1-16 Hangfire dashboard + cleanup** — `Hangfire.Dashboard` с авторизацией только для SuperAdmin. Scheduled: ежедневный cleanup `StockMovement` старше 2 лет, audit-log старше 90 дней. ## Лог - Каждый пункт: build + тесты + коммит порцией + отметка [x] + коммит прогресса. - Все правки на ветке `main` (origin Forgejo), без коммита `global.json`.