示例#1
0
        public async Task EvaluatePromotionsAsync_HasCart_PromotionEvaluated()
        {
            // Arrange
            var cartAggregate = GetValidCartAggregate();

            cartAggregate.Cart.Items = new List <LineItem> {
                _fixture.Create <LineItem>()
            };

            var context = new PromotionEvaluationContext();

            var promoResult = new PromotionResult();
            var promoReward = new StubPromotionReward
            {
                Id      = _fixture.Create <string>(),
                IsValid = true
            };

            promoResult.Rewards.Add(promoReward);

            _mapperMock.Setup(x => x.Map <PromotionEvaluationContext>(It.Is <CartAggregate>(x => x == cartAggregate)))
            .Returns(context);

            _marketingPromoEvaluatorMock
            .Setup(x => x.EvaluatePromotionAsync(It.Is <PromotionEvaluationContext>(x => x == context)))
            .ReturnsAsync(promoResult);

            // Act
            var result = await cartAggregate.EvaluatePromotionsAsync();

            // Assert
            result.Rewards.Should().ContainSingle(x => x.Id == promoReward.Id);
        }
示例#2
0
        public async Task RecalculateAsync_HasPromoRewards_CalculateTotalsCalled()
        {
            // Arrange
            var cartAggregate = GetValidCartAggregate();

            cartAggregate.Cart.Items = new List <LineItem> {
                _fixture.Create <LineItem>()
            };

            var context = new PromotionEvaluationContext();

            var promoResult = new PromotionResult();
            var promoReward = new StubPromotionReward
            {
                Id      = _fixture.Create <string>(),
                IsValid = true
            };

            promoResult.Rewards.Add(promoReward);

            _mapperMock.Setup(x => x.Map <PromotionEvaluationContext>(It.Is <CartAggregate>(x => x == cartAggregate)))
            .Returns(context);

            _marketingPromoEvaluatorMock
            .Setup(x => x.EvaluatePromotionAsync(It.Is <PromotionEvaluationContext>(x => x == context)))
            .ReturnsAsync(promoResult);

            // Act
            var result = await cartAggregate.RecalculateAsync();

            // Assert
            _shoppingCartTotalsCalculatorMock.Verify(x => x.CalculateTotals(It.Is <ShoppingCart>(x => x == cartAggregate.Cart)), Times.Once);
        }
        public void EvaluateRewards_CombineByPriorityOrder()
        {
            //Arrange
            var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("FedEx Get 50% Off", "FedEx Get 30% Off", "ProductA and ProductB Get 2 With 50% Off", "Get ProductA With 25$ Off"));
            var productA   = new ProductPromoEntry {
                ProductId = "ProductA", Price = 100, Quantity = 1
            };
            var productB = new ProductPromoEntry {
                ProductId = "ProductB", Price = 100, Quantity = 3
            };
            var context = new PromotionEvaluationContext
            {
                ShipmentMethodCode  = "FedEx",
                ShipmentMethodPrice = 100,
                PromoEntries        = new [] { productA, productB }
            };
            //Act
            var rewards = evalPolicy.EvaluatePromotion(context).Rewards;

            //Assert
            Assert.Equal(rewards.Count(), 5);
            Assert.Equal(context.ShipmentMethodPrice, 35m);
            Assert.Equal(productA.Price, 37.5m);
            Assert.Equal(productB.Price, 50);
        }
        public static PromotionEvaluationContext ToPromotionEvaluationContext(this WorkContext workContext)
        {
            var retVal = new PromotionEvaluationContext
            {
                CartPromoEntries = workContext.CurrentCart.Items.Select(x => x.ToPromotionItem()).ToList(),
                CartTotal        = workContext.CurrentCart.Total,
                Coupon           = workContext.CurrentCart.Coupon != null ? workContext.CurrentCart.Coupon.Code : null,
                Currency         = workContext.CurrentCurrency,
                CustomerId       = workContext.CurrentCustomer.Id,
                IsRegisteredUser = workContext.CurrentCustomer.IsRegisteredUser,
                Language         = workContext.CurrentLanguage,
                StoreId          = workContext.CurrentStore.Id
            };

            //Set cart lineitems as default promo items
            retVal.PromoEntries = retVal.CartPromoEntries;
            if (workContext.CurrentProduct != null)
            {
                retVal.PromoEntry = workContext.CurrentProduct.ToPromotionItem();
            }
            if (workContext.CurrentCatalogSearchResult != null && workContext.CurrentCatalogSearchResult.Products != null)
            {
                retVal.PromoEntries = workContext.CurrentCatalogSearchResult.Products.Select(x => x.ToPromotionItem()).ToList();
            }
            return(retVal);
        }
        private static PromotionEvaluationContext GetPromotionEvaluationContext()
        {
            var context = new PromotionEvaluationContext();

            context.CartPromoEntries = context.PromoEntries = new[]
            {
                new ProductPromoEntry
                {
                    CatalogId  = "Samsung",
                    CategoryId = "100df6d5-8210-4b72-b00a-5003f9dcb79d",
                    ProductId  = "v-b000bkzs9w",
                    Price      = 160.44m,
                    Quantity   = 2,
                },
                new ProductPromoEntry
                {
                    CatalogId  = "Sony",
                    CategoryId = "100df6d5-8210-4b72-b00a-5003f9dcb79d",
                    ProductId  = "v-a00032ksj",
                    Price      = 12.00m,
                    Quantity   = 1,
                },
                new ProductPromoEntry
                {
                    CatalogId  = "LG",
                    CategoryId = "100df6d5-8210-4b72-b00a-5003f9dcb79d",
                    ProductId  = "v-c00021211",
                    Price      = 1.00m,
                    Quantity   = 1,
                }
            };
            return(context);
        }
