Header Image

Documentation

1.0 - Introduction

Avetti Commerce is an Enterprise Ecommerce Java solution. We are one of the fastest ecommerce platform in the market today. Avetti Commerce has a full sets of standard features that will get your online store up and running quickly and easily. With our organized project structure and module system and build tools, developers can easily create custom modules and extend from the standard core package.

1.1 - Getting Started

Simply download our latest install script from our website, and purchase a Level 1 license to get started.

1.3 - Architecture and Concept

Avetti Commerce utilizes the best Java technologies and proper design patterns to create top class ecommerce solutions. Avetti Commerce has 4 logical layers which separates business independencies to allow developers easily and quickly customize both the Core and create/change modules. Different design patterns are used in the project Core to provide a standard framework to enhance existing feature and customizations. Let us now get into more details on the major sub-systems and concepts of Avetti Commerce.

1.3.1 - Controllers, Business Actions and Business Objects

Avetti Commerce uses Spring and Hibernate as its core framework. To allow full customization on a low raw level, the Core is built on standard spring controllers. Controllers will encapsulate all front end logic which deals with passing data to the front end views like jsp, velocity templates. All heavy business logics are handled by Business Action Objects (BA). The job of BAs is to consolidate and handle integrations from different parts of the system on a high level. Finally Business Objects will handle the low level business logic individually and are passed to Business Actions. Let’s look at each section in more details.

1.3.1.1 - Controllers and Views

Avetti Commerce makes use of standard Spring Controllers. Controllers handle all request and response made to the application. For example, when a browser hits an Avetti Commerce URL, the first thing it hit is the Spring Controllers and Filters. Controllers then redirect these requests to the necessary Business Actions for data returned. The returned data is then passed to the Views for display on the browser. The 2 standard views we use are JSPs and Velocity Templates.

1.3.1.2 - Business Actions

Business Action Classes are used to handle top level logics that will consolidate lower level business logic. For example, suppose we have a controller that will accept an itemId, a categoryId, add this item to the category, and return all the item details.

In our controller we will have:

    
    public class AttachItemToCategoryController extends BaseCheckoutController {
    private ItemCategoryBA itemCategoryBA;
    
       protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, BindException errors) throws Exception {
           String itemId = request.getParameter("itemId");
           String categoryId = request.getParameter("categoryId");
           request.setAttribute("itemDetail", itemCategoryBA.attachCategory(itemId, categoryId));
    
           ...
       }
    }
        

Here we have injected the BA ItemCategoryBA in our controller. The method attachCategory() will help us do all our logic making the controller very simple and need not to worry about how to attach a category or returning the item details.

1.3.1.3 - Business Objects

Business Objects a lower level business layer that handles single task logics. The divide jobs from BAs and split them into individual tasks. Using our previous example and the Data Transfer Object, we will create the following BOs

            
    public class ItemDTO {
       private Item item;
       private StoreProperty;
       ...
    }
    
    public class ItemBOImpl implements ItemBO {
       private ItemDAO itemDao;
       private StorePropertyDAO storePropertyDao;
              
       public ItemDTO getItemDetail(String itemId){
           Item item = itemDao.getItem(itemId);
           StoreProperty storeProperty = storePropertyDao.getStoreProperty(itemId);
           ItemDTO itemDTO = new ItemDTO(item,storeProperty);
           return itemDTO;            
       }
    }
    
    public class CategoryBOImpl implements CategoryBO {
       private CategoryDAO categoryDao;
       private ItemDAO itemDao;
    
       public boolean getAttachItemToCategory(String itemId, String categoryId){
            Item item = itemDao.getItem(itemId);
            Category category = categoryDao.getCategory(categoryId);
            category.getItems().add(item);
            return categoryDao.saveCategory(category);
       }
    
    }
        

Notice how different DAOs are injected to each BO. And each method in the BO handles 1 single business logic task.

1.3.1.4 - Database Access Objects

Database Access Objects are our bottom layer in the application which talks directly to the database. We try to make DAOs as simple as possible and only dealing with a single task related to the database. For example, getting an item object, updating a certain object etc. And Avetti Commerce uses the Hibernate Criteria Query as a standard.

1.3.2 - Proxy Pattern

