Esempio n. 1
0
        public virtual async Task <PromotionSearchResult> SearchPromotionsAsync(PromotionSearchCriteria criteria)
        {
            var cacheKey = CacheKey.With(GetType(), "SearchPromotionsAsync", criteria.GetCacheKey());

            return(await _platformMemoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(PromotionCacheRegion.CreateChangeToken());
                var retVal = AbstractTypeFactory <PromotionSearchResult> .TryCreateInstance();
                using (var repository = _repositoryFactory())
                {
                    var query = GetPromotionsQuery(repository, criteria);

                    var sortInfos = criteria.SortInfos;
                    if (sortInfos.IsNullOrEmpty())
                    {
                        sortInfos = new[] { new SortInfo {
                                                SortColumn = ReflectionUtility.GetPropertyName <Promotion>(x => x.Priority), SortDirection = SortDirection.Descending
                                            } };
                    }
                    query = query.OrderBySortInfos(sortInfos);

                    retVal.TotalCount = await query.CountAsync();

                    if (criteria.Take > 0)
                    {
                        var ids = await query.Select(x => x.Id)
                                  .Skip(criteria.Skip)
                                  .Take(criteria.Take).ToArrayAsync();
                        var promotions = await _promotionService.GetPromotionsByIdsAsync(ids);
                        retVal.Results = promotions.OrderBy(p => ids.ToList().IndexOf(p.Id)).ToList();
                    }
                }
                return retVal;
            }));
        }
        public virtual async Task <PromotionSearchResult> SearchPromotionsAsync(PromotionSearchCriteria criteria)
        {
            var cacheKey = CacheKey.With(GetType(), nameof(SearchPromotionsAsync), criteria.GetCacheKey());

            return(await _platformMemoryCache.GetOrCreateExclusiveAsync(cacheKey, async (cacheEntry) =>
            {
                cacheEntry.AddExpirationToken(PromotionSearchCacheRegion.CreateChangeToken());

                var result = AbstractTypeFactory <PromotionSearchResult> .TryCreateInstance();

                using (var repository = _repositoryFactory())
                {
                    var sortInfos = BuildSortExpression(criteria);
                    var query = BuildQuery(repository, criteria);
                    //https://github.com/zzzprojects/EntityFramework-Plus/issues/293
                    //Workaround ArgumentException with CountAsync have no predicate when query has a Cast or OfType expression
                    result.TotalCount = await query.CountAsync(x => true);

                    if (criteria.Take > 0)
                    {
                        var ids = await query.OrderBySortInfos(sortInfos).ThenBy(x => x.Id)
                                  .Select(x => x.Id)
                                  .Skip(criteria.Skip).Take(criteria.Take)
                                  .ToArrayAsync();

                        result.Results = (await _promotionService.GetPromotionsByIdsAsync(ids))
                                         .OrderBy(x => Array.IndexOf(ids, x.Id)).ToList();
                    }
                }
                return result;
            }));
        }
Esempio n. 3
0
        public virtual GenericSearchResult <coreModel.Promotion> SearchPromotions(PromotionSearchCriteria criteria)
        {
            var retVal = new GenericSearchResult <coreModel.Promotion>();

            using (var repository = _repositoryFactory())
            {
                var query = GetPromotionsQuery(repository, criteria);

                var sortInfos = criteria.SortInfos;
                if (sortInfos.IsNullOrEmpty())
                {
                    sortInfos = new[] { new SortInfo {
                                            SortColumn = ReflectionUtility.GetPropertyName <coreModel.Promotion>(x => x.Priority), SortDirection = SortDirection.Descending
                                        } };
                }
                query = query.OrderBySortInfos(sortInfos).ThenBy(x => x.Id);

                retVal.TotalCount = query.Count();

                var ids = query.Select(x => x.Id)
                          .Skip(criteria.Skip)
                          .Take(criteria.Take)
                          .ToArray();

                retVal.Results = _promotionSrevice.GetPromotionsByIds(ids)
                                 .OrderBy(p => Array.IndexOf(ids, p.Id))
                                 .ToList();
            }
            return(retVal);
        }
Esempio n. 4
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);
        }
Esempio n. 5
0
        public GenericSearchResult <Promotion> SearchPromotions(PromotionSearchCriteria criteria)
        {
            var cacheKey = GetCacheKey("IPromotionSearchService.SearchPromotions", criteria.GetCacheKey());
            var retVal   = _cacheManager.Get(cacheKey, RegionName, () => _promoSearchService.SearchPromotions(criteria));

            return(retVal);
        }
        public IHttpActionResult PromotionsSearch(PromotionSearchCriteria criteria)
        {
            var retVal = new GenericSearchResult <webModel.Promotion>();

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

            var promoSearchResult = _promoSearchService.SearchPromotions(criteria);

            retVal.TotalCount = promoSearchResult.TotalCount;
            retVal.Results    = promoSearchResult.Results.Select(x => x.ToWebModel()).ToList();
            return(Ok(retVal));
        }
