BR 1.14 — Warehouse Service
Миграция
- Создать таблицу
warehouses(id, franchise_id, store_id, name, status, created_at) - UNIQUE constraint (franchise_id, store_id)
- Индекс
idx_warehouses_franchise_idна franchise_id - Создать таблицу
stock_batches(id, warehouse_id FK, ingredient_id FK, purchase_price, quantity, unit_of_measure, received_date, shelf_life_date, status, created_at) - Индекс
idx_stock_batches_warehouse_ingredientна (warehouse_id, ingredient_id) - Создать таблицу
stock_balances(id, warehouse_id FK, ingredient_id FK, current_quantity, average_cost, unit_of_measure, updated_at) - UNIQUE constraint (warehouse_id, ingredient_id)
- Создать таблицу
receipt_acts(id, franchise_id, warehouse_id FK, document_number, receipt_date, comment, status, total_amount, created_by, timestamps) - Индекс
idx_receipt_acts_franchise_statusна (franchise_id, status) - Создать таблицу
receipt_act_lines(id, receipt_act_id FK CASCADE, ingredient_id FK, quantity, unit_of_measure, unit_price, line_total, shelf_life_date) - Создать таблицу
write_off_acts(id, franchise_id, warehouse_id FK, document_number, write_off_date, reason, status, total_cost, created_by, timestamps) - Индекс
idx_write_off_acts_franchise_statusна (franchise_id, status) - Создать таблицу
write_off_act_lines(id, write_off_act_id FK CASCADE, ingredient_id FK, quantity, unit_cost, line_cost)
Entity / DTO
- Создать
Warehouseentity - Создать
WarehouseResponseDTO - Создать
StockBatchentity - Создать
StockBalanceentity - Создать
StockBalanceResponseDTO - Создать
ReceiptActentity - Создать
ReceiptActLineentity - Создать
ReceiptActResponse,ReceiptActLineResponseDTO - Создать
CreateReceiptActRequest,UpdateReceiptActRequestDTO - Создать
CreateReceiptActLineRequest,UpdateReceiptActLineRequestDTO - Создать
WriteOffActentity - Создать
WriteOffActLineentity - Создать
WriteOffActResponse,WriteOffActLineResponseDTO - Создать
CreateWriteOffActRequest,UpdateWriteOffActRequestDTO - Создать
CreateWriteOffActLineRequestDTO - Создать
AverageCostResponseDTO
Repository
- Создать
WarehouseRepository(findByFranchiseId, findByFranchiseIdAndStoreId) - Создать
StockBatchRepository(findByWarehouseIdAndIngredientId с qty > 0, сортировка по received_date ASC для FIFO) - Создать
StockBalanceRepository(findByWarehouseId, findByWarehouseIdAndIngredientId) - Создать
ReceiptActRepository(findByFranchiseId с фильтрами warehouse_id, status, пагинация) - Создать
ReceiptActLineRepository(findByReceiptActId) - Создать
WriteOffActRepository(findByFranchiseId с фильтрами) - Создать
WriteOffActLineRepository(findByWriteOffActId)
Service
- Создать
WarehouseService— автоматическое создание склада при событии store.created, получение складов по franchise_id с ролевой фильтрацией - Создать
StockService— управление балансами, расчёт средневзвешенной цены, FIFO-логика списания партий - Создать
ReceiptActService— CRUD draft-документов, проводка (создание партий, обновление балансов, пересчёт average_cost), генерация document_number - Создать
WriteOffActService— CRUD draft-документов, проводка (валидация остатков, FIFO-списание, обновление балансов), расчёт unit_cost из средневзвешенной - Обновить
CostCalculationService— получение average_cost из stock_batches вместо статического значения
Controller
- Создать
WarehouseController(GET /warehouses) - Создать
StockController(GET /stock-balances, GET /stock-balances/{wId}/{iId}, GET /ingredients/{id}/average-cost) - Создать
ReceiptActController(GET/POST /receipt-acts, GET/PATCH /receipt-acts/{id}, POST /receipt-acts/{id}/post, POST/PATCH/DELETE /receipt-acts/{id}/lines) - Создать
WriteOffActController(GET/POST /write-off-acts, GET/PATCH /write-off-acts/{id}, POST /write-off-acts/{id}/post, POST/DELETE /write-off-acts/{id}/lines)
Kafka Consumer
- Добавить consumer для
store.created→ автоматическое создание склада (WarehouseService.createForStore)
Тестирование
- Unit-тесты: FIFO-логика в StockService
- Unit-тесты: средневзвешенная цена
- Unit-тесты: проводка приёмки (создание партий + обновление балансов)
- Unit-тесты: проводка списания (валидация остатков + FIFO)
- Integration-тесты: полный цикл приёмка → списание → проверка остатков