Adding the recycling fee functionality to the tax integration interface

You can add the recycling fee functionality to the tax integration interface. In order to retrieve the recycling fee from an external tax system you need to do the following:

Installing and configuring the external tax system

You must install and configure the external tax system that supports the recycling fee.

Writing customized code

Writing customized code to retrieve the tax rate involves:

  1. Extend the ApplyCalcualationUsageTIKCmdImpl and override the performExecute method.
  2. In the performExecute method call super(), and then call getItems() to get all the order items.
  3. Loop through the order items and call orderItem[i].getRecyclingFee() to get the recycling fee for the order item.
  4. Call getTotalRecyclingFee() to retrieve the recycling fee.

You can use the data depending on your set up and business requirements.

The following is the sample code to retrieve the recycling fee:

import com.ibm.commerce.exception.ECException;
import com.ibm.commerce.order.calculation.Group;
import com.ibm.commerce.order.calculation.Item;


public class SampleRecFee extends ApplyCalculationUsageTIKBaseCmdImpl {

public void performExecute() throws ECException {
super.performExecute();
Item[] orderItem = getItems();
for (int i = 0 ; i < orderItem.length ; i ++) {
System.out.println("Get Recycling Fee : " + orderItem[i].getRecyclingFee());
}
System.out.println("Get Total Recycling Fee : " + getTotalRecyclingFee());
}

}

To ensure that the total price includes the recycling fee, you must make an adjustment to the order and order item. See the following sample code to do this:

import java.math.BigDecimal;
import java.rmi.RemoteException;
import java.util.Enumeration;

import javax.ejb.CreateException;
import javax.ejb.FinderException;
import javax.naming.NamingException;

import com.ibm.commerce.exception.ECException;
import com.ibm.commerce.exception.ECSystemException;
import com.ibm.commerce.fulfillment.objects.CalculationCodeDescriptionAccessBean;
import com.ibm.commerce.order.calculation.CalculationConstants;
import com.ibm.commerce.order.calculation.Item;
import com.ibm.commerce.order.objects.OrderAccessBean;
import com.ibm.commerce.order.objects.OrderAdjustmentAccessBean;
import com.ibm.commerce.order.objects.OrderItemAdjustmentAccessBean;
import com.ibm.commerce.order.utils.CalculationCmdHelper;
import com.ibm.commerce.order.utils.OrderRecycler;
import com.ibm.commerce.ras.ECMessage;
import com.ibm.commerce.ras.ECTrace;
import com.ibm.commerce.ras.ECTraceIdentifiers;
import com.ibm.commerce.taxation.objects.CalculationCodeTaxExemptAccessBean;

