eCommerce with Hybris: Sending emails

Any eCommerce application needs to send emails once in a while, e.g. order approval, shipping notification and the like. Enabling the eEmail sending feature in a Hybris application is a multistep process that requires creating a handful of components and custom Java classes. It might look as an overhead for such a trivial task as sending an email, but if you follow the Hybris prescribed procedures, the end users will get a convenient and useful tool. Let’s discuss the advantages of emailing the Hybris-way vs. the standard JavaMail processes.

First, we’d like to create a reusable and easily configurable email template. Since each email is a regular WCMS page you can use Content Slots and Components while composing an email. Email templates can be visually edited by admin either in WCMS cockpit or in hMC. The preparation of the email templates can be assigned to the users, having particular roles, e.g. Marketing Director. The role separation and the use of components smoothly integrates into the Hybris ecosystem, and you get it for free out of the box.

Second, you can have a different template for each locale supported by your storefront. The appropriate template will be automatically chosen based on the site your customer works with. Otherwise you should manually determine which locale to use in each particular case.

With the Hybris-way you get a well-defined business process. It means that sending emails becomes a regular business process like many other workflows in Hybris, e.g. B2B Order Approval process, Order Placement process, Customer Registration email process, etc.

Last, but not least, you can manage the steps of this process in the hMC visually. Creating such visualisation manually wouldn’t be so easy to implement.

By choosing this approach you follow a common pattern that makes the code more maintainable and easy to understand for any Hybris developer. Since each functional piece is represented as a separate component you can reuse them for different business processes. There is no need to go through a multi-step preparation process for each type of the email in your application. Otherwise there would be tens of “simple” implementations that in a long run would complicate things more than if you’d be using the Hybris recommendation.

Enough of a theory, let’s implement a simple scenario – each time a customer makes a purchase over $1 million the application should send him/her a thank-you email:

The Email Process

First of all, we need to create our business process and define which steps it consists of. The process is a regular itemtype, so let’s add it to our-items.xml (Please note that it extends StoreFrontProcess class):

<itemtype code="OneMillionPurchaseProcess"
          extends="StoreFrontProcess"
          autocreate="true"
          generate="true"
          jaloclass="com.bdi.core.jalo.OneMillionPurchaseProcess">
    <description>Sends thank-you email to the customer.</description>
</itemtype>

To define process actions let’s create/resources//processes/OneMillionPurchaseProcess.xml file:

<?xml version="1.0" encoding="utf-8"?>
<process xmlns="http://www.hybris.de/xsd/processdefinition"
         start="generateOneMillionPurchaseEmail"
         name="oneMillionPurchaseProcess"
         processClass="com.project.model.OneMillionPurchaseProcessModel"
         onError="error">

    <action id="generateOneMillionPurchaseEmail" bean="generateOneMillionPurchaseEmail">
        <transition name="OK" to="sendEmail"/>
        <transition name="NOK" to="error"/>
    </action>

    <action id="sendEmail" bean="sendEmail">
        <transition name="OK" to="removeSentEmail"/>
        <transition name="NOK" to="failed"/>
    </action>

    <action id="removeSentEmail" bean="removeSentEmail">
         <transition name="OK" to="success"/>
         <transition name="NOK" to="error"/>
    </action>

    <end id="error" state="ERROR">Something went wrong.</end>
    <end id="failed" state="FAILED">Could not send email.</end>
    <end id="success" state="SUCCEEDED">Sent thank-you email.</end>

</process>

Pay attention to the following in the above process definition file:

1. The start attribute specifies which action will be executed first. It must match exactly one of your action IDs;
2. The name attribute uniquely identifies process;
3. The processClass attribute must reference our process’s model that is generated for itemtype, thus it can be found in com. .model package and class name has the same name as our process suffixed with Model.;
4. The bean attribute of the action element references an object that will generate EmailMessage for us.

In order to add this process definition to our system we need to register it as ProcessDefinitionResource in Spring’s configuration file:

<bean id="bdiCustomerServiceAccountExistsEmailProcessDefinitionResource"
      class="de.hybris.platform.processengine.definition.ProcessDefinitionResource"
      scope="tenant">
    <property name="resource" value="classpath:/project/processes/OneMillionPurchaseProcess.xml"/>
</bean>


