public void ProcessBill_WhenPromotionRuleIsApplied_Then_CalculateTotalPrice_Scenario4() { // 3 B : final total cost : (30 + 30 + 30) - 15 = 75 //Arrange var carts = new List <Cart>() { new Cart(Constants.B, 3) }; var promotionRule = new PromotionRule { RuleName = "Rule_B", SKUId = Constants.B, NumberOfApperance = 2, LumsumAmountToReduceFromPrice = 15, PercentageToReduceFromPrice = 0 }; var item = new Item() { SKUId = Constants.B, Name = "B Name", Price = 30 }; _PromotionRuleServicesMock.Setup(x => x.GetPromotionRulesBySKUId(Constants.B)).Returns(promotionRule); _ItemServicesMock.Setup(x => x.GetItemBySkuId(Constants.B)).Returns(item); //Act var totalPrice = OrderServices.ProcessBill(carts); //Assert Assert.AreEqual(totalPrice, 75); }
public void ProcessBill_WhenPromotionRuleIsApplied_Then_CalculateTotalPrice_Scenario2() { // 4 A : final total cost : (150 - 30) + 50 = 180 //Arrange var carts = new List <Cart>() { new Cart(Constants.A, 4) }; var promotionRule = new PromotionRule { RuleName = "Rule_A", SKUId = Constants.A, NumberOfApperance = 3, LumsumAmountToReduceFromPrice = 20, PercentageToReduceFromPrice = 0 }; var item = new Item() { SKUId = Constants.A, Name = "A Name", Price = 50 }; _PromotionRuleServicesMock.Setup(x => x.GetPromotionRulesBySKUId(Constants.A)).Returns(promotionRule); _ItemServicesMock.Setup(x => x.GetItemBySkuId(Constants.A)).Returns(item); //Act var totalPrice = OrderServices.ProcessBill(carts); //Assert Assert.AreEqual(totalPrice, 180); }
public void Init() { //Rules section _rules = new Dictionary <char, Tuple <int, double> >(); _comboRules = new List <Tuple <char, char, double> >(); //Adding first Rule for skuid -A _rules.Add('A', new Tuple <int, double>(3, 130)); //Adding first Rule for skuid -B _rules.Add('B', new Tuple <int, double>(2, 45)); _comboRules = new List <Tuple <char, char, double> >(); //Adding combo Rule _comboRules.Add(new Tuple <char, char, double>('C', 'D', 30)); _promotionRule = new PromotionRule(_rules, _comboRules); //Master Data section productWithPrice = new Dictionary <char, double>(); productWithPrice.Add('A', 50); productWithPrice.Add('B', 30); productWithPrice.Add('C', 20); productWithPrice.Add('D', 15); _SKUCart = new SKUCart(productWithPrice); _promotionEngine = new PromotionEngine_V1(); _orderCalculator = new OrderCalculator(_promotionEngine); }
private decimal PromotionCalculation(Product product, int count, PromotionRule promoRule) { int productTotal = 0; if (promoRule.Value > 0) { decimal validPromoItems = Convert.ToDecimal(count) / promoRule.PromoItems; if ((validPromoItems % 1) == 0) { productTotal += (int)validPromoItems * promoRule.Value; } else { int eligiblePromoApplies = (int)Math.Truncate(validPromoItems); var promoAppliedProducts = eligiblePromoApplies * promoRule.PromoItems; var remainingProdcts = count - promoAppliedProducts; productTotal = (eligiblePromoApplies * promoRule.Value) + (remainingProdcts * (int)product.Price); } } else { productTotal = count * (int)product.Price; } return(productTotal); }
// *** INITIALIZATION *** // #region SetGameVariables public override void SetGameVariables() { base.SetGameVariables(); Castling = new ChoiceVariable(); Castling.AddChoice("Standard", "King starting on e or f file slides three squares either direction, " + "subject to the usual restrictions, to castle with the piece in the corner"); Castling.AddChoice("Long", "King starting on e or f file slides three squares when castling short " + "or four when castling long, subject to the usual restrictions, to castle with the piece in the corner"); Castling.AddChoice("Flexible", "King starting on e or f file slides two or more squares, subject to the usual " + "restrictions, to castle with the piece in the corner"); Castling.AddChoice("Close-Rook", "King starting on e or f file slides two squares either direction, " + "subject to the usual restrictions, to castle with the piece on the b or i file"); Castling.AddChoice("Close-Rook Flexible", "King starting on e or f file slides two or more squares, " + "subject to the usual restrictions, to castle with the piece on the b or i file"); Castling.AddChoice("2R Standard", "King starting on e or f file on the second rank slides three squares either direction, " + "subject to the usual restrictions, to castle with the piece on the edge"); Castling.AddChoice("2R Long", "King starting on e or f file on the second rank slides three squares when castling short " + "or four when castling long, subject to the usual restrictions, to castle with the piece on the edge"); Castling.AddChoice("2R Flexible", "King starting on e or f file on the second rank slides two or more squares, subject to the usual " + "restrictions, to castle with the piece on the edge"); Castling.AddChoice("2R Close-Rook", "King starting on e or f file on the second rank slides two squares either direction, " + "subject to the usual restrictions, to castle with the piece on the b or i file on the second rank"); Castling.AddChoice("2R Close-Rook Flexible", "King starting on e or f file on the second rank slides two or more squares, " + "subject to the usual restrictions, to castle with the piece on the b or i file"); Castling.AddChoice("None", "No castling"); Castling.Value = "None"; PromotionRule.AddChoice("Grand"); }
public void ProcessBill_WhenNoPromotionRule_Then_CalculateTotalPrice() { //Arrange var carts = new List <Cart>() { new Cart(Constants.A, 2) }; var promotionRule = new PromotionRule { RuleName = "Rule_A", SKUId = Constants.A, NumberOfApperance = 3, LumsumAmountToReduceFromPrice = 20, PercentageToReduceFromPrice = 0 }; var item = new Item() { SKUId = Constants.A, Name = "A Name", Price = 50 }; _PromotionRuleServicesMock.Setup(x => x.GetPromotionRulesBySKUId(Constants.A)).Returns <PromotionRule>(null); _ItemServicesMock.Setup(x => x.GetItemBySkuId(Constants.A)).Returns(item); //Act var totalPrice = OrderServices.ProcessBill(carts); //Assert Assert.AreEqual(totalPrice, 100); }
public void ProcessBill_WhenPromotionRuleIsApplied_Then_CalculateTotalPrice_Scenario_For_A(List <Cart> carts, int res) { var promotionRule = new PromotionRule { RuleName = "Rule_A", SkuId = Constants.A, NumberOfAppearance = 3, LumpSumAmountToReduceFromPrice = 20, PercentageToReduceFromPrice = 0 }; var item = new Item() { SkuId = Constants.A, Name = "A Name", Price = 50 }; _promotionRuleServicesMock.Setup(x => x.GetPromotionRulesBySkuId(Constants.A)).Returns(promotionRule); _itemServicesMock.Setup(x => x.GetItemBySkuId(Constants.A)).Returns(item); //Act var totalPrice = _orderServices.ProcessBill(carts); //Assert Assert.AreEqual(totalPrice, res); }
public void ProcessBill_WhenPromotionRuleIsApplied_Then_CalculateTotalPrice_PDFScenarioA() { // A B C = 100 //Arrange var carts = new List <Cart>() { new Cart(Constants.A, 1), new Cart(Constants.B, 1), new Cart(Constants.C, 1) }; var promotionRule = new PromotionRule { RuleName = "Rule_C", SKUId = Constants.C, NumberOfApperance = 1, LumsumAmountToReduceFromPrice = 5, PercentageToReduceFromPrice = 0, ListOfAnotherItemsToBeConsidered = new List <char>() { Constants.D } }; var itemA = new Item() { SKUId = Constants.A, Name = "A Name", Price = 50 }; var itemB = new Item() { SKUId = Constants.B, Name = "B Name", Price = 30 }; var itemC = new Item() { SKUId = Constants.C, Name = "C Name", Price = 20 }; var itemD = new Item() { SKUId = Constants.D, Name = "D Name", Price = 15 }; _PromotionRuleServicesMock.Setup(x => x.GetPromotionRulesBySKUId(Constants.C)).Returns(promotionRule); _ItemServicesMock.Setup(x => x.GetItemBySkuId(Constants.A)).Returns(itemA); _ItemServicesMock.Setup(x => x.GetItemBySkuId(Constants.B)).Returns(itemB); _ItemServicesMock.Setup(x => x.GetItemBySkuId(Constants.C)).Returns(itemC); _ItemServicesMock.Setup(x => x.GetItemBySkuId(Constants.D)).Returns(itemD); //Act var totalPrice = OrderServices.ProcessBill(carts); //Assert Assert.AreEqual(totalPrice, 100); }
public static PromotionRule CreatePromotionRule(TestContext ctx, int promotionId, int ruleId) { PromotionRule promotionRule = new PromotionRule(); promotionRule.PromotionId = promotionId; promotionRule.Promotion = ctx.Promotions.Where(x => x.PromotionId == promotionId).FirstOrDefault(); promotionRule.RuleId = ruleId; promotionRule.Rule = ctx.Rules.Where(x => x.RuleId == ruleId).FirstOrDefault(); ctx.PromotionRules.Add(promotionRule); return(promotionRule); }
// *** INITIALIZATION *** // #region SetGameVariables public override void SetGameVariables() { base.SetGameVariables(); Array = "12/12/2rnbqkbnr2/2pppppppp2/12/12/12/12/2PPPPPPPP2/2RNBQKBNR2/12/12"; Castling.AddChoice("ChessOnA12x12Board", "Kings on g3 and g10 slide two squares in either direction to castle with the pieces on the c and j files"); Castling.Value = "ChessOnA12x12Board"; PromotionRule.AddChoice("ChessOnA12x12Board", "Standard promotion except that promote on the 10th rank"); PromotionRule.Value = "Custom"; PromotionTypes = "QRBN"; PawnMultipleMove.Value = "@4(2)"; EnPassant = true; }
public override void SetGameVariables() { base.SetGameVariables(); Array = "w10w/1crnbqkbnrc1/1pppppppppp1/12/12/12/12/12/12/1PPPPPPPPPP1/1CRNBQKBNRC1/W10W"; PromotionRule.AddChoice("Omega", "Standard promotion except that pawns promote on the 11th rank"); PromotionRule.Value = "Omega"; PromotionTypes = "QRBNCW"; Castling.AddChoice("Omega", "Omega Chess requires custom castling handling because the notations of the board squares is non-standard"); Castling.Value = "Omega"; PawnMultipleMove.Value = "@3(2,3)"; EnPassant = true; }
private int ApplyPromotionRule(List <Cart> carts, Cart cart, PromotionRule promoRule) { var item = _itemServices.GetItemBySkuId(cart.SkuId); if (promoRule == null) { return(cart.TotalCount * item.Price); } if (promoRule.LumpSumAmountToReduceFromPrice > 0) { return(CalculatePrice(carts, cart, promoRule)); } return(0); }
private double PromotionProcessor(List <char> skus) { double totalCartValue = 0; var distinctProducts = skus.Distinct().ToList(); if (distinctProducts.Contains('C') & distinctProducts.Contains('D')) { decimal combinedProductTotal = 0; Product productCInfo = _productProvider.GetProduct('C'); Product productDInfo = _productProvider.GetProduct('D'); var countProductC = skus.Count(x => x == 'C'); var countProductD = skus.Count(x => x == 'D'); if (countProductC == countProductD) { combinedProductTotal = (countProductC + countProductD) / 2 * 30; } else if (countProductC > countProductD) { var productCDifference = countProductC - countProductD; var comboPrice = ((countProductC + countProductD) - productCDifference) * 30; combinedProductTotal = comboPrice + (productCDifference * (int)productCInfo.Price); } else if (countProductD > countProductC) { var productDDifference = countProductD - countProductC; var comboPrice = ((countProductC + countProductD) - productDDifference) * 30; combinedProductTotal = comboPrice + (productDDifference * (int)productDInfo.Price); } distinctProducts.Remove('C'); distinctProducts.Remove('D'); totalCartValue = Convert.ToDouble(combinedProductTotal); } foreach (char prod in distinctProducts) { Product product = _productProvider.GetProduct(prod); PromotionRule promoRule = _productProvider.GetPromotion(prod); totalCartValue += Convert.ToDouble(PromotionCalculation(product, skus.Count(x => x == prod), promoRule)); } return(totalCartValue); }
private int ApplyPromotionRule(List <Cart> carts, Cart cart, PromotionRule promoRule) { var item = itemServices.GetItemBySkuId(cart.SKUId); if (promoRule == null) { return(cart.CountOfRemainingItemsForPromo * item.Price); // "CountOfRemainingItemsForPromo" test case Scenario6 } if (promoRule.LumsumAmountToReduceFromPrice > 0) { return(CalculatePrice(carts, cart, promoRule)); } if (promoRule.PercentageToReduceFromPrice > 0) { // we can add future requirement here Ex : discount based on percentage } throw new Exception("invalid input..."); }
private int CalculatePrice(List <Cart> carts, Cart cart, PromotionRule promoRule) { var price = 0; var item = _itemServices.GetItemBySkuId(cart.SkuId); // process until item count are applicable for promo rules while (promoRule.NumberOfAppearance <= cart.CountOfRemainingItemsForPromo && cart.CountOfRemainingItemsForPromo != 0) { var isOtherItemExistInCart = true; foreach (var otherItem in promoRule.ListOfAnotherItemsToBeConsidered) { var anotherItem = _itemServices.GetItemBySkuId(otherItem); isOtherItemExistInCart = carts.Any(x => x.SkuId == anotherItem.SkuId); // for rule like : C + D = x amount if (isOtherItemExistInCart) // if other item is in cart { price += anotherItem.Price; // add other item price in total price var cartItem = carts.First(x => x.SkuId == anotherItem.SkuId); cartItem.CountOfRemainingItemsForPromo = cartItem.CountOfRemainingItemsForPromo - promoRule.NumberOfAppearance; } } if (isOtherItemExistInCart) // if yes : Apply promo rule { price += (GetProductPrice(item, promoRule.NumberOfAppearance) - promoRule.LumpSumAmountToReduceFromPrice); } else // not exist then normal calculation { price += GetProductPrice(item, cart.CountOfRemainingItemsForPromo); } // remove no of items processed (so will get count of items that can process with promo rule) cart.CountOfRemainingItemsForPromo = cart.CountOfRemainingItemsForPromo - promoRule.NumberOfAppearance; } // remaining item after promo rule, will process with normal calculation if (cart.CountOfRemainingItemsForPromo > 0) { price += GetProductPrice(item, cart.CountOfRemainingItemsForPromo); cart.CountOfRemainingItemsForPromo = 0; // all item are processed } return(price); }
public bool IsMatch(RenderContext context, PromotionRule rule, Cart cart, CartItem cartitem) { var carttotal = cart.ItemTotal; foreach (var item in rule.TargetValue) { var value = Kooboo.Lib.Reflection.TypeHelper.ChangeType(item, typeof(decimal)); if (value != null) { var decvalue = (decimal)value; if (decvalue > 0) { if (carttotal >= decvalue) { return(true); } } } } return(false); }
public bool IsMatch(RenderContext context, PromotionRule rule, Cart cart, CartItem item) { if (rule.TargetValue == null || !rule.TargetValue.Any()) { return(false); } var productcatservice = ServiceProvider.GetService <ProductCategoryService>(context); var allcat = productcatservice.FindCategoies(item.ProductId); foreach (var target in rule.TargetValue) { if (System.Guid.TryParse(target, out System.Guid value)) { if (allcat.Contains(value)) { return(true); } } } return(false); }
public void PromotionRuleChanged(PromotionRule entity, UpdateOperations operation) { CheckIsAdminOrSystem(); }
public void CalculateOrderPrice(OrderAPIViewModel order, DateTime time) { #region OrderDetail #region Service and variable IProductService productService = DependencyUtils.Resolve <IProductService>(); double orderDetailTotalAmount = 0; double orderDetailFinalAmount = 0; //double discountOrderDetail = 0; //biến giảm giá trên mỗi sản phẩm double discountEachProduct = 0; //biến giảm giá trên toàn hóa đơn double discount = 0; bool checkDeliveryFee = false; double finalAmount = 0; double totalAmount = 0; double deliveryFee = 0; //add order detail have product is a delivery fee //giảm giá trên từng sản phẩm, hóa đơn tùy theo rule ở hàm checkPromotionRUle int quantity = 0;//check quantity trong order gửi 1 đơn hàng và có quantity trong đó #endregion foreach (var item in order.OrderDetails) { if (item.ParentId == 0) { item.ParentId = null; } if (item.Quantity <= 0) { throw ApiException.Get(false, ConstantManager.MES_CREATE_ORDER_NEGATIVE_QUANTITY, ResultEnum.OrderDetailQuantity, HttpStatusCode.BadRequest); } var product = productService.GetProductById(item.ProductID); if (product == null) { throw ApiException.Get(false, ConstantManager.MES_CREATE_ORDER_NOT_FOUND_PRODUCT, ResultEnum.ProductNotFound, HttpStatusCode.NotFound); } item.ProductType = product.ProductType; item.TotalAmount = product.Price * item.Quantity; orderDetailTotalAmount += item.TotalAmount; item.UnitPrice = product.Price; //lấy giảm giá theo rule PromotionRule rule = new PromotionRule(); rule = PromotionRuleUtility.checkPromotionRule(order, quantity, item); //check rule 1, 2 dc định nghĩ ở ConstantManager if (rule.rule == ConstantManager.PROMOTION_RULE_2 || rule.countProduct) { item.Discount = rule.discountAmount; } else if (rule.rule == ConstantManager.PROMOTION_RULE_1) { discount = rule.discountAmount; } quantity = rule.quantity; item.FinalAmount = item.TotalAmount - item.Discount; orderDetailFinalAmount += item.FinalAmount; discountEachProduct += item.Discount; //discountOrderDetail += item.Discount; item.OrderDate = time; } foreach (var item in order.OrderDetails) { if (item.ProductType != (int)ProductTypeEnum.ServiceFee) { totalAmount = productService.GetProductById(item.ProductID).Price *item.Quantity; finalAmount += totalAmount - item.Discount; if (finalAmount >= ConstantManager.DELIVERY_FREE || order.OrderType != (int)OrderTypeEnum.MobileDelivery) { checkDeliveryFee = true; } } } if (!checkDeliveryFee) { var tmpOrderDetail = order.OrderDetails.ToList(); var productDelivery = productService.GetProductDeliveryFee(); OrderDetailAPIViewModel deliveryOrderDt = new OrderDetailAPIViewModel(); deliveryOrderDt.ProductID = productDelivery.ProductID; deliveryOrderDt.Quantity = 1; deliveryOrderDt.TotalAmount = productDelivery.Price; deliveryOrderDt.FinalAmount = productDelivery.Price; deliveryOrderDt.UnitPrice = productDelivery.Price; deliveryFee = productDelivery.Price; deliveryOrderDt.ProductOrderType = (int)Models.ProductOrderType.Single; deliveryOrderDt.OrderDate = time; deliveryOrderDt.ProductType = (int)ProductTypeEnum.ServiceFee; tmpOrderDetail.Add(deliveryOrderDt); order.OrderDetails = tmpOrderDetail; } #endregion #region Order order.CheckInDate = time; var vatAmount = 0; //VAT 10% #region edit promotion #endregion order.TotalAmount = orderDetailTotalAmount; order.Discount = discount; order.DiscountOrderDetail = discountEachProduct; order.FinalAmount = orderDetailTotalAmount + deliveryFee - vatAmount - discount - discountEachProduct;//l?y order detail sum l?i => ra du?c order thi?t c?a passio //order.DiscountOrderDetail = discountOrderDetail; //gán giản giá trên từng sản phẩm cho order #endregion }
public void Save(PromotionRule aggregate) { throw new NotImplementedException(); }
internal static DiscountItem CalculateCartItemRuleDiscount(RenderContext context, PromotionRule rule, CartItem item) { if (rule == null || (rule.Percent == 1 && rule.Amount == 0)) { return(null); } decimal offprice = 0; if (rule.Percent > 0 && rule.Percent < 1) { offprice = item.UnitPrice * rule.Percent; } if (rule.Amount > 0) { offprice = offprice + rule.Amount; } if (offprice <= 0) { return(null); } DiscountItem result = new DiscountItem(); var reasonobj = rule.GetValue(context.Culture); if (reasonobj != null) { result.Reason = reasonobj.ToString(); } result.Discount = offprice; result.RuleId = rule.Id; result.Quantity = item.Quantity; result.CanCombine = rule.CanCombine; return(result); }
internal static DiscountItem CalculateCartRuleDiscount(RenderContext context, PromotionRule rule, Cart cart) { if (rule == null || (rule.Percent == 1 && rule.Amount == 0)) { return(null); } DiscountItem result = new DiscountItem(); var reasonobj = rule.GetValue(context.Culture); if (reasonobj != null) { result.Reason = reasonobj.ToString(); } decimal offprice = 0; if (rule.Percent > 0 && rule.Percent <= 1) { offprice = cart.TotalAmount * rule.Percent; } if (rule.Amount > 0) { offprice = offprice + rule.Amount; } result.Discount = offprice; result.CanCombine = rule.CanCombine; return(result); }