示例#6
0
        public static int GetCartItemsOfProductQuantity(this PromotionEvaluationContext context, string productId)
        {
            var retVal = context.CartPromoEntries.InProducts(new[] { productId })
                         .Sum(x => x.Quantity);

            return(retVal);
        }
        public Task <IEnumerable <PromotionReward> > GetPromotionRewardsAsync(PromotionEvaluationContext context)
        {
            var rewards = SendAsync <PromotionEvaluationContext, IEnumerable <PromotionReward> >(
                CreateRequestUri(RelativePaths.GetPromotionRewards), HttpMethod.Post, context);

            return(rewards);
        }
示例#8
0
 public static bool IsAnyLineItemExtendedTotalNew(this PromotionEvaluationContext context, decimal lineItemTotal, decimal lineItemTotalSecond, string compareCondition, string[] excludingCategoryIds, string[] excludingProductIds)
 {
     if (compareCondition.EqualsInvariant(ModuleConstants.ConditionOperation.Exactly))
     {
         return(context.CartPromoEntries.Where(x => x.Price * x.Quantity == lineItemTotal)
                .ExcludeCategories(excludingCategoryIds)
                .ExcludeProducts(excludingProductIds)
                .Any());
     }
     else if (compareCondition.EqualsInvariant(ModuleConstants.ConditionOperation.AtLeast))
     {
         return(context.CartPromoEntries.Where(x => x.Price * x.Quantity >= lineItemTotal)
                .ExcludeCategories(excludingCategoryIds)
                .ExcludeProducts(excludingProductIds)
                .Any());
     }
     else if (compareCondition.EqualsInvariant(ModuleConstants.ConditionOperation.IsLessThanOrEqual))
     {
         return(context.CartPromoEntries.Where(x => x.Price * x.Quantity <= lineItemTotal)
                .ExcludeCategories(excludingCategoryIds)
                .ExcludeProducts(excludingProductIds)
                .Any());
     }
     else if (compareCondition.EqualsInvariant(ModuleConstants.ConditionOperation.Between))
     {
         return(context.CartPromoEntries.Where(x => x.Price * x.Quantity >= lineItemTotal && x.Quantity <= lineItemTotalSecond)
                .ExcludeCategories(excludingCategoryIds)
                .ExcludeProducts(excludingProductIds)
                .Any());
     }
     throw new Exception("CompareCondition has incorrect value.");
 }
        public virtual void EvaluateDiscounts(PromotionEvaluationContext context, IEnumerable <IDiscountable> owners)
        {
            var contextDto = context.ToPromotionEvaluationContextDto();
            var rewards    = _marketingApi.MarketingModulePromotion.EvaluatePromotions(contextDto);

            InnerEvaluateDiscounts(rewards, owners);
        }
