Mango.Nop.Plugins/Nop.Plugin.Misc.AIPlugin/docs/DOMAIN_MODEL.md

5.0 KiB

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.