예제 #1
0
        public async Task <PromotionResult> EvaluatePromotionAsync(IEvaluationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var promoContext = context as PromotionEvaluationContext;

            if (promoContext == null)
            {
                throw new ArgumentException($"{nameof(context)} type {context.GetType()} must be derived from PromotionEvaluationContext");
            }

            var promotionSearchCriteria = new PromotionSearchCriteria
            {
                OnlyActive = true,
                StoreIds   = string.IsNullOrEmpty(promoContext.StoreId) ? null : new[] { promoContext.StoreId },
                Take       = int.MaxValue
            };

            var promotions = await _promotionSearchService.SearchPromotionsAsync(promotionSearchCriteria);

            var result = new PromotionResult();

            Func <PromotionEvaluationContext, IEnumerable <PromotionReward> > evalFunc = (evalContext) => promotions.Results.SelectMany(x => x.EvaluatePromotion(evalContext))
                                                                                         .OrderByDescending(x => x.Promotion.IsExclusive)
                                                                                         .ThenByDescending(x => x.Promotion.Priority)
                                                                                         .Where(x => x.IsValid)
                                                                                         .ToList();

            EvalAndCombineRewardsRecursively(promoContext, evalFunc, result.Rewards, new List <PromotionReward>());
            return(result);
        }
        public virtual async Task <LoadPromotionsResponce> Handle(LoadPromotionsQuery request, CancellationToken cancellationToken)
        {
            var promotions = await _promotionSearchService.SearchPromotionsAsync(new PromotionSearchCriteria
            {
                ObjectIds = request.Ids.ToArray(),
            });

            return(new LoadPromotionsResponce
            {
                Promotions = promotions.Results.ToDictionary(x => x.Id)
            });
        }