示例#10
0
 public static bool IsItemInCategory(this PromotionEvaluationContext context, string categoryId, string[] excludingCategoryIds, string[] excludingProductIds)
 {
     return(new ProductPromoEntry[] { context.PromoEntry }.InCategories(new[] { categoryId })
            .ExcludeCategories(excludingCategoryIds)
            .ExcludeProducts(excludingProductIds)
            .Any());
 }
示例#11
0
        public void EvaluateRewards_CombineByPriorityOrder()
        {
            //Arrange
            var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("FedEx Get 50% Off", "FedEx Get 30% Off", "ProductA and ProductB Get 2 With 50% Off", "Get ProductA With 25$ Off"));
            var productA   = new ProductPromoEntry {
                ProductId = "ProductA", Price = 100, Quantity = 1
            };
            var productB = new ProductPromoEntry {
                ProductId = "ProductB", Price = 100, Quantity = 3
            };
            var context = new PromotionEvaluationContext
            {
                ShipmentMethodCode  = "FedEx",
                ShipmentMethodPrice = 100,
                PromoEntries        = new[] { productA, productB }
            };
            //Act
            var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards;

            //Assert
            Assert.Equal(5, rewards.Count);
            Assert.Equal(35m, context.ShipmentMethodPrice);
            Assert.Equal(37.5m, productA.Price);
            Assert.Equal(66.67m, Math.Round(productB.Price, 2));
        }
        public void EvaluatePromotion_GetBestPaymentReward()
        {
            //Agganre
            var blockReward = new BlockReward().WithChildrens(new RewardPaymentGetOfAbs()
            {
                Amount = 10m, PaymentMethod = "PayTest"
            });
            var dynamicPromotion = new DynamicPromotion
            {
                DynamicExpression = AbstractTypeFactory <PromotionConditionAndRewardTree> .TryCreateInstance()
            };

            dynamicPromotion.DynamicExpression.WithChildrens(blockReward);

            var evalPolicy = GetPromotionEvaluationPolicy(new[] { dynamicPromotion });
            var productA   = new ProductPromoEntry {
                ProductId = "ProductA", Price = 100, Quantity = 1
            };
            var context = new PromotionEvaluationContext
            {
                PaymentMethodCode  = "PayTest",
                PaymentMethodPrice = 5m,
                PromoEntries       = new[] { productA }
            };

            //Act
            var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards.OfType <PaymentReward>().ToList();

            //Assert
            Assert.Equal(10m, rewards.First().Amount);
            Assert.True(rewards.First().IsValid);
        }
示例#13
0
        public static int GetCartItemsQuantity(this PromotionEvaluationContext context, string[] excludingCategoryIds, string[] excludingProductIds)
        {
            var retVal = context.CartPromoEntries.ExcludeCategories(excludingCategoryIds)
                         .ExcludeProducts(excludingProductIds)
                         .Sum(x => x.Quantity);

            return(retVal);
        }
示例#14
0
        public static decimal GetCartTotalWithExcludings(this PromotionEvaluationContext context, string[] excludingCategoryIds, string[] excludingProductIds)
        {
            var retVal = context.CartPromoEntries.ExcludeCategories(excludingCategoryIds)
                         .ExcludeProducts(excludingProductIds)
                         .Sum(x => x.Price * x.Quantity);

            return(retVal);
        }