Notice here that our bean’s type is ProcessDefinitionResource.

In the previous step we referenced generateOneMillionPurchaseEmail bean, let’s add it to our project’s Spring configuration file (/resources/-spring.xml):

<bean id="generateOneMillionPurchaseEmail"
      class="de.hybris.platform.acceleratorservices.process.email.actions.GenerateEmailAction"
      scope="tenant"
      parent="abstractAction">
    <property name="modelService" ref="modelService"/>
    <property name="frontendTemplateName" value="OneMillionPurchaseEmailTemplate"/>
    <property name="cmsEmailPageService" ref="cmsEmailPageService"/>
    <property name="contextResolutionStrategy" ref="b2bAcceleratorProcessContextResolutionStrategy"/>
    <lookup-method name="getEmailGenerationService" bean="emailGenerationService"/>
</bean>


Pay attention to the following in the above Spring configuration file :
1. The id attribute matches bean name that we referenced in OneMillionPurchaseProcess.xml;
2. The bean is an instance of Hybris built-in GenerateEmailAction class;
3. value of frontendTemplateName is unique ID of the template that must be registered in ImpEx file. We won’t cover creating template in this article because it’s nearly identical to regular WCMS page. Actually EmailPageTemplate extends regular PageTemplate, can have the same content slots as regular page can, and provides several additional attributes.

Email Context Object

The context object keeps the data that is required to generate an email. Here is the code for our context object (the code is simplified for brevity):

 
public class OneMillionPurchaseEmailContext extends AbstractEmailContext
{
    // ...

    @Override
    public void init(final BusinessProcessModel businessProcessModel, final EmailPageModel emailPageModel)
    {
        // ...
        put(FROM_EMAIL, emailPageModel.getFromEmail());
        put(FROM_DISPLAY_NAME, emailPageModel.getFromName());
        put(DISPLAY_NAME, "BDI Customer Service");
        put(EMAIL, getCustomerEmailResolutionService().getEmailForCustomer(getCustomer()));
        // ...
    }

    @Override
    protected BaseSiteModel getSite(final BusinessProcessModel businessProcessModel)
    {
        return ((StoreFrontProcessModel) businessProcessModel).getSite();
    }

    @Override
    protected CustomerModel getCustomer(final BusinessProcessModel businessProcessModel)
    {
        return ((StoreFrontCustomerProcessModel) businessProcessModel).getCustomer();
    }
}

The above Java class extends AbstractEmailContext class. The init method does most of the work here. It defines the model and its attributes that will be accessible from the email template and also sets the email address of the recipient. You can see how we use the Email Resolution Service (see the next section) to specify the recipient’s email.

The context object must be registered in Spring configuration file (/resources/-spring.xml):

<bean id="oneMillionPurchaseEmailContext"
      class="com.project.facades.process.email.context.OneMillionPurchaseEmailContext"
      parent="abstractEmailContext"
      scope="prototype">
    <property name="customerEmailResolutionService" ref="oneMillionPurchaseEmailResolutionService"/>
</bean>


Important: the property customerEmailResolutionService references the Email Resolution Service that we are about to put into play.

Email Resolution Service

The resolution service defines an algorithm of determining the email address of the recipient. Here is how it looks like in our case:

 
public class OneMillionPurchaseEmailResolutionService extends DefaultCustomerEmailResolutionService
{
    @Override
    public String getEmailForCustomer(final CustomerModel customerModel)
    {
        return customerModel.getUid();
    }
}

The above class extends DefaultCustomerEmailResolutionService and overrides the ancestor’s getEmailForCustomer implementation. The base class’s algorithm to determine email is almost the same as our custom implementation. The difference is that if it doesn’t find the customer’s email in Uid field, it uses the “default” customer address (demo@example.com) to send the email, which is not the behavior I expect to see, I’d like to receive the explicit error in that case.

You can implement any custom application logic here, for example if it’s a B2B customer, you might want to send the thank-you email to the customer’s boss – it’s completely up to you what to do here.

Now, let’s register the resolution service in the Spring configuration file:

<bean id="oneMillionPurchaseEmailResolutionService"
      class="com.bdi.core.OneMillionPurchaseEmailResolutionService"
      scope="tenant">
    <property name="configurationService" ref="configurationService"/>