예제 #3
0
        public async Task <ActionResult <PromotionSearchResult> > PromotionsSearch([FromBody] PromotionSearchCriteria criteria)
        {
            //Scope bound ACL filtration
            var authorizationResult = await _authorizationService.AuthorizeAsync(User, criteria, new MarketingAuthorizationRequirement(ModuleConstants.Security.Permissions.Read));

            if (!authorizationResult.Succeeded)
            {
                return(Unauthorized());
            }
            var result = await _promoSearchService.SearchPromotionsAsync(criteria);

            return(Ok(result));
        }
        protected override async Task <PromotionResult> EvaluatePromotionWithoutCache(PromotionEvaluationContext promoContext)
        {
            var promotionSearchCriteria = AbstractTypeFactory <PromotionSearchCriteria> .TryCreateInstance();

            promotionSearchCriteria.PopulateFromEvalContext(promoContext);

            promotionSearchCriteria.OnlyActive = true;
            promotionSearchCriteria.Take       = int.MaxValue;
            promotionSearchCriteria.StoreIds   = string.IsNullOrEmpty(promoContext.StoreId) ? null : new[] { promoContext.StoreId };

            var promotions = await _promotionSearchService.SearchPromotionsAsync(promotionSearchCriteria);

            var result = new PromotionResult();

            await EvalAndCombineRewardsRecursivelyAsync(promoContext, promotions.Results, result.Rewards, new List <PromotionReward>());

            return(result);
        }
        public async Task <ActionResult <GenericSearchResult <DynamicPromotion> > > PromotionsSearch([FromBody] PromotionSearchCriteria criteria)
        {
            var retVal = new GenericSearchResult <Promotion>();

            //Scope bound ACL filtration
            criteria = FilterPromotionSearchCriteria(User.Identity.Name, criteria);

            var promoSearchResult = await _promoSearchService.SearchPromotionsAsync(criteria);

            //foreach (var promotion in promoSearchResult.Results.OfType<DynamicPromotion>())
            //{
            //    promotion.PredicateVisualTreeSerialized = null;
            //    promotion.PredicateSerialized = null;
            //    promotion.RewardsSerialized = null;
            //}

            retVal.TotalCount = promoSearchResult.TotalCount;
            retVal.Results    = promoSearchResult.Results.ToList();
            return(Ok(retVal));
        }
        protected override async Task <PromotionResult> EvaluatePromotionWithoutCache(PromotionEvaluationContext promoContext)
        {
            var promotionSearchCriteria = AbstractTypeFactory <PromotionSearchCriteria> .TryCreateInstance();

            promotionSearchCriteria.PopulateFromEvalContext(promoContext);

            promotionSearchCriteria.OnlyActive = true;
            promotionSearchCriteria.Take       = int.MaxValue;
            promotionSearchCriteria.StoreIds   = string.IsNullOrEmpty(promoContext.StoreId) ? null : new[] { promoContext.StoreId };

            var promotions = await _promotionSearchService.SearchPromotionsAsync(promotionSearchCriteria);

            var result            = new PromotionResult();
            var evalPromtionTasks = promotions.Results.Select(x => x.EvaluatePromotionAsync(promoContext)).ToArray();
            await Task.WhenAll(evalPromtionTasks);

            var rewards = evalPromtionTasks.SelectMany(x => x.Result).Where(x => x.IsValid).ToArray();

            var firstOrderExclusiveReward = rewards.FirstOrDefault(x => x.Promotion.IsExclusive);

            if (firstOrderExclusiveReward != null)
            {
                //Add only rewards from exclusive promotion
                result.Rewards.AddRange(rewards.Where(x => x.Promotion == firstOrderExclusiveReward.Promotion));
            }
            else
            {
                //best shipment promotion
                var curShipmentAmount              = promoContext.ShipmentMethodCode != null ? promoContext.ShipmentMethodPrice : 0m;
                var allShipmentRewards             = rewards.OfType <ShipmentReward>().ToArray();
                var groupedByShippingMethodRewards = allShipmentRewards.GroupBy(x => x.ShippingMethod);
                foreach (var shipmentRewards in groupedByShippingMethodRewards)
                {
                    var bestShipmentReward = GetBestAmountReward(curShipmentAmount, shipmentRewards);
                    if (bestShipmentReward != null)
                    {
                        result.Rewards.Add(bestShipmentReward);
                    }
                }

                //best payment promotion
                var currentPaymentAmount          = promoContext.PaymentMethodCode != null ? promoContext.PaymentMethodPrice : 0m;
                var allPaymentRewards             = rewards.OfType <PaymentReward>().ToArray();
                var groupedByPaymentMethodRewards = allPaymentRewards.GroupBy(x => x.PaymentMethod);
                foreach (var paymentRewards in groupedByPaymentMethodRewards)
                {
                    var bestPaymentReward = GetBestAmountReward(currentPaymentAmount, paymentRewards);
                    if (bestPaymentReward != null)
                    {
                        result.Rewards.Add(bestPaymentReward);
                    }
                }

                //best catalog item promotion
                var allItemsRewards = rewards.OfType <CatalogItemAmountReward>().ToArray();
                var groupRewards    = allItemsRewards.GroupBy(x => x.ProductId).Where(x => x.Key != null);
                foreach (var groupReward in groupRewards)
                {
                    var item = promoContext.PromoEntries.FirstOrDefault(x => x.ProductId == groupReward.Key);
                    if (item != null)
                    {
                        var bestItemReward = GetBestAmountReward(item.Price, item.Quantity, groupReward);
                        if (bestItemReward != null)
                        {
                            result.Rewards.Add(bestItemReward);
                        }
                    }
                }

                //best order promotion
                var cartSubtotalRewards = rewards.OfType <CartSubtotalReward>().Where(x => x.IsValid).OrderByDescending(x => x.GetRewardAmount(promoContext.CartTotal, 1));
                var cartSubtotalReward  = cartSubtotalRewards.FirstOrDefault(x => !string.IsNullOrEmpty(x.Coupon)) ?? cartSubtotalRewards.FirstOrDefault();
                if (cartSubtotalReward != null)
                {
                    result.Rewards.Add(cartSubtotalReward);
                }

                //Gifts
                rewards.OfType <GiftReward>().ToList().ForEach(x => result.Rewards.Add(x));

                //Special offer
                rewards.OfType <SpecialOfferReward>().ToList().ForEach(x => result.Rewards.Add(x));
            }

            return(result);
        }
        public async Task <PromotionResult> EvaluatePromotionAsync(IEvaluationContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var promoContext = context as PromotionEvaluationContext;

            if (promoContext == null)
            {
                throw new ArgumentException($"{nameof(context)} type {context.GetType()} must be derived from PromotionEvaluationContext");
            }


            var promotions = await _promotionSearchService.SearchPromotionsAsync(new PromotionSearchCriteria { OnlyActive = true, StoreIds = new[] { promoContext.StoreId }, Take = int.MaxValue });

            var result = new PromotionResult();

            var rewards = promotions.Results.SelectMany(x => x.EvaluatePromotion(context)).Where(x => x.IsValid).ToArray();

            var firstOrderExlusiveReward = rewards.FirstOrDefault(x => x.Promotion.IsExclusive);

            if (firstOrderExlusiveReward != null)
            {
                //Add only rewards from exclusive promotion
                result.Rewards.AddRange(rewards.Where(x => x.Promotion == firstOrderExlusiveReward.Promotion));
            }
            else
            {
                //best shipment promotion
                var curShipmentAmount              = promoContext.ShipmentMethodCode != null ? promoContext.ShipmentMethodPrice : 0m;
                var allShipmentRewards             = rewards.OfType <ShipmentReward>().ToArray();
                var groupedByShippingMethodRewards = allShipmentRewards.GroupBy(x => x.ShippingMethod);
                foreach (var shipmentRewards in groupedByShippingMethodRewards)
                {
                    var bestShipmentReward = GetBestAmountReward(curShipmentAmount, shipmentRewards);
                    if (bestShipmentReward != null)
                    {
                        result.Rewards.Add(bestShipmentReward);
                    }
                }

                //best catalog item promotion
                var allItemsRewards = rewards.OfType <CatalogItemAmountReward>().ToArray();
                var groupRewards    = allItemsRewards.GroupBy(x => x.ProductId).Where(x => x.Key != null);
                foreach (var groupReward in groupRewards)
                {
                    var item = promoContext.PromoEntries.FirstOrDefault(x => x.ProductId == groupReward.Key);
                    if (item != null)
                    {
                        var bestItemReward = GetBestAmountReward(item.Price, groupReward);
                        if (bestItemReward != null)
                        {
                            result.Rewards.Add(bestItemReward);
                        }
                    }
                }

                //best order promotion
                var cartSubtotalRewards = rewards.OfType <CartSubtotalReward>().Where(x => x.IsValid).OrderByDescending(x => x.GetRewardAmount(promoContext.CartTotal, 1));
                var cartSubtotalReward  = cartSubtotalRewards.FirstOrDefault(x => !string.IsNullOrEmpty(x.Coupon)) ?? cartSubtotalRewards.FirstOrDefault();
                if (cartSubtotalReward != null)
                {
                    result.Rewards.Add(cartSubtotalReward);
                }
                //Gifts
                rewards.OfType <GiftReward>().ToList().ForEach(x => result.Rewards.Add(x));

                //Special offer
                rewards.OfType <SpecialOfferReward>().ToList().ForEach(x => result.Rewards.Add(x));
            }

            return(result);
        }
        public async Task DoExportAsync(Stream outStream, Action <ExportImportProgressInfo> progressCallback,
                                        ICancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var progressInfo = new ExportImportProgressInfo {
                Description = "loading data..."
            };

            progressCallback(progressInfo);

            using (var sw = new StreamWriter(outStream))
                using (var writer = new JsonTextWriter(sw))
                {
                    await writer.WriteStartObjectAsync();

                    progressInfo.Description = "Promotions exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("Promotions");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, (skip, take) => _promotionSearchService.SearchPromotionsAsync(new PromotionSearchCriteria {
                        Skip = skip, Take = take
                    }), (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } promotions have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Dynamic content folders exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("DynamicContentFolders");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, (skip, take) => _dynamicContentSearchService.SearchFoldersAsync(new DynamicContentFolderSearchCriteria {
                        Skip = skip, Take = take
                    }), (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } dynamic content folders have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Dynamic content items exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("DynamicContentItems");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, (skip, take) => _dynamicContentSearchService.SearchContentItemsAsync(new DynamicContentItemSearchCriteria {
                        Skip = skip, Take = take
                    }), (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } dynamic content items have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Dynamic content places exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("DynamicContentPlaces");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, (skip, take) => _dynamicContentSearchService.SearchContentPlacesAsync(new DynamicContentPlaceSearchCriteria {
                        Skip = skip, Take = take
                    }), (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } dynamic content places have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Dynamic content publications exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("DynamicContentPublications");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, (skip, take) => _dynamicContentSearchService.SearchContentPublicationsAsync(new DynamicContentPublicationSearchCriteria {
                        Skip = skip, Take = take
                    }), (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } dynamic content publications have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Coupons exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("Coupons");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, (skip, take) => _couponService.SearchCouponsAsync(new CouponSearchCriteria {
                        Skip = skip, Take = take
                    }), (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } coupons have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Usages exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("Usages");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, (skip, take) => _promotionUsageService.SearchUsagesAsync(new PromotionUsageSearchCriteria {
                        Skip = skip, Take = take
                    }), (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } usages have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    await writer.WriteEndObjectAsync();

                    await writer.FlushAsync();
                }
        }
 protected virtual Task <PromotionSearchResult> LoadPromotionsPageAsync(int skip, int take, ExportImportOptions options, Action <ExportImportProgressInfo> progressCallback)
 {
     return(_promotionSearchService.SearchPromotionsAsync(new PromotionSearchCriteria {
         Skip = skip, Take = take
     }));
 }
