diff --git a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomOrderController.cs b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomOrderController.cs index 73682e3..df4306e 100644 --- a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomOrderController.cs +++ b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomOrderController.cs @@ -11,7 +11,7 @@ using Nop.Core.Domain.Shipping; using Nop.Core.Domain.Tax; using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; using Nop.Plugin.Misc.FruitBankPlugin.Factories; -using Nop.Plugin.Misc.FruitBankPlugin.Models; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; using Nop.Services.Common; using Nop.Services.Customers; using Nop.Services.Messages; @@ -132,7 +132,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers return RedirectToAction("List", "Order"); // store attributes in GenericAttribute table - await _genericAttributeService.SaveAttributeAsync(order, nameof(OrderModelExtended.IsMeasurable), model.IsMeasurable); + await _genericAttributeService.SaveAttributeAsync(order, nameof(IMeasurable.IsMeasurable), model.IsMeasurable); await _genericAttributeService.SaveAttributeAsync(order, nameof(IOrderDto.DateOfReceipt), model.DateOfReceipt); _notificationService.SuccessNotification("Custom attributes saved successfully."); diff --git a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomProductController.cs b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomProductController.cs index 1fc5d10..b98e41f 100644 --- a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomProductController.cs +++ b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Controllers/CustomProductController.cs @@ -13,6 +13,7 @@ using Nop.Core.Domain.Tax; using Nop.Core.Domain.Vendors; using Nop.Core.Http; using Nop.Core.Infrastructure; +using Nop.Plugin.Misc.FruitBankPlugin.Factories; using Nop.Services.Catalog; using Nop.Services.Common; using Nop.Services.Configuration; @@ -44,6 +45,7 @@ public partial class CustomProductController : BaseAdminController { #region Fields + private readonly CustomProductModelFactory _productModelFactory; protected readonly AdminAreaSettings _adminAreaSettings; protected readonly IAclService _aclService; protected readonly IBackInStockSubscriptionService _backInStockSubscriptionService; @@ -70,7 +72,6 @@ public partial class CustomProductController : BaseAdminController protected readonly IProductAttributeFormatter _productAttributeFormatter; protected readonly IProductAttributeParser _productAttributeParser; protected readonly IProductAttributeService _productAttributeService; - protected readonly IProductModelFactory _productModelFactory; protected readonly IProductService _productService; protected readonly IProductTagService _productTagService; protected readonly ISettingService _settingService; @@ -159,7 +160,7 @@ public partial class CustomProductController : BaseAdminController _productAttributeFormatter = productAttributeFormatter; _productAttributeParser = productAttributeParser; _productAttributeService = productAttributeService; - _productModelFactory = productModelFactory; + _productModelFactory = productModelFactory as CustomProductModelFactory; _productService = productService; _productTagService = productTagService; _settingService = settingService; @@ -878,7 +879,6 @@ public partial class CustomProductController : BaseAdminController [CheckPermission(StandardPermission.Catalog.PRODUCTS_VIEW)] public virtual async Task List() { - //prepare model var model = await _productModelFactory.PrepareProductSearchModelAsync(new ProductSearchModel()); return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Product/List.cshtml", model); @@ -918,7 +918,7 @@ public partial class CustomProductController : BaseAdminController public virtual async Task ProductList(ProductSearchModel searchModel) { //prepare model - var model = await _productModelFactory.PrepareProductListModelAsync(searchModel); + var model = await _productModelFactory.PrepareProductListModelExtendedAsync(searchModel); return Json(model); } diff --git a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/Product/List.cshtml b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/Product/List.cshtml index cfa08e8..fd5fed1 100644 --- a/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/Product/List.cshtml +++ b/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/Product/List.cshtml @@ -1,466 +1,488 @@ @model ProductSearchModel @using Nop.Core.Domain.Catalog; +@using Nop.Plugin.Misc.FruitBankPlugin.Models.Products @{ - //page title - ViewBag.PageTitle = T("Admin.Catalog.Products").Text; - //active menu item (system name) - NopHtml.SetActiveMenuItemSystemName("Products"); + //page title + ViewBag.PageTitle = T("Admin.Catalog.Products").Text; + //active menu item (system name) + NopHtml.SetActiveMenuItemSystemName("Products"); } @{ - const string hideSearchBlockAttributeName = "ProductListPage.HideSearchBlock"; - var hideSearchBlock = await genericAttributeService.GetAttributeAsync(await workContext.GetCurrentCustomerAsync(), hideSearchBlockAttributeName); + const string hideSearchBlockAttributeName = "ProductListPage.HideSearchBlock"; + var hideSearchBlock = await genericAttributeService.GetAttributeAsync(await workContext.GetCurrentCustomerAsync(), hideSearchBlockAttributeName); } @if (Model.LicenseCheckModel.BlockPages != true) { -
-
-

- Fruitbank @T("Admin.Catalog.Products") -

