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);
        }
Esempio n. 4
0
        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));
        }
Esempio n. 5
0
 public IActionResult Calculate([FromBody] TrolleyRequest trolleyRequest)
 {
     try
     {
         return(Ok(_trolleyTotalService.GetTotalInternal(trolleyRequest)));
     }
     catch (Exception e)
     {
         return(BadRequest("An error has occurred. " + e.Message));
     }
 }
Esempio n. 6
0
        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);
        }
Esempio n. 9
0
        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);
        }
Esempio n. 12
0
        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
                }));
            }
        }
Esempio n. 13
0
        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);
        }
Esempio n. 16
0
        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);
        }
Esempio n. 18
0
        /// <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));
        }
Esempio n. 19
0
        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));
 }
Esempio n. 23
0
 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)));
 }