示例#15
0
        public static bool IsItemCodeContains(this PromotionEvaluationContext context, string code)
        {
            var result = context.PromoEntry != null && !string.IsNullOrEmpty(context.PromoEntry.Code);

            if (result)
            {
                result = context.PromoEntry.Code.IndexOf(code, StringComparison.OrdinalIgnoreCase) != -1;
            }
            return(result);
        }
示例#16
0
        public async Task <ActionResult> GetActualProductPricesJson(Product[] products)
        {
            var prices = new List <ProductPrice>();

            if (products == null)
            {
                return(Json(prices, JsonRequestBehavior.AllowGet));
            }

            var pricesResponse = await _pricingApi.PricingModuleEvaluatePricesAsync(
                evalContextProductIds : products.Select(p => p.Id).ToList(),
                evalContextCatalogId : WorkContext.CurrentStore.Catalog,
                evalContextCurrency : WorkContext.CurrentCurrency.Code,
                evalContextCustomerId : WorkContext.CurrentCustomer.Id,
                evalContextLanguage : WorkContext.CurrentLanguage.CultureName,
                evalContextStoreId : WorkContext.CurrentStore.Id);

            if (pricesResponse == null)
            {
                return(Json(prices, JsonRequestBehavior.AllowGet));
            }

            prices = pricesResponse.Select(p => p.ToWebModel()).ToList();
            var promotionContext = new PromotionEvaluationContext
            {
                CartPromoEntries = GetCartPromoEntries(WorkContext.CurrentCart),
                Currency         = WorkContext.CurrentCurrency,
                CustomerId       = WorkContext.CurrentCustomer.Id,
                IsRegisteredUser = WorkContext.CurrentCustomer.HasAccount,
                Language         = WorkContext.CurrentLanguage,
                PromoEntries     = GetPromoEntries(products, prices),
                StoreId          = WorkContext.CurrentStore.Id
            };

            foreach (var product in products)
            {
                product.Currency = WorkContext.CurrentCurrency;
                product.Price    = prices.FirstOrDefault(p => p.ProductId == product.Id);
            }

            await _promotionEvaluator.EvaluateDiscountsAsync(promotionContext, products);

            prices = products.Select(p => p.Price).ToList();

            foreach (var price in prices)
            {
                if (price.ActiveDiscount != null)
                {
                    price.AbsoluteBenefit += price.ActiveDiscount.Amount;
                    price.ActualPrice      = price.SalePrice - price.AbsoluteBenefit;
                }
            }

            return(Json(prices, JsonRequestBehavior.AllowGet));
        }
示例#17
0
 public static bool IsItemsInStockQuantity(this PromotionEvaluationContext context, bool isExactly, int quantity)
 {
     if (isExactly)
     {
         return(context.PromoEntry.InStockQuantity == quantity);
     }
     else
     {
         return(context.PromoEntry.InStockQuantity >= quantity);
     }
 }
