public void AddCouponCode_WhenCouponCodeIsNotAppliedToPromotion_ShouldReturnFalse() { var couponCode = "IDONTEXIST"; _promotionEngineMock .Setup(x => x.Run(It.IsAny <IOrderGroup>(), It.IsAny <PromotionEngineSettings>())) .Returns(new[] { RewardDescription.CreatePercentageReward(FulfillmentStatus.Fulfilled, null, new PromotionForTest(), 10, string.Empty) }); var result = _subject.AddCouponCode(_cart, couponCode); Assert.False(result); }
public void AddCouponCode_WhenPromotionWithCodeExists_ShouldReturnTrue() { var couponCode = "IBUYALOT"; _promotionEngineMock .Setup(x => x.Run(It.IsAny <IOrderGroup>(), It.IsAny <PromotionEngineSettings>())) .Returns(new[] { RewardDescription.CreatePercentageReward(FulfillmentStatus.Fulfilled, null, new PromotionForTest { Coupon = new CouponData { Code = couponCode } }, 10, string.Empty) }); var result = _subject.AddCouponCode(_cart, couponCode); Assert.True(result); }
protected override RewardDescription Evaluate(VisitorGroupDiscountPromotion promotionData, PromotionProcessorContext context) { // get all items from the cart var lineItems = this.GetLineItems(context.OrderForm).ToList(); // get any codes that the promotion applies to (check visitor group to filter) Guid visitorGroupGuid; Guid.TryParse(promotionData.VisitorGroup, out visitorGroupGuid); var user = HttpContext.Current.User; var visitorGroupHelper = new VisitorGroupHelper(this._visitorGroupRoleRepository.Service); var visitorGroup = this._visitorGroupRepository.Service.Load(visitorGroupGuid); var isVisitorGroup = visitorGroupHelper.IsPrincipalInGroup(user, visitorGroup.Name); var applicableCodes = isVisitorGroup ? this._targetEvaluator.Service.GetApplicableCodes(lineItems, promotionData.Entries, true).ToList() : new List <string>(); // check to see whether the promotion has been fulfilled var fulfillmentStatus = this._fulfillmentEvaluator.Service .GetStatusForBuyFromCategoryPromotion(applicableCodes, lineItems); // get redemption status var redemptions = new List <RedemptionDescription>(); var affectedEntries = context.EntryPrices.ExtractEntries(applicableCodes, 1); if (affectedEntries != null) { redemptions.Add(this.CreateRedemptionDescription(affectedEntries)); } return(RewardDescription.CreatePercentageReward( fulfillmentStatus, redemptions, promotionData, promotionData.Percentage, fulfillmentStatus.GetRewardDescriptionText(this._localizationService.Service))); }
/* RewardDescription is "checking" whether the promotion was fulfilled (or not, or partially), * ...which items the promotion was applied to... * ...the fake-cart is taken care of) * PromotionProcessorBase has one abstract method to be implemented, Evaluate. * ...the method is supplied with a PromotionData, and a PromotionProcessorContext object * ...that contains information about the current order/fakeCart. */ protected override RewardDescription Evaluate( // note: it's OrderForm now... MyPercentagePromotion promotionData // the model --> look in the UI to see the properties , PromotionProcessorContext context) { /* A reward description contains information about if and how a reward is applied. * ...some properties are: * - A list of redemption descriptions, one for each of the maximum amount of redemptions * ...that could be applied to the current order. * This does not have to take redemption limits into consideration, that is handled by the * promotion engine. * - A reward type. Depending on the type, the promotion value is read from the properties * UnitDiscount, Percentage or Quantity. * - A status flag. Indicates if a promotion is not, partially, or fully fulfilled. * - A saved amount. The amount by which this reward reduces the order cost. * Is set by the promotion engine; should not be set in the promotion processor*/ IOrderForm orderForm = context.OrderForm; // OrderForm now pops in with the context //context. // lots of things IEnumerable <ILineItem> lineItemsCheck = orderForm.GetAllLineItems(); IEnumerable <ILineItem> lineItems = GetLineItems(context.OrderForm); #region Just Checking //var e = _contentLoader.Get<EntryContentBase>(item0); //should check if it's applicable... at all //var li = _orderFactory.Service.CreateLineItem(e.Code); //li.Quantity = 1; //li.PlacedPrice = 15; //orderForm.Shipments.First().LineItems.Add(li); #endregion // GetFulfillmentStatus - extension method FulfillmentStatus status = promotionData.MinNumberOfItems.GetFulfillmentStatus( orderForm, _targetEvaluator, _fulfillmentEvaluator); List <RewardDescription> rewardDescriptions = new List <RewardDescription>(); List <RedemptionDescription> redemptionDescriptions = new List <RedemptionDescription>(); #region NewStuff // The below does not see the cart, it's for landing pages for the Promotion itself (rendering) PromotionItems promoItems = GetPromotionItems(promotionData); // gets null var condition = promotionData.PercentageDiscount; // ...in the model var targets = promotionData.DiscountTargets; // get one in any case, points to what's at "promo" var skuCodes = _targetEvaluator.GetApplicableCodes( lineItems, targets.Items, targets.MatchRecursive); // get one if kicked in, 0 if not var fulfillmentStatus = _fulfillmentEvaluator.GetStatusForBuyQuantityPromotion( skuCodes , lineItems , promotionData.MinNumberOfItems.RequiredQuantity , promotionData.PartialFulfillmentNumberOfItems); // Just checking // The promotion engine creates a "price matrix" for all items in the order form. // OrderFormPriceMatrix, is accessible through the EntryPrices property // of the PromotionProcessorContext object. // PromotionProcessorContext is passed to the Evaluate method as one of the arguments. // ...the matrix holds "codes" and quantity // The second ExtractEntries call starts to receive entries where the first call ended. // ... makes it easy to create several redemptions by calling ExtractEntries in a loop, // ... and create one RedemptionDescription inside the loop. // The price matrix has one public method (ExtractEntries) // ... two overloads, both overloads takes entry codes and quantity as parameters. // ... one contains an action for getting the entries in a specific order. // ... if no specific order is specified, MostExpensiveFirst is used. var affectedEntries = context.EntryPrices.ExtractEntries( skuCodes, 1); // get one if it kicks in, null if not if (affectedEntries != null) { IEnumerable <PriceEntry> priceEntries = affectedEntries.PriceEntries; foreach (var item in priceEntries) { var qty = item.Quantity; var price = item.Price; var calc = item.CalculatedTotal; // involves the Qty var actuals = item.ActualTotal; // includes rounding } } // could have a look here switch (fulfillmentStatus) { case FulfillmentStatus.NotFulfilled: break; case FulfillmentStatus.PartiallyFulfilled: break; case FulfillmentStatus.Fulfilled: break; case FulfillmentStatus.CouponCodeRequired: break; case FulfillmentStatus.Excluded: break; case FulfillmentStatus.VisitorGroupRequired: break; case FulfillmentStatus.RedemptionLimitReached: break; case FulfillmentStatus.NoMoneySaved: break; case FulfillmentStatus.InvalidCoupon: break; case FulfillmentStatus.InvalidCombination: break; case FulfillmentStatus.MissingVisitorGroup: break; case FulfillmentStatus.NoRedemptionRemaining: break; case FulfillmentStatus.Ineffective: break; default: break; } // ... an extension method return(RewardDescription.CreatePercentageReward( fulfillmentStatus , GetRedemptions(skuCodes, promotionData, context) , promotionData , promotionData.PercentageDiscount.Percentage //, fulfillmentStatus.GetRewardDescriptionText() , fulfillmentStatus.GetRewardDescriptionText() + " : " + promotionData.Description + " : " )); #endregion #region Older stuff and debug - no show #region Older not in use //RewardDescription rewardDescription = new RewardDescription(); //var codes = _targetEvaluator.GetApplicableCodes(lineItems,) //_fulfillmentEvaluator.GetStatusForBuyQuantityPromotion( // ) #endregion // new stuff #region Previous version //if (status.HasFlag(FulfillmentStatus.Fulfilled)) //{ // return RewardDescription.CreateMoneyOrPercentageRewardDescription( // status, // redemptionDescriptions, // promotionData, // promotionData.PercentageDiscount, // context.OrderGroup.Currency, // "Custom promotion fulfilled"); // should have a more flexible way... GetDescription() //} //else //{ // return RewardDescription.CreateNotFulfilledDescription( // promotionData, FulfillmentStatus.NotFulfilled); //} #endregion #region Debug //RedemptionDescription rFirst; //redemptionDescriptions.Add(CreateRedemptionDescriptionText(orderForm)); // below "if-construct" is for debug //if (promotionData.PercentageDiscount <= 0) // ... return "sorry, no discount" //{ // return RewardDescription.CreatePercentageReward( // FulfillmentStatus.NotFulfilled, // redemptionDescriptions, // promotionData, // 0, // CreateRewardDescriptionText(redemptionDescriptions.First(), FulfillmentStatus.NotFulfilled, promotionData)); // /*RewardDescription.CreateMoneyOrPercentageRewardDescription(FulfillmentStatus.NotFulfilled,r,promotionData,null);*/ //} //IEnumerable<ContentReference> targetItems = promotionData.DiscountTargets.Items.ToList(); // set by the Promo-UI //bool matchRecursive = true; // walking down the catalog hierarchy //var lineItems = GetLineItems(orderForm); // "GetLineItems" - in the base class (PromotionProcessorBase) //var affectedItems = _targetEvaluator.GetApplicableItems(lineItems, targetItems, matchRecursive); // in CollectionTargetEvaluator //var affectedItems = _targetEvaluator.GetApplicableCodes(orderForm.GetAllLineItems(), targetItems, false); // small class --> just to get the status by the settings //var status = FulfillmentEvaluator.GetStatusForBuyQuantityPromotion(affectedItems.Select(x => x.LineItem) // , promotionData.MinNumberOfItems, promotionData.PartialFulfillmentNumberOfItems); // in the model //var s = FulfillmentEvaluator. //FulfillmentEvaluator ff = new FulfillmentEvaluator(); //if (rewardDescriptions.Any()) //{ // return rewardDescriptions.First(); //} //else //{ // return null; //} /*return RewardDescription.CreateMoneyOrPercentageRewardDescription( * status, * affectedItems, * promotionData, * promotionData.PercentageDiscount, * GetRewardDescriptionText(affectedItems, status, promotionData));*/ #endregion #endregion } // end RewardDescription