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); }