What are component type group in Hybris?

Not everything is for everyone. This simple law of nature binds everything together. A polar beer is best kept away tropical area. Your business may want to keep only coordinated banners in rotating image banners. The content slots are bounded to have only few type of components to achieve these restrictions.

Components are grouped on basis of their types. These groups are termed as ComponentTypeGroup. There is one to many relations between this group and the components. They are persisted in database. In earlier versions, the valid component list was used just as macro in impex.

This approach is more optimal than the previous one which had a slow many to many relationship between ContentSlotName and Cms Component type.

<relation code="ComponentTypeGroups2ComponentType" generate="true" localized="false" autocreate="true">
			<deployment table="CompTypeGrp2CompType" typecode="1097" />
			<sourceElement qualifier="componentTypeGroups" type="ComponentTypeGroup" cardinality="many" collectiontype="set"/>
			<targetElement qualifier="cmsComponentTypes" type="CMSComponentType" cardinality="many" collectiontype="set"/>
</relation>

There are few groups which are defined in OOB Hybris. We can also define our custom groups.



INSERT_UPDATE ComponentTypeGroup;code[unique=true]
;logo
;headerlinks
;searchbox
;minicart
;wide
;narrow
;footer
;navigation
;mobile

Each valid component type is added to the group.

INSERT_UPDATE ComponentTypeGroups2ComponentType;source(code)[unique=true];target(code)[unique=true]
;narrow;ProductFeatureComponent
;narrow;CategoryFeatureComponent

When a component type is checked against its validity for a given content slot, the system checks if it is contained in the component type group.

INSERT_UPDATE ContentSlotName;name[unique=true];template(uid,$contentCV)[unique=true][default='LandingPage4Template'];validComponentTypes(code);compTypeGroup(code)

;SiteLogo;;;logo
;HeaderLinks;;;headerlinks
;SearchBox;;;searchbox
;MiniCart;;;minicart
;NavigationBar;;;navigation
;Section1;;;wide
;Section2A;;;narrow
;Section2B;;;narrow
;Section2C;;;wide
;Section3;;;wide
;Section4;;;narrow
;Section5;;;wide
;Footer;;;footer
;TopHeaderSlot;;;wide
;BottomHeaderSlot;;;wide
;PlaceholderContentSlot;;;

Relative URLs in Hybris Cockpits

Very often in several business scenarios it is required to share direct Urls of order, cart or product with internal teams, e.g.:

After order is placed:

  • Send confirmation email to customer.

And

  • Also send email to a team of internal staff with direct URL of that order so that staff can directly go to that specific order just by clicking on URL rather than logging into cockpit and searching for that order.

Considering different nature of cockpit framework it’s not straight to create direct URL of an item as compared to storefront which is MVC.

Here is solution:

https://<hostname>:<port>/cscockpit/index.zul?persp=cscockpitPerspective&events=activation&act-item=8796093055021

Understanding URL:

A request event handler parses request parameters and dispatches a Cockpit business event. Different components are then notified of this dispatched event.

According to above URL, Activation request events is triggered for order item with pk – 8796093055021

What is the use ProductOption Enum in Hybris?

Products are core to any commerce. This is the product which drives the whole business and workflow associated with it. Be it procurement, inventory management, Media management, order management, fulfillment to name a few. Everything revolves around Product.

Essentially, this leads to having hundreds of attribute associated with products. Price, Stock , promotion, categories are few data set attached to product. Since not every page will want to have every data set to be populated. This is also not efficient to propagate all data sets to front layer.

Product Option is an Enum, which categorize hundreds of attribute of products into few data sets. For example attribute related to stocks (stock level, stock status) will be under Stock data set. Now the population of Product data will be done on the required data sets of Product Option Enum.

Take the example of Order history page, here we don’t want user to see stock data, product reviews, product delivery modes. So it is useless to populate these data sets.

 

Hybris provides a Bean class DefaultModifableConfigurablePopulator, which takes a Map of populators as one of the property. This map will contain Product Option enum as the key and corresponding populator bean id as the value.

 