public class SampleRecFee extends ApplyCalculationUsageTIKCmdImpl {
private static final String CLASSNAME = "SampleRecFee";


public void performExecute() throws ECException {
ECTrace.entry(ECTraceIdentifiers.COMPONENT_ORDER,CLASSNAME,"PerformExecute"); 
super.performExecute();

Item[] orderItem = getItems();
OrderAdjustmentAccessBean orderAdjustmentAB = null;
Long orderAdjustmentId = null;
OrderRecycler recycler = OrderRecycler.startUse(getCommandContext());

try {
for (int i = 0 ; i < orderItem.length ; i ++) {

BigDecimal recyclingFee = orderItem[i].getRecyclingFee();
ECTrace.trace(ECTraceIdentifiers.COMPONENT_ORDER,CLASSNAME,"PerformExecute",
"Get Recycling Fee : " + recyclingFee);

// Do not create an adjustment if the recycling fee is zero
if (recyclingFee.compareTo(BIG_DECIMAL_ZERO) != 0){
OrderItemAdjustmentAccessBean oiab = new OrderItemAdjustmentAccessBean();

if (null == orderAdjustmentAB) {
Long orderId = new Long (orderItem[i].getOrderItem().getOrderId());
// create the order adjustment if it hasn't been created already
orderAdjustmentAB = recycler.createOrderAdjustment(
orderId, BIG_DECIMAL_ZERO, null, 
CalculationCmdHelper.CALCULATION_USAGE_SALES_TAX, 
CalculationConstants.DISPLAYLEVEL_ORDERITEM);

orderAdjustmentId = orderAdjustmentAB.getOrderAdjustmentIdInEJBType();
ECTrace.trace(ECTraceIdentifiers.COMPONENT_ORDER,CLASSNAME,"PerformExecute",
"Creating OrderAdjustmentAccessBean : OrderAdjustmentId = " + orderAdjustmentId +
" OrderId = " + orderId + " amount = 0 Caclode = null calusage = " +
 CalculationCmdHelper.CALCULATION_USAGE_SALES_TAX +
" DisplayLevel = " + CalculationConstants.DISPLAYLEVEL_ORDERITEM) ;

}

// create the orderitem adjustment record
Long orderItemId = orderItem[i].getOrderItemId();
OrderItemAdjustmentAccessBean orderItemAdjustmentAB = 
recycler.createOrderItemAdjustment(orderAdjustmentId, orderItemId, recyclingFee); 
ECTrace.trace(ECTraceIdentifiers.COMPONENT_ORDER,CLASSNAME,"PerformExecute",
"Creating OrderItemAdjustmentAccessBean : OrderAdjustmentId = " + orderAdjustmentId +
" OrderItemId = " + orderItemId + " Amouunt = " + recyclingFee);

// Create the order item adjustment
// Note : this does not take into consideration any existing adjustments
orderItem[i].setAdjustmentTotal(recyclingFee);
orderItem[i].commit();
ECTrace.trace(ECTraceIdentifiers.COMPONENT_ORDER,CLASSNAME,"PerformExecute",
"Setting OrderItem AdjustmentTotal to " + recyclingFee);
}
}

BigDecimal totalRecyclingFee = getTotalRecyclingFee();
ECTrace.trace(ECTraceIdentifiers.COMPONENT_ORDER,CLASSNAME,"PerformExecute",
"Get Total Recycling Fee : " + totalRecyclingFee);

if (orderItem.length > 0){

// Create the order adjustment. 
// Note : this does not take into consideration any existing adjustments
OrderAccessBean oab = orderItem[0].getOrderItem().getOrder();
ECTrace.trace(ECTraceIdentifiers.COMPONENT_ORDER,CLASSNAME,"PerformExecute",
"Setting Order AdjustmentTotal to " + totalRecyclingFee);
oab.setTotalAdjustment(totalRecyclingFee);
oab.commitCopyHelper();

}

if (totalRecyclingFee.compareTo(BIG_DECIMAL_ZERO) != 0){ 

// if there is an order adjustment record then set its total
if (orderAdjustmentAB != null) {
orderAdjustmentAB.setAmount(totalRecyclingFee);

// commit changes to order adjustment record
orderAdjustmentAB.commitCopyHelper();
ECTrace.trace(ECTraceIdentifiers.COMPONENT_ORDER,CLASSNAME,"PerformExecute",
"Set Order Adjustment to : " + totalRecyclingFee);
}
}

ECTrace.exit(ECTraceIdentifiers.COMPONENT_ORDER,CLASSNAME,"PerformExecute"); 
} catch (javax.ejb.CreateException ex) {
throw new ECSystemException(ECMessage._ERR_CREATE_EXCEPTION,
 CLASSNAME, "PerformExecute", new Object[] {ex.toString()}, ex);
} catch (javax.ejb.FinderException ex) {
throw new ECSystemException(ECMessage._ERR_FINDER_EXCEPTION,
 CLASSNAME, "PerformExecute", new Object[] {ex.toString()}, ex);
} catch (javax.naming.NamingException ex) {
throw new ECSystemException(ECMessage._ERR_GENERIC,
 CLASSNAME, "PerformExecute", new Object[] {ex.toString()}, ex);
} catch (java.rmi.RemoteException ex) {
throw new ECSystemException(ECMessage._ERR_REMOTE_EXCEPTION,
 CLASSNAME, "PerformExecute", new Object[] {ex.toString()}, ex);
} finally {
OrderRecycler.endUse(getCommandContext());
} 
}
}

Register the new class

Register the new command in the WebSphere Commerce CMDREG table such that the com.ibm.commerce.isv.kit.tax.ApplyCalculationUsageSalesTaxTIKCmd interface points to your customized class. For example:

insert into cmdreg values (201, 'com.ibm.commerce.isv.kit.tax.ApplyCalculationUsageSalesTaxTIKCmd',
 'Sample Recyling Fee Test Class', 'com.company.package.SampleRecFee', null, null, 'Local')

Configuring the calculation framework

Create a new calcode with the correct product code in the CALCODE.CODE column. This product code tells the external tax system to charge a recycling fee. For example :

insert into calcode values (1, '06005', -3, 201, 0, null, 1, 9, null, null, -43, 
-44, -42, null, 'Recycling Fee', 0, null, null, 0 , 0)

Add a row to the CATENCALCD for each catentry that the recycling fee must apply to. For example:

insert into catencalcd values (201, 2, null, 20101098000, 1)