-
- - - @T("Admin.Common.AddNew") - - - - @T("Admin.Catalog.Products.BulkEdit") - - -
- - - -
- @if (!Model.IsLoggedInAsVendor || Model.AllowVendorsToImportProducts) - { - //a vendor cannot import products - - } - - - @await Component.InvokeAsync(typeof(AdminWidgetViewComponent), new { widgetZone = AdminWidgetZones.ProductListButtons, additionalData = Model }) -
-
+ +
+

+ Fruitbank @T("Admin.Catalog.Products") +

+
+ + + @T("Admin.Common.AddNew") + + + + @T("Admin.Catalog.Products.BulkEdit") + + +
+ + +
-
+ + + + + + +
+ @if (!Model.IsLoggedInAsVendor || Model.AllowVendorsToImportProducts) + { + //a vendor cannot import products + + } + + + @await Component.InvokeAsync(typeof(AdminWidgetViewComponent), new { widgetZone = AdminWidgetZones.ProductListButtons, additionalData = Model }) + + -
-
- +
+
+
+
+ - - - -
-
-
-
-
- - + + + + + + + + + + } - @*import products form*@ - +@*import products form*@ + - @*export selected (XML). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@ -
- -
+@*export selected (XML). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@ +
+ +
- @*export selected (Excel). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@ -
- -
+@*export selected (Excel). We don't use GET approach because it's limited to 2K-4K chars and won't work for large number of entities*@ +
+ +
- + \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Components/OrderAttributesViewComponent.cs b/Nop.Plugin.Misc.AIPlugin/Components/OrderAttributesViewComponent.cs index 6cc2ddc..18733c2 100644 --- a/Nop.Plugin.Misc.AIPlugin/Components/OrderAttributesViewComponent.cs +++ b/Nop.Plugin.Misc.AIPlugin/Components/OrderAttributesViewComponent.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Mvc; using Nop.Core; using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Orders; -using Nop.Plugin.Misc.FruitBankPlugin.Models; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; using Nop.Plugin.Misc.FruitBankPlugin.Services; using Nop.Services.Common; using Nop.Web.Areas.Admin.Models.Catalog; @@ -37,7 +37,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Components if (model.OrderId > 0) { var orderPickupAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync(model.OrderId, nameof(IOrderDto.DateOfReceipt)); - var orderMeasurableAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync(model.OrderId, nameof(OrderModelExtended.IsMeasurable)); + var orderMeasurableAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync(model.OrderId, nameof(IMeasurable.IsMeasurable)); model.IsMeasurable = orderMeasurableAttributeValue; if(orderPickupAttributeValue.HasValue && orderPickupAttributeValue.Value != DateTime.MinValue) diff --git a/Nop.Plugin.Misc.AIPlugin/Components/ProductAttributesViewComponent.cs b/Nop.Plugin.Misc.AIPlugin/Components/ProductAttributesViewComponent.cs index 6425006..2373507 100644 --- a/Nop.Plugin.Misc.AIPlugin/Components/ProductAttributesViewComponent.cs +++ b/Nop.Plugin.Misc.AIPlugin/Components/ProductAttributesViewComponent.cs @@ -42,7 +42,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Components } model.Tare = await _fruitBankAttributeService.GetGenericAttributeValueAsync(model.ProductId, nameof(ITare.Tare)); - model.IncomingQuantity = await _fruitBankAttributeService.GetGenericAttributeValueAsync(model.ProductId, "IncomingQuantity"); + model.IncomingQuantity = await _fruitBankAttributeService.GetGenericAttributeValueAsync(model.ProductId, nameof(IIncomingQuantity.IncomingQuantity)); } return View("~/Plugins/Misc.FruitBankPlugin/Views/ProductAttributes.cshtml", model); diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/FruitBankDbContext.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/FruitBankDbContext.cs index 29907ee..aac6e04 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/FruitBankDbContext.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/FruitBankDbContext.cs @@ -4,26 +4,17 @@ using AyCode.Utils.Extensions; using FruitBank.Common.Entities; using FruitBank.Common.Interfaces; using FruitBank.Common.Models; -using FruitBank.Common.Server; -using LinqToDB; -using LinqToDB.Common; -using Mango.Nop.Core.Loggers; using Mango.Nop.Core.Repositories; using Nop.Core; using Nop.Core.Caching; -using Nop.Core.ComponentModel; using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Customers; using Nop.Data; using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer.Interfaces; using Nop.Plugin.Misc.FruitBankPlugin.Services; using Nop.Services.Catalog; -using Nop.Services.Common; -using System.Transactions; -using DevExpress.XtraExport.Helpers; using FruitBank.Common.Dtos; -using Mango.Nop.Core.Dtos; -using Microsoft.CodeAnalysis.CSharp.Syntax; +using Mango.Nop.Core.Extensions; using Nop.Core.Domain.Orders; namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; @@ -45,6 +36,8 @@ public class FruitBankDbContext : MgDbContextBase, private readonly IProductService _productService; private readonly IStaticCacheManager _staticCacheManager; + public ProductDtoDbTable ProductDtos { get; set; } + public OrderDtoDbTable OrderDtos { get; set; } public OrderItemDtoDbTable OrderItemDtos { get; set; } @@ -67,7 +60,7 @@ public class FruitBankDbContext : MgDbContextBase, public FruitBankDbContext(INopDataProvider dataProvider, ILockService lockService, FruitBankAttributeService fruitBankAttributeService, IStoreContext storeContext, PartnerDbTable partnerDbTable, ShippingDbTable shippingDbTable, ShippingDocumentDbTable shippingDocumentDbTable, ShippingItemDbTable shippingItemDbTable, ShippingItemPalletDbTable shippingItemPalletDbTable, FilesDbTable filesDbTable, ShippingDocumentToFilesDbTable shippingDocumentToFilesDbTable, - OrderDtoDbTable orderDtoDbTable, OrderItemDtoDbTable orderItemDtoDbTable, OrderItemPalletDbTable orderItemPalletDbTable, + ProductDtoDbTable productDtoDbTable, OrderDtoDbTable orderDtoDbTable, OrderItemDtoDbTable orderItemDtoDbTable, OrderItemPalletDbTable orderItemPalletDbTable, IProductService productService, IStaticCacheManager staticCacheManager, IRepository productRepository, IRepository customerRepository, @@ -84,6 +77,8 @@ public class FruitBankDbContext : MgDbContextBase, Partners = partnerDbTable; Products = productRepository; + ProductDtos = productDtoDbTable; + OrderDtos = orderDtoDbTable; OrderItemDtos = orderItemDtoDbTable; OrderItemPallets = orderItemPalletDbTable; @@ -131,17 +126,17 @@ public class FruitBankDbContext : MgDbContextBase, => GetAllProducts(includeDeleted).Select(product => new ProductDto(product)); public IAsyncEnumerable GetAllMeasuringProductDtos(bool includeDeleted) - => GetAllProducts(includeDeleted).SelectAwait(async product => new MeasuringProductDto(product, await GetMeasuringAttributeValuesByProductIdAsync(product.Id))); + => GetAllProducts(includeDeleted).AsEnumerable().SelectAwait(async product => new MeasuringProductDto(product, await GetMeasuringAttributeValuesByProductIdAsync(product.Id))); public async Task GetMeasuringProductDtoByIdAsync(int productId) - => await Products.Table.Where(product => product.Id == productId).SelectAwait(async product => new MeasuringProductDto(product, await GetMeasuringAttributeValuesByProductIdAsync(product.Id))).FirstOrDefaultAsync(); + => await Products.Table.Where(product => product.Id == productId).AsEnumerable().SelectAwait(async product => new MeasuringProductDto(product, await GetMeasuringAttributeValuesByProductIdAsync(product.Id))).FirstOrDefaultAsync(); public async Task GetMeasuringAttributeValuesByProductIdAsync(int productId) => await _fruitBankAttributeService.GetMeasuringAttributeValuesAsync(productId); public async Task DeleteShippingSafeAsync(Shipping shipping) { - await TransactionSafeAsync(async tr => + await TransactionSafeAsync(async _ => { await Shippings.DeleteAsync(shipping, true); return true; @@ -150,7 +145,7 @@ public class FruitBankDbContext : MgDbContextBase, public async Task DeleteShippingDocumentSafeAsync(ShippingDocument shippingDocument) { - await TransactionSafeAsync(async tr => + await TransactionSafeAsync(async _ => { await ShippingDocuments.DeleteAsync(shippingDocument, true); return true; @@ -159,7 +154,7 @@ public class FruitBankDbContext : MgDbContextBase, public async Task DeleteShippingItemSafeAsync(ShippingItem shippingItem) { - await TransactionSafeAsync(async tr => + await TransactionSafeAsync(async _ => { await ShippingItems.DeleteAsync(shippingItem, true); return true; @@ -181,17 +176,17 @@ public class FruitBankDbContext : MgDbContextBase, { try { - Product? product = null; + ProductDto? productDto = null; var productIsMeasurable = false; if (shippingItem.ProductId > 0) { - product = await Products.GetByIdAsync(shippingItem.ProductId); + productDto = await ProductDtos.GetByIdAsync(shippingItem.ProductId!.Value, true); - if (product == null) + if (productDto == null) throw new Exception($"shippingItem.ProductId > 0 && product == null; shippingItem.ProductId: {shippingItem.ProductId}"); - productIsMeasurable = await _fruitBankAttributeService.IsMeasurableEntityAsync(product.Id); + productIsMeasurable = productDto.IsMeasurable; } shippingItem.IsMeasurable = productIsMeasurable; @@ -207,7 +202,7 @@ public class FruitBankDbContext : MgDbContextBase, var dbShippingItem = await ShippingItems.GetByIdAsync(shippingItem.Id, false); if (dbShippingItem == null) throw new Exception($"dbShippingItem == null; shippingItem.Id: {shippingItem.Id}"); - var isMeasuredPrerequisite = product != null && shippingItem.PalletsOnDocument == shippingItem.ShippingItemPallets.Count + var isMeasuredPrerequisite = productDto != null && shippingItem.PalletsOnDocument == shippingItem.ShippingItemPallets.Count && shippingItem.ShippingItemPallets.All(x => x.IsMeasuredAndValid(shippingItem.IsMeasurable)); SetupShippingItemMeasuringValues(shippingItem, isMeasuredPrerequisite); @@ -230,36 +225,51 @@ public class FruitBankDbContext : MgDbContextBase, if (shippingItem.IsMeasured) { - product!.StockQuantity += productIdChanged ? shippingItem.MeasuredQuantity : shippingItem.MeasuredQuantity - dbShippingItem.MeasuredQuantity; + var quantityInc = productIdChanged ? shippingItem.MeasuredQuantity : shippingItem.MeasuredQuantity - dbShippingItem.MeasuredQuantity; + productDto!.StockQuantity += quantityInc; - if (!await UpdateProductStockQuantityAsync(product, true)) - throw new Exception($"UpdateProductStockQuantity() == false; shippingItem! product.Id: {product.Id}"); + if (!await UpdateProductDtoStockQuantityAsync(productDto, true)) + throw new Exception($"UpdateProductStockQuantity() == false; shippingItem! product.Id: {productDto.Id}"); + + var incomingQuantity = productDto.GenericAttributes.GetValueOrNull(nameof(IIncomingQuantity.IncomingQuantity)); + if (incomingQuantity != null) + { + await _fruitBankAttributeService.UpdateGenericAttributeAsync + (productDto.Id, nameof(IIncomingQuantity.IncomingQuantity), incomingQuantity.Value - quantityInc); + } if (productIsMeasurable) - await _fruitBankAttributeService.InsertOrUpdateMeasuringAttributeValuesAsync(product.Id, + { + await _fruitBankAttributeService.InsertOrUpdateMeasuringAttributeValuesAsync(productDto.Id, productIdChanged ? shippingItem.MeasuredNetWeight : shippingItem.MeasuredNetWeight - dbShippingItem.MeasuredNetWeight, - productIdChanged ? shippingItem.MeasuredGrossWeight : shippingItem.MeasuredGrossWeight - dbShippingItem.MeasuredGrossWeight, shippingItem.IsMeasurable, true); + } } //if (productIdUnchanged || !dbShippingItem.IsMeasured) return true; if (!productIdChanged && (shippingItem.IsMeasured || !dbShippingItem.IsMeasured)) return true; - product = await Products.GetByIdAsync(dbShippingItem.ProductId); - - if (product != null) + productDto = await ProductDtos.GetByIdAsync(dbShippingItem.ProductId); + + if (productDto != null) { - productIsMeasurable = await _fruitBankAttributeService.IsMeasurableEntityAsync(product.Id); - product.StockQuantity -= dbShippingItem.MeasuredQuantity; + productIsMeasurable = productDto.IsMeasurable; + productDto.StockQuantity -= dbShippingItem.MeasuredQuantity; - if (!await UpdateProductStockQuantityAsync(product, true)) - throw new Exception($"UpdateProductStockQuantity() == false; dbShippingItem! product.Id: {product.Id}"); + if (!await UpdateProductDtoStockQuantityAsync(productDto, true)) + throw new Exception($"UpdateProductStockQuantity() == false; dbShippingItem! product.Id: {productDto.Id}"); + + var incomingQuantity = productDto.GenericAttributes.GetValueOrNull(nameof(IIncomingQuantity.IncomingQuantity)); + if (incomingQuantity != null) + { + await _fruitBankAttributeService.UpdateGenericAttributeAsync + (productDto.Id, nameof(IIncomingQuantity.IncomingQuantity), incomingQuantity.Value + dbShippingItem.MeasuredQuantity); + } if (!productIsMeasurable) return true; - var measuringValues = new MeasuringAttributeValues(product.Id, -dbShippingItem.MeasuredNetWeight, -dbShippingItem.MeasuredGrossWeight, dbShippingItem.IsMeasurable); + var measuringValues = new MeasuringAttributeValues(productDto.Id, -dbShippingItem.MeasuredNetWeight, dbShippingItem.IsMeasurable); await _fruitBankAttributeService.InsertOrUpdateMeasuringAttributeValuesAsync(measuringValues, true); - } else Logger.Warning($"product == null; dbShippingItem.ProductId: {dbShippingItem.ProductId}"); //else //TODO: productIdUnchanged-et lekezelni! - J. @@ -306,7 +316,7 @@ public class FruitBankDbContext : MgDbContextBase, } public Task AddShippingItemPalletSafeAsync(ShippingItemPallet shippingItemPallet) - => TransactionSafeAsync(async tr => await AddShippingItemPalletAsync(shippingItemPallet) != null); + => TransactionSafeAsync(async _ => await AddShippingItemPalletAsync(shippingItemPallet) != null); public async Task UpdateShippingItemPalletAsync(ShippingItemPallet shippingItemPallet) { @@ -317,13 +327,13 @@ public class FruitBankDbContext : MgDbContextBase, } public Task UpdateShippingItemPalletSafeAsync(ShippingItemPallet shippingItemPallet) - => TransactionSafeAsync(async tr => await UpdateShippingItemPalletAsync(shippingItemPallet) != null); + => TransactionSafeAsync(async _ => await UpdateShippingItemPalletAsync(shippingItemPallet) != null); public Task AddOrUpdateShippingItemPalletsSafeAsync(ShippingItem shippingItem) => AddOrUpdateShippingItemPalletsSafeAsync(shippingItem.ShippingItemPallets!, shippingItem); public Task AddOrUpdateShippingItemPalletsSafeAsync(IEnumerable shippingItemPallets, ShippingItem parentShippingItem) { - return TransactionSafeAsync(async tr => + return TransactionSafeAsync(async _ => { await AddOrUpdateShippingItemPalletAsync(shippingItemPallets, parentShippingItem); return true; @@ -344,7 +354,7 @@ public class FruitBankDbContext : MgDbContextBase, } public async Task AddOrUpdateShippingItemPalletSafeAsync(ShippingItemPallet shippingItemPallet) - => await TransactionSafeAsync(async tr => await AddOrUpdateShippingItemPalletAsync(shippingItemPallet) != null); + => await TransactionSafeAsync(async _ => await AddOrUpdateShippingItemPalletAsync(shippingItemPallet) != null); public async Task AddOrUpdateShippingItemPalletAsync(ShippingItemPallet shippingItemPallet) { @@ -355,7 +365,7 @@ public class FruitBankDbContext : MgDbContextBase, public async Task DeleteShippingItemPalletSafeAsync(ShippingItemPallet shippingItemPallet) { - await TransactionSafeAsync(async tr => + await TransactionSafeAsync(async _ => { await ShippingItemPallets.DeleteAsync(shippingItemPallet, false); return true; @@ -363,7 +373,7 @@ public class FruitBankDbContext : MgDbContextBase, } public async Task SetOrderStatusToCompleteSafe(int orderId) - => await TransactionSafeAsync(async tr => await SetOrderStatusToComplete(orderId) != null); + => await TransactionSafeAsync(async _ => await SetOrderStatusToComplete(orderId) != null); public async Task SetOrderStatusToComplete(int orderId) { @@ -385,7 +395,7 @@ public class FruitBankDbContext : MgDbContextBase, (orderItemDto.Id, nameof(IMeasuringNetWeight.NetWeight), orderItemDto.NetWeight); await _fruitBankAttributeService.InsertOrUpdateMeasuringAttributeValuesAsync - (orderItemDto.ProductId, -(orderItemDto.NetWeight-gaNetWeight), 0, orderItemDto.IsMeasurable, true); + (orderItemDto.ProductId, -(orderItemDto.NetWeight-gaNetWeight), orderItemDto.IsMeasurable, true); } return orderDto; @@ -408,7 +418,7 @@ public class FruitBankDbContext : MgDbContextBase, } public async Task AddOrUpdateOrderItemPalletSafeAsync(OrderItemPallet orderItemPallet) - => await TransactionSafeAsync(async tr => await AddOrUpdateOrderItemPalletAsync(orderItemPallet) != null); + => await TransactionSafeAsync(async _ => await AddOrUpdateOrderItemPalletAsync(orderItemPallet) != null); public async Task AddOrUpdateOrderItemPalletAsync(OrderItemPallet orderItemPallet) { @@ -435,22 +445,22 @@ public class FruitBankDbContext : MgDbContextBase, return true; } - private async Task UpdateProductStockQuantityAsync(int productId, bool publishEvent) + private async Task UpdateProductDtoStockQuantityAsync(int productDtoId, bool publishEvent) { - var product = await Products.GetByIdAsync(productId); - if (product != null) return await UpdateProductStockQuantityAsync(product, publishEvent); + var productDto = await ProductDtos.GetByIdAsync(productDtoId); + if (productDto != null) return await UpdateProductDtoStockQuantityAsync(productDto, publishEvent); - Logger.Error($"product == null; id: {productId}"); + Logger.Error($"product == null; id: {productDtoId}"); return await Task.FromResult(false); } - private async Task UpdateProductStockQuantityAsync(Product product, bool publishEvent) + private async Task UpdateProductDtoStockQuantityAsync(ProductDto productDto, bool publishEvent) { //Itt mi legyen? RollBack? - J. - if (product.StockQuantity < 0) - Logger.Error($"product.StockQuantity < 0; Id: {product.Id}; StockQuantity: {product.StockQuantity}"); + if (productDto.StockQuantity < 0) + Logger.Error($"productDto.StockQuantity < 0; Id: {productDto.Id}; StockQuantity: {productDto.StockQuantity}"); - await Products.UpdateAsync(product, publishEvent); + await ProductDtos.UpdateAsync(productDto, publishEvent); return await Task.FromResult(true); //var updatedRowsCount = await DataProvider.ExecuteNonQueryAsync($"update product set {nameof(Product.StockQuantity)} = {product.StockQuantity} where {nameof(Product.Id)} = {product.Id}"); diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderDtoDbTable.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderDtoDbTable.cs index ae8e980..174096c 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderDtoDbTable.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderDtoDbTable.cs @@ -11,28 +11,7 @@ using Nop.Services.Logging; namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; -public class OrderItemDtoDbTable : MgDbTableBase -{ - public OrderItemDtoDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger) - : base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger) - { - } - - public IQueryable GetAll(bool loadRelations) - { - return GetAll() - .LoadWith(oi => oi.OrderDto) - .LoadWith(oi => oi.OrderItemPallets) - .LoadWith(oi => oi.GenericAttributes) - .LoadWith(oi => oi.ProductDto).ThenLoad(prod => prod.GenericAttributes); - } - - public Task GetByIdAsync(int orderItemId) => GetAll(true).Where(x => x.Id == orderItemId).FirstOrDefaultAsync(null); - - public IQueryable GetAllByOrderId(int orderId)=> GetAll(true).Where(o => o.OrderId == orderId); -} - -public class OrderDtoDbTable : MgDbTableBase +public class OrderDtoDbTable : MgDtoDbTableBase { public OrderDtoDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger) : base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger) @@ -43,14 +22,15 @@ public class OrderDtoDbTable : MgDbTableBase { return GetAll() .LoadWith(o => o.GenericAttributes) + .LoadWith(o => o.Customer) .LoadWith(o => o.OrderItemDtos).ThenLoad(oi => oi.ProductDto).ThenLoad(prod => prod.GenericAttributes) .LoadWith(o => o.OrderItemDtos).ThenLoad(oi => oi.GenericAttributes) .LoadWith(o => o.OrderItemDtos).ThenLoad(oi => oi.OrderItemPallets); } - public Task GetByIdAsync(int orderId) => GetAll(true).Where(x => x.Id == orderId).FirstOrDefaultAsync(null); + public Task GetByIdAsync(int orderId, bool loadRelations) => GetAll(loadRelations).Where(x => x.Id == orderId).FirstOrDefaultAsync(null); - public IQueryable GetAllByOrderStatus(OrderStatus orderStatus) => GetAll(true).Where(o => o.OrderStatusId == (int)orderStatus); + public IQueryable GetAllByOrderStatus(OrderStatus orderStatus, bool loadRelations = true) => GetAll(loadRelations).Where(o => o.OrderStatusId == (int)orderStatus); - public IQueryable GetAllByIds(IEnumerable orderIds) => GetAll(true).Where(o => orderIds.Contains(o.Id)); + public IQueryable GetAllByIds(IEnumerable orderIds, bool loadRelations = true) => GetAll(loadRelations).Where(o => orderIds.Contains(o.Id)); } diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderItemDtoDbTable.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderItemDtoDbTable.cs new file mode 100644 index 0000000..d3f8aca --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/OrderItemDtoDbTable.cs @@ -0,0 +1,32 @@ +using FruitBank.Common.Dtos; +using LinqToDB; +using Mango.Nop.Core.Repositories; +using Nop.Core.Caching; +using Nop.Core.Configuration; +using Nop.Core.Domain.Orders; +using Nop.Core.Events; +using Nop.Data; +using Nop.Services.Logging; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; + +public class OrderItemDtoDbTable : MgDtoDbTableBase +{ + public OrderItemDtoDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger) + : base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger) + { + } + + public IQueryable GetAll(bool loadRelations) + { + return GetAll() + .LoadWith(oi => oi.OrderDto) + .LoadWith(oi => oi.OrderItemPallets) + .LoadWith(oi => oi.GenericAttributes) + .LoadWith(oi => oi.ProductDto).ThenLoad(prod => prod.GenericAttributes); + } + + public Task GetByIdAsync(int orderItemId, bool loadRelations) => GetAll(loadRelations).Where(x => x.Id == orderItemId).FirstOrDefaultAsync(null); + + public IQueryable GetAllByOrderId(int orderId, bool loadRelations = true)=> GetAll(loadRelations).Where(o => o.OrderId == orderId); +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ProductDtoDbTable.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ProductDtoDbTable.cs new file mode 100644 index 0000000..ad69ff8 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ProductDtoDbTable.cs @@ -0,0 +1,28 @@ +using FruitBank.Common.Dtos; +using LinqToDB; +using Mango.Nop.Core.Repositories; +using Nop.Core.Caching; +using Nop.Core.Configuration; +using Nop.Core.Domain.Catalog; +using Nop.Core.Events; +using Nop.Data; +using Nop.Services.Logging; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; + +public class ProductDtoDbTable : MgDtoDbTableBase +{ + public ProductDtoDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger) + : base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger) + { + } + + public IQueryable GetAll(bool loadRelations) + { + return GetAll().LoadWith(p => p.GenericAttributes); + } + + public Task GetByIdAsync(int productId, bool loadRelations) => GetAll(loadRelations).Where(x => x.Id == productId).FirstOrDefaultAsync(null); + + public IQueryable GetAllByIds(IEnumerable productIds, bool loadRelations = true) => GetAll(loadRelations).Where(p => productIds.Contains(p.Id)); +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDbTable.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDbTable.cs index b74ba46..f25eb69 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDbTable.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDbTable.cs @@ -25,7 +25,7 @@ public class ShippingDbTable : MgDbTableBase ? GetAll() .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.Product) + .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 1c45bb3..0db565c 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDocumentDbTable.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingDocumentDbTable.cs @@ -25,7 +25,7 @@ public class ShippingDocumentDbTable : MgDbTableBase ? GetAll() .LoadWith(sd => sd.Shipping) .LoadWith(sd => sd.ShippingItems).ThenLoad(si => si.Pallet) - .LoadWith(sd => sd.ShippingItems).ThenLoad(si => si.Product) + .LoadWith(sd => sd.ShippingItems).ThenLoad(si => si.ProductDto).ThenLoad(prod => prod.GenericAttributes) .LoadWith(sd => sd.ShippingItems).ThenLoad(si => si.ShippingItemPallets) .LoadWith(sd => sd.ShippingDocumentToFiles).ThenLoad(sdtof => sdtof.ShippingDocumentFile) .LoadWith(sd => sd.Partner) diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingItemDbTable.cs b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingItemDbTable.cs index 2474eee..7c7b384 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingItemDbTable.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/DataLayer/ShippingItemDbTable.cs @@ -38,9 +38,9 @@ public class ShippingItemDbTable : MgDbTableBase .LoadWith(si => si.ShippingDocument).ThenLoad(p => p.Partner) .LoadWith(si => si.ShippingDocument).ThenLoad(sd => sd.ShippingDocumentToFiles).ThenLoad(sdtof => sdtof.ShippingDocumentFile) .LoadWith(si => si.ShippingItemPallets) - .LoadWith(si => si.Product) + .LoadWith(si => si.ProductDto).ThenLoad(prod => prod.GenericAttributes) .LoadWith(si => si.Pallet) - : GetAll().LoadWith(si => si.ShippingItemPallets).LoadWith(si => si.Product).LoadWith(si => si.Pallet); + : GetAll().LoadWith(si => si.ShippingItemPallets).LoadWith(si => si.ProductDto).ThenLoad(prod => prod.GenericAttributes).LoadWith(si => si.Pallet); } public IQueryable GetAllNotMeasured(bool loadRelations) diff --git a/Nop.Plugin.Misc.AIPlugin/Domains/EventConsumers/FruitBankEventConsumer.cs b/Nop.Plugin.Misc.AIPlugin/Domains/EventConsumers/FruitBankEventConsumer.cs index d234afc..c0e100d 100644 --- a/Nop.Plugin.Misc.AIPlugin/Domains/EventConsumers/FruitBankEventConsumer.cs +++ b/Nop.Plugin.Misc.AIPlugin/Domains/EventConsumers/FruitBankEventConsumer.cs @@ -1,9 +1,12 @@ -using AyCode.Core.Loggers; +using System.Diagnostics.CodeAnalysis; +using AyCode.Core.Loggers; using AyCode.Interfaces.Entities; +using FruitBank.Common.Dtos; using FruitBank.Common.Entities; using FruitBank.Common.Interfaces; using FruitBank.Common.Loggers; using FruitBank.Common.Server; +using Humanizer; using Mango.Nop.Core.Loggers; using Mango.Nop.Services; using Microsoft.AspNetCore.Http; @@ -36,58 +39,83 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa { var product = eventMessage.Entity; - await SaveProductCustomAttributesAsync(eventMessage.Entity); + var saveProductCustomAttributesResult = await SaveProductCustomAttributesAsync(eventMessage.Entity); - var isMeasurableProduct = await fruitBankAttributeService.IsMeasurableEntityAsync(product.Id); + //var isMeasurableProduct = await fruitBankAttributeService.IsMeasurableEntityAsync(product.Id); - var shippingItems = await ctx.ShippingItems.Table - .Where(si => si.ProductId == product.Id && !si.IsMeasured && si.IsMeasurable != isMeasurableProduct) - .ToListAsync(); + if (saveProductCustomAttributesResult is { IsMeasurableChanged: true, IsMeasurable: not null }) + { + var shippingItems = await ctx.ShippingItems.Table + .Where(si => si.ProductId == product.Id && !si.IsMeasured && si.IsMeasurable != saveProductCustomAttributesResult.IsMeasurable.Value) + .ToListAsync(); - foreach (var shippingItem in shippingItems) - shippingItem.IsMeasurable = isMeasurableProduct; + if (shippingItems.Count > 0) + { + foreach (var shippingItem in shippingItems) shippingItem.IsMeasurable = saveProductCustomAttributesResult.IsMeasurable.Value; + await ctx.ShippingItems.UpdateAsync(shippingItems, false); + } + } - await ctx.ShippingItems.UpdateAsync(shippingItems, false); await base.HandleEventAsync(eventMessage); } public override async Task HandleEventAsync(EntityInsertedEvent eventMessage) { - await SaveProductCustomAttributesAsync(eventMessage.Entity); + await SaveProductCustomAttributesAsync(eventMessage.Entity); //TODO: ez ide miért kell? - J. await base.HandleEventAsync(eventMessage); } - private async Task SaveProductCustomAttributesAsync(Product product) + /// + /// + /// + /// + /// IsMeasureable + /// + + private async Task<(bool IsMeasurableChanged, bool? IsMeasurable)> SaveProductCustomAttributesAsync(Product product) { - if (product == null) return; + if (product == null) return (false, null); - var form = HttpContextAccessor.HttpContext?.Request?.Form; - if (form == null || form.Count == 0) return; + var hasForm = HttpContextAccessor.HttpContext?.Request?.HasFormContentType ?? false; + var form = hasForm ? HttpContextAccessor.HttpContext.Request.Form : null; - if (form.ContainsKey(nameof(IMeasurable.IsMeasurable)) && form.ContainsKey(nameof(IMeasuringNetWeight.NetWeight))) + if (form == null || form.Count == 0 || + !form.ContainsKey(nameof(IMeasurable.IsMeasurable)) || !form.ContainsKey(nameof(IMeasuringNetWeight.NetWeight)) || + !form.ContainsKey(nameof(IIncomingQuantity.IncomingQuantity)) || !form.ContainsKey(nameof(ITare.Tare))) return (false, null); + + bool? isMeasurable = null; + var isMeasurableChanged = false; + + var productDto = product.Id > 0 ? await ctx.ProductDtos.GetByIdAsync(product.Id, false) : null; + + //IsMeasurable + isMeasurable = form[nameof(IMeasurable.IsMeasurable)].ToString().Contains("true"); + if (productDto == null || productDto.IsMeasurable != isMeasurable.Value) { - var isMeasurable = form[nameof(IMeasurable.IsMeasurable)].ToString().Contains("true"); - //var isMeasurable = CommonHelper.To(form[nameof(IMeasurable.IsMeasurable)].ToString()); - var netWeight = CommonHelper.To(form[nameof(IMeasuringNetWeight.NetWeight)].ToString()); - - await fruitBankAttributeService.InsertOrUpdateMeasuringAttributeValuesAsync(product.Id, netWeight, 0, isMeasurable, false); + await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync(product.Id, nameof(IMeasurable.IsMeasurable), isMeasurable.Value); + isMeasurableChanged = true; } - if (form.ContainsKey(nameof(ITare.Tare))) - { - var tare = CommonHelper.To(form[nameof(ITare.Tare)].ToString()); - if (tare < 0) throw new Exception($"FruitBankEventConsumer->SaveProductCustomAttributesAsync(); (tare < 0); productId: {product.Id}; tare: {tare}"); + //NetWeight + var netWeight = double.Round(CommonHelper.To(form[nameof(IMeasuringNetWeight.NetWeight)].ToString()), 1); + if (productDto == null || productDto.NetWeight != netWeight) + await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync(product.Id, nameof(IMeasuringNetWeight.NetWeight), netWeight); + + //Tára + var tare = double.Round(CommonHelper.To(form[nameof(ITare.Tare)].ToString()), 1); + if (tare < 0) throw new Exception($"FruitBankEventConsumer->SaveProductCustomAttributesAsync(); (tare < 0); productId: {product.Id}; tare: {tare}"); + if (productDto == null || productDto.Tare != tare) await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync(product.Id, nameof(ITare.Tare), tare); - } - if (form.ContainsKey("IncomingQuantity")) - { - var incomingQuantity = CommonHelper.To(form["IncomingQuantity"].ToString()); - if (incomingQuantity < 0) throw new Exception($"FruitBankEventConsumer->SaveProductCustomAttributesAsync(); (incomingQuantity < 0); productId: {product.Id}; incomingQuantity: {incomingQuantity}"); + //IncomingQuantity + var incomingQuantity = CommonHelper.To(form[nameof(IIncomingQuantity.IncomingQuantity)].ToString()); + if (incomingQuantity < 0) throw new Exception($"FruitBankEventConsumer->SaveProductCustomAttributesAsync(); (incomingQuantity < 0); productId: {product.Id}; incomingQuantity: {incomingQuantity}"); - await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync(product.Id, "IncomingQuantity", incomingQuantity); - } + if (productDto == null || productDto.IncomingQuantity != incomingQuantity) + await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync(product.Id, nameof(IIncomingQuantity.IncomingQuantity), incomingQuantity); + + return (isMeasurableChanged, isMeasurable); } public async Task HandleEventAsync(EntityInsertedEvent eventMessage) diff --git a/Nop.Plugin.Misc.AIPlugin/Factories/CustomOrderModelFactory.cs b/Nop.Plugin.Misc.AIPlugin/Factories/CustomOrderModelFactory.cs index 1cf7973..844463e 100644 --- a/Nop.Plugin.Misc.AIPlugin/Factories/CustomOrderModelFactory.cs +++ b/Nop.Plugin.Misc.AIPlugin/Factories/CustomOrderModelFactory.cs @@ -11,7 +11,6 @@ using Nop.Core.Domain.Orders; using Nop.Core.Domain.Shipping; using Nop.Core.Domain.Tax; using Nop.Plugin.Misc.FruitBankPlugin.Helpers; -using Nop.Plugin.Misc.FruitBankPlugin.Models; using Nop.Plugin.Misc.FruitBankPlugin.Services; using Nop.Services.Affiliates; using Nop.Services.Catalog; @@ -37,15 +36,18 @@ using System.Collections; using System.Reflection; using System.Runtime.Intrinsics.Arm; using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; +using Nop.Plugin.Misc.FruitBankPlugin.Factories.MgBase; +using FruitBank.Common.Dtos; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; namespace Nop.Plugin.Misc.FruitBankPlugin.Factories { - public class CustomOrderModelFactory : OrderModelFactory + public class CustomOrderModelFactory : MgOrderModelFactory { - private FruitBankDbContext _ctx; + private readonly FruitBankDbContext _ctx; private readonly IOrderMeasurementService _orderMeasurementService; - private readonly IGenericAttributeService _genericAttributeService; + #region Ctor public CustomOrderModelFactory( FruitBankDbContext ctx, IOrderMeasurementService orderMeasurementService, @@ -139,40 +141,17 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Factories orderSettings, shippingSettings, urlRecordService, - taxSettings + taxSettings, + genericAttributeService ) { _ctx = ctx; _orderMeasurementService = orderMeasurementService; - _genericAttributeService = genericAttributeService; } - + #endregion Ctor public override async Task PrepareOrderSearchModelAsync(OrderSearchModel searchModel) { - // let base prepare default model first var baseModel = await base.PrepareOrderSearchModelAsync(searchModel); - - //foreach (var order in baseModel.order) - - - // create derived/extended instance - //var extended = new OrderSearchModelExtended(); - - // copy all public instance properties from baseModel to extended - //CopyModelHelper.CopyPublicProperties(baseModel, extended); - - // try to obtain NeedsMeasurement from the incoming searchModel (if it's extended) - //bool? needsMeasurement = null; - //var prop = searchModel?.GetType().GetProperty("NeedsMeasurement", BindingFlags.Public | BindingFlags.Instance); - //if (prop != null && prop.PropertyType == typeof(bool?)) - //{ - // needsMeasurement = (bool?)prop.GetValue(searchModel); - //} - - //extended.NeedsMeasurement = needsMeasurement; - - // return the extended object (it's assignable to OrderSearchModel) - //return extended; return baseModel; } @@ -181,18 +160,14 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Factories public async Task PrepareOrderListModelExtendedAsync(OrderSearchModel searchModel) { - var orderListModel = await PrepareOrderListModelAsync(searchModel); - var extendedRows = new List(orderListModel.RecordsFiltered); - - var orderDtosById = await _ctx.OrderDtos.GetAllByIds(orderListModel.Data.Select(x => x.Id)).ToDictionaryAsync(k => k.Id, v => v); + Dictionary orderDtosById = null; - foreach (var orderModel in orderListModel.Data) + var orderListModelExtended = await base.PrepareOrderListModelExtendedAsync(searchModel, async (orderListModel, orderModelExtended) => { - var orderDto = orderDtosById[orderModel.Id]; - - var orderModelExtended = new OrderModelExtended(); - PropertyHelper.CopyPublicValueTypeProperties(orderModel, orderModelExtended); + orderDtosById ??= await _ctx.OrderDtos.GetAllByIds(orderListModel.Data.Select(x => x.Id)).ToDictionaryAsync(k => k.Id, v => v); + var orderDto = orderDtosById[orderModelExtended.Id]; + orderModelExtended.IsMeasured = orderDto.IsMeasured; orderModelExtended.IsMeasurable = orderDto.IsMeasurable; orderModelExtended.DateOfReceipt = orderDto.DateOfReceipt; @@ -200,14 +175,8 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Factories //orderModelExtended.DateOfReceipt = await GetPickupDateTimeAsync(orderModel); Console.WriteLine(orderModelExtended.Id); - extendedRows.Add(orderModelExtended); - } - - orderListModel.Data = null; - - var orderListModelExtended = orderListModel.ToJson().JsonTo(); - orderListModelExtended.Data = extendedRows; - + }); + return orderListModelExtended; } @@ -232,7 +201,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Factories var fullOrder = await _orderService.GetOrderByIdAsync(order.Id); if (fullOrder != null) { - dateTime = await _genericAttributeService.GetAttributeAsync(fullOrder, nameof(IOrderDto.DateOfReceipt)); + dateTime = await GenericAttributeService.GetAttributeAsync(fullOrder, nameof(IOrderDto.DateOfReceipt)); if(dateTime == DateTime.MinValue || !dateTime.HasValue) { dateTime = null; diff --git a/Nop.Plugin.Misc.AIPlugin/Factories/CustomProductModelFactory.cs b/Nop.Plugin.Misc.AIPlugin/Factories/CustomProductModelFactory.cs new file mode 100644 index 0000000..9bb3a9b --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Factories/CustomProductModelFactory.cs @@ -0,0 +1,68 @@ +using FruitBank.Common.Dtos; +using Nop.Core; +using Nop.Core.Domain.Catalog; +using Nop.Core.Domain.Directory; +using Nop.Core.Domain.Tax; +using Nop.Core.Domain.Vendors; +using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; +using Nop.Plugin.Misc.FruitBankPlugin.Factories.MgBase; +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Products; +using Nop.Services.Catalog; +using Nop.Services.Common; +using Nop.Services.Configuration; +using Nop.Services.Customers; +using Nop.Services.Directory; +using Nop.Services.Discounts; +using Nop.Services.Helpers; +using Nop.Services.Localization; +using Nop.Services.Media; +using Nop.Services.Orders; +using Nop.Services.Seo; +using Nop.Services.Shipping; +using Nop.Services.Stores; +using Nop.Web.Areas.Admin.Factories; +using Nop.Web.Areas.Admin.Models.Catalog; +using Nop.Web.Framework.Factories; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Factories; + +public class CustomProductModelFactory : MgProductModelFactory +{ + private readonly FruitBankDbContext _ctx; + + public CustomProductModelFactory(FruitBankDbContext ctx,CatalogSettings catalogSettings, CurrencySettings currencySettings, IAddressService addressService, IBaseAdminModelFactory baseAdminModelFactory, ICategoryService categoryService, ICurrencyService currencyService, ICustomerService customerService, IDateTimeHelper dateTimeHelper, IDiscountService discountService, IDiscountSupportedModelFactory discountSupportedModelFactory, ILocalizationService localizationService, ILocalizedModelFactory localizedModelFactory, IManufacturerService manufacturerService, IMeasureService measureService, IOrderService orderService, IPictureService pictureService, IPriceFormatter priceFormatter, IProductAttributeFormatter productAttributeFormatter, IProductAttributeParser productAttributeParser, IProductAttributeService productAttributeService, IProductService productService, IProductTagService productTagService, IProductTemplateService productTemplateService, ISettingModelFactory settingModelFactory, ISettingService settingService, IShipmentService shipmentService, IShippingService shippingService, IShoppingCartService shoppingCartService, ISpecificationAttributeService specificationAttributeService, IStoreMappingSupportedModelFactory storeMappingSupportedModelFactory, IStoreContext storeContext, IStoreService storeService, IUrlRecordService urlRecordService, IVideoService videoService, IWorkContext workContext, MeasureSettings measureSettings, NopHttpClient nopHttpClient, TaxSettings taxSettings, VendorSettings vendorSettings, IGenericAttributeService genericAttributeService) : base(catalogSettings, currencySettings, addressService, baseAdminModelFactory, categoryService, currencyService, customerService, dateTimeHelper, discountService, discountSupportedModelFactory, localizationService, localizedModelFactory, manufacturerService, measureService, orderService, pictureService, priceFormatter, productAttributeFormatter, productAttributeParser, productAttributeService, productService, productTagService, productTemplateService, settingModelFactory, settingService, shipmentService, shippingService, shoppingCartService, specificationAttributeService, storeMappingSupportedModelFactory, storeContext, storeService, urlRecordService, videoService, workContext, measureSettings, nopHttpClient, taxSettings, vendorSettings, genericAttributeService) + { + _ctx = ctx; + } + + public override async Task PrepareProductSearchModelAsync(ProductSearchModel searchModel) + { + var baseModel = await base.PrepareProductSearchModelAsync(searchModel); + return baseModel; + } + + public override async Task PrepareProductListModelAsync(ProductSearchModel searchModel) + => await base.PrepareProductListModelAsync(searchModel); + + public async Task PrepareProductListModelExtendedAsync(ProductSearchModel searchModel) + { + Dictionary productDtosById = null; + + var productListModelExtended = await base.PrepareProductListModelExtendedAsync(searchModel, async (productListModel, productModelExtended) => + { + productDtosById ??= await _ctx.ProductDtos.GetAllByIds(productListModel.Data.Select(x => x.Id)).ToDictionaryAsync(k => k.Id, v => v); + var productDto = productDtosById[productModelExtended.Id]; + + productModelExtended.Tare = productDto.Tare; + productModelExtended.NetWeight = productDto.NetWeight; + productModelExtended.IsMeasurable = productDto.IsMeasurable; + productModelExtended.IncomingQuantity = productDto.IncomingQuantity; + + productModelExtended.StockQuantityStr = productModelExtended.StockQuantity.ToString(); + }); + + return productListModelExtended; + } +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Factories/MgBase/MgOrderModelFactory.cs b/Nop.Plugin.Misc.AIPlugin/Factories/MgBase/MgOrderModelFactory.cs new file mode 100644 index 0000000..7ea8e50 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Factories/MgBase/MgOrderModelFactory.cs @@ -0,0 +1,171 @@ +using AyCode.Core.Extensions; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.AspNetCore.Mvc.Routing; +using Nop.Core; +using Nop.Core.Domain.Catalog; +using Nop.Core.Domain.Common; +using Nop.Core.Domain.Directory; +using Nop.Core.Domain.Orders; +using Nop.Core.Domain.Shipping; +using Nop.Core.Domain.Tax; +using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; +using Nop.Plugin.Misc.FruitBankPlugin.Services; +using Nop.Services.Affiliates; +using Nop.Services.Catalog; +using Nop.Services.Common; +using Nop.Services.Configuration; +using Nop.Services.Customers; +using Nop.Services.Directory; +using Nop.Services.Discounts; +using Nop.Services.Helpers; +using Nop.Services.Localization; +using Nop.Services.Media; +using Nop.Services.Orders; +using Nop.Services.Payments; +using Nop.Services.Security; +using Nop.Services.Seo; +using Nop.Services.Shipping; +using Nop.Services.Stores; +using Nop.Services.Tax; +using Nop.Services.Vendors; +using Nop.Web.Areas.Admin.Factories; +using Nop.Web.Areas.Admin.Models.Orders; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Factories.MgBase; + +public class MgOrderModelFactory : OrderModelFactory + where TOrderListModelExt:OrderListModelExtended where TOrderModelExt: OrderModelExtended +{ + protected IGenericAttributeService GenericAttributeService; + + #region Ctor + public MgOrderModelFactory( + AddressSettings addressSettings, + CatalogSettings catalogSettings, + CurrencySettings currencySettings, + IActionContextAccessor actionContextAccessor, + IAddressModelFactory addressModelFactory, + IAddressService addressService, + IAffiliateService affiliateService, + IBaseAdminModelFactory baseAdminModelFactory, + ICountryService countryService, + ICurrencyService currencyService, + ICustomerService customerService, + IDateTimeHelper dateTimeHelper, + IDiscountService discountService, + IDownloadService downloadService, + IEncryptionService encryptionService, + IGiftCardService giftCardService, + ILocalizationService localizationService, + IMeasureService measureService, + IOrderProcessingService orderProcessingService, + IOrderReportService orderReportService, + IOrderService orderService, + IPaymentPluginManager paymentPluginManager, + IPaymentService paymentService, + IPictureService pictureService, + IPriceCalculationService priceCalculationService, + IPriceFormatter priceFormatter, + IProductAttributeService productAttributeService, + IProductService productService, + IReturnRequestService returnRequestService, + IRewardPointService rewardPointService, + ISettingService settingService, + IShipmentService shipmentService, + IShippingService shippingService, + IStateProvinceService stateProvinceService, + IStoreService storeService, + ITaxService taxService, + IUrlHelperFactory urlHelperFactory, + IVendorService vendorService, + IWorkContext workContext, + MeasureSettings measureSettings, + NopHttpClient nopHttpClient, + OrderSettings orderSettings, + ShippingSettings shippingSettings, + IUrlRecordService urlRecordService, + TaxSettings taxSettings, + IGenericAttributeService genericAttributeService) + : base(addressSettings, + catalogSettings, + currencySettings, + actionContextAccessor, + addressModelFactory, + addressService, + affiliateService, + baseAdminModelFactory, + countryService, + currencyService, + customerService, + dateTimeHelper, + discountService, + downloadService, + encryptionService, + giftCardService, + localizationService, + measureService, + orderProcessingService, + orderReportService, + orderService, + paymentPluginManager, + paymentService, + pictureService, + priceCalculationService, + priceFormatter, + productAttributeService, + productService, + returnRequestService, + rewardPointService, + settingService, + shipmentService, + shippingService, + stateProvinceService, + storeService, + taxService, + urlHelperFactory, + vendorService, + workContext, + measureSettings, + nopHttpClient, + orderSettings, + shippingSettings, + urlRecordService, + taxSettings + ) + { + GenericAttributeService = genericAttributeService; + } + #endregion Cotr + + public override Task PrepareOrderSearchModelAsync(OrderSearchModel searchModel) + => base.PrepareOrderSearchModelAsync(searchModel); + + public override Task PrepareOrderListModelAsync(OrderSearchModel searchModel) + => base.PrepareOrderListModelAsync(searchModel); + + public virtual async Task PrepareOrderListModelExtendedAsync(OrderSearchModel searchModel, Func dataItemCopiedCallback) + { + var orderListModel = await PrepareOrderListModelAsync(searchModel); + var extendedRows = new List(orderListModel.RecordsFiltered); + + foreach (var orderModel in orderListModel.Data.ToList()) + { + var orderModelExtended = Activator.CreateInstance(); + + PropertyHelper.CopyPublicValueTypeProperties(orderModel, orderModelExtended); + extendedRows.Add(orderModelExtended); + + if (dataItemCopiedCallback == null) continue; + await dataItemCopiedCallback.Invoke(orderListModel, orderModelExtended); + } + + orderListModel.Data = null; + + //var orderListModelExtended = orderListModel.ToJson().JsonTo(); + var orderListModelExtended = orderListModel.CloneTo(); + orderListModelExtended.Data = extendedRows; + + return orderListModelExtended; + } +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Factories/MgBase/MgProductModelFactory.cs b/Nop.Plugin.Misc.AIPlugin/Factories/MgBase/MgProductModelFactory.cs new file mode 100644 index 0000000..8754204 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Factories/MgBase/MgProductModelFactory.cs @@ -0,0 +1,165 @@ +using AyCode.Core.Extensions; +using Microsoft.AspNetCore.Mvc.Infrastructure; +using Microsoft.AspNetCore.Mvc.Routing; +using Nop.Core; +using Nop.Core.Domain.Catalog; +using Nop.Core.Domain.Common; +using Nop.Core.Domain.Directory; +using Nop.Core.Domain.Orders; +using Nop.Core.Domain.Shipping; +using Nop.Core.Domain.Tax; +using Nop.Core.Domain.Vendors; +using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Products; +using Nop.Plugin.Misc.FruitBankPlugin.Services; +using Nop.Services.Affiliates; +using Nop.Services.Catalog; +using Nop.Services.Common; +using Nop.Services.Configuration; +using Nop.Services.Customers; +using Nop.Services.Directory; +using Nop.Services.Discounts; +using Nop.Services.Helpers; +using Nop.Services.Localization; +using Nop.Services.Media; +using Nop.Services.Orders; +using Nop.Services.Payments; +using Nop.Services.Security; +using Nop.Services.Seo; +using Nop.Services.Shipping; +using Nop.Services.Stores; +using Nop.Services.Tax; +using Nop.Services.Vendors; +using Nop.Web.Areas.Admin.Factories; +using Nop.Web.Areas.Admin.Models.Catalog; +using Nop.Web.Areas.Admin.Models.Orders; +using Nop.Web.Framework.Factories; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Factories.MgBase; + +public class MgProductModelFactory : ProductModelFactory + where TProductListModelExt : ProductListModelExtended where TProductModelExt : ProductModelExtended +{ + protected IGenericAttributeService GenericAttributeService; + + #region Ctor + + public MgProductModelFactory( + CatalogSettings catalogSettings, + CurrencySettings currencySettings, + IAddressService addressService, + IBaseAdminModelFactory baseAdminModelFactory, + ICategoryService categoryService, + ICurrencyService currencyService, + ICustomerService customerService, + IDateTimeHelper dateTimeHelper, + IDiscountService discountService, + IDiscountSupportedModelFactory discountSupportedModelFactory, + ILocalizationService localizationService, + ILocalizedModelFactory localizedModelFactory, + IManufacturerService manufacturerService, + IMeasureService measureService, + IOrderService orderService, + IPictureService pictureService, + IPriceFormatter priceFormatter, + IProductAttributeFormatter productAttributeFormatter, + IProductAttributeParser productAttributeParser, + IProductAttributeService productAttributeService, + IProductService productService, + IProductTagService productTagService, + IProductTemplateService productTemplateService, + ISettingModelFactory settingModelFactory, + ISettingService settingService, + IShipmentService shipmentService, + IShippingService shippingService, + IShoppingCartService shoppingCartService, + ISpecificationAttributeService specificationAttributeService, + IStoreMappingSupportedModelFactory storeMappingSupportedModelFactory, + IStoreContext storeContext, + IStoreService storeService, + IUrlRecordService urlRecordService, + IVideoService videoService, + IWorkContext workContext, + MeasureSettings measureSettings, + NopHttpClient nopHttpClient, + TaxSettings taxSettings, + VendorSettings vendorSettings, + IGenericAttributeService genericAttributeService) + : base( + catalogSettings, + currencySettings, + addressService, + baseAdminModelFactory, + categoryService, + currencyService, + customerService, + dateTimeHelper, + discountService, + discountSupportedModelFactory, + localizationService, + localizedModelFactory, + manufacturerService, + measureService, + orderService, + pictureService, + priceFormatter, + productAttributeFormatter, + productAttributeParser, + productAttributeService, + productService, + productTagService, + productTemplateService, + settingModelFactory, + settingService, + shipmentService, + shippingService, + shoppingCartService, + specificationAttributeService, + storeMappingSupportedModelFactory, + storeContext, + storeService, + urlRecordService, + videoService, + workContext, + measureSettings, + nopHttpClient, + taxSettings, + vendorSettings) + { + GenericAttributeService = genericAttributeService; + } + + #endregion Cotr + + public override Task PrepareProductSearchModelAsync(ProductSearchModel searchModel) + => base.PrepareProductSearchModelAsync(searchModel); + + public override Task PrepareProductListModelAsync(ProductSearchModel searchModel) + => base.PrepareProductListModelAsync(searchModel); + + public virtual async Task PrepareProductListModelExtendedAsync(ProductSearchModel searchModel, Func dataItemCopiedCallback) + { + var productListModel = await PrepareProductListModelAsync(searchModel); + var extendedRows = new List(productListModel.RecordsFiltered); + + foreach (var productModel in productListModel.Data.ToList()) + { + var productModelExtended = Activator.CreateInstance(); + + PropertyHelper.CopyPublicValueTypeProperties(productModel, productModelExtended); + extendedRows.Add(productModelExtended); + + if (dataItemCopiedCallback == null) continue; + await dataItemCopiedCallback.Invoke(productListModel, productModelExtended); + } + + productListModel.Data = null; + + //var productListModelExtended = productListModel.ToJson().JsonTo(); + var productListModelExtended = productListModel.CloneTo(); + productListModelExtended.Data = extendedRows; + + return productListModelExtended; + } +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Infrastructure/PluginNopStartup.cs b/Nop.Plugin.Misc.AIPlugin/Infrastructure/PluginNopStartup.cs index e478105..9639bf0 100644 --- a/Nop.Plugin.Misc.AIPlugin/Infrastructure/PluginNopStartup.cs +++ b/Nop.Plugin.Misc.AIPlugin/Infrastructure/PluginNopStartup.cs @@ -58,6 +58,7 @@ public class PluginNopStartup : INopStartup services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -86,6 +87,7 @@ public class PluginNopStartup : INopStartup //services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/Nop.Plugin.Misc.AIPlugin/Models/IOrderListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/IOrderListModelExtended.cs deleted file mode 100644 index 5df5da5..0000000 --- a/Nop.Plugin.Misc.AIPlugin/Models/IOrderListModelExtended.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Nop.Web.Framework.Models; - -namespace Nop.Plugin.Misc.FruitBankPlugin.Models; - -public interface IOrderListModelExtended: IPagedModel where T : BaseNopModel -{ - public bool? NeedsMeasurement { get; set; } -} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/IMgListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/IMgListModelExtended.cs new file mode 100644 index 0000000..4eda7d8 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/IMgListModelExtended.cs @@ -0,0 +1,7 @@ +using Nop.Web.Framework.Models; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase; + +public interface IMgListModelExtended: IPagedModel where T : BaseNopModel, IMgModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/IMgModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/IMgModelExtended.cs new file mode 100644 index 0000000..0a4418c --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/IMgModelExtended.cs @@ -0,0 +1,5 @@ +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase; + +public interface IMgModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/IMgOrderListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/IMgOrderListModelExtended.cs new file mode 100644 index 0000000..68083f5 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/IMgOrderListModelExtended.cs @@ -0,0 +1,5 @@ +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; + +public interface IMgOrderListModelExtended: IMgListModelExtended where T : MgOrderModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/IMgOrderModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/IMgOrderModelExtended.cs new file mode 100644 index 0000000..fb9bb9b --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/IMgOrderModelExtended.cs @@ -0,0 +1,5 @@ +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; + +public interface IMgOrderModelExtended : IMgModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/MgOrderListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/MgOrderListModelExtended.cs new file mode 100644 index 0000000..e648648 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/MgOrderListModelExtended.cs @@ -0,0 +1,8 @@ +using Nop.Web.Framework.Models; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; + +public partial record MgOrderListModelExtended : BasePagedListModel, IMgOrderListModelExtended + where TOrderModelExt: MgOrderModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/MgOrderModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/MgOrderModelExtended.cs new file mode 100644 index 0000000..a3735b9 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/OrderModels/MgOrderModelExtended.cs @@ -0,0 +1,8 @@ +using Nop.Web.Areas.Admin.Models.Orders; +using Nop.Web.Framework.Models; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; + +public partial record MgOrderModelExtended : OrderModel, IMgOrderModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/IMgProductListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/IMgProductListModelExtended.cs new file mode 100644 index 0000000..94a2ec9 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/IMgProductListModelExtended.cs @@ -0,0 +1,5 @@ +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels; + +public interface IMgProductListModelExtended: IMgListModelExtended where T : MgProductModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/IMgProductModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/IMgProductModelExtended.cs new file mode 100644 index 0000000..85d15f9 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/IMgProductModelExtended.cs @@ -0,0 +1,5 @@ +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels; + +public interface IMgProductModelExtended : IMgModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/MgProductListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/MgProductListModelExtended.cs new file mode 100644 index 0000000..c28fbda --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/MgProductListModelExtended.cs @@ -0,0 +1,8 @@ +using Nop.Web.Framework.Models; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels; + +public partial record MgProductListModelExtended : BasePagedListModel, IMgProductListModelExtended + where TProductModelExt: MgProductModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/MgProductModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/MgProductModelExtended.cs new file mode 100644 index 0000000..b0e86ef --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/MgBase/ProductModels/MgProductModelExtended.cs @@ -0,0 +1,8 @@ +using Nop.Web.Areas.Admin.Models.Catalog; +using Nop.Web.Framework.Models; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels; + +public partial record MgProductModelExtended : ProductModel, IMgProductModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/OrderListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/OrderListModelExtended.cs deleted file mode 100644 index 6e6998a..0000000 --- a/Nop.Plugin.Misc.AIPlugin/Models/OrderListModelExtended.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Nop.Web.Areas.Admin.Models.Orders; -using Nop.Web.Framework.Models; - -namespace Nop.Plugin.Misc.FruitBankPlugin.Models -{ - public partial record OrderListModelExtended : BasePagedListModel, IOrderListModelExtended - { - public bool? NeedsMeasurement { get; set; } - } -} - diff --git a/Nop.Plugin.Misc.AIPlugin/Models/OrderModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/OrderModelExtended.cs deleted file mode 100644 index 8687e20..0000000 --- a/Nop.Plugin.Misc.AIPlugin/Models/OrderModelExtended.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Nop.Web.Areas.Admin.Models.Orders; - -namespace Nop.Plugin.Misc.FruitBankPlugin.Models -{ - public partial record OrderModelExtended : OrderModel - { - public bool IsMeasurable { get; set; } - public DateTime? DateOfReceipt { get; set; } - } -} - diff --git a/Nop.Plugin.Misc.AIPlugin/Models/OrderSearchModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/OrderSearchModelExtended.cs deleted file mode 100644 index 7d46408..0000000 --- a/Nop.Plugin.Misc.AIPlugin/Models/OrderSearchModelExtended.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Nop.Web.Areas.Admin.Models.Orders; - -namespace Nop.Plugin.Misc.FruitBankPlugin.Models -{ - public partial record OrderSearchModelExtended : OrderSearchModel - { - public bool? NeedsMeasurement { get; set; } - } -} - diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Orders/IOrderListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/Orders/IOrderListModelExtended.cs new file mode 100644 index 0000000..87e4bc6 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/Orders/IOrderListModelExtended.cs @@ -0,0 +1,7 @@ +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; + +public interface IOrderListModelExtended: IMgOrderListModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Orders/IOrderModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/Orders/IOrderModelExtended.cs new file mode 100644 index 0000000..69e803f --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/Orders/IOrderModelExtended.cs @@ -0,0 +1,9 @@ +using FruitBank.Common.Interfaces; +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; + +public interface IOrderModelExtended : IMgOrderModelExtended, IMeasurable, IMeasured +{ + public DateTime? DateOfReceipt { get; set; } +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/OrderAttributesModel.cs b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderAttributesModel.cs similarity index 90% rename from Nop.Plugin.Misc.AIPlugin/Models/OrderAttributesModel.cs rename to Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderAttributesModel.cs index 080e9f6..0fec549 100644 --- a/Nop.Plugin.Misc.AIPlugin/Models/OrderAttributesModel.cs +++ b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderAttributesModel.cs @@ -2,7 +2,7 @@ using Nop.Web.Framework.Models; using Nop.Web.Framework.Mvc.ModelBinding; -namespace Nop.Plugin.Misc.FruitBankPlugin.Models +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Orders { public record OrderAttributesModel : BaseNopModel, IMeasurable { diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderListModelExtended.cs new file mode 100644 index 0000000..55e74f6 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderListModelExtended.cs @@ -0,0 +1,10 @@ +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; +using Nop.Web.Areas.Admin.Models.Orders; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Orders +{ + public partial record OrderListModelExtended : MgOrderListModelExtended, IOrderListModelExtended + { + } +} + diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderModelExtended.cs new file mode 100644 index 0000000..dabbceb --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/Orders/OrderModelExtended.cs @@ -0,0 +1,12 @@ +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Orders +{ + public partial record OrderModelExtended : MgOrderModelExtended, IOrderModelExtended + { + public bool IsMeasured { get; set; } + public bool IsMeasurable { get; set; } + public DateTime? DateOfReceipt { get; set; } + } +} + diff --git a/Nop.Plugin.Misc.AIPlugin/Models/ProductAttributesModel.cs b/Nop.Plugin.Misc.AIPlugin/Models/ProductAttributesModel.cs index daca835..56726ab 100644 --- a/Nop.Plugin.Misc.AIPlugin/Models/ProductAttributesModel.cs +++ b/Nop.Plugin.Misc.AIPlugin/Models/ProductAttributesModel.cs @@ -4,7 +4,7 @@ using Nop.Web.Framework.Mvc.ModelBinding; namespace Nop.Plugin.Misc.FruitBankPlugin.Models { - public record ProductAttributesModel : BaseNopModel, IMeasurable, IMeasuringWeights, ITare + public record ProductAttributesModel : BaseNopModel, IMeasurable, IMeasuringWeights, ITare, IIncomingQuantity { public int ProductId { get; set; } @@ -18,7 +18,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Models public double GrossWeight { get; set; } [NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.IncomingQuantity")] - public int? IncomingQuantity { get; set; } + public int IncomingQuantity { get; set; } [NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.Tare")] public double Tare { get; set; } diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Products/IProductListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/Products/IProductListModelExtended.cs new file mode 100644 index 0000000..8d95665 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/Products/IProductListModelExtended.cs @@ -0,0 +1,9 @@ + + +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Products; + +public interface IProductListModelExtended: IMgProductListModelExtended +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Products/IProductModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/Products/IProductModelExtended.cs new file mode 100644 index 0000000..5ab6a82 --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/Products/IProductModelExtended.cs @@ -0,0 +1,9 @@ +using FruitBank.Common.Interfaces; +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Products; + +public interface IProductModelExtended : IMgProductModelExtended, IMeasurable, ITare, IMeasuringNetWeight, IIncomingQuantity +{ +} \ No newline at end of file diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Products/ProductListModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/Products/ProductListModelExtended.cs new file mode 100644 index 0000000..401a91d --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/Products/ProductListModelExtended.cs @@ -0,0 +1,11 @@ +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels; +using Nop.Web.Areas.Admin.Models.Orders; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Products +{ + public partial record ProductListModelExtended : MgProductListModelExtended, IProductListModelExtended + { + } +} + diff --git a/Nop.Plugin.Misc.AIPlugin/Models/Products/ProductModelExtended.cs b/Nop.Plugin.Misc.AIPlugin/Models/Products/ProductModelExtended.cs new file mode 100644 index 0000000..44ddbaa --- /dev/null +++ b/Nop.Plugin.Misc.AIPlugin/Models/Products/ProductModelExtended.cs @@ -0,0 +1,15 @@ +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels; +using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels; + +namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Products +{ + public partial record ProductModelExtended : MgProductModelExtended, IProductModelExtended + { + public bool IsMeasurable { get; set; } + + public double Tare { get; set; } + public double NetWeight { get; set; } + public int IncomingQuantity { get; set; } + } +} + diff --git a/Nop.Plugin.Misc.AIPlugin/Services/EventConsumer.cs b/Nop.Plugin.Misc.AIPlugin/Services/EventConsumer.cs index 0b11407..67d5201 100644 --- a/Nop.Plugin.Misc.AIPlugin/Services/EventConsumer.cs +++ b/Nop.Plugin.Misc.AIPlugin/Services/EventConsumer.cs @@ -5,6 +5,7 @@ using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Orders; using Nop.Core.Events; using Nop.Plugin.Misc.FruitBankPlugin.Models; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; using Nop.Services.Catalog; using Nop.Services.Common; using Nop.Services.Events; @@ -122,7 +123,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services var store = await _storeContext.GetCurrentStoreAsync(); // itt adjuk hozzá a GenericAttribute flag-et az orderhez await _genericAttributeService.SaveAttributeAsync(order, - nameof(OrderModelExtended.IsMeasurable), true, store.Id); + nameof(IMeasurable.IsMeasurable), true, store.Id); // status pending // paymentstatus pending } diff --git a/Nop.Plugin.Misc.AIPlugin/Services/FruitBankAttributeService.cs b/Nop.Plugin.Misc.AIPlugin/Services/FruitBankAttributeService.cs index ea6f623..a3a1f0e 100644 --- a/Nop.Plugin.Misc.AIPlugin/Services/FruitBankAttributeService.cs +++ b/Nop.Plugin.Misc.AIPlugin/Services/FruitBankAttributeService.cs @@ -10,7 +10,6 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services; public class FruitBankAttributeService(IGenericAttributeService genericAttributeService, IStoreContext storeContext) { private const string NET_WEIGHT_KEY = nameof(IMeasuringAttributeValues.NetWeight); - private const string GROSS_WEIGHT_KEY = nameof(IMeasuringAttributeValues.GrossWeight); private const string IS_MEASURABLE_KEY = nameof(IMeasuringAttributeValues.IsMeasurable); @@ -31,11 +30,11 @@ public class FruitBankAttributeService(IGenericAttributeService genericAttribute public async Task?> GetMeasuringAttributesAsync(int entityId, int storeId) { var measuringAttributes = (await genericAttributeService.GetAttributesForEntityAsync(entityId, typeof(TEntity).Name)) - .Where(ga => ga.StoreId == storeId && ga.Key is NET_WEIGHT_KEY or GROSS_WEIGHT_KEY or IS_MEASURABLE_KEY) + .Where(ga => ga.StoreId == storeId && ga.Key is NET_WEIGHT_KEY or IS_MEASURABLE_KEY) .ToList(); if (measuringAttributes.Count == 0) return null; - if (measuringAttributes.Count != 3) throw new Exception($"FruitBankAttributeService->GetMeasuringAttributesAsync(); measuringAttributes.Count != 3; entityId: {entityId}"); + if (measuringAttributes.Count != 2) throw new Exception($"FruitBankAttributeService->GetMeasuringAttributesAsync(); measuringAttributes.Count != 2; entityId: {entityId}"); return measuringAttributes; } @@ -51,7 +50,6 @@ public class FruitBankAttributeService(IGenericAttributeService genericAttribute var measuringAttributeValues = new MeasuringAttributeValues( entityId, CommonHelper.To(measuringAttributes.Single(ga => ga.Key == NET_WEIGHT_KEY).Value), - CommonHelper.To(measuringAttributes.Single(ga => ga.Key == GROSS_WEIGHT_KEY).Value), CommonHelper.To(measuringAttributes.Single(ga => ga.Key == IS_MEASURABLE_KEY).Value)); return measuringAttributeValues; @@ -64,13 +62,12 @@ public class FruitBankAttributeService(IGenericAttributeService genericAttribute return measurableAttribute != null && CommonHelper.To(measurableAttribute.Value); } - public async Task InsertOrUpdateMeasuringAttributeValuesAsync(int entityId, double netWeight, double grossWeight, bool isMeasurable, bool cumulativeWeightUpdate) + public async Task InsertOrUpdateMeasuringAttributeValuesAsync(int entityId, double netWeight, bool isMeasurable, bool cumulativeWeightUpdate) { var measuringAttributeValues = new MeasuringAttributeValues { Id = entityId, NetWeight = netWeight, - GrossWeight = grossWeight, IsMeasurable = isMeasurable }; @@ -91,27 +88,15 @@ public class FruitBankAttributeService(IGenericAttributeService genericAttribute if (measuringAttributes == null) { await InsertGenericAttributeAsync(entityId, NET_WEIGHT_KEY, double.Round(measuringAttributeValues.NetWeight, 1), storeId); - await InsertGenericAttributeAsync(entityId, GROSS_WEIGHT_KEY, double.Round(measuringAttributeValues.GrossWeight, 1), storeId); await InsertGenericAttributeAsync(entityId, IS_MEASURABLE_KEY, measuringAttributeValues.IsMeasurable, storeId); return; } await UpdateMeasuringWeightAttributeValueAsync(measuringAttributes.Single(ma => ma.Key == NET_WEIGHT_KEY), measuringAttributeValues.NetWeight, cumulativeWeightUpdate); - await UpdateMeasuringWeightAttributeValueAsync(measuringAttributes.Single(ma => ma.Key == GROSS_WEIGHT_KEY), measuringAttributeValues.GrossWeight, cumulativeWeightUpdate); - await UpdateGenericAttributeAsync(measuringAttributes.Single(ma => ma.Key == IS_MEASURABLE_KEY), measuringAttributeValues.IsMeasurable); - //var netWeightAttribute = measuringAttributes?.SingleOrDefault(ma => ma.Key == NET_WEIGHT_KEY); - //if (netWeightAttribute != null) await UpdateMeasuringWeightAttributeValueAsync(netWeightAttribute, measuringAttributeValues.NetWeight, cumulativeWeightUpdate); - //else await InsertGenericAttributeAsync(entityId, NET_WEIGHT_KEY, measuringAttributeValues.NetWeight, storeId); - - //var grossWeightAttribute = measuringAttributes?.SingleOrDefault(ma => ma.Key == GROSS_WEIGHT_KEY); - //if (grossWeightAttribute != null) await UpdateMeasuringWeightAttributeValueAsync(grossWeightAttribute, measuringAttributeValues.GrossWeight, cumulativeWeightUpdate); - //else await InsertGenericAttributeAsync(entityId, GROSS_WEIGHT_KEY, measuringAttributeValues.GrossWeight, storeId); - - //var isMeasurableAttribute = measuringAttributes?.SingleOrDefault(ma => ma.Key == IS_MEASURABLE_KEY); - //if (isMeasurableAttribute != null) await UpdateGenericAttributeAsync(isMeasurableAttribute, measuringAttributeValues.IsMeasurable); - //else await InsertGenericAttributeAsync(entityId, IS_MEASURABLE_KEY, measuringAttributeValues.IsMeasurable, storeId); + //TODO: ezzel mi legyen? - J. + //await UpdateGenericAttributeAsync(measuringAttributes.Single(ma => ma.Key == IS_MEASURABLE_KEY), measuringAttributeValues.IsMeasurable); } private async Task UpdateMeasuringWeightAttributeValueAsync(GenericAttribute genericAttribute, double newWeightValue, bool cumulativeWeightUpdate) diff --git a/Nop.Plugin.Misc.AIPlugin/Services/OrderMeasurementService.cs b/Nop.Plugin.Misc.AIPlugin/Services/OrderMeasurementService.cs index c84f94f..d5dbf86 100644 --- a/Nop.Plugin.Misc.AIPlugin/Services/OrderMeasurementService.cs +++ b/Nop.Plugin.Misc.AIPlugin/Services/OrderMeasurementService.cs @@ -1,5 +1,6 @@ -using Nop.Core.Domain.Orders; -using Nop.Plugin.Misc.FruitBankPlugin.Models; +using FruitBank.Common.Interfaces; +using Nop.Core.Domain.Orders; +using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; using Nop.Services.Common; namespace Nop.Plugin.Misc.FruitBankPlugin.Services @@ -24,7 +25,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services return false; return await _genericAttributeService.GetAttributeAsync( - order, nameof(OrderModelExtended.IsMeasurable), order.StoreId); + order, nameof(IMeasurable.IsMeasurable), order.StoreId); } } } diff --git a/Nop.Plugin.Misc.AIPlugin/Views/OrderAttributes.cshtml b/Nop.Plugin.Misc.AIPlugin/Views/OrderAttributes.cshtml index b3dcd1d..a20d517 100644 --- a/Nop.Plugin.Misc.AIPlugin/Views/OrderAttributes.cshtml +++ b/Nop.Plugin.Misc.AIPlugin/Views/OrderAttributes.cshtml @@ -1,4 +1,5 @@ -@model Nop.Plugin.Misc.FruitBankPlugin.Models.OrderAttributesModel +@using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders +@model OrderAttributesModel