</bean>


It’s pretty straightforward, isn’t it? We keep all the default configuration, adding a unique bean name and the full name of the class.

Kicking Off the Email Sending

By this moment we have all the required pieces defined. To kick off the mailing process we use BusinessProcessService, here is the code:

 
final BusinessProcessModel oneMillionPurchaseProcessModel = getBusinessProcessService().createProcess(
        ONE_MILLION_PURCHASE_PROCESS_CODE + System.currentTimeMillis(),
        ONE_MILLION_PURCHASE_PROCESS_CODE);
getBusinessProcessService().startProcess(oneMillionPurchaseProcessModel);

Here you can cast BusinessModelProcess to your custom type and provide any custom data you need within the OneMillionPurchaseEmailContext#init method. Usually this code is wrapped into a Spring’s event listener and is triggered by sending a custom event written by a developer.

Summary

Let’s recap what benefits the Hybris emailing process gives us:

– Configurable email templates. Since each email is a regular WCMS page you can use content slots and components while composing an email.
– Localized versions of the email. You can have different templates for each locale you storefront supports.
– A well-defined business process.
– Reusable components that you can use as building blocks. Since each functional piece is represented as a separate component you can reuse this components for different business processes. You don’t need to reproduce all of these steps for each type of the email you want to have in your application.

Anton Moiseev

E-Commerce with Hybris

People are accustomed to buying goods online. If a company sells products to individuals, we call it B2C for Business To Consumers. If a business sells to other businesses – it’s B2B. Having an online store allows to sell around the clock regardless of the consumer’s location (at least within the country) as long as he or she is connected to the Internet. People spend some substantial time online and sellers are trying to reach their clients via all possible channels and devices being that a regular HTML Web page, a social network, a mobile application on any device with embedded browser. Still, some people aren’t Internet savvy and business will continue using more traditional channels like printed mail order catalogs. This is what the multi-channel marketing is about. Ideally, a business should be able to combine marketing the products with selling them right there. If you’ve seen the product commercial on Facebook or your mobile phone the storefront should be there too.

Ingredients of an online store

If I’d ask you to give me an example of an e-commerce site, most likely you’d answer Amazon or eBay. Agree. But what’s needed for building an e-commerce system? Let’s come up with a list of building blocks and solutions that Joe Smith, a CIO of the Best Stuff, Inc. would need to create an e-commerce portal:

– A shopping cart
– A catalog
– Integration with several payment systems
– Order management system
– Full text search
– High-load solutions
– Selling through social networks
– Ability to create UI supporting variety of desktop and handheld devices
– Integration with warehousing software
– Data feeds from external systems
– Consumers reviews, locator services, Web analytics
– Live video chats with customer supports

This list is not complete. Starting developing such a complex system from scratch would be insane unless you have unlimited budget and no deadlines to meet. On the other hand, trying to find a Swiss army knife solution usually translates into purchasing super expensive software with 80% of the functionality that you’ll never use. The truth is somewhere in the middle, especially in the age of Software-As-A-Service (SaaS) where you can subscribe to only what you need.

Hybris ingredients

Our company, Farata Systems has an e-commerce team that works with the Hybris software suite. For detailed comparison reviews of the e-commerce solutions refer to Gartner or Forrester. I can just offer you a Hybris review based on our real-world experience.

When we were offered to work on our first Hybris project we had to google this name up. Still, we were hired because of our solid expertise in enterprise development using Java and Spring framework, which are pre-requisites for developing software with Hybris Multi-Channel Suite.

Hybris is a well designed modularized software built on top of Apache and SpringSource components, containers and servers. We’ve been given login credentials to be able to access product Wiki and rolled up our sleeves. The software comes with an installer that includes modified Apache Tomcat servlet container, Spring modules and a home-made ORM framework for data persistence.

Finding goods

Finding goods in your online store has to be easier than in a brick and mortar one. Say you want to buy an engagement ring, but not sure if it has to be made of a white gold with diamonds or something more modest. Writing strict SQL queries is not overly flexible, but the full text search (FTS) technique allows examine all words in each document in your database rather then specifying the column names in the database table. The FTS feature give lots of flexibility in creating stores which allow to quickly find the products that closely match your customer’s needs (e.g. diamonds of certain shape, size, price range etc.) Hybris ships with the FTS module based on the fast search engine Apache SOLR (a Lucene extension). The system periodically (say, every minute) runs the data indexing process. You write queries not in SQL, but in a special query language.

