private async Task <(string Price, string PriceWithDiscount)> PreparePrice(Product product, GetSearchAutoComplete request) { string price, priceWithDiscount; double finalPriceWithoutDiscount = (await(_taxService.GetProductPrice(product, (await _pricingService.GetFinalPrice(product, request.Customer, request.Currency, includeDiscounts: false)).finalPrice))).productprice; var appliedPrice = (await _pricingService.GetFinalPrice(product, request.Customer, request.Currency, includeDiscounts: true)); var finalPriceWithDiscount = (await _taxService.GetProductPrice(product, appliedPrice.finalPrice)).productprice; price = _priceFormatter.FormatPrice(finalPriceWithoutDiscount); priceWithDiscount = _priceFormatter.FormatPrice(finalPriceWithDiscount); return(price, priceWithDiscount); }
private async Task <ProductOverviewModel.ProductPriceModel> PreparePriceModel(Product product, Dictionary <string, string> res, bool forceRedirectionAfterAddingToCart, bool enableShoppingCart, bool displayPrices, bool enableWishlist, bool priceIncludesTax) { #region Prepare product price var priceModel = new ProductOverviewModel.ProductPriceModel { ForceRedirectionAfterAddingToCart = forceRedirectionAfterAddingToCart }; switch (product.ProductTypeId) { case ProductType.GroupedProduct: { #region Grouped product var associatedProducts = await _productService.GetAssociatedProducts(product.Id, _workContext.CurrentStore.Id); //add to cart button (ignore "DisableBuyButton" property for grouped products) priceModel.DisableBuyButton = !enableShoppingCart || !displayPrices; //add to wishlist button (ignore "DisableWishlistButton" property for grouped products) priceModel.DisableWishlistButton = !enableWishlist || !displayPrices; //compare products priceModel.DisableAddToCompareListButton = !_catalogSettings.CompareProductsEnabled; //catalog price, not used in views, but it's for front developer if (product.CatalogPrice > 0) { double catalogPrice = await _currencyService.ConvertFromPrimaryStoreCurrency(product.CatalogPrice, _workContext.WorkingCurrency); priceModel.CatalogPrice = _priceFormatter.FormatPrice(catalogPrice, _workContext.WorkingCurrency, _workContext.WorkingLanguage, priceIncludesTax); } switch (associatedProducts.Count) { case 0: { } break; default: { //we have at least one associated product //compare products priceModel.DisableAddToCompareListButton = !_catalogSettings.CompareProductsEnabled; if (displayPrices) { //find a minimum possible price double? minPossiblePrice = null; Product minPriceProduct = null; foreach (var associatedProduct in associatedProducts) { //calculate for the maximum quantity (in case if we have tier prices) var tmpPrice = (await _pricingService.GetFinalPrice(associatedProduct, _workContext.CurrentCustomer, _workContext.WorkingCurrency, 0, true, int.MaxValue)).finalPrice; if (!minPossiblePrice.HasValue || tmpPrice < minPossiblePrice.Value) { minPriceProduct = associatedProduct; minPossiblePrice = tmpPrice; } } if (minPriceProduct != null && !minPriceProduct.EnteredPrice) { if (minPriceProduct.CallForPrice) { priceModel.OldPrice = null; priceModel.Price = res["Products.CallForPrice"]; } else if (minPossiblePrice.HasValue) { //calculate prices double finalPrice = (await _taxService.GetProductPrice(minPriceProduct, minPossiblePrice.Value, priceIncludesTax, _workContext.CurrentCustomer)).productprice; priceModel.OldPrice = null; priceModel.Price = string.Format(res["Products.PriceRangeFrom"], _priceFormatter.FormatPrice(finalPrice, _workContext.WorkingCurrency, _workContext.WorkingLanguage, priceIncludesTax)); priceModel.PriceValue = finalPrice; //PAngV baseprice (used in Germany) if (product.BasepriceEnabled) { priceModel.BasePricePAngV = await _mediator.Send(new GetFormatBasePrice() { Currency = _workContext.WorkingCurrency, Product = product, ProductPrice = finalPrice }); } } else { //Actually it's not possible (we presume that minimalPrice always has a value) //We never should get here Debug.WriteLine("Cannot calculate minPrice for product #{0}", product.Id); } } } else { //hide prices priceModel.OldPrice = null; priceModel.Price = null; } } break; } #endregion } break; case ProductType.SimpleProduct: case ProductType.Reservation: default: { #region Simple product //add to cart button priceModel.DisableBuyButton = product.DisableBuyButton || !enableShoppingCart || !displayPrices; //add to wishlist button priceModel.DisableWishlistButton = product.DisableWishlistButton || !enableWishlist || !displayPrices; //compare products priceModel.DisableAddToCompareListButton = !_catalogSettings.CompareProductsEnabled; //pre-order if (product.AvailableForPreOrder) { priceModel.AvailableForPreOrder = !product.PreOrderDateTimeUtc.HasValue || product.PreOrderDateTimeUtc.Value >= DateTime.UtcNow; priceModel.PreOrderDateTimeUtc = product.PreOrderDateTimeUtc; } //catalog price, not used in views, but it's for front developer if (product.CatalogPrice > 0) { double catalogPrice = await _currencyService.ConvertFromPrimaryStoreCurrency(product.CatalogPrice, _workContext.WorkingCurrency); priceModel.CatalogPrice = _priceFormatter.FormatPrice(catalogPrice, _workContext.WorkingCurrency, _workContext.WorkingLanguage, priceIncludesTax); } //start price for product auction if (product.StartPrice > 0) { double startPrice = await _currencyService.ConvertFromPrimaryStoreCurrency(product.StartPrice, _workContext.WorkingCurrency); priceModel.StartPrice = _priceFormatter.FormatPrice(startPrice, _workContext.WorkingCurrency, _workContext.WorkingLanguage, priceIncludesTax); priceModel.StartPriceValue = startPrice; } //highest bid for product auction if (product.HighestBid > 0) { double highestBid = await _currencyService.ConvertFromPrimaryStoreCurrency(product.HighestBid, _workContext.WorkingCurrency); priceModel.HighestBid = _priceFormatter.FormatPrice(highestBid, _workContext.WorkingCurrency, _workContext.WorkingLanguage, priceIncludesTax); priceModel.HighestBidValue = highestBid; } //prices if (displayPrices) { if (!product.EnteredPrice) { if (product.CallForPrice) { //call for price priceModel.OldPrice = null; priceModel.Price = res["Products.CallForPrice"]; } else { //prices //calculate for the maximum quantity (in case if we have tier prices) var infoprice = (await _pricingService.GetFinalPrice(product, _workContext.CurrentCustomer, _workContext.WorkingCurrency, 0, true, int.MaxValue)); priceModel.AppliedDiscounts = infoprice.appliedDiscounts; priceModel.PreferredTierPrice = infoprice.preferredTierPrice; double minPossiblePrice = infoprice.finalPrice; double oldPriceBase = (await _taxService.GetProductPrice(product, product.OldPrice, priceIncludesTax, _workContext.CurrentCustomer)).productprice; double finalPrice = (await _taxService.GetProductPrice(product, minPossiblePrice, priceIncludesTax, _workContext.CurrentCustomer)).productprice; double oldPrice = await _currencyService.ConvertFromPrimaryStoreCurrency(oldPriceBase, _workContext.WorkingCurrency); //do we have tier prices configured? var tierPrices = new List <TierPrice>(); if (product.TierPrices.Any()) { tierPrices.AddRange(product.TierPrices.OrderBy(tp => tp.Quantity) .FilterByStore(_workContext.CurrentStore.Id) .FilterByCurrency(_workContext.WorkingCurrency.CurrencyCode) .FilterForCustomer(_workContext.CurrentCustomer) .FilterByDate() .RemoveDuplicatedQuantities()); } //When there is just one tier (with qty 1), //there are no actual savings in the list. bool displayFromMessage = tierPrices.Any() && !(tierPrices.Count == 1 && tierPrices[0].Quantity <= 1); if (displayFromMessage) { priceModel.OldPrice = null; priceModel.Price = string.Format(res["Products.PriceRangeFrom"], _priceFormatter.FormatPrice(finalPrice, _workContext.WorkingCurrency, _workContext.WorkingLanguage, priceIncludesTax)); priceModel.PriceValue = finalPrice; } else { if (finalPrice != oldPriceBase && oldPriceBase != 0) { priceModel.OldPrice = _priceFormatter.FormatPrice(oldPrice, _workContext.WorkingCurrency, _workContext.WorkingLanguage, priceIncludesTax); priceModel.OldPriceValue = oldPrice; priceModel.Price = _priceFormatter.FormatPrice(finalPrice, _workContext.WorkingCurrency, _workContext.WorkingLanguage, priceIncludesTax); priceModel.PriceValue = finalPrice; } else { priceModel.OldPrice = null; priceModel.Price = _priceFormatter.FormatPrice(finalPrice, _workContext.WorkingCurrency, _workContext.WorkingLanguage, priceIncludesTax); priceModel.PriceValue = finalPrice; } } if (product.ProductTypeId == ProductType.Reservation) { //rental product priceModel.OldPrice = _priceFormatter.FormatReservationProductPeriod(product, priceModel.OldPrice); priceModel.Price = _priceFormatter.FormatReservationProductPeriod(product, priceModel.Price); } //PAngV baseprice (used in Germany) if (product.BasepriceEnabled) { priceModel.BasePricePAngV = await _mediator.Send(new GetFormatBasePrice() { Currency = _workContext.WorkingCurrency, Product = product, ProductPrice = finalPrice }); } } } } else { //hide prices priceModel.OldPrice = null; priceModel.Price = null; } #endregion } break; } return(priceModel); #endregion }
public async Task Can_get_final_product_price() { var product = new Product { Id = "1", Name = "product name 01", Price = 49.99, EnteredPrice = false, Published = true, }; product.ProductPrices.Add(new ProductPrice() { CurrencyCode = "USD", Price = 49.99 }); var currency = new Currency { Id = "1", CurrencyCode = "USD", Rate = 1, Published = true, MidpointRoundId = System.MidpointRounding.ToEven, RoundingTypeId = RoundingType.Rounding001 }; var customer = new Customer(); var pr = (await _pricingService.GetFinalPrice(product, customer, currency, 0, false, 1)); Assert.AreEqual(49.99, pr.finalPrice); //returned price FOR ONE UNIT should be the same, even if quantity is different than 1 Assert.AreEqual(49.99, (await _pricingService.GetFinalPrice(product, customer, _currency, 0, false, 10)).finalPrice); }