Exemple #1
0
        /// <summary>
        /// Given a list of promotion prices, crunch them down into a single discounted amount
        /// </summary>
        /// <param name="promoPrices">Prices to crunch</param>
        /// <param name="price">Tentative item price before promotions</param>
        /// <returns></returns>
        private static Decimal CombinePromotionPrices(IEnumerable <PromoPrice> promoPrices, Decimal price)
        {
            Decimal totalAmount = 0;

            // only first non-compoundable promotion will be applied
            if (promoPrices.Any(p => !p.IsCompoundable))
            {
                PromoPrice nonCompoundable = promoPrices.Where(p => !p.IsCompoundable).First();
                totalAmount = Math.Max(nonCompoundable.AmountOff, nonCompoundable.PercentOff * price / 100);
            }

            // apply compoundable promotions in order of offer Id
            foreach (var promo in promoPrices.Where(p => p.IsCompoundable).OrderBy(p => p.PromoId))
            {
                // otherwise add the amount or percent to the total amount discounted
                if (promo.AmountOff != 0)
                {
                    totalAmount += promo.AmountOff;
                }
                else if (promo.PercentOff != 0)
                {
                    totalAmount += (price - totalAmount) * promo.PercentOff / 100;
                }
            }

            // don't discount more than the price
            if (totalAmount > price)
            {
                totalAmount = price;
            }

            return(totalAmount);
        }
Exemple #2
0
        /// <summary>
        /// Given a set of promotion lines, tentative item price, and item, calculate the price after promotions are applied
        /// </summary>
        /// <param name="promotionLines">List of promotion configurations active for this item</param>
        /// <param name="price">Price of the item before the promotion, derived from trade agreement or base item price</param>
        /// <param name="saleItem">The sale item whose price is being determined</param>
        /// <returns>Unrounded price after applying all promotions</returns>
        public static decimal CalculatePromotionPrice(IEnumerable <PromotionInfo> promotionLines, decimal price, BaseSaleItem saleItem)
        {
            if (saleItem == null)
            {
                NetTracer.Warning("saleItem parameter is null");
                throw new ArgumentNullException("saleItem");
            }

            if (promotionLines == null || promotionLines.Count() == 0)
            {
                return(price);
            }

            decimal            promoPrice  = price;
            IList <PromoPrice> promoPrices = new List <PromoPrice>();

            foreach (PromotionInfo promo in promotionLines)
            {
                PromoPrice promoLine = new PromoPrice();
                promoLine.PromoId        = promo.PromoId;
                promoLine.Concurrency    = promo.Concurrency;
                promoLine.IsCompoundable = false;

                switch (promo.DiscountMethod)
                {
                case DiscountMethod.DiscountPercent:
                    promoLine.PercentOff     = promo.MaxDiscPct;
                    promoLine.IsCompoundable = true;
                    promoPrices.Add(promoLine);
                    break;

                case DiscountMethod.OfferPrice:
                    if (!saleItem.Transaction.TaxIncludedInPrice)
                    {
                        promoLine.AmountOff = price - promo.Price;
                        promoPrices.Add(promoLine);
                    }
                    break;

                case DiscountMethod.OfferPriceInclTax:
                    if (saleItem.Transaction.TaxIncludedInPrice)
                    {
                        promoLine.AmountOff = price - promo.PriceInclTax;
                        promoPrices.Add(promoLine);
                    }
                    break;

                case DiscountMethod.DiscountAmount:
                    promoLine.AmountOff      = promo.MaxDiscAmount;
                    promoLine.IsCompoundable = true;
                    promoPrices.Add(promoLine);
                    break;
                }
            }

            promoPrice = price - FindConcurrentPromoAmount(promoPrices, price);

            return(promoPrice);
        }
Exemple #3
0
            /// <summary>
            /// Given a set of promotion lines, tentative item price, and item, calculate the price after promotions are applied.
            /// </summary>
            /// <param name="priceLines">List of possible adjustments and methods active for this item.</param>
            /// <param name="price">Price of the item before the promotion, derived from trade agreement or base item price.</param>
            /// <returns>
            /// Unrounded price after applying all promotions.
            /// </returns>
            internal static decimal CalculatePromotionPrice(IEnumerable <PriceAdjustmentPriceLine> priceLines, decimal price)
            {
                if (priceLines == null || !priceLines.Any())
                {
                    return(price);
                }

                decimal            promoPrice  = price;
                IList <PromoPrice> promoPrices = new List <PromoPrice>();

                foreach (var promo in priceLines)
                {
                    PromoPrice promoLine = new PromoPrice();
                    promoLine.PromoId        = promo.OriginId;
                    promoLine.Concurrency    = promo.Concurrency;
                    promoLine.IsCompoundable = false;

                    switch (promo.PriceMethod)
                    {
                    case PriceMethod.PercentOff:
                        promoLine.PercentOff     = promo.Value;
                        promoLine.IsCompoundable = true;
                        break;

                    case PriceMethod.Fixed:
                        promoLine.AmountOff = Math.Max(0m, price - promo.Value);
                        break;

                    case PriceMethod.AmountOff:
                        promoLine.AmountOff      = promo.Value;
                        promoLine.IsCompoundable = true;
                        break;

                    default:
                        throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Behavior not defined for price method: {0}", promo.PriceMethod));
                    }

                    promoPrices.Add(promoLine);
                }

                promoPrice = price - FindConcurrentPromoAmount(promoPrices, price);

                return(promoPrice);
            }