How to create data transfer object(DTO), Converter and populator, Facade?

In this blog, we will explain the process of creating a data transfer object(DTO), Converter and populator, facade. We will show you the process of calling facade from the controller class and defining spring bean and its properties. We will create one model attribute and populate it. We will modify the UI by making a change in the tag file.

We take one example and this example explains how to show cart subtotal without taxes. Remember that there are many other ways by which we can show cart subtotal without taxes but we took the following approach to explain the above points.

Show cart subtotal without taxes/How to show cart subtotal without taxes?

Currently in SAP Hybris Commerce Accelerator when we add products to the cart then it shows cart subtotal with taxes. You can observe this in below image where we added one product to the cart in the apparel storefront that shows cart subtotal with taxes.

cart subtotal with taxes

Now here our goal is to show cart subtotal without including taxes. To achieve this goal we do not make any changes in OOB(out of the box) files but we use them from our created custom files to achieve this goal. We need to follow the following steps to achieve this goal.

  1. Create data transfer object(DTO)
  2. Create converter and populator
  3. Create facade and populate the data
  4. Call the facade from CartPageController/ Modify CartPageController
  5. Modify the cartTotal.tag file

1. Create data transfer object(DTO)

Now we will create one DTO(data transfer object) class named as SubTotalWithOutTax and it contains one property called as a sub of PriceData type. This sub property will hold the value of order subtotal without taxes.

Steps to create SubTotalWithOutTax DTO class

  1. Navigate to yacceleratorfacades->resources and open yacceleratorfacades-beans.xml.
  2. Add the following lines of code to yacceleratorfacades-beans.xml file.
    SubTotalWithOutTax DTO class
    Note: This entry must be between <beans> </beans> tag.
  3. Build the hybris system by running ant clean all.
    After successful build we can check our SubTotalWithOutTax DTO(data transfer object) class at the specified package and the file will look like this.

    SubTotalWithOutTax.java
    SubTotalWithOutTax.java

     

2. Create converter and populator

Before learning how to create converter and populator we need to know why we need converters and populators?

Now we will create a converter and populator for our SubTotalWithOutTax DTO(data transfer object) class. We need to follow the following steps to create a converter and populator.

  1. Now we create SubTotalWithOutTaxPopulator to fill the data in SubTotalWithOutTax DTO(data transfer object) class as you can see in the below image. SubTotalWithOutTaxPopulator implements the Populator interface.
    SubTotalWithOutTaxPopulator.java
    SubTotalWithOutTaxPopulator.java

     

  2. Navigate to yacceleratorfacades->resources and open yacceleratorfacades-spring.xml. Now we define a spring bean for the new SubTotalWithOutTaxPopulator and SubTotalWithOutTaxConverter as shown in below image.
    yacceleratorfacades-spring.xml
    yacceleratorfacades-spring.xml

     

  3. Build the hybris system by running ant clean all.

3. Create facade and populate the data

Generally, facade classes are created to call the services and to fill the data in DTO(data transfer object) class using converters and populators.

In our case, we create one DefaultBitbyteCartFacade class that implements BitbyteCartFacade interface. Through this class, we make a call to CartService and populate the data in SubTotalWithOutTax DTO class using converter and populator.

We need to follow the following steps to create BitbyteCartFacade

  1. Navigate to yacceleratorfacades->src and create an interface named as BitbyteCartFacade. as you can see in the below image

    BitbyteCartFacade.java
    BitbyteCartFacade.java
  2. Now we provide the implementation for the BibyteCartFacade interface in DefaultBitbyteCartFacade class.

    DefaultBitbyteCartFacade.java
    DefaultBitbyteCartFacade.java
  3. Navigate to yacceleratorfacades/resources and open yacceleratorfacades-spring.xml. Now we define a spring bean for the new DefaultBitbyteCartFacade as shown in below image.

    Spring Bean for Facade
    yacceleratorfacades-spring.xml
  4. Build the hybris system by running ant clean all.

4. Call the facade from CartPageController/Modify CartPageController

CartPageController is permitted to use annotation-based declaration so we inject BitbyteCartFacade as shown below in CartPageController.

BitbyteCartFacade bean Injection
CartPageController.java

Now add following lines of code inside prepareDataForPage method

Setting Model Attribute
CartPageController.java

Build the hybris system by running ant clean all.

5. Modify the cartTotal.tag file

Navigate to yacceleratorstorefront->web->webroot->WEB-INF->tags->cart and open cartTotal.tag file.

Replace the following lines of code with line number 14 and 15 to this file as shown in the image.

cartTotals.tag
cartTotals.tag

