# Nop.Plugin.Misc.AIPlugin (FruitBank nopCommerce Plugin) @project { type = "nopcommerce-plugin" own-dep-projects = [ "Mango.Nop.Core, Mango.Nop.Services (in NopCommerce.Common/4.70/Libraries)" ] } > For Mango.Nop library docs see `NopCommerce.Common/4.70/Libraries/README.md` > For FruitBankHybridApp domain rules see the FruitBankHybridApp solution's `.github/copilot-instructions.md` > For core measurement system rules and common domain traps, see: `../../../../FruitBankHybridApp/FruitBank.Common/docs/GLOSSARY.md` Server-side nopCommerce plugin for FruitBank, a fruit and vegetable wholesaler. Manages supplier inbound delivery (receiving), warehouse weighing (net/gross/pallet/tare weights), outbound order measurement, inventory stocktaking, AI services, and Billingo invoicing. Runs inside nopCommerce 4.80.9 (**net9.0**). Project file: `Nop.Plugin.Misc.FruitBankPlugin.csproj` ## Documentation | Document | Topic | |---|---| | `docs/SCHEMA.md` | Authoritative domain model in TOON format — all entities, DTOs, enums, relationships | | `docs/DOMAIN_MODEL.md` | Behavioral docs: weight formula, MeasuringStatus lifecycle, GenericAttribute keys, entity hierarchy overview | | `docs/MEASUREMENT.md` | Three measurement workflows (inbound shipping, outbound order, stocktaking), MeasuringStatus lifecycle, pricing, checkout filter | | `docs/AI_SERVICES.md` | OpenAI, Cerebras, Replicate providers, FruitBankSettings, file storage, PDF conversion, audio transcription | | `docs/DATA_LAYER.md` | FruitBankDbContext, StockTakingDbContext, DbTable repositories, entity mapping, FruitBankEventConsumer | | `docs/SIGNALR/README.md` | SignalR endpoints, FruitBankDataController, InnVoice/Billingo integration, FruitBankAttributeService | ## Folder Structure | Folder | Purpose | |---|---| | `Areas/Admin/Controllers/` | Admin MVC controllers — order, product, shipping, SignalR endpoints, file management | | `Areas/Admin/Components/` | Admin ViewComponents — DevExtreme grids | | `Areas/Admin/Models/` | Admin view models | | `Areas/Admin/Views/` | Admin Razor views | | `Components/` | Public-side ViewComponents | | `Controllers/` | Public-side controllers — `FruitBankDataController`, `CheckoutController` | | `Domains/DataLayer/` | DbContexts, DbTable repositories, interfaces | | `Domains/EventConsumers/` | nopCommerce entity event handlers | | `Factories/` | Model factories (order, product, shipping) | | `Filters/` | `PendingMeasurementCheckoutFilter` | | `Infrastructure/` | `PluginNopStartup` (DI), `RouteProvider`, `ViewLocationExpander` | | `Mapping/` | EF Core entity mapping, `PluginBuilder` | | `Migrations/` | FluentMigrator database schema | | `Models/` | Shared models — AI chat, MgBase extensions, order/product models | | `Services/` | Business logic — AI, measurement, file storage, invoicing, locking | ## Dependencies - `Mango.Nop.Core`, `Mango.Nop.Services` (ProjectReferences via `../../Libraries/`) - `Nop.Services`, `Nop.Web` (nopCommerce ProjectReferences) - AyCode.Core solution assemblies (DLL HintPaths in .csproj) - DevExpress ASP.NET Core 25.1.3, DevExtreme 25.1.3 - SignalR, EF Core 9.0, PdfPig, PDFtoImage ## 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`, `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`).