Debugging a Category’s Bad Child Products

Today I was using the CategoryLookup droplet to find a category’s child products. However when I accessed the child products I would get this JDBC error.

java.lang.NullPointerException
at java.lang.String.(String.java:166)
at oracle.sql.CharacterSet.AL32UTF8ToString(CharacterSet.java:1517)

I realized my product data was corrupted. However this category had over 70 child products. The stack trace wasn’t telling me which one was corrupt and going through each child product to find out which one was corrupt was too painful.

I first queried the database to find all the child product ID’s.

SQL> select child_prd_id from dcs_cat_chldprd where category_id='cat101' order by sequence_num;

I then created a simple JHTML page which would query each child product and output which ones were corrupted.

<java>
final String [] product_ids = { "prod101", "prod102", "prod103" };

for (int ii = 0; ii < product_ids.length; ii++) {
out.print(ii + ". [" + product_ids[ii] + "] ");
try {
</java>
<droplet name="/atg/commerce/catalog/ProductLookup">
<param name="id" value="`product_ids[ii]`">
<oparam name="output">
<valueof param="element.displayName"/><br/>
</oparam>
</droplet>
<java>
} catch (RuntimeException exc) {
out.println(exc + "<br>");
}
}
</java>

Once I knew which child products were bad I removed their mappings to the category in dcs_cat_chldprd.

SQL> delete from dcs_cat_childprd where child_prd_id = 'prod102' and category_id='cat101';

Then I updated the sequence numbers so that they are all consecutive by moving the ones at the end to fill the holes created by the previous deletes.

SQL> update dcs_cat_childprd set sequence_num = 1 where child_prd_id = 'prod103' and category_id='cat101';

Creating Buy N Get M Free Promotions

parents for sale, buy one get one free | FlickrATG’s promotion engine is pretty advanced and relatively easy to use for creating promotions as described in their Creating Promotions section in the Commerce Programming Guide.

ATG’s documentation gives numerous examples of how to create buy N get M free promotions.

For example to create a simple Buy 2 Get 1 Free promotion one would create the following rule.

“For next 2 items whose product is in the category named Foo, discount up to 1 item whose product is in the category named Foo”

The only issue with the above rule is that you cannot set conditions on customers. If you need to set conditions on customers then you have create a rule like this.

“When order contains at least 3 items whose product is in the category named Foo and at most 5 items whose product is in the category named Foo and customer’s name is Frank, discount up to 1 item whose product is in the category named Foo”

Note you will have to create separate promotions for each level, i.e. one for the 3 for 1, one for the 6 for 2, one for the 9 for 3, etc.

Also if you change a promotion I believe you have to restart the ATG server otherwise at least the current customers will still be using the old promotion.

Retrieving the Source from the Database

Sometimes I am faced with a situation where I need to know the source for a view or a procedure or a function. Fortunately Oracle stores the source in the database.

First I check to see what kind of object whose source I need is.

SQL> select object_name,object_type,status from user_objects where object_name = 'FOO';

If the object is a table I can simply recreate the table by doing a desc on that object.

SQL> desc FOO;

If the object is a function or stored procedure you can find its source in the user_source table.

SQL> select text from user_source where name = 'FOO' order by line;

If the object is a view you can find its source in the user_views table.

SQL> select text from user_views where view_name = 'FOO';

If the output seems to be truncated it is because text is of type LONG which is a big binary field. To allow more output do this.

SQL> set long 4000

Thanks to this article and this forum for helping me figure this out.

Viewing Expert-Level Information in the ACC

William T. Sherman | FlickrSome information, such as properties and item descriptors, are marked as expert (i.e. expert=true) so that they are not displayed in the ACC unless you are an expert user.

For example:

<property name="type" data-type="enumerated" expert="true"/>

To display expert-level information in the ACC go to Tools > Preferences and select the "Show expert-level information" box.

ATG ACC Preferences

Note that this is not a "sticky" preference, i.e. you have to set it every time you restart the ACC.

Cannot Create New ATG Scenario

Though I have a distaste for scenarios on occasion there will be a time when I want to create a new scenario. On such an occasion I still start up the ACC, go to Scenarios > Scenarios and discover I can’t create a scenario because the New Scenario box is grayed out.

The issue is often because the process editor server is configured incorrectly. ATG documents how to configure the process editor server.

For example today I found I could not create a new scenario. After putting this scenarioManager.xml in localconfig/atg/scenario and then restarting ATG I was able to create new scenarios again.

