예제 #1
0
        /// <summary>
        /// Filters the promotions.
        /// </summary>
        /// <param name="evaluationContext">The evaluation context.</param>
        /// <param name="records">The records, must be sorted in the order they are applied.</param>
        /// <returns></returns>
        public PromotionRecord[] FilterPromotions(IPromotionEvaluationContext evaluationContext, PromotionRecord[] records)
        {
            // applied global promotion, set to empty at the beginning
            var appliedGlobalPromotionId = String.Empty;
            var appliedRecords           = new List <PromotionRecord>();

            foreach (var record in records)
            {
                if (appliedGlobalPromotionId == String.Empty)
                {
                    if (record.Reward.Promotion.ExclusionTypeId == (int)ExclusivityType.Global)
                    {
                        // set promotion id so we can filter all the rest of promotions
                        appliedGlobalPromotionId = record.Reward.Promotion.PromotionId;
                    }

                    appliedRecords.Add(record);
                }
                else // remove the rest of promotion records unless it was generated by the applied global promotion
                {
                    if (record.Reward.Promotion.PromotionId == appliedGlobalPromotionId)
                    {
                        appliedRecords.Add(record);
                    }
                }
            }

            return(appliedRecords.ToArray());
        }
        /// <summary>
        /// Filters the promotions.
        /// </summary>
        /// <param name="evaluationContext">The evaluation context.</param>
        /// <param name="records">The records, must be sorted in the order they are applied.</param>
        /// <returns></returns>
		public PromotionRecord[] FilterPromotions(IPromotionEvaluationContext evaluationContext, PromotionRecord[] records)
		{
            var appliedRecords = new List<PromotionRecord>();

            var groups = new Dictionary<string, string>();

            foreach (var record in records)
            {
                if (!groups.ContainsKey(record.PromotionType)) // we already have exclusive withing a current group, so ignore
                {
                    if (record.Reward.Promotion.ExclusionTypeId == (int)ExclusivityType.Group)
                    {
                        groups.Add(record.PromotionType, record.Reward.Promotion.PromotionId);
                    }

                    appliedRecords.Add(record);
                }
                else // remove the rest of promotion records unless it was generated by the applied group promotion
                {
                    if (groups.ContainsValue(record.Reward.Promotion.PromotionId))
                        appliedRecords.Add(record);
                }
            }

            return appliedRecords.ToArray();
		}
 public PromotionRecord[] FilterPromotions(IPromotionEvaluationContext evaluationContext, PromotionRecord[] records)
 {
     /*
      *          var retVal = promotions;
      *          var cartSubtotalRewards = retVal.SelectMany(x => x.Rewards.OfType<CartSubtotalReward>()).ToArray();
      *          //Only a max relative(%) discount or absolute($). The relative (%) has a exlude the absolute ($).
      *          var maxCartSubtotalReward = cartSubtotalRewards.Where(x => x.AmountTypeId == (int)RewardAmountType.Relative)
      *                                                                                                                     .OrderByDescending(x => x.Amount)
      *                                                                                                                     .FirstOrDefault();
      *          if (maxCartSubtotalReward == null)
      *          {
      *                  maxCartSubtotalReward = cartSubtotalRewards.Where(x => x.AmountTypeId == (int)RewardAmountType.Absolute)
      *                                                                                                                             .OrderByDescending(x => x.Amount)
      *                                                                                                                             .FirstOrDefault();
      *          }
      *          if (maxCartSubtotalReward != null)
      *          {
      *                  //Remove all other cartSubtotalRewards from promotions
      *                  foreach (var toRemoveReward in cartSubtotalRewards.Where(x => x != maxCartSubtotalReward))
      *                  {
      *                          toRemoveReward.Promotion.Rewards.Remove(toRemoveReward);
      *                  }
      *          }
      *
      *          return retVal.Where(x => x.Rewards.Count() > 0).ToArray();
      * */
     return(records);
 }
		public PromotionRecord[] FilterPromotions(IPromotionEvaluationContext evaluationContext, PromotionRecord[] records)
		{
            /*
			var retVal = promotions;
			var shipmentRewards = retVal.SelectMany(x => x.Rewards.OfType<ShipmentReward>()).ToArray();
			//Only a max relative(%) discount or absolute($). The relative (%) has a exlude the absolute ($).
			var maxShipmentReward = shipmentRewards.Where(x => x.AmountTypeId == (int)RewardAmountType.Relative)
																   .OrderByDescending(x => x.Amount)
																   .FirstOrDefault();
			if (maxShipmentReward == null)
			{
				maxShipmentReward = shipmentRewards.Where(x => x.AmountTypeId == (int)RewardAmountType.Absolute)
																	   .OrderByDescending(x => x.Amount)
																	   .FirstOrDefault();
			}
			if (maxShipmentReward != null)
			{
				//Remove all other shipment rewards from promotions
				foreach (var toRemoveReward in shipmentRewards.Where(x => x != maxShipmentReward))
				{
					toRemoveReward.Promotion.Rewards.Remove(toRemoveReward);
				}
			}

			return retVal.Where(x => x.Rewards.Count() > 0).ToArray();
             * */
            return records;
		}
        /// <summary>
        /// Filters the promotions.
        /// </summary>
        /// <param name="evaluationContext">The evaluation context.</param>
        /// <param name="records">The records, must be sorted in the order they are applied.</param>
        /// <returns></returns>
		public PromotionRecord[] FilterPromotions(IPromotionEvaluationContext evaluationContext, PromotionRecord[] records)
		{
            // applied global promotion, set to empty at the beginning
            var appliedGlobalPromotionId = String.Empty;
            var appliedRecords = new List<PromotionRecord>();

            foreach (var record in records)
            {
                if (appliedGlobalPromotionId == String.Empty)
                {
                    if (record.Reward.Promotion.ExclusionTypeId == (int)ExclusivityType.Global)
                    {
                        // set promotion id so we can filter all the rest of promotions
                        appliedGlobalPromotionId = record.Reward.Promotion.PromotionId;
                    }

                    appliedRecords.Add(record);
                }
                else // remove the rest of promotion records unless it was generated by the applied global promotion
                {
                    if (record.Reward.Promotion.PromotionId == appliedGlobalPromotionId)
                        appliedRecords.Add(record);
                }
            }

            return appliedRecords.ToArray();
		}