After saving this file, refresh apparel storefront and you can clearly observe that subtotal of the cart does not include taxes.

Cart Subtotal Without Taxes

Interceptor in SAP Hybris Commerce

Interceptor

An interceptor addresses a particular step in the life cycle of a model. When the life cycle reaches a certain step, you can activate a corresponding interceptor. An interceptor can modify the model, raise an exception to interrupt the current step or publish an event if the model matches certain criteria. For example, you could check that an attribute contains certain values before saving the model.

In easy words, we can say that anything that intercepts something else is called an interceptor. We can take one example to explain interceptor concept in a real-life scenario. We take one example where a person wants to watch a movie in the cinema hall. Now we will see how an interceptor is used in this scenario.

Interceptor Example

In the above diagram, we can see that one person went to the cinema hall and his journey intercepted at the ticket checking counter. Here Diamond(Has ticket) works as an interceptor. If a person has a ticket then he is permitted to watch a movie. If he doesn’t have a ticket then he is redirected to buy a ticket at the ticket counter.

What is the model’s life cycle?

This question is asked in hybris interviews. Here I am trying to explain this so it can help you in cracking hybris interview.

A model represents a state in the database. The representation is not live, that means that modified model values are not written to the database automatically. Instead, when you modify a model, you must explicitly save it to the database to have its state reflected there.

Model Life cycle
Model Life Cycle

Phases in the Model’s life cycle

There are four phases in the model’s life cycle.

  1. Instantiating the model
  2. Modifying model values
  3. Saving Model Values
  4. Removing the model

 

1. Instantiating the model

This can be done by either creating a new Model instance or by loading a Model from the database.

  1. Creating a model instance:- Visit link Model service create method vs new operator.
  2. Loading an existing model from the database is possible either by using pk or by using a query expression.
    Example:- UserModel user = modelService.get(pk);    [loading using primary key]

2. Modifying model values

We can modify the properties of the model if required.

3. Saving model values

If a model is created or modified. We save back the model to update the database. If we have used a new model, a new record is inserted/created in the database, otherwise, the existing record is updated.

4. Removing the model

If the model is no longer needed, the database record is deleted.

We can use interceptors to hook into the model’s life cycle.

Types of interceptors

  1. Load interceptor

    The load interceptor is called whenever a model is loaded from the database. You may want to use this interceptor if you want to change the values of the model after load. An exception raised during execution prevents the model from being loaded. To use this interceptor we must implement LoadInterceptor interface.

  2. InitDefaults Interceptor

    The InitDefaults interceptor is called when a model is filled with its default values. This happens either when it is created via the modelService.create method or when the modelService.initDefaults method is called. You can use this interceptor to fill the model with additional default values defined in the items.xml. To use this interceptor we must implement InitDefaultsInterceptor interface.

  3. Prepare interceptor

    The Prepare interceptor is called before a model is saved to the database before it is validated by Validate interceptors. Use this to add values to the model or modify existing ones before they are saved. An exception is raised during execution prevents the model from being saved. Prepare interceptor is called before the Impex translators. To use this interceptor we must implement PrepareInterceptor.

  4.  Validate interceptor

    The Validate interceptor is called before a model is saved to the database after is been prepared by the Prepare interceptors. We can use Validate interceptor to validate values of the model and raise an InterceptorException if any values are not valid. To use this interceptor we must implement ValidateInterceptor.

  5.  Remove Interceptor

    The Remove interceptor is called before a model is removed from the database. We can use this interceptor to prevent the removal of the model by raising an InterceptorException. To use this interceptor we must implement RemoveInterceptor.

How to register an interceptor?

After implementing an interceptor, we need to register it as a spring bean. The steps involved in registering an interceptor as followed:-

  1. Navigate to  customExtension->resources and open customExtension-spring.xml. Add the following line of code to this file.
    Custom Interceptor Bean
  2. In this step, we will do Interceptor mapping as shown in below image.
    Interceptor Mapping

Backoffice Customization

What is Backoffice Framework?

Backoffice Framework is new SAP Hybris Backoffice Framework designed to facilitate the creation of business tools and user interfaces in an easy and consistent way. It is shipped with SAP Hybris Commerce in the backoffice extension. It makes it possible to create a variety of components that can be reused later on in all kinds of applications. These components are standalone and deployable widgets can be easily modified without touching the code base.

In this tutorial, we will show you, how to create a custom widget using the Backoffice Framework. Our custom widget will have one input and one submit button. Suppose we enter some input and press the button, If the entered value is an integer then one pop up appears and it contains a message that Input value is an integer otherwise it will display an error that entered input is not an integer.

