Ejemplo n.º 1
0
 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
     });
 }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        /// <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);
        }
Ejemplo n.º 4
0
        /// <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);
        }
Ejemplo n.º 5
0
        private static decimal CalculateSavings(List <TrolleyProduct> products, TrolleySpecial special)
        {
            var fullPriceEquivalentOfSpecial = CalculatePrice(products, special.Quantities);

            return(fullPriceEquivalentOfSpecial - special.Total);
        }
Ejemplo n.º 6
0
 private static decimal GetSpecialQuantity(TrolleySpecial special, string productName)
 {
     return(special.Quantities
            .FirstOrDefault(quantity => quantity.Name == productName)
            ?.Quantity ?? 0);
 }
Ejemplo n.º 7
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());
 }