Sunday, 30 November 2014

Websphere Commerce Calculation Framework Part 2

Please read the post on IBM WCS Calculation Framework Part 1  before reading the below section. 

Sales Tax and Shipping Tax Customizations

Follow the below steps to create customized calculation methods for both Sales Tax  and Shipping Tax

Step 1

Create the custom interface  and implementation class

public interface < Sample>TaxCalculationCodeCalculateCmd extends
                              CalculationCodeCalculateCmd {
}

public class < Sample> ExtendedTaxCustomCmdImpl implements
                              < Sample>TaxCalculationCodeCalculateCmd {
}

Step 2

Create a new entry into the CALMETHOD table for the tax calculation usage for this interface

//Create an entry in CALMETHOD for the sales tax

Insert into CALMETHOD(CALMETHOD_ID, STOREENT_ID, CALUSAGE_ID, TASKNAME, DESCRIPTION, SUBCLASS,NAME)values
((select max(calmethod_id)+1 from calmethod), (Select STOREENT_ID from STOREENT where IDENTIFIER = '<StoreId>'), (select CALUSAGE_ID from CALUSAGE WHERE DESCRIPTION = 'Sales Tax'),'com.<sample>.commerce.order.calculation.<Sample>TaxCalculationCodeCalculateCmd',
'method to calculate sales tax code for <Store> (referenced by CALCODE.CALMETHOD_ID)', 3,'CalculationCodeCalculate<Sample>salestax)');

//Create an entry in CALMETHOD for the Shipping tax

Insert into CALMETHOD(CALMETHOD_ID, STOREENT_ID, CALUSAGE_ID, TASKNAME, DESCRIPTION, SUBCLASS, NAME) values
((select max(calmethod_id)+1 from calmethod), (Select STOREENT_ID from STOREENT where IDENTIFIER = '<StoreId>'), (select CALUSAGE_ID from CALUSAGE WHERE DESCRIPTION = 'Shipping Tax'),'com.<sample>.commerce.order.calculation.<Sample>TaxCalculationCodeCalculateCmd',
'method to calculate shipping tax code for <Sample> (referenced by CALCODE.CALMETHOD_ID)', 3,'CalculationCodeCalculate<Sample>shipping tax)');

Step 3

Update the CALCODE tables that were pointing to the generic CalculationCodeCalculateCmd reference to the new interface created.

//Get Calmethod_id of Sales Tax
select calmethod_id from calmethod where name = ''CalculationCodeCalculate<Sample>salestax ' and storeent_id = (Select STOREENT_ID from STOREENT where IDENTIFIER = '<StoreId>')

//Update CALCODE table with the Sales Tax CALMETHOD_ID got as a result of above query

UPDATE CALCODE SET CALMETHOD_ID=<calmethod_id> WHERE STOREENT_ID=< StoreId > AND  CALUSAGE_ID=-3; 

//Get Calmethod_id of Shipping Tax

select calmethod_id from calmethod where name = 'CalculationCodeCalculate<Sample>shipping tax' and storeent_id = (Select STOREENT_ID from STOREENT where IDENTIFIER = '<StoreId>')

//Update CALCODE table with  the Shipping Tax CALMETHOD_ID got as a result of above query

UPDATE CALCODE SET CALMETHOD_ID=<calmethod_id> WHERE STOREENT_ID=< StoreId> AND  CALUSAGE_ID=-4; 

Step 4

Update the CMDREG table to point this Custom Class

insert into CMDREG (STOREENT_ID, INTERFACENAME, DESCRIPTION, CLASSNAME, TARGET) values
((select storeent_id from storeent where identifier = '<StoreId>'),
'com.<sample>.commerce.order.calculation.<Sample>TaxCalculationCodeCalculateCmd',
'For custom tax Calculation','com.<sample>.commerce.tax.commands.<Sample>ExtendedTaxCustomCmdImpl' , 'Local');



Sample Tax Customizations


1) Tax Customization -Calculating the total tax on an order by rounding the tax on each item
By default, WebSphere Commerce calculates the tax on the sum of an order. This value is rounded up to the nearest cent. You would like the tax to be calculated by item. If the tax is calculated in this manner, tax will be applied to each item,rounded up to the nearest cent, and then summed.

Cause

The following example demonstrates the two approaches for calculating the tax on an order:
Assume that the price of an item A is $1.89 and the order requires 20 items of A.
The current tax rate is 16%.
To calculate the tax by rounding the tax on the total sum:
Total Sum = $1.89 x 20 = $37.8
Tax = $37.8 x 16% = 6.048 -> rounding -> $6.05
To calculate the tax by rounding the tax on each item:
Tax of each item = $1.89 * 16% = $0.3024 -> rounding -> $0.30
Tax = $0.30 * 20 = $6.00

