improvements, fixes, etc...

This commit is contained in:
Loretta 2025-10-16 11:43:51 +02:00
parent fbf83e5736
commit ba52be2847
46 changed files with 1727 additions and 1166 deletions

View File

@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Mvc;
using Nop.Core.Domain.Orders; using Nop.Core.Domain.Orders;
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
using Nop.Plugin.Misc.FruitBankPlugin.Factories; 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.Common;
using Nop.Services.Messages; using Nop.Services.Messages;
using Nop.Services.Orders; using Nop.Services.Orders;
@ -126,7 +126,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers
return RedirectToAction("List", "Order"); return RedirectToAction("List", "Order");
// store attributes in GenericAttribute table // 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); await _genericAttributeService.SaveAttributeAsync(order, nameof(IOrderDto.DateOfReceipt), model.DateOfReceipt);
_notificationService.SuccessNotification("Custom attributes saved successfully."); _notificationService.SuccessNotification("Custom attributes saved successfully.");

View File

@ -13,6 +13,7 @@ using Nop.Core.Domain.Tax;
using Nop.Core.Domain.Vendors; using Nop.Core.Domain.Vendors;
using Nop.Core.Http; using Nop.Core.Http;
using Nop.Core.Infrastructure; using Nop.Core.Infrastructure;
using Nop.Plugin.Misc.FruitBankPlugin.Factories;
using Nop.Services.Catalog; using Nop.Services.Catalog;
using Nop.Services.Common; using Nop.Services.Common;
using Nop.Services.Configuration; using Nop.Services.Configuration;
@ -44,6 +45,7 @@ public partial class CustomProductController : BaseAdminController
{ {
#region Fields #region Fields
private readonly CustomProductModelFactory _productModelFactory;
protected readonly AdminAreaSettings _adminAreaSettings; protected readonly AdminAreaSettings _adminAreaSettings;
protected readonly IAclService _aclService; protected readonly IAclService _aclService;
protected readonly IBackInStockSubscriptionService _backInStockSubscriptionService; protected readonly IBackInStockSubscriptionService _backInStockSubscriptionService;
@ -70,7 +72,6 @@ public partial class CustomProductController : BaseAdminController
protected readonly IProductAttributeFormatter _productAttributeFormatter; protected readonly IProductAttributeFormatter _productAttributeFormatter;
protected readonly IProductAttributeParser _productAttributeParser; protected readonly IProductAttributeParser _productAttributeParser;
protected readonly IProductAttributeService _productAttributeService; protected readonly IProductAttributeService _productAttributeService;
protected readonly IProductModelFactory _productModelFactory;
protected readonly IProductService _productService; protected readonly IProductService _productService;
protected readonly IProductTagService _productTagService; protected readonly IProductTagService _productTagService;
protected readonly ISettingService _settingService; protected readonly ISettingService _settingService;
@ -159,7 +160,7 @@ public partial class CustomProductController : BaseAdminController
_productAttributeFormatter = productAttributeFormatter; _productAttributeFormatter = productAttributeFormatter;
_productAttributeParser = productAttributeParser; _productAttributeParser = productAttributeParser;
_productAttributeService = productAttributeService; _productAttributeService = productAttributeService;
_productModelFactory = productModelFactory; _productModelFactory = productModelFactory as CustomProductModelFactory;
_productService = productService; _productService = productService;
_productTagService = productTagService; _productTagService = productTagService;
_settingService = settingService; _settingService = settingService;
@ -878,7 +879,6 @@ public partial class CustomProductController : BaseAdminController
[CheckPermission(StandardPermission.Catalog.PRODUCTS_VIEW)] [CheckPermission(StandardPermission.Catalog.PRODUCTS_VIEW)]
public virtual async Task<IActionResult> List() public virtual async Task<IActionResult> List()
{ {
//prepare model
var model = await _productModelFactory.PrepareProductSearchModelAsync(new ProductSearchModel()); var model = await _productModelFactory.PrepareProductSearchModelAsync(new ProductSearchModel());
return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Product/List.cshtml", model); 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<IActionResult> ProductList(ProductSearchModel searchModel) public virtual async Task<IActionResult> ProductList(ProductSearchModel searchModel)
{ {
//prepare model //prepare model
var model = await _productModelFactory.PrepareProductListModelAsync(searchModel); var model = await _productModelFactory.PrepareProductListModelExtendedAsync(searchModel);
return Json(model); return Json(model);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,466 +1,488 @@
@model ProductSearchModel @model ProductSearchModel
@using Nop.Core.Domain.Catalog; @using Nop.Core.Domain.Catalog;
@using Nop.Plugin.Misc.FruitBankPlugin.Models.Products
@{ @{
//page title //page title
ViewBag.PageTitle = T("Admin.Catalog.Products").Text; ViewBag.PageTitle = T("Admin.Catalog.Products").Text;
//active menu item (system name) //active menu item (system name)
NopHtml.SetActiveMenuItemSystemName("Products"); NopHtml.SetActiveMenuItemSystemName("Products");
} }
@{ @{
const string hideSearchBlockAttributeName = "ProductListPage.HideSearchBlock"; const string hideSearchBlockAttributeName = "ProductListPage.HideSearchBlock";
var hideSearchBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideSearchBlockAttributeName); var hideSearchBlock = await genericAttributeService.GetAttributeAsync<bool>(await workContext.GetCurrentCustomerAsync(), hideSearchBlockAttributeName);
} }
@if (Model.LicenseCheckModel.BlockPages != true) @if (Model.LicenseCheckModel.BlockPages != true)
{ {
<form asp-controller="Product" asp-action="List" method="post"> <form asp-controller="Product" asp-action="List" method="post">
<div class="content-header clearfix"> <div class="content-header clearfix">
<h1 class="float-left"> <h1 class="float-left">
Fruitbank @T("Admin.Catalog.Products") Fruitbank @T("Admin.Catalog.Products")
</h1> </h1>
<div class="float-right"> <div class="float-right">
<a asp-action="Create" class="btn btn-primary"> <a asp-action="Create" class="btn btn-primary">
<i class="fas fa-square-plus"></i> <i class="fas fa-square-plus"></i>
@T("Admin.Common.AddNew") @T("Admin.Common.AddNew")
</a> </a>
<a asp-action="BulkEdit" class="btn btn-info"> <a asp-action="BulkEdit" class="btn btn-info">
<i class="fas fa-pen"></i> <i class="fas fa-pen"></i>
@T("Admin.Catalog.Products.BulkEdit") @T("Admin.Catalog.Products.BulkEdit")
</a> </a>
<button asp-action="DownloadCatalogPDF" type="submit" name="download-catalog-pdf" class="btn bg-purple"> <button asp-action="DownloadCatalogPDF" type="submit" name="download-catalog-pdf" class="btn bg-purple">
<i class="far fa-file-pdf"></i> <i class="far fa-file-pdf"></i>
@T("Admin.Catalog.Products.List.DownloadPDF") @T("Admin.Catalog.Products.List.DownloadPDF")
</button> </button>
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-success"> <button type="button" class="btn btn-success">
<i class="fas fa-download"></i> <i class="fas fa-download"></i>
@T("Admin.Common.Export") @T("Admin.Common.Export")
</button> </button>
<button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span> <span class="caret"></span>
<span class="sr-only">&nbsp;</span> <span class="sr-only">&nbsp;</span>
</button> </button>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li class="dropdown-item"> <li class="dropdown-item">
<button asp-action="ExportToXml" type="submit" name="exportxml-all"> <button asp-action="ExportToXml" type="submit" name="exportxml-all">
<i class="far fa-file-code"></i> <i class="far fa-file-code"></i>
@T("Admin.Common.ExportToXml.All") @T("Admin.Common.ExportToXml.All")
</button> </button>
</li> </li>
<li class="dropdown-item"> <li class="dropdown-item">
<button type="button" id="exportxml-selected"> <button type="button" id="exportxml-selected">
<i class="far fa-file-code"></i> <i class="far fa-file-code"></i>
@T("Admin.Common.ExportToXml.Selected") @T("Admin.Common.ExportToXml.Selected")
</button> </button>
</li> </li>
<li class="dropdown-divider"></li> <li class="dropdown-divider"></li>
<li class="dropdown-item"> <li class="dropdown-item">
<button asp-action="ExportToExcel" type="submit" name="exportexcel-all"> <button asp-action="ExportToExcel" type="submit" name="exportexcel-all">
<i class="far fa-file-excel"></i> <i class="far fa-file-excel"></i>
@T("Admin.Common.ExportToExcel.All") @T("Admin.Common.ExportToExcel.All")
</button> </button>
</li> </li>
<li class="dropdown-item"> <li class="dropdown-item">
<button type="button" id="exportexcel-selected"> <button type="button" id="exportexcel-selected">
<i class="far fa-file-excel"></i> <i class="far fa-file-excel"></i>
@T("Admin.Common.ExportToExcel.Selected") @T("Admin.Common.ExportToExcel.Selected")
</button> </button>
</li> </li>
</ul> </ul>
</div> </div>
@if (!Model.IsLoggedInAsVendor || Model.AllowVendorsToImportProducts) @if (!Model.IsLoggedInAsVendor || Model.AllowVendorsToImportProducts)
{ {
//a vendor cannot import products //a vendor cannot import products
<button type="button" name="importexcel" class="btn bg-olive" data-toggle="modal" data-target="#importexcel-window"> <button type="button" name="importexcel" class="btn bg-olive" data-toggle="modal" data-target="#importexcel-window">
<i class="fas fa-upload"></i> <i class="fas fa-upload"></i>
@T("Admin.Common.Import") @T("Admin.Common.Import")
</button> </button>
} }
<button type="button" id="delete-selected" class="btn btn-danger"> <button type="button" id="delete-selected" class="btn btn-danger">
<i class="far fa-trash-can"></i> <i class="far fa-trash-can"></i>
@T("Admin.Common.Delete.Selected") @T("Admin.Common.Delete.Selected")
</button> </button>
<nop-action-confirmation asp-button-id="delete-selected" /> <nop-action-confirmation asp-button-id="delete-selected" />
@await Component.InvokeAsync(typeof(AdminWidgetViewComponent), new { widgetZone = AdminWidgetZones.ProductListButtons, additionalData = Model }) @await Component.InvokeAsync(typeof(AdminWidgetViewComponent), new { widgetZone = AdminWidgetZones.ProductListButtons, additionalData = Model })
</div> </div>
</div> </div>
<section class="content"> <section class="content">
<div class="container-fluid"> <div class="container-fluid">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="cards-group"> <div class="cards-group">
<div class="card card-default card-search"> <div class="card card-default card-search">
<div class="card-body"> <div class="card-body">
<div class="row search-row @(!hideSearchBlock ? "opened" : "")" data-hideAttribute="@hideSearchBlockAttributeName"> <div class="row search-row @(!hideSearchBlock ? "opened" : "")" data-hideAttribute="@hideSearchBlockAttributeName">
<div class="search-text">@T("Admin.Common.Search")</div> <div class="search-text">@T("Admin.Common.Search")</div>
<div class="icon-search"><i class="fas fa-magnifying-glass" aria-hidden="true"></i></div> <div class="icon-search"><i class="fas fa-magnifying-glass" aria-hidden="true"></i></div>
<div class="icon-collapse"><i class="far fa-angle-@(!hideSearchBlock ? "up" : "down")" aria-hidden="true"></i></div> <div class="icon-collapse"><i class="far fa-angle-@(!hideSearchBlock ? "up" : "down")" aria-hidden="true"></i></div>
</div> </div>
<div class="search-body @(hideSearchBlock ? "closed" : "")"> <div class="search-body @(hideSearchBlock ? "closed" : "")">
<div class="row"> <div class="row">
<div class="col-md-5"> <div class="col-md-5">
<div class="form-group row"> <div class="form-group row">
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="SearchProductName" /> <nop-label asp-for="SearchProductName" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<nop-editor asp-for="SearchProductName" /> <nop-editor asp-for="SearchProductName" />
</div> </div>
</div> </div>
<div class="form-group row" @(Model.AvailableCategories.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)> <div class="form-group row" @(Model.AvailableCategories.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)>
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="SearchCategoryId" /> <nop-label asp-for="SearchCategoryId" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<nop-select asp-for="SearchCategoryId" asp-items="Model.AvailableCategories" /> <nop-select asp-for="SearchCategoryId" asp-items="Model.AvailableCategories" />
</div> </div>
</div> </div>
<div class="form-group row" @(Model.AvailableCategories.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)> <div class="form-group row" @(Model.AvailableCategories.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)>
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="SearchIncludeSubCategories" /> <nop-label asp-for="SearchIncludeSubCategories" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<nop-editor asp-for="SearchIncludeSubCategories" /> <nop-editor asp-for="SearchIncludeSubCategories" />
</div> </div>
</div> </div>
<div class="form-group row" @(Model.AvailableManufacturers.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)> <div class="form-group row" @(Model.AvailableManufacturers.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)>
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="SearchManufacturerId" /> <nop-label asp-for="SearchManufacturerId" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<nop-select asp-for="SearchManufacturerId" asp-items="Model.AvailableManufacturers" /> <nop-select asp-for="SearchManufacturerId" asp-items="Model.AvailableManufacturers" />
</div> </div>
</div> </div>
<div class="form-group row" @(Model.AvailableVendors.SelectionIsNotPossible() || Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)> <div class="form-group row" @(Model.AvailableVendors.SelectionIsNotPossible() || Model.IsLoggedInAsVendor ? Html.Raw("style='display: none;'") : null)>
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="SearchVendorId" /> <nop-label asp-for="SearchVendorId" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<nop-select asp-for="SearchVendorId" asp-items="Model.AvailableVendors" /> <nop-select asp-for="SearchVendorId" asp-items="Model.AvailableVendors" />
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-7"> <div class="col-md-7">
<div class="form-group row" @(Model.HideStoresList ? Html.Raw("style=\"display:none\"") : null)> <div class="form-group row" @(Model.HideStoresList? Html.Raw("style=\"display:none\"") : null)>
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="SearchStoreId" /> <nop-label asp-for="SearchStoreId" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<nop-select asp-for="SearchStoreId" asp-items="Model.AvailableStores" /> <nop-select asp-for="SearchStoreId" asp-items="Model.AvailableStores" />
</div> </div>
</div> </div>
<div class="form-group row" @(Model.AvailableWarehouses.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)> <div class="form-group row" @(Model.AvailableWarehouses.SelectionIsNotPossible() ? Html.Raw("style=\"display:none\"") : null)>
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="SearchWarehouseId" /> <nop-label asp-for="SearchWarehouseId" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<nop-select asp-for="SearchWarehouseId" asp-items="Model.AvailableWarehouses" /> <nop-select asp-for="SearchWarehouseId" asp-items="Model.AvailableWarehouses" />
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="SearchProductTypeId" /> <nop-label asp-for="SearchProductTypeId" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<nop-select asp-for="SearchProductTypeId" asp-items="Model.AvailableProductTypes" /> <nop-select asp-for="SearchProductTypeId" asp-items="Model.AvailableProductTypes" />
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="SearchPublishedId" /> <nop-label asp-for="SearchPublishedId" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<nop-select asp-for="SearchPublishedId" asp-items="Model.AvailablePublishedOptions" /> <nop-select asp-for="SearchPublishedId" asp-items="Model.AvailablePublishedOptions" />
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-md-4"> <div class="col-md-4">
<nop-label asp-for="GoDirectlyToSku" /> <nop-label asp-for="GoDirectlyToSku" />
</div> </div>
<div class="col-md-8"> <div class="col-md-8">
<div class="input-group input-group-short"> <div class="input-group input-group-short">
<nop-editor asp-for="GoDirectlyToSku" /> <nop-editor asp-for="GoDirectlyToSku" />
<span class="input-group-append"> <span class="input-group-append">
<button type="submit" id="go-to-product-by-sku" name="go-to-product-by-sku" class="btn btn-info btn-flat"> <button type="submit" id="go-to-product-by-sku" name="go-to-product-by-sku" class="btn btn-info btn-flat">
@T("Admin.Common.Go") @T("Admin.Common.Go")
</button> </button>
</span> </span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="text-center col-12"> <div class="text-center col-12">
<button type="button" id="search-products" class="btn btn-primary btn-search"> <button type="button" id="search-products" class="btn btn-primary btn-search">
<i class="fas fa-magnifying-glass"></i> <i class="fas fa-magnifying-glass"></i>
@T("Admin.Common.Search") @T("Admin.Common.Search")
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="card card-default"> <div class="card card-default">
<div class="card-body"> <div class="card-body">
<nop-doc-reference asp-string-resource="@T("Admin.Documentation.Reference.Products", Docs.Products + Utm.OnAdmin)" /> <nop-doc-reference asp-string-resource="@T("Admin.Documentation.Reference.Products", Docs.Products + Utm.OnAdmin)" />
@await Html.PartialAsync("Table", new DataTablesModel @await Html.PartialAsync("Table", new DataTablesModel
{ {
Name = "products-grid", Name = "products-grid",
UrlRead = new DataUrl("ProductList", "CustomProduct", null), UrlRead = new DataUrl("ProductList", "CustomProduct", null),
SearchButtonId = "search-products", SearchButtonId = "search-products",
Length = Model.PageSize, Length = Model.PageSize,
LengthMenu = Model.AvailablePageSizes, LengthMenu = Model.AvailablePageSizes,
Filters = new List<FilterParameter> Filters = new List<FilterParameter>
{ {
new FilterParameter(nameof(Model.SearchProductName)), new FilterParameter(nameof(Model.SearchProductName)),
new FilterParameter(nameof(Model.SearchCategoryId)), new FilterParameter(nameof(Model.SearchCategoryId)),
new FilterParameter(nameof(Model.SearchIncludeSubCategories), typeof(bool)), new FilterParameter(nameof(Model.SearchIncludeSubCategories), typeof(bool)),
new FilterParameter(nameof(Model.SearchManufacturerId)), new FilterParameter(nameof(Model.SearchManufacturerId)),
new FilterParameter(nameof(Model.SearchStoreId)), new FilterParameter(nameof(Model.SearchStoreId)),
new FilterParameter(nameof(Model.SearchWarehouseId)), new FilterParameter(nameof(Model.SearchWarehouseId)),
new FilterParameter(nameof(Model.SearchVendorId)), new FilterParameter(nameof(Model.SearchVendorId)),
new FilterParameter(nameof(Model.SearchProductTypeId)), new FilterParameter(nameof(Model.SearchProductTypeId)),
new FilterParameter(nameof(Model.SearchPublishedId)) new FilterParameter(nameof(Model.SearchPublishedId))
}, },
ColumnCollection = new List<ColumnProperty> ColumnCollection = new List<ColumnProperty>
{ {
new ColumnProperty(nameof(ProductModel.Id)) new ColumnProperty(nameof(ProductModel.Id))
{ {
IsMasterCheckBox = true, IsMasterCheckBox = true,
Render = new RenderCheckBox("checkbox_products"), Render = new RenderCheckBox("checkbox_products"),
ClassName = NopColumnClassDefaults.CenterAll, ClassName = NopColumnClassDefaults.CenterAll,
Width = "50" Width = "40"
}, },
new ColumnProperty(nameof(ProductModel.PictureThumbnailUrl)) new ColumnProperty(nameof(ProductModel.PictureThumbnailUrl))
{ {
Title = T("Admin.Catalog.Products.Fields.PictureThumbnailUrl").Text, Title = T("Admin.Catalog.Products.Fields.PictureThumbnailUrl").Text,
Width = "100", Width = "100",
Render = new RenderPicture(width: 100) Render = new RenderPicture(width: 100),
}, Visible = false
new ColumnProperty(nameof(ProductModel.Name)) },
{ new ColumnProperty(nameof(ProductModel.Name))
Title = T("Admin.Catalog.Products.Fields.Name").Text {
}, Title = T("Admin.Catalog.Products.Fields.Name").Text
new ColumnProperty(nameof(ProductModel.Sku)) },
{ new ColumnProperty(nameof(ProductModel.Sku))
Title = T("Admin.Catalog.Products.Fields.Sku").Text, {
Width = "100" Title = "SKU", //T("Admin.Catalog.Products.Fields.Sku").Text,
}, Width = "100"
new ColumnProperty(nameof(ProductModel.FormattedPrice)) },
{ new ColumnProperty(nameof(ProductModel.FormattedPrice))
Title = T("Admin.Catalog.Products.Fields.Price").Text {
}, Title = T("Admin.Catalog.Products.Fields.Price").Text
new ColumnProperty(nameof(ProductModel.StockQuantityStr)) },
{ new ColumnProperty(nameof(ProductModel.StockQuantityStr))
Title = T("Admin.Catalog.Products.Fields.StockQuantity").Text {
}, Title = T("Admin.Catalog.Products.Fields.StockQuantity").Text
new ColumnProperty(nameof(ProductModel.Published)) },
{ new ColumnProperty(nameof(ProductModelExtended.NetWeight))
Title = T("Admin.Catalog.Products.Fields.Published").Text, {
Width = "80", Title = "Súly(kg)"//T("Admin.Catalog.Products.Fields.NetWeight").Text
ClassName = NopColumnClassDefaults.CenterAll, },
Render = new RenderBoolean() new ColumnProperty(nameof(ProductModelExtended.Tare))
}, {
new ColumnProperty(nameof(ProductModel.Id)) Title = "Tára(kg)"//T("Admin.Catalog.Products.Fields.Tare").Text
{ },
Title = T("Admin.Common.Edit").Text, new ColumnProperty(nameof(ProductModelExtended.IncomingQuantity))
Width = "80", {
ClassName = NopColumnClassDefaults.Button, Title = "Bejövő"//T("Admin.Catalog.Products.Fields.Tare").Text
Render = new RenderButtonEdit(new DataUrl("~/Admin/Product/Edit")) },
} new ColumnProperty(nameof(ProductModelExtended.IsMeasurable))
} {
}) Title = "Mérendő?",//T("Admin.Catalog.Products.Fields.Tare").Text
Width = "75",
ClassName = NopColumnClassDefaults.CenterAll,
Render = new RenderBoolean()
},
new ColumnProperty(nameof(ProductModel.Published))
{
Title = T("Admin.Catalog.Products.Fields.Published").Text,
Width = "75",
ClassName = NopColumnClassDefaults.CenterAll,
Render = new RenderBoolean()
},
new ColumnProperty(nameof(ProductModel.Id))
{
Title = T("Admin.Common.Edit").Text,
Width = "80",
ClassName = NopColumnClassDefaults.Button,
Render = new RenderButtonEdit(new DataUrl("~/Admin/Product/Edit"))
}
}
})
<script> <script>
$(function() {
$('#delete-selected-action-confirmation-submit-button').bind('click', function () {
var postData = {
selectedIds: selectedIds
};
addAntiForgeryToken(postData);
$.ajax({
cache: false,
type: "POST",
url: "@(Url.Action("DeleteSelected", "Product"))",
data: postData,
error: function (jqXHR, textStatus, errorThrown) {
showAlert('deleteSelectedFailed', errorThrown);
},
complete: function (jqXHR, textStatus) {
if (jqXHR.status === 204)
{
showAlert('nothingSelectedAlert', '@T("Admin.Common.Alert.NothingSelected")');
return;
}
updateTable('#products-grid');
}
});
$('#delete-selected-action-confirmation').modal('toggle');
return false;
});
});
</script> $(function() {
<nop-alert asp-alert-id="deleteSelectedFailed" /> $('#delete-selected-action-confirmation-submit-button').bind('click', function () {
<nop-alert asp-alert-id="nothingSelectedAlert" /> var postData = {
</div> selectedIds: selectedIds
</div> };
</div> addAntiForgeryToken(postData);
</div> $.ajax({
</div> cache: false,
</section> type: "POST",
<script> url: "@(Url.Action("DeleteSelected", "Product"))",
$(function() { data: postData,
$("#@Html.IdFor(model => model.GoDirectlyToSku)").keydown(function (event) { error: function (jqXHR, textStatus, errorThrown) {
if (event.keyCode === 13) { showAlert('deleteSelectedFailed', errorThrown);
$("#go-to-product-by-sku").trigger("click"); },
return false; complete: function (jqXHR, textStatus) {
} if (jqXHR.status === 204)
}); {
}); showAlert('nothingSelectedAlert', '@T("Admin.Common.Alert.NothingSelected")');
</script> return;
}
updateTable('#products-grid');
}
});
$('#delete-selected-action-confirmation').modal('toggle');
return false;
});
});
</script>
<nop-alert asp-alert-id="deleteSelectedFailed" />
<nop-alert asp-alert-id="nothingSelectedAlert" />
</div>
</div>
</div>
</div>
</div>
</section>
<script>
$(function() {
$("#@Html.IdFor(model => model.GoDirectlyToSku)").keydown(function (event) {
if (event.keyCode === 13) {
$("#go-to-product-by-sku").trigger("click");
return false;
}
});
});
</script>
</form> </form>
} }
<script> <script>
$(function() { $(function() {
var displayModal = @((Model.LicenseCheckModel?.DisplayWarning == true || Model.LicenseCheckModel?.BlockPages == true).ToString().ToLower()); var displayModal = @((Model.LicenseCheckModel?.DisplayWarning == true || Model.LicenseCheckModel?.BlockPages == true).ToString().ToLower());
if (displayModal) { if (displayModal) {
$('#license-window').modal({ $('#license-window').modal({
backdrop: 'static', backdrop: 'static',
keyboard: false keyboard: false
}); });
$('#license-window').on('shown.bs.modal', function (event) { $('#license-window').on('shown.bs.modal', function (event) {
var modalCloseEl = $(this).find('button.close'); var modalCloseEl = $(this).find('button.close');
var closeTextEl = $('span', modalCloseEl); var closeTextEl = $('span', modalCloseEl);
var startFrom = 5; var startFrom = 5;
closeTextEl.text(startFrom); closeTextEl.text(startFrom);
const timer = setInterval(function() { const timer = setInterval(function() {
if (startFrom-- > 0) if (startFrom-- > 0)
closeTextEl.text(startFrom); closeTextEl.text(startFrom);
}, 1000); }, 1000);
setTimeout(function() { setTimeout(function() {
closeTextEl.html('&times;'); closeTextEl.html('&times;');
modalCloseEl.on('click', function() { modalCloseEl.on('click', function() {
$('#license-window').modal('hide') $('#license-window').modal('hide')
}); });
clearInterval(timer); clearInterval(timer);
}, startFrom*1000); }, startFrom*1000);
}); });
} }
}); });
</script> </script>
<div id="license-window" class="modal fade" tabindex="-1" role="dialog"> <div id="license-window" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<div class="modal-content"> <div class="modal-content">
@Html.Raw(Model.LicenseCheckModel?.WarningText) @Html.Raw(Model.LicenseCheckModel?.WarningText)
</div> </div>
</div> </div>
</div> </div>
@*import products form*@ @*import products form*@
<div id="importexcel-window" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="importexcel-window-title"> <div id="importexcel-window" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="importexcel-window-title">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h4 class="modal-title" id="importexcel-window-title">@T("Admin.Common.ImportFromExcel")</h4> <h4 class="modal-title" id="importexcel-window-title">@T("Admin.Common.ImportFromExcel")</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
</div> </div>
<form asp-controller="Product" asp-action="ImportExcel" method="post" enctype="multipart/form-data"> <form asp-controller="Product" asp-action="ImportExcel" method="post" enctype="multipart/form-data">
<div class="form-horizontal"> <div class="form-horizontal">
<div class="modal-body"> <div class="modal-body">
<ul class="common-list"> <ul class="common-list">
<li> <li>
<em>@T("Admin.Catalog.Products.List.ImportFromExcelTip")</em> <em>@T("Admin.Catalog.Products.List.ImportFromExcelTip")</em>
</li> </li>
<li> <li>
<em>@T("Admin.Common.ImportFromExcel.ManyRecordsWarning")</em> <em>@T("Admin.Common.ImportFromExcel.ManyRecordsWarning")</em>
</li> </li>
</ul> </ul>
<div class="form-group row"> <div class="form-group row">
<div class="col-md-2"> <div class="col-md-2">
<div class="label-wrapper"> <div class="label-wrapper">
<label class="col-form-label"> <label class="col-form-label">
@T("Admin.Common.ExcelFile") @T("Admin.Common.ExcelFile")
</label> </label>
</div> </div>
</div> </div>
<div class="col-md-10"> <div class="col-md-10">
<input type="file" id="importexcelfile" name="importexcelfile" class="form-control" /> <input type="file" id="importexcelfile" name="importexcelfile" class="form-control" />
</div> </div>
</div> </div>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="submit" class="btn btn-primary"> <button type="submit" class="btn btn-primary">
@T("Admin.Common.ImportFromExcel") @T("Admin.Common.ImportFromExcel")
</button> </button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</div> </div>
</div> </div>
@*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*@
<form asp-controller="Product" asp-action="ExportXmlSelected" method="post" id="export-xml-selected-form"> <form asp-controller="Product" asp-action="ExportXmlSelected" method="post" id="export-xml-selected-form">
<input type="hidden" id="selectedIds" name="selectedIds" value="" /> <input type="hidden" id="selectedIds" name="selectedIds" value="" />
</form> </form>
<script> <script>
$(function() { $(function() {
$('#exportxml-selected').click(function (e) { $('#exportxml-selected').click(function (e) {
e.preventDefault(); e.preventDefault();
var ids = selectedIds.join(","); var ids = selectedIds.join(",");
if (!ids) { if (!ids) {
$('#exportXmlSelected-info').text("@T("Admin.Products.NoProducts")"); $('#exportXmlSelected-info').text("@T("Admin.Products.NoProducts")");
$("#exportXmlSelected").trigger("click"); $("#exportXmlSelected").trigger("click");
} }
else { else {
$('#export-xml-selected-form #selectedIds').val(ids); $('#export-xml-selected-form #selectedIds').val(ids);
$('#export-xml-selected-form').submit(); $('#export-xml-selected-form').submit();
updateTable('#products-grid'); updateTable('#products-grid');
} }
return false; return false;
}); });
}); });
</script> </script>
<nop-alert asp-alert-id="exportXmlSelected" /> <nop-alert asp-alert-id="exportXmlSelected" />
@*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*@
<form asp-controller="Product" asp-action="ExportExcelSelected" method="post" id="export-excel-selected-form"> <form asp-controller="Product" asp-action="ExportExcelSelected" method="post" id="export-excel-selected-form">
<input type="hidden" id="selectedIds" name="selectedIds" value="" /> <input type="hidden" id="selectedIds" name="selectedIds" value="" />
</form> </form>
<script> <script>
$(function() { $(function() {
$('#exportexcel-selected').click(function (e) { $('#exportexcel-selected').click(function (e) {
e.preventDefault(); e.preventDefault();
var ids = selectedIds.join(","); var ids = selectedIds.join(",");
if (!ids) { if (!ids) {
$('#exportExcelSelected-info').text("@T("Admin.Products.NoProducts")"); $('#exportExcelSelected-info').text("@T("Admin.Products.NoProducts")");
$("#exportExcelSelected").trigger("click"); $("#exportExcelSelected").trigger("click");
} }
else { else {
$('#export-excel-selected-form #selectedIds').val(ids); $('#export-excel-selected-form #selectedIds').val(ids);
$('#export-excel-selected-form').submit(); $('#export-excel-selected-form').submit();
updateTable('#products-grid'); updateTable('#products-grid');
} }
return false; return false;
}); });
}); });
</script> </script>
<nop-alert asp-alert-id="exportExcelSelected" /> <nop-alert asp-alert-id="exportExcelSelected" />

View File

@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Mvc;
using Nop.Core; using Nop.Core;
using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Orders; 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.Plugin.Misc.FruitBankPlugin.Services;
using Nop.Services.Common; using Nop.Services.Common;
using Nop.Web.Areas.Admin.Models.Catalog; using Nop.Web.Areas.Admin.Models.Catalog;
@ -37,7 +37,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Components
if (model.OrderId > 0) if (model.OrderId > 0)
{ {
var orderPickupAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Order, DateTime?>(model.OrderId, nameof(IOrderDto.DateOfReceipt)); var orderPickupAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Order, DateTime?>(model.OrderId, nameof(IOrderDto.DateOfReceipt));
var orderMeasurableAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Order, bool>(model.OrderId, nameof(OrderModelExtended.IsMeasurable)); var orderMeasurableAttributeValue = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Order, bool>(model.OrderId, nameof(IMeasurable.IsMeasurable));
model.IsMeasurable = orderMeasurableAttributeValue; model.IsMeasurable = orderMeasurableAttributeValue;
if(orderPickupAttributeValue.HasValue && orderPickupAttributeValue.Value != DateTime.MinValue) if(orderPickupAttributeValue.HasValue && orderPickupAttributeValue.Value != DateTime.MinValue)

View File

@ -42,7 +42,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Components
} }
model.Tare = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Product, double>(model.ProductId, nameof(ITare.Tare)); model.Tare = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Product, double>(model.ProductId, nameof(ITare.Tare));
model.IncomingQuantity = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Product, int>(model.ProductId, "IncomingQuantity"); model.IncomingQuantity = await _fruitBankAttributeService.GetGenericAttributeValueAsync<Product, int>(model.ProductId, nameof(IIncomingQuantity.IncomingQuantity));
} }
return View("~/Plugins/Misc.FruitBankPlugin/Views/ProductAttributes.cshtml", model); return View("~/Plugins/Misc.FruitBankPlugin/Views/ProductAttributes.cshtml", model);

View File

@ -45,6 +45,8 @@ public class FruitBankDbContext : MgDbContextBase,
private readonly IProductService _productService; private readonly IProductService _productService;
private readonly IStaticCacheManager _staticCacheManager; private readonly IStaticCacheManager _staticCacheManager;
public ProductDtoDbTable ProductDtos { get; set; }
public OrderDtoDbTable OrderDtos { get; set; } public OrderDtoDbTable OrderDtos { get; set; }
public OrderItemDtoDbTable OrderItemDtos { get; set; } public OrderItemDtoDbTable OrderItemDtos { get; set; }
@ -67,7 +69,7 @@ public class FruitBankDbContext : MgDbContextBase,
public FruitBankDbContext(INopDataProvider dataProvider, ILockService lockService, FruitBankAttributeService fruitBankAttributeService, IStoreContext storeContext, public FruitBankDbContext(INopDataProvider dataProvider, ILockService lockService, FruitBankAttributeService fruitBankAttributeService, IStoreContext storeContext,
PartnerDbTable partnerDbTable, ShippingDbTable shippingDbTable, ShippingDocumentDbTable shippingDocumentDbTable, ShippingItemDbTable shippingItemDbTable, PartnerDbTable partnerDbTable, ShippingDbTable shippingDbTable, ShippingDocumentDbTable shippingDocumentDbTable, ShippingItemDbTable shippingItemDbTable,
ShippingItemPalletDbTable shippingItemPalletDbTable, FilesDbTable filesDbTable, ShippingDocumentToFilesDbTable shippingDocumentToFilesDbTable, ShippingItemPalletDbTable shippingItemPalletDbTable, FilesDbTable filesDbTable, ShippingDocumentToFilesDbTable shippingDocumentToFilesDbTable,
OrderDtoDbTable orderDtoDbTable, OrderItemDtoDbTable orderItemDtoDbTable, OrderItemPalletDbTable orderItemPalletDbTable, ProductDtoDbTable productDtoDbTable, OrderDtoDbTable orderDtoDbTable, OrderItemDtoDbTable orderItemDtoDbTable, OrderItemPalletDbTable orderItemPalletDbTable,
IProductService productService, IStaticCacheManager staticCacheManager, IProductService productService, IStaticCacheManager staticCacheManager,
IRepository<Product> productRepository, IRepository<Product> productRepository,
IRepository<Customer> customerRepository, IRepository<Customer> customerRepository,
@ -84,6 +86,8 @@ public class FruitBankDbContext : MgDbContextBase,
Partners = partnerDbTable; Partners = partnerDbTable;
Products = productRepository; Products = productRepository;
ProductDtos = productDtoDbTable;
OrderDtos = orderDtoDbTable; OrderDtos = orderDtoDbTable;
OrderItemDtos = orderItemDtoDbTable; OrderItemDtos = orderItemDtoDbTable;
OrderItemPallets = orderItemPalletDbTable; OrderItemPallets = orderItemPalletDbTable;

View File

@ -11,27 +11,6 @@ using Nop.Services.Logging;
namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
public class OrderItemDtoDbTable : MgDbTableBase<OrderItemDto>
{
public OrderItemDtoDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger)
: base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger)
{
}
public IQueryable<OrderItemDto> 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<OrderItemDto> GetByIdAsync(int orderItemId) => GetAll(true).Where(x => x.Id == orderItemId).FirstOrDefaultAsync(null);
public IQueryable<OrderItemDto> GetAllByOrderId(int orderId)=> GetAll(true).Where(o => o.OrderId == orderId);
}
public class OrderDtoDbTable : MgDbTableBase<OrderDto> public class OrderDtoDbTable : MgDbTableBase<OrderDto>
{ {
public OrderDtoDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger) public OrderDtoDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger)

View File

@ -0,0 +1,31 @@
using FruitBank.Common.Dtos;
using LinqToDB;
using Mango.Nop.Core.Repositories;
using Nop.Core.Caching;
using Nop.Core.Configuration;
using Nop.Core.Events;
using Nop.Data;
using Nop.Services.Logging;
namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
public class OrderItemDtoDbTable : MgDbTableBase<OrderItemDto>
{
public OrderItemDtoDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger)
: base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger)
{
}
public IQueryable<OrderItemDto> 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<OrderItemDto> GetByIdAsync(int orderItemId) => GetAll(true).Where(x => x.Id == orderItemId).FirstOrDefaultAsync(null);
public IQueryable<OrderItemDto> GetAllByOrderId(int orderId)=> GetAll(true).Where(o => o.OrderId == orderId);
}

View File

@ -0,0 +1,27 @@
using FruitBank.Common.Dtos;
using LinqToDB;
using Mango.Nop.Core.Repositories;
using Nop.Core.Caching;
using Nop.Core.Configuration;
using Nop.Core.Events;
using Nop.Data;
using Nop.Services.Logging;
namespace Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
public class ProductDtoDbTable : MgDbTableBase<ProductDto>
{
public ProductDtoDbTable(IEventPublisher eventPublisher, INopDataProvider dataProvider, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, AppSettings appSettings, ILogger logger)
: base(eventPublisher, dataProvider, shortTermCacheManager, staticCacheManager, appSettings, logger)
{
}
public IQueryable<ProductDto> GetAll(bool loadRelations)
{
return GetAll().LoadWith(p => p.GenericAttributes);
}
public Task<ProductDto> GetByIdAsync(int productId) => GetAll(true).Where(x => x.Id == productId).FirstOrDefaultAsync(null);
public IQueryable<ProductDto> GetAllByIds(IEnumerable<int> productIds) => GetAll(true).Where(p => productIds.Contains(p.Id));
}

View File

@ -25,7 +25,7 @@ public class ShippingDbTable : MgDbTableBase<Shipping>
? GetAll() ? GetAll()
.LoadWith(s => s.ShippingDocuments).ThenLoad(sd => sd.ShippingItems).ThenLoad(si => si.ShippingItemPallets) .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.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.ShippingDocumentToFiles).ThenLoad(sdtof => sdtof.ShippingDocumentFile)
.LoadWith(s => s.ShippingDocuments).ThenLoad(sd => sd.Partner) .LoadWith(s => s.ShippingDocuments).ThenLoad(sd => sd.Partner)
: GetAll(); : GetAll();