Think of Proxy Pattern as setting a proxy in your internet browser connection settings. Having set to different proxies you will be serving the internet on different location. In Avetti Commerce, the proxy pattern is used to allow injection of different implementations of a certain interface dynamically. Spring has bean injection which injects different implementation of an interface, but that is manual. The proxy pattern allows us to add new implementations of an existing interface without specifically declaring an injection. http://docs.avetticommerce.com/twiki/bin/view/DeveloperDocumentation/HowToUseProxyClassesToCustomizeCommerceClasses

1.3.3 - Component Controller

Component Controller is a special implementation that extends the default spring controllers. The concept is to allow different components to be injected into a controller so that upon the same action, different logic is executed.

        
    "personalizedQuestionController"
         class="com.avetti.commerce.store.personalizedquestion.web.PersonalizedQuestionController">
      ...
       "referenceDataComponents">
         
           "pageTileComponentBA"/>
           "pageComponentProcessor"/>
           "miniBasketDataBA"/>
           "catalogAuthenticateBA"/>
           "categoryPathComponentBA"/>
           "storeCurrencyComponent"/>
           "welcomeMatBA"/>
            "componentFactory"/>
         
       
       ...
        

From the above, upon execution of personalizedQuestionController, all the component listed in referenceDataComponents will get executed. Lets look at one of the implementations:

    
    public class WelcomeMatBA implements IComponentBA {
       ...
       public void process(ComponentDTO parameters, Object command) {
           String vid = parameters.getVendorSettings().getVendorId();
    
              ...
       }
       ...
    }
        

Any components must implement the method process() which will be executed from any component controller.

1.3.4 - Package Structures

Avetti Commerce Core holds the package structure as com.avetti.commerce And all sub packages within commerce holds each feature within the core.

For modules, Avetti Commerce use the package standard of:

com.avetti.commerce.{moduleName} instead of having packages like:

com.avetti.commerce.service
com.avetti.commerce.dao

we use the package structure that defines by feature.
so:

com.avetti.commerce.helloworldmodule.controller
com.avetti.commerce.helloworldmodule.businessaction
com.avetti.commerce.helloworldmodule.dao
com.avetti.commerce.goodbyeworldmodule.controller
com.avetti.commerce.goodbyeworldmodule.businessaction
com.avetti.commerce.goodbyeworldmodule.dao
etc.

in short, we stick to package in the structure to modules.

1.3.5 - Key Data Models and Elements

Let’s have a closer look on the key data elements

1.3.5.1 - Vendor

The Vendor model defines the stores for the system. creating a vendor will grant access to the full sets of respective customers and items and orders. All other key elements must associate themselves with a Vendor.

1.3.5.2 - Storeproperties

As the name suggests, Storeproperties is the list of properties associated with a particular vendor. These properties define the settings for different parts of the system. For example: SOLR_BUILD_ON_SERVER_START if set to YES, then solr will rebuild when server starts.

1.3.5.3 - Items

This is the main object that holds all the item information that are to display in the catalogs of the store. All the basic information like title, description are all stored here.

1.3.5.4 - Offerprices

This is where the prices for each item is stored. Each record is associated with the item’s itemid. It has prices for different range of quantities purchased. For example, quantity purchased from 1-10 is priced at $10 and from 20-30 can be set to $9.

1.3.5.5 - Attributes

Attributes are custom options for items. For example: Shirt has Color, Size. Attributes are the Color and Size.

1.3.5.6 - Properties

Item Properties are used to store data per item. For example: extra descriptions, factory serial numbers etc. Any extra information regarding the item can be added here.

1.3.5.7 - Inventory

Inventories specifies how much instock for an item. Avetti Commerce system will look into this table for information about instock, minimum order quantity, drop ship quantities etc. Each item should have 1(one) inventory record.

1.3.5.8 - Customer

Customers registered or as a guest will be stored here when registered or check out as guest. All basic information about the customer is strored here. We can make reference from all orders to the customer details.

1.3.5.9 - Orderdata

When an order is placed, 1(one) orderdata record is created for that order. Orderdata stores all the main information about the order. Each orderdata will have a set of orderitems.

1.3.5.10 - Orderitem

Orderitem stores all the line items in the order. For example: in an order with 2 TV, 3 shirts and 5 boots, there will be 3 orderitems with TV quantity 2, shirt quantity 3 and boots quantity 5.

