/// <summary> /// Used to calculate price for a given day /// </summary> /// <param name="priceToCalculate">price with date information for calculation</param> /// <param name="promotionsAvailable">available promotions to check for calculating</param> /// <returns>Calculated price with names for the day</returns> public virtual IPromotable CalculatePriceForDate(List<Promotion> promotionsAvailable, IPromotable priceToCalculate) { // no promotions for business, return what was sent in if (promotionsAvailable == null || !promotionsAvailable.Any()) { return priceToCalculate; } // logic here IEnumerable<Promotion> validPromos = promotionsAvailable.Where(p => IsPromotionAvailable(p, priceToCalculate)); // work out best discount if promotions available if (validPromos.Any()) { // get the Maximum promo discount promotion var maxPromo = validPromos.Aggregate((vp, x) => (vp == null || x.Discount > vp.Discount ? x : vp)); var newRate = priceToCalculate.Rate * (1 - (maxPromo.Discount / 100)); priceToCalculate.WasRate = priceToCalculate.Rate; priceToCalculate.Rate = newRate; priceToCalculate.PromoName = string.IsNullOrWhiteSpace(maxPromo.DisplayName) ? maxPromo.Name : maxPromo.DisplayName; priceToCalculate.Discount = maxPromo.Discount; } return priceToCalculate; }
/// <summary> /// Used to calculate price for a given day /// </summary> /// <param name="businessId">business id for these prices</param> /// <param name="priceToCalculate">price with date information for calculation</param> /// <returns>Calculated price with names for the day</returns> public IPromotable CalculatePriceForDate(long businessId, IPromotable priceToCalculate) { // Get promos for the given business // Using Cache, which will be thread safe // Will filter later var cache = Cache.Cache.PromoCache; List<Promotion> promos = cache.TryGetValue(businessId); return CalculatePriceForDate(promos, priceToCalculate); }
/// <summary> /// Checks Rate Plan /// Status /// Booking Window /// DayOfWeek /// </summary> /// <remarks> /// Change for date checks /// </remarks> /// <param name="promo">promotion to check</param> /// <param name="price">price to check</param> /// <returns>true if available for this price</returns> private bool IsPromotionAvailable(Promotion promo, IPromotable price) { return promo.Status.Type == PromotionStatusEnum.Active && promo.AssociatedRatePlanIds != null && promo.AssociatedRatePlanIds.Any(i => i == price.RatePlanId) && IsPromotionInWindow(promo, price.Date) && IsPromotionStayDateValid(promo, price.Date) && IsPromotionValidOnDay(promo, price.Date); }
public void CalculatePriceForDateDoesCorrectCalculationForGivenPromotions(List<Promotion> promotionsAvailable, IPromotable price, IPromotable resultPrice) { // Arrange done in test case // Act var calculatedPrice = promoCalculator.CalculatePriceForDate(promotionsAvailable, price); // Assert Assert.AreEqual(resultPrice.RoomTypeId, calculatedPrice.RoomTypeId, "Roomtype did not match"); Assert.AreEqual(resultPrice.RatePlanId, calculatedPrice.RatePlanId, "Rateplan did not match"); Assert.AreEqual(resultPrice.PromoName, calculatedPrice.PromoName, "Promo name did not match"); Assert.AreEqual(resultPrice.Rate, calculatedPrice.Rate, "price did not match"); Assert.AreEqual(resultPrice.WasRate, calculatedPrice.WasRate, "was price did not match"); Assert.AreEqual(resultPrice.Discount, calculatedPrice.Discount, "Discount did not match"); }