[LOADED_DOCS: 3 files, no new loads]

Add type-location map and DRY measurement docs

Added a "Type-Location Map" to the plugin README for quick type lookup. Updated MEASUREMENT.md to reference canonical definitions in DOMAIN_MODEL.md for shared measurement logic, reducing duplication. Clarified pallet weighing workflow and fixed the client app doc path. Minor formatting and clarity improvements.
This commit is contained in:
Loretta 2026-04-28 06:51:57 +02:00
parent ccc3f18772
commit 23ce78abf3
3 changed files with 29 additions and 20 deletions

View File

@ -57,3 +57,25 @@ Project file: `Nop.Plugin.Misc.FruitBankPlugin.csproj`
## Initialization & Quirks
- **AcBinary Source Generator Registration**: NopCommerce plugins are loaded dynamically via `AssemblyLoadContext`, which prevents the .NET runtime from executing `[ModuleInitializer]` attributes. To ensure the high-performance binary serializers are registered (instead of falling back to slow reflection), `PluginNopStartup.ConfigureServices` must call `Mango.Nop.Core.AcBinaryForcedInit.ForceRegister()`.
## Type-Location Map
Quick lookup for "where does this type live?" — saves cross-repo grep rounds.
| Type / class family | Lives in | Path (relative or NuGet) |
|---|---|---|
| `Customer`, `Order`, `OrderItem`, `OrderNote`, `Product`, `GenericAttribute`, `CustomerRole` | nopCommerce framework | `Nop.Core` (ProjectRef) |
| `*Dto` classes (`OrderDto`, `OrderItemDto`, `ProductDto`, `GenericAttributeDto`, `StockQuantityHistoryDto`) | Mango.Nop.Core | `../../Libraries/Mango.Nop.Core/` |
| `MgDbContextBase`, `MgDbTableBase<T>`, `MgEventConsumerBase`, other `Mg*` base types | Mango.Nop.* libraries | `../../Libraries/Mango.Nop.{Core,Services,Data}/` |
| `Ac*` types (`AcBinaryHubProtocol`, `AcBinarySerializer`, `AcLoggerBase`, `AcBinaryForcedInit`) | AyCode.Core (DLL HintPath) | `../../../Aycode/Source/AyCode.Core/` |
| `fb*`-table entities: `Shipping`, `ShippingDocument`, `ShippingItem`, `ShippingItemPallet`, `OrderItemPallet`, `StockTaking`, `StockTakingItem`, `StockTakingItemPallet`, `Partner`, `Files`, `Pallet` | this plugin | `Domains/...` (full schema in `docs/SCHEMA.md`) |
| `FullProcessModel` (bulk SignalR sync container) | this plugin | `Models/` |
| `FruitBankDbContext`, `StockTakingDbContext`, `*DbTable` repositories (`OrderDtoDbTable`, `ShippingDbTable`, …), `I*DbSet` interfaces | this plugin | `Domains/DataLayer/` |
| `FruitBankEventConsumer`, `MeasurementService`, `CustomPriceCalculationService`, `FruitBankAttributeService` | this plugin | `Domains/EventConsumers/`, `Services/` |
| AI: `OpenAIApiService`, `CerebrasAPIService`, `ReplicateService`, `OpenAIService`, `AICalculationService` | this plugin | `Services/` |
| File / PDF / Audio: `FileStorageService`, `LocalStorageProvider`, `PdfToImageService`, `FruitBankAudioController` | this plugin | `Services/`, `Controllers/` |
| Billingo: `InnVoiceOrderService`, `InnvoiceApiService` (+ `InnVoiceOrderController`, `InnVoiceOrderSyncController`) | this plugin | `Services/`, `Areas/Admin/Controllers/` |
| SignalR: `FruitBankHub`, `CustomOrderSignalREndpoint`, `StockSignalREndpointServer`, `FruitBankDataController` | this plugin | `Services/`, `Areas/Admin/Controllers/`, `Controllers/` |
| Infra: `FruitBankSettings`, `PluginNopStartup`, `RouteProvider`, `ViewLocationExpander`, `PendingMeasurementCheckoutFilter` | this plugin | `Infrastructure/`, `Filters/` |
If a type isn't listed: grep `../../Libraries/` first → `../../../Aycode/Source/AyCode.Core/` next → otherwise it's a nopCommerce framework type (`Nop.Core`, `Nop.Services`, `Nop.Web`).

View File

@ -7,25 +7,13 @@
Three parallel measurement workflows share the same weight formula and `MeasuringStatus` lifecycle.
## MeasuringStatus Lifecycle
## Shared concepts (canonical in DOMAIN_MODEL.md)
```
NotStarted (0) → Started (10) → Finnished (20) → Audited (30)
[no record] [record created] [IsMeasured=true] [RevisorId > 0]
```
These are defined once in [`DOMAIN_MODEL.md`](DOMAIN_MODEL.md) — referenced here, not duplicated:
- **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 (for tare-weight calculations)
- Product is not included in average weight checks
- **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
@ -44,8 +32,7 @@ Shipping (truck)
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 computed: `GrossWeight - PalletWeight - (TrayQuantity * TareWeight)`
- 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

View File

@ -27,5 +27,5 @@ Per the AI Agent Core Protocol (folder navigation rule), start from this README
## See also
- **Parent framework** (Mango.Nop.Core): `../../../Libraries/Mango.Nop.Core/docs/README.md`
- **Client-side app**: `../../../../FruitBankHybridApp/docs/README.md`
- **Client-side app**: `../../../../../FruitBankHybridApp/docs/README.md`
- **Host (nopCommerce deployment)**: `../../../../../FruitBank/` (see `.github/copilot-instructions.md` for scope)