1.3.6 - Webservices

Xfire and Spring webservices is used in Avetti Commerce. http://docs.avetticommerce.com/twiki/bin/view/Documentation_OLD/WebServices

1.3.7 - Control Threads

Avetti Commerce has control threads that runs in the background to provide support to the main application. Control threads handle sub tasks like scheduled tasks, dynamic check and update of databases, clear cache on events etc.

1.3.8 - Data Transfer Objects

Different logical layers in Avetti Commerce uses the concept of a Data Transfer Object to communicate. The idea is to use a consolidated Object that is NOT the Hibernate database object. For example, to transfer information from Controller to BA, we will create an item DTO that will have all necessary properties from the item and pass this object to the BA layer. And the same object can be passed to the BO layer. In the BO layer is where we will create the Hibernate object from the DTO and store to database if necessary. The same holds true when getting data from DAO layer. The DAO layer will ALWAYS return and accept Hibernate objects. And the BO layer will ALWAYS translate from and to between Hibernate object and the DTOs.

1.3.9 - Velocity Templates and Integrations

All front end pages which the shopper will view is rendered by a velocity template. The integration happens on the controller where the view pages are specified by the name of the templates. For example: for an item page, the item controller when rendering will look for a template named itemtemplate.vm which all DTOs are passed to this template and render the final html that is transferred to the browser. To change the behavior and look and feel of the items page, one must edit the itemtemplate.vm direct from the Avetti Commerce Admin console. Yes, this is done on the front end admin page console, not a file in the project code. The Avetti Commerce Admin Console for managing template has its own repository system which manages template versioning.

2.0 - General Framework overview

Avetti Commerce uses Spring and Hibernate as the base platform. It utilizes proxy pattern to automatically inject module logic into the core for extensions and customizations. Avetti Commerce has its own build tool which is built on maven to handle project management. Avetti Commerce is based on a core project which is in itself a powerful ecommerce platform. But is also extendable by list of modules to enhance standard functionalities or add new features.

2.1 - Spring - How To

Avetti Commerce utilizes the famous Spring framework as its core platform. From simple java bean injection to AOP to scheduled tasks. Avetti Commerce makes full use of the Spring package. Examples of spring to come.

2.2 - Hibernate - How To

Hibernate is another core library of Avetti Commerce. We will look into hibernate in details Examples of hibernate mapping and initialize new objects.

2.4 - Core and Modules - How To