View File

@ -25,7 +25,7 @@ public class ShippingDocumentDbTable : MgDbTableBase<ShippingDocument>
? GetAll() ? GetAll()
.LoadWith(sd => sd.Shipping) .LoadWith(sd => sd.Shipping)
.LoadWith(sd => sd.ShippingItems).ThenLoad(si => si.Pallet) .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.ShippingItems).ThenLoad(si => si.ShippingItemPallets)
.LoadWith(sd => sd.ShippingDocumentToFiles).ThenLoad(sdtof => sdtof.ShippingDocumentFile) .LoadWith(sd => sd.ShippingDocumentToFiles).ThenLoad(sdtof => sdtof.ShippingDocumentFile)
.LoadWith(sd => sd.Partner) .LoadWith(sd => sd.Partner)

View File

@ -38,9 +38,9 @@ public class ShippingItemDbTable : MgDbTableBase<ShippingItem>
.LoadWith(si => si.ShippingDocument).ThenLoad(p => p.Partner) .LoadWith(si => si.ShippingDocument).ThenLoad(p => p.Partner)
.LoadWith(si => si.ShippingDocument).ThenLoad(sd => sd.ShippingDocumentToFiles).ThenLoad(sdtof => sdtof.ShippingDocumentFile) .LoadWith(si => si.ShippingDocument).ThenLoad(sd => sd.ShippingDocumentToFiles).ThenLoad(sdtof => sdtof.ShippingDocumentFile)
.LoadWith(si => si.ShippingItemPallets) .LoadWith(si => si.ShippingItemPallets)
.LoadWith(si => si.Product) .LoadWith(si => si.ProductDto).ThenLoad(prod => prod.GenericAttributes)
.LoadWith(si => si.Pallet) .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<ShippingItem> GetAllNotMeasured(bool loadRelations) public IQueryable<ShippingItem> GetAllNotMeasured(bool loadRelations)

