/// <summary> /// Get language from the requested page URL /// </summary> /// <returns>The found language</returns> protected virtual async Task <Language> GetLanguageFromUrlAsync() { if (_httpContextAccessor.HttpContext?.Request == null) { return(null); } //whether the requsted URL is localized var path = _httpContextAccessor.HttpContext.Request.Path.Value; var(isLocalized, language) = await path.IsLocalizedUrlAsync(_httpContextAccessor.HttpContext.Request.PathBase, false); if (!isLocalized) { return(null); } //check language availability if (!await _storeMappingService.AuthorizeAsync(language)) { return(null); } return(language); }
private async Task <bool> CheckCategoryAvailabilityAsync(Category category) { var isAvailable = true; if (category == null || category.Deleted) { isAvailable = false; } var notAvailable = //published? !category.Published || //ACL (access control list) !await _aclService.AuthorizeAsync(category) || //Store mapping !await _storeMappingService.AuthorizeAsync(category); //Check whether the current user has a "Manage categories" permission (usually a store owner) //We should allows him (her) to use "Preview" functionality var hasAdminAccess = await _permissionService.AuthorizeAsync(StandardPermissionProvider.AccessAdminPanel) && await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCategories); if (notAvailable && !hasAdminAccess) { isAvailable = false; } return(isAvailable); }
/// <summary> /// Prepare billing address model /// </summary> /// <param name="cart">Cart</param> /// <param name="selectedCountryId">Selected country identifier</param> /// <param name="prePopulateNewAddressWithCustomerFields">Pre populate new address with customer fields</param> /// <param name="overrideAttributesXml">Override attributes xml</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the billing address model /// </returns> public virtual async Task <CheckoutBillingAddressModel> PrepareBillingAddressModelAsync(IList <ShoppingCartItem> cart, int?selectedCountryId = null, bool prePopulateNewAddressWithCustomerFields = false, string overrideAttributesXml = "") { var model = new CheckoutBillingAddressModel { ShipToSameAddressAllowed = _shippingSettings.ShipToSameAddress && await _shoppingCartService.ShoppingCartRequiresShippingAsync(cart), //allow customers to enter (choose) a shipping address if "Disable Billing address step" setting is enabled ShipToSameAddress = !_orderSettings.DisableBillingAddressCheckoutStep }; //existing addresses var customer = await _workContext.GetCurrentCustomerAsync(); var addresses = await(await _customerService.GetAddressesByCustomerIdAsync(customer.Id)) .WhereAwait(async a => !a.CountryId.HasValue || await _countryService.GetCountryByAddressAsync(a) is Country country && (//published country.Published && //allow billing country.AllowsBilling && //enabled for the current store await _storeMappingService.AuthorizeAsync(country))) .ToListAsync(); foreach (var address in addresses) { var addressModel = new AddressModel(); await _addressModelFactory.PrepareAddressModelAsync(addressModel, address : address, excludeProperties : false, addressSettings : _addressSettings); if (await _addressService.IsAddressValidAsync(address)) { model.ExistingAddresses.Add(addressModel); } else { model.InvalidExistingAddresses.Add(addressModel); } } //new address model.BillingNewAddress.CountryId = selectedCountryId; await _addressModelFactory.PrepareAddressModelAsync(model.BillingNewAddress, address : null, excludeProperties : false, addressSettings : _addressSettings, loadCountries : async() => await _countryService.GetAllCountriesForBillingAsync((await _workContext.GetWorkingLanguageAsync()).Id), prePopulateWithCustomerFields : prePopulateNewAddressWithCustomerFields, customer : customer, overrideAttributesXml : overrideAttributesXml); return(model); }
public virtual async Task <IActionResult> Category(int categoryId, CatalogPagingFilteringModel command) { var category = await _categoryService.GetCategoryByIdAsync(categoryId); if (category == null || category.Deleted) { return(InvokeHttp404()); } var notAvailable = //published? !category.Published || //ACL (access control list) !await _aclService.AuthorizeAsync(category) || //Store mapping !await _storeMappingService.AuthorizeAsync(category); //Check whether the current user has a "Manage categories" permission (usually a store owner) //We should allows him (her) to use "Preview" functionality var hasAdminAccess = await _permissionService.AuthorizeAsync(StandardPermissionProvider.AccessAdminPanel) && await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCategories); if (notAvailable && !hasAdminAccess) { return(InvokeHttp404()); } //'Continue shopping' URL await _genericAttributeService.SaveAttributeAsync(await _workContext.GetCurrentCustomerAsync(), NopCustomerDefaults.LastContinueShoppingPageAttribute, _webHelper.GetThisPageUrl(false), (await _storeContext.GetCurrentStoreAsync()).Id); //display "edit" (manage) link if (await _permissionService.AuthorizeAsync(StandardPermissionProvider.AccessAdminPanel) && await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageCategories)) { DisplayEditLink(Url.Action("Edit", "Category", new { id = category.Id, area = AreaNames.Admin })); } //activity log await _customerActivityService.InsertActivityAsync("PublicStore.ViewCategory", string.Format(await _localizationService.GetResourceAsync("ActivityLog.PublicStore.ViewCategory"), category.Name), category); //model var model = await _catalogModelFactory.PrepareCategoryModelAsync(category, command); //template var templateViewPath = await _catalogModelFactory.PrepareCategoryTemplateViewPathAsync(category.CategoryTemplateId); return(View(templateViewPath, model)); }
public async Task <IActionResult> TopicDetails(int topicId, bool popup = false) { await _helper.GetBreadcrumbAsync(_breadcrumb, ControllerContext); var cacheKey = string.Format(ModelCacheInvalidator.TOPIC_BY_ID_KEY, topicId, Services.WorkContext.WorkingLanguage.Id, Services.StoreContext.CurrentStore.Id, Services.WorkContext.CurrentCustomer.GetRolesIdent()); var cacheModel = await Services.CacheFactory.GetMemoryCache().GetAsync(cacheKey, async(o) => { o.ExpiresIn(TimeSpan.FromDays(1)); var topic = await Services.DbContext.Topics.FindByIdAsync(topicId, false); if (topic == null || !topic.IsPublished) { return(null); } if (!await _storeMappingService.AuthorizeAsync(topic)) { return(null); } if (!await _aclService.AuthorizeAsync(topic)) { return(null); } return(PrepareTopicModel(topic)); }); if (cacheModel == null || (!popup && cacheModel.RenderAsWidget)) { return(NotFound()); } ViewBag.IsPopup = popup; if (!cacheModel.RenderAsWidget) { Services.DisplayControl.Announce(new Topic { Id = cacheModel.Id }); } return(View("TopicDetails", cacheModel)); }
public virtual async Task <IActionResult> Authenticate(int id, string password) { var authResult = false; var title = string.Empty; var body = string.Empty; var error = string.Empty; var topic = await _topicService.GetTopicByIdAsync(id); if (topic != null && topic.Published && //password protected? topic.IsPasswordProtected && //store mapping await _storeMappingService.AuthorizeAsync(topic) && //ACL (access control list) await _aclService.AuthorizeAsync(topic)) { if (topic.Password != null && topic.Password.Equals(password)) { authResult = true; title = await _localizationService.GetLocalizedAsync(topic, x => x.Title); body = await _localizationService.GetLocalizedAsync(topic, x => x.Body); } else { error = await _localizationService.GetResourceAsync("Topic.WrongPassword"); } } return(Json(new { Authenticated = authResult, Title = title, Body = body, Error = error })); }
/// <summary> /// Gets all categories displayed on the home page /// </summary> /// <param name="showHidden">A value indicating whether to show hidden records</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the categories /// </returns> public virtual async Task <IList <Category> > GetAllCategoriesDisplayedOnHomepageAsync(bool showHidden = false) { var categories = await _categoryRepository.GetAllAsync(query => { return(from c in query orderby c.DisplayOrder, c.Id where c.Published && !c.Deleted && c.ShowOnHomepage select c); }, cache => cache.PrepareKeyForDefaultCache(NopCatalogDefaults.CategoriesHomepageCacheKey)); if (showHidden) { return(categories); } var cacheKey = _staticCacheManager.PrepareKeyForDefaultCache(NopCatalogDefaults.CategoriesHomepageWithoutHiddenCacheKey, await _storeContext.GetCurrentStoreAsync(), await _customerService.GetCustomerRoleIdsAsync(await _workContext.GetCurrentCustomerAsync())); var result = await _staticCacheManager.GetAsync(cacheKey, async() => { return(await categories .WhereAwait(async c => await _aclService.AuthorizeAsync(c) && await _storeMappingService.AuthorizeAsync(c)) .ToListAsync()); }); return(result); }
/// <summary> /// Get language from the request /// </summary> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the found language /// </returns> protected virtual async Task <Language> GetLanguageFromRequestAsync() { var requestCultureFeature = _httpContextAccessor.HttpContext?.Features.Get <IRequestCultureFeature>(); if (requestCultureFeature is null) { return(null); } //whether we should detect the current language by customer settings if (requestCultureFeature.Provider is not NopSeoUrlCultureProvider && !_localizationSettings.AutomaticallyDetectLanguage) { return(null); } //get request culture if (requestCultureFeature.RequestCulture is null) { return(null); } //try to get language by culture name var requestLanguage = (await _languageService.GetAllLanguagesAsync()).FirstOrDefault(language => language.LanguageCulture.Equals(requestCultureFeature.RequestCulture.Culture.Name, StringComparison.InvariantCultureIgnoreCase)); //check language availability if (requestLanguage == null || !requestLanguage.Published || !await _storeMappingService.AuthorizeAsync(requestLanguage)) { return(null); } return(requestLanguage); }
public async Task <IActionResult> ProductDetails(int productId, ProductVariantQuery query) { var product = await _db.Products.FindByIdAsync(productId, false); if (product == null || product.Deleted || product.IsSystemProduct) { return(NotFound()); } // Is published? Check whether the current user has a "Manage catalog" permission. // It allows him to preview a product before publishing. if (!product.Published && !await Services.Permissions.AuthorizeAsync(Permissions.Catalog.Product.Read)) { return(NotFound()); } // ACL (access control list). if (!await _aclService.AuthorizeAsync(product)) { return(NotFound()); } // Store mapping. if (!await _storeMappingService.AuthorizeAsync(product)) { return(NotFound()); } // TODO: (mh) (core) Continue CatalogController.Category() var store = Services.StoreContext.CurrentStore; var price = store.PrimaryStoreCurrency.AsMoney(product.Price).ExchangeTo(Services.WorkContext.WorkingCurrency); return(Content($"Product --> Id: {product.Id}, Name: {product.Name}, Price: {price}")); }
/// <summary> /// Checks whether entities are accessible in a given store. /// </summary> /// <typeparam name="T">Entity type.</typeparam> /// <param name="service">Store mapping service.</param> /// <param name="entities">Entities to check.</param> /// <param name="storeId">Store identifier.</param> /// <returns>Authorized entities.</returns> public static IAsyncEnumerable <T> SelectAuthorizedAsync <T>(this IStoreMappingService service, IEnumerable <T> entities, int storeId) where T : BaseEntity, IStoreRestricted { Guard.NotNull(entities, nameof(entities)); return(entities.WhereAsync(x => service.AuthorizeAsync(x.GetEntityName(), x.Id, storeId))); }
/// <summary> /// Gets all languages /// </summary> /// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param> /// <param name="showHidden">A value indicating whether to show hidden records</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the languages /// </returns> public virtual async Task <IList <Language> > GetAllLanguagesAsync(bool showHidden = false, int storeId = 0) { //cacheable copy var key = _staticCacheManager.PrepareKeyForDefaultCache(NopLocalizationDefaults.LanguagesAllCacheKey, storeId, showHidden); var languages = await _staticCacheManager.GetAsync(key, async() => { var allLanguages = await _languageRepository.GetAllAsync(query => { if (!showHidden) { query = query.Where(l => l.Published); } query = query.OrderBy(l => l.DisplayOrder).ThenBy(l => l.Id); return(query); }); //store mapping if (storeId > 0) { allLanguages = await allLanguages .WhereAwait(async l => await _storeMappingService.AuthorizeAsync(l, storeId)) .ToListAsync(); } return(allLanguages); }); return(languages); }
/// <summary> /// Get the topic model by topic identifier /// </summary> /// <param name="topicId">Topic identifier</param> /// <param name="showHidden">A value indicating whether to show hidden records</param> /// <returns>Topic model</returns> public virtual async Task <TopicModel> PrepareTopicModelByIdAsync(int topicId, bool showHidden = false) { var topic = await _topicService.GetTopicByIdAsync(topicId); if (topic == null) { return(null); } if (showHidden) { return(await PrepareTopicModelAsync(topic)); } if (!topic.Published || //ACL (access control list) !await _aclService.AuthorizeAsync(topic) || //store mapping !await _storeMappingService.AuthorizeAsync(topic)) { return(null); } return(await PrepareTopicModelAsync(topic)); }
private async Task <int> GetDefaultStoreLangaugeIdAsync() { // Get the default language id for the current store. var defaultLanguageId = _storeContext.GetCurrentStore().DefaultLanguageId; if (defaultLanguageId == 0) { var allLanguages = await _languageService.GetAllLanguagesAsync(); int currentStoreId = _storeContext.GetCurrentStore().Id; var storeLanguages = await allLanguages.WhereAwait(async l => await _storeMappingService.AuthorizeAsync(l, currentStoreId)).ToListAsync(); // If there is no language mapped to the current store, get all of the languages, // and use the one with the first display order. This is a default nopCommerce workflow. if (storeLanguages.Count == 0) { storeLanguages = allLanguages.ToList(); } var defaultLanguage = storeLanguages.OrderBy(l => l.DisplayOrder).First(); defaultLanguageId = defaultLanguage.Id; } return(defaultLanguageId); }
public async Task <int> GetProductsCountAsync( DateTime?createdAtMin = null, DateTime?createdAtMax = null, DateTime?updatedAtMin = null, DateTime?updatedAtMax = null, bool?publishedStatus = null, string vendorName = null, int?categoryId = null) { var query = GetProductsQuery(createdAtMin, createdAtMax, updatedAtMin, updatedAtMax, vendorName, publishedStatus, categoryId: categoryId); return(await query.WhereAwait(async p => await _storeMappingService.AuthorizeAsync(p)).CountAsync()); }
public async Task <int> GetCategoriesCountAsync( DateTime?createdAtMin = null, DateTime?createdAtMax = null, DateTime?updatedAtMin = null, DateTime?updatedAtMax = null, bool?publishedStatus = null, int?productId = null) { var query = GetCategoriesQuery(createdAtMin, createdAtMax, updatedAtMin, updatedAtMax, publishedStatus, productId); return(await query.WhereAwait(async c => await _storeMappingService.AuthorizeAsync(c)).CountAsync()); }
public async Task <IActionResult> Category(int categoryId, CatalogSearchQuery query) { var category = await _db.Categories.FindByIdAsync(categoryId, false); if (category == null || category.Deleted) { return(NotFound()); } // Check whether the current user has a "Manage catalog" permission. // It allows him to preview a category before publishing. if (!category.Published && !await Services.Permissions.AuthorizeAsync(Permissions.Catalog.Category.Read)) { return(NotFound()); } // ACL (access control list). if (!await _aclService.AuthorizeAsync(category)) { return(NotFound()); } // Store mapping. if (!await _storeMappingService.AuthorizeAsync(category)) { return(NotFound()); } var customer = Services.WorkContext.CurrentCustomer; // 'Continue shopping' URL. if (!customer.IsSystemAccount) { customer.GenericAttributes.LastContinueShoppingPage = Services.WebHelper.GetCurrentPageUrl(false); await _db.SaveChangesAsync(); } // TODO: (mh) (core) Continue CatalogController.Category() return(Content($"Category --> Id: {category.Id}, Name: {category.Name}")); }
/// <summary> /// Checks whether an entity can be accessed in a given store. /// </summary> /// <typeparam name="T">Entity type.</typeparam> /// <param name="service">Store mapping service.</param> /// <param name="entity">Entity to check.</param> /// <param name="storeId">Store identifier.</param> /// <returns><c>true</c> authorized, otherwise <c>false</c>.</returns> public static Task <bool> AuthorizeAsync <T>(this IStoreMappingService svc, T entity, int storeId) where T : BaseEntity, IStoreRestricted { if (entity == null) { return(Task.FromResult(false)); } if (!entity.LimitedToStores) { return(Task.FromResult(true)); } return(svc.AuthorizeAsync(entity.GetEntityName(), entity.Id, storeId)); }
public virtual async Task <IActionResult> Vote(int pollAnswerId) { var pollAnswer = await _pollService.GetPollAnswerByIdAsync(pollAnswerId); if (pollAnswer == null) { return(Json(new { error = "No poll answer found with the specified id" })); } var poll = await _pollService.GetPollByIdAsync(pollAnswer.PollId); if (!poll.Published || !await _storeMappingService.AuthorizeAsync(poll)) { return(Json(new { error = "Poll is not available" })); } var customer = await _workContext.GetCurrentCustomerAsync(); if (await _customerService.IsGuestAsync(customer) && !poll.AllowGuestsToVote) { return(Json(new { error = await _localizationService.GetResourceAsync("Polls.OnlyRegisteredUsersVote") })); } var alreadyVoted = await _pollService.AlreadyVotedAsync(poll.Id, customer.Id); if (!alreadyVoted) { //vote await _pollService.InsertPollVotingRecordAsync(new PollVotingRecord { PollAnswerId = pollAnswer.Id, CustomerId = customer.Id, CreatedOnUtc = DateTime.UtcNow }); //update totals pollAnswer.NumberOfVotes = (await _pollService.GetPollVotingRecordsByPollAnswerAsync(pollAnswer.Id)).Count; await _pollService.UpdatePollAnswerAsync(pollAnswer); await _pollService.UpdatePollAsync(poll); } return(Json(new { html = await RenderPartialViewToStringAsync("_Poll", await _pollModelFactory.PreparePollModelAsync(poll, true)), })); }
public virtual async Task <IActionResult> NewsItem(int newsItemId) { if (!_newsSettings.Enabled) { return(RedirectToRoute("Homepage")); } var newsItem = await _newsService.GetNewsByIdAsync(newsItemId); if (newsItem == null) { return(InvokeHttp404()); } var notAvailable = //published? !newsItem.Published || //availability dates !_newsService.IsNewsAvailable(newsItem) || //Store mapping !await _storeMappingService.AuthorizeAsync(newsItem); //Check whether the current user has a "Manage news" permission (usually a store owner) //We should allows him (her) to use "Preview" functionality var hasAdminAccess = await _permissionService.AuthorizeAsync(StandardPermissionProvider.AccessAdminPanel) && await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageNews); if (notAvailable && !hasAdminAccess) { return(InvokeHttp404()); } var model = new NewsItemModel(); model = await _newsModelFactory.PrepareNewsItemModelAsync(model, newsItem, true); //display "edit" (manage) link if (hasAdminAccess) { DisplayEditLink(Url.Action("NewsItemEdit", "News", new { id = newsItem.Id, area = AreaNames.Admin })); } return(View(model)); }
public async Task <IActionResult> ProductDetails(int productId, ProductVariantQuery query) { var product = await _db.Products.FindByIdAsync(productId, false); if (product == null || product.Deleted || product.IsSystemProduct) { return(NotFound()); } // Is published? Check whether the current user has a "Manage catalog" permission. // It allows him to preview a product before publishing. if (!product.Published && !await Services.Permissions.AuthorizeAsync(Permissions.Catalog.Product.Read)) { return(NotFound()); } // ACL (access control list). if (!await _aclService.AuthorizeAsync(product)) { return(NotFound()); } // Store mapping. if (!await _storeMappingService.AuthorizeAsync(product)) { return(NotFound()); } // Save as recently viewed _recentlyViewedProductsService.AddProductToRecentlyViewedList(product.Id); // Activity log Services.ActivityLogger.LogActivity("PublicStore.ViewProduct", T("ActivityLog.PublicStore.ViewProduct"), product.Name); // TODO: (mh) (core) Continue CatalogController.Category() var store = Services.StoreContext.CurrentStore; var price = Services.CurrencyService.ConvertToWorkingCurrency(product.Price); return(Content($"Product --> Id: {product.Id}, Name: {product.Name}, Price: {price}")); }
public virtual async Task <IActionResult> BlogPost(int blogPostId) { if (!_blogSettings.Enabled) { return(RedirectToRoute("Homepage")); } var blogPost = await _blogService.GetBlogPostByIdAsync(blogPostId); if (blogPost == null) { return(InvokeHttp404()); } var notAvailable = //availability dates !_blogService.BlogPostIsAvailable(blogPost) || //Store mapping !await _storeMappingService.AuthorizeAsync(blogPost); //Check whether the current user has a "Manage blog" permission (usually a store owner) //We should allows him (her) to use "Preview" functionality var hasAdminAccess = await _permissionService.AuthorizeAsync(StandardPermissionProvider.AccessAdminPanel) && await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageBlog); if (notAvailable && !hasAdminAccess) { return(InvokeHttp404()); } //display "edit" (manage) link if (hasAdminAccess) { DisplayEditLink(Url.Action("BlogPostEdit", "Blog", new { id = blogPost.Id, area = AreaNames.Admin })); } var model = new BlogPostModel(); await _blogModelFactory.PrepareBlogPostModelAsync(model, blogPost, true); return(View(model)); }
/// <summary> /// Gets all currencies /// </summary> /// <param name="showHidden">A value indicating whether to show hidden records</param> /// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param> /// <returns> /// A task that represents the asynchronous operation /// The task result contains the currencies /// </returns> public virtual async Task <IList <Currency> > GetAllCurrenciesAsync(bool showHidden = false, int storeId = 0) { var currencies = await _currencyRepository.GetAllAsync(query => { if (!showHidden) { query = query.Where(c => c.Published); } query = query.OrderBy(c => c.DisplayOrder).ThenBy(c => c.Id); return(query); }, cache => cache.PrepareKeyForDefaultCache(NopDirectoryDefaults.CurrenciesAllCacheKey, showHidden)); //store mapping if (storeId > 0) { currencies = await currencies .WhereAwait(async c => await _storeMappingService.AuthorizeAsync(c, storeId)) .ToListAsync(); } return(currencies); }
public async Task <IViewComponentResult> InvokeAsync(int productId, int?productThumbPictureSize) { if (!_catalogSettings.ProductsAlsoPurchasedEnabled) { return(Content("")); } //load and cache report var store = await _storeContext.GetCurrentStoreAsync(); var productIds = await _staticCacheManager.GetAsync(_staticCacheManager.PrepareKeyForDefaultCache(NopModelCacheDefaults.ProductsAlsoPurchasedIdsKey, productId, store), async() => await _orderReportService.GetAlsoPurchasedProductsIdsAsync(store.Id, productId, _catalogSettings.ProductsAlsoPurchasedNumber) ); //load products var products = await(await _productService.GetProductsByIdsAsync(productIds)) //ACL and store mapping .WhereAwait(async p => await _aclService.AuthorizeAsync(p) && await _storeMappingService.AuthorizeAsync(p)) //availability dates .Where(p => _productService.ProductIsAvailable(p)).ToListAsync(); if (!products.Any()) { return(Content("")); } var model = (await _productModelFactory.PrepareProductOverviewModelsAsync(products, true, true, productThumbPictureSize)).ToList(); return(View(model)); }
public async Task <IActionResult> Category(int categoryId, CatalogSearchQuery query) { var category = await _db.Categories .Include(x => x.MediaFile) .FindByIdAsync(categoryId, false); if (category == null || category.Deleted) { return(NotFound()); } // Check whether the current user has a "Manage catalog" permission. // It allows him to preview a category before publishing. if (!category.Published && !await Services.Permissions.AuthorizeAsync(Permissions.Catalog.Category.Read)) { return(NotFound()); } // ACL (access control list). if (!await _aclService.AuthorizeAsync(category)) { return(NotFound()); } // Store mapping. if (!await _storeMappingService.AuthorizeAsync(category)) { return(NotFound()); } var customer = Services.WorkContext.CurrentCustomer; var storeId = Services.StoreContext.CurrentStore.Id; // 'Continue shopping' URL. if (!customer.IsSystemAccount) { customer.GenericAttributes.LastContinueShoppingPage = Services.WebHelper.GetCurrentPageUrl(false); } var model = await _helper.PrepareCategoryModelAsync(category); if (_seoSettings.CanonicalUrlsEnabled) { model.CanonicalUrl = _urlHelper.Value.RouteUrl("Category", new { model.SeName }, Request.Scheme); } if (query.IsSubPage && !_catalogSettings.ShowDescriptionInSubPages) { model.Description.ChangeValue(string.Empty); model.BottomDescription.ChangeValue(string.Empty); } model.Image = await _helper.PrepareCategoryImageModelAsync(category, model.Name); // Category breadcrumb. if (_catalogSettings.CategoryBreadcrumbEnabled) { await _helper.GetBreadcrumbAsync(_breadcrumb, ControllerContext); } // Products. var catIds = new int[] { categoryId }; if (_catalogSettings.ShowProductsFromSubcategories) { // Include subcategories. catIds = catIds.Concat(await _helper.GetChildCategoryIdsAsync(categoryId)).ToArray(); } query.WithCategoryIds(_catalogSettings.IncludeFeaturedProductsInNormalLists ? null : false, catIds); var searchResult = await _catalogSearchService.SearchAsync(query); model.SearchResult = searchResult; var viewMode = _helper.GetSearchQueryViewMode(query); var mappingSettings = _helper.GetBestFitProductSummaryMappingSettings(viewMode); model.Products = await _helper.MapProductSummaryModelAsync(searchResult, mappingSettings); model.SubCategoryDisplayType = _catalogSettings.SubCategoryDisplayType; var pictureSize = _mediaSettings.CategoryThumbPictureSize; var fallbackType = _catalogSettings.HideCategoryDefaultPictures ? FallbackPictureType.NoFallback : FallbackPictureType.Entity; var hideSubCategories = _catalogSettings.SubCategoryDisplayType == SubCategoryDisplayType.Hide || (_catalogSettings.SubCategoryDisplayType == SubCategoryDisplayType.AboveProductList && query.IsSubPage && !_catalogSettings.ShowSubCategoriesInSubPages); var hideFeaturedProducts = _catalogSettings.IgnoreFeaturedProducts || (query.IsSubPage && !_catalogSettings.IncludeFeaturedProductsInSubPages); // Subcategories. if (!hideSubCategories) { var subCategories = await _categoryService.GetCategoriesByParentCategoryIdAsync(categoryId); model.SubCategories = await _helper.MapCategorySummaryModelAsync(subCategories, pictureSize); } // Featured Products. if (!hideFeaturedProducts) { CatalogSearchResult featuredProductsResult = null; string cacheKey = ModelCacheInvalidator.CATEGORY_HAS_FEATURED_PRODUCTS_KEY.FormatInvariant(categoryId, string.Join(",", customer.GetRoleIds()), storeId); var hasFeaturedProductsCache = await Services.Cache.GetAsync <bool?>(cacheKey); var featuredProductsQuery = new CatalogSearchQuery() .VisibleOnly(customer) .WithVisibility(ProductVisibility.Full) .WithCategoryIds(true, categoryId) .HasStoreId(storeId) .WithLanguage(Services.WorkContext.WorkingLanguage) .WithCurrency(Services.WorkContext.WorkingCurrency); if (!hasFeaturedProductsCache.HasValue) { featuredProductsResult = await _catalogSearchService.SearchAsync(featuredProductsQuery); hasFeaturedProductsCache = featuredProductsResult.TotalHitsCount > 0; await Services.Cache.PutAsync(cacheKey, hasFeaturedProductsCache); } if (hasFeaturedProductsCache.Value && featuredProductsResult == null) { featuredProductsResult = await _catalogSearchService.SearchAsync(featuredProductsQuery); } if (featuredProductsResult != null) { var featuredProductsMappingSettings = _helper.GetBestFitProductSummaryMappingSettings(ProductSummaryViewMode.Grid); model.FeaturedProducts = await _helper.MapProductSummaryModelAsync(featuredProductsResult, featuredProductsMappingSettings); } } // Prepare paging/sorting/mode stuff. _helper.MapListActions(model.Products, category, _catalogSettings.DefaultPageSizeOptions); // Template. var templateCacheKey = string.Format(ModelCacheInvalidator.CATEGORY_TEMPLATE_MODEL_KEY, category.CategoryTemplateId); var templateViewPath = await Services.Cache.GetAsync(templateCacheKey, async() => { var template = await _db.CategoryTemplates.FindByIdAsync(category.CategoryTemplateId, false) ?? await _db.CategoryTemplates.FirstOrDefaultAsync(); return(template.ViewPath); }); // Activity log. Services.ActivityLogger.LogActivity("PublicStore.ViewCategory", T("ActivityLog.PublicStore.ViewCategory"), category.Name); Services.DisplayControl.Announce(category); return(View(templateViewPath, model)); }
/// <returns>A task that represents the asynchronous operation</returns> public async Task <IViewComponentResult> InvokeAsync(int?productThumbPictureSize) { if (!_catalogSettings.ShowBestsellersOnHomepage || _catalogSettings.NumberOfBestsellersOnHomepage == 0) { return(Content("")); } //load and cache report var report = (await _staticCacheManager.GetAsync(_staticCacheManager.PrepareKeyForDefaultCache(NopModelCacheDefaults.HomepageBestsellersIdsKey, await _storeContext.GetCurrentStoreAsync()), async() => await _orderReportService.BestSellersReportAsync( storeId: (await _storeContext.GetCurrentStoreAsync()).Id, pageSize: _catalogSettings.NumberOfBestsellersOnHomepage))) .ToList(); //load products var products = await(await _productService.GetProductsByIdsAsync(report.Select(x => x.ProductId).ToArray())) //ACL and store mapping .WhereAwait(async p => await _aclService.AuthorizeAsync(p) && await _storeMappingService.AuthorizeAsync(p)) //availability dates .Where(p => _productService.ProductIsAvailable(p)).ToListAsync(); if (!products.Any()) { return(Content("")); } //prepare model var model = (await _productModelFactory.PrepareProductOverviewModelsAsync(products, true, true, productThumbPictureSize)).ToList(); return(View(model)); }
public async Task <IActionResult> ProductDetails(int productId, ProductVariantQuery query) { var product = await _db.Products .IncludeMedia() .IncludeManufacturers() .Where(x => x.Id == productId) .FirstOrDefaultAsync(); if (product == null || product.IsSystemProduct) { return(NotFound()); } // Is published? Check whether the current user has a "Manage catalog" permission. // It allows him to preview a product before publishing. if (!product.Published && !await Services.Permissions.AuthorizeAsync(Permissions.Catalog.Product.Read)) { return(NotFound()); } // ACL (access control list). if (!await _aclService.AuthorizeAsync(product)) { return(NotFound()); } // Store mapping. if (!await _storeMappingService.AuthorizeAsync(product)) { return(NotFound()); } // Is product individually visible? if (product.Visibility == ProductVisibility.Hidden) { // Find parent grouped product. var parentGroupedProduct = await _db.Products.FindByIdAsync(product.ParentGroupedProductId, false); if (parentGroupedProduct == null) { return(NotFound()); } var seName = await parentGroupedProduct.GetActiveSlugAsync(); if (seName.IsEmpty()) { return(NotFound()); } var routeValues = new RouteValueDictionary { { "SeName", seName } }; // Add query string parameters. Request.Query.Each(x => routeValues.Add(x.Key, Request.Query[x.Value].ToString())); return(RedirectToRoute("Product", routeValues)); } // Prepare the view model var model = await _helper.MapProductDetailsPageModelAsync(product, query); // Some cargo data model.PictureSize = _mediaSettings.ProductDetailsPictureSize; model.HotlineTelephoneNumber = _contactDataSettings.HotlineTelephoneNumber.NullEmpty(); if (_seoSettings.CanonicalUrlsEnabled) { model.CanonicalUrl = _urlHelper.Value.RouteUrl("Product", new { model.SeName }, Request.Scheme); } // Save as recently viewed _recentlyViewedProductsService.AddProductToRecentlyViewedList(product.Id); // Activity log Services.ActivityLogger.LogActivity("PublicStore.ViewProduct", T("ActivityLog.PublicStore.ViewProduct"), product.Name); // Breadcrumb if (_catalogSettings.CategoryBreadcrumbEnabled) { await _helper.GetBreadcrumbAsync(_breadcrumb, ControllerContext, product); _breadcrumb.Track(new MenuItem { Text = model.Name, Rtl = model.Name.CurrentLanguage.Rtl, EntityId = product.Id, Url = Url.RouteUrl("Product", new { model.SeName }) }); } return(View(model.ProductTemplateViewPath, model)); }
public async Task <IViewComponentResult> InvokeAsync(int?productThumbPictureSize, bool?preparePriceModel) { if (!_catalogSettings.RecentlyViewedProductsEnabled) { return(Content("")); } var preparePictureModel = productThumbPictureSize.HasValue; var products = await(await _recentlyViewedProductsService.GetRecentlyViewedProductsAsync(_catalogSettings.RecentlyViewedProductsNumber)) //ACL and store mapping .WhereAwait(async p => await _aclService.AuthorizeAsync(p) && await _storeMappingService.AuthorizeAsync(p)) //availability dates .Where(p => _productService.ProductIsAvailable(p)).ToListAsync(); if (!products.Any()) { return(Content("")); } //prepare model var model = new List <ProductOverviewModel>(); model.AddRange(await _productModelFactory.PrepareProductOverviewModelsAsync(products, preparePriceModel.GetValueOrDefault(), preparePictureModel, productThumbPictureSize)); return(View(model)); }
public async Task <IViewComponentResult> InvokeAsync(int?productThumbPictureSize) { var cart = await _shoppingCartService.GetShoppingCartAsync(await _workContext.GetCurrentCustomerAsync(), ShoppingCartType.ShoppingCart, (await _storeContext.GetCurrentStoreAsync()).Id); var products = await(await _productService.GetCrossSellProductsByShoppingCartAsync(cart, _shoppingCartSettings.CrossSellsNumber)) //ACL and store mapping .WhereAwait(async p => await _aclService.AuthorizeAsync(p) && await _storeMappingService.AuthorizeAsync(p)) //availability dates .Where(p => _productService.ProductIsAvailable(p)) //visible individually .Where(p => p.VisibleIndividually).ToListAsync(); if (!products.Any()) { return(Content("")); } //Cross-sell products are displayed on the shopping cart page. //We know that the entire shopping cart page is not refresh //even if "ShoppingCartSettings.DisplayCartAfterAddingProduct" setting is enabled. //That's why we force page refresh (redirect) in this case var model = (await _productModelFactory.PrepareProductOverviewModelsAsync(products, productThumbPictureSize: productThumbPictureSize, forceRedirectionAfterAddingToCart: true)) .ToList(); return(View(model)); }
/// <returns>A task that represents the asynchronous operation</returns> public virtual async Task <IActionResult> ProductDetails(int productId, int updatecartitemid = 0) { var product = await _productService.GetProductByIdAsync(productId); if (product == null || product.Deleted) { return(InvokeHttp404()); } var notAvailable = //published? (!product.Published && !_catalogSettings.AllowViewUnpublishedProductPage) || //ACL (access control list) !await _aclService.AuthorizeAsync(product) || //Store mapping !await _storeMappingService.AuthorizeAsync(product) || //availability dates !_productService.ProductIsAvailable(product); //Check whether the current user has a "Manage products" permission (usually a store owner) //We should allows him (her) to use "Preview" functionality var hasAdminAccess = await _permissionService.AuthorizeAsync(StandardPermissionProvider.AccessAdminPanel) && await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageProducts); if (notAvailable && !hasAdminAccess) { return(InvokeHttp404()); } //visible individually? if (!product.VisibleIndividually) { //is this one an associated products? var parentGroupedProduct = await _productService.GetProductByIdAsync(product.ParentGroupedProductId); if (parentGroupedProduct == null) { return(RedirectToRoute("Homepage")); } return(RedirectToRoutePermanent("Product", new { SeName = await _urlRecordService.GetSeNameAsync(parentGroupedProduct) })); } //update existing shopping cart or wishlist item? ShoppingCartItem updatecartitem = null; if (_shoppingCartSettings.AllowCartItemEditing && updatecartitemid > 0) { var cart = await _shoppingCartService.GetShoppingCartAsync(await _workContext.GetCurrentCustomerAsync(), storeId : (await _storeContext.GetCurrentStoreAsync()).Id); updatecartitem = cart.FirstOrDefault(x => x.Id == updatecartitemid); //not found? if (updatecartitem == null) { return(RedirectToRoute("Product", new { SeName = await _urlRecordService.GetSeNameAsync(product) })); } //is it this product? if (product.Id != updatecartitem.ProductId) { return(RedirectToRoute("Product", new { SeName = await _urlRecordService.GetSeNameAsync(product) })); } } //save as recently viewed await _recentlyViewedProductsService.AddProductToRecentlyViewedListAsync(product.Id); //display "edit" (manage) link if (await _permissionService.AuthorizeAsync(StandardPermissionProvider.AccessAdminPanel) && await _permissionService.AuthorizeAsync(StandardPermissionProvider.ManageProducts)) { //a vendor should have access only to his products if (await _workContext.GetCurrentVendorAsync() == null || (await _workContext.GetCurrentVendorAsync()).Id == product.VendorId) { DisplayEditLink(Url.Action("Edit", "Product", new { id = product.Id, area = AreaNames.Admin })); } } //activity log await _customerActivityService.InsertActivityAsync("PublicStore.ViewProduct", string.Format(await _localizationService.GetResourceAsync("ActivityLog.PublicStore.ViewProduct"), product.Name), product); //model var model = await _productModelFactory.PrepareProductDetailsModelAsync(product, updatecartitem, false); //template var productTemplateViewPath = await _productModelFactory.PrepareProductTemplateViewPathAsync(product); return(View(productTemplateViewPath, model)); }
public virtual async Task <IList <string> > ValidateProductAsync(AddToCartContext ctx, IEnumerable <OrganizedShoppingCartItem> shoppingCart) { Guard.NotNull(ctx, nameof(ctx)); var warnings = new List <string>(); var product = ctx.Product; var cartType = ctx.CartType; if (product.Deleted) { warnings.Add(T("ShoppingCart.ProductDeleted")); ctx.Warnings.AddRange(warnings); return(ctx.Warnings); } // Grouped products are not available for order if (product.ProductType == ProductType.GroupedProduct) { warnings.Add(T("ShoppingCart.ProductNotAvailableForOrder")); } // Validate product bundle, no customer entered price allowed if (product.ProductType == ProductType.BundledProduct && product.BundlePerItemPricing && ctx.CustomerEnteredPrice != decimal.Zero) { warnings.Add(T("ShoppingCart.Bundle.NoCustomerEnteredPrice")); } // Not published or no permissions for customer or store if (!product.Published || !await _aclService.AuthorizeAsync(product, ctx.Customer) || !await _storeMappingService.AuthorizeAsync(product.Name, product.Id, ctx.StoreId ?? _storeContext.CurrentStore.Id)) { warnings.Add(T("ShoppingCart.ProductUnpublished")); } // Disabled buy button if (cartType == ShoppingCartType.ShoppingCart && product.DisableBuyButton) { warnings.Add(T("ShoppingCart.BuyingDisabled")); } // Disabled wishlist button if (cartType == ShoppingCartType.Wishlist && product.DisableWishlistButton) { warnings.Add(T("ShoppingCart.WishlistDisabled")); } // Call for price if (cartType == ShoppingCartType.ShoppingCart && product.CallForPrice) { warnings.Add(T("Products.CallForPrice")); } // Customer entered price if (product.CustomerEntersPrice && (ctx.CustomerEnteredPrice < product.MinimumCustomerEnteredPrice || ctx.CustomerEnteredPrice > product.MaximumCustomerEnteredPrice)) { var minimum = _currencyService.ConvertFromPrimaryStoreCurrency(product.MinimumCustomerEnteredPrice, _workContext.WorkingCurrency); var maximum = _currencyService.ConvertFromPrimaryStoreCurrency(product.MaximumCustomerEnteredPrice, _workContext.WorkingCurrency); var moneyMin = _currencyService.CreateMoney(minimum, true, displayTax: false); var moneyMax = _currencyService.CreateMoney(maximum, true, displayTax: false); warnings.Add(T("ShoppingCart.CustomerEnteredPrice.RangeError", moneyMin.ToString(), moneyMax.ToString())); } // Quantity validation if (ctx.Quantity <= 0) { warnings.Add(T("ShoppingCart.QuantityShouldPositive")); } if (ctx.Quantity < product.OrderMinimumQuantity) { warnings.Add(T("ShoppingCart.MinimumQuantity", product.OrderMinimumQuantity)); } if (ctx.Quantity > product.OrderMaximumQuantity) { warnings.Add(T("ShoppingCart.MaximumQuantity", product.OrderMaximumQuantity)); } var allowedQuantities = product.ParseAllowedQuantities(); if (allowedQuantities.Length > 0 && !allowedQuantities.Contains(ctx.Quantity)) { warnings.Add(T("ShoppingCart.AllowedQuantities", string.Join(", ", allowedQuantities))); } // Stock validation var validateOutOfStock = ctx.CartType == ShoppingCartType.ShoppingCart || !_cartSettings.AllowOutOfStockItemsToBeAddedToWishlist; if (validateOutOfStock) { switch (product.ManageInventoryMethod) { case ManageInventoryMethod.ManageStock: { if (product.BackorderMode != BackorderMode.NoBackorders || product.StockQuantity >= ctx.Quantity) { break; } var warning = product.StockQuantity > 0 ? T("ShoppingCart.QuantityExceedsStock", product.StockQuantity) : T("ShoppingCart.OutOfStock"); warnings.Add(warning); } break; case ManageInventoryMethod.ManageStockByAttributes: { var combination = await _productAttributeMaterializer.FindAttributeCombinationAsync(product.Id, ctx.AttributeSelection); if (combination == null || combination.AllowOutOfStockOrders || combination.StockQuantity >= ctx.Quantity) { break; } var warning = combination.StockQuantity > 0 ? T("ShoppingCart.QuantityExceedsStock", combination.StockQuantity) : T("ShoppingCart.OutOfStock"); warnings.Add(warning); } break; case ManageInventoryMethod.DontManageStock: default: break; } } // Validate availability var availableStartDateError = false; if (ctx.Product.AvailableStartDateTimeUtc.HasValue) { var availableStartDate = DateTime.SpecifyKind(ctx.Product.AvailableStartDateTimeUtc.Value, DateTimeKind.Utc); if (availableStartDate.CompareTo(DateTime.UtcNow) > 0) { warnings.Add(T("ShoppingCart.NotAvailable")); availableStartDateError = true; } } if (ctx.Product.AvailableEndDateTimeUtc.HasValue && !availableStartDateError) { var availableEndDate = DateTime.SpecifyKind(ctx.Product.AvailableEndDateTimeUtc.Value, DateTimeKind.Utc); if (availableEndDate.CompareTo(DateTime.UtcNow) < 0) { warnings.Add(T("ShoppingCart.NotAvailable")); } } ctx.Warnings.AddRange(warnings); return(warnings); }