Create New Customer Project Step by Step Guide:

  1. For each client or customer, we will create a project dedicated to them. (This is just a simple project with 1 (ONE) file, the pom.xml that indicates what core and modules are needed for this client)
  2. In this project, we will not have any code or class files.
  3. We will create a pom.xml with all necessary settings for this customer.
  4. run the command:
    mvn archetype:generate -B -DarchetypeGroupId=com.avetti
    -DarchetypeArtifactId=initclient
    -DarchetypeVersion=1.0
    -DarchetypeRepository=http://svn.avetticommerce.com/nexus/content/repositories/thirdparty
    -Dversion=1.0
    -DgroupId={packageName}
    -DartifactId={clientName}
  5. Now that the clientProject folder has been created, cd to the directory and modify the pom.xml in it:
                            
        <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
       <modelVersion>4.0.0</modelVersion>
       <groupId>${groupId}</groupId>
       <artifactId>CHANGME</artifactId>
       <version>${version}</version>
       <packaging>jar</packaging>
       <name>Avetti Commerce Client: CHANGEME</name>
       <description>DESCRIPTION CHANGEME</description>
       <url>http://www.avetti.com</url>
     
       <!--Properties Starts DO NOT REMOVE -->
        <properties>
            <!-- Project Properties Starts DO NOT REMOVE -->
           <project.module.list>
              adminRolesModuleAvettiCom/tags/1.0,
                ccProcessorsModuleAvettiCom/tags/1.0,
              rewardsPointsModuleAvettiCom
           </project.module.list>
          <project.core>commerce8/tags/Commerce8.1</project.core>
          <project.svn.module.dir>http://svn.avetticommerce.com/software/avetticommerce/modules/
          </project.svn.module.dir>
          <project.svn.core.dir>http://svn.avetticommerce.com/software/avetticommerce/
          </project.svn.core.dir>
         <project.svn.username></project.svn.username><!-- optional -->
          <project.svn.password></project.svn.password><!-- optional -->
          <project.debug>Y</project.debug>
          <!-- Project Properties Ends DO NOT REMOVE -->
        </properties>
       <!--Properties Ends DO NOT REMOVE -->
     
     
       <!--Profiles Starts DO NOT REMOVE -->
       <!--Profiles Ends DO NOT REMOVE -->
     
       <!--PluginRepositories Starts DO NOT REMOVE -->
        <pluginRepositories>
          <pluginRepository>
             <id>avetti-remote-repo</id>
             <url>http://svn.avetticommerce.com/nexus/content/repositories/thirdparty
             </url>
             <snapshots>
                <enabled>true</enabled>
             </snapshots>
             <releases>
                <enabled>true</enabled>  <!-- Workaround for MNG-2974, see note below -->
             </releases>
          </pluginRepository>
       </pluginRepositories>
       <!--PluginRepositories Ends DO NOT REMOVE -->
       <!--Repositories Starts DO NOT REMOVE -->
       <!--Repositories Ends DO NOT REMOVE -->
       <!--Build Starts DO NOT REMOVE -->
       <!--Build Ends DO NOT REMOVE -->
       <!--Reporting Starts DO NOT REMOVE -->
       <!--Reporting Ends DO NOT REMOVE -->
       <!--Dependencies Starts DO NOT REMOVE -->
       <dependencies>
           <dependency>
                <groupId>avetti</groupId>
                <artifactId>module</artifactId>
                <version>1.6</version>
            </dependency>
          <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>3.8.1</version>
             <scope>test</scope>
          </dependency>
       </dependencies>
       <!--Dependencies Ends DO NOT REMOVE -->
                        
  6. Change directory to customer project folder.
  7. To check out all your necessary projects, do: mvn avetti:module:setup
  8. After all projects are checked out from svn, to compile the projects into tomcat do: mvn avetti:module:deploy -Ppreview clean compile war:exploded
  9. DONE! you have now completed setting up a new customer.

Create New Module Guide:

  1. Change directory to the folder you want to create the module project in.
  2. Run the command to create a new project skeleton:
    mvn archetype:generate -B -DarchetypeGroupId=com.avetti
    -DarchetypeArtifactId=initmodule -DarchetypeVersion=1.0
    -DarchetypeRepository=http://svn.avetticommerce.com/nexus/content/repositories/thirdparty
    -Dversion=1.0 -DgroupId={packageName} -DartifactId={moduleName}
  3. After the project skeleton has been created, edit the newly created project pom.xml
                        
         <modelVersion>4.0.0</modelVersion>
         <groupId>com.avetti</groupId>
         <artifactId>initmodule</artifactId>
         <version>1.0</version>
         <name>Archetype - initmodule</name>
         <url>http://www.avetti.ca</url>
         
         <distributionManagement>
           <repository>
               <id>avetti-repo</id>
               <url>http://svn.avetticommerce.com/nexus/content/repositories/thirdparty</url>
           </repository>
         
         </distributionManagement>
         
        </project>
                        
  4. Now you are ready to add new java logic for your module!
  5. Simply create java files, hibernate files, jsps, etc in the similar structure as the core project.
  6. To compile the module with the core project please see Create New Customer Project Step by Step Guide from above.
2.5 - Simplemerce Jar - How To

The Simplemerce Jar holds all deprecated classes of Avetti Commerce. Slowly all deprecated classes will be refactored and moved to com.avetti.commerce packages. As of right now, many deprecated classes still exist, and Avetti Commerce will require this deprecated jar to deploy and run. The installation of the jar should be fully automatic but developers should be aware of this jar because many parts of the system still reference it.

3.0 - Design and Coding Standards

It is advised to stick to Avetti Commerce design and coding standards when modifying the core or creating new modules. Please check each section for details on different parts of the system and their standards.

3.1 - Variable, Class extension

All variables should be marked private and only be allowed to access with getters and setters. Only constants are allowed to be declared as public. Classes should all be named with respect to their module names. Each layer should follow the naming conventions of: XxxxxController, XxxxxBA, XxxxxBO, XxxxxDAO