Resolving the problem
To customize WebSphere Commerce to calculate the tax by item: 
1.Create a new task command, or interface, that extends CalculationCodeCalculateCmd.
For example:
public interface EXCalculationCodeCalculateCmd extends com.ibm.commerce.order.calculation.
CalculationCodeCalculateCmd {
public static final String defaultCommandClassName =  "test.EXCalculationCodeCalculateCmdImpl";
2.Create an implementation of the above task command that extends CalculationCodeCalculateCmdImpl.
public class EXCalculationCodeCalculateCmdImpl extends  
CalculationCodeCalculateCmdImpl implements EXCalculationCodeCalculateCmd {
}
3.Override its roundValues() method to round the tax amounts on a   per-quantity basis  
protected void roundValues() throws ECException {
Integer[] nTaxCategoryIds = getTaxCategoryIds();
if(nTaxCategoryIds == null || nTaxCategoryIds.length == 0) { return; }
Item[] items = getItems();
if(items == null || items.length == 0) { return; }
for(int i = 0; i < nTaxCategoryIds.length; i++) {
//these are the tax amounts of the orderitems for a particular tax category
BigDecimal[] dValues = getValues(nTaxCategoryIds[i]);
if(dValues == null || dValues.length == 0) { continue; }
for(int j = 0; j < dValues.length; j++) {
BigDecimal dQuantity = items[j].getQuantity();
BigDecimal dPerQuantityValue =
CalculationHelper.getInstance().divide(dValues[j], dQuantity);
dPerQuantityValue =
CalculationHelper.getInstance().round(dPerQuantityValue, getCurrency(),     getCommandContext());
//round the tax amount of an orderitem on a per-quantity basis
dValues[j] = dPerQuantityValue.multiply(dQuantity);
}
}
4.Register the above task command as a calculation method.  
<calmethod_id> = Pick a unique ID from the CALMETHOD table. For example, 12345
Note: Do not use a negative ID. Negative IDs are reserved for system use only.
INSERT INTO CALMETHOD VALUES (<calmethod_id>, -1, -3, 'mypackage.EXCalculationCodeCalculateCmd', 'custom CalculationCodeCalculate method which rounds on a per-quantity basis', 3, 'custom ExCalculationCodeCalculate method');
5.Update the sales tax calculation codes to use this method. For  example: 
<calmethod_id> = must be the same one selected in step 4.
<store ID> = the id of the store that will use this customization.
All the store in the system can be found in the store table.
UPDATE CALCODE SET CALMETHOD_ID=<calmethod_id> WHERE
STOREENT_ID=<store ID> AND CALUSAGE_ID=-3; 

2)TAX Customizations to  to update tax from third party application 
Step 1:
INSERT INTO CALMETHOD (CALMETHOD_ID, STOREENT_ID, CALUSAGE_ID, TASKNAME,DESCRIPTION, SUBCLASS, NAME) VALUES((select coalesce((min(calmethod_id)-1),1)from calmethod), 10501 , -3,'com.example.commerce.order.calculation.EXApplyCalculationUsageCmd', 'custommethod for calculation sales taxes', 12, 'ApplyCalculationUsageSalesTax')
Step2:
UPDATE STENCALUSG SET CALMETHOD_ID_APP =
(SELECT CALMETHOD_ID FROM CALMETHOD WHERE TASKNAME = 'com.example.commerce.order.calculation.EXApplyCalculationUsageCmd'
AND STOREENT_ID = 10501 AND CALUSAGE_ID = -3) and calusage_id=-3
Step 3:
insert into CMDREG (STOREENT_ID, INTERFACENAME, DESCRIPTION, CLASSNAME, PROPERTIES, LASTUPDATE, TARGET)  values
(0,'com.example.commerce.order.calculation.EXApplyCalculationUsageCmd','Sales Tax calculation usage for third-party tax providers',
'com.example.commerce.order.calculation.EXApplyCalculationUsageCmdImpl',null,null,'Local')
Step 4:
public class EXApplyCalculationUsageCmdImpl extends ApplyCalculationUsageCmdImpl{
public void performExecute()  throws ECException    {
BigDecimal orderTaxAmount  =  getOrderTax() //get tax from third party
Item[] orditems = super.getItems();
// set  tax on first order item from the order
for (int count = 0; count < 1; count++) {
orditems [i].setSalesTaxTotal(orderTaxAmount );
orditems [i].commit();
}
}  

Saturday, 29 November 2014

ERROR - SRVE0255E: A Web Group/Virtual Host to handle has not been defined in Websphere Commerce



Solution:
 1.    Publish the application once again and see if it publishes successfully. Try accessing the URL to see if it works. Go to below steps only if the step 1 doesn’t work.

2.      If step 1 doesn’t resolve the issue go to WAS Admin Console and make sure application started. Make sure that Application WC status is coming as green as shown below.

    
Websphere Application Server Admin Console


3.    Verify the virtual host 'host aliases' definition in Web Sphere Admin Console.
Virtual hosts’ entries for Web Applications can be configured in Admin Console "Environment -> Virtual Hosts -> default host".

Websphere Application Server Admin Console
Websphere Application Server Admin Console


4.      Verify that ‘context root' is correctly defined in the Web Application.

Context roots enable hosting several applications (Web Modules) in one JEE Web Application (WAR file). For example, if your context root for a Web module is 'shop', and your login page is Home.jsp, the URL must be read as http://localhost:80/shop/Home.jsp". We can check the context roots in Admin console by navigating to "Applications -> Enterprise Application ->Your application". Click on "Context root for Web Modules"