public IActionResult Index(int id) { if (id < 1) { return(NotFound()); } var product = _productService.Get(id); if (!product.IsPublic() && !CurrentUser.Can(CapabilitySystemNames.EditProduct)) { return(NotFound()); } //is the product restricted to roles if (product.RestrictedToRoles) { var userRoleIds = CurrentUser?.Roles?.Select(x => x.Id).ToList(); if (userRoleIds == null || product.EntityRoles.All(x => !userRoleIds.Contains(x.RoleId))) { return(NotFound()); } } var productModel = _productModelFactory.Create(product); var response = R.Success; response.With("product", productModel); if (_catalogSettings.EnableRelatedProducts) { var productRelations = _productRelationService.GetByProductId(id, ProductRelationType.RelatedProduct, 1, _catalogSettings.NumberOfRelatedProducts); if (productRelations.Any()) { var relatedProductsModel = productRelations.Select(x => x.DestinationProduct).Select(_productModelFactory.Create).ToList(); response.With("relatedProducts", relatedProductsModel); } } if (product.HasVariants) { //any variants var variants = _productVariantService.GetByProductId(product.Id); var variantModels = new List <object>(); foreach (var variant in variants) { _priceAccountant.GetProductPriceDetails(product, null, variant.Price, out decimal priceWithoutTax, out decimal tax, out decimal taxRate, out _); var variantObject = new { attributes = new Dictionary <string, string>(), price = _priceAccountant .ConvertCurrency( (_taxSettings.DisplayProductPricesWithoutTax ? priceWithoutTax : priceWithoutTax + tax), ApplicationEngine.CurrentCurrency).ToCurrency(), isAvailable = !variant.TrackInventory || (variant.TrackInventory && variant.IsAvailableInStock(product)), sku = !variant.Sku.IsNullEmptyOrWhiteSpace() ? variant.Sku : product.Sku, gtin = !variant.Gtin.IsNullEmptyOrWhiteSpace() ? variant.Gtin : product.Gtin, mpn = !variant.Mpn.IsNullEmptyOrWhiteSpace() ? variant.Mpn : product.Mpn }; foreach (var pva in variant.ProductVariantAttributes) { variantObject.attributes.Add(pva.ProductAttribute.Label, pva.ProductAttributeValue.AvailableAttributeValue.Value); } variantModels.Add(variantObject); } if (variantModels.Any()) { response.With("variants", variantModels); } productModel.IsAvailable = variantModels.Any(x => (bool)((dynamic)x).isAvailable); } //downloads if (product.IsDownloadable) { var downloads = _downloadService.GetWithoutBytes(x => x.ProductId == product.Id && !x.RequirePurchase).ToList(); if (CurrentUser.IsVisitor()) { downloads = downloads.Where(x => !x.RequireLogin).ToList(); } var downloadModels = downloads.Select(_productModelFactory.Create).ToList(); response.With("downloads", downloadModels); } //reviews if (_catalogSettings.EnableReviews) { var reviews = _reviewService.Get(x => x.ProductId == product.Id, 1, _catalogSettings.NumberOfReviewsToDisplayOnProductPage).ToList(); if (reviews.Any()) { var reviewModels = reviews.Select(x => { var model = _modelMapper.Map <ReviewModel>(x); model.DisplayName = x.Private ? _catalogSettings.DisplayNameForPrivateReviews : x.User?.Name; if (model.DisplayName.IsNullEmptyOrWhiteSpace()) { model.DisplayName = T("Store Customer"); } return(model); }).ToList(); response.With("reviews", reviewModels); } } //breadcrumbs if (_generalSettings.EnableBreadcrumbs) { var categoryTree = _categoryService.GetFullCategoryTree(); var category = product.Categories?.FirstOrDefault(); var currentCategoryFull = categoryTree.FirstOrDefault(x => x.Id == category?.Id); BreadcrumbHelper.SetCategoryBreadcrumb(currentCategoryFull, categoryTree); SetBreadcrumbToRoute(product.Name, RouteNames.SingleProduct, new { seName = product.SeoMeta.Slug }, localize: false); } //seo data SeoMetaHelper.SetSeoData(product.Name, product.Description, product.Description); return(response.With("preview", !product.Published).Result); }
public IActionResult ProductsListApi(ProductSearchModel searchModel, string viewName = null) { searchModel.Count = _catalogSettings.NumberOfProductsPerPage; IList <int> categoryIds = null; if (searchModel.CategoryId.HasValue && searchModel.CategoryId.Value > 0) { categoryIds = new List <int>() { searchModel.CategoryId.Value }; var fullCategoryTree = _categoryService.GetFullCategoryTree(); var currentCategory = fullCategoryTree.FirstOrDefault(x => x.Id == searchModel.CategoryId.Value); //set breadcrumb BreadcrumbHelper.SetCategoryBreadcrumb(currentCategory, fullCategoryTree); if (_catalogSettings.DisplayProductsFromChildCategories) { if (currentCategory != null) { var childIds = currentCategory.Children.SelectManyRecursive(x => x.Children).Select(x => x.Id); categoryIds = categoryIds.Concat(childIds).ToList(); } } } //create order by expression Expression <Func <Product, object> > orderByExpression = null; switch (searchModel.SortColumn?.ToLower()) { case "name": orderByExpression = product => product.Name; break; case "createdon": orderByExpression = product => product.CreatedOn; break; case "price": orderByExpression = product => product.Price; break; case "popularity": default: orderByExpression = product => product.PopularityIndex; searchModel.SortOrder = SortOrder.Descending; searchModel.SortColumn = "popularity"; break; } IList <int> roleIds = CurrentUser?.Roles?.Select(x => x.Id).ToList(); var products = _productService.GetProducts(out int totalResults, out decimal availableFromPrice, out decimal availableToPrice, out Dictionary <int, string> availableManufacturers, out Dictionary <int, string> availableVendors, out Dictionary <string, List <string> > availableFilters, searchText: searchModel.Search, filterExpression: searchModel.Filters, published: true, tags: searchModel.Tags, vendorIds: searchModel.VendorIds, manufacturerIds: searchModel.ManufacturerIds, categoryids: categoryIds, roleIds: roleIds, fromPrice: searchModel.FromPrice, toPrice: searchModel.ToPrice, sortOrder: searchModel.SortOrder, orderByExpression: orderByExpression, page: searchModel.Page, count: searchModel.Count); var productModels = products.Select(_productModelFactory.Create).ToList(); searchModel.AvailableFromPrice = availableFromPrice; searchModel.AvailableToPrice = availableToPrice; searchModel.AvailableFilters = availableFilters; searchModel.AvailableManufacturers = availableManufacturers; searchModel.AvailableVendors = availableVendors; //get the category if (searchModel.CategoryId > 0) { var category = _categoryService.Get(searchModel.CategoryId.Value); if (category != null) { SeoMetaHelper.SetSeoData(category.Name, category.Description, category.Description); } } if (viewName.IsNullEmptyOrWhiteSpace()) { viewName = "ProductsList"; } return(R.Success.With("products", productModels) .WithParams(searchModel) .WithGridResponse(totalResults, searchModel.Page, searchModel.Count, searchModel.SortColumn, searchModel.SortOrder) .WithView(viewName) .Result); }