public decimal GetTotalInternal(TrolleyRequest trolleyRequest) { //Quantities is what is in your cart //Product is a list of the products and their original price //Specials are a list of possible specials, sometimes involving the requirement of multiple items together which then all get sold for total //All items in quantities must be listed in each special, products which aren't in the special are still set to quantity 0 //If you have a product in quantities that isn't in the product list, it's free if (trolleyRequest.Products == null || trolleyRequest.Products.Count == 0) { throw new ArgumentException(nameof(trolleyRequest) + " no products are specified in request"); } if (trolleyRequest.Quantities == null || trolleyRequest.Quantities.Count == 0) { throw new ArgumentException(nameof(trolleyRequest) + " no products are specified in request"); } //TODO: validate the data var values = new List <decimal>(); GetTotalRecursive(values, trolleyRequest.Specials, trolleyRequest.Products, trolleyRequest.Quantities, 0); var lowest = values.Min(); return(lowest); }
public static Trolley ToTrolley(TrolleyRequest request) { return(new Trolley { Products = request.Products, Discounts = request.Specials.Select(s => ToDiscount(s)), Purchases = request.Quantities.Select(q => ToPurchase(q)) }); }
/// <summary> /// This method calls the WooliesX trolleyTotal API /// </summary> /// <param name="trolleyRequest"></param> /// <returns></returns> public async Task <decimal> CalculateTrolleyTotal(TrolleyRequest trolleyRequest) { var content = new StringContent(JsonConvert.SerializeObject(trolleyRequest), Encoding.UTF8, "application/json"); var httpResponse = await _client.PostAsync($"resource/trolleyCalculator", content); var products = await httpResponse.Content.ReadAsAsync <decimal>(); return(products); }
public async Task <decimal> CalculateTrolleyAsync(TrolleyRequest request) { var requestParams = new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("token", _config.Token) }; var result = await PostAsync(requestParams, request, TrolleyCalculatorPath); return(decimal.Parse(result)); }
public IActionResult Calculate([FromBody] TrolleyRequest trolleyRequest) { try { return(Ok(_trolleyTotalService.GetTotalInternal(trolleyRequest))); } catch (Exception e) { return(BadRequest("An error has occurred. " + e.Message)); } }
public async Task <ActionResult <decimal> > GetTrolleyTotal([FromBody] TrolleyRequest trolleyRequest) { var total = await _trolleyService.GetTrolleyTotalAsync(trolleyRequest); if (total <= 0) { return(BadRequest()); } return(Ok(total)); }
public async Task CalculateLowestTrolleyTotal() { var trolleyRequest = new TrolleyRequest() { Products = new List <Product> { new Product() { Name = "ProductA", Price = 15.40150525M } }, Quantities = new List <ProductQuantity> { new ProductQuantity() { Name = "ProductA", Quantity = 9 } }, Specials = new List <Special> { new Special() { Quantities = new List <ProductQuantity> { new ProductQuantity() { Name = "ProductA", Quantity = 5 } }, Total = 50 }, new Special() { Quantities = new List <ProductQuantity> { new ProductQuantity() { Name = "ProductA", Quantity = 3 } }, Total = 35 } } }; var result = await new TrolleyService().CalculateTrolleyTotal(trolleyRequest); result.ShouldBe(100.40150525M); }
public async Task GetTrolleyTotal() { // Arrange var trolleyRequest = new TrolleyRequest { Products = new List <ProductRequest> { new ProductRequest { Name = "Test A", Price = 14 } }, Specials = new List <SpecialRequest> { new SpecialRequest { Quantities = new List <QuantityRequest> { new QuantityRequest { Name = "Test B", Quantity = 1 } } } }, Quantities = new List <QuantityRequest> { new QuantityRequest { Name = "Test C" , Quantity = 1 } } }; _trolleyService.GetTrolleyTotalAsync(trolleyRequest).Returns(Task.FromResult(14m)); // Act var actionResult = await _controller.GetTrolleyTotal(trolleyRequest); var result = actionResult.Result as OkObjectResult; var total = (decimal)result.Value; // Assert Assert.IsAssignableFrom <decimal>(total); Assert.Equal(14, total); }
public async Task <IActionResult> Post([FromBody] TrolleyRequest request) { try { var response = await _trolleyService.TrolleyTotal(request); return(Ok(response)); } catch (System.Exception ex) { logger.Error(ex, "Unable to retrieve total trolley details"); } return(new BadRequestResult()); }
public static Order ToOrder(this TrolleyRequest trolleyRequest) { return(new Order() { ProductWithQuantities = trolleyRequest.Products.Select(x => { return new ProductWithQuantity() { Name = x.Name, Price = x.Price, Quantity = trolleyRequest.Quantities.Where(x => x.Name == x.Name).FirstOrDefault().Quantity }; }).ToList() }); }
private async Task <decimal> ResourceLookup <T>(string resourceEndpoint, TrolleyRequest request) { var requestObject = JsonConvert.SerializeObject(request, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); var response = await _httpClient.PostAsync($"{resourceEndpoint}?token={Constants.Authentication.Token}", new StringContent(requestObject, Encoding.UTF8, "application/json")); var readResponse = await response.Content.ReadAsStringAsync(); if (decimal.TryParse(readResponse, out decimal temp)) { return(temp); } return(0M); }
public IActionResult Exercise3([FromBody] TrolleyRequest trolleyRequest) { var result = Exercise3Service.CalculateMinimumTrolleyTotal(trolleyRequest.specials, trolleyRequest.products, trolleyRequest.quantities); if (result.IsOk) { return(Ok(result.Value)); } else { return(BadRequest(new ApiResponse() { passed = false, url = "", message = result.Errors })); } }
public async Task <decimal> GetTotal(TrolleyRequest trolleyRequest) { var requestJson = JsonConvert.SerializeObject(trolleyRequest); var content = new StringContent(requestJson, Encoding.UTF8, "application/json"); var url = _settings.BaseUrl + $"/api/resource/trolleyCalculator?token={_settings.Token}"; var response = await PostAsync(url, content).ConfigureAwait(false); response.EnsureSuccessStatusCode(); var responseJson = await response.Content.ReadAsStringAsync().ConfigureAwait(false); return(JsonConvert.DeserializeObject <decimal>(responseJson)); }
public decimal GetLowestTotal(TrolleyRequest trolleyRequest) { var order = trolleyRequest.ToOrder(); var specials = trolleyRequest.Specials; specials.Sort((a, b) => { return(GetSavingsFromSpecial(b, order).CompareTo(GetSavingsFromSpecial(a, order))); }); foreach (var item in specials) { order = ApplySpecial(order, item); } return(order.Total); }
public decimal CalculateTotal(TrolleyRequest trolleyRequest) { var productPriceMap = trolleyRequest.Products.ToDictionary(r => r.Name, r => r.Price); var sums = new List <decimal>(); decimal maxTotal = 0; foreach (var quantity in trolleyRequest.Quantities) { maxTotal += quantity.Quantity * productPriceMap[quantity.Name]; } if (trolleyRequest.Specials == null || !trolleyRequest.Specials.Any()) { return(maxTotal); } sums.Add(maxTotal); var quantityMap = trolleyRequest.Quantities.ToDictionary(r => r.Name, r => r.Quantity); var productNames = trolleyRequest.Products.Select(r => r.Name).ToList(); foreach (var special in trolleyRequest.Specials) { if (CheckSpecialMatchesAllProducts(special, productNames)) { throw new ValidationException("Specials does not match with Products"); } decimal totalWithoutSpecialPrice = 0; var minSpecialMultiplier = GetMinSpecialMultiplier(special, quantityMap); foreach (var spectialQuantity in special.Quantities) { var quantityRemaining = (GetQuantityByName(quantityMap, spectialQuantity.Name) - spectialQuantity.Quantity * minSpecialMultiplier); totalWithoutSpecialPrice += GetPriceByName(productPriceMap, spectialQuantity.Name) * (quantityRemaining > 0 ? quantityRemaining : 0); } sums.Add(totalWithoutSpecialPrice + special.Total * minSpecialMultiplier); } var minTotal = sums.Min(); return(minTotal); }
public async Task <decimal> GetTrolleyTotalAsync(TrolleyRequest trolleyRequest) { try { var response = await _wolliesXApiClient.GetTrolleyTotalAsync(_appSettings.Token, trolleyRequest); if (!response.IsSuccessStatusCode) { return(0); } return(response.Content); } catch { // Log Exception return(0); } }
public async Task CalculateTrolley_Should_Return_Ok() { var client = new ResourceApiClient(new ApplicationConfig { ResourceEndpoint = "http://resource-endpoint/api/resource/", Token = "Enter token here" }); var request = new TrolleyRequest { Products = new List <ProductRequestItem>() { new ProductRequestItem() { Name = "Test Product B", Price = 101.99M } }, Specials = new List <SpecialsRequestItem>() { new SpecialsRequestItem() { Quantities = new List <QuantityRequestItem>() { new QuantityRequestItem() { Name = "Test Product B", Quantity = 1 } }, Total = 1 } }, Quantities = new List <QuantityRequestItem>() { new QuantityRequestItem() { Name = "Test Product B", Quantity = 1 } } }; var result = await client.CalculateTrolleyAsync(request); }
/// <summary> /// This method is an implementation of the WooliesX trolleyTotal end point /// </summary> /// <param name="trolleyRequest"></param> /// <returns></returns> public async Task <decimal> CalculateTrolleyTotal(TrolleyRequest trolleyRequest) { var applicableSpecials = new List <Special>(); var trolleyProducts = trolleyRequest.Products; var trolleySpecials = trolleyRequest.Specials; var trolleyQuantities = trolleyRequest.Quantities; var products = (from p in trolleyProducts join q in trolleyQuantities on p.Name equals q.Name select new TrolleyProduct { Name = p.Name, Price = p.Price, Quantity = q.Quantity }).ToList(); if (trolleySpecials != null && trolleySpecials.Any()) { foreach (var special in trolleySpecials) { var totalPrice = (from tp in products join sp in special.Quantities on tp.Name equals sp.Name group new { tp, sp } by tp.Name into productQtyGroup select productQtyGroup.Sum(x => x.tp.Price * x.sp.Quantity)).Sum(); special.TotalBenefit = totalPrice - special.Total; } var result = GetApplicableSpecials(products?.ToDictionary(x => x.Name), trolleySpecials); if (result != null && result.Any()) { applicableSpecials.AddRange(result); } } return((applicableSpecials?.Sum(x => x.Total) ?? 0) + products.Sum(p => p.Quantity * p.Price)); }
public async Task <IActionResult> GetTrolleyTotal([FromBody] TrolleyRequest trolleyRequest) { var validationResult = new TrolleyRequestValidator().Validate(trolleyRequest); if (!validationResult.IsValid) { var errors = validationResult.Errors.Select(e => e.ErrorMessage).ToList(); return(BadRequest(errors)); } try { _logger.LogInformation("GetTrolleyTotal Requested:", trolleyRequest); var trolleyTotal = await _trolleyService.CalculateTrolleyTotal(trolleyRequest); return(Ok(trolleyTotal)); } catch (Exception e) { _logger.LogError(e, "An error has occured while calculating trolley total."); throw; } }
public ActionResult <decimal> CalculateTotal([FromBody] TrolleyRequest trolleyRequest) { var products = _trolleyCalculatorService.CalculateTotal(trolleyRequest); return(Ok(products)); }
public async Task <decimal> GetTotal(TrolleyRequest trolleyRequest) { return(await _wooliesXApiClient.GetTotal(trolleyRequest).ConfigureAwait(false)); }
public async Task <decimal> TrolleyTotal(TrolleyRequest request) { return(await ResourceLookup <decimal>(Constants.Url.TrolleyCalculatorApiUrl, request)); }
public IActionResult Exercise3([FromBody] TrolleyRequest trolleyRequest) { return(Ok(Exercise3Service.CalculateMinimumTrolleyTotal(trolleyRequest.specials, trolleyRequest.products, trolleyRequest.quantities))); }
public async Task <IActionResult> TrolleyTotal(TrolleyRequest request) { return(Ok(_trolleryService.GetLowestTotal(request))); }