<alias name="defaultProductConfiguredPopulator" alias="productConfiguredPopulator"/>
<bean id="defaultProductConfiguredPopulator" class="de.hybris.platform.commercefacades.converter.impl.DefaultConfigurablePopulator" >
<property name="populators">
<map key-type="de.hybris.platform.commercefacades.product.ProductOption">
<entry key="BASIC" value-ref="productBasicPopulatorList"/>
<entry key="PRICE" value-ref="productPricePopulatorList"/>
<entry key="PRICE_RANGE" value-ref="productPriceRangePopulator"/>
<entry key="GALLERY" value-ref="productGalleryPopulatorList"/>
<entry key="SUMMARY" value-ref="productSummaryPopulatorList"/>
<entry key="DESCRIPTION" value-ref="productDescriptionPopulatorList"/>
<entry key="CATEGORIES" value-ref="productCategoriesPopulatorList"/>
<entry key="PROMOTIONS" value-ref="productPromotionsPopulatorList"/>
<entry key="STOCK" value-ref="productStockPopulatorList"/>
<entry key="REVIEW" value-ref="productReviewPopulatorList"/>
<entry key="CLASSIFICATION" value-ref="productClassificationPopulatorList"/>
<entry key="VARIANT_FULL" value-ref="productVariantFullPopulatorList"/>
<entry key="REFERENCES" value-ref="productReferencesPopulator"/>
<entry key="DELIVERY_MODE_AVAILABILITY" value-ref="productDeliveryModeAvailabilityPopulator"/>
</map>
</property>
</bean>

 

If You want to add a new populator to the system, for example say video.

<enum class="de.hybris.platform.commercefacades.product.ProductOption">
<value>VIDEO</value>
</enum>

 

Now redefine the configureable populator bean to include your populator. Now the product data will start having your data set as well.

<alias name="videoProductConfiguredPopulator" alias="productConfiguredPopulator"/>
<bean id="myProductConfiguredPopulator" parent="defaultProductConfiguredPopulator">
    <property name="populators">
        <map key-type="com.myproject.facades.product.MyProductOption" merge="true">
            <entry key="Video" value-ref="videoOptionPopulator"/>
        </map>
    </property>
</bean>
 

 

 

Hook Interfaces and Strategies in Hybris

Customizing ordering processes could not be easier. Those were days when we used to override facades, services and strategies to inject a line of code just before or after a specific event in an ordering process. E.g. Before and After:

  • payment Authorization
  • adding product to cart
  • cart calculation lifecycle
  • cloning a saved cart
  • flagging a cart for deletion
  • Placing order
  • saving a cart
  • restoring a cart
  • updating cart entry

  Since version 5.4 onward (if I am not wrong) SAP Hybris has introduced a number of hook interfaces which can be implemented to inject your code at a specific time without hassle of overriding a chain of classes. Below is a list of few of them:

  • AuthorizePaymentMethodHook
  • CommerceAddToCartMethodHook
  • CommerceCartCalculationMethodHook
  • CommerceCloneSavedCartMethodHook
  • CommerceFlagForDeletionMethodHook
  • CommercePlaceOrderMethodHook
  • CommerceSaveCartMethodHook
  • CommerceSaveCartRestorationMethodHook
  • CommerceUpdateCartEntryHook

Usage: Implement required interface and corresponding method. And define below bean and add entry in directive: <bean id=yourCustomAddToCartMethodHook class=”xx.yy.zz”/> <bean id=“commerceAddToCartMethodHooksListMergeDirective” depends-on=“commerceAddToCartMethodHooks” parent=“listMergeDirective”> <property name=“add” ref=yourCustomAddToCartMethodHook /> </bean>    

B2B with B2C – a perfect blend of accelerators (storefronts)

One Hybris – One Accelerator – B2B and B2C – a vision few years ago has been implemented and is at its best now.

There was always need of a blend of B2B and B2C where a B2C customer might have requirement of small organisations concept(B2B units) or a B2B customer might expect a little more from promotions.

B2B features are now available across all Accelerators: in B2C accelertor  -Business units can be created along with their associated supporting elements, such as cost centers, permissions,budgets, users and user groups.

Additionally, commerceorgaddon and b2bacceleratoraddon are introduced to provide B2B storefront support to default accelerator – empowering single accelerator with all features of B2B and B2C.

Load balancer Redirection issue

In clustered environment it’s very common to terminate SSL at load balancer layer and pass non secure requests to Hybris applications servers.

This brings in some complexities if configuration is not correct.

As hybris servers get http request so in case redirection is required they redirect to same non secure protocol which is then recreated into secure request by rules configured at load balancer layer.

To avoid this unnecessary redirection and other potential session issues you have to configure all application servers to redirect to specific port and name.

Add following attributes to <Connector port=”${tomcat.http.port}” in server.xml files of all servers:

proxyPort=”443″ proxyName=”${proxyName}

proxyName – URL of application e.g. google.com

Setting up ASM (assisted service module ) and facing : “Error creating bean with name ‘getAssistedservicestorefrontBeforeViewHandler’”

Are you facing this exception while setting up Assisted Service Module:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘getAssistedservicestorefrontBeforeViewHandler’: Post-processing of FactoryBean’s singleton object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy160]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy160

Solution:

Disable Autoproxy – remove entry “<aop:aspectj-autoproxy />” from assistedservicestorefront-web-spring.xml and restart server.. boom!!