예제 #10
0
        public async Task DoExportAsync(Stream outStream, Action <ExportImportProgressInfo> progressCallback,
                                        ICancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var progressInfo = new ExportImportProgressInfo {
                Description = "loading data..."
            };

            progressCallback(progressInfo);

            using (var sw = new StreamWriter(outStream))
                using (var writer = new JsonTextWriter(sw))
                {
                    await writer.WriteStartObjectAsync();

                    progressInfo.Description = "Promotions exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("Promotions");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, async (skip, take) =>
                                                                   (GenericSearchResult <Promotion>) await _promotionSearchService.SearchPromotionsAsync(new PromotionSearchCriteria {
                        Skip = skip, Take = take
                    })
                                                                   , (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } promotions have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Dynamic content folders exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("DynamicContentFolders");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, async (skip, take) =>
                    {
                        var searchResult        = AbstractTypeFactory <DynamicContentFolderSearchResult> .TryCreateInstance();
                        var result              = await LoadFoldersRecursiveAsync(null);
                        searchResult.Results    = result;
                        searchResult.TotalCount = result.Count;
                        return((GenericSearchResult <DynamicContentFolder>)searchResult);
                    }, (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } dynamic content folders have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Dynamic content items exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("DynamicContentItems");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, async (skip, take) =>
                                                                   (GenericSearchResult <DynamicContentItem>) await _dynamicContentSearchService.SearchContentItemsAsync(new DynamicContentItemSearchCriteria {
                        Skip = skip, Take = take
                    })
                                                                   , (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } dynamic content items have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Dynamic content places exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("DynamicContentPlaces");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, async (skip, take) =>
                                                                   (GenericSearchResult <DynamicContentPlace>) await _dynamicContentSearchService.SearchContentPlacesAsync(new DynamicContentPlaceSearchCriteria {
                        Skip = skip, Take = take
                    })
                                                                   , (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } dynamic content places have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Dynamic content publications exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("DynamicContentPublications");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, async (skip, take) =>
                    {
                        var searchResult = await _dynamicContentSearchService.SearchContentPublicationsAsync(new DynamicContentPublicationSearchCriteria {
                            Skip = skip, Take = take
                        });
                        return((GenericSearchResult <DynamicContentPublication>)searchResult);
                    }, (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } dynamic content publications have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Coupons exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("Coupons");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, (skip, take) => _couponService.SearchCouponsAsync(new CouponSearchCriteria {
                        Skip = skip, Take = take
                    }), (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } coupons have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    progressInfo.Description = "Usages exporting...";
                    progressCallback(progressInfo);

                    await writer.WritePropertyNameAsync("Usages");

                    await writer.SerializeJsonArrayWithPagingAsync(_jsonSerializer, _batchSize, (skip, take) => _promotionUsageService.SearchUsagesAsync(new PromotionUsageSearchCriteria {
                        Skip = skip, Take = take
                    }), (processedCount, totalCount) =>
                    {
                        progressInfo.Description = $"{ processedCount } of { totalCount } usages have been exported";
                        progressCallback(progressInfo);
                    }, cancellationToken);

                    await writer.WriteEndObjectAsync();

                    await writer.FlushAsync();
                }
        }