From 2442094a08a74e386fd1f2ce8730ba0cf9ef51b7 Mon Sep 17 00:00:00 2001 From: Loretta Date: Sun, 31 May 2026 14:01:58 +0200 Subject: [PATCH] Add CargoPartner/CargoTruck relations and eager loading - Updated controllers and DbTables to support eager loading of CargoPartner and CargoTruck relations. - Enhanced Shipping and ShippingDocument queries to include related transport entities. - Extended SCHEMA.md with CargoPartner, CargoTruck, and updated Shipping schema details. --- .../Controllers/FruitBankDataController.cs | 6 +- .../Domains/DataLayer/CargoPartnerDbTable.cs | 6 +- .../Domains/DataLayer/ShippingDbTable.cs | 5 +- .../DataLayer/ShippingDocumentDbTable.cs | 3 + Nop.Plugin.Misc.AIPlugin/docs/SCHEMA.md | 64 +++++++++++++++++-- 5 files changed, 75 insertions(+), 9 deletions(-) diff --git a/Nop.Plugin.Misc.AIPlugin/Controllers/FruitBankDataController.cs b/Nop.Plugin.Misc.AIPlugin/Controllers/FruitBankDataController.cs index a847798..d7dcf78 100644 --- a/Nop.Plugin.Misc.AIPlugin/Controllers/FruitBankDataController.cs +++ b/Nop.Plugin.Misc.AIPlugin/Controllers/FruitBankDataController.cs @@ -142,14 +142,14 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers { _logger.Detail($"GetCargoPartners invoked"); - return await ctx.CargoPartners.GetAll().ToListAsync(); + return await ctx.CargoPartners.GetAll(true).ToListAsync(); } [SignalR(SignalRTags.GetCargoPartnerById)] public async Task GetCargoPartnerById(int id) { _logger.Detail($"GetCargoPartnerById invoked; id: {id}"); - return await ctx.CargoPartners.GetByIdAsync(id); + return await ctx.CargoPartners.GetByIdAsync(id, true); } [SignalR(SignalRTags.AddCargoPartner)] @@ -180,7 +180,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers { _logger.Detail($"GetCargoTrucks invoked"); - return await ctx.CargoTrucks.GetAll().ToListAsync(); + return await ctx.CargoTrucks.GetAll(true).ToListAsync(); } [SignalR(SignalRTags.GetCargoTruckById)] diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/CargoPartnerDbTable.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/CargoPartnerDbTable.cs index 88a9d93..e7343e6 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/CargoPartnerDbTable.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/CargoPartnerDbTable.cs @@ -19,7 +19,11 @@ public class CargoPartnerDbTable : MgDbTableBase public IQueryable GetAll(bool loadRelations) { - return loadRelations ? GetAll().LoadWith(sd => sd.CargoTrucks) : GetAll(); + return loadRelations ? + GetAll() + .LoadWith(sd => sd.CargoTrucks) + //.LoadWith(sd => sd.Shippings) + : GetAll(); } public Task GetByIdAsync(int id, bool loadRelations) => GetAll(loadRelations).FirstOrDefaultAsync(p => p.Id == id); diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDbTable.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDbTable.cs index 17f55e9..450de3e 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDbTable.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDbTable.cs @@ -23,11 +23,14 @@ public class ShippingDbTable : MgDbTableBase { return loadRelations ? GetAll() + .LoadWith(s => s.CargoPartner) + .LoadWith(s => s.CargoTruck) + .LoadWith(s => s.CargoTrailer) + .LoadWith(s => s.ShippingDocuments).ThenLoad(sd => sd.Partner) .LoadWith(s => s.ShippingDocuments).ThenLoad(sd => sd.ShippingItems).ThenLoad(si => si.ShippingItemPallets) .LoadWith(s => s.ShippingDocuments).ThenLoad(sd => sd.ShippingItems).ThenLoad(si => si.Pallet) .LoadWith(s => s.ShippingDocuments).ThenLoad(sd => sd.ShippingItems).ThenLoad(si => si.ProductDto).ThenLoad(prod => prod.GenericAttributes) .LoadWith(s => s.ShippingDocuments).ThenLoad(sd => sd.ShippingDocumentToFiles).ThenLoad(sdtof => sdtof.ShippingDocumentFile) - .LoadWith(s => s.ShippingDocuments).ThenLoad(sd => sd.Partner) : GetAll(); } diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDocumentDbTable.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDocumentDbTable.cs index c02f3b5..bef7f36 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDocumentDbTable.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDocumentDbTable.cs @@ -24,6 +24,9 @@ public class ShippingDocumentDbTable : MgDbTableBase return loadRelations ? GetAll() .LoadWith(sd => sd.Shipping) + .LoadWith(sd => sd.Shipping).ThenLoad(s => s.CargoPartner) + .LoadWith(sd => sd.Shipping).ThenLoad(s => s.CargoTruck) + .LoadWith(sd => sd.Shipping).ThenLoad(s => s.CargoTrailer) .LoadWith(sd => sd.ShippingItems).ThenLoad(si => si.Pallet) .LoadWith(sd => sd.ShippingItems).ThenLoad(si => si.ProductDto).ThenLoad(prod => prod.GenericAttributes) .LoadWith(sd => sd.ShippingItems).ThenLoad(si => si.ShippingItemPallets) diff --git a/Nop.Plugin.Misc.AIPlugin/docs/SCHEMA.md b/Nop.Plugin.Misc.AIPlugin/docs/SCHEMA.md index a856ccc..b663d9e 100644 --- a/Nop.Plugin.Misc.AIPlugin/docs/SCHEMA.md +++ b/Nop.Plugin.Misc.AIPlugin/docs/SCHEMA.md @@ -10,7 +10,7 @@ format = "toon" source-code-language = "C#" context = "This is a nopCommerce plugin developed for FruitBank, a fruit and vegetable wholesaler. The plugin manages supplier inbound delivery (receiving), warehouse weighing (net/gross/pallet/tare weights), and inventory stocktaking. The business logic is centered around FruitBank's requirement for precise physical measurement and quantity tracking." - types = ["OrderStatus", "ShippingStatus", "PaymentStatus", "GenericAttributeDto", "MeasuringStatus", "VatNumberStatus", "TaxDisplayType", "OrderNote", "PreOrderItemStatus", "PreOrderStatus", "DocumentType", "Files", "Pallet", "ProductDto", "Customer", "PreOrderItem", "PreOrder", "FullProcessModel", "OrderDto", "OrderItemDto", "OrderItemPallet", "Partner", "Shipping", "ShippingDocument", "ShippingDocumentToFiles", "ShippingItem", "ShippingItemPallet", "StockTaking", "StockTakingItem", "StockTakingItemPallet"] + types = ["OrderStatus", "ShippingStatus", "PaymentStatus", "GenericAttributeDto", "MeasuringStatus", "VatNumberStatus", "TaxDisplayType", "OrderNote", "PreOrderItemStatus", "PreOrderStatus", "DocumentType", "Files", "Pallet", "ProductDto", "Customer", "PreOrderItem", "PreOrder", "CargoPartner", "CargoTruck", "FullProcessModel", "OrderDto", "OrderItemDto", "OrderItemPallet", "Partner", "Shipping", "ShippingDocument", "ShippingDocumentToFiles", "ShippingItem", "ShippingItemPallet", "StockTaking", "StockTakingItem", "StockTakingItemPallet"] } @types { @@ -305,6 +305,50 @@ purpose: "Primary key / unique identification" primary-key: true + CargoPartner: "Transport / haulage company (carrier) with its vehicle fleet" + table-name: "fbCargoPartner" + purpose: "A carrier that delivers goods to the warehouse and owns the CargoTrucks (both trucks and trailers). Distinct from Partner, which is the goods supplier. Name, address and tax fields are inherited from PartnerBase." + CargoTrucks: List + other-key: "CargoPartnerId" + navigation: "one-to-many" + inverse-property: "CargoPartner" + CertificationNumber: string + City: string + Country: string + CountryCode: string + County: string + Created: DateTime + Modified: DateTime + Name: string + PostalCode: string + State: string + Street: string + TaxId: string + Id: int + purpose: "Primary key / unique identification" + primary-key: true + + CargoTruck: "Cargo vehicle — truck or trailer — owned by a transport partner" + table-name: "fbCargoTruck" + purpose: "A single vehicle in a transport company's fleet. One table holds both tractor units and trailers, distinguished by IsTrailer. Truck and trailer are tracked as separate vehicles because Hungarian EKÁER road-freight reporting (NAV) declares the towing vehicle and the trailer as distinct entries (vehicle / vehicle2), each with its own licence plate and country code — i.e. these shipments carry an EKÁER declaration obligation." + CargoPartner: CargoPartner + foreign-key: "CargoPartnerId" + navigation: "many-to-one" + inverse-property: "CargoTrucks" + CargoPartnerId: int + purpose: "FK to the owning transport company (CargoPartner) — the carrier, not the goods supplier." + CargoPartnerName: string + constraints: "readonly, not-mapped" + CountryCode: string + Created: DateTime + IsTrailer: bool + purpose: "Discriminates the shared table: false = tractor/truck unit, true = trailer." + LicencePlate: string + Modified: DateTime + Id: int + purpose: "Primary key / unique identification" + primary-key: true + FullProcessModel: "Object of type FullProcessModel" table-name: "FullProcessModel" purpose: "Container model for Shipping, Order" @@ -489,9 +533,6 @@ purpose: "Measured gross weight; 0.0 if product is not measurable" IsMeasured: bool purpose: "Status flag" - MeasuringStatus: MeasuringStatus - business-logic: "get => IsMeasured ? MeasuringStatus.Finnished : Id > 0 ? MeasuringStatus.Started : MeasuringStatus.NotStarted" - constraints: "readonly, not-mapped" Modified: DateTime ModifierId: int? NetWeight: double @@ -533,6 +574,21 @@ table-name: "fbShipping" purpose: "Represents a physical inbound delivery event (truck arrival) at the warehouse, tracking the vehicle and the overall measurement status of the shipment" CargoCompany: string + CargoPartner: CargoPartner + purpose: "The transport company (carrier) that hauled this delivery — distinct from the goods supplier, which is reached via ShippingDocument.Partner." + foreign-key: "CargoPartnerId" + navigation: "many-to-one" + CargoPartnerId: int + CargoTrailer: CargoTruck + purpose: "The trailer — the SAME CargoTruck table as CargoTruck, but the row with IsTrailer=true (CargoTrailerId → CargoTruck.Id)." + foreign-key: "CargoTrailerId" + navigation: "many-to-one" + CargoTrailerId: int + CargoTruck: CargoTruck + purpose: "The tractor/truck unit — a CargoTruck row with IsTrailer=false." + foreign-key: "CargoTruckId" + navigation: "many-to-one" + CargoTruckId: int Comment: string Created: DateTime IsAllMeasured: bool