3.2 - Package and Folder Structures

All modules should follow the exact structure of the core.
Modules should be created using:
mvn archetype:generate -B -DarchetypeGroupId=com.avetti
-DarchetypeArtifactId=initmodule -DarchetypeVersion=1.0
-DarchetypeRepository=http://svn.avetticommerce.com/nexus/content/repositories/thirdparty
-Dversion=1.0 -DgroupId={packageName} -DartifactId={moduleName}

Package structure should be:
com.avetti.{modulename}. {other sub packages}

4.0 - Modules and Core

Avetti Commerce has a powerful sub-system which enables user to easily add new functionality or modify existing functionality without having to worry about existing code. A Core project which is a standalone application which features a full set of standard e-commerce solution. And a list of modules which when installed will enhance this enterprise e-commerce solution further. Also customized modules can be created and installed easily into this e-commerce system.

4.1 - Core and Module Concept

In Avetti Commerce, instead of splitting projects by layers, i.e. 1 project for DAO, 1 project for BA, 1 project for controllers etc. We split our application by feature(s). With all the basic standard features in our Core. And any custom, or extra features in modules.

You will be able to simply compile and run the core by using the commands:
mvn avetti:module:setup
mvn avetti:util:dbmigrator -Pupdate-db-preview
mvn avetti:module:deploy -Ppreview clean compile war:exploded
Then install any modules as an extension to our existing core for extra functionalities.
The project is fully extendible with any module modifications.

4.2 - Extending Core

To Extend from the Core, Avetti Commerce follows the proxy pattern to open “hooks” in the system so that new implementation can be injected. Avetti Commerce comes with a set of standard hooks built into the system. Searching the project with the keyword of Proxy will show you all the available proxies. Once a proxy is opened in the core, new logic can be implemented and injected into that new proxy so hence changing the behavior of the system.

4.3 - Multi-Module, Core Integration - How To

Multiple modules can be installed to core. And modules not hosted on Avetti Svn can also be added to the core. To do so, edit the pom.xml for the parent folder that links the Core and Modules together.

            
    <!-- Project Properties Starts DO NOT REMOVE -->
    <project.module.list>
        AvettiComAdminRolesModule/tags/1.0,
        AvettiComImportFullIceCatModule/tags/1.0,
        AvettiComImportOpenIceCatModule, 
        AvettiComManageFacetsModule,
        AvettiComReplicationMarketPlaceModule</project.module.list>
    <project.core>commerce8/tags/Commerce8.1</project.core>
    <project.svn.module.dir>http://svn.avetticommerce.com/software/avetticommerce/modules/
    </project.svn.module.dir>
    <project.svn.core.dir>http://svn.avetticommerce.com/software/avetticommerce/
    </project.svn.core.dir>
    <project.svn.username></project.svn.username><!-- optional -->
    <project.svn.password></project.svn.password><!-- optional -->
    <project.debug>Y</project.debug>
    
    <project.custom.module.list>
    </project.custom.module.list><!-- optional -->
    <project.custom.svn.module.dir>
        http://svn.avetticommerce.com/software/avetticommerce/modules/
    </project.custom.svn.module.dir><!-- optional -->
    <project.custom.svn.username></project.custom.svn.username><!-- optional -->
    <project.custom.svn.password></project.custom.svn.password><!-- optional -->
    
    <!-- Project Properties Ends DO NOT REMOVE -->
            

5.0 - Database Migrator and Module Installer

Extending Avetti Commerce can be done without forking the code by creating modules. In addition Avetti Commerce provide developers a nice easy way of making database changes and updating existing database. The database migrator keeps track of all database patches and automatically updates the database to the latest revision.

The database migrator will track each module individually, so even when installing multiple modules will be with ease.

5.1 - Database Migrator Concept and How To
Idea and Design Decision

It has been difficult to manage all the different features and custom logic that satisfies different customer needs.

So we came up with the idea of a module system for Commerce 8 in order to simply and manage these customizations better.

The idea is that we would have a core project that is stand alone which will give most customers what they need as an e-commerce solution.

Then any custom or extra features are made into modules that will be plugged into the core project.

These modules will need to be dependent on the core. Which means they will not function without a core.

