ART#308(A) - How to extend/customize commerceItem in ATG?

Back



Next




Since we have now understood the know-how of a commerceItem, we will discuss the extension of commerceItem.
As always, before jumping to the "HOW", we will discuss "WHY"!

WHY Extend a CommerceItem?
There can be many scenarios wherein you might need to extend a commerceItem. Let us analyze them one-by-one.

Scenario#1: Mostly, in item-descriptors which can be changed by users (e.g. user's profile, user's address etc.), we usually add a last modified date.
Similarly, since commerceItem is also user changeable (a person can increase or decrease quantity of a commerceItem, apply discounts etc.), many projects add a lastModifiedDate to the commerceItem just for the purpose of tracking.
In this case, you might have to add a new property to the commerceItem.


Scenario#2: This scenario might pop-up when you have a requirement, wherein you need some properties specific to commerceItem which you cannot have in SKU or PRODUCT. 
For example, you have to make an item as free-shippable, if user adds quantity as two. Now, you can have a boolean property in the commerceItem as "freeShipping", which will be true ONLY if user add 2 quantities of an item to cart. We cannot define this property at SKU/PRODUCT level, because you can never know how much quantity the user will add. This is decided ONLY when you add the item to cart.


Scenario#3: Consider an example, where you want to sell a gift-card on your website, which occurs in the denominations of $50, $100, $150... upto $1000. Now, you will not create a SKU for each denomination. A better approach would be to re-use existing SKU and add a property "giftCardPrice" in the commerceItem, because you dont know what price the user will select.


Now, since you want to distinguish this commerceItem from normal commerceItem [because it is a gift-card], you will create a new commerceItem [say giftCardCommerceItem], which should have existing properties of the commerceItem, along with your new property "giftCardPrice".

These are some basic scenarios where you might need to extend a commerceItem, there might be various other situations too, but above three scenarios broadly classify the type of extensions.



How to Extend a CommerceItem? 
Now that we know the need of creating a commerceItem, let us understand the basics of commerceItem extensions. First, lets talk about scenario1 and scenario 2, where we need to add a single property to a commerceItem.

A) Extend existing commerceItem

In our previous articles we discussed that commerceItem is an item-descriptor in OrderRepository backed by a Java Bean.

STEP#1:  Customizing the commerceItem item-descriptor in /atg/commerce/order/OrderRepository.
The process is same as adding a new property to the item-descriptor. You can visit the article on adding a new property to an item-descriptor HERE. 
XML: /atg/commerce/order/orderrepository.xml
item-descriptor: commerceItem 
primary table: dcspp_item 
Assume that we are adding a property "freeShipping" of type boolean in this step.

Your database and repository-XML will roughly look like:-



STEP#2:  Extending the JavaBean corresponding to the commerceItem.
Create a class which extends the class atg.commerce.order.CommerceItemImpl 
Let that class be: com.mycompany.commerce.order.MyCommerceItemImpl 



Create setters and getters for the property you have added in STEP1.
In our case, we will have to create the methods isFreeShipping() and setFreeShipping() respectively. [for boolean properties, it is better to have "is" as the prefix instead of "get"]

Your class will look like:- 


a. We declare a String constant "freeShipping": This is same as the property we defined above in the item-descriptor. Please note that this step is just for simplicity. We have declared a constant so that we can use this in different places. Writing the same string in different places might cause typographical errors.

b. We create a getter method. Since the property is of type "boolean", we declare isFreeShipping().

c.   Since the class CommerceItemImpl extends the class RepositoryItem, it derives the methods "setPropertyValue" and "getPropertyValue", which are used to set and get the properties on an item-descriptor respectively.CommerceItem is linked to its corresponding repository-item internally, so these methods work just fine.

In this method, we return the value of property "freeShipping" directly from the repository using getPropertyValue() method.

d. This is the setter method for the property "freeShipping".

e. setPropertyValue() method writes directly to the repository. 

NOTE: We have not added any property corresponding to the setters and getters as the value of property is fetched and stored directory into the repository.


STEP#3:  We have extended the repository, and extended the class for our custom commerceItem.
Now, 
a. Default class for commerceItem: We need to notify ATG which class should be used for our default commerceItem.
For this, we have to make an entry in /atg/commerce/order/OrderTools component.

We extend the OrderTools.properties and add the following code:-

commerceItemTypeClassMap-=\
    default=atg.commerce.order.CommerceItemImpl


commerceItemTypeClassMap+=\
    default=
com.mycompany.commerce.order.MyCommerceItemImpl 


In previous article we discussed that we passed "default" as the type of commerceItem we want to add. ATG maps the "default" type of commerceItem to the class CommerceItemImpl.
commerceItemTypeClassMap is the property in OrderTools which contains a mapping of commerceItem's "type" to a class.
 
Since we are extending the OOTB commerceItem, we have to remove this mapping and map the "default" type of commerceItem to "MyCommerceItemImpl" class [which is created by us] .

b. Item Descriptor for new class:  Here, we notify ATG which item-descriptor should be mapped to our custom class defined above. This is also done in OrderTools.properties.
We can add below code to do this:-

beanNameToItemDescriptorMap-=\
atg.commerce.order.CommerceItemImpl=commerceItem 

beanNameToItemDescriptorMap+=\
com.mycompany.commerce.order.MyCommerceItemImpl=commerceItem 

"beanNameToItemDescriptorMap" is the property-name in OrderTools. It contains the mapping of our class to the item-descriptor.
We remove the previous mapping for CommerceItemImpl with the commerceItem item-descriptor and add our mapping for MyCommerceItemImpl with commerceItem. 

 

To summarize,
1. We extended the item-descriptor "commerceItem" and added a property.
2. We extended OOTB class CommerceItemImpl and added setter-getter method to write and read directly from the repository.
3. We defined mappings for 
commerceItemType to a class [using commerceItemTypeClassMap property]
AND
class to item-descriptor [using beanNameToItemDescriptorMap property]

This was the process when you need to add some properties to EXISTING commerceItem.
This pretty much handles the basics of extending a commerceItem, but we have a lot to discuss in this topic in coming articles, so stay TUNED!

Back



Next



 






5 comments:

  1. Monis,
    First off all a BIG thanks for all your efforts; I am new to ATG and started this article in the morning and I completed all the chapters by evening. You have put all the concepts in a simple and understandable way. I can talk confidently on most of ATG topics and pretty sure I will be more confident when I make my hands dirty.

    By the way do we get trail license of ATG?

    ReplyDelete
  2. Hi Monis,
    Thank you for the wonderful tutorials. It has been of great help.
    Eagerly awaiting your next post.

    ReplyDelete
  3. Thanks Monis for this very helpful tutorials.
    It is quite easy to understand the concepts of ATG after reading your posts.
    When will you add next tutorial, it has been more than 2 months?

    ReplyDelete
  4. Thank you very much.

    we are waiting for next tutorials..........

    ReplyDelete
  5. Hi Monis,
    Very Nice Post
    Can you Please explain Order Management

    ReplyDelete

Subscribe

Get All The Latest Updates Delivered Straight Into Your Inbox For Free!

Flickr