SaaS CMS has officially launched! Learn more now.

Episerver 10: Combining multiple promotion coupon in the cart throws error

Vote:
 

We have two coupons,

  1. one 30% of a lineItem - lineitem coupon
  2. One is 100% off on shipping charge. - shipping coupon

We have total based shipping. So this is causing an issue.

When we apply both this coupon to the cart we get internal server error. Looking more details into error, it seems this is what is happening.

Total before discount $53.44 / This puts you in shipping cost bracket of $9.99 

So when you apply SHIP2 coupon the shipment discount = 9.99 

Your total shipping charge = 9.99 -9.99 = 0.00 

Applying coupon MPMPA30 gives you 30% off. So now your total is 53.44 - 16.03 = 37.41 

So you are now in shipping cost bracket of 5.99 

But the SHIP2 discount was already calculated as 9.99 

So shipment charge = 5.99-9.99 = $-4.00 (negative) This throws error

Is there any way you can decide the priority/sequence in which the coupons are applied, with epi 10 promotion module?

#181154
Aug 09, 2017 19:56
Vote:
 

Hi,

You can set the priority of promotions, so promotion with coupon A can be processed in promotion with coupon B.

However this sounds like a bug for me. What version are you using? Would you mind trying Commerce 10.8.0 to see if it's fixed? 

#181157
Aug 10, 2017 0:28
Vote:
 

Hi Quan!

For this particular project we are using Episerrver Commerce 10.4.3

How can we set the promotion priority in new promotion module?

Do you remember if this is a known bug, and if it fixed in a later version?

#181174
Aug 10, 2017 16:09
Vote:
 

Sapna,

This page explains how a merchandiser would apply discount priorities: http://webhelp.episerver.com/latest/commerce/marketing/prioritizing-discounts.htm.

#181175
Aug 10, 2017 16:52
Vote:
 

Thank you Bob!

That helped.

#181177
Aug 10, 2017 18:28
Vote:
 

Hi Quan

So per Bob above I did try to adjust the coupon priority and it worked for us.

But then we upgraded to 10.8.0 and it stopped working again. As you mentioned above 10.8.0 could fix it. It seems liek it broke it rather. Any insight on this. 

Our customer often use promotions in combination with shipping promotions. And they have order total range based shipping charges.

Meanining 0-25 order total - Shipping charge = 5.99
25.01-50  order total - Shipping charge = 9.99

50.01-75  order total - Shipping charge = 14.99

75+  order total - Shipping charge = Free

So if one promotion  changes your shipping threshold, and you are using free shipping coupon it breaks the cart.

 

#182510
Sep 21, 2017 20:54
Vote:
 

Could you tell me how it breaks the cart? Which promotions are applied and what items do you have in the cart etc? 

#182515
Sep 21, 2017 22:59
Vote:
 

I have given the details in the first discussion on this thread. Please let me know if you need anything else

#182516
Sep 21, 2017 23:06
Vote:
 

It sounds very much as the shipping discount has higher priority than the lineitem discount. Is that the case perhaps? 

#182528
Sep 22, 2017 8:41
Vote:
 

It is not the case. We moved the shipping discount all the way down.

#182556
Sep 22, 2017 15:42
Vote:
 

Hi all

This is still an issue for us. We created a ticket but couldn't get this resolved yet. Any of you have any more insights on this?

We should be able to use shipping coupon with other promotions. 

Please note: that is works fine. Except that when the shiiping charge changes after promotion 1 is applied, the cart breaks. This is due to tiered shipping cahrge. We have shipping based on order total.

My quick question is - how are you guys able to verify the priority of the shipping coupon is workign fine when the shipping charge is a fixed amount. The ticket is claiming the issue is in our code. If that was the case we would be able to debug it. 

The cart fails at the first instance of tryign to fetch cart total. 

Really really appreciate any help.

#183505
Oct 16, 2017 17:21
Vote:
 

Hm, could you post the exception you're getting? Even if it's internal epi

#183507
Oct 16, 2017 18:21
Vote:
 

Yes offcourse:

System.ComponentModel.DataAnnotations.ValidationException: Invalid shipping cost for order form
at EPiServer.Commerce.Marketing.Internal.MoneyExtensions.Validate(Money money, String validationErrorMessage)
at EPiServer.Commerce.Order.Calculator.DefaultShippingCalculator.ValidateShippingCostForOrderForm(Money money)
at EPiServer.Commerce.Order.Calculator.DefaultShippingCalculator.GetShippingCost(IOrderForm orderForm, IMarket market, Currency currency)
at EPiServer.Commerce.Order.Calculator.DefaultShippingCalculator.<>c__DisplayClass8_0.<CalculateShippingCost>b__0(IOrderForm form)
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.Sum(IEnumerable`1 source)
at EPiServer.Commerce.Order.Calculator.DefaultShippingCalculator.CalculateShippingCost(IOrderGroup orderGroup, IMarket market, Currency currency)
at EPiServer.Commerce.Order.Calculator.DefaultShippingCalculator.GetShippingCost(IOrderGroup orderGroup, IMarket market, Currency currency)
at EPiServer.Commerce.Order.Calculator.DefaultOrderGroupCalculator.CalculateTotal(IOrderGroup orderGroup)
at EPiServer.Commerce.Order.Calculator.DefaultOrderGroupCalculator.GetTotal(IOrderGroup orderGroup)
at EPiServer.Commerce.Order.IOrderGroupExtensions.GetTotal(IOrderGroup orderGroup)
at Whereoware.WOWCCMS.Models.ViewModels.CartModel.get_CartTotalPrice()
at ASP._Page_Views_Shared_Orders__OrderSummary_cshtml.Execute()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.HtmlHelper.RenderPartialInternal(String partialViewName, ViewDataDictionary viewData, Object model, TextWriter writer, ViewEngineCollection viewEngineCollection)
at System.Web.Mvc.Html.PartialExtensions.Partial(HtmlHelper htmlHelper, String partialViewName, Object model, ViewDataDictionary viewData)
at ASP._Page_Views_CheckoutPage_PaymentMethod_cshtml.Execute()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy()
at System.Web.Mvc.WebViewPage.ExecutePageHierarchy()
at System.Web.WebPages.StartPage.RunPage()
at System.Web.WebPages.StartPage.ExecutePageHierarchy()
at System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage)
at System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance)
at System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer)
at System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList`1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<>c__DisplayClass2b.<BeginInvokeAction>b__1c()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncVoid`1.CallEndDelegate(IAsyncResult asyncResult)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase`1.End()
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

#183508
Oct 16, 2017 18:24
Vote:
 

How have you implemented the tiered shipping cost?

#183556
Oct 17, 2017 14:16
Vote:
 

We are doing the normal epi recommended custom shipping. Where we have shipping charges based on order total. 

This is how it looks in commerce manager in the parameters tab

https://www.screencast.com/t/aO424XkU69A

And this is how we retrive the shipping charge from our custom shipping method

//Getting the price involves invoking the appropriate shipping gateway
Type type = Type.GetType(sh.ShippingOptionRow.ClassName);
IShippingGateway provider = (IShippingGateway)Activator.CreateInstance(type);

decimal price = decimal.Zero;
string msg = string.Empty;

var rate = provider.GetRate(sh.ShippingMethodId, shipment as Shipment, ref msg);
if (rate != null)
price = rate.Money.Amount;
else
{
//Display error message
}

#183564
Oct 17, 2017 16:22
Vote:
 

I can't help but to wonder if Episerver really have intended and taken height for the shipping cost to be affected by promotions. I would assume not.

I don't think your problem has anything to do with the order/priority of the promotions.

You are expecting that your IShippingGateway gets called by the shipping promotion or just before all shipping promotions gets calculated, it doesn't.

My recommendation to you is to write your own custom shiping discount that calls your gateway.

#183566
Oct 17, 2017 16:40
Vote:
 

Well, what is happening is it is calling our shipping gateway. Because the shipping discount shown in the database is what it should be the charge for second tier shipping cost.

But then due to the priority of the promotions or the way they are applied the discount is higher than the actual shipping charge which becomes tier 1 after promotions 1 is applied.

Hmmm... I am not sure how to get this resolve. Everyone just tries to put the ball in others court. It is so difficult to convince anythign to epi, just cause we have one thing customized. 

#183567
Oct 17, 2017 16:49
Vote:
 

Still, my recommendation would be to write your own shipping promotion and promotion processor.

When that shipping processor is called it will have the discounted total in PromotionProcessorContext.CurrentOrderFormSubTotal, use that to calculate the correct discount for your tiered shipping.

Read more about how to do it here: https://world.episerver.com/documentation/developer-guides/commerce/marketing/custom-promotions/

#183623
Edited, Oct 18, 2017 13:59
Vote:
 

Is it possible to override just the Promotion processor?

Has anybody done that?

#183635
Oct 18, 2017 15:42
Vote:
 

It should be, as long as you specify a Priority that is high enough.

Sapna, if you asked a question and developer support didn't response with a satisfactory answer, let me know your ticket number and I'll follow up with them 

#183636
Oct 18, 2017 15:52
Vote:
 

Hi Quan!

If we do customise the shipping promotion processor, are we able to decide the priority of the promotion applied in there?

Or we need to override some other function for this. Because we strongly believe the issue is with the order in which the promotions are applied. 

Yes there has been no resolution so far. Or a satisfactory answer. Here is the ticket number - 78241

If you can please follow up that would be really great!

#183645
Oct 18, 2017 21:45
Vote:
 

If you have multiple processors which can handle the same promotion type, then the highest priority one will be selected. You can override the Priority property - the default one is 0 so if it's better than 0 it should be good.

I took a look at the ticket - such a long thread :). To follow up with support team I will have spend time reading and undertanding the issue. It might not be soon-ish - but I'll try :)

#183646
Oct 18, 2017 22:10
Vote:
 

I understand! Appreciate your help!

#183647
Oct 18, 2017 22:30
Vote:
 

Try overriding the DefaultShippingCalculator with overriding the method GetDiscountedShippingAmount as follows

 public Money GetDiscountedShippingAmount(IShipment shipment, IMarket market, Currency currency)
        {
            ParameterValidator.ThrowIfNull(() => shipment, shipment);
            ParameterValidator.ThrowIfNull(() => market, market);

            var cost = CalculateShippingCost(shipment, market, currency);
            var discount = new Money(shipment.TryGetDiscountValue(x => x.ShipmentDiscount), currency);
            if (cost - discount < 0)
            {
                return new Money(0, currency);
            }
            var result = cost - discount;
            ValidateShippingCostForShipment(result);

            return result;
        }
#183806
Oct 24, 2017 1:11
Vote:
 

Thank you Mark! That worked. 

FYI: we inheritted from DefaultShippingCalculator and IShippingCalculator. This way we could still use most of the base class functionality.

Also we had to do the above same logic in GetShippingCosts methods. That was throwing error as well. But then it worked just fine.

We also had to fake the display. As the ShippingDiscount was 9.99 and ShippingCarge was 5.99. But there were no errors and order total calculations were just fine.

Thank you for your help!

#185258
Nov 13, 2017 16:57
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.