Our idea of a module is to implement new classes that will make use of existing core APIs and functionality in order enhance into new features.

But we will not allow overriding existing classes and logic.

For example: if paymentController exist in core, the module will not be able have the same class. It may be extended, but developers will not be able to use the extended class to replace existing beans. For designs please check out http://docs.avetticommerce.com/twiki/bin/view/DeveloperDocumentation/CommerceModuleInstallerUserGuide

Implementation Details:

In order to implement the installer, a maven plugin was created.

mvn avetti:module:setup

This plugin resides in the class: com.avetti.plugin.module.ModuleSetup

With the following parameters:

            
    /**
     * The list of modules to checkout, in the form of module1, module2, module3 ...
     * 
     * @parameter expression="${project.module.list}"
     * @required
     */
    private String moduleList;
    
    /**
     * The core project folder name which to checkout.
     * @parameter expression="${project.core}"
     * @required
     */
    private String core;
    
    private List moduleNames = new ArrayList();
    
    /**
     * The SVN directory name for the modules.
     * 
     * @parameter expression="${project.svn.module.dir}"
     * @required
     */
    private String moduleDir;
    
    /**
     * The SVN directory name for the cores.
     * 
     * @parameter expression="${project.svn.core.dir}"
     * @required
     */
    private String coreDir;
    /**
     * the svn username
     * 
     * @parameter expression="${project.svn.username}"
     * @required
     */
    private String username;
    /**
     * the svn password
     * 
     * @parameter expression="${project.svn.password}"
     * @required
     */
    private String password;

            

This task needs to be run under the folder of a clientProject (please see user doc for explanation on clientProject)

When this task is executed, it will checkout all projects required to build the clientProject into the folder ../.

Hence you will get the structure:


    ./
    ./clientProject
    ./coreProject
    ./module1
    ./module1
            

in the same folder.

If the projects already exist, it will do an svn update on them to get the up to date.

It will also copy solr configuration files to the solr home directory set in the /tomcat/conf/.../solr*.xml

mvn avetti:module:deploy clean compile war:exploded -Ppreview (or shop)

This plugin resides in the class: com.avetti.plugin.module.ModuleDeploy

With the following parameters:

            
    /**
    * If this parameter is Y, it will enable debug statements when program is running.
    * 
    * @parameter expression="${project.debug}"
    * 
    */
    private String debug = "N";
    
    /**
    * The list of modules to checkout, in the form of module1, module2, module3 ...
    * 
    * @parameter expression="${project.module.list}"
    * @required
    */
    private String moduleList;
    
    /**
    * The core project folder name which to checkout.
    * @parameter expression="${project.core}"
    * @required
    */
    private String core;
            

This task needs to be run under the folder of a clientProject (please see user doc for explanation on clientProject)

When this task is executed, it will copy all files from core and modules and put them all into the clientProject folder.

During the copying process it will validate the following:

  1. It will make sure that no file names are the same for all files, it will throw error if any file names are conflicting in any modules or core.
  2. It will make sure that no beans are overriding each other, if bean id = paymentController exist, there CANNOT be another bean with id paymentController.
  3. It will merge all messages*.properties and shopmessages*.properties files in the modules into the core files, (there is no validation on these properties atm, because spring does not validate it, so we have no need to do so)
  4. It will merge all files into the structures of core and modules, so if the module or core file is in /test/abc/justAFile.jsp, this file will be copied direct into the /clientProject/test/abc/jstAFile.jsp. So folder structures are preserved.

Once all files pass validation, it will then do a normal compile war:exploded as standard Commerce 7 compile. This time the compiler and spring validations will take over. No logic is added after this point from the installer.

The combined project under /!clientProject is then compiled into a war, and exploded into tomcat directory just like the stand alone core project compile.

Initialize Skeleton Module Project
            
    mvn archetype:generate -B -DarchetypeGroupId=com.avetti -DarchetypeArtifactId=initmodule -DarchetypeVersion=1.0 -DarchetypeRepository=http://svn.avetticommerce.com/nexus/content/repositories/thirdparty -Dversion=1.0 -DgroupId={packageName} -DartifactId={moduleName} 
    
    {packageName} - This is the package name you want your module to have, usually is com.avetti.module
    {moduleName} -This is the name you want to call your module.
            

