public void sale_with_2_momogi_and_pepsi_should_be_totaled_6000()
 {
     var sale = new Sale();
     sale.AddLineItem(momogi, 2);
     sale.AddLineItem(pepsi);
     Assert.AreEqual(6000m, sale.GetTotal());
 }
 public void add_sli_with_same_product_will_change_quantity()
 {
     var sale = new Sale();
     sale.AddLineItem(momogi, 2);
     Assert.AreEqual(1, sale.LineItems.Count);
     sale.AddLineItem(momogi);
     Assert.AreEqual(1, sale.LineItems.Count);
     var sli = sale.GetLineItem(momogi);
     Assert.AreEqual(3, sli.Quantity);
 }
Exemplo n.º 3
0
        /// <summary>
        /// Mutates the sale with 'Buy N Get One' type discounts and gets the total.
        /// </summary>
        /// <param name="sale"></param>
        /// <returns></returns>
        public decimal GetTotal(Sale sale)
        {
            var discountedLineItems = new List <SalesLineItem>();
            var originalLineItems   = new List <SalesLineItem>();

            foreach (var lineItem in sale.LineItems)
            {
                // Apply discounts directly to line item, if any.

                foreach (
                    var discount in
                    _discounts
                    .Where(d => d.IsValid() && d.DiscountAppliedOnNextProduct)
                    .Where(d => d.ProductId == lineItem.ProductId && lineItem.Quantity > d.ThresholdQuantity)
                    .OrderByDescending(d => d.ThresholdQuantity))
                {
                    // There may be eligible discount(s) to apply to current line item based on quantity.
                    // Apply the discounts with the largest quantities first as they generally have the better discounts.

                    while (lineItem.Quantity > discount.ThresholdQuantity)
                    {
                        // Create a separate line item that receives the discount.
                        var discountedLineItem =
                            new SalesLineItem(new Product(lineItem.ProductId, lineItem.ProductPrice), 1);
                        discountedLineItem.SetDiscount(discount.Discount);

                        // Save to temporary list.
                        discountedLineItems.Add(discountedLineItem);

                        // Decrement original line item quantity by the threshold quantity plus the promotional item.
                        lineItem.AddQuantity(-1 * (discount.ThresholdQuantity + 1));

                        // Create a new line item with the original threshold quantity to a temporary list.
                        // Do not want to count these quantities again.
                        var originalLineItem = new SalesLineItem(new Product(lineItem.ProductId, lineItem.ProductPrice),
                                                                 discount.ThresholdQuantity);
                        originalLineItems.Add(originalLineItem);

                        // TODO: Add a limit, i.e. only get the discount a certain number of times.
                    }
                }
            }

            sale.RemoveZeroQuantityLineItems();

            foreach (var item in originalLineItems)
            {
                sale.MakeLineItem(new Product(item.ProductId, item.ProductPrice), item.Quantity);
            }

            foreach (var item in discountedLineItems)
            {
                sale.AddLineItem(item); // Add these directly to the sale.
            }
            var total = sale.LineItems.Sum(i => i.GetSubtotal());

            return(total);
        }
        public void sale_total_with_changing_product_price_should_remain_consistent()
        {
            var sale = new Sale();
            sale.AddLineItem(momogi);
            Assert.AreEqual(500m, sale.GetTotal());

            momogi.UnitPrice = 0;
            Assert.AreEqual(500m, sale.GetTotal());
        }
Exemplo n.º 5
0
        public void MakeLineItemIdenticalProductUpdatesQuantityByMultiples()
        {
            var sale = new Sale(SetupFileManagerWithNoPromotions().Object);

            sale.AddLineItem(new SalesLineItem(new Product("Oranges", 0.2m)));

            // Act
            sale.MakeLineItem(new Product("Oranges", 0.2m), quantity: 2); // add same line item

            Assert.That(sale.LineItems.Count, Is.EqualTo(1),
                        "Adding identical line item should update the quantity of the existing line item.");
            Assert.That(sale.LineItems[0].Quantity, Is.EqualTo(3));
        }
        /// <summary>
        /// Mutates the sale with quantity type discounts and gets the total.
        /// </summary>
        /// <param name="sale"></param>
        /// <returns></returns>
        public decimal GetTotal(Sale sale)
        {
            var discountedLineItems = new List <SalesLineItem>();

            foreach (var lineItem in sale.LineItems)
            {
                // Apply discounts directly to line item, if any.

                foreach (
                    var discount in
                    _discounts
                    .Where(d => d.IsValid() && !d.DiscountAppliedOnNextProduct)
                    .Where(d => d.ProductId == lineItem.ProductId && lineItem.Quantity >= d.ThresholdQuantity)
                    .OrderByDescending(d => d.ThresholdQuantity))
                {
                    // There may be eligible discount(s) to apply to current line item based on quantity.
                    // Apply the discounts with the largest quantities first as they generally have the better discounts.

                    while (lineItem.Quantity >= discount.ThresholdQuantity)
                    {
                        // Create new line item with the quantity that gets the discount.
                        var discountedLineItem =
                            new SalesLineItem(new Product(lineItem.ProductId, lineItem.ProductPrice), discount.ThresholdQuantity);
                        discountedLineItem.SetDiscount(discount.Discount);

                        // Store in temporary list.
                        discountedLineItems.Add(discountedLineItem);

                        // Decrement the threshold quantity from the original line item.
                        lineItem.AddQuantity(-1 * discount.ThresholdQuantity);

                        // TODO: Add a limit, i.e. only get the discount a certain number of times.
                    }
                }
            }

            sale.RemoveZeroQuantityLineItems();

            // Add newly created line items that have the discount directly to the sale.
            foreach (var item in discountedLineItems)
            {
                sale.AddLineItem(item);
            }

            var total = sale.LineItems.Sum(i => i.GetSubtotal());

            return(total);
        }
 public void sale_with_2_pepsi_should_be_totaled_10000()
 {
     var sale = new Sale();
     sale.AddLineItem(pepsi, 2);
     Assert.AreEqual(10000m, sale.GetTotal());
 }