FruitBankHybridApp/docs/adr/0001-non-measurable-item-de...

48 lines
4.6 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.

# 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`.