This is simply an archetype which resides in nexus.

This task can be run anywhere to create a skeleton of a module project.

When this task is executed, it will try to get the archetype we have created in our nexus, The create all the necessary folders and initial file from the archetype.

Initialize Skeleton Client Project
            
    mvn archetype:generate -B -DarchetypeGroupId=com.avetti -DarchetypeArtifactId=initclient -DarchetypeVersion=1.0 -DarchetypeRepository=http://svn.avetticommerce.com/nexus/content/repositories/thirdparty -Dversion=1.0 -DgroupId={packageName} -DartifactId={moduleName} 
    
    {packageName} - This is the package name you want your client project to have, usually is com.company
    
    {moduleName} -This is the name you want to call your client project.
            

This is simply an archetype which resides in nexus.

This task can be run anywhere to create a skeleton of a client project.

When this task is executed, it create a client project with

Maven Archetype

An archetype for the project skeleton has been created.

This archetype simply has all the folder structures on where the jsp, resource files, java classes, spring xmls go.

It contains a st of empty messages*.properties files, and shopmessages*.properties,

it has a springapp-module-RENAMEME.xml which the developer should rename.

No java or jsp or resource files are added into the archetype. At least not at this point where the initial module java classes are not clear.

5.2 - Module Installer How to

Obligation rule(must follow) :

These rules should be applied to the database name, table name and column name.

  • By using the "_" to separate the words in the name
  • No "`" around the name in hibernate mapping file
  • Avoid the database reserved keywords , such as 'TYPE', 'DEFAULT'. If not sure, use at least two words for a name.
  • all names should be lowercase in hibernate mapping file
  • Database engine for MYSQL must be InnoDB? .
  • Character set must be utf-8.

Best Practice(recommend to follow) :

Open to have more best practices in this doc.

  • Use singular for table names.
  • Use suffix _arc to represent the history / archive table

Index must be created for any frequently searched columns.
for example, if queries like:
select * from item where name = {name} and code = {code} and description like %{description}%
then an index must be created for name, code and description.

5.3 - Key Database Objects

Let's look at some of the key objects for Avetti Commerce Database.

5.3.1 - Items and related Tables

The Items table holds all information about item in your store. Items has the following key aspects:
-Item descriptions and images - The image and descriptions are stored in the items table, they are the details of what the item is and sample images.
-Attributes and Itemskus - Attributes and itemskus handles different options an item can have and the relationship between child and parent items.
For Example: Item Shirt can have the attributes: Size and Color, and will have the options Large Medium Small for Size, and Blue Green Red for Color.
The itemskus then specifies given item GOLFSHIRTSB is a child item of GOLFSHIT with the options: Small in Size and Blue in Color.

So a sample full list of child parent itemsku relationship will be:

GOLFSHIRTSB, Small, Blue, GOLFSHIRT
GOLFSHIRTMB, Medium, Blue, GOLFSHIRT
GOLFSHIRTLB, Large, Blue, GOLFSHIRT
GOLFSHIRTSR, Small, Red, GOLFSHIRT
GOLFSHIRTMR, Medium, Red, GOLFSHIRT
GOLFSHIRTLG, Large, Green, GOLFSHIRT

Notice you do not need to fill in all options, any missing combinations of the options will simply be unavailable.

5.3.2 - Customers and related Tables

In Avetti Commerce, all customers(Anonymous or not), will be recorded into the database before making an order. Customers may have different properties, addresses.

All the basic information about the customer is stored in the Customer Object. Any extra information is stored in the CustomerProps. Address stores the customer addresses which can be billing, shipping addresses.

5.3.3 - Orders and related Tables

The main order entry is stored in the OrderData Object. OrderData specifies the general information about the order. More detailed information about the order is stored in separate tables. OrderItem stores each of the item details and quantity purchased for each line item in the order.

OrderPayment stores all the payment information about the order, usually there should only be 1 orderPayment, but sometimes orders are paid separately with different methods of payment. For example, 50% of the order is paid with a gift card, and remaining with Credit card, in this case, there will be 2 records to the OrderPayment. Finally, OrderProperties stores all extra properties associated with the order. Things like checkout question/survey would be ideal to store in order properties.

6.0 - Proxy Pattern

General Information

