40 lines
2.7 KiB
Markdown
40 lines
2.7 KiB
Markdown
# FruitBank.Common Domain Rules & Glossary
|
||
|
||
> This file acts as the single source of truth for the core Measurement System and Common Traps shared across all FruitBank applications (Hybrid App, Blazor, and nopCommerce server plugin).
|
||
|
||
## Measurement System
|
||
|
||
| Term | Definition |
|
||
|---|---|
|
||
| **IsMeasurable** | Product-level flag. If `false`: weights = 0.0, only `TrayQuantity` matters. A Pallet record is still created. |
|
||
| **NetWeight** | `GrossWeight − PalletWeight − (TrayQuantity × TareWeight)` — universal formula across all three hierarchies. |
|
||
| **TrayQuantity** | Always recorded, regardless of measurability. Count of trays/crates. |
|
||
| **GrossWeight** | Total weight including pallet and packaging. 0.0 if not measurable. |
|
||
| **PalletWeight** | Weight of the physical pallet. 0.0 if goods arrive without one. |
|
||
| **TareWeight** | Weight of a single tray/crate. Used in NetWeight calculation. |
|
||
| **AverageWeight** | Per-pallet average: `NetWeight / TrayQuantity`. Validated against threshold. |
|
||
| **MeasuringStatus** | NotStarted(0) → Started(10) → **Finnished**(20) → Audited(30). Note: "Finnished" is intentional. |
|
||
| **RevisorId** | Quality auditor's Customer ID. OrderItemPallet becomes "Audited" when RevisorId > 0. |
|
||
|
||
## Three Measurement Hierarchies
|
||
|
||
All share `MeasuringItemPalletBase` with the same NetWeight formula:
|
||
|
||
| Flow | Parent | Pallet Record | Extra |
|
||
|--------------|-----------------|-------------------------|---------------------------------------|
|
||
| **Inbound** | ShippingItem | ShippingItemPallet | Declared vs measured discrepancy |
|
||
| **Outbound** | OrderItemDto | OrderItemPallet | RevisorId for audit |
|
||
| **Inventory**| StockTakingItem | StockTakingItemPallet | QuantityDiff for stock adjustment |
|
||
|
||
## Common Traps
|
||
|
||
| Trap | Correct Behavior |
|
||
|---|---|
|
||
| "Pallet" = physical pallet | ❌ It's a measurement record. Always created. |
|
||
| Shipping = outgoing | ❌ Shipping = INBOUND. Order = OUTBOUND. |
|
||
| Fix "Finnished" spelling | ❌ Intentional legacy typo. Do NOT fix. |
|
||
| IsMeasurable=false means no Pallet | ❌ Pallet is always created, weights just = 0.0 |
|
||
| NetWeight is stored/settable | ❌ It is calculated. The setter throws an Exception! It only exists to satisfy the `IMeasuringItemPalletBase` interface boundary. Set `GrossWeight`, `PalletWeight`, `TareWeight` instead. |
|
||
| Setting MeasuringStatus | ❌ It's a calculated property (evaluates `IsMeasured`, `Id`, or child pallets). Do not try to set it. |
|
||
| Setting ForeignKey | ❌ `ForeignKey` is read-only. Use `SetForeignKey(id)` method instead. |
|
||
| GenericAttribute is simple | ❌ It's polymorphic: KeyGroup determines which entity type owns the record | |