public void Can_calculate_rental_periods_for_days() { var product = new Product { IsRental = true, RentalPricePeriod = RentalPricePeriod.Days }; //rental period length = 1 day product.RentalPriceLength = 1; //the same date product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 5)).ShouldEqual(1); //1 day product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 6)).ShouldEqual(1); //2 days product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 7)).ShouldEqual(2); //3 days product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 8)).ShouldEqual(3); //rental period length = 2 days product.RentalPriceLength = 2; //the same date product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 5)).ShouldEqual(1); //1 day product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 6)).ShouldEqual(1); //2 days product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 7)).ShouldEqual(1); //3 days product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 8)).ShouldEqual(2); }
/// <summary> /// Gets the final price /// </summary> /// <param name="product">Product</param> /// <param name="customer">The customer</param> /// <param name="overriddenProductPrice">Overridden product price. If specified, then it'll be used instead of a product price. For example, used with product attribute combinations</param> /// <param name="additionalCharge">Additional charge</param> /// <param name="includeDiscounts">A value indicating whether include discounts or not for final price computation</param> /// <param name="quantity">Shopping cart item quantity</param> /// <param name="rentalStartDate">Rental period start date (for rental products)</param> /// <param name="rentalEndDate">Rental period end date (for rental products)</param> /// <param name="discountAmount">Applied discount amount</param> /// <param name="appliedDiscounts">Applied discounts</param> /// <returns>Final price</returns> public virtual decimal GetFinalPrice(Product product, Customer customer, decimal? overriddenProductPrice, decimal additionalCharge, bool includeDiscounts, int quantity, DateTime? rentalStartDate, DateTime? rentalEndDate, out decimal discountAmount, out List<Discount> appliedDiscounts) { if (product == null) throw new ArgumentNullException("product"); discountAmount = decimal.Zero; appliedDiscounts = new List<Discount>(); var cacheKey = string.Format(PriceCacheEventConsumer.PRODUCT_PRICE_MODEL_KEY, product.Id, overriddenProductPrice.HasValue ? overriddenProductPrice.Value.ToString(CultureInfo.InvariantCulture) : null, additionalCharge.ToString(CultureInfo.InvariantCulture), includeDiscounts, quantity, string.Join(",", customer.GetCustomerRoleIds()), _storeContext.CurrentStore.Id); var cacheTime = _catalogSettings.CacheProductPrices ? 60 : 0; //we do not cache price for rental products //otherwise, it can cause memory leaks (to store all possible date period combinations) if (product.IsRental) cacheTime = 0; var cachedPrice = _cacheManager.Get(cacheKey, cacheTime, () => { var result = new ProductPriceForCaching(); //initial price decimal price = overriddenProductPrice.HasValue ? overriddenProductPrice.Value : product.Price; //special price var specialPrice = product.GetSpecialPrice(); if (specialPrice.HasValue) price = specialPrice.Value; //tier prices if (product.HasTierPrices) { decimal? tierPrice = GetMinimumTierPrice(product, customer, quantity); if (tierPrice.HasValue) price = Math.Min(price, tierPrice.Value); } //additional charge price = price + additionalCharge; //rental products if (product.IsRental) if (rentalStartDate.HasValue && rentalEndDate.HasValue) price = price * product.GetRentalPeriods(rentalStartDate.Value, rentalEndDate.Value); if (includeDiscounts) { //discount List<Discount> tmpAppliedDiscounts; decimal tmpDiscountAmount = GetDiscountAmount(product, customer, price, out tmpAppliedDiscounts); price = price - tmpDiscountAmount; if (tmpAppliedDiscounts != null) { result.AppliedDiscountIds = tmpAppliedDiscounts.Select(x=>x.Id).ToList(); result.AppliedDiscountAmount = tmpDiscountAmount; } } if (price < decimal.Zero) price = decimal.Zero; result.Price = price; return result; }); if (includeDiscounts) { //Discount instance cannnot be cached between requests (when "catalogSettings.CacheProductPrices" is "true) //This is limitation of Entity Framework //That's why we load it here after working with cache foreach (var appliedDiscountId in cachedPrice.AppliedDiscountIds) { var appliedDiscount = _discountService.GetDiscountById(appliedDiscountId); if (appliedDiscount != null) appliedDiscounts.Add(appliedDiscount); } if (appliedDiscounts.Any()) { discountAmount = cachedPrice.AppliedDiscountAmount; } } return cachedPrice.Price; }
public void Can_calculate_rental_periods_for_months() { var product = new Product { IsRental = true, RentalPricePeriod = RentalPricePeriod.Months }; //rental period length = 1 month product.RentalPriceLength = 1; //the same date product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 5)).ShouldEqual(1); //several days but less than a month product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 4)).ShouldEqual(1); //1 month product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 4, 5)).ShouldEqual(1); //1 month and 1 day product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 4, 6)).ShouldEqual(2); //several days but less than two months product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 4, 13)).ShouldEqual(2); //2 months product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 5, 5)).ShouldEqual(2); //3 months product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 5, 8)).ShouldEqual(3); //several more unit tests product.GetRentalPeriods(new DateTime(1900, 1, 1), new DateTime(1900, 1, 1)).ShouldEqual(1); product.GetRentalPeriods(new DateTime(1900, 1, 1), new DateTime(1900, 1, 2)).ShouldEqual(1); product.GetRentalPeriods(new DateTime(1900, 1, 2), new DateTime(1900, 1, 1)).ShouldEqual(1); product.GetRentalPeriods(new DateTime(1900, 1, 1), new DateTime(1900, 2, 1)).ShouldEqual(1); product.GetRentalPeriods(new DateTime(1900, 2, 1), new DateTime(1900, 1, 1)).ShouldEqual(1); product.GetRentalPeriods(new DateTime(1900, 1, 31), new DateTime(1900, 2, 1)).ShouldEqual(1); product.GetRentalPeriods(new DateTime(1900, 8, 31), new DateTime(1900, 9, 30)).ShouldEqual(1); product.GetRentalPeriods(new DateTime(1900, 8, 31), new DateTime(1900, 10, 1)).ShouldEqual(2); product.GetRentalPeriods(new DateTime(1900, 1, 1), new DateTime(1901, 1, 1)).ShouldEqual(12); product.GetRentalPeriods(new DateTime(1900, 1, 1), new DateTime(1911, 1, 1)).ShouldEqual(132); product.GetRentalPeriods(new DateTime(1900, 8, 31), new DateTime(1901, 8, 30)).ShouldEqual(12); //rental period length = 2 months product.RentalPriceLength = 2; //the same date product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 5)).ShouldEqual(1); //several days but less than a month product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 4)).ShouldEqual(1); //1 month product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 4, 5)).ShouldEqual(1); //several days but less than two months product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 4, 13)).ShouldEqual(1); //2 months product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 5, 5)).ShouldEqual(1); //3 months product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 5, 8)).ShouldEqual(2); }
public void Can_calculate_rental_periods_for_years() { var product = new Product { IsRental = true, RentalPricePeriod = RentalPricePeriod.Years }; //rental period length = 1 years product.RentalPriceLength = 1; //the same date product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 5)).ShouldEqual(1); //several days but less than a year product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2015, 1, 1)).ShouldEqual(1); //more than one year product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2015, 3, 7)).ShouldEqual(2); //rental period length = 2 years product.RentalPriceLength = 2; //the same date product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 5)).ShouldEqual(1); //several days but less than a year product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2015, 1, 1)).ShouldEqual(1); //more than one year product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2015, 3, 7)).ShouldEqual(1); //more than two year product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2016, 3, 7)).ShouldEqual(2); }
public void Can_calculate_rental_periods_for_weeks() { var product = new Product { IsRental = true, RentalPricePeriod = RentalPricePeriod.Weeks }; //rental period length = 1 week product.RentalPriceLength = 1; //the same date product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 5)).ShouldEqual(1); //several days but less than a week product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 3)).ShouldEqual(1); //1 week product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 12)).ShouldEqual(1); //several days but less than two weeks product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 13)).ShouldEqual(2); //2 weeks product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 19)).ShouldEqual(2); //3 weeks product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 26)).ShouldEqual(3); //rental period length = 2 weeks product.RentalPriceLength = 2; //the same date product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 5)).ShouldEqual(1); //several days but less than a week product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 3)).ShouldEqual(1); //1 week product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 12)).ShouldEqual(1); //several days but less than two weeks product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 13)).ShouldEqual(1); //2 weeks product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 19)).ShouldEqual(1); //3 weeks product.GetRentalPeriods(new DateTime(2014, 3, 5), new DateTime(2014, 3, 26)).ShouldEqual(2); }