Files
PriceForge/bible/vendor-mapping.md

91 lines
3.7 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.
# Vendor Mapping (Сопоставление partnumber → LOT)
> Решение зафиксировано: 2026-02-18
## Концепция
`lot_partnumbers` — канонический контракт сопоставления для внешнего конфигуратора.
Маппинг строго 1:1 по ключу `(vendor, partnumber)``lot_name`.
---
## Правила
### 1. Единственная запись на ключ
Запрещено создавать несколько строк для одного ключа `(vendor, partnumber)`.
### 2. Порядок резолвинга (фиксированный)
```
1. Точное совпадение: vendor + partnumber → lot_name
2. Fallback: vendor='' + partnumber → lot_name
```
Резолвер: `internal/lotmatch/matcher.go`
### 3. Составные маппинги — через бандлы
Если один внешний partnumber соответствует нескольким LOT — использовать внутренние бандл-таблицы:
```
lot_partnumbers: (vendor, partnumber) → bundle_lot_name
qt_lot_bundles: bundle_lot_name → [item1, item2, ...]
qt_lot_bundle_items: bundle_lot_name, lot_name, qty
```
- Bundle LOT — внутренний, скрыт в обычном UI LOT по умолчанию.
- Bundle expansion (разворачивание) происходит только внутри PriceForge при расчёте warehouse-прайслиста.
### 4. Ignore-логика
- **Не использовать** `stock_ignore_rules` для новой логики.
- Использовать `qt_vendor_partnumber_seen.is_ignored`.
- `qt_vendor_partnumber_seen` хранится в формате **1 строка на partnumber** (vendor/source не участвуют в уникальности).
- Ignore применяется по `partnumber` (одинаково для записей с vendor и без vendor).
### 5. Клиентская совместимость
- Клиент потребляет LOT-based прайслисты (как обычно).
- Bundle expansion/allocation происходит только внутри PriceForge.
---
## Allocation при отсутствии estimate
Если у bundle-компонента нет estimate-цены:
1. Fallback: взять из предыдущего активного warehouse-прайслиста.
2. Если нет предыдущего — цена `0`.
---
## Таблицы БД
| Таблица | Назначение |
|---------|------------|
| `lot_partnumbers` | Канонические маппинги `(vendor, partnumber)``lot_name` |
| `qt_lot_bundles` | Определения бандлов (bundle LOT → описание) |
| `qt_lot_bundle_items` | Состав бандла: `(bundle_lot_name, lot_name, qty)` |
| `qt_vendor_partnumber_seen` | Реестр seen-записей (уникально по `partnumber`) + флаг `is_ignored` |
Миграции:
- `migrations/023_vendor_partnumber_global_mapping.sql`
- `migrations/025_dedup_vendor_seen_by_partnumber.sql`
---
## Связанные модули
| Роль | Файл |
|------|------|
| Миграция | `migrations/023_vendor_partnumber_global_mapping.sql` |
| Миграция | `migrations/025_dedup_vendor_seen_by_partnumber.sql` |
| Резолвер | `internal/lotmatch/matcher.go` |
| Сервис | `internal/services/vendor_mapping.go` |
| API | `internal/handlers/pricing.go` |
| Warehouse calc | `internal/warehouse/snapshot.go` |
| Stock import seen/ignore | `internal/services/stock_import.go` |
| Модели | `internal/models/lot.go`, `internal/models/configuration.go` |
| Роутинг | `cmd/pfs/main.go` |