We are working for a client who uses cost based shipping. This means that when a customer's subtotal is under $50, the shipping is $5. If it's under $100, the shipping is $10.
The issue I'm having is related to discounts. Say I apply an order level discount first. The order level discount gives you $60 off on orders over $100.
So, in this case, your cart subtotal is $99. $60 off makes it now $39. If we apply the above rules for cost based shipping, your shipping cost was originally $10, but now it is $5. Here is what it looks like before and after discount.
Order Level Discount: $0
Shipping Discount: $0
Order Level Discount: ($60)
This is all fine and dandy until you add a shipping discount (and it does not matter how they're prioritized, I have tried that). If I have a shipping discount for free shipping, then NO MATTER WHAT, the returned SavedAmount on the RewardDescription for that promotion is always what it was before the shipping bucket changed before any discounts were applied. Here is an example of before and after (both have the order level discount applied).
Shipping Discount: ($10) [THIS VALUE NEEDS TO BE $5, I need to pull $5 from the SavedAmount on the RewardDescription object]
The "after" directly above this paragraph should show a shipping discount of $5. Not $10. How can I make the promotions completely apply all other discounts before the shipping ones kick in? I need the shipping discounts to apply to the new shipping value that we fall into due to the cost based shipping table. Shipping discounts always need to be prioritized last, and all other discounts need to completely resolve as well. You can see the math doesn't add up in my last example. The customer is going to think the total should be $34, but that's wrong. EPiServer is at least getting the final total right, it's just the shipping discount actually applied is wrong.
Did I understand it correctly that the cost based shipping is applied through the promotion system as well? Or is it applied in another manner? I'm thinking about the first example where the the shipping cost goes from $10 to $5 but the Shipping Discount remains at $0.
The cost based shipping happens in a custom implementation of ShippingGateway, and that kicks in after promotions are applied to the order.
That seems to be your issue in that case. If the order comes into the PromotionEngine with a $10 shipping cost there is not much that it can do but give $10 discount if the intent is to give free shipping.
Applying custom discounts to an order after the promotion engine has already run makes it difficult to consistently make the correct discount decision at that stage. But I understand that in this case it is also difficult to assert the shipping cost before knowing the order total.
Your specific example of offering free shipping is solveable by adding additional logic to your custom shipping method implementation. But another case - giving 50% discount on your custom discount would be a bit harder to manage without taking another approach.
I only have the info you gave in this thread, so this assertion might not be the best given all your business needs. But my take is that it would be best to have another shipping method that returns the "base" shipping cost, then the cost based shipping part of it can be set up as a normal discount. There are built in discount types that can do this. Then the only issue would be prioratizing them in the correct order.