Use billing address in custom ICustomerTaxClassService

Andy Bochmann asked on February 28, 2020 22:50


Based on the example here, I'm trying to implement a custom ICustomerTaxClassService to determine the tax class.

The only thing I'd like to add is a condition based on the billing address country. In my example, the result should be Taxable, if the CustomerTaxRegistrationID is empty OR if the customer is located in a certain country, regardless of the CustomerTaxRegistrationID.

public class CustomCustomerTaxClassService : ICustomerTaxClassService
    private IShoppingService ShoppingService { get; }
    private int UkCountryId { get; set; }

    public CustomCustomerTaxClassService(IShoppingService shoppingService)
        ShoppingService = shoppingService;
        UkCountryId = CountryInfoProvider.GetCountryInfoByCode("GBR").CountryID;

    /// <summary>
    /// Returns a CustomerTaxClass object for the specified customer to determine whether they are subject to tax.
    /// The default value is CustomerTaxClass.Taxable.
    /// </summary>
    public CustomerTaxClass GetTaxClass(CustomerInfo customer)
        var billingAddress = ShoppingService.GetBillingAddress();
        if (billingAddress != null && customer != null &&
            (billingAddress.AddressCountryID == UkCountryId || string.IsNullOrWhiteSpace(customer.CustomerTaxRegistrationID)))
            // Apply tax rules if customer billing address is UK or customer doesn't have tax registration ID
            return CustomerTaxClass.Taxable;

        return CustomerTaxClass.Exempt;

The problem is, calling ShoppingService.GetBillingAddress(); causes a StackOverflow exception, because that call by itself seems to perform a shopping cart calculation, which will eventually call the GetTaxClass method again.

Is there a better solution to do this or a way to avoid the exception?

Thanks, Andy

Recent Answers

Peter Mogilnitski answered on February 28, 2020 23:49

You have dependency injection in you constructor. Are you sure that IShoppingService is getting resolved correctly? If you have customerInfo can you simply use AddressInfoProvider?

var address = AddressInfoProvider.GetAddresses().WhereEquals("AddressCustomerID", customer.CustomerID)

CountryInfo country = CountryInfoProvider.GetCountryInfo(address.AddressCountryID);
0 votesVote for this answer Mark as a Correct answer

Andy Bochmann answered on February 29, 2020 00:03

Peter, yes, it gets resolved correctly. Your solution would only take the first saved address, but wouldn't use the selected billing address from the shopping cart.

I found another solution, which requires more code. I've now written a custom ITaxCalculationService, in which the billing address is available by default.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.