48 lines
4.6 KiB
Markdown
48 lines
4.6 KiB
Markdown
# ADR 0001: Nem mérendő tétel súlya — derivált pallet-mérés a termék átlagsúlyából és tárájából
|
||
|
||
## Status
|
||
|
||
Proposed (2026-07-14)
|
||
|
||
## Context
|
||
|
||
- **Kiváltó:** az EKÁER kimenő bejelentésnél a `tradeCard.weight` nem mérendő tételnél 0, mert a nem mérendő pallet súlyai 0-k (domain #4). A NAV pozitív bruttót vár → **alul-jelentés**.
|
||
- Az `OrderItemDto.GrossWeight` copy-paste bug (nettót summázott) 2026-07-ben javítva, de a valódi hiány marad: **nem mérendő tételnek nincs súlya sehol**.
|
||
- **Időzítés:** most, mert az EKÁER kimenő beküldés élesedik (sandbox-auth után), és éles kimenő bejelentés helytelen súllyal menne ki. A kolléga a per-termék rekesz-`AverageWeight` megadását épp készíti — az adat-oldal adott lesz.
|
||
- **Scope IN:** a mérési súly-modell nem mérendő tételre (`OrderItemPallet` + a közös `MeasuringItemPalletBase` validáció); a kimenő mérés UI (tára/rekesz). **Scope OUT:** a per-termék `AverageWeight` felvitel (kolléga); a bejövő/leltár ág konkrét migrációja (követő döntés).
|
||
|
||
## Decision
|
||
|
||
A nem mérendő tétel is **teljes értékű, perzisztált pallet-mérést** kap: a kimenő mérésnél a **rekeszszám** (megvan) + **tára** (a productból default, a textbox `Visible=true`) + opcionális raklap alapján a pallet súlyai kiszámolódnak és **beíródnak** a palletbe — `NetWeight = ProductDto.AverageWeight (rekeszenkénti nettó) × rekeszszám`, `GrossWeight = Net + rekesz×tára + raklap`. Az `IsMeasurable` jelentése ezzel **„a súly forrása"** (kézi mérés vs. termék-átlagból derivált), nem „van-e súly".
|
||
|
||
## Consequences
|
||
|
||
**Positive:**
|
||
- A kimenő EKÁER-súly nem mérendő tételnél is valós (nem 0) → NAV-megfelelőség.
|
||
- A pallet marad az **egyetlen igazságforrás** (audit): a súly fizikailag benne van, nem számított nézet.
|
||
- Az `IsValidMeasuringValues` `!isMeasurable`-ága **kivehető** → a sok `IsMeasurable`-elágazás egységesül (a súly-validáció alakja azonos mindkét ágon).
|
||
|
||
**Negative / kockázat (a három csapda):**
|
||
- **Közös bázis:** az `IsValidMeasuringValues(bool)` a `MeasuringItemPalletBase`-ben van → Shipping + StockTaking is hívja. `StockTakingDbContext:151` **dob** (`throw`), `FruitBankDbContext:245` gátol nem mérendő 0-súlyú palleten. A módosítás mindhárom hierarchiát érinti, nem csak az Order-ágat.
|
||
- **Visszamenőleges adat:** a régi, súly=0-s nem mérendő palletek egy egységesített szabály alatt „érvénytelenné" válnak → `SetOrderDtoToComplete` (`FruitBankDbContext:525`) + a „kész" színezés/összegzők visszaesnek a régi rendeléseknél.
|
||
- **Gomb-időzítés:** a mentés-gomb a memóriabeli palleten validál mentés ELŐTT (`PalletItemComponent:100`, `MeasuringIn.razor.cs:163`) → a derivált súlyt **élőben, kliens-oldalon** kell számolni (rekesz/tára beírásakor), nem mentéskor, különben a gomb sosem aktiválódik.
|
||
|
||
**Follow-ups required:**
|
||
- Kolléga: per-termék `AverageWeight` (rekeszenkénti nettó) felvitel.
|
||
- **Nyitott döntés:** mindhárom ág egységesítése vs. `OrderItemPallet`-override (Csapda 1) — lásd az A' alternatívát.
|
||
- **Migrációs stratégia** a régi 0-súlyú nem mérendő palletekre (Csapda 2).
|
||
- Kimenő mérés UI: tára-textbox `Visible=true` + élő súly-számítás (Csapda 3).
|
||
- Doksi: `FruitBank.Common/docs/GLOSSARY.md` + `OrderItemPallet` ToonDescription („weights = 0.0" invariáns → derivált súly), plugin `docs/MEASUREMENT.md`.
|
||
|
||
## Alternatives considered
|
||
|
||
- **B — Read-time deriváció** (elvetve): a súlyt ne perzisztáld, hanem az `OrderItemDto.GrossWeight`/`NetWeight` getterben deriváld (nem mérendő → `AvgWeight × rekesz`), a pallet marad 0.
|
||
- *Reversibility:* olcsóbb (2 getter, `IsMeasurable`-guard), **nincs migráció, egyik csapda sem nyílik ki**.
|
||
- *Cons:* a pallet NEM igazságforrás (számított nézet), nincs tára/raklap-bontás, nem „egységes" — ezért elvetve az egységesség-cél (single source of truth) miatt.
|
||
- **A' — Order-only override** (nyitott implementációs fork, nem elvetett): csak `OrderItemPallet.IsValidMeasuringValues` override-ol, a bázis marad → Csapda 1 elkerülve, de a nem mérendő szemantika ágakonként eltér (az „egységes" cél sérül). Az implementációkor eldöntendő A (teljes egységesítés) vs. A'.
|
||
|
||
## Related
|
||
|
||
- **Related TODOs/Issues:** `MGFBANKPLUG-EKAER` K7Q2 **#7** (kimenő irány — a kimenő súly `OrderItemDto.GrossWeight`); az `OrderItemDto.GrossWeight` bug-fix (2026-07, pre-flight — nettó→bruttó summázás).
|
||
- **Related docs:** plugin `docs/MEASUREMENT.md`, `docs/EKAER/README.md`, `FruitBank.Common/docs/GLOSSARY.md`.
|