예제 #1
0
        public decimal GetTrolleyTotal(TrolleyModel trolley)
        {
            _trolley = trolley;
            if ((_trolley == null) ||
                (_trolley.Products == null) ||
                (_trolley.Quantities == null))
            {
                return(0);
            }

            decimal lowestTotal = CalculateProductTotal();

            List <TrolleySpecial> specials = GetApplicableSpecials();

            if (specials.Count > 0)
            {
                decimal specialsTotal = GetSpecialsLowestTotal(specials);
                if (specialsTotal < lowestTotal)
                {
                    lowestTotal = specialsTotal;
                }
            }

            return(lowestTotal);
        }
        public void GetTrolleyTotal_WithSpecial()
        {
            TrolleyModel trolleyModel = new TrolleyModel();

            trolleyModel.Products = new List <TrolleyProduct>();
            trolleyModel.Products.Add(new TrolleyProduct()
            {
                Name = "Product 0", Price = 2
            });
            trolleyModel.Products.Add(new TrolleyProduct()
            {
                Name = "Product 1", Price = 5
            });

            trolleyModel.Specials = new List <TrolleySpecial>();
            List <TrolleyProductQuantity> tpq1 = new List <TrolleyProductQuantity>();

            tpq1.Add(new TrolleyProductQuantity()
            {
                Name = "Product 0", Quantity = 3
            });
            tpq1.Add(new TrolleyProductQuantity()
            {
                Name = "Product 1", Quantity = 0
            });
            trolleyModel.Specials.Add(new TrolleySpecial()
            {
                Total = 5, Quantities = tpq1
            });

            List <TrolleyProductQuantity> tpq2 = new List <TrolleyProductQuantity>();

            tpq2.Add(new TrolleyProductQuantity()
            {
                Name = "Product 0", Quantity = 1
            });
            tpq2.Add(new TrolleyProductQuantity()
            {
                Name = "Product 1", Quantity = 2
            });;
            trolleyModel.Specials.Add(new TrolleySpecial()
            {
                Total = 10, Quantities = tpq2
            });

            trolleyModel.Quantities = new List <TrolleyProductQuantity>();
            trolleyModel.Quantities.Add(new TrolleyProductQuantity()
            {
                Name = "Product 0", Quantity = 3
            });
            trolleyModel.Quantities.Add(new TrolleyProductQuantity()
            {
                Name = "Product 1", Quantity = 2
            });

            decimal total = _trolleyTotalService.GetTrolleyTotal(trolleyModel);

            Assert.AreEqual(14, total);
        }
        public void TestTrolleyTotal()
        {
            // arrange
            var trolley = new TrolleyModel
            {
                products = new[]
                {
                    new ProductModel {
                        name = "c", price = 1.01d
                    },
                    new ProductModel {
                        name = "a", price = 1.07d
                    },
                    new ProductModel {
                        name = "d", price = 0.99d
                    },
                    new ProductModel {
                        name = "b", price = 1.04d
                    },
                },
                specials = new[]
                {
                    new SpecialModel {
                        quantities = new[]
                        {
                            new QuantityModel {
                                name = "e", quantity = 3d
                            },
                            new QuantityModel {
                                name = "f", quantity = 5d
                            },
                        },
                        total = 25d
                    }
                },
                quantities = new[]
                {
                    new QuantityModel {
                        name = "a", quantity = 2d
                    },
                    new QuantityModel {
                        name = "b", quantity = 4d
                    },
                    new QuantityModel {
                        name = "c", quantity = 1d
                    },
                    new QuantityModel {
                        name = "d", quantity = 5d
                    }
                }
            };

            // act
            var     rs    = new ResourceService(It.IsAny <HttpClient>(), It.IsAny <IOptions <Config> >());
            decimal total = rs.TrolleyTotal(trolley.products, trolley.specials, trolley.quantities);

            // assert
            Assert.AreEqual((decimal)37.26, total);
        }
        public async Task <IActionResult> TrolleyTotal([FromBody] TrolleyModel trolleyModel)
        {
            Logger?.LogDebug("'{0}' has been invoked", nameof(TrolleyTotal));

            var trolleyTotal = await _mediator.Send(new GetTrolleyTotalQuery(trolleyModel, Environment.GetEnvironmentVariable("AUTHENTICATION_TOKEN")));

            return(Ok(trolleyTotal));
        }
        public async Task getTrolleyTotalSample4()
        {
            decimal      expected       = 6.296458940268143M;
            TrolleyModel trolleyModel   = JsonConvert.DeserializeObject <TrolleyModel>(File.ReadAllText(@"Mock\\Trolley\\TrolleyRequest-Sample4.json"));
            var          trolleyService = new TrolleyService();
            var          result         = await trolleyService.GetTrollyTotal(trolleyModel, _token);

            Assert.Equal(expected, result);
        }
