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