Steps to create a custom widget

  1. Create a custom  backoffice extension

  2. Create a widget definition

  3. Creating a widget view

  4. Create a service for widget/Use existing service for a widget

  5. Create a controller for the widget

  6. Build and start the server

  7. Deploy the widget

1. Create a custom  backoffice extension

Here we will create one custom backoffice extension named hybrisdiary using the BackOffice template extension. In this custom backoffice extension (hybrisdiary) we can create our custom widgets. To create custom backoffice extension(hybrisdiary) follow the following steps:-

  1. Open the command prompt and navigate to  <%HYBRIS_HOME_DIR%>/hybris/bin/platform directory and run the setantenv.bat file as shown in below image.setantenv.bat
  2. Now run ant extgen command.ant extgen
    Extgen prompts you to specify values for the technical aspects of an extension. Extgen comes with default values for all these technical aspects.
    These default values are defined in the project.properties file in the extgen directory. The default value is displayed in brackets ([ and ])
  3. Now we enter ybackoffice as shown in below image.ybackoffice
  4. Now enter extension name hybrisdiary as shown in below image.
    hybrisdiary custom backoffice name
  5. Now enter the package name(de.hybris.hybridiary) as shown in below  image
    package name
  6. If you want to register  SASS support for your extension then press enter otherwise type false and then press enter. Here we are using default value so we will press enter.
  7. If you want to create sample widget then press enter otherwise type false and then press enter. Here we are creating sample widget so will press enter.
  8. If you want to create a sample style sheet then type true and then press enter. If you do not want to create a sample style sheet then simply press enter.
    SASS extension sample widget sample style sheet
  9. Navigate to <%HYBRIS_HOME_DIR%>/config and open local.properties file and specify the following entry and save it.
    backoffice.sass.enabled=true
  10. Now run ant sasscompile from the platform.
    ant sasscompile
  11. Now we will add our custom backoffice extension(hybrisdiary) to localextensions.xml
    localextensions.xml
  12. Now we will do ant clean all.
    ant clean all

If the build successful then your custom backoffice extension successfully generated. If you are using eclipse then import your custom backoffice extension in to eclipse.

2. Create a widget definition

To create a widget definition, we must keep in mind that widget-definition id must be unique. If your widget-definition id matches with existing widget-definition id then your new widget will not appear on the list of widgets in the choose widget wizard. Now do the following steps to create the widget definition:-

  1. Navigate to hybrisdiary->backoffice->Resources->widgets and create a new folder called as mycustominput
    mycustominput folder location
  2. Now create a definition.xml file inside the newly created folder(mycustominput).
  3. Now add the following lines of code to the file(definition.xml).

    definition.xml
    definition.xml

3.Creating a widget view

The view of our widget will be defined in the ZUL file and the name of the file must match with last part of the widget ID as defined in the definition.xml file. The last part of widget ID is mycustominput so the view file name will be mycustominput.zul. In mycustominput.zul file, we will define all frontend component. To check whether the entered input is an integer or not we need one textbox for input and one button to submit. So we will define one textbox and one button in mycustominput.zul file. Now follow the following steps to create the widget view:-

  1. Now create a mycustominput.zul file inside the mycustominput folder.
  2. Now add the following lines of code to the mycustominput.zul file.
    mycustominput.zul
    mycustominput.zul

     

4.Create a service for widget/ Use existing service for a widget

For our example, we need some service to do some action. Either we can create our custom service to do some logic or we can use existing services. In our example, we will create a custom service that will check that the entered input is an integer or not. To create a service for our custom widget, we need to follow the following steps:-

  1. Navigate to hybrisdiary->src folder and create MyCustomInputService.java file in de.hybris.hybrisdiary.mycustominput package.
  2. Add the following lines of code to the MyCustomInputService.java file.

    MyCustomInputService.java file
    MyCustomInputService.java
  3. Navigate to hybrisdiary->resources and open hybrisdiary-backoffice-spring.xml file and define the bean for MyCustomInputService as shown in below image.
    mycustominputservice bean
    mycustominputservice bean

     

5. Create a controller for the widget

Here we have not defined any action for submit button so when we click on the button nothing will happen. To do some action we need to define a controller for the widget. To create a controller for the custom widget we need to follow the following steps:-

  1. Navigate to hybrisdiary->backoffice/src and create MyCustomInputController.java in de.hybris.hybrisdiary.widgets.mycustominput package.
  2. Add the following lines of code to the file.

    MyCustomInputController
    MyCustomInputController.java
  3. Navigate to hybrisdiary->backoffice->Resouces->widgets->mycustominput and open definition.xml file and we add a controller class to this file as shown in the image.

    definition.xml
    definition.xml