View File

@ -81,12 +81,12 @@ public class FruitBankEventConsumer(IHttpContextAccessor httpContextAcc, FruitBa
await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, double>(product.Id, nameof(ITare.Tare), tare); await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, double>(product.Id, nameof(ITare.Tare), tare);
} }
if (form.ContainsKey("IncomingQuantity")) if (form.ContainsKey(nameof(IIncomingQuantity.IncomingQuantity)))
{ {
var incomingQuantity = CommonHelper.To<int>(form["IncomingQuantity"].ToString()); var incomingQuantity = CommonHelper.To<int>(form[nameof(IIncomingQuantity.IncomingQuantity)].ToString());
if (incomingQuantity < 0) throw new Exception($"FruitBankEventConsumer->SaveProductCustomAttributesAsync(); (incomingQuantity < 0); productId: {product.Id}; incomingQuantity: {incomingQuantity}"); if (incomingQuantity < 0) throw new Exception($"FruitBankEventConsumer->SaveProductCustomAttributesAsync(); (incomingQuantity < 0); productId: {product.Id}; incomingQuantity: {incomingQuantity}");
await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, int>(product.Id, "IncomingQuantity", incomingQuantity); await fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync<Product, int>(product.Id, nameof(IIncomingQuantity.IncomingQuantity), incomingQuantity);
} }
} }

