public void Execute_03_NoCartLines( IRuleValue <string> targetTag, Cart cart, CartTotals cartTotals, CommerceContext commerceContext, CartItemTargetTagFreeGiftAction action, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.Clear(); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.TargetTag = targetTag; context.Fact(Arg.Any <IFactIdentifier>()).Returns(commerceContext); /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty(); cart.Adjustments.Should().BeEmpty(); }
public void Execute_02_NoCart( IRuleValue <string> targetTag, CartTotals cartTotals, CommerceContext commerceContext, CartItemTargetTagFreeGiftAction action, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ commerceContext.AddObject(cartTotals); action.TargetTag = targetTag; context.Fact(Arg.Any <IFactIdentifier>()).Returns(commerceContext); /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); }
public void Execute_13_NoMaximumApplications( CartAnyItemQuantityXForQuantityYAction action, IRuleValue <int> quantityX, IRuleValue <int> quantityY, //IRuleValue<int> maximumApplications, Cart cart, CartTotals cartTotals, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.QuantityX = quantityX; action.QuantityY = quantityY; action.MaximumApplications = null; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().Throw <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty(); cart.Adjustments.Should().BeEmpty(); }
public void Execute_08_NoAmount( BaseCartItemSubtotalAmountOffAction action, IBinaryOperator <decimal, decimal> subtotalOperator, IRuleValue <decimal> subtotal, Cart cart, CartTotals cartTotals, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.MatchingLines(context).ReturnsForAnyArgs(cart.Lines); action.SubtotalOperator = subtotalOperator; action.Subtotal = subtotal; action.AmountOff = null; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty(); cart.Adjustments.Should().BeEmpty(); }
public void Execute_02_NoCart( BaseCartItemSubtotalAmountOffAction action, IBinaryOperator <decimal, decimal> subtotalOperator, IRuleValue <decimal> subtotal, IRuleValue <decimal> amountOff, CartTotals cartTotals, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); action.SubtotalOperator = subtotalOperator; action.Subtotal = subtotal; action.AmountOff = amountOff; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); }
public void Execute_02_NoCart( CartItemQuantityRangePercentOffAction action, IRuleValue <string> targetItemId, IRuleValue <decimal> minQuantity, IRuleValue <decimal> maxQuantity, IRuleValue <decimal> percentOff, CartTotals cartTotals, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); action.TargetItemId = targetItemId; action.MinQuantity = minQuantity; action.MaxQuantity = maxQuantity; action.PercentOff = percentOff; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); }
public void Execute_ShouldRoundPriceCalc_True( BaseCartItemSubtotalAmountOffAction action, IRuleValue <decimal> subtotal, IRuleValue <decimal> amountOff, Cart cart, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>(); globalPricingPolicy.ShouldRoundPriceCalc = true; globalPricingPolicy.RoundDigits = 3; globalPricingPolicy.MidPointRoundUp = true; cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100); var cartline = cart.Lines[1]; cartline.Totals.SubTotal.Amount = 175; var cartTotals = new CartTotals(cart); subtotal.Yield(context).ReturnsForAnyArgs(150); amountOff.Yield(context).ReturnsForAnyArgs(25.555555M); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.MatchingLines(context).ReturnsForAnyArgs(cart.Lines); action.SubtotalOperator = new DecimalGreaterThanEqualToOperator(); action.Subtotal = subtotal; action.AmountOff = amountOff; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1); cart.Adjustments.Should().BeEmpty(); cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(149.444M); cartline.Adjustments.Should().NotBeEmpty(); cartline.Adjustments.FirstOrDefault().Should().NotBeNull(); cartline.Adjustments.FirstOrDefault().Should().BeOfType <CartLineLevelAwardedAdjustment>(); cartline.Adjustments.FirstOrDefault()?.Name.Should().Be(commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount); cartline.Adjustments.FirstOrDefault()?.DisplayName.Should().Be(commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount); cartline.Adjustments.FirstOrDefault()?.AdjustmentType.Should().Be(commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount); cartline.Adjustments.FirstOrDefault()?.AwardingBlock.Should().Contain(nameof(BaseCartItemSubtotalAmountOffAction)); cartline.Adjustments.FirstOrDefault()?.IsTaxable.Should().BeFalse(); cartline.Adjustments.FirstOrDefault()?.Adjustment.CurrencyCode.Should().Be(commerceContext.CurrentCurrency()); cartline.Adjustments.FirstOrDefault()?.Adjustment.Amount.Should().Be(-25.556M); cartline.HasComponent <MessagesComponent>().Should().BeTrue(); }
public void Execute_PercentOff( CartItemQuantityRangePercentOffAction action, IRuleValue <string> targetItemId, IRuleValue <decimal> minQuantity, IRuleValue <decimal> maxQuantity, IRuleValue <decimal> percentOff, Cart cart, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>(); globalPricingPolicy.ShouldRoundPriceCalc = true; cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100); targetItemId.Yield(context).Returns("Habitat_Master|12345|"); var index = 12345; cart.Lines.ForEach(line => { line.ItemId = $"Habitat_Master|{index++}|"; line.Quantity = 2; line.Totals.SubTotal.Amount = 150; line.SetPolicy(new PurchaseOptionMoneyPolicy()); }); var cartTotals = new CartTotals(cart); minQuantity.Yield(context).ReturnsForAnyArgs(2); maxQuantity.Yield(context).ReturnsForAnyArgs(3); percentOff.Yield(context).ReturnsForAnyArgs(10); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.TargetItemId = targetItemId; action.MinQuantity = minQuantity; action.MaxQuantity = maxQuantity; action.PercentOff = percentOff; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1); cart.Adjustments.Should().BeEmpty(); cartTotals.Lines[cart.Lines[0].Id].SubTotal.Amount.Should().Be(135); }
public void Execute_TimesQualified_Two_MaximumApplications_One( CartAnyItemQuantityXForQuantityYAction action, IRuleValue <int> quantityX, IRuleValue <int> quantityY, IRuleValue <int> maximumApplications, Cart cart, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>(); globalPricingPolicy.ShouldRoundPriceCalc = false; cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100); while (cart.Lines.Count > 1) { cart.Lines.RemoveAt(0); } var cartline = cart.Lines[0]; cartline.Quantity = 8; cartline.Totals.SubTotal.Amount = 200; cartline.SetPolicy(new PurchaseOptionMoneyPolicy { SellPrice = new Money(25) }); var cartTotals = new CartTotals(cart); quantityX.Yield(context).ReturnsForAnyArgs(4); quantityY.Yield(context).ReturnsForAnyArgs(3); maximumApplications.Yield(context).ReturnsForAnyArgs(1); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.QuantityX = quantityX; action.QuantityY = quantityY; action.MaximumApplications = maximumApplications; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1); cart.Adjustments.Should().BeEmpty(); cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(175); }
public void Execute_12_NoPurchaseOptionMoneyPolicy( CartItemQuantityXForQuantityYAction action, IRuleValue <string> targetItemId, IRuleValue <int> quantityX, IRuleValue <int> quantityY, IRuleValue <int> maximumApplications, Cart cart, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>(); globalPricingPolicy.ShouldRoundPriceCalc = false; cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100); while (cart.Lines.Count > 1) { cart.Lines.RemoveAt(0); } var cartline = cart.Lines[0]; cartline.Quantity = 4; cartline.Totals.SubTotal.Amount = 100; cartline.ItemId = "Habitat_Master|12345|"; var cartTotals = new CartTotals(cart); targetItemId.Yield(context).ReturnsForAnyArgs("Habitat_Master|12345|"); quantityX.Yield(context).ReturnsForAnyArgs(4); quantityY.Yield(context).ReturnsForAnyArgs(3); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.TargetItemId = targetItemId; action.QuantityX = quantityX; action.QuantityY = quantityY; action.MaximumApplications = maximumApplications; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(0); cart.Adjustments.Should().BeEmpty(); }
public async void Execute_NoMatchingLinesAutoAddToCartEnabled_ShouldAddToCartAndApplyCartLineAdjustment( string targetItemId, bool autoAddToCart, bool autoRemove, Cart cart, CartTotals cartTotals, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ ApplyFreeGiftDiscountCommand discountCommand; ApplyFreeGiftEligibilityCommand eligibilityCommand; ApplyFreeGiftAutoRemoveCommand autoRemoveCommand; AddCartLineCommand addCartLineCommand; CartItemTargetIdFreeGiftAction action = BuildAction(out discountCommand, out eligibilityCommand, out autoRemoveCommand, out addCartLineCommand); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); action.TargetItemId = Substitute.For <IRuleValue <string> >(); action.TargetItemId.Yield(context).ReturnsForAnyArgs(targetItemId); action.AutoAddToCart = Substitute.For <IRuleValue <bool> >(); action.AutoAddToCart.Yield(context).ReturnsForAnyArgs(autoAddToCart); action.AutoRemove = Substitute.For <IRuleValue <bool> >(); action.AutoRemove.Yield(context).ReturnsForAnyArgs(autoRemove); context.Fact(Arg.Any <IFactIdentifier>()).Returns(commerceContext); addCartLineCommand .WhenForAnyArgs(x => x.Process(Arg.Any <CommerceContext>(), cart, Arg.Any <CartLineComponent>())) .Do(x => cart.Lines[0].ItemId = targetItemId); /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); await addCartLineCommand.Received().Process(Arg.Any <CommerceContext>(), cart, Arg.Any <CartLineComponent>()); eligibilityCommand.Received().Process(Arg.Any <CommerceContext>(), cart, Arg.Any <string>()); discountCommand.Received().Process(Arg.Any <CommerceContext>(), Arg.Any <CartLineComponent>(), Arg.Any <string>()); autoRemoveCommand.Received().Process(Arg.Any <CommerceContext>(), Arg.Any <CartLineComponent>(), autoRemove); }
public void ApplyPromo(CartTotals cartTotals) { var matchedBookItems = cartTotals.OrderedBooks.Where(b => b.Author == _freeBook.Author && b.Title == _freeBook.Title).ToList(); if (matchedBookItems.Any()) { cartTotals.BooksTotalCost -= matchedBookItems.Sum(b => b.Price); } }
public void Execute_DecimalGreaterThanEqualToOperator_True( BaseCartItemSubtotalAmountOffAction action, IRuleValue <decimal> subtotal, IRuleValue <decimal> amountOff, Cart cart, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>(); globalPricingPolicy.ShouldRoundPriceCalc = false; cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100); var cartline = cart.Lines[1]; cartline.Totals.SubTotal.Amount = 175; var cartTotals = new CartTotals(cart); subtotal.Yield(context).ReturnsForAnyArgs(150); amountOff.Yield(context).ReturnsForAnyArgs(25); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.MatchingLines(context).ReturnsForAnyArgs(cart.Lines); action.SubtotalOperator = new DecimalGreaterThanEqualToOperator(); action.Subtotal = subtotal; action.AmountOff = amountOff; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1); cart.Adjustments.Should().BeEmpty(); cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(150); }
public void Execute_HasMatchingLines_ShouldApplyCartLineAdjustment( string targetTag, bool autoRemove, Cart cart, CartProductComponent cartProductComponent, CartTotals cartTotals, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ ApplyFreeGiftDiscountCommand discountCommand; ApplyFreeGiftEligibilityCommand eligibilityCommand; ApplyFreeGiftAutoRemoveCommand autoRemoveCommand; CartItemTargetTagFreeGiftAction action = BuildAction(out discountCommand, out eligibilityCommand, out autoRemoveCommand); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); cartProductComponent.Tags.Add(new Tag(targetTag)); cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); cart.Lines[0].SetComponent(cartProductComponent); action.TargetTag = Substitute.For <IRuleValue <string> >(); action.TargetTag.Yield(context).ReturnsForAnyArgs(targetTag); action.AutoRemove = Substitute.For <IRuleValue <bool> >(); action.AutoRemove.Yield(context).ReturnsForAnyArgs(autoRemove); context.Fact(Arg.Any <IFactIdentifier>()).Returns(commerceContext); /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); eligibilityCommand.Received().Process(Arg.Any <CommerceContext>(), cart, Arg.Any <string>()); discountCommand.Received().Process(Arg.Any <CommerceContext>(), Arg.Any <CartLineComponent>(), Arg.Any <string>()); }
public void Execute_11_EqualQuantityXAndQuantityY( CartItemQuantityXForQuantityYAction action, IRuleValue <string> targetItemId, IRuleValue <int> quantityX, IRuleValue <int> quantityY, IRuleValue <int> maximumApplications, Cart cart, CartTotals cartTotals, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); quantityX.Yield(context).ReturnsForAnyArgs(4); quantityY.Yield(context).ReturnsForAnyArgs(4); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.TargetItemId = targetItemId; action.QuantityX = quantityX; action.QuantityY = quantityY; action.MaximumApplications = maximumApplications; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty(); cart.Adjustments.Should().BeEmpty(); }
public void Execute_12_MinQuantityGreaterThanMaxQuantity( CartItemQuantityRangePercentOffAction action, IRuleValue <string> targetItemId, IRuleValue <decimal> minQuantity, IRuleValue <decimal> maxQuantity, IRuleValue <decimal> percentOff, Cart cart, CartTotals cartTotals, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); minQuantity.Yield(context).ReturnsForAnyArgs(2); maxQuantity.Yield(context).ReturnsForAnyArgs(1); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.TargetItemId = targetItemId; action.MinQuantity = minQuantity; action.MaxQuantity = maxQuantity; action.PercentOff = percentOff; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty(); cart.Adjustments.Should().BeEmpty(); }
public void Execute_02_NoCart( CartItemQuantityXSellPriceAction action, IRuleValue <string> targetItemId, IRuleValue <int> quantityX, IRuleValue <decimal> sellPrice, IRuleValue <int> maximumApplications, //Cart cart, CartTotals cartTotals, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ //cart.Adjustments.Clear(); //cart.Lines.ForEach(l => l.Adjustments.Clear()); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); //commerceContext.AddObject(cart); //action.MatchingLines(context).ReturnsForAnyArgs(cart.Lines); action.TargetItemId = targetItemId; action.QuantityX = quantityX; action.SellPrice = sellPrice; action.MaximumApplications = maximumApplications; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); //cart.Lines.SelectMany(l => l.Adjustments).Should().BeEmpty(); //cart.Adjustments.Should().BeEmpty(); }
public CartTotals GetCartTotals(IEnumerable <Book> orderedBooks, IEnumerable <IPromo> shoppingCartPromos) { ResetVisitor(); foreach (var orderedBook in orderedBooks) { orderedBook.Accept(this); } var cartTotal = new CartTotals() { BooksTotalCost = GetTotalCost(), OrderedBooks = orderedBooks, DeliveryCost = GetDeliveryPrice(), }; var promos = _permanentPromos.Union(shoppingCartPromos); foreach (var promo in promos.OrderBy(x => x.Priority)) { promo.ApplyPromo(cartTotal); } return(cartTotal); }
public void ApplyPromo(CartTotals cartTotals) => cartTotals.BooksTotalCost -= _discount;
public void Execute_WithProperties( BaseCartItemSubtotalPercentOffAction action, IRuleValue <decimal> subtotal, IRuleValue <decimal> percentOff, Cart cart, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>(); globalPricingPolicy.ShouldRoundPriceCalc = false; cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100); var cartline = cart.Lines[1]; cartline.Totals.SubTotal.Amount = 150; var cartTotals = new CartTotals(cart); subtotal.Yield(context).ReturnsForAnyArgs(150); percentOff.Yield(context).ReturnsForAnyArgs(25.55M); var propertiesModel = new PropertiesModel(); propertiesModel.Properties.Add("PromotionId", "id"); propertiesModel.Properties.Add("PromotionCartText", "carttext"); propertiesModel.Properties.Add("PromotionText", "text"); commerceContext.AddObject(propertiesModel); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.MatchingLines(context).ReturnsForAnyArgs(cart.Lines); action.SubtotalOperator = new DecimalGreaterThanEqualToOperator(); action.Subtotal = subtotal; action.PercentOff = percentOff; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1); cart.Adjustments.Should().BeEmpty(); cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(111.6750M); cartline.Adjustments.Should().NotBeEmpty(); cartline.Adjustments.FirstOrDefault().Should().NotBeNull(); cartline.Adjustments.FirstOrDefault().Should().BeOfType <CartLineLevelAwardedAdjustment>(); cartline.Adjustments.FirstOrDefault()?.Name.Should().Be("text"); cartline.Adjustments.FirstOrDefault()?.DisplayName.Should().Be("carttext"); cartline.Adjustments.FirstOrDefault()?.AdjustmentType.Should().Be(commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount); cartline.Adjustments.FirstOrDefault()?.AwardingBlock.Should().Contain(nameof(BaseCartItemSubtotalPercentOffAction)); cartline.Adjustments.FirstOrDefault()?.IsTaxable.Should().BeFalse(); cartline.Adjustments.FirstOrDefault()?.Adjustment.CurrencyCode.Should().Be(commerceContext.CurrentCurrency()); cartline.Adjustments.FirstOrDefault()?.Adjustment.Amount.Should().Be(-38.325M); cartline.HasComponent <MessagesComponent>().Should().BeTrue(); }
public void ApplyPromo(CartTotals cartTotals) { cartTotals.DeliveryCost -= cartTotals.DeliveryCost; }
public void Execute_TimesQualified_One_UpperLimit( CartItemQuantityXSellPriceAction action, IRuleValue <string> targetItemId, IRuleValue <int> quantityX, IRuleValue <decimal> sellPrice, IRuleValue <int> maximumApplications, Cart cart, CommerceContext commerceContext, IRuleExecutionContext context) { /********************************************** * Arrange **********************************************/ cart.Adjustments.Clear(); cart.Lines.ForEach(l => l.Adjustments.Clear()); var globalPricingPolicy = commerceContext.GetPolicy <GlobalPricingPolicy>(); globalPricingPolicy.ShouldRoundPriceCalc = false; cart.Lines.ForEach(l => l.Totals.SubTotal.Amount = 100); while (cart.Lines.Count > 1) { cart.Lines.RemoveAt(0); } var cartline = cart.Lines[0]; cartline.Quantity = 3; cartline.Totals.SubTotal.Amount = 225; cartline.ItemId = "Habitat_Master|12345|"; cartline.SetPolicy(new PurchaseOptionMoneyPolicy { SellPrice = new Money(75) }); var cartTotals = new CartTotals(cart); targetItemId.Yield(context).ReturnsForAnyArgs("Habitat_Master|12345|"); quantityX.Yield(context).ReturnsForAnyArgs(2); sellPrice.Yield(context).ReturnsForAnyArgs(40); maximumApplications.Yield(context).ReturnsForAnyArgs(0); context.Fact <CommerceContext>().ReturnsForAnyArgs(commerceContext); commerceContext.AddObject(cartTotals); commerceContext.AddObject(cart); action.TargetItemId = targetItemId; action.QuantityX = quantityX; action.SellPrice = sellPrice; action.MaximumApplications = maximumApplications; /********************************************** * Act **********************************************/ Action executeAction = () => action.Execute(context); /********************************************** * Assert **********************************************/ executeAction.Should().NotThrow <Exception>(); cart.Lines.SelectMany(l => l.Adjustments).Should().HaveCount(1); cart.Adjustments.Should().BeEmpty(); cartTotals.Lines[cartline.Id].SubTotal.Amount.Should().Be(115); }
public void Execute(IRuleExecutionContext context) { CommerceContext commerceContext = context.Fact <CommerceContext>((string)null); CommerceContext commerceContext1 = commerceContext; Cart cart = commerceContext1 != null?commerceContext1.GetObjects <Cart>().FirstOrDefault <Cart>() : (Cart)null; CommerceContext commerceContext2 = commerceContext; CartTotals totals = commerceContext2 != null?commerceContext2.GetObjects <CartTotals>().FirstOrDefault <CartTotals>() : (CartTotals)null; if (cart == null || !cart.Lines.Any <CartLineComponent>() || (totals == null || !totals.Lines.Any <KeyValuePair <string, Totals> >())) { return; } List <CartLineComponent> list = new List <CartLineComponent>(); //Get the valid cartline items that matches specific tag provided foreach (var cartLine in cart.Lines.Where(x => x.HasComponent <CartProductComponent>())) { var firstOrDefault = cartLine.GetComponent <CartProductComponent>().Tags.FirstOrDefault(t => t.Name == this.Tag.Yield(context)); if (!string.IsNullOrEmpty(firstOrDefault?.Name)) { list.Add(cartLine); } } if (!list.Any <CartLineComponent>()) { return; } list.ForEach((Action <CartLineComponent>)(line => { if (!totals.Lines.ContainsKey(line.Id)) { return; } PropertiesModel propertiesModel = commerceContext.GetObject <PropertiesModel>(); string discountPolicy = commerceContext.GetPolicy <KnownCartAdjustmentTypesPolicy>().Discount; //Extract the coupon code in-order to associate coupon code with adjustment (1 to 1 mapping) string couponCode = string.Empty; if (cart.HasComponent <CartCouponsComponent>()) { if (cart.GetComponent <CartCouponsComponent>().List != null && cart.GetComponent <CartCouponsComponent>().List.Any()) { couponCode = cart.GetComponent <CartCouponsComponent>().List.FirstOrDefault(c => c.Promotion.EntityTarget == (string)propertiesModel?.GetPropertyValue("PromotionId"))?.CouponId; } } //calculate discounts on specified custom pricing if (line.HasComponent <CustomPriceInfoComponent>()) { var customPriceInfo = line.GetComponent <CustomPriceInfoComponent>(); Decimal discount = 0; if (this.BasePrice.Yield(context)) { discount += (Decimal)((double)this.PercentOff.Yield(context) * 0.01) * (decimal.Parse(customPriceInfo.BasePrice.ToString())); } if (this.ActivationPrice.Yield(context)) { discount += (Decimal)((double)this.PercentOff.Yield(context) * 0.01) * (decimal.Parse(customPriceInfo.ActivationPrice.ToString())); } if (this.DeliveryPrice.Yield(context)) { discount += (Decimal)((double)this.PercentOff.Yield(context) * 0.01) * (decimal.Parse(customPriceInfo.DeliveryPrice.ToString())); } if (commerceContext.GetPolicy <GlobalPricingPolicy>().ShouldRoundPriceCalc) { discount = Decimal.Round(discount, commerceContext.GetPolicy <GlobalPricingPolicy>().RoundDigits, commerceContext.GetPolicy <GlobalPricingPolicy>().MidPointRoundUp ? MidpointRounding.AwayFromZero : MidpointRounding.ToEven); } Decimal amount = discount * Decimal.MinusOne; //Create an adjustment and associate coupon code with coupon description delimited by '|' [Workaround for known issue with Promotion Plugin] IList <AwardedAdjustment> adjustments = line.Adjustments; adjustments.Add((AwardedAdjustment) new CartLineLevelAwardedAdjustment() { Name = (propertiesModel?.GetPropertyValue("PromotionText") as string ?? discountPolicy), DisplayName = couponCode + "|" + (propertiesModel?.GetPropertyValue("PromotionCartText") as string ?? discountPolicy), Adjustment = new Money(commerceContext.CurrentCurrency(), amount), AdjustmentType = discountPolicy, IsTaxable = false, AwardingBlock = nameof(CustomPercentOffAction) }); totals.Lines[line.Id].SubTotal.Amount = totals.Lines[line.Id].SubTotal.Amount + amount; line.GetComponent <MessagesComponent>().AddMessage(commerceContext.GetPolicy <KnownMessageCodePolicy>().Promotions, string.Format("PromotionApplied: {0}", propertiesModel?.GetPropertyValue("PromotionId") ?? (object)nameof(CustomPercentOffAction))); } })); }
public void ApplyPromo(CartTotals cartTotals) => cartTotals.BooksTotalCost *= (100 - _discountPercent) / 100;
public CartViewModel(List <CartView> items, CartTotals totals) { Items = items; Totals = totals; }