Take a look at this page:
What probably messed things up for you is this part:
If you also look under the section "Changes to calculators" you'll see some things that are of interest to you as well.
I don't know in what order your activities run but I assume that whatever you set OrderForm.TaxTotal to in your activity is overwritten by another activity that runs later, probably one that calls the Calculators.
There's an IOrderFormCalculator where you should be able to add your tax calculation code instead if you want it to always run that code when the calculators are called.
So it looks as though the order in which we called our activities was now causing the tax to get overriden by epi's calculation. I moved the custom calculations for handling and tax to the end of the activity flow and that has seemed to work.
return activityFlow.Do<CustomValidateLineItemsActivity>() .Do<GetFulfillmentWarehouseActivity>() .Do<CheckInventoryActivity>() .Do<CustomProcessShipmentsActivity>() .Do<CalculateTotalsActivity>() .Do<CustomCalculateDiscountsActivity>() .Do<CustomValidateLineItemsActivity>() .Do<UpdateGiftItemActivity>() .Do<CalculateTotalsActivity>() .Do<CustomCalculateTaxActivity>() .Do<CustomApplyHandlingToTotals>(); //.Do<UpdateTotalsActivity>();
Another issue, it looks like OrderGroup.OrderForms[0].TaxTotal and Total no longer are accurate, only OrderGroup.TaxTotal and Total. Can you confirm this? thanks
Also, the UpdateTotalsActivity seems to clear the tax calc as well, so i've commented it out. That just seems to add together payment amounts. ???
I wouldn't recommend removing UpdateTotalsActivity, it's responsible for setting values properly on the various parts of an order (OrderGroup, OrderForm, Shipments, LineItems etc).
As mentioned above it would be better if you move your Handling and Tax calculation code to an appropriate Calculator. Maybe IOrderFormCalculator. Then you can remove your own activity and it will be handled by existing activities everytime.
You can read more about the calculators here:
https://world.episerver.com/documentation/developer-guides/commerce/orders/calculating-orders-intro/
Hopefully that will help you select the appropriate level calculator to add your code to.
Hi Todd,
Jafet's comment was right. To customize the order form's tax total, you should customize the order form calculator instead of workflow activity (as the commerce 12 came out, almost tax business was moved from the workflow to calculators).
In this case, I thing you should simply override CalculateTaxTotal of DefaultOrderFormCalculator.cs, as sample code in here to reference.
public class OrderFormCalculatorOverridingDefault : DefaultOrderFormCalculator { public OrderFormCalculatorOverridingDefault(IShippingCalculator shippingCalculator, ITaxCalculator taxCalculator) : base(shippingCalculator, taxCalculator) { } protected override Money CalculateTaxTotal(IOrderForm orderForm, IMarket market, Currency currency) { return new Money(0, currency); // return your custom tax here } }
/Tuan
Thank you all, I have overriden the DefaultOrderGroupCalculator and registered IOrderGroupCalculator with my custom class in StructureMap. This seems to be working.
I'm still noticing that OrderGroup.OrderForm.Total does not reflect any tax, shipping total, etc.. OrderGroup.Total does. Not a huge problem right now as both are accessible, but was just curious.
@Todd: I have the same issue, I am not using workflow but upon using IOrderGroupCalculator my taxes are all zero. Did you have a work around for this?
Yes, override the DefaultOrderGroupCalcultor and DefaultOrderFormCalculator, i'll post code below
1. Be sure to register your overrides with your IoC container:
container.Configure(x => x.For<IOrderGroupCalculator>().Use<CustomOrderGroupCalculator>()); container.Configure(x => x.For<IOrderFormCalculator>().Use<CustomOrderFormCalculator>());
2. Override the calculators like below:
public class CustomOrderFormCalculator : DefaultOrderFormCalculator { private Injected<ICheckoutRepository> _checkoutRepository; private Injected<ISalesTaxDataAccess> _salesTaxDataAccess; public CustomOrderFormCalculator(IShippingCalculator shippingCalculator) : base(shippingCalculator) { } protected override Money CalculateShippingSubTotal(IOrderForm orderForm, IMarket market, Currency currency) { var cart = _checkoutRepository.Service.GetCart(); if (cart == null) return new Money(0, Currency.USD); return new Money(cart.ShippingTotal, Currency.USD); } protected override Money CalculateHandlingTotal(IOrderForm orderForm, Currency currency) { var of = orderForm as OrderForm; if (of == null) return new Money(0, Currency.USD); decimal feeTotal = 0; foreach (var lineItem in of.LineItems) { feeTotal += CalculatorHelper.GetLineItemFreightFee(lineItem as ILineItem); } orderForm.HandlingTotal = feeTotal; of.HandlingTotal = feeTotal; return new Money(feeTotal, Currency.USD); } protected override Money CalculateTaxTotal(IOrderForm orderForm, IMarket market, Currency currency) { var of = orderForm as OrderForm; if (of == null) return new Money(0, Currency.USD); of.TaxTotal = 0; var shippingAddress = orderForm.Shipments.FirstOrDefault()?.ShippingAddress as OrderAddress; if (shippingAddress == null) return new Money(0, Currency.USD); var taxableStates = _salesTaxDataAccess.Service.GetTaxableStates(); if (!taxableStates.Contains(shippingAddress.State, StringComparer.InvariantCultureIgnoreCase)) return new Money(0, Currency.USD); if (shippingAddress.State.IsNullOrWhiteSpace() || shippingAddress.PostalCode.IsNullOrWhiteSpace()) return new Money(0, Currency.USD); var taxableTotal = of.TaxableTotal(); var taxTotal = _salesTaxDataAccess.Service.GetTaxTotal(taxableTotal, of.ShippingTotal, shippingAddress.State, shippingAddress.PostalCode); return new Money(taxTotal, Currency.USD); } }
public class CustomOrderGroupCalculator : DefaultOrderGroupCalculator { private Injected<ICheckoutRepository> _checkoutRepository; private Injected<ISalesTaxDataAccess> _salesTaxDataAccess; public CustomOrderGroupCalculator(IOrderFormCalculator orderFormCalculator) : base(orderFormCalculator) { } protected override Money CalculateShippingSubTotal(IOrderGroup orderGroup) { var cart = _checkoutRepository.Service.GetCart(); if (cart == null) return new Money(0, Currency.USD); return new Money(cart.ShippingTotal, Currency.USD); } protected override Money CalculateHandlingTotal(IOrderGroup orderGroup) { var og = orderGroup as OrderGroup; if (og == null) return new Money(0, Currency.USD); var orderForm = og.OrderForms?.FirstOrDefault(); if (orderForm == null) return new Money(0, Currency.USD); decimal feeTotal = 0; foreach (var lineItem in orderForm.LineItems) { feeTotal += CalculatorHelper.GetLineItemFreightFee(lineItem as ILineItem); } orderForm.HandlingTotal = feeTotal; og.HandlingTotal = feeTotal; return new Money(feeTotal, Currency.USD); } protected override Money CalculateTaxTotal(IOrderGroup orderGroup) { var og = orderGroup as OrderGroup; if (og == null) return new Money(0, Currency.USD); og.TaxTotal = 0; var shippingAddress = og.OrderAddresses.FirstOrDefault(x => x.Name == "ShippingAddress"); if (shippingAddress == null) return new Money(0, Currency.USD); var taxableStates = _salesTaxDataAccess.Service.GetTaxableStates(); if (!taxableStates.Contains(shippingAddress.State, StringComparer.InvariantCultureIgnoreCase)) return new Money(0, Currency.USD); if (shippingAddress.State.IsNullOrWhiteSpace() || shippingAddress.PostalCode.IsNullOrWhiteSpace()) return new Money(0, Currency.USD); var taxableTotal = og.TaxableTotal(); var taxTotal = _salesTaxDataAccess.Service.GetTaxTotal(taxableTotal, og.ShippingTotal, shippingAddress.State, shippingAddress.PostalCode); return new Money(taxTotal, Currency.USD); } }
@Todd Jasper: Thank you for the quick response, but how can we save the value in the orderform taxtotal now? Cause I dont think the property exists, so once the custom implementation spits out the value I plan to save it to the oderform taxtotal, which I am unable to do.
We've recently upgraded from commerce 9 to commerce 12. In the activity flows we have a custom tax activity where we manually set tax total on an order based on our tax rules. After the upgrade the tax total is being set however when the cart is referenced anywhere outside the activity flow the tax total is 0.
Below is the custom activity we've been using in 9. Where can we set tax total now? Thank you