View File

@ -11,7 +11,6 @@ using Nop.Core.Domain.Orders;
using Nop.Core.Domain.Shipping; using Nop.Core.Domain.Shipping;
using Nop.Core.Domain.Tax; using Nop.Core.Domain.Tax;
using Nop.Plugin.Misc.FruitBankPlugin.Helpers; using Nop.Plugin.Misc.FruitBankPlugin.Helpers;
using Nop.Plugin.Misc.FruitBankPlugin.Models;
using Nop.Plugin.Misc.FruitBankPlugin.Services; using Nop.Plugin.Misc.FruitBankPlugin.Services;
using Nop.Services.Affiliates; using Nop.Services.Affiliates;
using Nop.Services.Catalog; using Nop.Services.Catalog;
@ -37,15 +36,18 @@ using System.Collections;
using System.Reflection; using System.Reflection;
using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.Arm;
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; 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 namespace Nop.Plugin.Misc.FruitBankPlugin.Factories
{ {
public class CustomOrderModelFactory : OrderModelFactory public class CustomOrderModelFactory : MgOrderModelFactory<OrderListModelExtended, OrderModelExtended>
{ {
private FruitBankDbContext _ctx; private FruitBankDbContext _ctx;
private readonly IOrderMeasurementService _orderMeasurementService; private readonly IOrderMeasurementService _orderMeasurementService;
private readonly IGenericAttributeService _genericAttributeService;
#region Ctor
public CustomOrderModelFactory( public CustomOrderModelFactory(
FruitBankDbContext ctx, FruitBankDbContext ctx,
IOrderMeasurementService orderMeasurementService, IOrderMeasurementService orderMeasurementService,
@ -139,40 +141,17 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Factories
orderSettings, orderSettings,
shippingSettings, shippingSettings,
urlRecordService, urlRecordService,
taxSettings taxSettings,
genericAttributeService
) )
{ {
_ctx = ctx; _ctx = ctx;
_orderMeasurementService = orderMeasurementService; _orderMeasurementService = orderMeasurementService;
_genericAttributeService = genericAttributeService;
} }
#endregion Ctor
public override async Task<OrderSearchModel> PrepareOrderSearchModelAsync(OrderSearchModel searchModel) public override async Task<OrderSearchModel> PrepareOrderSearchModelAsync(OrderSearchModel searchModel)
{ {
// let base prepare default model first
var baseModel = await base.PrepareOrderSearchModelAsync(searchModel); 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; return baseModel;
} }
@ -181,18 +160,14 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Factories
public async Task<OrderListModelExtended> PrepareOrderListModelExtendedAsync(OrderSearchModel searchModel) public async Task<OrderListModelExtended> PrepareOrderListModelExtendedAsync(OrderSearchModel searchModel)
{ {
var orderListModel = await PrepareOrderListModelAsync(searchModel); Dictionary<int, OrderDto> orderDtosById = null;
var extendedRows = new List<OrderModelExtended>(orderListModel.RecordsFiltered);
var orderDtosById = await _ctx.OrderDtos.GetAllByIds(orderListModel.Data.Select(x => x.Id)).ToDictionaryAsync(k => k.Id, v => v); var orderListModelExtended = await base.PrepareOrderListModelExtendedAsync(searchModel, async (orderListModel, orderModelExtended) =>
foreach (var orderModel in orderListModel.Data)
{ {
var orderDto = orderDtosById[orderModel.Id]; orderDtosById ??= await _ctx.OrderDtos.GetAllByIds(orderListModel.Data.Select(x => x.Id)).ToDictionaryAsync(k => k.Id, v => v);
var orderDto = orderDtosById[orderModelExtended.Id];
var orderModelExtended = new OrderModelExtended();
PropertyHelper.CopyPublicValueTypeProperties(orderModel, orderModelExtended);
orderModelExtended.IsMeasured = orderDto.IsMeasured;
orderModelExtended.IsMeasurable = orderDto.IsMeasurable; orderModelExtended.IsMeasurable = orderDto.IsMeasurable;
orderModelExtended.DateOfReceipt = orderDto.DateOfReceipt; orderModelExtended.DateOfReceipt = orderDto.DateOfReceipt;
@ -200,13 +175,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Factories
//orderModelExtended.DateOfReceipt = await GetPickupDateTimeAsync(orderModel); //orderModelExtended.DateOfReceipt = await GetPickupDateTimeAsync(orderModel);
Console.WriteLine(orderModelExtended.Id); Console.WriteLine(orderModelExtended.Id);
extendedRows.Add(orderModelExtended); });
}
orderListModel.Data = null;
var orderListModelExtended = orderListModel.ToJson().JsonTo<OrderListModelExtended>();
orderListModelExtended.Data = extendedRows;
return orderListModelExtended; return orderListModelExtended;
} }
@ -232,7 +201,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Factories
var fullOrder = await _orderService.GetOrderByIdAsync(order.Id); var fullOrder = await _orderService.GetOrderByIdAsync(order.Id);
if (fullOrder != null) if (fullOrder != null)
{ {
dateTime = await _genericAttributeService.GetAttributeAsync<DateTime>(fullOrder, nameof(IOrderDto.DateOfReceipt)); dateTime = await GenericAttributeService.GetAttributeAsync<DateTime>(fullOrder, nameof(IOrderDto.DateOfReceipt));
if(dateTime == DateTime.MinValue || !dateTime.HasValue) if(dateTime == DateTime.MinValue || !dateTime.HasValue)
{ {
dateTime = null; dateTime = null;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,170 @@
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<TOrderListModelExt, TOrderModelExt> : 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<OrderSearchModel> PrepareOrderSearchModelAsync(OrderSearchModel searchModel)
=> base.PrepareOrderSearchModelAsync(searchModel);
public override Task<OrderListModel> PrepareOrderListModelAsync(OrderSearchModel searchModel)
=> base.PrepareOrderListModelAsync(searchModel);
public virtual async Task<TOrderListModelExt> PrepareOrderListModelExtendedAsync(OrderSearchModel searchModel, Func<OrderListModel, TOrderModelExt, Task> dataItemCopiedCallback)
{
var orderListModel = await PrepareOrderListModelAsync(searchModel);
var extendedRows = new List<TOrderModelExt>(orderListModel.RecordsFiltered);
foreach (var orderModel in orderListModel.Data.ToList())
{
var orderModelExtended = Activator.CreateInstance<TOrderModelExt>();
PropertyHelper.CopyPublicValueTypeProperties(orderModel, orderModelExtended);
extendedRows.Add(orderModelExtended);
if (dataItemCopiedCallback == null) continue;
await dataItemCopiedCallback.Invoke(orderListModel, orderModelExtended);
}
orderListModel.Data = null;
var orderListModelExtended = orderListModel.ToJson().JsonTo<TOrderListModelExt>();
orderListModelExtended.Data = extendedRows;
return orderListModelExtended;
}
}

View File

@ -0,0 +1,164 @@
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<TProductListModelExt, TProductModelExt> : 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<ProductSearchModel> PrepareProductSearchModelAsync(ProductSearchModel searchModel)
=> base.PrepareProductSearchModelAsync(searchModel);
public override Task<ProductListModel> PrepareProductListModelAsync(ProductSearchModel searchModel)
=> base.PrepareProductListModelAsync(searchModel);
public virtual async Task<TProductListModelExt> PrepareProductListModelExtendedAsync(ProductSearchModel searchModel, Func<ProductListModel, TProductModelExt, Task> dataItemCopiedCallback)
{
var productListModel = await PrepareProductListModelAsync(searchModel);
var extendedRows = new List<TProductModelExt>(productListModel.RecordsFiltered);
foreach (var productModel in productListModel.Data.ToList())
{
var productModelExtended = Activator.CreateInstance<TProductModelExt>();
PropertyHelper.CopyPublicValueTypeProperties(productModel, productModelExtended);
extendedRows.Add(productModelExtended);
if (dataItemCopiedCallback == null) continue;
await dataItemCopiedCallback.Invoke(productListModel, productModelExtended);
}
productListModel.Data = null;
var productListModelExtended = productListModel.ToJson().JsonTo<TProductListModelExt>();
productListModelExtended.Data = extendedRows;
return productListModelExtended;
}
}

View File

@ -58,6 +58,7 @@ public class PluginNopStartup : INopStartup
services.AddScoped<FruitBankAttributeService>(); services.AddScoped<FruitBankAttributeService>();
services.AddScoped<ProductDtoDbTable>();
services.AddScoped<OrderDtoDbTable>(); services.AddScoped<OrderDtoDbTable>();
services.AddScoped<OrderItemDtoDbTable>(); services.AddScoped<OrderItemDtoDbTable>();
services.AddScoped<OrderItemPalletDbTable>(); services.AddScoped<OrderItemPalletDbTable>();
@ -86,6 +87,7 @@ public class PluginNopStartup : INopStartup
//services.AddScoped<OrderSearchModel, OrderSearchModelExtended>(); //services.AddScoped<OrderSearchModel, OrderSearchModelExtended>();
services.AddScoped<IOrderModelFactory, CustomOrderModelFactory>(); services.AddScoped<IOrderModelFactory, CustomOrderModelFactory>();
services.AddScoped<IProductModelFactory, CustomProductModelFactory>();
services.AddScoped<IGenericAttributeService, GenericAttributeService>(); services.AddScoped<IGenericAttributeService, GenericAttributeService>();
services.AddScoped<CerebrasAPIService>(); services.AddScoped<CerebrasAPIService>();
services.AddScoped<OpenAIApiService>(); services.AddScoped<OpenAIApiService>();

View File

@ -1,8 +0,0 @@
using Nop.Web.Framework.Models;
namespace Nop.Plugin.Misc.FruitBankPlugin.Models;
public interface IOrderListModelExtended<T>: IPagedModel<T> where T : BaseNopModel
{
public bool? NeedsMeasurement { get; set; }
}

View File

@ -0,0 +1,7 @@
using Nop.Web.Framework.Models;
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase;
public interface IMgListModelExtended<T>: IPagedModel<T> where T : BaseNopModel, IMgModelExtended
{
}

View File

@ -0,0 +1,5 @@
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase;
public interface IMgModelExtended
{
}

View File

@ -0,0 +1,5 @@
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels;
public interface IMgOrderListModelExtended<T>: IMgListModelExtended<T> where T : MgOrderModelExtended
{
}

View File

@ -0,0 +1,5 @@
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels;
public interface IMgOrderModelExtended : IMgModelExtended
{
}

View File

@ -0,0 +1,8 @@
using Nop.Web.Framework.Models;
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels;
public partial record MgOrderListModelExtended<TOrderModelExt> : BasePagedListModel<TOrderModelExt>, IMgOrderListModelExtended<TOrderModelExt>
where TOrderModelExt: MgOrderModelExtended
{
}

View File

@ -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
{
}

View File

@ -0,0 +1,5 @@
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels;
public interface IMgProductListModelExtended<T>: IMgListModelExtended<T> where T : MgProductModelExtended
{
}

View File

@ -0,0 +1,5 @@
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels;
public interface IMgProductModelExtended : IMgModelExtended
{
}

View File

@ -0,0 +1,8 @@
using Nop.Web.Framework.Models;
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels;
public partial record MgProductListModelExtended<TProductModelExt> : BasePagedListModel<TProductModelExt>, IMgProductListModelExtended<TProductModelExt>
where TProductModelExt: MgProductModelExtended
{
}

View File

@ -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
{
}

View File

@ -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<OrderModelExtended>, IOrderListModelExtended<OrderModelExtended>
{
public bool? NeedsMeasurement { get; set; }
}
}

View File

@ -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; }
}
}

View File

@ -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; }
}
}