예제 #6
0
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string       requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            TrolleyModel data        = JsonConvert.DeserializeObject <TrolleyModel>(requestBody);
            var          products    = data.products;
            var          specials    = data.specials;
            var          quantities  = data.quantities;


            var res = _service.TrolleyTotal(products, specials, quantities);

            return(new OkObjectResult(res));
        }
예제 #7
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);
        }
예제 #8
0
        public IActionResult Total([FromBody] TrolleyModel trolleyModel)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var trolleyModelJson = JsonConvert.SerializeObject(trolleyModel);

            System.Diagnostics.Trace.WriteLine(trolleyModelJson);
            logger.LogError(trolleyModelJson);

            try
            {
                var trolley = CreateTrolley(trolleyModel);
                var total   = trolleyService.CalculateTotal(trolley);
                return(Ok(total));
            }
            catch (Exception ex)
            {
                logger.LogError(ex, ex.Message);
                return(StatusCode(StatusCodes.Status500InternalServerError, "Operation failed."));
            }
        }
        private decimal CalculateTrolleyTotal(TrolleyModel trolleyModel)
        {
            //STEP 1
            //Get the list of products and quantities into respective dictionaries
            var productDictionary  = trolleyModel.Products.ToDictionary(x => x.Name, x => x.Price);
            var quantityDictionary = trolleyModel.Quantities.ToDictionary(y => y.Name, y => y.Quantity);

            //if there are no products/quantities exists just return 0
            if (productDictionary.Count == 0 || quantityDictionary.Count == 0 ||
                productDictionary.Sum(x => x.Value) <= 0 ||
                quantityDictionary.Sum(x => x.Value) <= 0)
            {
                return(0);
            }

            //STEP 2
            //if product & quantity names doesn't match throw exception
            var productQualityDiff = productDictionary.Keys.Except(quantityDictionary.Keys).Concat(quantityDictionary.Keys.Except(productDictionary.Keys));

            if (productQualityDiff.Any())
            {
                var ex = new Exception(message: "incomplete content");
                ex.Data.Add("product quality differences: ", productQualityDiff);
                throw ex;
            }


            //STEP 3
            //get the maximum price and keep it aside
            var maxPrice = productDictionary.ToDictionary(orig => orig.Key, orig => orig.Value * quantityDictionary[orig.Key]).Sum(x => x.Value);


            //check if specials exists, if not just return regular price
            if (trolleyModel.Specials.Count == 0)
            {
                return(maxPrice);
            }

            //STEP 4
            //Now get the list of quantities as dictionaries along with their totals and unit price
            var listOfSpecials = new List <(Dictionary <string, int> Quantity, decimal Total)>();

            trolleyModel.Specials.ForEach(special =>
            {
                //Check if the special quantity exceeds required quantity, if so just ignore this special
                if (special.Quantities.ToDictionary(p => p.Name, p => quantityDictionary[p.Name] - p.Quantity)
                    .ToDictionary(orig => orig.Key, orig => orig.Value).Any(x => x.Value < 0) || special.Quantities.Sum(x => x.Quantity) <= 0)
                {
                    return;
                }

                listOfSpecials.Add((special.Quantities.ToDictionary(x => x.Name, x => x.Quantity), special.Total));
            });

            //there are no special that can offer better unit price than maxPrice, so just return maxPrice
            if (listOfSpecials.Count == 0)
            {
                return(maxPrice);
            }
            //Add the max price to the price combinations
            priceCombinations.Add(maxPrice);

            //STEP 5
            //Validate specials against the products
            listOfSpecials.ForEach(special =>
            {
                if (productDictionary.Keys.Except(special.Quantity.Keys).Concat(special.Quantity.Keys.Except(productDictionary.Keys)).Any())
                {
                    priceCombinations.Add(0);
                    return;
                }
            });


            //STEP 6
            //Get the lowest special quantity based on the following criteria
            //a. that offers best unit price
            //b. that has least quantity so that
            //var lowestSpecialQuantity = listOfSpecials.OrderBy(x => x.UnitPrice).ThenBy(y => y.Quantity.Values.Sum()).FirstOrDefault();

            listOfSpecials.ForEach(special =>
            {
                //Get all the price combinations using lowest special quantity
                AddPriceCombinations(special, listOfSpecials, quantityDictionary, productDictionary);
            });

            //FINAL STEP
            //Finally return the least possible price from the list
            return(priceCombinations.Min());
        }
        public async Task <decimal> GetTrollyTotal(TrolleyModel TrolleyModel, string token)
        {
            decimal trolleyTotal = CalculateTrolleyTotal(TrolleyModel);

            return(await Task.FromResult(trolleyTotal));
        }
        public void GetTrolleyTotal_NoSpecial()
        {
            TrolleyModel trolleyModel = new TrolleyModel();

            trolleyModel.Products = new List <TrolleyProduct>();
            trolleyModel.Products.Add(new TrolleyProduct()
            {
                Name = "Product 0", Price = 14.6584559975464M
            });
            trolleyModel.Products.Add(new TrolleyProduct()
            {
                Name = "Product 1", Price = 6.25149348110496M
            });
            trolleyModel.Products.Add(new TrolleyProduct()
            {
                Name = "Product 2", Price = 13.6667721409662M
            });

            trolleyModel.Specials = new List <TrolleySpecial>();
            List <TrolleyProductQuantity> tpq1 = new List <TrolleyProductQuantity>();

            tpq1.Add(new TrolleyProductQuantity()
            {
                Name = "Product 0", Quantity = 5
            });
            tpq1.Add(new TrolleyProductQuantity()
            {
                Name = "Product 1", Quantity = 5
            });
            tpq1.Add(new TrolleyProductQuantity()
            {
                Name = "Product 2", Quantity = 2
            });
            trolleyModel.Specials.Add(new TrolleySpecial()
            {
                Total = 8.78499156130719M, Quantities = tpq1
            });

            List <TrolleyProductQuantity> tpq2 = new List <TrolleyProductQuantity>();

            tpq2.Add(new TrolleyProductQuantity()
            {
                Name = "Product 0", Quantity = 0
            });
            tpq2.Add(new TrolleyProductQuantity()
            {
                Name = "Product 1", Quantity = 4
            });
            tpq2.Add(new TrolleyProductQuantity()
            {
                Name = "Product 2", Quantity = 3
            });
            trolleyModel.Specials.Add(new TrolleySpecial()
            {
                Total = 31.7466055797785M, Quantities = tpq2
            });

            List <TrolleyProductQuantity> tpq3 = new List <TrolleyProductQuantity>();

            tpq3.Add(new TrolleyProductQuantity()
            {
                Name = "Product 0", Quantity = 1
            });
            tpq3.Add(new TrolleyProductQuantity()
            {
                Name = "Product 1", Quantity = 9
            });
            tpq3.Add(new TrolleyProductQuantity()
            {
                Name = "Product 2", Quantity = 5
            });
            trolleyModel.Specials.Add(new TrolleySpecial()
            {
                Total = 29.3865395547186M, Quantities = tpq3
            });

            trolleyModel.Quantities = new List <TrolleyProductQuantity>();
            trolleyModel.Quantities.Add(new TrolleyProductQuantity()
            {
                Name = "Product 0", Quantity = 5
            });
            trolleyModel.Quantities.Add(new TrolleyProductQuantity()
            {
                Name = "Product 1", Quantity = 7
            });
            trolleyModel.Quantities.Add(new TrolleyProductQuantity()
            {
                Name = "Product 2", Quantity = 1
            });

            decimal total = _trolleyTotalService.GetTrolleyTotal(trolleyModel);

            Assert.AreEqual(130.71950649643292M, total);
        }
 public decimal GetTrolleyTotal([FromBody] TrolleyModel trolley)
 {
     return(_service.GetTrolleyTotal(trolley));
 }
예제 #13
0
 public GetTrolleyTotalQuery(TrolleyModel trolleyModel, string token)
 {
     TrolleyModel = trolleyModel;
     Token        = token;
 }