Example #1
0
        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));
            }
        }
Example #5
0
        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);
        }