View File

@ -0,0 +1,7 @@
using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.OrderModels;
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Orders;
public interface IOrderListModelExtended: IMgOrderListModelExtended<OrderModelExtended>
{
}

View File

@ -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; }
}

View File

@ -2,7 +2,7 @@
using Nop.Web.Framework.Models; using Nop.Web.Framework.Models;
using Nop.Web.Framework.Mvc.ModelBinding; using Nop.Web.Framework.Mvc.ModelBinding;
namespace Nop.Plugin.Misc.FruitBankPlugin.Models namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Orders
{ {
public record OrderAttributesModel : BaseNopModel, IMeasurable public record OrderAttributesModel : BaseNopModel, IMeasurable
{ {

View File

@ -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<OrderModelExtended>, IOrderListModelExtended
{
}
}

View File

@ -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; }
}
}

View File

@ -4,7 +4,7 @@ using Nop.Web.Framework.Mvc.ModelBinding;
namespace Nop.Plugin.Misc.FruitBankPlugin.Models 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; } public int ProductId { get; set; }
@ -18,7 +18,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Models
public double GrossWeight { get; set; } public double GrossWeight { get; set; }
[NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.IncomingQuantity")] [NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.IncomingQuantity")]
public int? IncomingQuantity { get; set; } public int IncomingQuantity { get; set; }
[NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.Tare")] [NopResourceDisplayName("Plugins.YourCompany.ProductAttributes.Fields.Tare")]
public double Tare { get; set; } public double Tare { get; set; }

View File

@ -0,0 +1,9 @@

using Nop.Plugin.Misc.FruitBankPlugin.Models.MgBase.ProductModels;
namespace Nop.Plugin.Misc.FruitBankPlugin.Models.Products;
public interface IProductListModelExtended: IMgProductListModelExtended<ProductModelExtended>
{
}

View File

@ -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
{
}

View File

@ -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<ProductModelExtended>, IProductListModelExtended
{
}
}

