5.0 KiB
Domain Model — Behavioral Documentation
Part of
Nop.Plugin.Misc.FruitBankPlugin. SeeREADME.mdfor project overview. For entity definitions, properties, and relationships seedocs/SCHEMA.md(authoritative TOON schema). For measurement workflows seedocs/MEASUREMENT.md. For data layer details seedocs/DATA_LAYER.md. For core measurement system rules and common domain traps, see:../../../../../FruitBankHybridApp/FruitBank.Common/docs/GLOSSARY.md
This document explains how the domain model behaves in the plugin. For what the entities are (properties, types, relationships), see docs/SCHEMA.md.
Weight Formula
All three pallet types (ShippingItemPallet, OrderItemPallet, StockTakingItemPallet) use the same formula:
NetWeight = GrossWeight - PalletWeight - (TrayQuantity * TareWeight)
| Field | Meaning |
|---|---|
GrossWeight |
Scale reading (total weight). 0.0 if product is not measurable |
PalletWeight |
Weight of the physical pallet. 0.0 if goods arrive without pallet |
TareWeight |
Weight of one tray/crate (per unit) |
TrayQuantity |
Number of trays/crates. Always recorded, even for non-measurable products |
NetWeight |
Computed, read-only, not-mapped (setter exists for shared interface but throws Exception) |
MeasuringStatus Lifecycle
NotStarted (0) → Started (10) → Finnished (20) → Audited (30)
[no record] [record created] [IsMeasured=true] [RevisorId > 0]
- NotStarted: No pallet record exists yet
- Started: Pallet record created (Id > 0) but
IsMeasured = false - Finnished:
IsMeasured = true— weights recorded - Audited:
RevisorId > 0— quality auditor confirmed (OrderItemPallet only)
IsMeasurable Flag
ProductDto.IsMeasurable is the master toggle (stored as GenericAttribute). When false:
- Weight validation is bypassed
- One pallet record is still created with
GrossWeight = 0.0 - Only
TrayQuantityis recorded - Product is not included in average weight checks
GenericAttribute Keys
Custom product/order properties are stored via nopCommerce's GenericAttribute table. The DTO classes expose these as computed, not-mapped properties.
Product attributes (saved by FruitBankEventConsumer)
| Key | Type | Purpose |
|---|---|---|
IsMeasurable |
bool | Master flag for weight validation |
NetWeight |
double | Product net weight |
Tare |
double | Tare weight per tray |
AverageWeight |
double | Expected average weight per tray |
AverageWeightTreshold |
double | Max allowed deviation % from AverageWeight |
IncomingQuantity |
int | Incoming stock not yet received |
Order attributes
| Key | Type | Purpose |
|---|---|---|
DateOfReceipt |
DateTime | Scheduled delivery date |
MeasurementOwnerId |
int | User who started measuring |
RevisorId |
int | Quality auditor user ID |
Entity Hierarchy Overview
Inbound Delivery (Shipping)
Shipping (fbShipping) ← truck arrival
└─ ShippingDocument (fbShippingDocument) ← supplier delivery note [1:N]
├─ ShippingItem (fbShippingItem) ← product line [1:N]
│ └─ ShippingItemPallet ← measurement event [1:N]
├─ ShippingDocumentToFiles ← uploaded PDFs [1:N]
│ └─ Files (fbFiles) [N:1]
└─ Partner (fbPartner) ← supplier [N:1]
Outbound Order
OrderDto (Order) ← nopCommerce order
├─ OrderItemDto (OrderItem) ← line item [1:N]
│ ├─ OrderItemPallet (fbOrderItemPallet) ← measurement record [1:N]
│ └─ ProductDto (Product) [N:1]
├─ Customer [N:1]
└─ GenericAttributeDto ← custom attributes [1:N]
Inventory (StockTaking)
StockTaking (fbStockTaking) ← inventory session
└─ StockTakingItem (fbStockTakingItem) ← product line [1:N]
├─ StockTakingItemPallet ← measurement record [1:N]
└─ ProductDto (Product) [N:1]
FullProcessModel
Container for bulk data sync between server and FruitBankHybridApp via SignalR:
| Property | Type | Purpose |
|---|---|---|
Orders |
List<OrderDto> |
All active orders with full graph |
Shippings |
List<Shipping> |
All active shipments with full graph |
StockTakings |
List<StockTaking> |
All active inventory sessions |
Note on "Pallet" Naming
The term "Pallet" in OrderItemPallet, ShippingItemPallet, and StockTakingItemPallet is a legacy naming convention. These are general measurement records that are always created for every item, regardless of whether goods arrive on a physical pallet. For non-measurable products, weight fields are 0.0 and only TrayQuantity is tracked.