예제 #6
0
        /// <summary>
        /// Filters the promotions.
        /// </summary>
        /// <param name="evaluationContext">The evaluation context.</param>
        /// <param name="records">The records, must be sorted in the order they are applied.</param>
        /// <returns></returns>
        public PromotionRecord[] FilterPromotions(IPromotionEvaluationContext evaluationContext, PromotionRecord[] records)
        {
            var appliedRecords = new List <PromotionRecord>();

            var groups = new Dictionary <string, string>();

            foreach (var record in records)
            {
                if (!groups.ContainsKey(record.PromotionType)) // we already have exclusive withing a current group, so ignore
                {
                    if (record.Reward.Promotion.ExclusionTypeId == (int)ExclusivityType.Group)
                    {
                        groups.Add(record.PromotionType, record.Reward.Promotion.PromotionId);
                    }

                    appliedRecords.Add(record);
                }
                else // remove the rest of promotion records unless it was generated by the applied group promotion
                {
                    if (groups.ContainsValue(record.Reward.Promotion.PromotionId))
                    {
                        appliedRecords.Add(record);
                    }
                }
            }

            return(appliedRecords.ToArray());
        }
		public void RegisterToUsePromotion(IPromotionEvaluationContext context, Promotion promotion)
		{
			var promotionUsage = new PromotionUsage
			{
				CouponCode = context.CouponCode,
				MemberId = context.CustomerId,
				PromotionId = promotion.PromotionId,
				OrderGroupId = ((OrderGroup)context.ContextObject).OrderGroupId
			};

            _marketingRepository.Add(promotionUsage);

            _marketingRepository.UnitOfWork.Commit();
		}
        public void RegisterToUsePromotion(IPromotionEvaluationContext context, Promotion promotion)
        {
            var promotionUsage = new PromotionUsage
            {
                CouponCode   = context.CouponCode,
                MemberId     = context.CustomerId,
                PromotionId  = promotion.PromotionId,
                OrderGroupId = ((OrderGroup)context.ContextObject).OrderGroupId
            };

            _marketingRepository.Add(promotionUsage);

            _marketingRepository.UnitOfWork.Commit();
        }
		public Model.Promotion[] EvaluatePromotions(IPromotionEvaluationContext context)
		{
			return _evaluator.EvaluatePromotion(context);
		}
		public Promotion[] EvaluatePromotion(IPromotionEvaluationContext context)
		{
            if (!(context.ContextObject is Dictionary<string, object>))
                throw new ArgumentException("context.ContextObject must be a Dictionary");

			var query = GetPromotions();
			var utcnow = DateTime.UtcNow;

			switch (context.PromotionType)
			{
				case PromotionType.CatalogPromotion:
					query = query.OfType<CatalogPromotion>();
					break;
				case PromotionType.ShipmentPromotion:
				case PromotionType.CartPromotion:
					query = query.OfType<CartPromotion>();
					if (!string.IsNullOrEmpty(context.Store))
					{
						query = query.Cast<CartPromotion>().Where(x => x.StoreId == context.Store);

					}
					break;
			}

            // sort promotions by type and priority
            query = query.OrderByDescending(x => x.GetType().Name).ThenByDescending(x => x.Priority);

			//filter by date expiration
            query = query.Where(x => x.Status.Equals(PromotionStatus.Active.ToString()) && (x.StartDate == null || utcnow >= x.StartDate) && (x.EndDate == null || x.EndDate >= utcnow));

			//Evaluate query
			var promotions = query.ToArray();
			Func<Promotion, bool> isValidCouponPredicate = x => false;
			//filter by entered coupons 
            if (!string.IsNullOrEmpty(context.CouponCode))
            {
                //check coupon code if specified coupon set for promotion
				isValidCouponPredicate = x =>
                    {
                        var coupons = new string[] { };
                        if (x.CouponId != null)
                        {
                            coupons = _repository.Coupons.Where(c => c.CouponId == x.CouponId).Select(c => c.Code).ToArray();
                        }
                        else if (x.CouponSetId != null)
                        {
                            coupons = _repository.CouponSets.Expand(c => c.Coupons)
                                                 .Where(c => c.CouponSetId == x.CouponSetId)
                                                 .SelectMany(c => c.Coupons)
                                                 .Select(c => c.Code).ToArray();
                        }

                        var retVal = coupons.Contains(context.CouponCode);

                        return retVal;
                    };
            }

			//Allow only those rewards that do not require coupons or check if coupon is valid
			promotions = promotions.Where(x => isValidCouponPredicate(x) || string.IsNullOrEmpty(x.CouponId) && string.IsNullOrEmpty(x.CouponSetId)).ToArray();
		
			//Filter promotion by usage limit
			promotions = promotions.Where(x => x.TotalLimit <= 0 || _usageProvider.GetTotalUsageCount(x.PromotionId) < x.TotalLimit).ToArray();
			promotions = promotions.Where(x => x.PerCustomerLimit <= 0 || _usageProvider.GetUsagePerCustomerCount(x.PromotionId, context.CustomerId) < x.PerCustomerLimit).ToArray();
			
			//TODO: Filter by customer segments
						
			//Evaluate promotions
			Func<Promotion, bool> conditionPredicate = x =>
				{
					var condition = DeserializeExpression<Func<IEvaluationContext, bool>>(x.PredicateSerialized);
					return condition(context);
				};
			
			promotions = promotions.Where(conditionPredicate).ToArray();
			return promotions;
		}
 public Model.Promotion[] EvaluatePromotions(IPromotionEvaluationContext context)
 {
     return(_evaluator.EvaluatePromotion(context));
 }
        public Promotion[] EvaluatePromotion(IPromotionEvaluationContext context)
        {
            if (!(context.ContextObject is Dictionary <string, object>))
            {
                throw new ArgumentException("context.ContextObject must be a Dictionary");
            }

            var query  = GetPromotions();
            var utcnow = DateTime.UtcNow;

            switch (context.PromotionType)
            {
            case PromotionType.CatalogPromotion:
                query = query.OfType <CatalogPromotion>();
                break;

            case PromotionType.ShipmentPromotion:
            case PromotionType.CartPromotion:
                query = query.OfType <CartPromotion>();
                if (!string.IsNullOrEmpty(context.Store))
                {
                    query = query.Cast <CartPromotion>().Where(x => x.StoreId == context.Store);
                }
                break;
            }

            // sort promotions by type and priority
            query = query.OrderByDescending(x => x.GetType().Name).ThenByDescending(x => x.Priority);

            //filter by date expiration
            query = query.Where(x => x.Status.Equals(PromotionStatus.Active.ToString()) && (x.StartDate == null || utcnow >= x.StartDate) && (x.EndDate == null || x.EndDate >= utcnow));

            //Evaluate query
            var promotions = query.ToArray();
            Func <Promotion, bool> isValidCouponPredicate = x => false;

            //filter by entered coupons
            if (!string.IsNullOrEmpty(context.CouponCode))
            {
                //check coupon code if specified coupon set for promotion
                isValidCouponPredicate = x =>
                {
                    var coupons = new string[] { };
                    if (x.CouponId != null)
                    {
                        coupons = _repository.Coupons.Where(c => c.CouponId == x.CouponId).Select(c => c.Code).ToArray();
                    }
                    else if (x.CouponSetId != null)
                    {
                        coupons = _repository.CouponSets.Expand(c => c.Coupons)
                                  .Where(c => c.CouponSetId == x.CouponSetId)
                                  .SelectMany(c => c.Coupons)
                                  .Select(c => c.Code).ToArray();
                    }

                    var retVal = coupons.Contains(context.CouponCode);

                    return(retVal);
                };
            }

            //Allow only those rewards that do not require coupons or check if coupon is valid
            promotions = promotions.Where(x => isValidCouponPredicate(x) || string.IsNullOrEmpty(x.CouponId) && string.IsNullOrEmpty(x.CouponSetId)).ToArray();

            //Filter promotion by usage limit
            promotions = promotions.Where(x => x.TotalLimit <= 0 || _usageProvider.GetTotalUsageCount(x.PromotionId) < x.TotalLimit).ToArray();
            promotions = promotions.Where(x => x.PerCustomerLimit <= 0 || _usageProvider.GetUsagePerCustomerCount(x.PromotionId, context.CustomerId) < x.PerCustomerLimit).ToArray();

            //TODO: Filter by customer segments

            //Evaluate promotions
            Func <Promotion, bool> conditionPredicate = x =>
            {
                var condition = DeserializeExpression <Func <IEvaluationContext, bool> >(x.PredicateSerialized);
                return(condition(context));
            };

            promotions = promotions.Where(conditionPredicate).ToArray();
            return(promotions);
        }