private void ApplyBundeledSpecials(List <Product> products, Trolley trolley)
        {
            var validSpecials = new List <Special>();

            //Filter only those specials which have Total less than the full price total for bundeled products.
            var orderedSpecials = trolley.Specials.Where(x => x.Total < x.FullTotal).OrderByDescending(s => (s.FullTotal - s.Total));

            foreach (var special in orderedSpecials)
            {
                bool applySpecial = true;
                foreach (var qty in special.Quantities)
                {
                    var product = products.FirstOrDefault(x => x.Name == qty.Name);
                    if (product.Quantity < qty.Quantity)
                    {
                        applySpecial = false;
                    }
                }

                if (applySpecial)
                {
                    _eligibleSpecials.Add(special);

                    foreach (var qty in special.Quantities)
                    {
                        var product = products.FirstOrDefault(x => x.Name == qty.Name);
                        product.Quantity = product.Quantity - qty.Quantity;
                    }

                    ApplyBundeledSpecials(products, trolley);
                }
            }
        }
        private async Task <TrolleyViewModel> CreateTrolleyViewModelFromTrolleyAsync(Trolley trolley)
        {
            var trolleyViewModel = new TrolleyViewModel {
                Id = trolley.Id, OwnerId = trolley.OwnerId
            };

            foreach (var trolleyItem in trolley.Items)
            {
                var trolleyItemViewModel = new TrolleyItemViewModel
                {
                    Id = trolleyItem.Id, CatalogItemId = trolleyItem.CatalogItemId, Quantity = trolleyItem.Quantity
                };

                var catalogItem = await _catalogItemRepository.GetAsync(trolleyItem.CatalogItemId);

                var newItem = _manager.GetIndustry().ConvertItem(catalogItem);

                trolleyItemViewModel.ProductId          = newItem.ProductId;
                trolleyItemViewModel.ProductName        = newItem.ProductName;
                trolleyItemViewModel.ProductPictureUrl  = newItem.ProductPictureUrl;
                trolleyItemViewModel.ProductAllergyInfo = newItem.ProductAllergyInfo;
                trolleyViewModel.Items.Add(trolleyItemViewModel);
            }

            return(trolleyViewModel);
        }
        public async void WhenPostTrolleyCalculatorCalledItReturnsCorrectTotalAmount()
        {
            var trolley = new Trolley
            {
                Products = new[] { new Product {
                                       Name = "product1", Price = 1
                                   } },
                Specials = new[]
                {
                    new Special
                    {
                        Quantities =
                            new[]
                        {
                            new ProductQuantity
                            {
                                Name = "product1", Quantity = 2
                            }
                        },
                        Total = 1.5m
                    }
                },
                Quantities = new[]
                {
                    new ProductQuantity {
                        Name = "product1", Quantity = 4
                    }
                }
            };

            var result = await HttpRequestHelper.PostTrolleyCalculator(trolley);

            result.Should().Be(3);
        }
Пример #4
0
        public async Task <double> GetLowestTotal(Trolley trolley)
        {
            using (HttpClient httpClient = HttpClientBuilder.Build(_appSettings))
            {
                _logger.LogDebug($"Requesting trolley calculator service at {_appSettings.ResourceBaseUrl}/{Constants.Urls.Products}");


                using (HttpResponseMessage response = await httpClient.PostAsJsonAsync(
                           $"{Constants.Urls.TrolleyCalculator}?token={_appSettings.Token}",
                           trolley))
                {
                    string content = await response.Content.ReadAsStringAsync();

                    try
                    {
                        response.EnsureSuccessStatusCode();

                        double total = 0;
                        double.TryParse(content, out total);

                        return(total);
                    }
                    catch (HttpRequestException)
                    {
                        _logger.LogError("Error occurred while requesting trolley calculate service, error message: " + content);

                        throw;
                    }
                }
            }
        }
