private decimal GetCheapestTotal(TrolleyVM trolley, List <SpecialVM> potentialSpecials, TrolleyCheckout trolleyCheckout)
        {
            int     indexCheapest = 0;
            decimal cheapest      = 0;

            for (int i = 0; i < potentialSpecials.Count; i++)
            {
                var special            = potentialSpecials[i];
                var checkoutForSpecial = new TrolleyCheckout(trolleyCheckout.Total);
                var trolleyForSpecial  = new TrolleyVM(trolley);

                checkoutForSpecial.Total += special.Total;
                ApplySpecial(special, trolleyForSpecial.Quantities);

                // Recursive call to continue calculating with reduced items
                var totalForSpecial = GetTrolleyTotal(trolleyForSpecial, checkoutForSpecial);

                if (i == 0)
                {
                    cheapest = totalForSpecial;
                }
                else if (totalForSpecial < cheapest)
                {
                    indexCheapest = i;
                    cheapest      = totalForSpecial;
                }
            }

            // Apply the special that has cheapest end value
            return(cheapest);
        }
        // Get total for current trolley - Recursive function
        private decimal GetTrolleyTotal(TrolleyVM trolley, TrolleyCheckout trolleyCheckout)
        {
            // 1. Get all specials that apply to trolley.
            var potentialSpecials = GetPotentialSpecials(trolley);

            // 2. Calculate end cost of each potential special to get the cheapest result
            if (potentialSpecials.Count > 0)
            {
                return(GetCheapestTotal(trolley, potentialSpecials, trolleyCheckout));
            }
            else
            {
                return(GetSingularItemsTotal(trolley, trolleyCheckout));
            }
        }
        private decimal GetSingularItemsTotal(TrolleyVM trolley, TrolleyCheckout trolleyCheckout)
        {
            // finally calculate the remaining trolley items
            foreach (ProductQuantityVM item in trolley.Quantities)
            {
                var product = trolley.Products.Find(p => p.Name == item.Name);
                if (product == null)
                {
                    throw new Exception("Item in trolley is not listed as a product");
                }

                trolleyCheckout.Total += item.Quantity * product.Price;
                item.Quantity          = 0;
            }

            return(trolleyCheckout.Total);
        }
        public decimal CalculateTrolleyTotal(TrolleyVM trolleyVM)
        {
            var trolleyCheckout = new TrolleyCheckout();

            return(GetTrolleyTotal(trolleyVM, trolleyCheckout));
        }