public AddFreeProduct_Brasseler(ICartPipeline cartPipeline, IOrderLineUtilities orderLineUtilities, IPricingServiceFactory pricingServiceFactory, ICustomerOrderUtilities customerOrderUtilities, IUnitOfWorkFactory unitOfWorkFactory, IPricingPipeline PricingPipeline, IPromotionAmountProvider promotionProvider, InventorySettings inventorySettings, Lazy <IInventoryPipeline> inventoryPipeline, IProductUtilities productUtilities)
     : base(PricingPipeline, promotionProvider)
 {
     this.CustomerOrderUtilities = customerOrderUtilities;
     this.UnitOfWork             = unitOfWorkFactory.GetUnitOfWork();
     this.pricingPipeline        = PricingPipeline;
     this.ProductUtilities       = productUtilities;
     this.CartPipeline           = cartPipeline;
     this.OrderLineUtilities     = orderLineUtilities;
     this.InventorySettings      = inventorySettings;
     this.InventoryPipeline      = inventoryPipeline;
 }
        //public override Decimal ProductDiscount(CustomerOrder customerOrder)
        //{
        //    return Decimal.Zero;
        //}

        public override void ApplyPromotionResult(CustomerOrder customerOrder)
        {
            //BUSA- 463 Subscrition- Not include promotional product in subscrition order
            if (!customerOrder.Status.EqualsIgnoreCase("Saved") && !customerOrder.Status.EqualsIgnoreCase("SubscriptionOrder") && !customerOrder.Status.EqualsIgnoreCase("Return Requested"))
            {
                if (!this.PromotionResult.Amount.HasValue)
                {
                    throw new ArgumentNullException("Amount");
                }
                if (this.PromotionResult.Amount.Value <= Decimal.Zero)
                {
                    throw new ArgumentOutOfRangeException("Amount");
                }
                if (this.PromotionResult.Product == null)
                {
                    throw new ArgumentNullException("Product");
                }
                if (this.PromotionResult.Product.TrackInventory && (!this.InventorySettings.AllowBackOrder || this.PromotionResult.Product.IsDiscontinued))
                {
                    ProductInventory inventory = this.InventoryPipeline.Value.GetQtyOnHand(new GetQtyOnHandParameter(true)
                    {
                        GetInventoryParameter = new GetInventoryParameter()
                        {
                            ProductIds = new List <Guid>()
                            {
                                this.PromotionResult.Product.Id
                            },
                            Products = new List <Product>()
                            {
                                this.PromotionResult.Product
                            }
                        }
                    }).Inventories[this.PromotionResult.Product.Id];
                    if ((inventory != null ? inventory.QtyOnHand : Decimal.Zero) < this.PromotionResult.Amount.Value)
                    {
                        return;
                    }
                }
                IProductUtilities productUtilities = this.ProductUtilities;
                List <Product>    products         = new List <Product>();
                products.Add(this.PromotionResult.Product);
                Customer billTo = SiteContext.Current.BillTo;
                Customer shipTo = SiteContext.Current.ShipTo;
                if (productUtilities.GetRestrictedProductIds(products, billTo, shipTo).Any <Guid>())
                {
                    return;
                }
                OrderLine orderLine1 = new OrderLine();
                orderLine1.UnitOfMeasure = this.PromotionResult.Product.UnitOfMeasure;
                orderLine1.Id            = Guid.NewGuid();
                // BUSA-1319: Limit Qty Per Product
                var maxProductQty = this.PromotionResult.Product.CustomProperties.Where(x => x.Name == "maxProductQty").Select(s => s.Value).FirstOrDefault() ?? "0";

                if (!string.IsNullOrEmpty(maxProductQty) && Convert.ToInt32(maxProductQty) != 0 && this.PromotionResult.Amount.Value > Convert.ToDecimal(maxProductQty))
                {
                    orderLine1.QtyOrdered = Convert.ToDecimal(maxProductQty);
                }
                else
                {
                    orderLine1.QtyOrdered = this.PromotionResult.Amount.Value;
                } // BUSA-1319: END
                OrderLine orderLine2 = orderLine1;
                this.OrderLineUtilities.SetProduct(orderLine2, this.PromotionResult.Product);
                PipelineHelper.VerifyResults((PipeResultBase)this.CartPipeline.AddCartLine(new Insite.Cart.Services.Pipelines.Parameters.AddCartLineParameter()
                {
                    Cart     = customerOrder,
                    CartLine = orderLine2
                }));
                CustomerOrderPromotion customerOrderPromotion = customerOrder.CustomerOrderPromotions.FirstOrDefault <CustomerOrderPromotion>((Func <CustomerOrderPromotion, bool>)(p => p.PromotionId == this.PromotionResult.PromotionId));
                if (customerOrderPromotion != null)
                {
                    customerOrderPromotion.OrderLineId = new Guid?(orderLine2.Id);
                    customerOrderPromotion.Amount      = new Decimal?(new Decimal());
                }
                orderLine2.PromotionResult  = this.PromotionResult;
                orderLine2.IsPromotionItem  = true;
                orderLine2.UnitNetPrice     = Decimal.Zero;
                orderLine2.UnitRegularPrice = this.PromotionResult.Product.BasicListPrice;

                // BUSA-683 : Volume Discount Promotion -Issue when user cart qualifies add free product promotion & volume discount group.
                var orderLineCount = customerOrder.OrderLines.Where(x => x.Id == new Guid()).Count();

                //start BUSA-683 Volume Discount Promotion -Issue when user's cart qualifies add free product promotion & volume discount group
                if (this.PromotionResult.Promotion.RuleManager.RuleClauses.Where(x => x.CriteriaType == "OverideVolumeDiscount").Count() > 0)
                {
                    var vdgOverride = this.PromotionResult.Promotion.RuleManager.RuleClauses.Where(x => x.CriteriaType == "OverideVolumeDiscount").FirstOrDefault().CriteriaValue;
                    //check if override VDG
                    if (vdgOverride == "Yes")
                    {
                        var ruleProductId = this.PromotionResult.Promotion.RuleManager.RuleClauses.Where(x => x.CriteriaType == "OrderedProduct").Count() > 0 ? this.PromotionResult.Promotion.RuleManager.RuleClauses.Where(x => x.CriteriaType == "OrderedProduct").FirstOrDefault().SimpleValue : string.Empty;

                        var ruleOrderLine = customerOrder.OrderLines.Where(x => x.ProductId.ToString() == ruleProductId.ToString()).FirstOrDefault();
                        if (ruleOrderLine != null && !string.IsNullOrEmpty(ruleOrderLine.ConfigurationViewModel))
                        {
                            ruleOrderLine.UnitNetPrice = ruleOrderLine.UnitListPrice;
                            ruleOrderLine.SmartPart    = string.Empty;

                            ruleOrderLine.ConfigurationViewModel = "false";
                            var grpDescription = ruleOrderLine.GetProperty("GrpDescription", "");

                            if (!string.IsNullOrEmpty(grpDescription))
                            {
                                ruleOrderLine.SetProperty("GrpDescription", " ");
                            }

                            CartHelper_Brasseler helper = new CartHelper_Brasseler(this.pricingPipeline);
                            helper.UpdateVolumeGrpPricing(customerOrder, ruleOrderLine.Product.PriceBasis, UnitOfWork);
                            if (orderLineCount == 0)
                            {
                                PipelineHelper.VerifyResults((PipeResultBase)this.CartPipeline.AddCartLine(new Insite.Cart.Services.Pipelines.Parameters.AddCartLineParameter()
                                {
                                    Cart     = customerOrder,
                                    CartLine = orderLine1
                                }));
                                orderLine1.PromotionResult = this.PromotionResult;

                                orderLine1.IsPromotionItem  = true;
                                orderLine1.UnitNetPrice     = Decimal.Zero;
                                orderLine1.UnitRegularPrice = this.PromotionResult.Product.BasicListPrice;
                            }
                        }
                        else
                        {
                            if (orderLineCount == 0)
                            {
                                PipelineHelper.VerifyResults((PipeResultBase)this.CartPipeline.AddCartLine(new Insite.Cart.Services.Pipelines.Parameters.AddCartLineParameter()
                                {
                                    Cart     = customerOrder,
                                    CartLine = orderLine1
                                }));
                                orderLine1.PromotionResult = this.PromotionResult;

                                orderLine1.IsPromotionItem  = true;
                                orderLine1.UnitNetPrice     = Decimal.Zero;
                                orderLine1.UnitRegularPrice = this.PromotionResult.Product.BasicListPrice;
                            }
                        }
                    }
                    else
                    {
                        //Do nothing
                    }
                }
                //end BUSA-683 Volume Discount Promotion -Issue when user's cart qualifies add free product promotion & volume discount group
                else
                {
                    PipelineHelper.VerifyResults((PipeResultBase)this.CartPipeline.AddCartLine(new Insite.Cart.Services.Pipelines.Parameters.AddCartLineParameter()
                    {
                        Cart     = customerOrder,
                        CartLine = orderLine1
                    }));
                    orderLine1.PromotionResult = this.PromotionResult;

                    orderLine1.IsPromotionItem  = true;
                    orderLine1.UnitNetPrice     = Decimal.Zero;
                    orderLine1.UnitRegularPrice = this.PromotionResult.Product.BasicListPrice;
                }
            }
        }