示例#18
0
        public void EvaluateRewards_DynamicPromotions()
        {
            //Arrange
            var couponSearchMockServiceMock = new Mock <ICouponSearchService>();
            var promotionUsageSearchMock    = new Mock <IPromotionUsageSearchService>();
            var promoConditionTree          = "{\"AvailableChildren\":null,\"Children\":[{\"All\":false,\"Not\":false,\"AvailableChildren\":null,\"Children\":[{\"AvailableChildren\":null,\"Children\":[],\"Id\":\"ConditionIsRegisteredUser\"}],\"Id\":\"BlockCustomerCondition\"},{\"All\":false,\"Not\":false,\"AvailableChildren\":null,\"Children\":[],\"Id\":\"BlockCatalogCondition\"},{\"All\":false,\"Not\":false,\"AvailableChildren\":null,\"Children\":[{\"NumItem\":10,\"NumItemSecond\":13,\"ProductId\":null,\"ProductName\":null,\"CompareCondition\":\"Between\",\"AvailableChildren\":null,\"Children\":[],\"Id\":\"ConditionAtNumItemsInCart\"},{\"SubTotal\":0.0,\"SubTotalSecond\":100.0,\"ExcludingCategoryIds\":[],\"ExcludingProductIds\":[],\"CompareCondition\":\"AtLeast\",\"AvailableChildren\":null,\"Children\":[],\"Id\":\"ConditionCartSubtotalLeast\"}],\"Id\":\"BlockCartCondition\"},{\"AvailableChildren\":null,\"Children\":[{\"Amount\":15.0,\"AvailableChildren\":null,\"Children\":[],\"Id\":\"RewardCartGetOfAbsSubtotal\"}],\"Id\":\"BlockReward\"}],\"Id\":\"PromotionConditionAndRewardTree\"}";

            AbstractTypeFactory <Promotion> .RegisterType <DynamicPromotion>().WithSetupAction((promotion) =>
            {
                var dynamicPromotion = promotion as DynamicPromotion;
                dynamicPromotion.CouponSearchService         = couponSearchMockServiceMock.Object;
                dynamicPromotion.PromotionUsageSearchService = promotionUsageSearchMock.Object;
                dynamicPromotion.DynamicExpression           = AbstractTypeFactory <PromotionConditionAndRewardTree> .TryCreateInstance();
                dynamicPromotion.DynamicExpression.Children  = dynamicPromotion.DynamicExpression.AvailableChildren.ToList();
            });

            foreach (var conditionTree in AbstractTypeFactory <PromotionConditionAndRewardTreePrototype> .TryCreateInstance().Traverse <IConditionTree>(x => x.AvailableChildren))
            {
                AbstractTypeFactory <IConditionTree> .RegisterType(conditionTree.GetType());
            }

            var evalPolicy = GetPromotionEvaluationPolicy(new List <Promotion> {
                new DynamicPromotion
                {
                    CouponSearchService         = couponSearchMockServiceMock.Object,
                    PromotionUsageSearchService = promotionUsageSearchMock.Object,
                    DynamicExpression           = JsonConvert.DeserializeObject <PromotionConditionAndRewardTree>(promoConditionTree, new ConditionJsonConverter(), new PolymorphJsonConverter())
                }
            });

            var context = new PromotionEvaluationContext()
            {
                IsRegisteredUser = true,
                IsEveryone       = true,
                Currency         = "usd",
                PromoEntries     = new List <ProductPromoEntry> {
                    new ProductPromoEntry()
                    {
                        ProductId = "1"
                    }
                },
                CartPromoEntries = new List <ProductPromoEntry> {
                    new ProductPromoEntry {
                        Quantity = 11, Price = 5
                    }
                }
            };

            //Act
            var rewards = evalPolicy.EvaluatePromotionAsync(context).GetAwaiter().GetResult().Rewards;

            //Assert
            Assert.Equal(1, rewards.Count);
        }
示例#19
0
        protected virtual void EvaluateReward(PromotionEvaluationContext promoContext, bool couponIsValid, PromotionReward reward)
        {
            reward.Promotion = this;
            reward.IsValid   = couponIsValid && Condition(promoContext);

            //Set productId for catalog item reward
            if (reward is CatalogItemAmountReward catalogItemReward && catalogItemReward.ProductId == null)
            {
                catalogItemReward.ProductId = promoContext.PromoEntry.ProductId;
            }
        }
