How to enable QR code in SAP Commerce?

In this blog I would like to showcase how I created capability to generate a Barcode of QR code type and how you can use similar steps to enable and generate QR codes in SAP commerce.

Barcodes are used to convey information visually. We’ll most likely provide an appropriate barcode image in a web page, email, or a printable document.

QR(Quick Response) Codes are becoming the most widely recognised 2D barcodes worldwide.

The big benefit of the QR code is that we can store large amounts of data in a limited space.

Use Case : Generate a QR code on Product details page(PDP) which can be scanned using a Barcode/QR code scanner on mobile device to provide a link to visit product details page from your website to your mobile device, creating an omni-channel experience.

Note : For simplicity purpose I have used link of PDP inside a QR code although you can have any type of link like a Wishlist or paragraph information as well concealed in it.

Technical Details:

Pre-requisite/Setup: 

I have created myprojectstorefront using modulegen and enabled Electronics storefront in my local system for demo.
In case you want to understand how modulegen is used to generate electronics storefront please check this SAP Help page: Customizing the B2C Accelerator to Have B2B and B2C Storefronts

Barcode Library Used

I have used the following  Open Source Java Barcode Libraries can be used to generate barcodes in custom extension in SAP commerce:

  • Barcode4j : It offers 2D barcode formats – like QR code , DataMatrix and PDF417 – and more output formats. 

Note: There are other open source libraries such as ZXing also available at your disposal to accomplish similar task, but for out article we are going forward with Barcode4j.

Solution:

  • Add Barcode4j library to external-dependencies.xml of myprojectfacades
    as shown below code snippet:
     <dependency> <groupId>net.sf.barcode4j</groupId> <artifactId>barcode4j</artifactId> <version>2.1</version> </dependency>

    Important : To generate barcode4j.2.1.jar on ant build you need to make sure that usemaven=“true” in /myprojectfacades/extensioninfo.xml.

    Result : Run ant clean all and you should be able to see barcode4j.2.1.jar in lib folder in lib folder.

  • Generate QR code On Load of Product data

    Generate QR code in myprojectFacades extension by creating Custom Facade and extending DefaultProductFacade<ProductModel> and over-ridding getProductForCodeAndOptions function.
  • Create a BarcodeMediaModel ( which is an Out-of-Box(OOB) Model provided in SAP Commerce ) on load of each product and add link of product as data of QR code to be scanned.
  • Assign that BarcodeMediaModel  to ProductModel
    I have added new attribute to store barcode media model in myprojectcore-items.xml for product model.
    Below is code snippet for the same:
    <attribute autocreate="true" qualifier="productQRCode" type="BarcodeMedia"> <modifiers read="true" write="true" search="false" optional="true" /> <persistence type="property" /> </attribute>

    IMPORTANT: Please run System update after this change.

  • Populate and Show BarcodeMediaModel to Frontend PDP page by adding it to ProductData by converting BarcodeMediaModel to MediaData using OOB mediaModelConverter
    as shown below.
  • Custom Java Code Snippet:
public class CustomProductFacade extends DefaultProductFacade<ProductModel>
{ private static final Logger LOG = Logger.getLogger(CustomProductFacade.class); @Resource(name = "mediaService") MediaService mediaService; @Resource(name = "mediaModelConverter") Converter<MediaModel, MediaData> mediaModelConverter; @Override public ProductData getProductForCodeAndOptions(final String code, final Collection<ProductOption> options) { final ProductModel productModel = getProductService().getProductForCode(code); try { if (null == productModel.getProductQRCode()) { final BufferedImage QRImage = this.generateQRCodeImage("https://localhost:9002/myprojectstorefront/en/USD/p/" + code); LOG.info("finished generateQRCodeImage "); final String filePath = "productQRCode.png"; final int size = 125; final File qrFile = new File(filePath); final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ImageIO.write(QRImage, "png", outputStream); // Passing: ​(RenderedImage im, String formatName, OutputStream output) final InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); LOG.info("Created Input stream "); final BarcodeMediaModel barcodeMediaModel = getModelService().create(BarcodeMediaModel.class); barcodeMediaModel.setCatalogVersion(productModel.getCatalogVersion()); barcodeMediaModel.setCode("productQRCode" + productModel.getCode()); barcodeMediaModel.setRealFileName("productQRCode" + productModel.getCode() + ".png"); barcodeMediaModel.setBarcodeText("https://localhost:9002/myprojectstorefront/en/USD/p/" + code); barcodeMediaModel.setBarcodeType(BarcodeType.QR); getModelService().save(barcodeMediaModel); getModelService().refresh(barcodeMediaModel); mediaService.setStreamForMedia(barcodeMediaModel, inputStream); final Collection<BarcodeMediaModel> barcodeMediaList = new ArrayList<>(); barcodeMediaList.add(barcodeMediaModel); productModel.setProductQRCode(barcodeMediaModel); getModelService().saveAll(barcodeMediaModel, productModel); LOG.info("Created Barcode media model in product "); } } catch (final Exception e) { e.printStackTrace(); } final ProductData productData = getProductConverter().convert(productModel); final MediaData mediaData = mediaModelConverter.convert(productModel.getProductQRCode()); productData.setProductQRCodeMedia(mediaData); if (options != null) { getProductConfiguredPopulator().populate(productModel, productData, options); } return productData; } public static BufferedImage generateQRCodeImage(final String barcodeText) throws Exception { LOG.info("Inside generateQRCodeImage "); final QRCodeWriter barcodeWriter = new QRCodeWriter(); final BitMatrix bitMatrix = barcodeWriter.encode(barcodeText, BarcodeFormat.QR_CODE, 200, 200); return MatrixToImageWriter.toBufferedImage(bitMatrix); }
  • Spring Entries in /resources/myprojectfacades-spring.xml
    <alias name="customProductFacade" alias="productFacade"/> <bean id="customProductFacade" class="com.hybris.myproject.facades.impl.CustomProductFacade" parent="defaultProductFacade" /> 
  • Bean entry and Product Data code in /resources/myprojectfacades-beans.xml updated for frontend rendering:
    <bean class="de.hybris.platform.commercefacades.product.data.ProductData"> <property name="genders" type="java.util.List&lt;com.hybris.myproject.facades.product.data.GenderData>"/> <property name="productQRCodeMedia" type="de.hybris.platform.cmsfacades.data.MediaData" /> </bean>​
  • Add following code in /myprojectstorefront/web/webroot/WEB-INF/tags/responsive/product/productDetailsPanel.tag
    <img src="${fn:escapeXml(product.productQRCodeMedia.url)}" />

     

DEMO :
Below are some screenshots of how PDP will be rendered after making above changes.

Please note that it is a localhost demo hence all URLs and links will be in localhost:9002 format.

PDP page view:

PDP%20page%20view%20showing%20QR%20code%20generated%20in%20Frontend

Figure 1: PDP page view showing QR code generated in Frontend. * Click to enlarge

Backoffice View for Product having Barcodes:

Click on below shown Media model in Product Model in backoffice:

Product%20model%20linked%20to%20Barcode

Figure 2 : Product model linked to Barcode* Click to enlarge

Barcode%20Media%20In%20Backoffice

Figure 3 : Barcode Media In Backoffice* Click to enlarge

Scan QR codes using a barcode scanner in your mobile device:

You will be able to see encoded link which you have provided in JAVA code above as below:

https://localhost:9002/myprojectstorefront/en/USD/p/553637

Using above approach you can enable and generate different type of barcodes depending on your requirements.

Thanks for reading.

You should now be able to enable QR code in SAP Commerce cloud code and show it on your accelerator storefront.
Please feel free to share feedback and your thoughts on this topic.

Related Links: