134 lines
6.2 KiB
Markdown
134 lines
6.2 KiB
Markdown
# Механика расчёта дефицита поверх прогноза
|
||
|
||
## Общая схема
|
||
|
||
```
|
||
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) (полуоткрытые).
|