<?xml version="1.0" encoding="ISO-8859-1" ?>
<process-manager-configuration>
 <process-editor-server>
  <server-name xml-combine="replace">
   CRAPBOOK-PRO:8850
  </server-name>
 </process-editor-server>
</process-manager-configuration>

Note that the server name must be the same as the one found at /atg/dynamo/service/ServerName.serverName. For more information about the atg.service.ServerName class, see Referring to Dynamo Servers in the Nucleus: Using Nucleus section of the ATG Programming Guide.

ThinkPad T60 Blank Display After Resume

Every once in awhile I’d find after leaving my Thinkpad for awhile that I’d find the screen blank. No matter what I did I could not get it to come back.

I finally figured out a workaround. By pressing Fn + Spacebar I decreased the screen resolution and the screen was displayed again. I then pressed Fn + Spacebar again to get back to my original display and then had to move back windows to where they were and resize some.

After doing this too many times I finally did a Google search to find out what was wrong. Fortunately this turned out to be a common problem, both on Windows and Linux.

Using the Windows Device Manager I saw that the driver for my ThinkPad PM (Power Management) Device was version 1.33.0.0. According to this page the latest driver is 1.43.0.0.

I updated this driver using ThinkVantage’s System Update utility (under Start Menu > ThinkVantage). I actually had to run the Software Installer which, because it was out of date, uninstalled itself and updated the System Update. Then when I ran the System Update it pulled down the driver update as part of its recommended updates.

So far the update seems to be working.

12/03/2007 – Turns out the update did not fix this problem. I then ran System Update and updated all critical and recommended updates. I am not sure if this solved the problem but I did notice my display now sometimes flickers. 🙁

Date and Timestamp Repository Data Types

Today I noticed that my timestamp property was being saved with only the date information, not the time information. That is when I queried the corresponding column I saw something like this.

> select TO_CHAR(timestamp, 'yyyy-mm-dd hh24:mi:ss') from foo;

2007-11-17 00:00:00

The timestamp property was represented in Java using a Date class. I thought of switching it to a Timestamp class but was dubious because the only real difference is that the Timestamp class stores fractional seconds.

Then I looked at /atg/commerce/order/orderrepository.xml and the corresponding OrderImpl.java and realized that it used the timestamp repository data type while I was using the date repository date type. Since the Oracle column data type was also timestamp I found when I switched the repository data type the time information was also saved.

> select TO_CHAR(timestamp, 'yyyy-mm-dd hh24:mi:ss') from foo;

2007-11-17 20:03:00 

The moral of the story is to use the timestamp repository data type, not the date repository data type.

ATG has more documentation about this though it is not entirely true, i.e. you can use the Date Java class type with the timestamp SQL type.

Test Credit Card Numbers


Card Type Number
Master Card (16 Digits) 5105105105105100
Master Card (16 Digits) 5555555555554444
Visa (13 Digits) 4222222222222
Visa (16 Digits) 4111111111111111
Visa (16 Digits) 4012888888881881
American Express (15 Digits) 378282246310005
American Express (15 Digits) 371449635398431
Amex Corporate (15 Digits) 378734493671000
Dinners Club (14 Digits) 38520000023237
Dinners Club (14 Digits) 30569309025904
Discover (16 Digits) 6011111111111117
Discover (16 Digits) 6011000990139424
JCB (16 Digits) 3530111333300000
JCB (16 Digits) 3566002020360505

 
If you want more test credit card numbers try Google.

CommerceItem, which one is the SKU ID?

Colors | Flickr

Colors by CurveTo

The CommerceItem has two properties, catalogRefId and catalogId.

I always forget which one is which so I am writing this post so I can remember. I guess it was because some companies have different conventions about SKU’s and products.

ATG Real World
catalogRefId SKU ID
catalogId Product ID

Maybe one day someone will explain the reason for the naming.

Note that sometimes the catalogId is null though I’ve never seen the catalogRefId be null.

You can also try to get the product ID by using the auxiliaryData property. This property has a productId property.

ATG DUST

ATG has a new open source framework for doing integrated tests called ATG DUST. It sounds interesting though it’s still somewhat raw and I have not tested it myself.

Here is the description from the website.

ATG DUST is a framework for building JUnit tests for applications built on the ATG Dynamo platform. This framework allows one to quickly write test code that depends up Nucleus or ATG Repositories. By using this framework one can drastically cut down on development time. It takes only a few seconds to start up a test with a repository, but it may take multiple minutes to start up an application server.

You can see the source and download the source tarball.