Esempio n. 7
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 virtual IList <SortInfo> BuildSortExpression(PromotionSearchCriteria criteria)
        {
            var sortInfos = criteria.SortInfos;

            if (sortInfos.IsNullOrEmpty())
            {
                sortInfos = new[]
                {
                    new SortInfo
                    {
                        SortColumn    = nameof(Promotion.Priority),
                        SortDirection = SortDirection.Descending
                    }
                };
            }

            return(sortInfos);
        }
Esempio n. 9
0
        public IHttpActionResult PromotionsSearch(PromotionSearchCriteria criteria)
        {
            var retVal = new GenericSearchResult <Promotion>();

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

            var promoSearchResult = _promoSearchService.SearchPromotions(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));
        }
Esempio n. 10
0
        public GenericSearchResult <coreModel.Promotion> SearchPromotions(PromotionSearchCriteria criteria)
        {
            var retVal = new GenericSearchResult <coreModel.Promotion>();

            using (var repository = _repositoryFactory())
            {
                var query = repository.Promotions;
                if (!string.IsNullOrEmpty(criteria.Store))
                {
                    query = query.Where(x => x.StoreId == criteria.Store);
                }
                if (criteria.OnlyActive)
                {
                    var now = DateTime.UtcNow;
                    query = query.Where(x => x.IsActive && (x.StartDate == null || now >= x.StartDate) && (x.EndDate == null || x.EndDate >= now));
                }
                if (!string.IsNullOrEmpty(criteria.Keyword))
                {
                    query = query.Where(x => x.Name.Contains(criteria.Keyword) || x.Description.Contains(criteria.Keyword));
                }

                var sortInfos = criteria.SortInfos;
                if (sortInfos.IsNullOrEmpty())
                {
                    sortInfos = new[] { new SortInfo {
                                            SortColumn = ReflectionUtility.GetPropertyName <coreModel.Promotion>(x => x.Priority), SortDirection = SortDirection.Descending
                                        } };
                }
                query = query.OrderBySortInfos(sortInfos);

                retVal.TotalCount = query.Count();

                var ids = query.Select(x => x.Id)
                          .Skip(criteria.Skip)
                          .Take(criteria.Take).ToArray();
                retVal.Results = _promotionSrevice.GetPromotionsByIds(ids).OrderBy(p => ids.ToList().IndexOf(p.Id)).ToList();
            }
            return(retVal);
        }
Esempio n. 11
0
        protected virtual IQueryable <Model.PromotionEntity> GetPromotionsQuery(IMarketingRepository repository, PromotionSearchCriteria criteria)
        {
            var query = repository.Promotions;

            if (!string.IsNullOrEmpty(criteria.Store))
            {
                query = query.Where(x => !x.Stores.Any() || x.Stores.Any(s => s.StoreId == criteria.Store));
            }

            if (!criteria.StoreIds.IsNullOrEmpty())
            {
                query = query.Where(x => !x.Stores.Any() || x.Stores.Any(s => criteria.StoreIds.Contains(s.StoreId)));
            }

            if (criteria.OnlyActive)
            {
                var now = DateTime.UtcNow;
                query = query.Where(x => x.IsActive && (x.StartDate == null || now >= x.StartDate) && (x.EndDate == null || x.EndDate >= now));
            }
            if (!string.IsNullOrEmpty(criteria.Keyword))
            {
                query = query.Where(x => x.Name.Contains(criteria.Keyword) || x.Description.Contains(criteria.Keyword));
            }

            return(query);
        }
        private PromotionSearchCriteria FilterPromotionSearchCriteria(string userName, PromotionSearchCriteria criteria)
        {
            if (!_securityService.UserHasAnyPermission(userName, null, MarketingPredefinedPermissions.Read))
            {
                //Get defined user 'read' permission scopes
                var readPermissionScopes = _securityService.GetUserPermissions(userName)
                                           .Where(x => x.Id.StartsWith(MarketingPredefinedPermissions.Read))
                                           .SelectMany(x => x.AssignedScopes)
                                           .ToList();

                //Check user has a scopes
                //Store
                criteria.Store = readPermissionScopes.OfType <MarketingSelectedStoreScope>()
                                 .Select(x => x.Scope)
                                 .Where(x => !String.IsNullOrEmpty(x))
                                 .FirstOrDefault();
            }
            return(criteria);
        }
        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));
        }
        public PromotionResult EvaluatePromotion(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 = _promotionSearchService.SearchPromotions(promotionSearchCriteria).Results;

            var result = new PromotionResult();

            var rewards = promotions.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);
        }
 protected virtual GenericSearchResult <Promotion> SearchPromotions(PromotionSearchCriteria criteria)
 {
     return(_promotionSearchService.SearchPromotions(criteria));
 }