示例#20
0
        public ConditionsBenchmark()
        {
            pCtx = MockPromotionEvaluationContext();

            // Customer conditions
            _conditionIsRegisteredUser   = new ConditionIsRegisteredUser();
            _conditionIsEveryone         = new ConditionIsEveryone();
            _conditionIsFirstTimeBuyer   = new ConditionIsFirstTimeBuyer();
            _userGroupsContainsCondition = new UserGroupsContainsCondition()
            {
                Group = "Group7"
            };

            // Catalog conditions
            _conditionCategoryIs = new ConditionCategoryIs()
            {
                CategoryId = "8B77CD0F-5C4E-4BBA-9AEF-CD3022D0D2C1"
            };
            _conditionCodeContains = new ConditionCodeContains()
            {
                Keyword = "16-29"
            };
            _conditionCurrencyIs = new ConditionCurrencyIs()
            {
                Currency = "USD"
            };
            _conditionEntryIs = new ConditionEntryIs()
            {
                ProductIds = new string[] { "4B70F12A-25F8-4225-9A50-68C7E6DA25B3", "4B70F12A-25F8-4225-9A50-68C7E5DA25B2", "4B70F12B-25F8-4225-9A50-68C7E6DA25B2", "4B70F12A-2EF8-4225-9A50-68C7E6DA25B2", "4B70F12A-25F8-4225-9A50-68C7E6DA25B2" }
            };
            _conditionInStockQuantity = new ConditionInStockQuantity()
            {
                CompareCondition = ConditionOperation.Between, Quantity = 1, QuantitySecond = 100
            };
            _conditionHasNoSalePrice = new ConditionHasNoSalePrice();

            // Cart conditions
            _conditionAtNumItemsInCart = new ConditionAtNumItemsInCart()
            {
                CompareCondition = ConditionOperation.Between, NumItem = 1, NumItemSecond = 100
            };
            _conditionAtNumItemsInCategoryAreInCart = new ConditionAtNumItemsInCategoryAreInCart()
            {
                CompareCondition = ConditionOperation.Between, NumItem = 1, NumItemSecond = 100, CategoryId = "8B77CD0F-5C4E-4BBA-9AEF-CD3022D0D2C1"
            };
            _conditionAtNumItemsOfEntryAreInCart = new ConditionAtNumItemsOfEntryAreInCart()
            {
                CompareCondition = ConditionOperation.Between, NumItem = 1, NumItemSecond = 100, ProductId = "8B77CD0F-5C4E-4BBA-9AEF-CD3022D0D2C1"
            };
            _conditionCartSubtotalLeast = new ConditionCartSubtotalLeast()
            {
                CompareCondition = ConditionOperation.Between, SubTotal = 1, SubTotalSecond = 100
            };
        }
示例#21
0
        protected virtual void EvaluateReward(PromotionEvaluationContext promoContext, bool couponIsValid, PromotionReward reward)
        {
            reward.Promotion = this;
            reward.IsValid   = couponIsValid && (DynamicExpression?.IsSatisfiedBy(promoContext) ?? false);

            //Set productId for catalog item reward
            if (reward is CatalogItemAmountReward catalogItemReward && catalogItemReward.ProductId == null)
            {
                catalogItemReward.ProductId = promoContext.PromoEntry.ProductId;
            }
        }
示例#22
0
        public static bool IsAnyLineItemExtendedTotal(this PromotionEvaluationContext context, decimal lineItemTotal, bool isExactly, string[] excludingCategoryIds, string[] excludingProductIds)
        {
            var compareCondition = ModuleConstants.ConditionOperation.AtLeast;

            if (isExactly)
            {
                compareCondition = ModuleConstants.ConditionOperation.Exactly;
            }

            return(IsAnyLineItemExtendedTotalNew(context, lineItemTotal, 0, compareCondition, excludingCategoryIds, excludingProductIds));
        }
示例#23
0
        public virtual PromotionEvaluationContext ToPromotionEvaluationContext(ShoppingCart cart)
        {
            var result = new PromotionEvaluationContext();

            result.Cart     = cart;
            result.Customer = cart.Customer;
            result.Currency = cart.Currency;
            result.Language = cart.Language;
            result.StoreId  = cart.StoreId;

            return(result);
        }
