Training Notes
Training Notes
1. Help URL
http://javainsimpleway.com/hybris-b2b-installation/
2. hybrisserver.bat debug
We can see the hac at https://localhost:9002/hac. We can do following things inside hac:-
Platform/Initialization
Platform/Update
Console/Scripting Language
Console/FlexibleSearch- select {unit} from {PMProduct} where {code} = '1001400'
Console/ImpEx Import and Export
3. Recipe has to be installed for non –developers( I mean when there were no extensions needed for customizing the lookup or when
there are only a need of standard extensions, no custom extension, then we require install.bat to happen else not needed.)
STEPS
4. Navigate to the “< HYBRIS_BIN_DIR >/platform “ directory.- Set ant environment by entering the following command
• input.module parameter : Configures the modulegen task to use the accelerator module.
• input.name value : Indicates the prefix that is added to the new extensions generated by modulegen.
• input.package value : Defines the default Java package prefix.
• input.template parameter : Defines how to use the default Hybris configuration
8. After running the ant modulegen command successfully, open the ” localextensions.xml ” file located in
“< HYBRIS_HOME >/hybris/config” folder.
9. Add the new extensions generated by modulegen to the “localextensions.xml” file
<extension name="mystorefulfilmentprocess"/>
<extension name="mystorecockpits"/>
<extension name="mystorecore"/>
<extension name="mystorefacades"/>
<extension name="mystoretest"/>
<extension name="mystoreinitialdata"/>
<extension name="mystorestorefront"/>
10. As instructed in the console output, remove the following extensions which are present in your “localextensions.xml” file
yacceleratorcore
yacceleratorfacades
yacceleratorstorefront
yacceleratorinitialdata
yacceleratortest
yacceleratorcockpits
yacceleratorfulfilmentproces
After adding Any attribute- System Update must be done in hac Port with Platform/update. Only after system update, we can make
use of Model Class in Controller/Façade etc.
Populator.java
ImpEX
After loading the data in items.xml, I have to load the ImpEX(Load the data into BackOffice).
Remove
Flex Search
FLOW DIAGRAM
CONTROLLER
Service
DAO
FACADES
https://hybrisinstructive.blogspot.com/2017/12/converters-and-populators-in-hybris.html
Approach
The below diagram depicts a high level view of what we are trying to accomplish.
Implementation
The particular example we will pick is responsible for serving responsive images using the ResponsiveMediaFacade. This facade is called by a
controller SimpleResponsiveBannerComponentController.
The facades instantiate a model object either by calling the Services layer (for most cases) or by instantiating the model directly. After which,
the facade then calls the Converter which returns the DTO that the controller requires for the UI.
Before starting on implementing this you need to have an idea of what data your Storefront requires and from which model object(s) you will
need to get that data and also identify if there are any existing Converters that you can extend and modify/add existing Populators.
The following are the steps on how to define converters and Populators.
When defining a Converter we need to specify what our target object is. In other words, the DTO that we want our Converter to build.
In our example:-
The Populators property has several ways that allows for injecting either
a. Single Populator
b. List of Populators
<bean id="responsiveMediaContainerPopulator"
class="de.hybris.platform.acceleratorfacades.device.populators.ResponsiveMediaContainerPopulator">
<property name="imageConverter" ref="responsiveImageConverter"/>
</bean>
b. Development
All Populators implement the Populator<SOURCE, TARGET> interface and implement the populate method.
The populate method can be as simple as getting and setting values from the Model object (Source) to the target (DTO) or calling Services to get
additional data or calling other convertors to get another DTO.
public void populate(final MediaContainerModel source, final List<ImageData> target) throws ConversionException
{
populateImages(source, target, ImageDataType.GALLERY); //GALLERY by default
}
Here we call the converters covert method or the convertAll which invokes all the populators defined for that convertor in sequence.
In our example this is being done in the getImagesFromMediaContainer. Hopefully this gave you better idea not only how to implement this
pattern but also on the reasons behind why SAP Commerce uses this pattern.
Assignment
Step 1. Stop the server and
Step 2. Add attributes in Items.xml
a.
b.
c.
Day 3.
CronJobs
Caching Level
1. Attribute level
2. Item Level
Cluster
Service Layer
Java Changes- Ant All
Implementing Service
Overriding the default service
Overiding defaultImportService to pmDefaultImportService
Lifecycle of a model
Interceptors Overview
Preferred way is of line no. 22. ProductModel pm=modelService.create(ProductModel.class);
At line 29, When we do save, Prepare and validate interceptor will be called before saving. Any Modification/Update operation can also be
done in prepared Interceptor before saving the model into database.
Description =Name+Code+sequence
Line 33, Validate Interceptor will be used for mandatory values like if code is null, it will be handled here.
POJO
Populators in Code
<bean id="trainingProductPopulator"
class="org.training.facades.populators.TrainingPopulator"></bean>
<bean parent="modifyPopulatorList">
<property name="list" ref="productConverter"/>
<property name="add" ref="trainingProductPopulator"/>
</bean>
/**
*
*/
package org.training.facades.populators;
import de.hybris.platform.commercefacades.product.data.ProductData;
import de.hybris.platform.converters.Populator;
import de.hybris.platform.core.model.product.ProductModel;
import de.hybris.platform.servicelayer.dto.converter.ConversionException;
/**
* @author muhammad.ayzaz
*
*/
public class TrainingProductPopulator implements Populator<ProductModel, ProductData>
{
/*
* (non-Javadoc)
*
* @see de.hybris.platform.converters.Populator#populate(java.lang.Object, java.lang.Object)
*/
@Override
public void populate(final ProductModel source, final ProductData target) throws ConversionException
{
// XXX Auto-generated method stub
System.out.print("Call is here");
System.out.print("Call ends");
target.setMobile(source.getMobileNumber());
}
}
Items.xml
<itemtype code="Product" extends="Product"
autocreate="false" generate="false">
<description>Demo training product.</description>
<attributes>
<attribute qualifier="mobileNumber"
type="localized:java.lang.String">
<description>mobile number for Training
Products</description>
<modifiers />
<persistence type="property" />
</attribute>
</attributes>
</itemtype>
===training bean fascade xml======
<bean
class="de.hybris.platform.commercefacades.product.data.ProductData">
<property name="mobile" type="String" />
</bean>
-----training bean springxml
<bean id="trainingProductPopulator"
class="org.training.facades.populators.TrainingProductPopulator"></bean>
<bean parent="modifyPopulatorList">
<property name="list" ref="productConverter"/>
<property name="add" ref="trainingProductPopulator"/>
</bean>
POPULATOR Implementation
/**
*
*/
package org.training.facades.populators;
import de.hybris.platform.commercefacades.product.data.ProductData;
import de.hybris.platform.converters.Populator;
import de.hybris.platform.core.model.product.ProductModel;
import de.hybris.platform.servicelayer.dto.converter.ConversionException;
/**
* @author amarnath
*
*/
public class TrainingProductPopulator implements Populator<ProductModel, ProductData>
{
/*
* (non-Javadoc)
*
* @see de.hybris.platform.converters.Populator#populate(java.lang.Object, java.lang.Object)
*/
@Override
public void populate(final ProductModel source, final ProductData target) throws ConversionException
{
// XXX Auto-generated method stub
System.out.print("Call is here");
System.out.print("Call ends");
target.setMobile(source.getMobileNumber());
JSP Implementation
2. Go to Backoofice in Catalog/Products
And search the copied Id in the search bar and click on Online One.
Go to Administration block and find using ctrl+f- attribute added= mobileNumber and save.
Need of Solr-
- Solr is defacto search engine, document search. Most ecommerce used solr as json based query..
- The disadvantage is that it does not have access control.
Need to work
Address Verification
Pincode Verification, Validating the addresses- External Api. Most common used Address verification is Avalara.
HOP- Hosted Order Page (When the payment is done, there must be a host page where you go to a host page like payment provider
page.)
SOP-(Silent Order Page)- The Main Page will internally being integrated in the Main Page with No host page.
OMS- Order management system- Order Lifecycle is maintained with separate licencing contest.
Product Bundling- Two Products are managed to provide services to customer.
One Store has multiple sites. However will be same with multiple sites.
India, The site is taken from 3rd party make use of it.
Catalog-1. Product Cataog 2. Content Catalog
Cart and Order
Check cronjob-
select {code} from {servicelayerjob} where {code} = 'TrainingCronJob'
INSERT_UPDATE Trigger;cronjob(code)[unique=true];cronExpression
;TrainingCronJob;5 * * ? * *
Backoffice
CheckOut
productVolumePricesProvider
ant startSolrServer
https://localhost:8983/solr
solrserver
server123
Commerce Detailed View Links
PaymentTypeCheckoutStepController
PaymentTypeFormValidator
DeliveryAddressCheckoutStepController
DeliveryMethodCheckoutStepController
ChooseDeliveryMethodPage
ChooseDeliveryMethodPage.jsp
DefaultCommerceDeliveryModeStrategy
SummaryCheckoutStepController.java
GuidKeyGenerator
CartPageController
CommercePriceService.java Interface
DefaultCommercePriceService
CommerceStockService
DefaultDiscountService
DefaultTaxService
productVolumePricesProvider
ProductStockLevelStatusValueProvider
SOLR
https://localhost:8983/solr
solrserver
server123
productSearchFacade
DefaultSolrProductSearchService
SolrSearchRequestResponsePopulator
http://techhybris.com/sap-hybris-customizing-solr-search-queries/
https://hybrismart.com/apache-solr-search-in-sap-hybris/
http://javainsimpleway.com/
ecommercecandles hybris
CMSSiteFilter
1905
https://help.sap.com/viewer/3fb5dcdfe37f40edbac7098ed40442c0/1905/en-US
SimpleResponsiveBannerComponentController
ProductAddToCartComponentModel
productaddtocartcomponent.jsp
addtocartaction.jsp
AddToCartController
addtocartpopup.jsp
WCMS
Site Component
Cms- are the component like here as cockpit, lib and core . We can create a new or extend existing cms.
Different components
Hierarchical Structure
Content slots only where we have put component
CMS Restrictions
Banner
Backoffice
https://192.168.3.127:9002/cmscockpit/index.zul
Through Impex
Checkout Hands On
PROMOTIONs
Go to façade code and find the promotion data is set in product façade.
Note: - You will check there are two methods define which are used for GET and POST condition.
There are two Façade also, On which userFacade is having Titles and CustomerFacade has Other Attributes.
You will get to know the Data and Model defined for the same.
trainingfacades-spring.xml
i. Making changes for showing only attribute in PDP page. We need to do some changes in
controller for Form Page.
j. Get Model Form added for customValue in .java file using setter and Getter and do ant all.
Till now, You can do all ant all and update in hac and see the attribute in PDP page But to make some more
changes like to do Get and POST functionality.
n. Now, for GET and POST we need to make changes in GET and POST Method and Also create
some Interface classes and extend those in custom Classes.
o. For Get is already done. For POST add the below code.
p. FAÇADE LAYER: -Open the implementation of update profile in Façade.
--------------
Similarly implement the same and Create a custom Façade(Interface and class) and do the implementation for
the same in Façade Layer.
Note: The Interface has extended the Product Interface and the Method updateProfile has same method
definition Structure as of the Product Interface(Check in the Product Interface)
Note It has extended the Product Façade class and Implemented the Custom Façade Interface.
Also code for the implementation of Service Class as done in the Product By see how the Product has
implemented.
q. SERVICE LAYER: -It will call the Service Interface Layer and then Implementation.
The below same code must be used in the interface of Custom Definition Layer.
Similarly define your own Interface extending the Parent Interface and Implement the class by implementing
this custom Interface and extending product Class.
Note add your attribute wherever required.
Note It has extended the Product Service class also and extended Interface.
Just Call your own Façade in controller and define the same
Just make changes in Façade Layer.
2. Go to eclipse do ctrl +h and paste the page title and in properties file.
Copy the text above and paste it in ctrl+ h with .jsp ,.tag file.
To Make Changes for Attribute Field Name in the PDP Page:
Search the Existing Value using f12 and copy the label name.
Search the same in Project
Check Out
Search
Why I was getting server error in FB Storefront?
Note: - Whenever You trigger the storefront, The first Java File triggered is CMSSiteFilter.
1. We will have the Json file and we will trigger the same in Postman by importing the file in postman.
2. Import the Json request file into Postman from local place.
Response
{
"TransactionId": "79d30f2f63e54751b769d6cd47207632",
"Branch": {
"BranchId": "473",
"Products": [
{
"Sku": "280002fgf7adgdagdha",
"Description": "",
"Barcode": "",
"UnitOfMeasure": "",
"StatusCode": "",
"StockMessage": "",
"Quantity": "0",
"Code": "2",
"Message": "Invalid Sku"
},
{
"Sku": "2800050",
"Description": "GIB STANDARD 3600X1200 10MM WALLBOARD",
"Barcode": "9416463115402",
"UnitOfMeasure": "ST",
"StatusCode": "3",
"StockMessage": "Ring Branch for Availability",
"Quantity": "0",
"Code": "0",
"Message": ""
}
]
},
"ServiceResult": {
"Code": 2,
"Message": "Some of the Skus are not valid"
}
}
3. Now our task is to convert the Json String into Java for response and request.
TransactionId- String
Branch- Java Class which has Branch Id (String)and Products(Java which has Skus,Unit measure,Description, etc as string ).
Service Result: - Also a Java which has Code and Message as String.
4. Let us name the Request as: PMSyncStockRequest.java and similarly for Response (PMSyncStockResponse.java).
ACEServiceResult.java
ACEStockBranchResponse.java
ACEStockProductInfoResponse.java
PMSyncStockRequest.java
PMSyncStockResponse.java
8. Till Now Only Request is checked. We have to make changes for Response and convert the response seen above from Json String to
Java String.
a. AceStockUtil.java- This will handle all the functionality for JSon String.
e.g. constructDynamicJsonInput –Preparing the request by concatenating the SKUs(List of Searches Units by
converting them from list to Array of String.) with Other Values like Branch Id and Txn Id.
final PMSyncStockRequest request = new PMSyncStockRequest(BRANCH_ID, TXN_ID,
convertToStringArray(skus));
This is the actual Testing Java Class which has main method with sending List of products (Here Stocks as SKUs). Also It will have all the urls
Linked to Requests.(Shown Below)
executeDynamicProductStock:- It will have the actual execution with Calling of the client and returning the string of response.
constructMapFromAceResponse: - It will construct the response into Map and return
back.
3.
Note: - Everything will be same replicating in Hybris only The data we are Hardcoding has to be changed in to local.properties.
Ant all
Like Below:
One Small Correction:-
While Testing the data fetched from search were a string data and has some decimal values. Because of which, I was getting exception.
Searchresultsgridcomponent.jsp
productListerGridItem.tag
BackOffice
Adding Bearer Token from HAC
Go to Platform/configuration
Step 8.
Do the following Things :- Take any product id from storefront and add the value here mobile Number
BackOffice-> Catalogs->Products
Under Administration
Go to Backoffice->System->Search and Navigation -> Indexed Types-> Select Powertools Product Type-
>Index Properties and Add the custom Attribute
Like below
Go inside facet Search Configuration of Search and Navigation category only and add refresh index
After update hac
Go to solr page
Write below query code with product id and execute the query
Find your changes in the result by ctrl+f =mobileNumber and see the change which has been done in
backOffice.
Once it is coming you can see the same in the PLP page for same Product Id.
http://javainsimpleway.com/wcms-overview/
https://help.sap.com/viewer/86dd1373053a4c2da8f9885cc9fbe55d/1905/en-US/
4cf11877c72143419a948f06943c62d3.html
http://hybrisdeepdive.com/index.php/2018/06/16/details-of-page-slots-components-and-content-
slots/
http://javainsimpleway.com/adding-new-cms-component/
In Brief about WCMS
http://www.hybriscx.com/sap-hybris/sap-hybris-how-to-create-a-new-page-wcms/
GIT HUB:-
WCMS – Part of hybris platform which facilitate to create manage and render website content.
Components are basically Areas on JSP for adding the dynamic contents. (Dynamic content in
the context of HTML and the World Wide Web refers to website content that constantly or
regularly changes based on user interactions, timing and other parameters that determine
what content is delivered to the user.). At top level we have page templates. Page
template contains multiplepage slots. Page slots contains multiple components and then
each component can contain multiple content slots.
A cms component consists of three elements interact with one another : Model, JSP
and Controller.
Model : identify the component with a uid, name, catalog version and also holds
the inputs to be sent to the JSP.
JSP : is the template of the component, describe the look and feel of it.
Controller : is the mediator between the Model and the JSP, inputs are sent
from the Model to the JSP with the help of it.
SMART EDIT
https://hybrismart.com/2019/04/14/smartedit-a-deep-dive-into-technical-aspects-of-the-new-cms-
personalizationcapabilities/
Key Components
Modes of Smart Edit
https://help.sap.com/viewer/86dd1373053a4c2da8f9885cc9fbe55d/1905/en-US/
6fd6968e127f4acdba68eaac672e18fa.html
https://help.sap.com/viewer/86dd1373053a4c2da8f9885cc9fbe55d/1905/en-US/
dffe44f9de0b414b80c7163f54f96514.html
Procedure
https://help.sap.com/viewer/86dd1373053a4c2da8f9885cc9fbe55d/1905/en-US/
8927a5e262e04f3aa1f4ede0051ffc5b.html
https://hybrisinstructive.blogspot.com/2018/12/custom-component-in-hybris.html
ProductCarouselComponentController.java
productcarouselcomponent.jsp
http://javainsimpleway.com/how-to-add-new-custom-cms-component-type-to-a-page-in-hybris/
Workflow of Adding a New Custom Component
Core
Service- NA
Façade- NA
Controller
JSPs
fbstorefront\web\webroot\WEB-INF\views\responsive\cms\customselectcomponent.jsp
2. Add below component into the Home Page jsp using CMS Tags at fbstorefront\web\webroot\WEB-INF\views\responsive\pages\
layout\landingLayout2Page.jsp
# -----------------------------------------------------------------------
# Copyright (c) 2018 SAP SE or an SAP affiliate company. All rights reserved.
# Information and shall use it only in accordance with the terms of the
# -----------------------------------------------------------------------
$contentCatalog=placemakersContentCatalog
$contentCatalogName=placemakers Content Catalog
$contentCV=catalogVersion(CatalogVersion.catalog(Catalog.id[default=$contentCatalog]),CatalogVersion.version[default=Online])
[default=$contentCatalog:Online]
$productCatalog=placemakersProductCatalog
$productCV=catalogVersion(catalog(id[default=$productCatalog]),version[default='Staged'])[unique=true,default=$productCatalog:Staged]
$picture=media(code, $contentCV);
$image=image(code, $contentCV);
$media=media(code, $contentCV);
$page=page(uid, $contentCV);
$contentPage=contentPage(uid, $contentCV);
$product=product(code, $productCV)
$category=category(code, $productCV)
$siteResource=jar:com.fb.initialdata.constants.FbInitialDataConstants&/fbinitialdata/import/sampledata/contentCatalogs/$contentCatalog
$productResource=jar:com.fb.initialdata.constants.FbInitialDataConstants&/fbinitialdata/import/sampledata/productCatalogs/
$productCatalog
$jarResourceCms=jar:com.fb.initialdata.constants.FbInitialDataConstants&/fbinitialdata/import/sampledata/cockpits/cmscockpit
$addonExtensionName=b2bacceleratoraddon
$medias=medias(code, $contentCV);
$mediaContainer=media(qualifier, $contentCV);
$siteUid=placemakers
# Language
$lang=en
INSERT_UPDATE CustomSelectComponent;
$contentCV[unique=true];uid[unique=true];name;selectVar1[lang=$lang];selectVar2[lang=$lang];&componentRef;
INSERT_UPDATE ContentSlot;$contentCV[unique=true];uid[unique=true];name;active;cmsComponents(&componentRef)
INSERT_UPDATE ContentSlotForPage;$contentCV[unique=true];uid[unique=true];position[unique=true];page(uid,$contentCV)[unique=true]
[default='homepage'];contentSlot(uid,$contentCV)[unique=true]
;;customSelectContentslotforpage-Homepage;CustomSelectSlotName;;customSelectContentSlot
STOREFRONT
CART CUSTOMIZATION
1. git status
2. git branch
3. git pull origin feature/dashboard
4. git add {path}
5. git diff {modified Values in path} – to check the modified changes
6. git commit -m "Changes for Team Invite Dash Board | On Behalf of Mohinder"
7. git push origin feature/dashboard
Steps:-