Search This Blog

Friday, March 30, 2012

Shipping simplyfied

For each of the shipping charge that has been set up, one will have to use these two data models. The relationship path of the entries must be followed.

JURISTGROUP <-> SHPJCRULE <-> CALRULE <-> CRULESCALE <-> CALSCALE <-> CALRANGE <-> CALRLOOKUP
Diagram showing the database relationships described in the preceding paragraph. Each link on the image leads to a related database table.
Diagram showing the database relationships described in the preceding paragraph. Each link on the image leads to a related database table.

Hence, the relationship from the jurisdiction up to the shipping cost has to be followed.

So, starting with JURSTGROUP, this should show something that looks familiar in the CODE field. For example, 'Canada' is the shipping jurisdiction.

select * from JURSTGROUP where CODE='Canada'
JURSTGROUP_ID ​ DESCRIPTION ​ SUBCLASS ​ STOREENT_ID ​ CODE ​ MARKFORDELETE ​
10651 ​ NULL ​ 1 ​ 10001 ​ '​Canada ​' ​ 0 ​

Using CALRULE, the relationship based on JURSTGROUP_ID can be found.

select * from SHPJCRULE where JURSTGROUP_ID=10651
CALRULE_ID ​ SHPJCRULE_ID ​ FFMCENTER_ID ​ JURSTGROUP_ID ​ PRECEDENCE ​ SHIPMODE_ID ​
10003 ​ 11151 ​ 10001 ​ 10651 ​ 1.0 ​ 10001 ​

The result is the CALRULE_ID.

Thus, in CALRULE,

select * from CALRULE where CALRULE_ID=10003
CALRULE_ID ​ CALCODE_ID ​ STARTDATE ​ TAXCGRY_ID ​ ENDDATE ​ SEQUENCE ​ COMBINATION ​ CALMETHOD_ID ​ CALMETHOD_ID_QFY ​ FIELD1 ​ FIELD2 ​ FLAGS ​ IDENTIFIER ​
10003 ​ 10004 ​ 1900-01-01 00:00:00.0 ​ NULL ​ 2100-01-01 00:00:00.0 ​ 0.0 ​ 2 ​ -27 ​ -26 ​ NULL ​ NULL ​ 1 ​ 1 ​

By using the CRULESCALE table, you can see the relationship between CALRULE and CALSCALE.

select * from CRULESCALE where CALRULE_ID=10003
CALSCALE_ID ​ CALRULE_ID ​
11152 ​ 10003 ​

Hence, the CALSCALE record contains some of the details, as they show up in WebSphere Commerce Accelerator. In this case, CALUSAGE_ID -2 means this is shipping. CALMETHOD_ID = -28, means the scale range is based on items purchased.

select * from CALSCALE where CALSCALE_ID=11152
CALSCALE_ID ​ QTYUNIT_ID ​ CODE ​ DESCRIPTION ​ STOREENT_ID ​ CALUSAGE_ID ​ SETCCURR ​ CALMETHOD_ID ​ FIELD1 ​
11152 ​ NULL ​ 'Regular Delivery ' ​ 'Regular Delivery per order charge' ​ 10001 ​ -2 ​ NULL ​ -28​ NULL ​

The CALSCALE has to be based on the net price of the order, not the total number of items purchased. This can be updated in the database.

update CALSCALE set CALMETHOD_ID=-31 where CALSCALE_ID=11152
CALSCALE_ID ​ QTYUNIT_ID ​ CODE ​ DESCRIPTION ​ STOREENT_ID ​ CALUSAGE_ID ​ SETCCURR ​ CALMETHOD_ID ​ FIELD1 ​
11152 ​ NULL ​ 'Regular Delivery ' ​ 'Regular Delivery per order charge' ​ 10001 ​ -2 ​ NULL ​ -31​ NULL ​

This CALSCALE is associated to a particular CALRANGE.

select * from CALRANGE where CALSCALE_ID=11152
CALRANGE_ID ​ CALSCALE_ID ​ CALMETHOD_ID ​ RANGESTART ​ CUMULATIVE ​ FIELD1 ​ FIELD2 ​ FIELD3 ​ MARKFORDELETE ​
11152 ​ 11152 ​ -33 ​ 0.00000​ 0 ​ NULL ​ NULL ​ NULL ​ 0 ​

RANGESTART of 0.0000 indicates that this CALRANGE starts at 0, and applies to any order of $0 or higher, since the CALMETHOD_ID was changed to -31 in the related CALSCALE table, as per the previous step. If the CALMETHOD_ID was not changed from -28, this CALRANGE would apply to orders with 0 or more items.