Пример #5
0
        public static decimal CalculateTotal(Trolley trolley)
        {
            var totals = new List <decimal>();

            if (trolley.Products.Length == 0 || trolley.Quantities.Length == 0)
            {
                return(0m);
            }

            if (trolley.Specials.Length == 0)
            {
                return(trolley.Products.Sum(p => p.Price * trolley.Quantities.First(q => q.Name == p.Name).Quantity));
            }
            else
            {
                foreach (var special in trolley.Specials)
                {
                    var min = special.Quantities.Min(
                        s => s.Quantity == 0 ? int.MaxValue : Math.Floor((decimal)(trolley.Quantities.First(q => q.Name == s.Name).Quantity / s.Quantity)));


                    var total = trolley.Quantities.Sum(q => (q.Quantity - min * special.Quantities.First(s => s.Name == q.Name).Quantity) * trolley.Products.First(p => p.Name == q.Name).Price) + special.Total * min;

                    totals.Add(total);
                }
            }

            return(totals.Min());
        }
Пример #6
0
        public int PostTrolleyTotal([FromBody] Trolley trolley)
        {
            var user = new User();

            user.name  = configuration.GetValue <string>("ApiSettings:UserName");
            user.token = configuration.GetValue <string>("ApiSettings:Token");
            string trolleyCalculatorUrl = configuration.GetValue <string>("ApiSettings:BaseUrl") + "/" +
                                          configuration.GetValue <string>("ApiSettings:trolleyCalculatorUrl") +
                                          "?token=" + user.token;

            string response = "";

            using (var httpClient = new HttpClient())
            {
                Uri u = new Uri(trolleyCalculatorUrl);

                string      strPayload = JsonConvert.SerializeObject(trolley);
                HttpContent c          = new StringContent(strPayload, Encoding.UTF8, "application/json");
                var         t          = Task.Run(() => SendURI(u, c));
                t.Wait();
                response = t.Result;
            }

            double total;
            bool   res = double.TryParse(response, out total);

            if (res == false)
            {
                total = 0;
            }

            return(Convert.ToInt32(total));
        }
Пример #7
0
        public static async Task <decimal> PostTrolleyCalculator(Trolley trolley)
        {
            var total = 0m;

            var client = new HttpClient
            {
                BaseAddress = new Uri(
                    "http://dev-wooliesx-recruitment.azurewebsites.net")
            };

            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            var content = JsonConvert.SerializeObject(trolley);

            Console.WriteLine(content);

            var stringContent = new StringContent(
                content,
                Encoding.UTF8,
                "application/json");

            var response = await client.PostAsync("/api/resource/trolleyCalculator?token=87c30bff-0669-4dcb-a5da-ae240fe9cdd7", stringContent);

            if (response.IsSuccessStatusCode)
            {
                total = JsonConvert.DeserializeObject <decimal>(await response.Content.ReadAsStringAsync());
            }

            return(total);
        }
        public decimal CalculateLowestTotal(Trolley trolley)
        {
            decimal total = 0;

            while (ProductsLeftToProcess(trolley.Quantities) > 0)
            {
                foreach (var special in trolley.Specials)
                {
                    if (IsSpecialActivated(special.Quantities, trolley.Quantities))
                    {
                        foreach (var specialQuantity in special.Quantities)
                        {
                            DecreaseQuantityForProductName(trolley.Quantities, specialQuantity.Name, specialQuantity.Quantity);
                        }
                        total += special.Total;
                    }
                }

                foreach (var productQuantity in trolley.Quantities)
                {
                    if (productQuantity.Quantity > 0)
                    {
                        total += GetPriceFromProductName(trolley.Products, productQuantity.Name);
                        DecreaseQuantityForProductName(trolley.Quantities, productQuantity.Name, 1);
                    }
                }
            }
            return(total);
        }
        private async Task <TrolleyViewModel> CreateTrolleyViewModelFromTrolleyAsync(Trolley trolley)
        {
            var trolleyViewModel = new TrolleyViewModel
            {
                Id      = trolley.Id,
                OwnerId = trolley.OwnerId
            };

            foreach (var trolleyItem in trolley.Items)
            {
                var trolleyItemViewModel = new TrolleyItemViewModel
                {
                    Id            = trolleyItem.Id,
                    CatalogItemId = trolleyItem.CatalogItemId,
                    Quantity      = trolleyItem.Quantity
                };

                var catalogItem = await _catalogItemRepository.GetAsync(trolleyItem.CatalogItemId);

                trolleyItemViewModel.ProductId         = catalogItem.ProductId;
                trolleyItemViewModel.ProductName       = catalogItem.ProductName;
                trolleyItemViewModel.ProductPictureUrl = catalogItem.ProductPictureUrl;
                trolleyViewModel.Items.Add(trolleyItemViewModel);
            }

            return(trolleyViewModel);
        }
