117 lines
5.0 KiB
Markdown
117 lines
5.0 KiB
Markdown
# Domain Model — Behavioral Documentation
|
|
|
|
> Part of `Nop.Plugin.Misc.FruitBankPlugin`. See `README.md` for project overview.
|
|
> For entity definitions, properties, and relationships see `docs/SCHEMA.md` (authoritative TOON schema).
|
|
> For measurement workflows see `docs/MEASUREMENT.md`.
|
|
> For data layer details see `docs/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 `TrayQuantity` is 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.
|