In the CALRANGE table, CALMETHOD_ID=-33 is also there. This is a fixed amount, and the shipping cost is a fixed value of $20.00. You can change the value based on how the shipping cost is set up. For the example mentioned above, it will need to be -33.

The final shipping charge is defined in the CALRLOOKUP table, related to the CALRANGE.

select * from CALRLOOKUP where CALRANGE_ID=11152
CALRLOOKUP_ID ​ SETCCURR ​ CALRANGE_ID ​ VALUE ​
11152 ​ 'USD' ​ 11152 ​ 20.00000​

The CALRLOOKUP table is where the shipping cost is defined. The example below has a shipping cost of $20. The cost is fixed, because it was confirmed earlier that the CALMETHOD_ID in the related CALRANGE entry, was set to -33.


From this information, you can trace each shipping jurisdiction up to the shipping code or charge, or backwards from the shipping charge (CALRLOOKUP) to the jurisdiction (JURSTGROUP).

This relationship can be followed in the database, and a new range needs to be added in the shipping price. This ensures that there is free shipping if the total order is over $250 for 'Canada'.

If the above relationship is satisfied, you can see from JURSTGROUP to CALRLOOKUP, and can charge $20 for each order in this jurisdiction.

A new range has to be defined. This means that two ranges will be there with one range for any order over $0 (charged $20), and another range for any order over $250 (charged $0).

An entry has to be added to CALRANGE, so that any order on the original CALSCALE (in the above example 11152), which has a value over $250 will use this code. The CUMULATIVE=0 has to be set, so that the other charges (compound) to this shipping charge are not included.

Note: CALRANGE_ID is a unique key in this table
insert into CALRANGE values (11154,11152,-33,250.00000,0,NULL,NULL,NULL,0)
CALRANGE_ID ​ CALSCALE_ID ​ CALMETHOD_ID ​ RANGESTART ​ CUMULATIVE ​ FIELD1 ​ FIELD2 ​ FIELD3 ​ MARKFORDELETE ​
11152 ​ 11152 ​ -33 ​ 0.00000 ​ 0 ​ NULL ​ NULL ​ NULL ​ 0 ​
11154​ 11152 ​ -33 ​ 250.00000 ​ 0 ​ NULL ​ NULL ​ NULL ​ 0 ​


Now that this is added, a charge based on this range has to be defined. To get a charge of $0 in this range, one has to add using the SQL below (note that this entry is associated to the newly created CALRANGE entry).

Note: CALRLOOKUP_ID is a unique key in this table
insert into CALRLOOKUP values (11154,'USD',11154,0)
CALRLOOKUP_ID ​ SETCCURR ​ CALRANGE_ID ​ VALUE ​
11152 ​ 'USD' ​ 11152 ​ 20.00000 ​
11154​ 'USD' ​ 11154​ 0.00000​


In such a scenario, if their order is over 250 (CALRANGE.RANGESTART), the charge will be 0 (CALRLOOKUP.VALUE).

Notes:
The meaning of the CALMETHOD setting can be found in the database CALMETHOD.DESCRIPTION field for each CALMETHOD entry.


In case we want shipping charge based on category id or product..

There are two following table which has linking between product/category with CALCODE_ID

  • CATENCALCD -- > For Product and CALCODE_ID linking
  • CATGPCALCD --> For Category and CALCODE_ID linking

Wednesday, March 28, 2012

WCS Web service call returns a null response object

The problem that I was facing was that when the web service was called to get the Inventory response than there is a connection error at Mule.
WCS Framework is returning null object for our web Service.

There was nothing in the System logs from WCS related to this. We can see the following Connection error at the Mule Server End.


Following exception came at the Mule End
WARN 2012-03-13 16:42:36,448 [[MNSIntelligentStubs].connector.http.mule.default.receiver.02] org.apache.cxf.phase.PhaseInterceptorChain: Interceptor for {http://www.ibm.com/xmlns/prod/commerce/inventory}InventoryServicesPortTypeService#{http://www.ibm.com/xmlns/prod/commerce/inventory}ProcessOrderInventory has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:255)
at org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:224)
at org.mule.module.cxf.CxfInboundMessageProcessor$1.write(CxfInboundMessageProcessor.java:383)
at org.mule.transport.http.HttpServerConnection.writeResponse(HttpServerConnection.java:315)
at org.mule.transport.http.HttpMessageReceiver$HttpWorker.run(HttpMessageReceiver.java:164)
at org.mule.work.WorkerContext.run(WorkerContext.java:310)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.DataOutputStream.write(Unknown Source)
at org.apache.commons.httpclient.ChunkedOutputStream.flushCache(ChunkedOutputStream.java:100)
at org.apache.commons.httpclient.ChunkedOutputStream.finish(ChunkedOutputStream.java:143)
at org.apache.commons.httpclient.ChunkedOutputStream.close(ChunkedOutputStream.java:199)
at org.mule.module.cxf.support.DelegatingOutputStream.close(DelegatingOutputStream.java:39)
at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:47)
at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:188)
at org.mule.module.cxf.transport.MuleUniversalDestination$ResponseConduit.close(MuleUniversalDestination.java:81)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
... 9 more


