From ce2853b3e8d0c5b89eda912c84a1d2bb6516c2d1 Mon Sep 17 00:00:00 2001 From: KrzysztofPajak Date: Fri, 13 Aug 2021 08:28:14 +0200 Subject: [PATCH] Improvements - Admin panel - Allow to edit alt and title attribute for the picture in a separate window --- .../Views/Product/ProductPicturePopup.cshtml | 74 +++++++ .../Product/_CreateOrUpdate.Pictures.cshtml | 9 +- .../Controllers/ProductController.cs | 172 +++++++-------- .../Interfaces/IProductViewModelService.cs | 3 +- .../Services/ProductViewModelService.cs | 202 +++++++----------- .../App_Data/Resources/DefaultLanguage.xml | 3 + 6 files changed, 240 insertions(+), 223 deletions(-) create mode 100644 src/Web/Grand.Web.Admin/Areas/Admin/Views/Product/ProductPicturePopup.cshtml diff --git a/src/Web/Grand.Web.Admin/Areas/Admin/Views/Product/ProductPicturePopup.cshtml b/src/Web/Grand.Web.Admin/Areas/Admin/Views/Product/ProductPicturePopup.cshtml new file mode 100644 index 000000000..badb0888e --- /dev/null +++ b/src/Web/Grand.Web.Admin/Areas/Admin/Views/Product/ProductPicturePopup.cshtml @@ -0,0 +1,74 @@ + +@model ProductModel.ProductPictureModel +@{ + Layout = Grand.Web.Admin.Extensions.Constants.Layout_AdminPopup; + //page title + ViewBag.Title = Loc["Admin.Catalog.Products.Pictures.Details"]; +} +
+ +
+ + + + +
+
+
+
+
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+ @if (ViewBag.RefreshPage == true) + { + + } +
\ No newline at end of file diff --git a/src/Web/Grand.Web.Admin/Areas/Admin/Views/Product/_CreateOrUpdate.Pictures.cshtml b/src/Web/Grand.Web.Admin/Areas/Admin/Views/Product/_CreateOrUpdate.Pictures.cshtml index 5328d605f..289ea057a 100644 --- a/src/Web/Grand.Web.Admin/Areas/Admin/Views/Product/_CreateOrUpdate.Pictures.cshtml +++ b/src/Web/Grand.Web.Admin/Areas/Admin/Views/Product/_CreateOrUpdate.Pictures.cshtml @@ -75,7 +75,7 @@ columns: [{ field: "PictureUrl", title: "@Loc["Admin.Catalog.Products.Pictures.Fields.Picture"]", - template: '#=PictureId#', + template: "#=PictureId#", width: 165 }, { field: "DisplayOrder", @@ -95,13 +95,6 @@ minScreenWidth: 500, }, { command: [{ - name: "edit", - text: { - edit: "@Loc["Admin.Common.Edit"]", - update: "@Loc["Admin.Common.Update"]", - cancel: "@Loc["Admin.Common.Cancel"]" - } - }, { name: "destroy", text: "@Loc["Admin.Common.Delete"]" }], diff --git a/src/Web/Grand.Web.Admin/Controllers/ProductController.cs b/src/Web/Grand.Web.Admin/Controllers/ProductController.cs index 8a8d86245..60402ab30 100644 --- a/src/Web/Grand.Web.Admin/Controllers/ProductController.cs +++ b/src/Web/Grand.Web.Admin/Controllers/ProductController.cs @@ -138,8 +138,7 @@ public async Task List() public async Task ProductList(DataSourceRequest command, ProductListModel model) { var (productModels, totalCount) = await _productViewModelService.PrepareProductsModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = productModels.ToList(), Total = totalCount }; @@ -404,8 +403,7 @@ public async Task RequiredProductAddPopup(string productIdsInput) public async Task RequiredProductAddPopupList(DataSourceRequest command, ProductModel.AddRequiredProductModel model) { var (products, totalCount) = await _productViewModelService.PrepareProductModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = products.ToList(), Total = totalCount }; @@ -427,8 +425,7 @@ public async Task ProductCategoryList(DataSourceRequest command, return ErrorForKendoGridJson(permission.message); var productCategoriesModel = await _productViewModelService.PrepareProductCategoryModel(product); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = productCategoriesModel, Total = productCategoriesModel.Count }; @@ -501,8 +498,7 @@ public async Task ProductCollectionList(DataSourceRequest command return ErrorForKendoGridJson(permission.message); var productCollectionsModel = await _productViewModelService.PrepareProductCollectionModel(product); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = productCollectionsModel, Total = productCollectionsModel.Count }; @@ -578,8 +574,7 @@ public async Task RelatedProductList(DataSourceRequest command, s var relatedProductsModel = new List(); foreach (var x in relatedProducts) { - relatedProductsModel.Add(new ProductModel.RelatedProductModel - { + relatedProductsModel.Add(new ProductModel.RelatedProductModel { Id = x.Id, ProductId1 = productId, ProductId2 = x.ProductId2, @@ -588,8 +583,7 @@ public async Task RelatedProductList(DataSourceRequest command, s }); } - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = relatedProductsModel, Total = relatedProductsModel.Count }; @@ -634,8 +628,7 @@ public async Task RelatedProductAddPopup(string productId) public async Task RelatedProductAddPopupList(DataSourceRequest command, ProductModel.AddRelatedProductModel model) { var (products, totalCount) = await _productViewModelService.PrepareProductModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = products.ToList(), Total = totalCount }; @@ -685,8 +678,7 @@ public async Task SimilarProductList(DataSourceRequest command, s var similarProductsModel = new List(); foreach (var x in similarProducts) { - similarProductsModel.Add(new ProductModel.SimilarProductModel - { + similarProductsModel.Add(new ProductModel.SimilarProductModel { Id = x.Id, ProductId1 = productId, ProductId2 = x.ProductId2, @@ -695,8 +687,7 @@ public async Task SimilarProductList(DataSourceRequest command, s }); } - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = similarProductsModel, Total = similarProductsModel.Count }; @@ -741,8 +732,7 @@ public async Task SimilarProductAddPopup(string productId) public async Task SimilarProductAddPopupList(DataSourceRequest command, ProductModel.AddSimilarProductModel model) { var (products, totalCount) = await _productViewModelService.PrepareProductModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = products.ToList(), Total = totalCount }; @@ -791,8 +781,7 @@ public async Task BundleProductList(DataSourceRequest command, st var bundleProductsModel = new List(); foreach (var x in bundleProducts) { - bundleProductsModel.Add(new ProductModel.BundleProductModel - { + bundleProductsModel.Add(new ProductModel.BundleProductModel { Id = x.Id, ProductBundleId = productId, ProductId = x.ProductId, @@ -801,8 +790,7 @@ public async Task BundleProductList(DataSourceRequest command, st Quantity = x.Quantity }); } - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = bundleProductsModel, Total = bundleProductsModel.Count }; @@ -847,8 +835,7 @@ public async Task BundleProductAddPopup(string productId) public async Task BundleProductAddPopupList(DataSourceRequest command, ProductModel.AddBundleProductModel model) { var (products, totalCount) = await _productViewModelService.PrepareProductModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = products.ToList(), Total = totalCount }; @@ -898,15 +885,13 @@ public async Task CrossSellProductList(DataSourceRequest command, var crossSellProductsModel = new List(); foreach (var x in crossSellProducts) { - crossSellProductsModel.Add(new ProductModel.CrossSellProductModel - { + crossSellProductsModel.Add(new ProductModel.CrossSellProductModel { Id = x, ProductId = product.Id, Product2Name = (await _productService.GetProductById(x))?.Name, }); } - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = crossSellProductsModel, Total = crossSellProductsModel.Count }; @@ -948,8 +933,7 @@ public async Task CrossSellProductAddPopup(string productId) public async Task CrossSellProductAddPopupList(DataSourceRequest command, ProductModel.AddCrossSellProductModel model) { var (products, totalCount) = await _productViewModelService.PrepareProductModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = products.ToList(), Total = totalCount }; @@ -1100,8 +1084,7 @@ public async Task AssociatedProductList(DataSourceRequest command vendorId: vendorId, showHidden: true); var associatedProductsModel = associatedProducts - .Select(x => new ProductModel.AssociatedProductModel - { + .Select(x => new ProductModel.AssociatedProductModel { Id = x.Id, ProductId = productId, ProductName = x.Name, @@ -1109,8 +1092,7 @@ public async Task AssociatedProductList(DataSourceRequest command }) .ToList(); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = associatedProductsModel, Total = associatedProductsModel.Count }; @@ -1165,8 +1147,7 @@ public async Task AssociatedProductAddPopup(string productId) public async Task AssociatedProductAddPopupList(DataSourceRequest command, ProductModel.AddAssociatedProductModel model) { var (products, totalCount) = await _productViewModelService.PrepareProductModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = products.ToList(), Total = totalCount }; @@ -1202,8 +1183,8 @@ public async Task AssociatedProductAddPopup(ProductModel.AddAssoc [HttpPost] [IgnoreAntiforgeryToken] - public async Task ProductPictureAdd(Reference reference, string objectId, - [FromServices] IPictureService pictureService, + public async Task ProductPictureAdd(Reference reference, string objectId, + [FromServices] IPictureService pictureService, [FromServices] MediaSettings mediaSettings) { if (!await _permissionService.Authorize(PermissionSystemName.Pictures)) @@ -1211,7 +1192,7 @@ public async Task AssociatedProductAddPopup(ProductModel.AddAssoc { success = false, message = "Access denied - picture permissions", - }); + }); if (reference != Reference.Product || string.IsNullOrEmpty(objectId)) return Json(new @@ -1330,9 +1311,8 @@ public async Task ProductPictureList(DataSourceRequest command, s if (!permission.allow) return ErrorForKendoGridJson(permission.message); - var productPicturesModel = await _productViewModelService.PrepareProductPictureModel(product); - var gridModel = new DataSourceResult - { + var productPicturesModel = await _productViewModelService.PrepareProductPicturesModel(product); + var gridModel = new DataSourceResult { Data = productPicturesModel, Total = productPicturesModel.Count }; @@ -1340,18 +1320,50 @@ public async Task ProductPictureList(DataSourceRequest command, s return Json(gridModel); } + [PermissionAuthorizeAction(PermissionActionName.Preview)] + public async Task ProductPicturePopup(string productId, string id) + { + var product = await _productService.GetProductById(productId); + if (product == null) + return Content("Product not exist"); + + var permission = await CheckAccessToProduct(product); + if (!permission.allow) + return Content(permission.message); + + var pp = product.ProductPictures.FirstOrDefault(x => x.Id == id); + if (pp == null) + return Content("Product picture not exist"); + + var model = await _productViewModelService.PrepareProductPictureModel(product, pp); + return View(model); + } + [PermissionAuthorizeAction(PermissionActionName.Edit)] [HttpPost] - public async Task ProductPictureUpdate(ProductModel.ProductPictureModel model) + public async Task ProductPicturePopup(ProductModel.ProductPictureModel model) { if (ModelState.IsValid) { + var product = await _productService.GetProductById(model.ProductId); + if (product == null) + throw new ArgumentException("No product found with the specified id"); + + if (product.ProductPictures.FirstOrDefault(x => x.Id == model.Id) == null) + throw new ArgumentException("No product picture found with the specified id"); + await _productViewModelService.UpdateProductPicture(model); - return new JsonResult(""); + + ViewBag.RefreshPage = true; + return View(model); } - return ErrorForKendoGridJson(ModelState); + + Error(ModelState); + + return View(model); } + [PermissionAuthorizeAction(PermissionActionName.Edit)] [HttpPost] public async Task ProductPictureDelete(ProductModel.ProductPictureModel model) @@ -1406,8 +1418,7 @@ public async Task ProductSpecAttrList(DataSourceRequest command, return ErrorForKendoGridJson(permission.message); var productrSpecsModel = await _productViewModelService.PrepareProductSpecificationAttributeModel(product); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = productrSpecsModel, Total = productrSpecsModel.Count }; @@ -1464,8 +1475,7 @@ public async Task ProductSpecAttrDelete(ProductSpecificationAttri [FromServices] IOrderViewModelService orderViewModelService) { if (!await _permissionService.Authorize(StandardPermission.ManageOrders)) - return Json(new DataSourceResult - { + return Json(new DataSourceResult { Data = null, Total = 0 }); @@ -1476,8 +1486,7 @@ public async Task ProductSpecAttrDelete(ProductSpecificationAttri if (!permission.allow) return ErrorForKendoGridJson(permission.message); - var model = new OrderListModel - { + var model = new OrderListModel { ProductId = productId }; @@ -1487,8 +1496,7 @@ public async Task ProductSpecAttrDelete(ProductSpecificationAttri model.VendorId = _workContext.CurrentVendor.Id; var (orderModels, totalCount) = await orderViewModelService.PrepareOrderModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = orderModels.ToList(), Total = totalCount }; @@ -1524,8 +1532,7 @@ public async Task Reviews(DataSourceRequest command, string produ await _productViewModelService.PrepareProductReviewModel(m, item, false, true); items.Add(m); } - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = items, Total = productReviews.Count, }; @@ -1623,8 +1630,7 @@ public async Task BulkEdit() public async Task BulkEditSelect(DataSourceRequest command, BulkEditListModel model) { var (bulkEditProductModels, totalCount) = await _productViewModelService.PrepareBulkEditProductModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = bulkEditProductModels.ToList(), Total = totalCount }; @@ -1670,16 +1676,14 @@ public async Task ProductPriceList(DataSourceRequest command, str var items = new List(); foreach (var item in product.ProductPrices) { - items.Add(new ProductModel.ProductPriceModel() - { + items.Add(new ProductModel.ProductPriceModel() { Id = item.Id, CurrencyCode = item.CurrencyCode, Price = item.Price }); } - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = items, Total = items.Count }; @@ -1702,8 +1706,7 @@ public async Task ProductPriceInsert(string productId, ProductMod { try { - await _productService.InsertProductPrice(new ProductPrice() - { + await _productService.InsertProductPrice(new ProductPrice() { ProductId = product.Id, CurrencyCode = model.CurrencyCode, Price = model.Price, @@ -1790,8 +1793,7 @@ public async Task TierPriceList(DataSourceRequest command, string return ErrorForKendoGridJson(permission.message); var tierPricesModel = await _productViewModelService.PrepareTierPriceModel(product); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = tierPricesModel, Total = tierPricesModel.Count }; @@ -1801,8 +1803,7 @@ public async Task TierPriceList(DataSourceRequest command, string [PermissionAuthorizeAction(PermissionActionName.Edit)] public async Task TierPriceCreatePopup(string productId) { - var model = new ProductModel.TierPriceModel - { + var model = new ProductModel.TierPriceModel { ProductId = productId }; await _productViewModelService.PrepareTierPriceModel(model); @@ -1915,8 +1916,7 @@ public async Task ProductAttributeMappingList(DataSourceRequest c return ErrorForKendoGridJson(permission.message); var attributesModel = await _productViewModelService.PrepareProductAttributeMappingModels(product); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = attributesModel, Total = attributesModel.Count }; @@ -2113,8 +2113,7 @@ public async Task EditAttributeValues(string productAttributeMapp return Content("This is not your product"); } var productAttribute = await productAttributeService.GetProductAttributeById(productAttributeMapping.ProductAttributeId); - var model = new ProductModel.ProductAttributeValueListModel - { + var model = new ProductModel.ProductAttributeValueListModel { ProductName = product.Name, ProductId = product.Id, ProductAttributeName = productAttribute.Name, @@ -2139,8 +2138,7 @@ public async Task ProductAttributeValueList(string productAttribu throw new ArgumentException("No product attribute mapping found with the specified id"); var values = await _productViewModelService.PrepareProductAttributeValueModels(product, productAttributeMapping); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = values, Total = values.Count() }; @@ -2314,8 +2312,7 @@ public async Task AssociateProductToAttributeValuePopup() ProductModel.ProductAttributeValueModel.AssociateProductToAttributeValueModel model) { var (products, totalCount) = await _productViewModelService.PrepareProductModel(model, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = products.ToList(), Total = totalCount }; @@ -2356,8 +2353,7 @@ public async Task ProductAttributeCombinationList(DataSourceReque return ErrorForKendoGridJson(permission.message); var combinationsModel = await _productViewModelService.PrepareProductAttributeCombinationModel(product); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = combinationsModel, Total = combinationsModel.Count }; @@ -2511,8 +2507,7 @@ public async Task ProductAttributeCombinationTierPriceList(DataSo return ErrorForKendoGridJson(permission.message); var tierPriceModel = await _productViewModelService.PrepareProductAttributeCombinationTierPricesModel(product, productAttributeCombinationId); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = tierPriceModel, Total = tierPriceModel.Count }; @@ -2610,8 +2605,7 @@ public async Task ListActivityLog(DataSourceRequest command, stri return ErrorForKendoGridJson(permission.message); var (activityLogModels, totalCount) = await _productViewModelService.PrepareActivityLogModel(productId, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = activityLogModels.ToList(), Total = totalCount }; @@ -2634,8 +2628,7 @@ public async Task ListReservations(DataSourceRequest command, str var reservations = await _productReservationService.GetProductReservationsByProductId(productId, null, null, command.Page - 1, command.PageSize); var reservationModel = reservations - .Select(x => new ProductModel.ReservationModel - { + .Select(x => new ProductModel.ReservationModel { ReservationId = x.Id, Date = x.Date, OrderId = x.OrderId, @@ -2645,8 +2638,7 @@ public async Task ListReservations(DataSourceRequest command, str Duration = x.Duration }).ToList(); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = reservationModel, Total = reservations.TotalCount }; @@ -2784,8 +2776,7 @@ public async Task GenerateCalendar(string productId, ProductModel if (counter++ > 1000) break; - await _productReservationService.InsertProductReservation(new ProductReservation - { + await _productReservationService.InsertProductReservation(new ProductReservation { OrderId = "", Date = iterator, ProductId = productId, @@ -2899,8 +2890,7 @@ public async Task ListBids(DataSourceRequest command, string prod return Json(new { errors = _translationService.GetResource("Admin.Catalog.Products.Permisions") }); var (bidModels, totalCount) = await _productViewModelService.PrepareBidMode(productId, command.Page, command.PageSize); - var gridModel = new DataSourceResult - { + var gridModel = new DataSourceResult { Data = bidModels.ToList(), Total = totalCount }; diff --git a/src/Web/Grand.Web.Admin/Interfaces/IProductViewModelService.cs b/src/Web/Grand.Web.Admin/Interfaces/IProductViewModelService.cs index 8906caaa1..c92f56e06 100644 --- a/src/Web/Grand.Web.Admin/Interfaces/IProductViewModelService.cs +++ b/src/Web/Grand.Web.Admin/Interfaces/IProductViewModelService.cs @@ -99,7 +99,8 @@ public interface IProductViewModelService Task DeleteProductAttributeCombinationTierPrices(Product product, ProductAttributeCombination productAttributeCombination, ProductCombinationTierPrices tierPrice); //Pictures - Task> PrepareProductPictureModel(Product product); + Task> PrepareProductPicturesModel(Product product); + Task PrepareProductPictureModel(Product product, ProductPicture productPicture); Task InsertProductPicture(Product product, Picture picture, int displayOrder, string overrideAltAttribute, string overrideTitleAttribute); Task UpdateProductPicture(ProductModel.ProductPictureModel model); Task DeleteProductPicture(ProductModel.ProductPictureModel model); diff --git a/src/Web/Grand.Web.Admin/Services/ProductViewModelService.cs b/src/Web/Grand.Web.Admin/Services/ProductViewModelService.cs index 0d7a1346c..9c2a67c2f 100644 --- a/src/Web/Grand.Web.Admin/Services/ProductViewModelService.cs +++ b/src/Web/Grand.Web.Admin/Services/ProductViewModelService.cs @@ -222,8 +222,7 @@ protected virtual async Task SaveProductTags(Product product, string[] productTa if (productTag2 == null) { //add new product tag - productTag = new ProductTag - { + productTag = new ProductTag { Name = productTagName, SeName = SeoExtensions.GetSeName(productTagName, seoSettings.ConvertNonWesternChars, seoSettings.AllowUnicodeCharsInUrls, seoSettings.SeoCharConversion), Count = 0, @@ -259,8 +258,7 @@ public virtual async Task PrepareAddProductAttributeCombinationModel(ProductAttr foreach (var attribute in attributes) { var productAttribute = await _productAttributeService.GetProductAttributeById(attribute.ProductAttributeId); - var attributeModel = new ProductAttributeCombinationModel.ProductAttributeModel - { + var attributeModel = new ProductAttributeCombinationModel.ProductAttributeModel { Id = attribute.Id, ProductAttributeId = attribute.ProductAttributeId, Name = productAttribute.Name, @@ -275,8 +273,7 @@ public virtual async Task PrepareAddProductAttributeCombinationModel(ProductAttr var attributeValues = attribute.ProductAttributeValues; foreach (var attributeValue in attributeValues) { - var attributeValueModel = new ProductAttributeCombinationModel.ProductAttributeValueModel - { + var attributeValueModel = new ProductAttributeCombinationModel.ProductAttributeValueModel { Id = attributeValue.Id, Name = attributeValue.Name, IsPreSelected = attributeValue.IsPreSelected, @@ -297,8 +294,7 @@ public virtual async Task PrepareAddProductAttributeCombinationModel(ProductAttr } foreach (var picture in product.ProductPictures) { - model.ProductPictureModels.Add(new ProductModel.ProductPictureModel - { + model.ProductPictureModels.Add(new ProductModel.ProductPictureModel { Id = picture.Id, ProductId = product.Id, PictureId = picture.PictureId, @@ -333,8 +329,7 @@ public virtual async Task PrepareProductAttributeValueModel(Product product, Pro //pictures foreach (var x in product.ProductPictures.OrderBy(x => x.DisplayOrder)) { - model.ProductPictureModels.Add(new ProductModel.ProductPictureModel - { + model.ProductPictureModels.Add(new ProductModel.ProductPictureModel { Id = x.Id, ProductId = product.Id, PictureId = x.PictureId, @@ -460,8 +455,7 @@ public virtual async Task OutOfStockNotifications(Product product, ProductAttrib //product attributes foreach (var productAttribute in await _productAttributeService.GetAllProductAttributes()) { - model.AvailableProductAttributes.Add(new SelectListItem - { + model.AvailableProductAttributes.Add(new SelectListItem { Text = productAttribute.Name, Value = productAttribute.Id.ToString() }); @@ -472,8 +466,7 @@ public virtual async Task OutOfStockNotifications(Product product, ProductAttrib var availableSpecificationAttributes = new List(); foreach (var sa in await _specificationAttributeService.GetSpecificationAttributes()) { - availableSpecificationAttributes.Add(new SelectListItem - { + availableSpecificationAttributes.Add(new SelectListItem { Text = sa.Name, Value = sa.Id.ToString() }); @@ -498,8 +491,7 @@ public virtual async Task OutOfStockNotifications(Product product, ProductAttrib var layouts = await _productLayoutService.GetAllProductLayouts(); foreach (var layout in layouts) { - model.AvailableProductLayouts.Add(new SelectListItem - { + model.AvailableProductLayouts.Add(new SelectListItem { Text = layout.Name, Value = layout.Id }); @@ -509,16 +501,14 @@ public virtual async Task OutOfStockNotifications(Product product, ProductAttrib model.IsLoggedInAsVendor = _workContext.CurrentVendor != null; //delivery dates - model.AvailableDeliveryDates.Add(new SelectListItem - { + model.AvailableDeliveryDates.Add(new SelectListItem { Text = _translationService.GetResource("Admin.Catalog.Products.Fields.DeliveryDate.None"), Value = "" }); var deliveryDates = await _deliveryDateService.GetAllDeliveryDates(); foreach (var deliveryDate in deliveryDates) { - model.AvailableDeliveryDates.Add(new SelectListItem - { + model.AvailableDeliveryDates.Add(new SelectListItem { Text = deliveryDate.Name, Value = deliveryDate.Id.ToString() }); @@ -526,15 +516,13 @@ public virtual async Task OutOfStockNotifications(Product product, ProductAttrib //warehouses var warehouses = await _warehouseService.GetAllWarehouses(); - model.AvailableWarehouses.Add(new SelectListItem - { + model.AvailableWarehouses.Add(new SelectListItem { Text = _translationService.GetResource("Admin.Catalog.Products.Fields.Warehouse.None"), Value = "" }); foreach (var warehouse in warehouses) { - model.AvailableWarehouses.Add(new SelectListItem - { + model.AvailableWarehouses.Add(new SelectListItem { Text = warehouse.Name, Value = warehouse.Id.ToString() }); @@ -543,8 +531,7 @@ public virtual async Task OutOfStockNotifications(Product product, ProductAttrib //multiple warehouses foreach (var warehouse in warehouses) { - var pwiModel = new ProductModel.ProductWarehouseInventoryModel - { + var pwiModel = new ProductModel.ProductWarehouseInventoryModel { WarehouseId = warehouse.Id, WarehouseName = warehouse.Name }; @@ -672,8 +659,7 @@ public virtual async Task SaveProductWarehouseInventory(Product product, IList

PrepareProductListModel() { - var model = new ProductListModel - { + var model = new ProductListModel { //a vendor should have access only to his products IsLoggedInAsVendor = _workContext.CurrentVendor != null }; @@ -779,7 +764,7 @@ public virtual async Task<(IEnumerable productModels, int totalCou } //limit for store manager - if(!string.IsNullOrEmpty(_workContext.CurrentCustomer.StaffStoreId)) + if (!string.IsNullOrEmpty(_workContext.CurrentCustomer.StaffStoreId)) model.SearchStoreId = _workContext.CurrentCustomer.StaffStoreId; var categoryIds = new List(); @@ -1071,8 +1056,7 @@ public virtual async Task DeleteSelected(IList selectedIds) } public virtual async Task PrepareAddRequiredProductModel() { - var model = new ProductModel.AddRequiredProductModel - { + var model = new ProductModel.AddRequiredProductModel { //a vendor should have access only to his products IsLoggedInAsVendor = _workContext.CurrentVendor != null }; @@ -1203,8 +1187,7 @@ public virtual async Task> PrepareProdu foreach (var x in productCategories) { var category = await _categoryService.GetCategoryById(x.CategoryId); - items.Add(new ProductModel.ProductCategoryModel - { + items.Add(new ProductModel.ProductCategoryModel { Id = x.Id, Category = await _categoryService.GetFormattedBreadCrumb(category), ProductId = product.Id, @@ -1229,8 +1212,7 @@ public virtual async Task InsertProductCategoryModel(ProductModel.ProductCategor if (product.ProductCategories.Where(x => x.CategoryId == model.CategoryId).Count() == 0) { - var productCategory = new ProductCategory - { + var productCategory = new ProductCategory { CategoryId = model.CategoryId, DisplayOrder = model.DisplayOrder, }; @@ -1291,8 +1273,7 @@ public virtual async Task> PreparePro var items = new List(); foreach (var x in product.ProductCollections.OrderBy(x => x.DisplayOrder)) { - items.Add(new ProductModel.ProductCollectionModel - { + items.Add(new ProductModel.ProductCollectionModel { Id = x.Id, Collection = (await _collectionService.GetCollectionById(x.CollectionId)).Name, ProductId = product.Id, @@ -1319,8 +1300,7 @@ public virtual async Task InsertProductCollection(ProductModel.ProductCollection var existingProductcollections = product.ProductCollections; if (product.ProductCollections.Where(x => x.CollectionId == collectionId).Count() == 0) { - var productCollection = new ProductCollection - { + var productCollection = new ProductCollection { CollectionId = collectionId, DisplayOrder = model.DisplayOrder, }; @@ -1392,8 +1372,7 @@ public virtual async Task InsertRelatedProductModel(ProductModel.AddRelatedProdu if (model.ProductId != id) if (existingRelatedProducts.Where(x => x.ProductId2 == id).Count() == 0) { - var related = new RelatedProduct - { + var related = new RelatedProduct { ProductId2 = id, DisplayOrder = 1, }; @@ -1458,8 +1437,7 @@ public virtual async Task InsertSimilarProductModel(ProductModel.AddSimilarProdu if (model.ProductId != id) if (existingSimilarProducts.Where(x => x.ProductId2 == id).Count() == 0) { - var similar = new SimilarProduct - { + var similar = new SimilarProduct { ProductId1 = model.ProductId, ProductId2 = id, DisplayOrder = 1, @@ -1527,8 +1505,7 @@ public virtual async Task InsertBundleProductModel(ProductModel.AddBundleProduct if (model.ProductId != id) if (existingBundleProducts.Where(x => x.ProductId == id).Count() == 0) { - var bundle = new BundleProduct - { + var bundle = new BundleProduct { ProductId = id, DisplayOrder = 1, Quantity = 1, @@ -1595,8 +1572,7 @@ public virtual async Task InsertCrossSellProductModel(ProductModel.AddCrossSellP { if (model.ProductId != id) await _productService.InsertCrossSellProduct( - new CrossSellProduct - { + new CrossSellProduct { ProductId1 = model.ProductId, ProductId2 = id, }); @@ -1606,8 +1582,7 @@ public virtual async Task InsertCrossSellProductModel(ProductModel.AddCrossSellP } public virtual async Task DeleteCrossSellProduct(string productId, string crossSellProductId) { - var crosssell = new CrossSellProduct() - { + var crosssell = new CrossSellProduct() { ProductId1 = productId, ProductId2 = crossSellProductId }; @@ -1665,8 +1640,7 @@ public virtual async Task DeleteAssociatedProduct(Product product) } public virtual async Task PrepareRelatedProductModel() { - var model = new ProductModel.AddRelatedProductModel - { + var model = new ProductModel.AddRelatedProductModel { //a vendor should have access only to his products IsLoggedInAsVendor = _workContext.CurrentVendor != null }; @@ -1690,8 +1664,7 @@ public virtual async Task PrepareRelatedPro } public virtual async Task PrepareSimilarProductModel() { - var model = new ProductModel.AddSimilarProductModel - { + var model = new ProductModel.AddSimilarProductModel { //a vendor should have access only to his products IsLoggedInAsVendor = _workContext.CurrentVendor != null }; @@ -1715,8 +1688,7 @@ public virtual async Task PrepareSimilarPro } public virtual async Task PrepareBundleProductModel() { - var model = new ProductModel.AddBundleProductModel - { + var model = new ProductModel.AddBundleProductModel { //a vendor should have access only to his products IsLoggedInAsVendor = _workContext.CurrentVendor != null }; @@ -1737,8 +1709,7 @@ public virtual async Task PrepareBundleProdu } public virtual async Task PrepareCrossSellProductModel() { - var model = new ProductModel.AddCrossSellProductModel - { + var model = new ProductModel.AddCrossSellProductModel { //a vendor should have access only to his products IsLoggedInAsVendor = _workContext.CurrentVendor != null }; @@ -1788,8 +1759,7 @@ public virtual async Task PrepareRecomm } public virtual async Task PrepareAssociatedProductModel() { - var model = new ProductModel.AddAssociatedProductModel - { + var model = new ProductModel.AddAssociatedProductModel { //a vendor should have access only to his products IsLoggedInAsVendor = _workContext.CurrentVendor != null }; @@ -1869,8 +1839,7 @@ public virtual async Task<(IEnumerable bulkEditProductMode return (products.Select((Func)(x => { - var productModel = new BulkEditProductModel - { + var productModel = new BulkEditProductModel { Id = x.Id, Name = x.Name, Sku = x.Sku, @@ -1967,8 +1936,7 @@ public virtual async Task> PrepareTierPriceMo else storeName = _translationService.GetResource("Admin.Catalog.Products.TierPrices.Fields.Store.All"); - items.Add(new ProductModel.TierPriceModel - { + items.Add(new ProductModel.TierPriceModel { Id = x.Id, StoreId = x.StoreId, Store = storeName, @@ -1992,8 +1960,7 @@ public virtual async Task<(IEnumerable bidModels, int tot var bidsModel = new List(); foreach (var x in bids) { - bidsModel.Add(new ProductModel.BidModel - { + bidsModel.Add(new ProductModel.BidModel { BidId = x.Id, ProductId = x.ProductId, Amount = priceFormatter.FormatPrice(x.Amount), @@ -2013,8 +1980,7 @@ public virtual async Task<(IEnumerable activityLo { var customer = await _customerService.GetCustomerById(x.CustomerId); items.Add( - new ProductModel.ActivityLogModel - { + new ProductModel.ActivityLogModel { Id = x.Id, ActivityLogTypeName = (await _customerActivityService.GetActivityTypeById(x.ActivityLogTypeId))?.Name, Comment = x.Comment, @@ -2027,14 +1993,12 @@ public virtual async Task<(IEnumerable activityLo } public virtual async Task PrepareProductAttributeMappingModel(Product product) { - var model = new ProductModel.ProductAttributeMappingModel - { + var model = new ProductModel.ProductAttributeMappingModel { ProductId = product.Id }; foreach (var attribute in await _productAttributeService.GetAllProductAttributes()) { - model.AvailableProductAttribute.Add(new SelectListItem() - { + model.AvailableProductAttribute.Add(new SelectListItem() { Value = attribute.Id, Text = attribute.Name }); @@ -2046,8 +2010,7 @@ public virtual async Task PrepareProd var model = productAttributeMapping.ToModel(); foreach (var attribute in await _productAttributeService.GetAllProductAttributes()) { - model.AvailableProductAttribute.Add(new SelectListItem() - { + model.AvailableProductAttribute.Add(new SelectListItem() { Value = attribute.Id, Text = attribute.Name, Selected = attribute.Id == model.ProductAttributeId @@ -2059,8 +2022,7 @@ public virtual async Task PrepareProd { foreach (var attribute in await _productAttributeService.GetAllProductAttributes()) { - model.AvailableProductAttribute.Add(new SelectListItem() - { + model.AvailableProductAttribute.Add(new SelectListItem() { Value = attribute.Id, Text = attribute.Name }); @@ -2072,8 +2034,7 @@ public virtual async Task> Prep var items = new List(); foreach (var x in product.ProductAttributeMappings.OrderBy(x => x.DisplayOrder)) { - var attributeModel = new ProductModel.ProductAttributeMappingModel - { + var attributeModel = new ProductModel.ProductAttributeMappingModel { Id = x.Id, ProductId = product.Id, ProductAttribute = (await _productAttributeService.GetProductAttributeById(x.ProductAttributeId))?.Name, @@ -2179,8 +2140,7 @@ public virtual async Task UpdateProductAttributeMappingModel(ProductModel.Produc } public virtual async Task PrepareProductAttributeMappingModel(ProductAttributeMapping productAttributeMapping) { - var model = new ProductModel.ProductAttributeMappingModel - { + var model = new ProductModel.ProductAttributeMappingModel { //prepare only used properties Id = productAttributeMapping.Id, ValidationRulesAllowed = productAttributeMapping.ValidationRulesAllowed(), @@ -2204,8 +2164,7 @@ public virtual async Task UpdateProductAttributeValidationRulesModel(ProductAttr } public virtual async Task PrepareProductAttributeConditionModel(Product product, ProductAttributeMapping productAttributeMapping) { - var model = new ProductAttributeConditionModel - { + var model = new ProductAttributeConditionModel { ProductAttributeMappingId = productAttributeMapping.Id, EnableCondition = productAttributeMapping.ConditionAttribute.Any(), ProductId = product.Id @@ -2224,8 +2183,7 @@ public virtual async Task PrepareProductAttribut foreach (var attribute in attributes) { var pam = await _productAttributeService.GetProductAttributeById(attribute.ProductAttributeId); - var attributeModel = new ProductAttributeConditionModel.ProductAttributeModel - { + var attributeModel = new ProductAttributeConditionModel.ProductAttributeModel { Id = attribute.Id, ProductAttributeId = attribute.ProductAttributeId, Name = pam.Name, @@ -2240,8 +2198,7 @@ public virtual async Task PrepareProductAttribut var attributeValues = product.ProductAttributeMappings.FirstOrDefault(x => x.Id == attribute.Id).ProductAttributeValues; foreach (var attributeValue in attributeValues) { - var attributeValueModel = new ProductAttributeConditionModel.ProductAttributeValueModel - { + var attributeValueModel = new ProductAttributeConditionModel.ProductAttributeValueModel { Id = attributeValue.Id, Name = attributeValue.Name, IsPreSelected = attributeValue.IsPreSelected @@ -2368,8 +2325,7 @@ public virtual async Task UpdateProductAttributeConditionModel(Product product, } public virtual async Task PrepareProductAttributeValueModel(Product product, ProductAttributeMapping productAttributeMapping) { - var model = new ProductModel.ProductAttributeValueModel - { + var model = new ProductModel.ProductAttributeValueModel { ProductAttributeMappingId = productAttributeMapping.Id, ProductId = product.Id, @@ -2386,8 +2342,7 @@ public virtual async Task PrepareProduc //pictures foreach (var x in product.ProductPictures) { - model.ProductPictureModels.Add(new ProductModel.ProductPictureModel - { + model.ProductPictureModels.Add(new ProductModel.ProductPictureModel { Id = x.Id, ProductId = product.Id, PictureId = x.PictureId, @@ -2413,8 +2368,7 @@ public virtual async Task> Prepar if (string.IsNullOrEmpty(pictureThumbnailUrl)) pictureThumbnailUrl = await _pictureService.GetPictureUrl("", 1, true); - items.Add(new ProductModel.ProductAttributeValueModel - { + items.Add(new ProductModel.ProductAttributeValueModel { Id = x.Id, ProductAttributeMappingId = productAttributeMapping.Id, //TODO - check x.ProductAttributeMappingId, AttributeValueTypeId = x.AttributeValueTypeId, @@ -2444,8 +2398,7 @@ public virtual async Task PrepareProduc { var associatedProduct = await _productService.GetProductById(pav.AssociatedProductId); - var model = new ProductModel.ProductAttributeValueModel - { + var model = new ProductModel.ProductAttributeValueModel { ProductAttributeMappingId = pa.Id, //TODO - check pav.ProductAttributeMappingId, AttributeValueTypeId = pav.AttributeValueTypeId, AttributeValueTypeName = pav.AttributeValueTypeId.GetTranslationEnum(_translationService, _workContext), @@ -2473,8 +2426,7 @@ public virtual async Task PrepareProduc } public virtual async Task InsertProductAttributeValueModel(ProductModel.ProductAttributeValueModel model) { - var pav = new ProductAttributeValue - { + var pav = new ProductAttributeValue { AttributeValueTypeId = model.AttributeValueTypeId, AssociatedProductId = model.AssociatedProductId, Name = model.Name, @@ -2511,8 +2463,7 @@ public virtual async Task UpdateProductAttributeValueModel(ProductAttributeValue } public virtual async Task PrepareAssociateProductToAttributeValueModel() { - var model = new ProductModel.ProductAttributeValueModel.AssociateProductToAttributeValueModel - { + var model = new ProductModel.ProductAttributeValueModel.AssociateProductToAttributeValueModel { //a vendor should have access only to his products IsLoggedInAsVendor = _workContext.CurrentVendor != null }; @@ -2542,8 +2493,7 @@ public virtual async Task> foreach (var x in product.ProductAttributeCombinations) { var attributes = await _productAttributeFormatter.FormatAttributes(product, x.Attributes, _workContext.CurrentCustomer, "
", true, true, true, false, true, true); - var pacModel = new ProductModel.ProductAttributeCombinationModel - { + var pacModel = new ProductModel.ProductAttributeCombinationModel { Id = x.Id, ProductId = product.Id, Attributes = string.IsNullOrEmpty(attributes) ? "(null)" : attributes, @@ -2567,8 +2517,7 @@ public virtual async Task PrepareProductAttrib var wim = new List(); foreach (var warehouse in await _warehouseService.GetAllWarehouses()) { - var pwiModel = new ProductAttributeCombinationModel.WarehouseInventoryModel - { + var pwiModel = new ProductAttributeCombinationModel.WarehouseInventoryModel { WarehouseId = warehouse.Id, WarehouseName = warehouse.Name }; @@ -2639,8 +2588,7 @@ async Task PrepareCombinationWarehouseInventory(ProductAttributeCombination comb if (whim.WarehouseUsed) { //no need to insert a record for qty 0 - existingPwI = new ProductCombinationWarehouseInventory - { + existingPwI = new ProductCombinationWarehouseInventory { WarehouseId = whim.WarehouseId, StockQuantity = whim.StockQuantity, ReservedQuantity = whim.ReservedQuantity @@ -2745,8 +2693,7 @@ async Task PrepareCombinationWarehouseInventory(ProductAttributeCombination comb } if (warnings.Count == 0) { - var combination = new ProductAttributeCombination - { + var combination = new ProductAttributeCombination { Attributes = customAttributes, StockQuantity = model.StockQuantity, ReservedQuantity = model.ReservedQuantity, @@ -2830,8 +2777,7 @@ public virtual async Task GenerateAllAttributeCombinations(Product product) continue; //save combination - var combination = new ProductAttributeCombination - { + var combination = new ProductAttributeCombination { Attributes = attributes.ToList(), StockQuantity = 0, AllowOutOfStockOrders = false, @@ -2877,8 +2823,7 @@ public virtual async Task> PrepareProductPictureModel(Product product) + public virtual async Task> PrepareProductPicturesModel(Product product) { var items = new List(); foreach (var x in product.ProductPictures.OrderBy(x => x.DisplayOrder)) { - var picture = await _pictureService.GetPictureById(x.PictureId); - var m = new ProductModel.ProductPictureModel - { + var m = new ProductModel.ProductPictureModel { Id = x.Id, ProductId = product.Id, PictureId = x.PictureId, @@ -2969,6 +2911,23 @@ public virtual async Task> PrepareProduc } return items; } + + public virtual async Task PrepareProductPictureModel(Product product, ProductPicture productPicture) + { + var picture = await _pictureService.GetPictureById(productPicture.PictureId); + var model = new ProductModel.ProductPictureModel { + Id = productPicture.Id, + ProductId = product.Id, + PictureId = productPicture.PictureId, + PictureUrl = picture != null ? await _pictureService.GetPictureUrl(picture) : null, + OverrideAltAttribute = picture?.AltAttribute, + OverrideTitleAttribute = picture?.TitleAttribute, + DisplayOrder = productPicture.DisplayOrder + }; + + return model; + } + public virtual async Task InsertProductPicture(Product product, Picture picture, int displayOrder, string overrideAltAttribute, string overrideTitleAttribute) { if (picture == null) @@ -2984,8 +2943,7 @@ public virtual async Task InsertProductPicture(Product product, Picture picture, overrideAltAttribute, overrideTitleAttribute); - await _productService.InsertProductPicture(new ProductPicture - { + await _productService.InsertProductPicture(new ProductPicture { PictureId = picture.Id, DisplayOrder = displayOrder, }, product.Id); @@ -3054,8 +3012,7 @@ public virtual async Task> PrepareProd foreach (var x in product.ProductSpecificationAttributes.OrderBy(x => x.DisplayOrder)) { var specificationAttribute = await _specificationAttributeService.GetSpecificationAttributeById(x.SpecificationAttributeId); - var psaModel = new ProductSpecificationAttributeModel - { + var psaModel = new ProductSpecificationAttributeModel { Id = x.Id, AttributeTypeId = (int)x.AttributeTypeId, ProductSpecificationId = specificationAttribute.Id, @@ -3099,8 +3056,7 @@ public virtual async Task InsertProductSpecificationAttributeModel(ProductModel. model.SpecificationAttributeOptionId = null; } - var psa = new ProductSpecificationAttribute - { + var psa = new ProductSpecificationAttribute { AttributeTypeId = model.AttributeTypeId, SpecificationAttributeOptionId = model.SpecificationAttributeOptionId, SpecificationAttributeId = model.SpecificationAttributeId, diff --git a/src/Web/Grand.Web/App_Data/Resources/DefaultLanguage.xml b/src/Web/Grand.Web/App_Data/Resources/DefaultLanguage.xml index 48053a9ed..115fc980e 100644 --- a/src/Web/Grand.Web/App_Data/Resources/DefaultLanguage.xml +++ b/src/Web/Grand.Web/App_Data/Resources/DefaultLanguage.xml @@ -3336,6 +3336,9 @@ Add a new picture + + Picture details + Display order