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) }); }
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 })); }
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(); } }