I checked if there was a problem at the web service itself. However, there was no problem at the web service level because I used SoapUI client to test the web service from Mule and I could get the response xml back.

Problem that we are not able to get the response from the web Service is following.

The problem was that WCS did not parse for response when Content-Length header was not available in the response. For smaller responses, the Content-Length http header was available and hence WCS was displaying the response whereas for large responses, there was no Content-Length header in the response which made WCS think that there was no response and hence return a null response object before the response body could processed.

The chunked encoding modifies the body of a message in order to transfer it as a series of chunks, each with its own size indicator, followed by an OPTIONAL trailer containing entity-header fields. This allows dynamically produced content to be transferred along with the information necessary for the recipient to verify that it has received the full message.

Since the messages are passed as chunks, there is no Content-Length header present. Content-Length header is present only when the actual size of the message and the size of the transmission is the same. In case of “chunked” the sizes are different.


To Resolve the Issue

We need to change following attribute in the wc-server.xml
1. Find the following entry in the wc-server.xml
<OutboundConnector default="true" enabled="true" id="-101" name="HTTP-WS" retries="3">

Now add following tag
<EditableProperty Admin="bufferResponse" display="false" editable="yes" name="setIsBufferResponse" value="false" />

Once the files are updated, restart the websphere application server. This should resolve the problem.

2. Ensure that the WCS is restarted.

3.Now Configure the message to use the bufferResponse property.
1. Open the WebSphere Commerce Administration Console
2. Select Configuration -> Message Types
3. Open the message
4. Click Next
5. In the Change Message Transport Assignment panel, set bufferResponse to true

Now you are able to get response back in WCS.


IBM links
http://www-01.ibm.com/support/docview.wss?uid=swg1JR36471

Saturday, March 24, 2012

Extended site customer login issue

This is an issue that I faced when creating a new extended site from the extended site Hub. After the store was created, I registered as a customer on the site. But, I couldn’t login to the site with error saying “user does not have the authority to perform the action”.
Finally after much research I found that the registered user does not have an entry in the MBRROLE table with role id -29 (registered user) for the Org Entity (foreign key to ORGENTITY table. It’s basically the site)
Also, apparently the organisation structure was modified as per the requirements of the organisation. I had to do the following entries in order to enable users registering on the site to login.
Open MemberRegistrationAttributes.xml and under add a new entry for user registration type for the new store

<MemberAttributes><UserRoles>
<User registrationType="UserRegistration" memberAncestor="o=Root Organization" storeAncestor="ou=My Seller OrganizationStoreName,o=My Seller Organization,o=Root Organization">
<Role name="Registered Customer" roleContext="storeOwner" DN="ou=My Seller OrganizationStoreName,o=My Seller Organization,o=Root Organization"/>
</User>

This will still not allow already registered users to login. For that I had to make an entry in the MBRROLE table with ROLE_ID=-29 for the site.

Wishlist Query

Websphere commerce wish lists are stored in IITEMLIST table. Items in the wish list are in IITEM table.Query to list all wishlists by registered users
select IITM.STOREENT_ID, count(distinct ITMLST.IITEMLIST_ID) as NoOfWishLists from IITEMLIST ITMLST, IITEM IITM,USERS USR, STOREENT ST where IITM.IITEMLIST_ID = ITMLST.IITEMLIST_ID and IITM.MEMBER_ID=USR.USERS_ID and USR.REGISTERTYPE = 'R' group by IITM.STOREENT_ID

Saturday, March 17, 2012

How to enable SQL logging in websphere commerce

1. Logon WebSphere Administrative console.
2. From left panel select Troubleshooting-->logs and trace->server1->change log details levels
3. Expand com.ibm.ejs.*
4. Expand sub element com.ibm.ejs.persistences.*
5. Enable all Messages and traces for com.ibm.ejs.persistence.EJSDBCFinder and com.ibm.ejs.persistence.EJSJDBCPersister.
6. Click OK and Save.
7. Restart App Server.