示例#24
0
        public async Task <Product> GetProductByKeywordAsync(SiteContext context, string keyword, ItemResponseGroups responseGroup = ItemResponseGroups.ItemLarge)
        {
            var product =
                await
                this._browseClient.GetProductByKeywordAsync(
                    context.StoreId,
                    context.Language,
                    keyword,
                    responseGroup);

            if (product == null)
            {
                return(null);
            }

            var variationIds = product.GetAllVariationIds();
            var prices       = await this.GetProductPricesAsync(context.PriceLists, variationIds);

            var price = prices.FirstOrDefault(p => p.ProductId == product.Id);
            //if (product.Variations != null)
            //{
            //    foreach (var variation in product.Variations)
            //    {
            //        price = prices.FirstOrDefault(p => p.ProductId == variation.Id);
            //    }
            //}

            var promoContext = new PromotionEvaluationContext
            {
                CustomerId   = context.CustomerId,
                CartTotal    = context.Cart.TotalPrice,
                Currency     = context.Shop.Currency,
                PromoEntries = new List <ProductPromoEntry>
                {
                    new ProductPromoEntry
                    {
                        CatalogId = product.CatalogId,
                        Price     = price != null ? (price.Sale.HasValue ? price.Sale.Value : price.List) : 0M,
                        ProductId = product.Id,
                        Quantity  = 1
                    }
                },
                IsRegisteredUser = context.Customer != null,
                StoreId          = context.StoreId
            };

            var rewards = await _marketingClient.GetPromotionRewardsAsync(promoContext);

            var inventories = await this.GetItemsInventoriesAsync(variationIds);

            return(product.AsWebModel(prices, rewards, inventories));
        }
示例#25
0
        public async Task EvaluateRewards_SpecialOfferReward_Applied()
        {
            //Arrange
            var evalPolicy = GetPromotionEvaluationPolicy(GetPromotions("Special offer"));
            var context    = new PromotionEvaluationContext();

            //Act
            var rewards = (await evalPolicy.EvaluatePromotionAsync(context)).Rewards;

            //Assert
            Assert.Single(rewards);
            Assert.Equal("Special offer", rewards.Single().Promotion.Id);
        }
示例#26
0
        public static PromotionEvaluationContext ToPromotionEvaluationContext(this ShoppingCart cart)
        {
            var result = new PromotionEvaluationContext(cart.Language, cart.Currency)
            {
                Cart     = cart,
                User     = cart.Customer,
                Currency = cart.Currency,
                Language = cart.Language,
                StoreId  = cart.StoreId
            };

            return(result);
        }
        private IEnumerable <PromotionRecord> CalculateCartDiscounts()
        {
            var records = new List <PromotionRecord>();

            foreach (var form in CurrentOrderGroup.OrderForms)
            {
                var set = GetPromotionEntrySetFromOrderForm(form);

                // create context
                var ctx = new Dictionary <string, object> {
                    { PromotionEvaluationContext.TargetSet, set }
                };

                var couponCode = CustomerSessionService.CustomerSession.CouponCode;

                //1. Prepare marketing context
                var evaluationContext = new PromotionEvaluationContext
                {
                    ContextObject    = ctx,
                    CustomerId       = CustomerSessionService.CustomerSession.CustomerId,
                    CouponCode       = CustomerSessionService.CustomerSession.CouponCode,
                    PromotionType    = PromotionType.CartPromotion,
                    Currency         = CustomerSessionService.CustomerSession.Currency,
                    Store            = CustomerSessionService.CustomerSession.StoreId,
                    IsRegisteredUser = CustomerSessionService.CustomerSession.IsRegistered,
                    IsFirstTimeBuyer = CustomerSessionService.CustomerSession.IsFirstTimeBuyer
                };

                //2. Evaluate
                //var evaluator = new DefaultPromotionEvaluator(MarketingRepository, PromotionUsageProvider, new IEvaluationPolicy[] { new GlobalExclusivityPolicy(), new CartSubtotalRewardCombinePolicy(), new ShipmentRewardCombinePolicy() }, CacheRepository);
                var promotions = PromotionEvaluator.EvaluatePromotion(evaluationContext);
                var rewards    = promotions.SelectMany(x => x.Rewards);

                //3. Generate warnings
                if (!string.IsNullOrEmpty(couponCode) && !promotions.Any(p => (p.CouponId != null && p.Coupon.Code == couponCode) ||
                                                                         (p.CouponSetId != null && p.CouponSet.Coupons.Any(c => c.Code == couponCode))))
                {
                    RegisterWarning(WorkflowMessageCodes.COUPON_NOT_APPLIED, "Coupon doesn't exist or is not applied");
                }

                records.AddRange(rewards.Select(reward => new PromotionRecord
                {
                    AffectedEntriesSet = set,
                    TargetEntriesSet   = set,
                    Reward             = reward,
                    PromotionType      = PromotionType.CartPromotion
                }));
            }

            return(records.ToArray());
        }
