analytics/context/06_DEFICIT_FORECAST.md
2026-02-18 14:36:38 +03:00

134 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Механика расчёта дефицита поверх прогноза
## Общая схема
```
forecast (прогноз) → sp_build_deficit_proposal → deficit_proposal
↑ ↓
stock + inbound + minAvail │ sp_rebuild_stock_plan_by_arrival
│ ↓
└──────────────────── stock_plan_by_arrival
```
## Таблицы
| Таблица | Назначение |
|---------|------------|
| `analytics.forecast` | Прогноз спроса по месяцам (scenario_id, 1c_id, code, month, value) |
| `analytics.deficit_proposal` | Рекомендации к заказу по дефициту (place_month, arrival_month, order_qty) |
| `analytics.stock_plan_by_arrival` | План по месяцам: opening, inbound_confirmed, inbound_deficit, forecast_demand, closing |
## Процедуры
### 1. sp_build_deficit_proposal
**Назначение:** Дефицит и рекомендации к заказу с учётом прогноза по сценарию.
**Параметры (по умолчанию):**
- `@scenario_id` = 4
- `@group_path` = '' — path группы ('' = все группы)
- `@lead_time_m` = 4 — срок поставки (мес.)
- `@cover_months` = 6 — горизонт покрытия (мес.)
- `@from_month` = текущий месяц
- `@to_month_excl` = '2028-01-01'
**Шаги логики:**
1. Календарь месяцев [from, to)
2. SKU по group_path (pbi.groups.path LIKE @path + '%')
3. Прогноз из `analytics.forecast` по scenario_id
4. Inbound — подтверждённые заказы (get_orders_by_group): статусы В пути, В производстве, Выгружен на складе (Согласован закомментирован в коде)
5. Stock = остаток склад (get_quantity_by_group) + MP (get_mp_quantity_by_group)
6. Последовательность по месяцам: demand_m, inbound_m, served_m, lost_m, net_stock (рекурсивный flow)
7. Первый месяц дефицита T: net_stock < minAvailable, месяц >= @from + lead_time
8. Якоря: T, T+cover, T+2cover... до to_month_excl
9. order_qty = прогноз окна [T .. T+cover) (demand_window)
**Результат:** INSERT в `deficit_proposal` (order_qty > 0).
**Источники данных:**
- forecast ← `analytics.forecast`
- inbound ← `analytics.get_orders_by_group`
- stock ← `analytics.get_quantity_by_group`, `analytics.get_mp_quantity_by_group`
- SKU/minAvail ← `pbi.nomenclature`, `pbi.groups`
---
### 2. sp_rebuild_stock_plan_by_arrival
**Назначение:** План остатков по месяцам прихода (opening, inbound, forecast, closing).
**Параметры:** @scenario_id, @from_month, @to_month
**Источники по CTE:**
1. opening_qty — остаток на дату < from_month (pbi.w_ostatok_da_net)
2. inbound_confirmed подтверждённые заказы по месяцу прихода (get_orders_by_group: В пути, В производстве, Выгружен на складе, Согласован)
3. inbound_deficit SUM(order_qty) по deficit_proposal
4. forecast_demand SUM(value) по forecast
**Формула closing:**
```
closing = opening + inbound_confirmed + inbound_deficit - forecast_demand
```
Rolling: opening для месяца M = LAG(closing) по SKU и arrival_month.
**Зависимость:** НЕ вызывает sp_build_deficit_proposal. Только читает deficit_proposal. Перед вызовом должен быть выполнен `sp_build_deficit_proposal` или `sp_run_deficit_all_skus`.
---
### 3. sp_run_deficit_all_skus
**Назначение:** Пересчёт дефицита по всем SKU (group_path = '').
Вызывает `sp_build_deficit_proposal` с @group_path = N''.
---
### 4. sp_загрузка_прогнозаакупки
**Назначение:** Загрузка прогноза из Excel/внешних источников.
Записывает в forecast (scenario_id = 8), при отсутствии кода подтягивает из scenario_id = 5.
В конце может вызывать `sp_build_deficit_proposal` (закомментировано для scenario 8).
---
### 5. create_forecast_loop
**Назначение:** Цикл по группам (path из pbi.groups, lvl=2).
Для каждого path вызывает `sp_build_forecast_s4_by_group` наполняет forecast, **не вызывает** sp_build_deficit_proposal.
---
### 6. sp_build_forecast_s4_by_group
**Назначение:** Построение прогноза по группе (rate_per_day × дни × seasonal_koef).
Вставляет в `analytics.forecast`. Источник сезонности `analytics.seasonality_groups`.
---
## Представления
| View | Источник | Назначение |
|------|----------|------------|
| `analytics.deficit_orders` | deficit_proposal + nomenclature | Заказы по дефициту с ценой и суммой (status='Дефицит') |
---
## Порядок выполнения (рекомендуемый)
1. Прогноз: `create_forecast_loop` или `sp_build_forecast_s4_by_group` или `sp_загрузка_прогнозаакупки`
2. Дефицит: `sp_build_deficit_proposal` или `sp_run_deficit_all_skus`
3. План: `sp_rebuild_stock_plan_by_arrival` (читает deficit_proposal; сперва должен быть вызван п.2)
---
## Правила данных (дефицит)
- Дефицит определяется как net_stock < minAvailable (nomenclature.minAvailableQty).
- order_qty = прогноз спроса на окно [T .. T+cover_months).
- Статусы заказов «входящих»: см. 01_DATA_RULES. Фактически: sp_build_deficit_proposal 3 статуса (Согласован закомментирован); sp_rebuild_stock_plan_by_arrival 4 статуса.
- Интервалы дат [start, end) (полуоткрытые).