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); }
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)); }
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); }
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)); }
public GetTrolleyTotalQuery(TrolleyModel trolleyModel, string token) { TrolleyModel = trolleyModel; Token = token; }