6.Build and start the server

Now we will build the system by running ant clean all and we start the server by running the hybrisserver.bat file.

7.Deploy the widget

Now we will deploy our custom widget. To deploy the custom widget do the following steps:-

  1. Open the internet browser.
  2. Enter https://localhost:9002/backoffice  in the browser’s address bar.
  3. Enter your credentials and log in.
    backoffice login
  4. Press F4 to enter into Application Orchestrator mode and click on the symbol(+ symbol inside an orange circle) to add the new widget as shown in below image.
    Application Orchestrator mode
    Application Orchestrator mode

    The choose widget appears, which contain all the available widgets and choose My Custom Input widget. You can easily learn the process of adding a widget to backoffice by observing the image.
    add widget process

  5. Now press F4 to enter into normal mode and you will see the newly added widget in backoffice.
    new widget in backoffice
  6. Now we enter 54 in the input box and which is an integer and we press the submit button. Now message box will appear which show us that “input value is an integer“.
    working widget

Navigation management in SAP Hybris Commerce

Navigation management through impex

When we create a website based on an existing content catalog, a default navigation structure is created for our content catalog. If we create a website based on a new content catalog, we must build navigation structure for our new content catalog. So we will learn here how to create navigation nodes using impexes.

Create new navigation node using impex

To explain this we will create one new custom navigation node in apparel storefront. In apparel storefront, there are 5 navigation nodes as shown in the image and we will add another navigation node at the end of navigation nodes.

Apparel Store
Apparel Storefront

Steps to create a new navigation node

Step-1

Create a new CMSNavigationNode. Like created in below image.

CMSNavigationNode

Step-2

Create a new CMSNavigationEntry for CMSNavigationNode. Like created in below image.

CMSNavigationEntry

Step-3

Create a new CMSLinkComponent. Like created in below image.

CMSLinkComponent

Step-4

In this step, we do localization of CMSNavigationNode and CMSLinkComponent as shown in the image

Localiztion

The complete impex will look like this.

create_navigation_node
new_navigation_node.impex

Here we assume that your server has started already. Now run the above impex(new_navigation_node.impex) in HAC(Hybris Administration Console) and synchronize the content catalog(apparel-ukContentCatalog).

Now access the apparel storefront and you can clearly observe newly created navigation node. In below image, you can see new custom navigation node.

Apparel store with new node
Apparel store with new navigation node

Create Children nodes of Custom navigation nodes

Now we will create children of above-created navigation node. To create children of above-created navigation node, we need to follow the following steps

Step-1

Create a new CMSNavigationNode. Like created in below image.

ChildrenCMSNavigationNode

Custom Brands Nav Node is a child of Custom Nav Node and Custom Brands Nav Node is the parent of bitbyte Link and hybrisdiary Link.

Navigation tree structure

Step-2

Create a new CMSNavigationEntry for children nodes. Like created in below image.

CMSNavigationEntry For Children

Step-3

Create a new CMSLinkComponent. Like created in below image.

CMSLinkComponentForChildren

Step-4

In this step, we do localization of CMSNavigationNode and CMSLinkComponent as shown in the image.

Children's localization

The complete impex will look like this.

Complete impex for children node
new_navigation_children_node.impex

Here we assume that your server has started already. Now run the above impex(new_navigation_children_node.impex) in HAC(Hybris Administration Console) and synchronize the content catalog(apparel-ukContentCatalog).

Now access the apparel storefront and Hover on custom navigation node and you can clearly observe newly created children(HYBRISDIARY and BITBYTE) of custom navigation node. In the below image you can observe.

Apparel store with Childrens
Apparel store with new navigation node and with its children

Hot Deployment – Hybris

Introduction

In this tutorial I will be covering the configuration of JRebel with Hybris. With JRebel configured you will be able to modify java source classes and compile them on the fly.

“No need to build and start the server again and again”

The configuration is very simple, just 3 steps and you are good to go!

Step 1

  • Download JRebel: Archive can be downloaded from the below link http://zeroturnaround.com/software/jrebel/download/prev-releases/
  • Extract the zip file at a location of your preference, for eg: C:/jrebel
    unzip
  • Active JRebel:
    – Go inside bin folder of JRebel.
    – Start the activation utility by running “activate-gui.cmd” file.
    – It will open a Jrebel activation window. The window will contain 2 tabs:
    Try JRebel    for free and I already have a license.Choose Try JRebel for FREE and fill the basic information.

jrebelfreeform
OR
Buy a license and fill the information in the I already have a license section.

