Proper way to implement custom shipping discount promotions

Vote:
 

Hello all, me again,

I am struggling to get my custom shipping discount promotion to work. It works great when an order has only one form, but I am struggling to get it to work with an order that has multiple forms.

The issue I am running into is that the discount is creating multiple reward descriptions due to the multiple forms, but I need the discount to only have one reward if just one of the forms fulfills the promotion.

Right now I have overrided the GetFulfillmentStatus and CreateRewardDescription to use my custom logic. In GetFulfillmentStatus, if the form does not meet the criteria i return not fulfilled, and if it does I return fulfilled, but the discount only works if every form is fulfilled. How can I get it to work when just one form is fulfilled?

Also is there any deeper documention on proper way to implement custom shipping discounts?

Thank you,

Brian

#194717
Edited, Jun 28, 2018 18:57
Vote:
 

You can create multiple RewardDescription, it's their statuses (Fulfilled or not) that matter. I'm not sure what would be the problem if, say, you return 2 RewardDescription but only one is Fulfilled?

#194718
Jun 28, 2018 20:12
Vote:
 

When it is not fulfilled I return a RewardDescription.CreateNotFulfilledDescription, and when it is fulfilled I return RewardDescription.CreatePercentageReward. When RewardDescription.CreateNotFulfilledDescription is returned once even though RewardDescription.CreatePercentageReward has been returned for a different form, the discount does not get applied.

#194719
Jun 28, 2018 20:16
Vote:
 

That is ... strange. Promotion engine should work perfectly with multiple forms. Can you post your processor here? 

#194721
Jun 28, 2018 20:35
Vote:
 
protected override PromotionItems GetPromotionItems(CustomerClubShippingDiscount promotionData)
        {
            return _baseProcessor.GetPromotionItems(promotionData);
        }
 
protected override RewardDescription CreateRewardDescription(CustomerClubShippingDiscount promotionData, FulfillmentStatus fulfillmentStatus, IEnumerable<RedemptionDescription> redemptions, PromotionProcessorContext context)
	{
		if (fulfillmentStatus == FulfillmentStatus.Fulfilled)
		{
			if (promotionData.Discount.GetRewardType() == RewardType.Percentage)
			{
				return RewardDescription.CreatePercentageReward(fulfillmentStatus, redemptions, promotionData, promotionData.Discount.Percentage, "Spend amount, get shipping discount.");
			}

			return RewardDescription.CreateMoneyReward(fulfillmentStatus, redemptions, promotionData, promotionData.Discount.GetDiscountAmountForCurrency(Currency.USD), "Spend amount, get shipping discount.");
		}
		else
		{
			return RewardDescription.CreateNotFulfilledDescription(promotionData, fulfillmentStatus);
		}
	}

	protected override FulfillmentStatus GetFulfillmentStatus(CustomerClubShippingDiscount promotionData, PromotionProcessorContext context)
	{
		/* Some custom business logic was here, can return FulfillmentStatus.NotFulfilled */
		
		//check if spend amount has been met
		var fulfillmentStatus = _fulfillmentEvaluator.GetStatusForSpendAmountPromotion(
			context.CurrentOrderFormSubTotal,
			context.OrderGroup.Currency,
			promotionData.Condition.Amounts,
			promotionData.Condition.PartiallyFulfilledThreshold);
		if (fulfillmentStatus != FulfillmentStatus.Fulfilled)
		{
			return FulfillmentStatus.NotFulfilled;
		}

		//check for shipping method
		var methodId = context.OrderGroup.GetFirstShipment().ShippingMethodId;
		if (!promotionData.ShippingMethods.Contains(methodId))
		{
			return FulfillmentStatus.NotFulfilled;
		}

		/* Some custom business logic was here, can return FulfillmentStatus.NotFulfilled */

		return FulfillmentStatus.Fulfilled;

	}
}

I stripped out some sensitive business logic, but all it would do is return NonFulfilled if some conditions were not met.

My main issue is around if the spend amount has been met. On my order examples I have 4 forms, 3 will fail to meet the amount and 1 does meet it, but the discount does not get applied.

#194722
Jun 28, 2018 20:51
Vote:
 

IPromotionEngine.Run will return a list of RewardDescription for each IOrderForm for each promotion, so it works perfectly on multiple forms scenario. However your processor has to aware of that. In your case, you are using this

context.OrderGroup.GetFirstShipment().ShippingMethodId;

which is not correct. You should get the shipment of the current order form (context.OrderForm.Shipment().First()) instead 

#194735
Jun 29, 2018 13:33
Vote:
 

Quan Mai,

I think I found the issue I am having. The way we use epi is pretty heavly customized and for this kind of order we have multiple order forms, but only one form has a shipment on it. So the form that was meeting the spend amount wouldnt actually get a shipping discount because it does not have a shipment on it.

This further complicates things because my first goal was to try to get the discounted sub total of the whole order group and use that to check the spend amount, but as I understand you cannot do that in the promotion engine.

#194739
Jun 29, 2018 15:45
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.