I've a problem with the calculation of the shipping costs when adding a coupon.
A customer has following settings:
Shipping Provider: FreeOverAmount which is set at 50$.
Coupon: 10% off (Discount the price) and constraint "Not usuable with other coupons"
Scenario: You have a item total of 51$ (the shipping is free) then you add the coupon (new total is 45,9$) but shipping is still free - thats' wrong. Even if you reload (PrepareInvoice is called) it's wrong.
I've tried to solve it with adding some ExtendedData but in the QuoteShipment() the Items are somehow cached and not with the new ExtendedData which is added in the TryAward() off the OfferComponent.
Also saving the shipping (ClearShipmentRateQuotes and SaveShipmentRateQuote) again seems not to work (sometimes it works sometimes not - Caching issue?).
Also a Constraint which will re-add the shipping cost do not work (it's not getting saved?).
I also tried to do it before shipping and payment selection/saving with no success.
This is a problem with the order of things happening. The shipping is calculated before the coupon is added. Shipping charges become an actual line item and are looked at as a value with respect to the discount.
In your scenario, you are hoping the shipping provider will kick in and requote after the coupon has been applied. I never considered that use case (it sort of seems like a negative - like why would I add a coupon if it's possible that the amount of the shipping could actually cause the price to increase after adding the coupon).
If you need this, you could create a custom offer constraint that recalculate the shipping cost based off the free over amount provider ...
I created a custom offer constraint to recalculate it but it seems not to work for me. The assigned Price is not being set. That's the Code I tried (I also put it in the App_Code of the FastTrack without success).
using System;
using System.Collections.Generic;
using System.Linq;
using Merchello.Core;
using Merchello.Core.Marketing.Offer;
using Merchello.Core.Models;
using Merchello.Web.Discounts.Coupons;
using Merchello.Web.Discounts.Coupons.Constraints;
using Umbraco.Core;
[OfferComponent("F89F860A-A0F2-42A2-BAC5-850E490DF9DD", "Test constraint", "This is for testing only.", RestrictToType = typeof(Coupon))]
public class TestConstraint : CollectionAlterationCouponConstraintBase
{
public TestConstraint(OfferComponentDefinition definition)
: base(definition)
{
}
public override bool RequiresConfiguration
{
get
{
return false;
}
}
public override Attempt<ILineItemContainer> TryApply(ILineItemContainer value, ICustomerBase customer)
{
List<ILineItem> lineItems = value.Items.Where(x => x.LineItemType != LineItemType.Shipping).ToList();
foreach(ILineItem lineItem in value.Items.Where(x => x.LineItemType == LineItemType.Shipping))
{
lineItem.Price = 1000; // Just a test to see that it worked
lineItems.Add(lineItem);
}
return Attempt<ILineItemContainer>.Succeed(CreateNewLineContainer(lineItems));
}
}
Also tried with set the Price of 1000 for every line item. Nothing changed.
In the constraints, the line item collection passed in is actually a clone of the line item container so that it can be manipulated without affecting the actual invoice.
In a reward the return value is a discount line item that gets added to the invoice so I don't think that will work in your scenario either.
You could look at replacing the previous task with a custom task that checks to see if the discount is going to be applied and then manipulate the shipping line item. This would be direct to the invoice line items.
Due to some internal methods inside your AddCouponDiscountsToInvoiceTask I had to call it with reflection:
public override Attempt<IInvoice> PerformTask(IInvoice value)
{
var type = Type.GetType("Merchello.Web.Workflow.InvoiceCreation.CheckoutManager.AddCouponDiscountsToInvoiceTask, Merchello.Web");
var task = Activator.CreateInstance(type, new object[] { base.CheckoutManager }) as CheckoutManagerInvoiceCreationAttemptChainTaskBase;
var = task.PerformTask(value);
CheckShippingCostsBecauseTheyAreCalculatedBeforeCouponsAreApplied(value);
return attempt;
}
Last question: What is the ExcludeTaxesIncludedInProductPrices constraint for when it just creates a clone of the LineItemContainer?
This seems to be a bug rather than coding in a workaround? Everytime I recalculate the shipping cost it is using the total price rather than the discounted basket total.
Problem with Coupon and Shipping Costs
Hi Rusty
I've a problem with the calculation of the shipping costs when adding a coupon.
A customer has following settings:
Shipping Provider: FreeOverAmount which is set at 50$.
Coupon: 10% off (Discount the price) and constraint "Not usuable with other coupons"
Scenario: You have a item total of 51$ (the shipping is free) then you add the coupon (new total is 45,9$) but shipping is still free - thats' wrong. Even if you reload (PrepareInvoice is called) it's wrong.
I've tried to solve it with adding some ExtendedData but in the QuoteShipment() the Items are somehow cached and not with the new ExtendedData which is added in the TryAward() off the OfferComponent.
Also saving the shipping (ClearShipmentRateQuotes and SaveShipmentRateQuote) again seems not to work (sometimes it works sometimes not - Caching issue?).
Also a Constraint which will re-add the shipping cost do not work (it's not getting saved?).
I also tried to do it before shipping and payment selection/saving with no success.
Do I do something wrong?
Thank you
Calvin
This is a problem with the order of things happening. The shipping is calculated before the coupon is added. Shipping charges become an actual line item and are looked at as a value with respect to the discount.
In your scenario, you are hoping the shipping provider will kick in and requote after the coupon has been applied. I never considered that use case (it sort of seems like a negative - like why would I add a coupon if it's possible that the amount of the shipping could actually cause the price to increase after adding the coupon).
If you need this, you could create a custom offer constraint that recalculate the shipping cost based off the free over amount provider ...
Thank you for your answer.
I created a custom offer constraint to recalculate it but it seems not to work for me. The assigned Price is not being set. That's the Code I tried (I also put it in the App_Code of the FastTrack without success).
Also tried with set the Price of 1000 for every line item. Nothing changed.
Thank you
Calvin
Sorry Calvin, I totally blew it.
In the constraints, the line item collection passed in is actually a clone of the line item container so that it can be manipulated without affecting the actual invoice.
In a reward the return value is a discount line item that gets added to the invoice so I don't think that will work in your scenario either.
However, in the builder task:
https://github.com/Merchello/Merchello/blob/merchello-dev/src/Merchello.Web/Workflow/InvoiceCreation/CheckoutManager/AddCouponDiscountsToInvoiceTask.cs
You could look at replacing the previous task with a custom task that checks to see if the discount is going to be applied and then manipulate the shipping line item. This would be direct to the invoice line items.
Nice! Seems to work thank you!!
Due to some internal methods inside your AddCouponDiscountsToInvoiceTask I had to call it with reflection:
Last question: What is the
ExcludeTaxesIncludedInProductPrices
constraint for when it just creates a clone of the LineItemContainer?Thank you
Calvin
Hi All
This seems to be a bug rather than coding in a workaround? Everytime I recalculate the shipping cost it is using the total price rather than the discounted basket total.
Calvin, are you able to share your code?
Thanks, Sam
is working on a reply...