Пример #10
0
        public static decimal CalculateTrolleyTotal(Trolley trolley)
        {
            var specialCombo         = GetBestSpecialCombo(trolley);
            var fullPricedQuantities = GetFullPricedQuantities(trolley, specialCombo);

            return(CalculatePrice(trolley.Products, fullPricedQuantities) + specialCombo.Total);
        }
Пример #11
0
        public async Task <decimal?> FindLowestTrolleyTotalAsync(Trolley trolley)
        {
            var uri = $"{TrolleyCalculatorUri}{_userProfile.Token}";

            try
            {
                var content = new StringContent(trolley.ToJsonString(), Encoding.UTF8, "application/json");

                var response = await _httpClient.PostAsync(uri, content);

                response.EnsureSuccessStatusCode();

                var value = await response.Content.ReadAsStringAsync();

                if (decimal.TryParse(value, out var rv))
                {
                    return(rv);
                }
            }
            catch (Exception e)
            {
                _logger.LogError($"Failed to get the lowest trolley total from {BaseAddress}{uri}. {e}");
            }

            return(null);
        }
Пример #12
0
        public ActionResult Create()
        {
            var t = new Trolley();

            t.IconColorRGB = "#008000";  // Must have starting value for Farbtastic
            return(View(t));
        }
Пример #13
0
        public async Task <IActionResult> Calculate([FromBody] Trolley trolley)
        {
            // validation and exception has not been implemented as this is only time with time contraints.
            // usually you would have at least 3 paths, model error, remote api error, unexpected error.
            decimal total = await _trolleySerivce.CalculateTotal(_token, trolley);

            return(Ok(total));
        }
Пример #14
0
        public TrolleyQuantityValidator(Trolley trolley)
        {
            RuleFor(quantity => quantity.Name)
            .Must(name => trolley.Products.Any(product => product.Name == name)).WithMessage("'Name' must be one of the Product names.");

            RuleFor(quantity => quantity.Quantity)
            .GreaterThanOrEqualTo(0);
        }
Пример #15
0
        private static List <TrolleySpecial> GetBestCandidateSpecialCombos(Trolley trolley)
        {
            var eligibleIndividualSpecials = trolley.Specials.Where(special => IsEligible(trolley.Quantities, special)).ToList();

            var bestSpecialCombo = new TrolleySpecial();

            return(GetBestCandidateSpecialCombos(trolley.Quantities, bestSpecialCombo, eligibleIndividualSpecials));
        }
Пример #16
0
 private static List <TrolleyQuantity> GetFullPricedQuantities(Trolley trolley, TrolleySpecial special)
 {
     return(trolley.Quantities.Select(quantity => new TrolleyQuantity
     {
         Name = quantity.Name,
         Quantity = quantity.Quantity - GetSpecialQuantity(special, quantity.Name)
     }).ToList());
 }
Пример #17
0
 /// <summary>
 /// 添加购物车
 /// </summary>
 /// <param name="trolley"></param>
 /// <returns></returns>
 public int AddTrolley(Trolley trolley)
 {
     using (OracleConnection conn = DapperHelper.GetConnString()) {
         conn.Open();
         string sql    = @"insert into trolley(trolleynumber,userid,storenumber,foodnumber,createtime,money,userphone,addressid) values(:trolleynumber,:userid,:storenumber,:foodnumber,:createtime,:money,:userphone,:addressid)";
         int    result = conn.Execute(sql, trolley);
         return(result);
     }
 }
