private async Task ValidateItemsAsync(ShoppingCart cart) { var workContext = _workContextFactory(); var productIds = cart.Items.Select(i => i.ProductId).ToArray(); var cacheKey = "CartValidator.ValidateItemsAsync-" + workContext.CurrentCurrency.Code + ":" + workContext.CurrentLanguage + ":" + string.Join(":", productIds); var products = await _cacheManager.GetAsync(cacheKey, "ApiRegion", async() => { return(await _catalogService.GetProductsAsync(productIds, ItemResponseGroup.ItemLarge)); }); var productsToReevaluate = GetProductsToReevaluate(cart, products); // Reevaluate products promotions for getting new product prices to compare with if (productsToReevaluate.Any()) { var promotionContext = workContext.ToPromotionEvaluationContext(productsToReevaluate); await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, productsToReevaluate); } foreach (var lineItem in cart.Items.ToList()) { lineItem.ValidationErrors.Clear(); var product = products.FirstOrDefault(p => p.Id == lineItem.ProductId); if (product == null || (product != null && (!product.IsActive || !product.IsBuyable))) { lineItem.ValidationErrors.Add(new ProductUnavailableError()); } else if (product != null) { if (product.TrackInventory && product.Inventory != null && (lineItem.ValidationType == ValidationType.PriceAndQuantity || lineItem.ValidationType == ValidationType.Quantity)) { var availableQuantity = product.Inventory.InStockQuantity; if (product.Inventory.ReservedQuantity.HasValue) { availableQuantity -= product.Inventory.ReservedQuantity.Value; } if (availableQuantity.HasValue && lineItem.Quantity > availableQuantity.Value) { lineItem.ValidationErrors.Add(new ProductQuantityError(availableQuantity.Value)); } } if (lineItem.PlacedPrice != product.Price.ActualPrice && (lineItem.ValidationType == ValidationType.PriceAndQuantity || lineItem.ValidationType == ValidationType.Price)) { var newLineItem = product.ToLineItem(workContext.CurrentLanguage, lineItem.Quantity); newLineItem.ValidationWarnings.Add(new ProductPriceError(lineItem.PlacedPrice)); cart.Items.Remove(lineItem); cart.Items.Add(newLineItem); } } } // Reevaluate shopping cart for applying promotions for changed product prices if (productsToReevaluate.Any()) { var promotionContext = workContext.ToPromotionEvaluationContext(); await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, new[] { cart }); } }
public virtual async Task <ICollection <ShippingMethod> > GetAvailableShippingMethodsAsync() { var availableShippingMethods = new List <ShippingMethod>(); // TODO: Remake with shipmentId var serviceModels = await _cartApi.CartModuleGetShipmentMethodsAsync(_cart.Id); foreach (var serviceModel in serviceModels) { availableShippingMethods.Add(serviceModel.ToWebModel(_cart.Currency)); } //Evaluate tax for shipping methods var taxEvalContext = _cart.ToTaxEvalContext(); taxEvalContext.Lines.Clear(); taxEvalContext.Lines.AddRange(availableShippingMethods.Select(x => x.ToTaxLine())); var taxResult = await _commerceApi.CommerceEvaluateTaxesAsync(_cart.StoreId, taxEvalContext); if (taxResult != null) { var taxRates = taxResult.Select(x => x.ToWebModel(_cart.Currency)).ToList(); foreach (var shippingMethod in availableShippingMethods) { shippingMethod.ApplyTaxRates(taxRates); } } //Evaluate promotions for shipping methods var promoEvalContext = _cart.ToPromotionEvaluationContext(); await _promotionEvaluator.EvaluateDiscountsAsync(promoEvalContext, availableShippingMethods); return(availableShippingMethods); }
public virtual async Task EvaluateProductPricesAsync(IEnumerable <Product> products, WorkContext workContext) { if (products == null) { throw new ArgumentNullException(nameof(products)); } if (workContext == null) { throw new ArgumentNullException(nameof(workContext)); } //Evaluate products prices var evalContext = workContext.ToPriceEvaluationContext(products); var cacheKey = CacheKey.With(GetType(), "EvaluateProductPricesAsync", evalContext.GetCacheKey()); var pricesResponse = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) => { cacheEntry.AddExpirationToken(PricingCacheRegion.CreateChangeToken()); cacheEntry.AddExpirationToken(_apiChangesWatcher.CreateChangeToken()); return(await _pricingApi.EvaluatePricesAsync(evalContext.ToPriceEvaluationContextDto())); }); ApplyProductPrices(products, pricesResponse, workContext); //Evaluate product discounts //Fill product inventories for getting InStockQuantity data for promotion evaluation await _inventoryService.EvaluateProductInventoriesAsync(products.ToList(), workContext); var promoEvalContext = workContext.ToPromotionEvaluationContext(products); await _promotionEvaluator.EvaluateDiscountsAsync(promoEvalContext, products); //Evaluate product taxes var taxEvalContext = workContext.ToTaxEvaluationContext(products); await _taxEvaluator.EvaluateTaxesAsync(taxEvalContext, products); }
private async Task LoadProductsDiscountsAsync(Product[] products) { var promotionContext = _workContext.ToPromotionEvaluationContext(); promotionContext.PromoEntries = products.Select(x => x.ToPromotionItem()).ToList(); await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, products); }
private async Task LoadProductsDiscountsAsync(IEnumerable <Product> products) { var workContext = _workContextFactory(); var promotionContext = workContext.ToPromotionEvaluationContext(products); promotionContext.PromoEntries = products.Select(x => x.ToPromotionItem()).ToList(); await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, products); }
public virtual async Task<IEnumerable<ShippingMethod>> GetAvailableShippingMethodsAsync() { var workContext = _workContextAccessor.WorkContext; //Request available shipping rates var retVal = await _cartService.GetAvailableShippingMethodsAsync(Cart); //Evaluate promotions cart and apply rewards for available shipping methods var promoEvalContext = Cart.ToPromotionEvaluationContext(); await _promotionEvaluator.EvaluateDiscountsAsync(promoEvalContext, retVal); //Evaluate taxes for available shipping rates var taxEvalContext = Cart.ToTaxEvalContext(workContext.CurrentStore); taxEvalContext.Lines.Clear(); taxEvalContext.Lines.AddRange(retVal.SelectMany(x => x.ToTaxLines())); await _taxEvaluator.EvaluateTaxesAsync(taxEvalContext, retVal); return retVal; }
public async Task <ActionResult> GetActualProductPricesJson(Product[] products) { var prices = new List <ProductPrice>(); if (products == null) { return(Json(prices, JsonRequestBehavior.AllowGet)); } var pricesResponse = await _pricingApi.PricingModuleEvaluatePricesAsync( evalContextProductIds : products.Select(p => p.Id).ToList(), evalContextCatalogId : WorkContext.CurrentStore.Catalog, evalContextCurrency : WorkContext.CurrentCurrency.Code, evalContextCustomerId : WorkContext.CurrentCustomer.Id, evalContextLanguage : WorkContext.CurrentLanguage.CultureName, evalContextStoreId : WorkContext.CurrentStore.Id); if (pricesResponse == null) { return(Json(prices, JsonRequestBehavior.AllowGet)); } prices = pricesResponse.Select(p => p.ToWebModel()).ToList(); var promotionContext = new PromotionEvaluationContext { CartPromoEntries = GetCartPromoEntries(WorkContext.CurrentCart), Currency = WorkContext.CurrentCurrency, CustomerId = WorkContext.CurrentCustomer.Id, IsRegisteredUser = WorkContext.CurrentCustomer.HasAccount, Language = WorkContext.CurrentLanguage, PromoEntries = GetPromoEntries(products, prices), StoreId = WorkContext.CurrentStore.Id }; foreach (var product in products) { product.Currency = WorkContext.CurrentCurrency; product.Price = prices.FirstOrDefault(p => p.ProductId == product.Id); } await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, products); prices = products.Select(p => p.Price).ToList(); foreach (var price in prices) { if (price.ActiveDiscount != null) { price.AbsoluteBenefit += price.ActiveDiscount.Amount; price.ActualPrice = price.SalePrice - price.AbsoluteBenefit; } } return(Json(prices, JsonRequestBehavior.AllowGet)); }
public virtual async Task <ICollection <ShippingMethod> > GetAvailableShippingMethodsAsync() { var workContext = _workContextFactory(); //Request available shipping rates var shippingRates = await _cartApi.CartModule.GetAvailableShippingRatesAsync(Cart.Id); var retVal = shippingRates.Select(x => x.ToShippingMethod(Cart.Currency, workContext.AllCurrencies)).OrderBy(x => x.Priority).ToList(); //Evaluate promotions cart and apply rewards for available shipping methods var promoEvalContext = Cart.ToPromotionEvaluationContext(); await _promotionEvaluator.EvaluateDiscountsAsync(promoEvalContext, retVal); //Evaluate taxes for available shipping rates var taxEvalContext = Cart.ToTaxEvalContext(); taxEvalContext.Lines.Clear(); taxEvalContext.Lines.AddRange(retVal.SelectMany(x => x.ToTaxLines())); await _taxEvaluator.EvaluateTaxesAsync(taxEvalContext, retVal); return(retVal); }
public virtual async Task EvaluateProductPricesAsync(ICollection <Product> products, WorkContext workContext) { //Evaluate products prices var evalContext = workContext.ToPriceEvaluationContextDto(products); var pricesResponse = await _pricingApi.PricingModule.EvaluatePricesAsync(evalContext); ApplyProductPricesInternal(products, pricesResponse, workContext); //Evaluate product discounts var promoEvalContext = workContext.ToPromotionEvaluationContext(products); await _promotionEvaluator.EvaluateDiscountsAsync(promoEvalContext, products); //Evaluate product taxes var taxEvalContext = workContext.ToTaxEvaluationContext(products); await _taxEvaluator.EvaluateTaxesAsync(taxEvalContext, products); }
public async Task <ActionResult> GetActualProductPricesJson(Product[] products) { if (products == null) { throw new ArgumentNullException("products"); } //Evaluate products prices await _pricingService.EvaluateProductPricesAsync(products); //Evaluate discounts var promotionContext = WorkContext.ToPromotionEvaluationContext(); promotionContext.PromoEntries = products.Select(x => x.ToPromotionItem()).ToList(); await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, products); var retVal = products.Select(x => x.Price).ToArray(); return(Json(retVal, JsonRequestBehavior.AllowGet)); }
public async Task <ActionResult> GetActualProductPrices(Product[] products) { if (products != null) { //Evaluate products prices await _pricingService.EvaluateProductPricesAsync(products); //Evaluate discounts var promotionContext = WorkContext.ToPromotionEvaluationContext(products); promotionContext.PromoEntries = products.Select(x => x.ToPromotionItem()).ToList(); await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, products); var retVal = products.Select(x => x.Price).ToArray(); return(Json(retVal)); } return(new HttpStatusCodeResult(HttpStatusCode.OK)); }
private async Task EvaluatePromotionsAsync() { var promotionItems = _cart.Items.Select(i => i.ToPromotionItem()).ToList(); var promotionContext = new PromotionEvaluationContext(); promotionContext.CartPromoEntries = promotionItems; promotionContext.CartTotal = _cart.Total; promotionContext.Coupon = _cart.Coupon != null ? _cart.Coupon.Code : null; promotionContext.Currency = _cart.Currency; promotionContext.CustomerId = _customer.Id; promotionContext.IsRegisteredUser = _customer.HasAccount; promotionContext.Language = _language; promotionContext.PromoEntries = promotionItems; promotionContext.StoreId = _store.Id; await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, new IDiscountable[] { _cart }); CalculateTotals(); }
public virtual async Task <ICartBuilder> EvaluatePromotionsAsync() { var promotionItems = _cart.Items.Select(i => i.ToPromotionItem()).ToList(); var promotionContext = new PromotionEvaluationContext(); promotionContext.CartPromoEntries = promotionItems; promotionContext.CartTotal = _cart.Total; promotionContext.Coupon = _cart.Coupon != null ? _cart.Coupon.Code : null; promotionContext.Currency = _cart.Currency; promotionContext.CustomerId = _cart.Customer.Id; promotionContext.IsRegisteredUser = _cart.Customer.IsRegisteredUser; promotionContext.Language = _cart.Language; promotionContext.PromoEntries = promotionItems; promotionContext.StoreId = _cart.StoreId; await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, new IDiscountable[] { _cart }); return(this); }
public virtual async Task EvaluateProductPricesAsync(ICollection <Product> products, WorkContext workContext) { //Evaluate products prices var evalContext = workContext.ToPriceEvaluationContextDto(products); var pricesResponse = await _pricingApi.PricingModule.EvaluatePricesAsync(evalContext); ApplyProductPricesInternal(products, pricesResponse, workContext); //Evaluate product discounts //Fill product inventories for getting InStockQuantity data for promotion evaluation await _inventoryService.EvaluateProductInventoriesAsync(products, workContext); var promoEvalContext = workContext.ToPromotionEvaluationContext(products); await _promotionEvaluator.EvaluateDiscountsAsync(promoEvalContext, products); //Evaluate product taxes var taxEvalContext = workContext.ToTaxEvaluationContext(products); await _taxEvaluator.EvaluateTaxesAsync(taxEvalContext, products); }
public async Task <ActionResult> GetActualProductPricesJson(Product[] products) { var prices = new List <ProductPrice>(); if (products == null) { return(Json(prices, JsonRequestBehavior.AllowGet)); } var pricesResponse = await _pricingApi.PricingModuleEvaluatePricesAsync( evalContextProductIds : products.Select(p => p.Id).ToList(), evalContextCatalogId : WorkContext.CurrentStore.Catalog, evalContextCurrency : WorkContext.CurrentCurrency.Code, evalContextCustomerId : WorkContext.CurrentCustomer.Id, evalContextLanguage : WorkContext.CurrentLanguage.CultureName, evalContextStoreId : WorkContext.CurrentStore.Id); if (pricesResponse == null) { return(Json(prices, JsonRequestBehavior.AllowGet)); } prices = pricesResponse.Select(p => p.ToWebModel()).ToList(); var promotionContext = WorkContext.ToPromotionEvaluationContext(); promotionContext.PromoEntries = GetPromoEntries(products, prices); foreach (var product in products) { product.Currency = WorkContext.CurrentCurrency; product.Price = prices.FirstOrDefault(p => p.ProductId == product.Id); } await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, products); return(Json(prices, JsonRequestBehavior.AllowGet)); }