113 lines
7.2 KiB
Markdown
113 lines
7.2 KiB
Markdown
# Measurement Workflows
|
||
|
||
> Part of `Nop.Plugin.Misc.FruitBankPlugin`. See `README.md` for project overview.
|
||
> For entity model see `docs/DOMAIN_MODEL.md`.
|
||
> For SignalR endpoints see `docs/SIGNALR/README.md`.
|
||
> For core measurement system rules and common domain traps, see: `../../../../../FruitBankHybridApp/FruitBank.Common/docs/GLOSSARY.md`
|
||
|
||
Three parallel measurement workflows share the same weight formula and `MeasuringStatus` lifecycle.
|
||
|
||
## Shared concepts (canonical in DOMAIN_MODEL.md)
|
||
|
||
These are defined once in [`DOMAIN_MODEL.md`](DOMAIN_MODEL.md) — referenced here, not duplicated:
|
||
|
||
- **Weight formula** — `NetWeight = GrossWeight − PalletWeight − (TrayQuantity × TareWeight)`. See [DOMAIN_MODEL.md § Weight Formula](DOMAIN_MODEL.md#weight-formula) for field meanings and edge cases.
|
||
- **MeasuringStatus lifecycle** — `NotStarted (0) → Started (10) → Finnished (20) → Audited (30)`. See [DOMAIN_MODEL.md § MeasuringStatus Lifecycle](DOMAIN_MODEL.md#measuringstatus-lifecycle) for state transitions. Note: `Finnished` is an intentional double-n typo — do not "fix" it.
|
||
- **IsMeasurable Flag** — `ProductDto.IsMeasurable` master toggle for weight validation. See [DOMAIN_MODEL.md § IsMeasurable Flag](DOMAIN_MODEL.md#ismeasurable-flag) for `false`-branch semantics.
|
||
|
||
## Workflow 1: Inbound Shipping
|
||
|
||
Supplier truck arrives at the warehouse. Goods are weighed and compared to the delivery document.
|
||
|
||
```
|
||
Shipping (truck)
|
||
→ ShippingDocument (supplier delivery note)
|
||
→ ShippingItem (product line)
|
||
→ ShippingItemPallet (individual measurement)
|
||
```
|
||
|
||
### Flow
|
||
|
||
1. **Create Shipping** — truck registration (LicencePlate, ShippingDate, CargoCompany)
|
||
2. **Add ShippingDocument** — link to Partner (supplier), upload PDF delivery note
|
||
3. **Add ShippingItem** — product line from document. `IsMeasurable` copied from `ProductDto.IsMeasurable`
|
||
4. **Weigh pallets** — `FruitBankDataController.AddOrUpdateMeasuredShippingItemPallet()`
|
||
- Each pallet: GrossWeight, PalletWeight, TareWeight, TrayQuantity → NetWeight (formula in Shared concepts above)
|
||
5. **Cascade update** — after each pallet measurement:
|
||
- `ShippingItem`: MeasuredGrossWeight, MeasuredNetWeight, MeasuredQuantity recalculated from pallets
|
||
- `ShippingDocument.IsAllMeasured` = all items measured
|
||
- `Shipping.IsAllMeasured` = all documents measured
|
||
- Product `AverageWeight` updated from measured data
|
||
|
||
### Event Cascade (FruitBankEventConsumer)
|
||
|
||
```
|
||
ShippingItemPallet deleted → ShippingItem measuring values refreshed
|
||
ShippingItem inserted/updated → ShippingDocument.IsAllMeasured rechecked
|
||
ShippingDocument inserted/updated → Shipping.IsAllMeasured rechecked
|
||
Shipping deleted → cascade delete ShippingDocuments
|
||
ShippingDocument deleted → cascade delete ShippingItems
|
||
ShippingItem deleted → cascade delete ShippingItemPallets
|
||
```
|
||
|
||
### ShippingItem: Declared vs Measured
|
||
|
||
| Declared (from document) | Measured (warehouse) | Discrepancy tracked |
|
||
|---|---|---|
|
||
| `QuantityOnDocument` | `MeasuredQuantity` | Yes |
|
||
| `GrossWeightOnDocument` | `MeasuredGrossWeight` | Yes |
|
||
| `NetWeightOnDocument` | `MeasuredNetWeight` | Yes |
|
||
|
||
## Workflow 2: Outbound Order
|
||
|
||
Customer order is prepared. Items are weighed before dispatch.
|
||
|
||
```
|
||
OrderDto (order)
|
||
→ OrderItemDto (line item)
|
||
→ OrderItemPallet (measurement record)
|
||
```
|
||
|
||
### Flow
|
||
|
||
1. **Start Measuring** — `CustomOrderSignalREndpoint.StartMeasuring(orderId, userId)`
|
||
- Sets `MeasurementOwnerId` via GenericAttribute
|
||
- Order status set to Processing, Payment to Pending
|
||
- Broadcasts `SendOrderChanged`
|
||
2. **Weigh pallets** — `CustomOrderSignalREndpoint.AddOrUpdateMeasuredOrderItemPallet()`
|
||
- Same weight formula as shipping
|
||
- Triggers price recalculation after each pallet
|
||
- Broadcasts `SendOrderItemPalletChanged`
|
||
3. **Complete order** — `CustomOrderSignalREndpoint.SetOrderStatusToComplete(orderId, revisorId)`
|
||
- Validates: all order items must have pallets
|
||
- Recalculates final prices v<>!I<><49>e<EFBFBD>vü<76>q |