protected void CreateLineItems(Product product, Special special, int scannedItemCount) { var scannedItems = CreateScannedItems(product, scannedItemCount); var productSpecial = new ProductSpecial(product, special); _lineItems = productSpecial.CreateLineItems(scannedItems); }
/// <summary> /// This function is to check if the special is cheaper than buying the product directly /// </summary> /// <param name="special"></param> /// <param name="productPrices"></param> /// <returns></returns> private bool IsSpecialCheaperThanProductPrices(ProductSpecial special, List <ProductPrice> productPrices) { var productPrice = special.Quantities.Join(productPrices, specialQuantity => specialQuantity.Name, productPrice => productPrice.Name, (specialQuantity, productPrice) => specialQuantity.Quantity * productPrice.Price).Sum(); return(special.Total < productPrice); }
/// <summary> /// This function updates product quantities by the number of times special can be applied for that product /// </summary> /// <param name="eligibleSpecial"></param> /// <param name="productQuantities"></param> /// <param name="products"></param> /// <param name="TimesCanBeApplied"></param> private void UpdateProductQuantities(ProductSpecial eligibleSpecial, List <ProductQuantity> productQuantities, List <ProductPrice> products, int TimesCanBeApplied) { foreach (var trolleyItem in productQuantities) { var product = products?.FirstOrDefault(x => x.Name.Equals(trolleyItem.Name, StringComparison.OrdinalIgnoreCase)); var productSpecial = eligibleSpecial?.Quantities.FirstOrDefault(x => x.Name.Equals(trolleyItem.Name, StringComparison.OrdinalIgnoreCase)); if (productSpecial != null && trolleyItem.Quantity >= productSpecial.Quantity) { trolleyItem.Quantity -= (productSpecial.Quantity * TimesCanBeApplied); } } }
/// <summary> /// This function applies passed special and checks recursively all combinations /// with other specials to get minimum trolley value /// </summary> /// <param name="eligibleSpecial"></param> /// <param name="TimesCanBeApplied"></param> /// <param name="productQuantities"></param> /// <param name="products"></param> /// <param name="eligibleSpecials"></param> /// <returns></returns> private decimal GetSpecialTotal(ProductSpecial eligibleSpecial, int TimesCanBeApplied, List <ProductQuantity> productQuantities, List <ProductPrice> products, List <ProductSpecial> eligibleSpecials ) { var trolleyTotal = eligibleSpecial.Total * TimesCanBeApplied; // updating product quantities after applying special UpdateProductQuantities(eligibleSpecial, productQuantities, products, TimesCanBeApplied); // getting if any other specials can be applied var otherSpecials = GetEligibleSpecials(eligibleSpecials, productQuantities, products, false); if (otherSpecials.Count > 0) { // list to get totals of other special combinations var innerTrolleyTotals = new List <(decimal, List <ProductQuantity>)>(); foreach (var otherSpecial in otherSpecials) { var tempProductQuantities = GetProductQuantityCopy(productQuantities); // getting other special total var tempTrolleyTotal = GetSpecialTotal(otherSpecial.eligibleSpecial, otherSpecial.TimesCanBeApplied, tempProductQuantities, products, eligibleSpecials); // if product total is greater than special then use special innerTrolleyTotals.Add((tempTrolleyTotal, tempProductQuantities)); } // returning the lowest trolley total of different special combinations var lowestTotal = innerTrolleyTotals.OrderBy(x => x.Item1).First(); productQuantities = lowestTotal.Item2; return(trolleyTotal += lowestTotal.Item1); } else { // apply product prices if no more specials are applicable return(trolleyTotal += GetTrolleyTotalWithoutSpecials(products, productQuantities)); } }
public decimal CalculateTotal(Trolley trolley) { var unitPrices = trolley.Products.ToDictionary(p => p.Name, p => p.Price); var specials = new Dictionary <string, List <ProductSpecial> >(); foreach (var trolleySpecial in trolley.Specials) { foreach (var trolleySpecialQuantity in trolleySpecial.Quantities) { if (trolleySpecialQuantity.Quantity == 0) { continue; } if (!specials.ContainsKey(trolleySpecialQuantity.Name)) { specials[trolleySpecialQuantity.Name] = new List <ProductSpecial>(); } var productSpecial = new ProductSpecial { Quantity = trolleySpecialQuantity.Quantity, SpecialUnitPrice = trolleySpecial.Total }; specials[trolleySpecialQuantity.Name].Add(productSpecial); } } decimal total = 0; foreach (var trolleyQuantity in trolley.Quantities) { var lowestTotal = CalculateTotalPrice(trolleyQuantity.Quantity, specials[trolleyQuantity.Name], unitPrices[trolleyQuantity.Name]); total += lowestTotal; } return(total); }