Customization

This tightly integrated software allows you to create and release in production a simple online store in less than a month. But a typical store or an auction requires implementation of lots of custom solutions. For example, let’s take order fulfillment. Hybris offers off the box the basic solutions supporting order management and consignment. But in our projects we had to implement fulfillment algorithm that would take into account the distance between the warehouse and the consumer and minimize the number of shipments. For example, the customer wants to purchase twenty large screen TVs. The system has found six TV’s in one of your stores and four in the other. Since we need another ten TV’s our custom algorithm sends a request to a warehouse to order these additional TV sets. As a result – the customer will get a shipment of all twenty items shipped in a least expensive way.

Such customized business logic is implemented in Java as beans of Spring framework, which is literally a fabric of the entire Hybris software. Your code always has access to Spring context object. By adding custom extensions you create the child context object with your Spring bean containing custom logic to place a distributed order of 20 TVs.

From the software architect perspective, the ease of extending existing Hybris entities is very appealing. For example, if you need to add customer reviews features, just add a couple of fields to the Product entity, create a new entity for ProductReview and link them together. Then add a row of those yellow stars to the storefront UI and you’re set.

User Interface

With Hybris you have a complete freedom of selecting the UI platform for your online store. So far we’ve been using HTML, JavaScript and JQuery framework. But we could have used Java, Flex, or Silverlight for the UI if this would meet our needs. Hybris uses Spring MVC that can present the data as JSP pages or send the raw data as XML or JSON to the UI tier – just parse the data and display them any way you like. If you prefer an easily customizable solution, Hybris includes a CMS module, which allows you to specify the Web page layout and change it dynamically during the run-time.

Product Maintenance

Yet another interesting Hybris module is called Cockpit, which becomes quite handy in environments where the information changes quickly and the customers need to see the latest product information. We even customized Cockpit for building our own administration tool for the online auction project.

Launching Server

The launch of your Hybris server can be configured to load only those modules that are needed for your store. Our fully loaded server starts within 2 minutes, which is not bad at all. The initial install of the Hybris server comes with the in-memory HSQLDB, which is fast, but not suitable for the real-world applications. We started with MySql Server and then switched to Oracle with very minimal manual tuning.

Payment processing

Integration with the payment gateway is probably the most critical component of any online store or auction. Hybris has its own payment module, but we’ve been asked to integration with another payment processing engine – Litle.com using XML as the data exchange format. Little accepts all kinds of credit cards, PayPal, eCheck, mobile payments, and bill-me-later option. Introducing another provider in your payment workflow can make a lot of business sense, but be prepare to find yourself in the middle of the finger pointing game until you finish the payment integration. Add some more cushion there if you are making project estimates.

Scalability

Hybris comes with a clustering solution from the box. Each node of your cluster can be configured to include only those Hybris extensions that it needs. For example, you can configure a cluster with one more for the administration module, three nodes for the store UI, and one node for the data indexing.

In March of 2012 Adobe has announced its partnership with Hybris. Adobe’s CQ5 will help in creating multi-channel digital marketing campaigns and building strong brands for online stores created by Hybris.

Room for improvements

Although our overall impression after using Hybris on a couple of projects is very positive, this software has room for improvements. I’m sure, Hybris management has their reasons for keeping its community closed, but it may hurt the adoption of the software. The product documentation is not too detailed and up to date. Hybris technical experts have to pay more attention to the developer’s forum. In many cases we’ve been using the source code de-compilers to find the answers to our questions. Since Hybris is built on top of Java EE, I’d like the future versions to include a JPA-based solution that would allow using the data persistence solution of our choice rather than a proprietary ORM.

Conclusion

While finding solutions in developing software with Hybris was difficult at time, we never hit the wall, which can be credited to the engineering team. Overall, it’s a solid platform for creating modern online stores and auctions.

When we started our first e-commerce projects with Hybris, we couldn’t find any publicly available online materials about this software written by people in the trenches. I really hope that this article will help anyone who’s still in the process of selecting the right e-commerce software package for their next generation online store.

Yakov Fain