Promotions BETA latest changes

After upgrading EPiServer Commerce from 9.6.0 to 9.8.1 I got some breaking changes in new Promotions. I figured out how to make it work, but I am not sure if it's correct way. 

First of all, implementing PromotionProcessor by inheriting from PromotionProcessorBase<> now has different abstract method:

RewardDescription Evaluate(IOrderForm orderForm, AdditionalDiscountPromoData promotionData, PromotionProcessorContext context)

Now it returns RewardDescription instead of IPromotionResult. It seems that I can keep my logic, but have to construct new RewardDescription. It has nice factory methods for different cases:

  • CreatePercentageReward
  • CreateFreeItemReward
  • CreateMoneyReward

Only missing method is when constructing response for no reward (not fulfilled). So I am doing it myself:

private RewardDescription NoReward(PromotionData promotionData)
{
	return new RewardDescription(
			FulfillmentStatus.NotFulfilled, 
			Enumerable.Empty<AffectedItem>(), 
			promotionData, 
			unitDiscount: 0,
			unitPercentage: 0, 
			rewardType: RewardType.None, 
			description: "No discount applied");
}

The resulting code is here:

public override RewardDescription Evaluate(
	IOrderForm orderForm, 
	AdditionalDiscountPromoData promotionData,
	PromotionProcessorContext context)
{
	var cart = context.OrderGroup as Cart;
	if (cart == null)
	{
		return NoReward(promotionData);
	}

	var additionalDiscountPercent = (decimal)(cart[Constants.AdditionalDiscountPercentMetaField] ?? 0.0m);
	if (additionalDiscountPercent == 0)
	{
		return NoReward(promotionData);
	}

	if (!orderForm.Shipments.Any()) // Shipment gets removed when no items in the cart
	{
		return NoReward(promotionData);
	}

	var affectedItems = orderForm.Shipments
								.First()
								.LineItems
								.Select(lineItem => new AffectedItem(LineItemContentLink(lineItem), lineItem));

	return RewardDescription.CreatePercentageReward(
								FulfillmentStatus.Fulfilled, 
								affectedItems, 
								promotionData, 
								additionalDiscountPercent, 
								description: $"{additionalDiscountPercent} % discount applied to order");
}

private ContentReference LineItemContentLink(ILineItem lineItem)
{
	return _referenceConverter.GetContentLink(lineItem.Code);
}

private RewardDescription NoReward(PromotionData promotionData)
{
	return new RewardDescription(
			FulfillmentStatus.NotFulfilled, 
			Enumerable.Empty<AffectedItem>(), 
			promotionData, 
			unitDiscount: 0,
			unitPercentage: 0, 
			rewardType: RewardType.None, 
			description: "No discount applied");
}

This works, but has some issues.

Promtions doesn't get removed from DB when you change promotion amount - old promotion's SavedAmount gets set to 0.

Also when you remove an item form the cart, shipment gets removed too - so you have to always check if Shipment exists in Evaluate method.

The questions are:

- How to make promotions get removed from DB? While it functions properly, it keeps unnecessary records in DB.

- Why shipment gets removed after all items removed from cart?

- Could RewardDescription.NoReward() factory method get added to newer version of Promotions?

#144769 Feb 18, 2016 15:10
  • 1. Next release should remove the old promotions, did not have time to make in 9.8.1

    2. How are you removing the item from cart?  

    3.  Yes we can add the method or extension method

    #144771 Feb 18, 2016 15:32
  • 2. I am removing it with such method:

    public void RemoveLineItem(string code)
    {
      LineItem lineItem = CartExtensions.GetLineItem(this.CartHelper.Cart, code);
      if (lineItem == null)
    	return;
      PurchaseOrderManager.RemoveLineItemFromOrder((OrderGroup) this.CartHelper.Cart, lineItem.LineItemId);
      this.ValidateCart(); // Runs validate workflow
      this.CartHelper.Cart.AcceptChanges();
    }

    #144773 Feb 18, 2016 15:36
First   1   Last