public Cart CalculatePricing(Cart cart)
        {
            /* Using session to mark if default campaign code has already been added is done so if customer
             * (for some reason) has removed the campaign code from the cart it will not show up again. 
             * 
             * A minor unhandled edge-case is that if a customer places two or more orders before the session has timed out
             * the default campaign code will not be applied to the later orders since the marker is stored in the session 
             * and not the cart, so it will not be cleared together with the cart on order completion.
             */ 
            
            var alreadyAdded = HttpContext.Current.Session["DefaultCampaignPricingProvider_Added"] != null 
                 ? true
                 : false;

            if (string.IsNullOrEmpty(cart.CampaignCode) && !alreadyAdded)
            {
                var defaultCampaignCode = ConfigurationManager.AppSettings["DefaultCampaignCode"] as String;

                if (!string.IsNullOrEmpty(defaultCampaignCode))
                {
                    cart.SetCampaignCode(defaultCampaignCode);
                    HttpContext.Current.Session["DefaultCampaignPricingProvider_Added"] = true;
                }
            }
            
            var calculatedCart = baseCartPricingService.CalculatePricing(cart);

            return calculatedCart;
        }
        /// <inheritdoc/>
        public Cart GetCart() 
        {
            var cart = HttpContext.Current.Session["Cart"] as Cart;

            if (cart == null)
            {
                cart = new Cart(this, cartPricingProvider);
            }

            return cart;
        }
        public Cart CalculatePricing(Cart cart)
        {
            foreach(var cartItem in cart.CartItems)
            {
                cartItem.SetPricing(10, 2, new List<Tax>());
            }

            cart.SetPricing(cart.CartItems.Sum(ci => ci.Price), cart.CartItems.Sum(ci => ci.Total), new List<Tax>());

            return cart;
        }
        /// <summary>
        /// Add or remove any required setup fees before calculating pricing for cart. 
        /// Setup fee items are marked with "NotRemovable" custom attributes as help to e.g. GUI code.
        /// </summary>
        public Cart CalculatePricing(Cart cart)
        {
            var setupFee = apiProductsProvider.GetProductsByCategories(new List<string>() { SetupFeeCategory }).FirstOrDefault();
            
            if (setupFee != null)
            {
                var allSetupFeeProducts = apiProductsProvider.GetProductsByCategories(ProductCategoriesWithSetupFee.ToList());
                var freePackageProducts = apiProductsProvider.GetProductsByCategories(new List<string> { FreePackageCategory });
                var setupFeeProducts = allSetupFeeProducts.Where(s => !freePackageProducts.Any(f => s.ArticleNumber == f.ArticleNumber));

                var shouldHaveSetupFee = setupFeeProducts.Any(p => cart.CartItems.Any(ci => ci.ArticleNumber == p.ArticleNumber));
                var hasSetupFee = cart.CartItems.Any(ci => ci.ArticleNumber == setupFee.ArticleNumber);

                if (shouldHaveSetupFee && !hasSetupFee)
                {
                    var setupFeeItem = new CartItem
                    {
                        ArticleNumber = setupFee.ArticleNumber,
                        Quantity = 1,
                        RenewalPeriod = null,
                        CustomAttributes = new List<Core.CustomAttribute>()
                        {
                            new Core.CustomAttribute{ Name = "NotRemovable", Value = "true" }
                        }
                    };

                    cart.AddItem(setupFeeItem);
                }
                else if (!shouldHaveSetupFee && hasSetupFee)
                {
                    var setupFeeItem = cart.CartItems.First(ci => ci.ArticleNumber == setupFee.ArticleNumber);
                    
                    cart.RemoveItem(setupFeeItem.Id);
                }
            }
            
            var calculatedCart = baseCartPricingService.CalculatePricing(cart);

            return calculatedCart;
        }
        /// <summary>
        /// OrderContext constructor
        /// </summary>
        /// <param name="cart">Collected cart data</param>
        /// <param name="contactDataCollection">Collected contact data</param>
        /// <param name="paymentData">Collected payment data</param>
        /// <param name="extraData">Any unspecified extra data</param>
        public OrderContext(Cart cart, IContactDataCollection contactDataCollection, PaymentData paymentData, IEnumerable<object> extraData)
        {
            if (cart == null)
            {
                throw new ArgumentNullException("cart");
            }

            if (contactDataCollection == null)
            {
                throw new ArgumentNullException("contactDataCollection");
            }

            if (paymentData == null)
            {
                throw new ArgumentNullException("paymentData");
            }

            this.cart = cart;
            this.contactData = contactDataCollection.GetContactData();
            this.paymentData = paymentData;
            this.extraData = extraData;
        }
        /// <inheritdoc />
        public Cart CalculatePricing(Cart cart)
        {
            var publicOrder = CreateBasicOrder();

            var publicOrderItems = new List<PublicOrderItem>();
            var itemNo = 0;

            foreach(var cartItem in cart.CartItems)
            {
                var renewalPeriodId = renewalPeriodProvider.GetRenewalPeriodId(cartItem);

                publicOrderItems.Add(new PublicOrderItem
                {
                    ItemNumber = cartItem.ArticleNumber,
                    RenewalPeriodId = renewalPeriodId,
                    Quantity = cartItem.Quantity,
                    ItemNo = itemNo++
                });
            }
            publicOrder.OrderItems = publicOrderItems.ToArray();

            var publicOrderCustomData = new List<PublicOrderCustomData>();
            if (!string.IsNullOrEmpty(cart.CampaignCode))
            {
                publicOrderCustomData.Add(new PublicOrderCustomData
                    {
                        Name = "CampaignCode",
                        Value = cart.CampaignCode
                    });
            }
            if (cart.CustomAttributes != null)
            {
                foreach (Core.CustomAttribute attr in cart.CustomAttributes)
                {
                    publicOrderCustomData.Add(new PublicOrderCustomData { Name = attr.Name, Value = attr.Value });
                }
            }

            publicOrder.CustomData = publicOrderCustomData.ToArray();

            var calculatedPublicOrder = BillingApi.CalculateOrder(publicOrder);

            IEnumerable<Tax> taxes = new List<Tax>();

            if (calculatedPublicOrder.Taxes != null && calculatedPublicOrder.Taxes.Count() > 0)
            {
                taxes = calculatedPublicOrder.Taxes.Select(t => new Tax(t.Name, t.Total, t.Percent));
            }

            var subtotal = this.pricesIncludeVat 
                ? calculatedPublicOrder.Total 
                : calculatedPublicOrder.Subtotal;

            cart.SetPricing(subtotal, calculatedPublicOrder.Total, taxes);

            var priceCalculator = new PriceCalculator(this.pricesIncludeVat, this.inclusiveTaxCalculationType);

            foreach(var cartItem in cart.CartItems)
            {
                PublicOrderItem calculatedItem;
                var calcOrderItems = calculatedPublicOrder.OrderItems;

                if (cartItem.RenewalPeriod == null)
                {
                    calculatedItem = calcOrderItems.First(x => 
                        x.ItemNumber == cartItem.ArticleNumber 
                        && x.RenewalPeriod == 0);
                }
                else
                {
                   calculatedItem = calcOrderItems.First(x => 
                       x.ItemNumber == cartItem.ArticleNumber 
                       && x.RenewalPeriod == cartItem.RenewalPeriod.Period 
                       && x.RenewalPeriodUnit.ToUpper() == cartItem.RenewalPeriod.Unit);
                }

                IEnumerable<Tax> itemTaxes = new List<Tax>();

                if (calculatedItem.Taxes != null && calculatedItem.Taxes.Count() > 0)
                {
                    itemTaxes = calculatedItem.Taxes.Select(t => new Tax(t.Name, calculatedItem.TaxAmount, t.Percent));
                }

                var price = priceCalculator.CalculatePrice(calculatedItem.Price, calculatedItem.Taxes);
                var discount = priceCalculator.CalculatePrice(calculatedItem.Discount, calculatedItem.Taxes);

                cartItem.SetPricing(price, discount, itemTaxes);
                cartItem.Quantity = calculatedItem.Quantity;
            }

            return cart;
        }
 /// <inheritdoc/>
 public void SaveCart(Cart cart)
 {
     HttpContext.Current.Session["Cart"] = cart;
 }
 public CartModel(Cart cart)
 {
     this.cart = cart;
 }