public void _8_BuyItemsGetItemFree_DifferentItem()
        {
            //Buy 5 item 1004 get 1004 free
            var exp =
                "PriceType=R;BuyItemCode=1004;BuyItemCount=5;GetItemCode=1001;GetItemCount=2";
            var promo = new PromotionLineItem {
                PromotionLineItemExpression = exp
            };

            var cartlineItems = new List <Cart>()
            {
                new Cart()
                {
                    Product = CartContext.Products.Single(p => p.Code == "1004"), OriginalPrice = 25m, DiscountAmount = 0m, Quantity = 6, DiscountApplied = false, PriceType = "R"
                },
                new Cart()
                {
                    Product = CartContext.Products.Single(p => p.Code == "1005"), OriginalPrice = 20m, DiscountAmount = 0m, Quantity = 2, DiscountApplied = false, PriceType = "R"
                }
            };

            new CartProcessor().ApplyEach(promo, cartlineItems);
            Assert.AreEqual(190m, cartlineItems.Sum(c => c.Sum));
            Assert.AreEqual("1001", cartlineItems.Single(c => c.AddOnItem).Product.Code);
            Assert.AreEqual(1, cartlineItems.Where(c => c.AddOnItem).ToList().Count);
            Assert.AreEqual(2, cartlineItems.Single(c => c.AddOnItem).Quantity);
        }
        public void _4_AmountDiscount_Categories()
        {
            //1.5 dollar off Female-Casual-Collection
            var exp =
                "Category=1002;PriceType=R;AmountDiscount=1.5";
            var promo = new PromotionLineItem {
                PromotionLineItemExpression = exp
            };

            var cartlineItems = new List <Cart>()
            {
                new Cart()
                {
                    Categories = new List <string>()
                    {
                        "1001"
                    }, OriginalPrice = 40m, DiscountAmount = 0m, Quantity = 1, DiscountApplied = false, PriceType = "R"
                },
                new Cart()
                {
                    Categories = new List <string>()
                    {
                        "1002", "1003"
                    }, OriginalPrice = 20m, DiscountAmount = 0m, Quantity = 2, DiscountApplied = false, PriceType = "R"
                }
            };

            new CartProcessor().ApplyEach(promo, cartlineItems);
            Assert.AreEqual(77m, cartlineItems.Sum(c => c.Sum));
        }
        public void _3_PercentDiscount_Categories()
        {
            //15 percent off Female-Winter-Collection
            var exp =
                "Category=1001;PriceType=R;PercentDiscount=0.15";
            var promoExp = PromotionLineItemExpression.Parse(exp);

            var promo = new PromotionLineItem {
                PromotionLineItemExpression = exp
            };

            var cartlineItems = new List <Cart>()
            {
                new Cart()
                {
                    Categories = new List <string>()
                    {
                        "1001"
                    }, OriginalPrice = 40m, DiscountAmount = 0m, Quantity = 2, DiscountApplied = false, PriceType = "R"
                },
                new Cart()
                {
                    Categories = new List <string>()
                    {
                        "1003", "1004"
                    }.ToList(), OriginalPrice = 20m, DiscountAmount = 0m, Quantity = 1, DiscountApplied = false, PriceType = "R"
                }
            };

            new CartProcessor().ApplyEach(promo, cartlineItems);
            Assert.AreEqual(88m, cartlineItems.Sum(c => c.Sum));
            //Assert.AreEqual(CartContext.Products.Single(p => p.Code == "1001").Price,
            //    cartProcessor.Process(promotion.PromotionLineItems, cartLineItems).FirstOrDefault().DiscountedPrice);
        }
        public void _6_AmountDiscount_ItemCodes()
        {
            //5.25 off item item 1005
            var exp =
                "ItemCode=1005;PriceType=R;AmountDiscount=5.25";
            var promo = new PromotionLineItem {
                PromotionLineItemExpression = exp
            };

            var cartlineItems = new List <Cart>()
            {
                new Cart()
                {
                    Product = CartContext.Products.Single(p => p.Code == "1004"), OriginalPrice = 25m, DiscountAmount = 0m, Quantity = 1, DiscountApplied = false, PriceType = "R"
                },
                new Cart()
                {
                    Product = CartContext.Products.Single(p => p.Code == "1005"), OriginalPrice = 20m, DiscountAmount = 0m, Quantity = 2, DiscountApplied = false, PriceType = "R"
                }
            };

            new CartProcessor().ApplyEach(promo, cartlineItems);
            Assert.AreEqual(54.5m, cartlineItems.Sum(c => c.Sum));
        }
        public override IDiscountResult ApplyPromotion(IPromotionUsage promotionUsage, IRuleContext ruleContext, IDiscountContext discountContext, Func <IDiscountResult> resultFactory)
        {
            Data.EntityContextDataContext context = new Data.EntityContextDataContext();
            IDiscountResult       retVal          = resultFactory();
            Decimal               totalDiscount   = Decimal.Zero;
            List <DiscountedItem> discountedItems = new List <DiscountedItem>();
            Int32 quantity             = 1;
            Int32 contextQuantity      = discountContext.DiscountableItems.Sum(s => s.Quantity);
            Int32 shoppingCartRecordId = 0;

            if (MatchQuantities && contextQuantity > 0)
            {
                quantity = discountContext.DiscountableItems.Sum(s => s.Quantity);
            }

            foreach (Int32 productId in GiftProductIds)
            {
                Data.ShoppingCart cart = null;

                //Try to find an existing free gift in the promotionlineitem table for this promousage
                PromotionLineItem giftItem = context.PromotionLineItems.FirstOrDefault(pli => pli.productId == productId && pli.isAGift && pli.PromotionUsageId == promotionUsage.Id);

                //Try to grab the shopping cart item for the promolineitem
                if (giftItem != null)
                {
                    cart = context.ShoppingCarts.FirstOrDefault(sc => sc.ShoppingCartRecID == giftItem.shoppingCartRecordId);
                }

                //Add the free item to the shoppingcart if it doesn't already exist
                if (cart == null)
                {
                    int variantId = context.ProductVariants.FirstOrDefault(pv => pv.ProductID == productId && pv.IsDefault == 1).VariantID;
                    if (ruleContext.AddItemToCart != null)
                    {
                        shoppingCartRecordId = ruleContext.AddItemToCart(productId, variantId, quantity);
                    }
                    cart = context.ShoppingCarts.FirstOrDefault(sc => sc.ShoppingCartRecID == shoppingCartRecordId);
                }
                else
                {
                    //Make sure our quantities match up.
                    cart.Quantity = quantity;
                    context.SubmitChanges();
                }

                if (cart != null)
                {
                    DiscountedItem discountedItem = new DiscountedItem();

                    //We store the original price of the item in the promotionlineitem table, we want to use that original price if we already have a promo line item
                    discountedItem.CartPrice            = giftItem == null ? (decimal)cart.ProductPrice : giftItem.cartPrice;
                    discountedItem.IsAGift              = true;
                    discountedItem.ProductId            = productId;
                    discountedItem.Quantity             = cart.Quantity;
                    discountedItem.ShoppingCartRecordId = cart.ShoppingCartRecID;
                    discountedItem.Sku            = cart.ProductSKU;
                    discountedItem.Subtotal       = (decimal)cart.ProductPrice * cart.Quantity;
                    discountedItem.VariantId      = cart.VariantID;
                    discountedItem.PromotionUsage = promotionUsage;

                    decimal discount = -(discountedItem.CartPrice) * (GiftDiscountPercentage * .01m);
                    //Make sure our price won't go negative
                    discount = Math.Abs(discount) > discountedItem.CartPrice ? -(discountedItem.CartPrice) : discount;

                    //The discount is already baked into the cart price we will record the discount in gift amount instead
                    discountedItem.DiscountAmount = 0.0M;
                    discountedItem.GiftAmount     = discount * cart.Quantity;
                    totalDiscount += discountedItem.GiftAmount;
                    discountedItem.DiscountPercentage = GiftDiscountPercentage;

                    Data.ContextController.TrackLineItemDiscount(discountedItem);

                    discountedItems.Add(discountedItem);
                    cart.ProductPrice        = discountedItem.CartPrice + discount;
                    cart.IsGift              = true;
                    cart.CustomerEntersPrice = 1;
                    context.SubmitChanges();
                }
            }
            retVal.DiscountedItems  = discountedItems;
            retVal.DiscountType     = DiscountType.Fixed;
            retVal.GiftProductTotal = totalDiscount;
            retVal.SequenceType     = (PromotionSequence)SequenceNumber;

            return(retVal);
        }
