Avalara Module Documentation

Customizing Requests

There is a pre-configured component called com.broadleafcommerce.vendor.avalara.tax.gateway.soap.TaxSoapRequestGeneratorImpl that builds tax requests compatible with the Avalara SOAP API. This has a Spring Bean name of blAvalaraTaxSoapRequestGenerator. You can override this bean by extending the TaxSoapRequestGeneratorImpl, and overriding any of its public or protected methods. Broadleaf will use your custom implementation with a simple configuration addition to your core applicationContext.xml:

<bean id="blAvalaraTaxSoapRequestGenerator" class="com.mycompany.tax.MyTaxSoapRequestGenerator"/>

Here is an example of the implemenation:

public class MyTaxSoapRequestGenerator extends TaxSoapRequestGeneratorImpl {
   ...
}

You can override any of the methods provided in order to manipulate the generation of the tax calculation request. Many of the methods provide hooks for you to override, but do nothing (or return null) out of the box. For example:

/**
 * Allows one to override the VAT or Business Identification Code at the Fulfillment Group Item level.
 * @param item
 * @return
*/
protected String determineBusinessIdentificationCode(FulfillmentGroupItem item, AvalaraTaxModuleConfiguration config) {
    return null;
}

If you needed to provide this information, you have a hook or mechanism to simply override this method and the request will contain the data that you return.

Here are some additional, special cases that deserve some extra attention:

Item Code

protected String determineItemCode(FulfillmentGroupItem fgItem, AvalaraTaxModuleConfiguration config) {
    String skuId = null;
    OrderItem orderItem = fgItem.getOrderItem();
    if (orderItem instanceof DiscreteOrderItem) {
        DiscreteOrderItem discreteItem = (DiscreteOrderItem) orderItem;
        skuId = String.valueOf(discreteItem.getSku().getId());
    } else if (orderItem instanceof BundleOrderItem) {
        BundleOrderItem bundleItem = (BundleOrderItem) orderItem;
        skuId = String.valueOf(bundleItem.getSku().getId());
    } else if (orderItem instanceof GiftWrapOrderItem) {
        GiftWrapOrderItem giftItem = (GiftWrapOrderItem) orderItem;
        skuId = String.valueOf(giftItem.getSku().getId());
    }
    String upcCode = determineUpcCode(fgItem, config);
    if (StringUtils.isNotBlank(upcCode)) {
        return new StringBuilder(upcCode).append('-').append(skuId).toString();
    }
    return skuId;
}

The above method uses the ID of the SKU for the item code that is passed to Avalara. This allows for a direct reference back to the SKU when reporting taxes. This can be completely overridden to provide a different reference to the Item Code. One thing to notice here is that it queries the determineUpcCode(...) to attempt to build a hyphen (-) separated code. See UPC Code below for more information on this.

UPC Code (Universal Product Code)

Avalara provides a service called MatrixMaster that allows tracking and calculation of taxes at the UPC level. Contact Avalara to activate this service. This service makes use of a specific Item Code format. In particular, it expects a String that is the UPC code followed by a hyphen (-), followed by the original item code (e.g. Sku ID). For example, 123456789-123. The method to determineItemCode invokes a method called determineUpcCode(...). The default implementation returns null:

protected String determineUpcCode(FulfillmentGroupItem fgItem, AvalaraTaxModuleConfiguration config) {
    return null;
}

You can override this method and determine UPC code, for example, from an extended SKU entitiy. For example:

protected String determineUpcCode(FulfillmentGroupItem fgItem, AvalaraTaxModuleConfiguration config) {
    String sku = null;
    OrderItem orderItem = fgItem.getOrderItem();
    if (orderItem instanceof DiscreteOrderItem) {
        DiscreteOrderItem discreteItem = (DiscreteOrderItem) orderItem;
        sku = discreteItem.getSku();
    } else if (orderItem instanceof BundleOrderItem) {
        BundleOrderItem bundleItem = (BundleOrderItem) orderItem;
        sku = bundleItem.getSku();
    } else if (orderItem instanceof GiftWrapOrderItem) {
        GiftWrapOrderItem giftItem = (GiftWrapOrderItem) orderItem;
        sku = giftItem.getSku();
    }
    if (sku != null && MySku.class.isAssignableFrom(sku.getClass())) {
        return ((MySku)sku).getUpcCode();
    }
    return null;
}

NOTE: As of Broadleaf version 4.0, UPC is available on the default Sku entity.