Пример #18
0
        public ActionResult <decimal> TrolleyTotal(Trolley trolley)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            return(_trolleyService.GetTrolleyTotal(trolley));
        }
Пример #19
0
 public void TestMethod1()
 {
     var trolley = new Trolley
     {
         Products = new List <BaseProduct>
         {
             new BaseProduct
             {
                 Name  = "1",
                 Price = 5.0m
             },
             new BaseProduct
             {
                 Name  = "2",
                 Price = 2.0m
             }
         },
         Specials = new[]
         {
             new Special
             {
                 Quantities = new List <ProductQuantity>
                 {
                     new ProductQuantity
                     {
                         Name = "1", Quantity = 3
                     }, new ProductQuantity
                     {
                         Name = "2", Quantity = 0
                     }
                 }, Total = 5m
             },
             new Special
             {
                 Quantities = new List <ProductQuantity>
                 {
                     new ProductQuantity
                     {
                         Name = "1", Quantity = 1
                     }, new ProductQuantity
                     {
                         Name = "2", Quantity = 2
                     }
                 }, Total = 10m
             }
         },
         Quantities = new ProductQuantity[]
         {
             new ProductQuantity
             {
                 Name = "1", Quantity = 3
             }, new ProductQuantity {
                 Name = "2", Quantity = 2
             }
         }
     };
 }
Пример #20
0
        private static void Creater_KeyPressEvent(Trolley trolley, Product product)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List <Product>));

            using (FileStream stream = new FileStream("trolley.txt", FileMode.Truncate))
            {
                serializer.Serialize(stream, trolley.Products);
            }
        }
Пример #21
0
 public async Task <decimal> CalculateTotal(string token, Trolley trolley)
 {
     try
     {
         return(await _trolleyAPI.Calculate(token, trolley));
     }catch (Exception ex)
     {
         return(0);
     }
 }
        private async Task <Trolley> CreateTrolleyForOwnerAsync(string ownerId)
        {
            var trolley = new Trolley {
                OwnerId = ownerId
            };

            await _trolleyRepository.AddAsync(trolley);

            return(trolley);
        }
Пример #23
0
 /// <summary>
 /// 修改购物车
 /// </summary>
 /// <param name="trolley"></param>
 /// <returns></returns>
 public int UpdateTrolley(Trolley trolley)
 {
     using (OracleConnection conn = DapperHelper.GetConnString())
     {
         conn.Open();
         string sql    = @"update trolley set trolleynumber=:trolleynumber,userid=:userid,storenumber=:storenumber,foodnumber=:foodnumber,createtime=:createtime,money=:money,userphone=:userphone,addressid=:addressid where id=:id";
         int    result = conn.Execute(sql, trolley);
         return(result);
     }
 }
        public TrolleySpecialValidator(Trolley trolley)
        {
            RuleFor(special => special.Quantities)
            .Must(quantities => quantities.Select(quantity => quantity.Name).IsUnique()).WithMessage("Names must be unique.")
            .ForEach(collection => collection.SetValidator(_ => new TrolleyQuantityValidator(trolley)));

            RuleFor(special => special.Total)
            .GreaterThan(0)
            .LessThan(special => TrolleyCalculator.CalculatePrice(trolley.Products, special.Quantities)).WithMessage("Special must be cheaper than Products full price");
        }
        /// <summary>
        /// Confirm that trolley color matches route color.   If not, change it and
        /// save to DB and reset arrival time logic for that trolley.
        /// </summary>
        /// <param name="trolley"></param>
        /// <param name="route"></param>
        private async Task CheckTrolleyColorMatch(Trolley trolley, Route route)
        {
            if (trolley.IconColorRGB.ToLower() == route.RouteColorRGB.ToLower())
            {
                return;
            }
            trolley.IconColorRGB = route.RouteColorRGB;
            await SaveTrolleyToDB(trolley);

            StopArrivalTime.ResetTrolleyInfo(trolley);
        }
