Mango.Nop.Plugins/Nop.Plugin.Misc.AIPlugin/docs/EKAER/EKAER_TODO.md

99 lines
11 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.

# EKÁER — TODO / nyitott döntések
> Companion to [`README.md`](README.md). Topic `EKAER`, prefix `MGFBANKPLUG` → entry IDs `MGFBANKPLUG-EKAER-T-<RAND>`.
> ID format, Status vocabulary, type codes, archival → `../../.github/TOPIC_CODES.md` (→ framework registry).
Scope: a `Shipping` / `ShippingDocument` → NAV `tradeCard` leképezés (`ShippingToEkaerMapper`, `FruitBank.Common/Services/Ekaer/`) nyitott üzleti/technikai döntései. A **tisztázott** megfeleltetést lásd [`README.md`](README.md).
## Active entries
## MGFBANKPLUG-EKAER-T-K7Q2: Shipping → tradeCard mapping — nyitott döntések
**Status:** Open · **Priority:** P2 · **Type:** T (mapping-tervezés)
A `ShippingToEkaerMapper` megírása előtt tisztázandó pontok. Minden sor a jelenlegi (alapértelmezett) feltételezést és a nyitott kérdést rögzíti.
| # | Téma | Jelenlegi feltételezés | Nyitott kérdés |
|---|------|------------------------|----------------|
| 1 | `tradeType` (E/I/D irány) | ✅ **Frissítve (2026-06):** a feladó és a címzett **országkódjának összevetése** dönt: egyezik → **D** (belföld); eltér → kimenőnél **E** (export), bejövőnél **I** (import). (Korábban: HU ↔ nem-HU.) | A `Customer.CountryId` → ISO-feloldás kimenőnél még TODO (#7) → addig a vevő HU, ezért a kimenő ténylegesen D marad. |
| 2 | Célhely / telephely | ✅ **Megoldva:** configból (`Ekaer:Company` + `Site` al-szekció) → `IEkaerSettings.Company` + `EkaerCompanyInfo.Site` (`LocationType`, fel-/lerakodás). Nincs hardcode. | Több telephely (mint a `PartnerDepot`) — későbbi, ha kell. |
| 3 | Érték (`value`, HUF) | ✅ **Megoldva:** `UnitPriceOnDocument × QuantityOnDocument × árfolyam` (`EkaerValueCalculator`). Pénznem a `Partner.Currency`-ből; EUR-HUF árfolyam configból (`Ekaer:ExchangeRate:EurHuf`, MNB középárfolyam). | Árfolyam dinamizálása (jelenleg „drót" config-érték) — későbbi. |
| 4 | Tömeg (`weight`) | `ShippingItem.MeasuredGrossWeight` (bruttó). | Az EKÁER **bruttó** tömeget vár — megerősíteni, hogy ez bruttó és nem nettó. |
| 5 | Granularitás | 1 `ShippingDocument` → 1 `tradeCard`; 1 `Shipping` → több művelet (több dokumentum). | Megerősíteni: tényleg dokumentumonként egy tradeCard? |
| 6 | Eladó (`seller*`) mezők | `ShippingDocument.Partner`-ből: `Name`, `TaxId` (első 8 jegy = adószám-törzs), `CountryCode`, `City`, `Street`, `PostalCode`. | A `Partner` (`PartnerBase`) pontos mezőnevei/forrásai — megerősíteni. |
| 7 | Kimenő irány (`Order` → EKÁER) | ✅ **Implementálva** (`ToConsignment(OrderDto)`): mi=eladó, vevő=címzett; tömeg `OrderItemDto.GrossWeight`, érték nettó (UnitPriceExclTax × qty), jelenleg minden HUF (rate 1). **`carrierText` kimenőnél NEM töltve** (üres) — a vevő maga viszi el, ő már a címzett; a carrierText opcionális (2026-06). | **Nyitott:** a vonó jármű (**rendszám**) forrása — a `Customer`-hez még nincs bekötve (üres → warning, a felrakodás megkezdéséig pótolandó). Külföldi deviza + `Customer.CountryId` ISO-feloldás (export `E`): későbbi. |
| 8 | `productVtsz` forrás | `ProductDto.Gtin` (átmeneti). | GTIN ≠ VTSZ — lásd [`MGFBANKPLUG-EKAER-I-T3X8`](EKAER_ISSUES.md); hosszú távon külön `Vtsz` mező. A VTSZ-**csoportosítás** + `productName` **külön** kérdés: **T-V9G3**. |
| 9 | tétel `tradeReason` | `A` (beszerzés) — a mapper ezt használja bejövő árura. | Korábban tévesen `S`-nek feltételezve; az enum valójában `S`=értékesítés, `A`=beszerzés. Üzletileg megerősítendő. |
| 10 | `value` mező | ✅ **Megoldva:** a value most töltve (lásd #3); 0 / ismeretlen ár esetén `null` marad. | A NAV 2021-től `value > 0`-t vár — a validátorban a `value > 0` üzleti szabály még hozzáadandó. |
**Affected:**
- `ShippingToEkaerMapper` (`FruitBank.Common/Services/Ekaer/`) — a leképezés
- `EkaerTradeCardValidator` / `EkaerSubmitService` / `EkaerManageService` (`AyCode.Services/Nav/Ekaer/`) — validáció + beküldés + HTTP (általános NAV-réteg)
- `FruitBankEkaerService` (`FruitBank.Common.Server/Services/Ekaer/`) — a szerver-oldali fogyasztó (map → submit)
- Forrás-entitások (`FruitBank.Common`): `Shipping`, `ShippingDocument`, `ShippingItem`, `ProductDto.Gtin`
## MGFBANKPLUG-EKAER-T-W3R8: EKÁER küszöb-kategória a terméknél (enum, DB-ben tárolva)
**Status:** Open · **Priority:** P2 · **Type:** T (adatmodell + mapping)
Az EKÁER bejelentés-kötelezettség küszöbe **termékfüggő** — a VTSZ kockázati besorolása dönti el, melyik értékhatár vonatkozik rá:
| Kategória | Tömeg | Érték (nettó) |
|---|---|---|
| Kockázatos élelmiszer | 200 kg | 250 000 Ft |
| Kockázatos egyéb (nem élelmiszer) | 500 kg | 1 000 000 Ft |
| Nem kockázatos | 2500 kg | 5 000 000 Ft |
> **A fenti értékek a 13/2020. (XII. 23.) PM rendelet kategóriái — REFERENCIA, 2026-06 állapot.** Az alkalmazott küszöb a kódba **NINCS drótozva** (`appsettings` → `Ekaer:Thresholds`), és a jogszabály/beállítás változásával módosul; ezt a táblát csak tájékoztatásul, **dátumozva** tartjuk.
>
> ⚠️ **A túljelentés is bírság** (megerősítve, 2026-06): a globális „legszigorúbb" küszöb egy **nem-élelmiszer** terméket (ami csak a magasabb határnál kötelező) **túljelentene**. Fruit-importőrnél (minden áru kockázatos élelmiszer) ez nem gond — de amint nem-élelmiszer is bekerül, ez a per-termék kategória **szükségessé** válik (nem csak P2).
**Jelenlegi (átmeneti):** a `CreateMissingEkaerHistories` egyetlen, globális küszöböt használ az `EkaerSettings`-ből — **configból** (`Ekaer:Thresholds`), a kódba **NEM drótozva**. Jelenleg a **kockázatos-élelmiszer** határ van beállítva (a fruit-importőr profil miatt, a legszigorúbb a beszerzéseknél). A kapu a küszöböt `(Shipping, Partner)`-re **aggregálva** nézi, külföldinél küszöb nélkül kötelez (lásd README → kapu-szakasz).
**Cél:** a **terméknél (Product) kézzel megadható** küszöb-**KATEGÓRIA** (nem a konkrét érték!) — egy **enum** (pl. `EkaerThresholdCategory { RiskyFood, RiskyOther, NonRisky }`) —, **DB-ben tárolva** (Product oszlop / GenericAttribute). A konkrét kg/Ft értékeket a **kód** rendeli a kategóriához → értékhatár-változáskor egy helyen módosul. A küszöb-kapu dokumentumonként a tételek kategóriái szerint alkalmazza a megfelelő határt. (Későbbi lépés: a kategória automatikus levezetése a NAV kockázatos-VTSZ-listákból.)
**Affected:**
- `FruitBank.Common/Dtos/ProductDto.cs` — küszöb-kategória mező (enum, DB-ben)
- `EkaerSettings` / `EkaerValueCalculator` (`FruitBank.Common/Services/Ekaer/`) — kategória → küszöbérték leképezés
- `FruitBankDataController.CreateMissingEkaerHistories` — a kapu a tételek kategóriái szerint
## MGFBANKPLUG-EKAER-T-V9G3: tradeCardItem-ek csoportosítása VTSZ szerint + `productName` Category-ből
**Status:** Open · **Priority:** P2 · **Type:** T (mapping) · **2026-06**
A NAV felé **egy VTSZ-re egy `tradeCardItem`** kell — több azonos-VTSZ-ű termék (pl. kajszibarack/nektarin/őszibarack, mind `08093000`) **egy** tételbe vonva, **összegzett** tömeggel/értékkel. Jelenleg a mapper terméktételenként ad egy `tradeCardItem`-et → azonos VTSZ-nél több sor (a NAV felé nem jó). A nehézség a **`productName`** (a csoport tagjainak más a neve).
> **Ez NEM a VTSZ/GTIN-szétválasztás** — az **külön** nyitott kérdés: [`MGFBANKPLUG-EKAER-I-T3X8`](EKAER_ISSUES.md) (lásd #8). A T-V9G3 **csak a csoportosítást és a csoport-nevet** oldja meg, a VTSZ tárolási helyétől (jelenleg `Product.Gtin`) **függetlenül**.
**Eldöntött terv (2026-06):**
- **`productName` (a csoport neve):** egy nopCommerce **`Category`**-ből, ami VTSZ→név **helper**: a `Category.MetaKeywords` első 8 karaktere = a VTSZ, a `Category.Name` = a `productName`. A kategóriát a **termék VTSZ-e** (jelenleg a `Gtin`-ben — I-T3X8) **= `MetaKeywords`[0..8]** match azonosítja → a termék kategória-**tagsága lényegtelen** (több kategóriából csak az egyező számít). A kategóriák a weben is pontosak maradnak.
- **`itemExternalId`:** **sorszám** (1, 2, …) a VTSZ-csoportok fölött — a séma szerint „bejelentésen belüli **tetszőleges** azonosító a **kérés↔válasz** párosításhoz" (max 50), NEM kell stabilnak / forrás-Id-nek lennie; int-parse-olható.
- **Csoportosítás helye:** `BuildTradeCard` (VTSZ szerint group → Σtömeg, Σérték, név a lookupból). A **kapu** (`EvaluateObligation`) NEM érintett (csak Σ-t számol → nincs plusz query a reconciliation-nél).
- **Név-feloldás:** **csak generáláskor**, szerver-oldalon — a `ProductDto`-t NEM szennyezzük EKÁER-only mezővel. A termék-query `(productId, categoryId)` tuple-t ad (a VTSZ↔`MetaKeywords` joinból), majd egy batch `Category`-load `ToDictionary`-be → `productId → categoryName`.
- **Fallback:** ha egy VTSZ-hez nincs kategória → a `productName` üres marad → a **generate-validátor** jelzi (mint a `value > 0`).
**Üzemeltetési feltétel:** a VTSZ-forrás (jelenleg `Gtin`) és a kategória `MetaKeywords`-VTSZ-e legyen **szinkronban** (FruitBank-felelősség; a beírásnál a VTSZ-t elöl).
**Affected:**
- `FruitBank.Common/Services/Ekaer/ShippingToEkaerMapper.cs``BuildTradeCard` VTSZ-group + `vtszNames` lookup
- `FruitBank.Common.Server/Services/Ekaer/{IFruitBankEkaerService,FruitBankEkaerService}.cs` — a `vtszNames` átadása a generate-en
- `FruitBankDataController.GenerateEkaerXmlDocument` (plugin) — `(productId, categoryId)` tuple + batch `Category`-load → `Dictionary<vtsz, name>`
- nopCommerce `Category` (MetaKeywords = VTSZ, Name = productName) — adat/üzemeltetés
## MGFBANKPLUG-EKAER-T-D8R4: Kapu-csoportosítás (Shipping, PartnerDepot)-re; a PartnerDepotId kötelező
**Status:** Open · **Priority:** P2 · **Type:** T (kapu) · **2026-06**
A `CreateMissingEkaerHistories` bejövő kapuja jelenleg `(ShippingId, PartnerId, PartnerDepotId)`-re csoportosít. Mivel a **`PartnerDepot` egyértelműen egy `Partner`-hez tartozik** (a depó implikálja a feladót), a `PartnerId` a kulcsban **redundáns** → elég a `(ShippingId, PartnerDepotId)` csoportosítás.
**Cél:**
- A csoportosítási kulcs `(ShippingId, PartnerDepotId)` (a `PartnerId` kivehető).
- A **`PartnerDepotId` kötelező** az EKÁER-hez: ha egy szállítólevélen **nincs** `PartnerDepotId`**hiba**, és **NE generálódjon** rá deklaráció. A kapu a hiányzó-telephelyű dokumentumokat kihagyja + üzenettel jelzi (mint a `DataError`-nál); a generate `ValidationError`-t ad (nem küldhető), nem üres/téves tradeCard-ot.
**Megj.:** szigorítás a jelenlegihez képest, ahol a `null` `PartnerDepotId` még külön (null-telephelyű) csoportként kezelődik. Bevezetés előtt a meglévő szállítólevelek `PartnerDepotId`-ját pótolni kell, különben a kapu kihagyja őket.
**Affected:**
- `FruitBankDataController.CreateMissingEkaerHistories` (plugin) — a `GroupBy` kulcs `(ShippingId, PartnerDepotId)`-re + a hiányzó-`PartnerDepotId` hiba-ág (kihagyás + üzenet)
- `FruitBankDataController.GenerateEkaerXmlDocument` / `FruitBankEkaerService` — hiányzó telephelynél `ValidationError`, nincs generálás
- `ShippingToEkaerMapper` / `EkaerReportability` (`FruitBank.Common/Services/Ekaer/`) — ha a feladó-cím a `PartnerDepot`-ból jön, a hiányzó telephely validációs hiba