This document describes how to use proxy classes to change default implementation of the Avetti Commerce classes. This will be useful when developer wants to add or change default behavior of class which Avetti Commerce has. Proxy classes allow to inject custom functionality without change of Avetti Commerce classes. Custom functionality has to be implemented in the customer sub-project (seeC8CustomizeWithMaven).

Proxy classes usage
Task description

Customer requires to use it own service for the price calculation. We have to use SOAP to interact with price calculation system. We need to send vendor identifier and item code to get prices details.

Problem

Avetti Commerce has it own system which stores prices in the database. We would like to leave current system and inject new price source which classes are in the customer sub-project. Maven allow to put Avetti Commerce7 and customer sub-project all together, but in case if we turn customer sub-project off Avetti Commerce7 should compile successfully and use prices from the database. To say more common Avetti Commerce doesn't have to have any dependencies from the customer sub-project.

Brief description of solution

Avetti Commerce price system can share an interface. Standard or default implementation of price system implements this interface and in this case we know that only one class implements interface which name are known. Other implementation of the interface can be defined in the customer sub-project. After maven put Avetti Commerce and sub-project together spring context will have 2 different beans which classes implement the interface. We can use spring context to find out that there is other implementation of the interface and this will be a reason of using it instead of standard implementation.

All these work to find custom implementation a proxy class should do. As a default implementation, the proxy class implements price interface too, so we can use it as reference to beans which need service of the price system. During initialization proxy class finds correct implementation of interface and initialize handler to it. Following picture demonstrates interface and classes:

ProxyClassesUsage.jpg Image 1 - Proxy Classes Usage
Store Price BO Proxy implementation

The key class is StorePriceBOProxy. It finds alternative implementation of StorePriceBO in the customer sub-project and delegates call to it:

            
    public class !StorePriceBOProxy implements IStorePriceBO, 
    ApplicationContextAware, InitializingBean {
       private final Log LOGGER = LogFactory.getLog(StorePriceBOProxy.class);
       
       private ApplicationContext applicationContext;
       private IStorePriceBO handler;
       
       
       public void setApplicationContext(ApplicationContext applicationContext) {
          this.applicationContext = applicationContext;
       }
    
       public void afterPropertiesSet() throws Exception {
          initializeHandler();
          
          if (LOGGER.isInfoEnabled())
             LOGGER.info("Instance of IStorePriceBO is " + 
                   handler.getClass().getName());
       }
    
       private void initializeHandler() {
          Collection storePriceBOBeans = applicationContext.getBeansOfType(
                IStorePriceBO.class).values();
          Iterator iter = storePriceBOBeans.iterator();
          // removing StorePriceBOProxy object
          while(iter.hasNext()){
             IStorePriceBO bean = (IStorePriceBO) iter.next();
             if (bean.getClass().equals(getClass())){
                iter.remove();
             }
          }
    
          // check and initialize alternative if it exists      
          if (storePriceBOBeans.size() == 1) {
             handler = (IStorePriceBO) storePriceBOBeans.iterator().next();
          } else {
             Iterator it = storePriceBOBeans.iterator();
             while (handler == null && it.hasNext()) {
                IStorePriceBO bean = (IStorePriceBO) it.next();
                if (!bean.getClass().equals(StorePriceBO.class))
                   handler = bean;
             }
          }
       }
    
       public Offerprices getItemPrice(String vid, String itemCode) {
           return handler.getItemPrice(vid, itemCode);
       }
    
       public List getItemsPrice(String vid, List itemCodes) { return handler.getItemsPrice(vid, itemCodes); } }
            

Now we can define beans in the Avetti Commerce:


<bean id="storePriceBOCommerce" class="com.avetti.simplemerce.store.businessobjects.StorePriceBOProxy"> <bean id="storePriceBOCommerceDefault" class="com.avetti.simplemerce.store.businessobjects.StorePriceBO"> ... </bean> </bean>
            

And in the customer sub-project:


<bean id="storePriceBOCustomerAA" class="com.avetti.customeraa.store.businessobjects.StorePriceBO"> ... </bean>
            
Design-StorePriceBOProxy.png Image 2 - Design Store Price BO Proxy

User Documentation

(for licensees only)

Developer Administration Documentation

(for licensees only)