Esempio n. 1
0
            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();
            }
Esempio n. 2
0
            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>();
            }
Esempio n. 3
0
            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();
            }
Esempio n. 4
0
            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();
            }
Esempio n. 5
0
            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>();
            }
Esempio n. 6
0
            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>();
            }
Esempio n. 7
0
            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();
            }
Esempio n. 8
0
            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);
            }
Esempio n. 9
0
            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();
            }
Esempio n. 11
0
            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);
            }
Esempio n. 12
0
        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);
            }
        }
Esempio n. 13
0
            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);
            }
Esempio n. 14
0
            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();
            }
Esempio n. 16
0
            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();
            }
Esempio n. 17
0
            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();
            }
Esempio n. 18
0
        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);
        }
Esempio n. 19
0
 public void ApplyPromo(CartTotals cartTotals) =>
 cartTotals.BooksTotalCost -= _discount;
Esempio n. 20
0
            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();
            }
Esempio n. 21
0
 public void ApplyPromo(CartTotals cartTotals)
 {
     cartTotals.DeliveryCost -= cartTotals.DeliveryCost;
 }
Esempio n. 22
0
            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)));
                }
            }));
        }
Esempio n. 24
0
 public void ApplyPromo(CartTotals cartTotals) =>
 cartTotals.BooksTotalCost *= (100 - _discountPercent) / 100;
Esempio n. 25
0
 public CartViewModel(List <CartView> items, CartTotals totals)
 {
     Items  = items;
     Totals = totals;
 }