private static TrolleySpecial CombineSpecials(TrolleySpecial special1, TrolleySpecial special2) { return(new TrolleySpecial { Quantities = special1.Quantities.Concat(special2.Quantities) .GroupBy(trolleyQuantity => trolleyQuantity.Name).Select( grouping => new TrolleyQuantity { Name = grouping.Key, Quantity = grouping.Sum(trolleyQuantity => trolleyQuantity.Quantity) }).ToList(), Total = special1.Total + special2.Total }); }
private Trolley CreateTrolley(TrolleyModel trolleyModel) { var trolley = new Trolley(); var products = trolleyModel.Products.ToDictionary(p => p.Name, p => new ProductRef { Name = p.Name, Price = p.Price, }); foreach (var item in trolleyModel.Quantities) { trolley.AddItem(products[item.Name], item.Quantity); } foreach (var item in trolleyModel.Specials.SelectMany(s => s.Quantities)) { var special = new TrolleySpecial(); special.AddItem(products[item.Name], item.Quantity); trolley.AddSpecial(special); } return(trolley); }
/// <summary> /// Applies the special on the trolley and returns the amount of special, also spits out the remaining items after deducting the calculated items (in <see cref="shoppedProductQuantitiesMapMinusSpecial"/>) /// </summary> /// <param name="trolleySpecial"></param> /// <param name="shoppedProductQuantitiesMap"></param> /// <param name="shoppedProductQuantitiesMapMinusSpecial">Shopped products quantities after deducting the calculated specialed items</param> /// <returns></returns> private decimal GetAmountOfAppliedSpecial(TrolleySpecial trolleySpecial, Dictionary <string, int> shoppedProductQuantitiesMap, out Dictionary <string, int> shoppedProductQuantitiesMapMinusSpecial) { var shoppedProductQuantitiesMapCopy = shoppedProductQuantitiesMap.ToDictionary(q => q.Key, q => q.Value); var maxApplicableCount = GetMaxApplicableCount(trolleySpecial, shoppedProductQuantitiesMapCopy); decimal totalAmount = 0; if (maxApplicableCount == 0) { shoppedProductQuantitiesMapMinusSpecial = shoppedProductQuantitiesMap; return(0m); } totalAmount += maxApplicableCount * trolleySpecial.Total; foreach (var specialQuantity in trolleySpecial.Quantities) { shoppedProductQuantitiesMapCopy[specialQuantity.Name] -= (maxApplicableCount * specialQuantity.Quantity); } shoppedProductQuantitiesMapMinusSpecial = shoppedProductQuantitiesMapCopy; return(totalAmount); }
/// <summary> /// This method returns a list of only the best candidate special combos, by combining as many specials as possible. /// For example, if a trolley is eligible for special1 and special2 combined, only that special combo is returned, /// but special1 and special2 are not returned individually. /// </summary> private static List <TrolleySpecial> GetBestCandidateSpecialCombos(List <TrolleyQuantity> trolleyQuantities, TrolleySpecial eligibleSpecialCombo, List <TrolleySpecial> otherEligibleSpecialsToCombineWith) { var bestCandidateSpecialCombos = new List <TrolleySpecial>(); for (int i = 0; i < otherEligibleSpecialsToCombineWith.Count; i++) { var newSpecialCombo = CombineSpecials(eligibleSpecialCombo, otherEligibleSpecialsToCombineWith[i]); if (IsEligible(trolleyQuantities, newSpecialCombo)) { bestCandidateSpecialCombos.AddRange( GetBestCandidateSpecialCombos(trolleyQuantities, newSpecialCombo, otherEligibleSpecialsToCombineWith.Skip(i).ToList())); } } if (!bestCandidateSpecialCombos.Any()) { bestCandidateSpecialCombos.Add(eligibleSpecialCombo); } return(bestCandidateSpecialCombos); }
private static decimal CalculateSavings(List <TrolleyProduct> products, TrolleySpecial special) { var fullPriceEquivalentOfSpecial = CalculatePrice(products, special.Quantities); return(fullPriceEquivalentOfSpecial - special.Total); }
private static decimal GetSpecialQuantity(TrolleySpecial special, string productName) { return(special.Quantities .FirstOrDefault(quantity => quantity.Name == productName) ?.Quantity ?? 0); }
private static List <TrolleyQuantity> GetFullPricedQuantities(Trolley trolley, TrolleySpecial special) { return(trolley.Quantities.Select(quantity => new TrolleyQuantity { Name = quantity.Name, Quantity = quantity.Quantity - GetSpecialQuantity(special, quantity.Name) }).ToList()); }