示例#28
0
        public async Task EvaluateDiscountsAsync(PromotionEvaluationContext context, IEnumerable <IDiscountable> owners)
        {
            var rewards = await _marketingApi.MarketingModulePromotionEvaluatePromotionsAsync(context.ToServiceModel());

            if (rewards == null)
            {
                return;
            }

            foreach (var owner in owners)
            {
                owner.ApplyRewards(rewards.Select(r => r.ToWebModel(owner.Currency)));
            }
        }
示例#29
0
        public virtual async Task EvaluateDiscountsAsync(PromotionEvaluationContext context, IEnumerable <IDiscountable> owners)
        {
            var cacheKey = CacheKey.With(GetType(), "EvaluateDiscountsAsync", context.GetCacheKey());
            var rewards  = await _memoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(MarketingCacheRegion.CreateChangeToken());
                cacheEntry.SetAbsoluteExpiration(TimeSpan.FromMinutes(1));

                var contextDto = context.ToPromotionEvaluationContextDto();
                return(await _promiotionApi.EvaluatePromotionsAsync(contextDto));
            });

            ApplyRewards(rewards, owners);
        }
        public async Task <ActionResult> GetActualProductPricesJson(Product[] products)
        {
            var prices = new List <ProductPrice>();

            if (products == null)
            {
                return(Json(prices, JsonRequestBehavior.AllowGet));
            }

            var pricesResponse = await _pricingApi.PricingModuleEvaluatePricesAsync(
                evalContextProductIds : products.Select(p => p.Id).ToList(),
                evalContextCatalogId : WorkContext.CurrentStore.Catalog,
                evalContextCurrency : WorkContext.CurrentCurrency.Code,
                evalContextCustomerId : WorkContext.CurrentCustomer.Id,
                evalContextLanguage : WorkContext.CurrentLanguage.CultureName,
                evalContextStoreId : WorkContext.CurrentStore.Id);

            if (pricesResponse == null)
            {
                return(Json(prices, JsonRequestBehavior.AllowGet));
            }

            prices = pricesResponse.Select(p => p.ToWebModel()).ToList();
            var promotionContext = new PromotionEvaluationContext
            {
                CartPromoEntries = GetCartPromoEntries(WorkContext.CurrentCart),
                Currency         = WorkContext.CurrentCurrency,
                CustomerId       = WorkContext.CurrentCustomer.Id,
                IsRegisteredUser = WorkContext.CurrentCustomer.HasAccount,
                Language         = WorkContext.CurrentLanguage,
                PromoEntries     = GetPromoEntries(products, prices),
                StoreId          = WorkContext.CurrentStore.Id
            };

            var rewards = await _marketingService.EvaluatePromotionRewardsAsync(promotionContext);

            var validRewards = rewards.Where(r => r.RewardType == PromotionRewardType.CatalogItemAmountReward && r.IsValid);

            foreach (var price in prices)
            {
                var validReward = validRewards.FirstOrDefault(r => r.ProductId == price.ProductId);
                if (validReward != null)
                {
                    price.ActiveDiscount = validReward.ToDiscountWebModel(price.SalePrice.Amount, 1, price.Currency);
                }
            }

            return(Json(prices, JsonRequestBehavior.AllowGet));
        }