public void CalculateOrderWithPromotion_OnValdInput_ShouldCalculateBasedOnPromotion_Promo2_Scenario2()
        {
            // Arrange
            var mockRequest = new CalculatePromotionRequest()
            {
                PromotionId = "1AA7E44F-6C5D-46CB-84D0-87720CDB58E3",
                Skus        = new List <SkuRequest>()
                {
                    new SkuRequest()
                    {
                        Name        = "A",
                        Rate        = 50,
                        SkuQuantity = 2
                    },
                    new SkuRequest()
                    {
                        Name        = "C",
                        Rate        = 50,
                        SkuQuantity = 2
                    }
                }
            };

            mockRepository.Setup((x) => x.GetPromotion(It.IsAny <Guid>())).Returns(mockPromotions[1]);
            mockRepository.Setup((x) => x.GetPromotionType(It.IsAny <Guid>())).Returns(mockPromotionTypes[0]);

            // Act
            var result = _promotionsController.CalculateOrderWithPromotion(mockRequest);

            // Assert
            Assert.AreEqual(200, result);
        }
        public void CalculateOrderWithPromotion_WhenPromotionIdIsNull_ShouldReturnZero()
        {
            // Arrange
            var mockRequest = new CalculatePromotionRequest()
            {
                PromotionId = null,
                Skus        = new List <SkuRequest>()
                {
                    new SkuRequest()
                    {
                        Name        = "A",
                        Rate        = 50,
                        SkuQuantity = 1
                    }
                }
            };

            mockRepository.Setup((x) => x.GetPromotion(It.IsAny <Guid>())).Returns(mockPromotions[0]);
            mockRepository.Setup((x) => x.GetPromotionType(It.IsAny <Guid>())).Returns((PromotionType)null);

            // Act
            var result = _promotionsController.CalculateOrderWithPromotion(null);

            // Assert
            Assert.AreEqual(0, result);
        }
        public void CalculateOrderWithPromotion_WhenPromotionNotFound_ShouldReturnZero()
        {
            // Arrange
            var mockRequest = new CalculatePromotionRequest()
            {
                PromotionId = "1AA7E44F-6C5D-46CB-84D0-87720CDB58E3",
                Skus        = new List <SkuRequest>()
                {
                    new SkuRequest()
                    {
                        Name        = "A",
                        Rate        = 50,
                        SkuQuantity = 1
                    }
                }
            };

            mockRepository.Setup((x) => x.GetPromotion(It.IsAny <Guid>())).Returns((Promotion)null);
            mockRepository.Setup((x) => x.GetPromotionType(It.IsAny <Guid>())).Returns(mockPromotionTypes[1]);

            // Act
            var result = _promotionsController.CalculateOrderWithPromotion(mockRequest);

            // Assert
            Assert.AreEqual(0, result);
        }
        public double CalculateOrderWithPromotion([FromBody] CalculatePromotionRequest promotionRequest)
        {
            if (promotionRequest == null || promotionRequest.PromotionId == null)
            {
                return(0);
            }

            return(PromotionEngine(promotionRequest));
        }
        private double PromotionEngine(CalculatePromotionRequest promotionRequest)
        {
            var promotion = _promotionsRepository.GetPromotion(Guid.Parse(promotionRequest.PromotionId));

            if (promotion == null)
            {
                return(0);
            }

            var promoType = _promotionsRepository.GetPromotionType(promotion.PrmotionTypeId);

            if (promoType == null)
            {
                return(0);
            }

            switch (promoType.Name)
            {
            case "FixedPricePerNSKUItmes":
                double totalCalculatedPromoAmount = 0;

                promotionRequest.Skus.ForEach((checkoutSku) =>
                {
                    bool isIncludedInPromo = promotion.SKUs.Contains(checkoutSku.Name);
                    if (isIncludedInPromo && checkoutSku.SkuQuantity >= promotion.NumberOfSKUItems)
                    {
                        double remainingQuantityCal     = (checkoutSku.SkuQuantity % promotion.NumberOfSKUItems) * checkoutSku.Rate;
                        double fixedQuantityCalculation = checkoutSku.SkuQuantity / promotion.NumberOfSKUItems * promotion.FixedPrice;
                        totalCalculatedPromoAmount     += fixedQuantityCalculation + remainingQuantityCal;
                    }
                    else
                    {
                        totalCalculatedPromoAmount += checkoutSku.SkuQuantity * checkoutSku.Rate;
                    }
                });

                return(totalCalculatedPromoAmount);

            case "FixedPriceForMoreThanOneSKUs":
                double totalCalculatedPromoAmountCase2 = 0;
                var    matchedList = new List <SkuRequest>();
                promotionRequest.Skus.ForEach((checkoutSku) =>
                {
                    bool isIncludedInPromo = promotion.SKUs.Contains(checkoutSku.Name);
                    if (isIncludedInPromo)
                    {
                        matchedList.Add(checkoutSku);
                    }
                    else
                    {
                        totalCalculatedPromoAmountCase2 += checkoutSku.SkuQuantity * checkoutSku.Rate;
                    }
                });
                if (matchedList.Count == promotion.SKUs.Count)
                {
                    totalCalculatedPromoAmountCase2 += promotion.FixedPrice;
                }
                else
                {
                    matchedList.ForEach((sku) =>
                    {
                        totalCalculatedPromoAmountCase2 += sku.SkuQuantity * sku.Rate;
                    });
                }
                return(totalCalculatedPromoAmountCase2);
            }
            ;
            return(0);
        }
        public async Task <IActionResult> CalculatePromotion([FromBody] CalculatePromotionRequest request)
        {
            var AllPromotion = await _PromotionService.GetAllAsync();

            var AllSkus = await _skuService.GetAllAsync();

            var LowestNoOfUnit = -999;
            var IgnoreSku      = new List <string>();

            CalculatePromotionResponse response = new CalculatePromotionResponse();

            response.CartItem = new List <webapi.Contracts.Responses.CartItem>();

            foreach (var cartItem in request.CartItem)
            {
                var matchedPromotion = AllPromotion.Where(x => x.SkuIds.Contains(cartItem.SkuId));

                var matchedSku = AllSkus.FirstOrDefault(x => x.SkuId == cartItem.SkuId);

                if (matchedPromotion == null)
                {
                    response.Total += (matchedSku == null) ? 0 : matchedSku.Price;
                    response.CartItem.Add(new webapi.Contracts.Responses.CartItem
                    {
                        SkuId        = cartItem.SkuId,
                        NumberOfUnit = cartItem.NumberOfUnit
                    });
                }
                else
                {
                    var firstMatchedPromotion = matchedPromotion.FirstOrDefault();
                    var skuIds = firstMatchedPromotion.SkuIds.Split(',').ToList();

                    if (skuIds.Count == 1)
                    {
                        var promotionAppliedGroupTotal    = (cartItem.NumberOfUnit / firstMatchedPromotion.NumberOfUnit) * firstMatchedPromotion.ForPrice;
                        var promotionNonAppliedGroupTotal = (cartItem.NumberOfUnit % firstMatchedPromotion.NumberOfUnit) * matchedSku.Price;

                        response.Total += (promotionAppliedGroupTotal + promotionNonAppliedGroupTotal);
                        response.CartItem.Add(new webapi.Contracts.Responses.CartItem
                        {
                            SkuId        = cartItem.SkuId,
                            NumberOfUnit = cartItem.NumberOfUnit
                        });
                    }
                    else
                    {
                        var allSkuIdsInCart = true;
                        foreach (var skuid in skuIds)
                        {
                            var found = request.CartItem.FirstOrDefault(x => x.SkuId == skuid);

                            if (found == null)
                            {
                                allSkuIdsInCart = false;
                                break;
                            }

                            if (LowestNoOfUnit == -999)
                            {
                                LowestNoOfUnit = found.NumberOfUnit;
                            }
                            else if (found.NumberOfUnit < LowestNoOfUnit)
                            {
                                LowestNoOfUnit = found.NumberOfUnit;
                            }
                        }
                        if (!allSkuIdsInCart)
                        {
                            response.Total += (cartItem.NumberOfUnit * matchedSku.Price);
                            response.CartItem.Add(new webapi.Contracts.Responses.CartItem
                            {
                                SkuId        = cartItem.SkuId,
                                NumberOfUnit = cartItem.NumberOfUnit
                            });
                        }
                        else
                        {
                            if (!IgnoreSku.Contains(cartItem.SkuId))
                            {
                                response.Total += (cartItem.NumberOfUnit * firstMatchedPromotion.ForPrice);
                            }
                            response.CartItem.Add(new webapi.Contracts.Responses.CartItem
                            {
                                SkuId        = cartItem.SkuId,
                                NumberOfUnit = cartItem.NumberOfUnit
                            });

                            skuIds.Remove(cartItem.SkuId);
                            IgnoreSku = skuIds;
                        }
                    }
                }
            }

            foreach (var promotion in AllPromotion)
            {
                var skuIds = promotion.SkuIds.Split(',');

                if (skuIds.Length == 1)
                {
                }
            }

            return(Ok(response));
        }