Beispiel #6
0
        public void ApplyEach(PromotionLineItem promo, List <Cart> carts)
        {
            var tempLineItems = new List <Cart>();

            foreach (var lineItem in carts)
            {
                var promoExp = PromotionLineItemExpression.Parse(promo.PromotionLineItemExpression);
                lineItem.DiscountApplied = false;

                if (promoExp.Category.Count > 0 && !lineItem.DiscountApplied &&
                    promoExp.PriceType.Contains(lineItem.PriceType))
                {
                    var qualifiedCategories = promoExp.Category.Intersect(lineItem.Categories);

                    if (qualifiedCategories.Count() > 0)
                    {
                        lineItem.DiscountAmount = promoExp.AmountDiscount +
                                                  (lineItem.OriginalPrice * promoExp.PercentDiscount);

                        //lineItem.DiscountedPrice = lineItem.OriginalPrice - lineItem.DiscountAmount;
                    }
                    lineItem.DiscountApplied = true;
                }

                if (promoExp.ItemCode.Count > 0 && !lineItem.DiscountApplied &&
                    promoExp.PriceType.Contains(lineItem.PriceType))
                {
                    var qualified = promoExp.ItemCode.Contains(lineItem.Product.Code);
                    if (qualified)
                    {
                        lineItem.DiscountAmount = promoExp.AmountDiscount +
                                                  (lineItem.OriginalPrice * promoExp.PercentDiscount);

                        //lineItem.DiscountedPrice = lineItem.OriginalPrice - lineItem.DiscountAmount;
                    }
                    lineItem.DiscountApplied = true;
                }

                if (promoExp.BuyItemCode.Count > 0 && !lineItem.DiscountApplied &&
                    promoExp.PriceType.Contains(lineItem.PriceType))
                {
                    var qualified = promoExp.BuyItemCode.Contains(lineItem.Product.Code) && lineItem.Quantity >= promoExp.BuyItemCount;
                    if (qualified)
                    {
                        //how many free items ?
                        var freeItemCount = lineItem.Quantity / promoExp.BuyItemCount;
                        //slow !!!!!!!!!!!!!!!
                        using (var context = new ShoppingCartContext())
                        {
                            var product = context.Products.Single(p => p.Code == promoExp.GetItemCode.FirstOrDefault()); //only support single get product
                            for (int i = 0; i < freeItemCount; i++)
                            {
                                tempLineItems.Add(new Cart()
                                {
                                    OriginalPrice  = context.ProductOffers.ToList().Single(po => po.ProductId == product.Id && po.PriceTypeId == 1).Price,
                                    DiscountAmount = context.ProductOffers.ToList().Single(po => po.ProductId == product.Id && po.PriceTypeId == 1).Price,
                                    ShippingCost   = lineItem.ShippingCost,
                                    //DiscountedPrice = 0m,
                                    DiscountApplied = true,
                                    AddOnItem       = true,
                                    Quantity        = promoExp.GetItemCount,
                                    Code            = Guid.NewGuid().ToString(),
                                    Categories      = lineItem.Categories,
                                    DateCreated     = lineItem.DateCreated,
                                    PriceType       = lineItem.PriceType,
                                    Product         = product
                                                      //ProductCode = product.Code
                                });
                            }
                        }
                    }
                }

                //if the cart line item applies for this promo
                //if (promo.ProductOffers.Any(po => po.Code == lineItem.ProductOffer.Code) && lineItem.ProductOffer.Discountable && promo.Quantity >= lineItem.Quantity)
                //{
                //    if (promo.FreeShipping)
                //        lineItem.ShippingCost = 0m;
                //    lineItem.DiscountAmount = (lineItem.OriginalPrice * (1 - promo.PercentDiscount)) - promo.AmountDiscount;
                //    lineItem.DiscountedPrice = lineItem.OriginalPrice - lineItem.DiscountAmount + lineItem.ShippingCost;
                //}
            }

            carts.AddRange(tempLineItems);
            //return ret;
        }