View File

@ -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; }
}
}

View File

@ -3,7 +3,7 @@ using FruitBank.Common.Interfaces;
using Nop.Core; using Nop.Core;
using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Catalog;
using Nop.Core.Domain.Orders; using Nop.Core.Domain.Orders;
using Nop.Plugin.Misc.FruitBankPlugin.Models; using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders;
using Nop.Services.Catalog; using Nop.Services.Catalog;
using Nop.Services.Common; using Nop.Services.Common;
using Nop.Services.Events; using Nop.Services.Events;
@ -114,7 +114,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
var store = await _storeContext.GetCurrentStoreAsync(); var store = await _storeContext.GetCurrentStoreAsync();
// itt adjuk hozzá a GenericAttribute flag-et az orderhez // itt adjuk hozzá a GenericAttribute flag-et az orderhez
await _genericAttributeService.SaveAttributeAsync(order, await _genericAttributeService.SaveAttributeAsync(order,
nameof(OrderModelExtended.IsMeasurable), true, store.Id); nameof(IMeasurable.IsMeasurable), true, store.Id);
// status pending // status pending
// paymentstatus pending // paymentstatus pending
} }

View File

@ -1,5 +1,6 @@
using Nop.Core.Domain.Orders; using FruitBank.Common.Interfaces;
using Nop.Plugin.Misc.FruitBankPlugin.Models; using Nop.Core.Domain.Orders;
using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders;
using Nop.Services.Common; using Nop.Services.Common;
namespace Nop.Plugin.Misc.FruitBankPlugin.Services namespace Nop.Plugin.Misc.FruitBankPlugin.Services
@ -24,7 +25,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services
return false; return false;
return await _genericAttributeService.GetAttributeAsync<bool>( return await _genericAttributeService.GetAttributeAsync<bool>(
order, nameof(OrderModelExtended.IsMeasurable), order.StoreId); order, nameof(IMeasurable.IsMeasurable), order.StoreId);
} }
} }
} }

View File

@ -1,4 +1,5 @@
@model Nop.Plugin.Misc.FruitBankPlugin.Models.OrderAttributesModel @using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders
@model OrderAttributesModel
<div class="card card-default"> <div class="card card-default">
<div class="card-header"> <div class="card-header">