Пример #26
0
        public void WhenCalculatingTrolley_TheLowestTotalIsReturned(
            decimal expectedTotal,
            decimal priceA,
            decimal priceB,
            int quantityA,
            int quantityB,
            int quantitySpecialA,
            int quantitySpecialB)
        {
            //Arrange
            var trolley = new Trolley
            {
                Products = new List <Product>
                {
                    new Product {
                        Name = "A", Price = priceA
                    },
                    new Product {
                        Name = "B", Price = priceB
                    }
                },
                Specials = new List <Special>
                {
                    new Special
                    {
                        Quantities = new List <ProductQuantity>
                        {
                            new ProductQuantity {
                                Name = "A", Quantity = quantitySpecialA
                            },
                            new ProductQuantity {
                                Name = "B", Quantity = quantitySpecialB
                            }
                        },
                        Total = 15
                    }
                },
                Quantities = new List <ProductQuantity>
                {
                    new ProductQuantity {
                        Name = "A", Quantity = quantityA
                    },
                    new ProductQuantity {
                        Name = "B", Quantity = quantityB
                    }
                }
            };

            //Act
            var total = _trolleyCalculator.CalculateLowestTotal(trolley);

            //Assert
            Assert.AreEqual(expectedTotal, total);
        }
Пример #27
0
        public ActionResult DeleteConfirmed(int id)
        {
            Trolley trolley = db.Trolleys.Find(id);

            logger.Info($"Deleted trolley # {trolley.Number} '{trolley.TrolleyName}'");


            db.Trolleys.Remove(trolley);
            db.SaveChanges();
            return(RedirectToAction("Index"));
        }
Пример #28
0
        public IHttpActionResult GetTrolley(int id)
        {
            Trolley trolley = db.Trolleys.Find(id);

            if (trolley == null)
            {
                return(NotFound());
            }

            return(Ok(trolley));
        }
Пример #29
0
        static void Main(string[] args)
        {
            using (File.Create("trolley.txt"));

            bool           isFinish = false;
            ProductCreater creater  = new ProductCreater();
            Trolley        trolley  = new Trolley();

            creater.KeyPressEvent += Creater_KeyPressEvent;

            while (true)
            {
                switch (Chose())
                {
                case Constants.ADD_CHOSE:
                    creater.CreateAndSave(trolley);
                    break;

                case Constants.EXIT_CHOSE:
                    isFinish = true;
                    break;

                default:
                    Console.WriteLine("Нету такого выбора");
                    break;
                }

                if (isFinish == true)
                {
                    break;
                }
            }

            // 1) Нет нельзя, можно задать строку но не изменить, а разные операторы и методы возвращают обновленную строку

            // 2) Инструмент для вскрытия решении
            //    Assembly assembly = Assembly.LoadFile(string path);

            // 3) Преобразовние объекта в поток байтов. Пример:
            // XmlSerializer serializer = new XmlSerializer(typeof(List<Product>));
            // using (FileStream stream = new FileStream('trolley.txt', FileMode.Truncate))
            // {
            //     serializer.Serialize(stream, trolley.Products);
            // }

            //4) В Market.Models есть класс TableDataService

            //5) Плюсы Interface: очень гибкие в плане множественного наследования, обобщают какое или какие либо действия
            //   Минусы Interface: нету дефолтной реализаций
            //   Плюсы Abstarct Class: Может иметь дефолтную реализацию матодов, обобщают какое или какие либо действия
            //   Минусы Abstarct Class: Не может возможности множественного наследия

            //6) nullable тип это тот тип который может принять null значение, у классов nullable стойти по дефолту, а у структур нужно писать nullable или знак вопроса после имя типа. Это нужно чтобы тип принемал null значение при ситуациях который могут вернуть null значение
        }
        public async Task <IActionResult> Post([FromBody] Trolley trolley)
        {
            if (trolley == null)
            {
                return(new BadRequestObjectResult("trolley is not provided"));
            }

            double total = await _trolleyService.GetLowestTotal(trolley);

            return(Ok(total));
        }