Step 2

  • Add the below given property in local.properties file
    tomcat.javaoptions=-agentpath:C:/jrebel/lib/jrebel64.dll
    ** change the version of the jrebel[XX].dll according to the machine specifications.

 Creation of rebel.xml file:
– You will be required to add the rebel.xml file in the resource folder of each extension.

rebel.png

– Create a new rebel.xml class and copy/paste the below given content into the file:

<?xml version=”1.0″ encoding=”UTF-8″?>
<application xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance&#8221; xmlns=”http://www.zeroturnaround.com&#8221; xsi:schemaLocation=”http://www.zeroturnaround.com http://update.zeroturnaround.com/jrebel/rebel-2_1.xsd”&gt;
<classpath>
<!– Make sure to replace Absolute_Path with your concrete values –>
    <dir name=”{Absolute_Path}/classes”/>
</classpath>
</application>

**   The absolute path should be the complete path to the classes folder.
Example: C:/hybris/bin/custom/demo/demofacades/classes

***The classes folder is the compiled source folder of Hybris and not IDE’s(eclipse).

Step 3

  • Change the IDE(eclipse) compile output path in “.classpath” file of the extension.classpath.png
    TO
    classpath1.png
    Path structure:
    path.png
    All the configurations are completed.You just need to recompile the code from IDE(eclipse) after making the changes in the Java source file.For Eclipse you need to do the below mentioned step:

    • Just go to Project -> Clean
    • Select “Clean projects selected below” option and select the extensions which contains the modified java source classes.
    • Select “Start build immediately”.
    • Select “Build only the selected projects”.
    • Press OK and you are done!

Understanding Spring Events in Hybris

We humans are known to celebrate certain milestones in our life journey. We do celebrate birth, tying knots etc. Similarly, in the buying journey of a customer, there are few milestones which are worth celebrating or react to. Order placement, registration of a customer is few of them. The reaction could be about sending a welcome email, or sending the order data to a third party system for fulfillment.

Further, let’s say, a customer registered on a web site, and wants to start browsing the cool products. But the lousy code of sending a fancy welcome email with a promotional voucher in it, took around one minute. He will regret his decision to register, and will walk away.

spring-listener.jpg

Spring based events, provides the exact same infrastructure. So now we know, whenever we have a situation where some lousy code is to be executed after some thing happens (an event), we will rely on events.

 First we need to create an Event class, that will hold the necessary data to pass to the listener.

protected AbstractCommerceUserEvent initializeEvent(final AbstractCommerceUserEvent event, final CustomerModel customerModel)
{
event.setBaseStore(getBaseStoreService().getCurrentBaseStore());
event.setSite(getBaseSiteService().getCurrentBaseSite());
event.setCustomer(customerModel);
event.setLanguage(getCommonI18NService().getCurrentLanguage());
event.setCurrency(getCommonI18NService().getCurrentCurrency());
return event;
}

Spring provides a way to publish an event.

getEventService().publishEvent(initializeEvent(new RegisterEvent(), customerModel));

There are dedicated listeners lying around, who listens to these wishes, and reacts the way, they are programmed.

Listeners can be bonded to publishing services via common event object.

public class RegisterEventListener extends AbstractEventListener
{
   @Override
   protected void onEvent(final AbstractEvent event)
   {
      if (event instanceof RegisteEvent)
      {
          // Do whatever you want. send email/voucher or whatever
      }
   }
}

Please note that since, listener code starts in a new thread, it will not hamper customer journey on your site. The listener code will execute as a back end process.

Adding a new attribute to edit view area in Product Cockpit.

I was working on a Project and there was a requirement to add a new attribute in edit view area In Product Cockpit.

I followed these few step to do this task.

1.Create a new Model e.g MyProduct that extends ProductModel in Items.xml, add attribute in this model e.g:

“<itemtype code=”MyProduct” extends=”Product”>
<description>my product that contains additional attributes.</description>
<attributes>
<attribute qualifier=”attribute1″ type=”localized:java.lang.String”>
<description>example for product cockpit</description>
</attribute>
</attributes>
</itemtype>”

after this,Build the project and start the server, do Update running system from Hac.

Add some product in your “Myproduct” Model.

2.Create  a editorArea_MyProduct.xml file in your Cockpit extension and add key for new attribute in xml file

editorArea_MyProduct

3. Localized the key name in  ProjetcNamecockpits-locales_en.properties and i3-label.properties file.

ProjetcNamecockpits-locales_en

 

4.Restart the server and do update from HAC. Open ProductCockpit in url “http://localhost:9001/productcockpit&#8221; and search your product which you added in “MyProduct” model .

5.Open that product and in left side you will find your new attribute in Editor_area.

Capture1