Installing Paazl's extension for SFCC SiteGenesis

This article explains how to install Paazl's extension in your Salesforce CC SiteGenesis implementation.

Note

The Paazl LINK cartridge can be used out of the box with A controller-based SiteGenesis - version 104.0.0

You can use it with other versions but you may need to make additional adjustments.

Step 1. Install LINK cartridge

Install the int_paazl_controllers and int_paazl_core cartridges in Commerce Cloud UX-studio.

Step 2. Import metadata

To add Paazl configuration functionality to Business Manager, import Paazl's predefined metadata as follows:

  1. Download the Paazl LINK installation package from https://github.com/SalesforceCommerceCloud/link_paazl
  2. Open the link_paazl-master/site_import/sites/ folder
  3. Rename the yourSiteId folder to your site's ID in Salesforce CC Business Manager
  4. Zip the site_import folder
  5. Import the zipped file into Business Manager (Administration > Site Development > Site Import & Export).

After the import, the following changes will have been made to Business Manager.

Paazl attributes will have been added to:

  • Administration > Site Development > System Object Types > Site Preferences > Attribute Definitions
  • Administration > Site Development > System Object Types > Order > Attribute Definitions
  • Administration > Site Development > System Object Types > Shipment > Attribute Definitions
  • Administration > Site Development > System Object Types > Basket > Attribute Definitions

The following services will have been added to Administration>Operations > Services:

  • service.paazl.rest.gettoken
  • service.paazl.rest.getSelectedOption

The paazl shipping method will have been added to [yourSiteId] > Merchant Tools > Ordering > Shipping Methods.

Step 3. Customize Storefront code

If you are using SiteGenesis, you need to add Paazl-specific code to the Storefront Controller (app_storefront_controller) and Storefront Core (app_storefront_core). The files you need to modify and the code changes you need to make are given below.

Storefront controller

The files you need to modify are:

  • controllers/COShipping.js
  • controllers/COBilling.js
  • controllers/COSummary.js

You will find them under app_storefront_controllers>cartridge.

COShipping.js

Modify the 'updateShippingMethodList' function in COShipping.js as follows.

Original
// line # 348
app.getView({
    Basket: cart.object,
    ApplicableShippingMethods: applicableShippingMethods,
    ShippingCosts: shippingCosts
}).render('checkout/shipping/shippingmethods');
Modified
// paazl related changes
var template = 'checkout/shipping/shippingmethods';
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var currentPaazlShippingMethodID = paazlHelper.getShippingMethodID();
var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
var paazlWidgetInit;
var paazlWidgetCustomizedStyle;
if (paazlStatus.applicable) {
    template = 'checkout/shipping/paazl_shippingmethods';
    if (cart) {
        var currentBasket = cart.object;
        paazlHelper.updateTokenInBasket(currentBasket);
        paazlWidgetInit = require('*/cartridge/scripts/init/initPaazlWidget').initPaazlWidget()
    }
 
    // If 'paazlWidgetPredefinedStyle' is set on CUSTOMIZED, fetch the customized style from the 'paazlWidgetCustomizedStyle' site preferences
    var paazlWidgetPredefinedStyle = Site.current.getCustomPreferenceValue('paazlWidgetPredefinedStyle');
    if (paazlWidgetPredefinedStyle.value === 'CUSTOMIZED') {
        paazlWidgetCustomizedStyle = Site.current.getCustomPreferenceValue('paazlWidgetCustomizedStyle');
    }
 
    var isPaazlUniqueShippingOption = false;
    if (applicableShippingMethods && applicableShippingMethods.length === 1) {
        if (applicableShippingMethods[0].ID === currentPaazlShippingMethodID) {
            isPaazlUniqueShippingOption = true;
        }
    }
}
 
app.getView({
    Basket: cart.object,
    ApplicableShippingMethods: applicableShippingMethods,
    ShippingCosts: shippingCosts,
    paazlWidgetInit: paazlWidgetInit, // paazl view-data variables
    paazlStatus: paazlStatus, // paazl view-data variables
    paazlWidgetCustomizedStyle: paazlWidgetCustomizedStyle, // paazl view-data variables
    currentPaazlShippingMethodID: currentPaazlShippingMethodID, // paazl view-data variables
    isPaazlUniqueShippingOption: isPaazlUniqueShippingOption // paazl view-data variables
}).render(template);

Modify the 'singleShipping' function in COShipping.js as follows.

Original
// line # 222
handleShippingSettings(cart)
Modified
if (!handleShippingSettings(cart)) {
    // If selected shipping method is Paazl but no Paazl shipping options are available or selected, stay on the Shipping page
    app.getController('COShipping').Start();
    return;
}

Open COShipping.js, go to 'handleShippingSettings' function line 125 and replace entire function with the one below

/**
 * Handles the selected shipping address and shipping method. Copies the
 * address details and gift options to the basket's default shipment. Sets the
 * selected shipping method to the default shipment.
 *
 * @transactional
 * @param {module:models/CartModel~CartModel} cart - A CartModel wrapping the current Basket.
 * @returns {boolean} return status
 */

function handleShippingSettings(cart) {
    var result = true;
    Transaction.wrap(function () {
        var defaultShipment, shippingAddress;
        defaultShipment = cart.getDefaultShipment();
        shippingAddress = cart.createShipmentShippingAddress(defaultShipment.getID());
        shippingAddress.setFirstName(session.forms.singleshipping.shippingAddress.addressFields.firstName.value);
        shippingAddress.setLastName(session.forms.singleshipping.shippingAddress.addressFields.lastName.value);
        shippingAddress.setAddress1(session.forms.singleshipping.shippingAddress.addressFields.address1.value);
        shippingAddress.setAddress2(session.forms.singleshipping.shippingAddress.addressFields.address2.value);
        shippingAddress.setCity(session.forms.singleshipping.shippingAddress.addressFields.city.value);
        shippingAddress.setPostalCode(session.forms.singleshipping.shippingAddress.addressFields.postal.value);
        shippingAddress.setStateCode(session.forms.singleshipping.shippingAddress.addressFields.states.state.value);
        shippingAddress.setCountryCode(session.forms.singleshipping.shippingAddress.addressFields.country.value);
        shippingAddress.setPhone(session.forms.singleshipping.shippingAddress.addressFields.phone.value);
        defaultShipment.setGift(session.forms.singleshipping.shippingAddress.isGift.value);
        defaultShipment.setGiftMessage(session.forms.singleshipping.shippingAddress.giftMessage.value);
        var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
        paazlHelper.resetSelectedShippingOption(cart.object);
        var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
        if (paazlStatus.active) {
            var paazlShippingOption = paazlHelper.getSelectedShippingOption(cart.object);
            if (!paazlShippingOption) {
                result = false;
            }
        } else {
            cart.updateShipmentShippingMethod(cart.getDefaultShipment().getID(), session.forms.singleshipping.shippingAddress.shippingMethodID.value, nullnull);
        }
        cart.calculate();
        cart.validateForCheckout();
    });
    return result;
}

Modify the 'start' function in COShipping.js as follows.

Original
// line # 109
app.getView({
    ContinueURL: URLUtils.https('COShipping-SingleShipping'),
    Basket: cart.object,
    HomeDeliveries: homeDeliveries
}).render('checkout/shipping/singleshipping');
Modified
// Paazl related changes
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
var paazlWidgetInit;
if (paazlStatus.applicable) {
    if (cart) {
        var currentBasket = cart.object;
        paazlHelper.updateTokenInBasket(currentBasket);
        paazlWidgetInit = require('*/cartridge/scripts/init/initPaazlWidget').initPaazlWidget()
    }
}
app.getView({
    ContinueURL: URLUtils.https('COShipping-SingleShipping'),
    Basket: cart.object,
    HomeDeliveries: homeDeliveries,
    paazlWidgetInit: paazlWidgetInit, // Paazl view-data variables
    paazlStatus: paazlStatus // Paazl view-data variables
}).render('checkout/shipping/singleshipping');

COBilling.js

Modify the 'publicStart' function in COBilling.js as follows.

Original
// line # 191
start(cart, {ApplicableCreditCards: creditCardList.ApplicableCreditCards});
Modified
var params = {
    ApplicableCreditCards: creditCardList.ApplicableCreditCards
};
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
params.paazlStatus = paazlStatus;
// Check whether or not Paazl is enabled
if (paazlStatus.active) {
    // If Paazl is active, add Paazl selected shipping option info to the data model
    var paazlShippingModel = paazlHelper.getPaazlShippingModel(cart.object);
    params.paazlShipment = paazlShippingModel;
}
start(cart, params);

COSummary.js

Modify the 'showConfirmation' function in COSummaryjs as follows.

Original
// line # 97
app.getView({
    Order: order,
    ContinueURL: URLUtils.https('Account-RegistrationForm'// needed by registration form after anonymous checkouts
}).render('checkout/confirmation/confirmation');
Modified
// Paazl related changes
var params = {
    Order: order,
    ContinueURL: URLUtils.https('Account-RegistrationForm'// needed by registration form after anonymous checkouts
};
var shipment = order.defaultShipment;
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var paazlStatus = paazlHelper.getPaazlStatus(shipment);
// Check whether or not Paazl is enabled 
if (paazlStatus.active) {
    // If Paazl is active, update the order shipping address with Paazl shipping address - only in case of pickup location delivery
    paazlHelper.updateShipment(order);
    // Add Paazl selected shipping option info to the data model
    var paazlShippingModel = paazlHelper.getPaazlShippingModel(order);
    params.paazlShipment = paazlShippingModel;
    params.paazlStatus = paazlStatus;
}
app.getView(params).render('checkout/confirmation/confirmation');

Modify the 'start' function in COSummary.js as follows.

Original
// line # 48
var pageMeta = require('~/cartridge/scripts/meta');
var viewContext = require('app_storefront_core/cartridge/scripts/common/extend').immutable(context, {
    Basket: cart.object
});
pageMeta.update({
    pageTitle: Resource.msg('summary.meta.pagetitle''checkout''SiteGenesis Checkout')
});
app.getView(viewContext).render('checkout/summary/summary');
Modified
var pageMeta = require('~/cartridge/scripts/meta');
pageMeta.update({
    pageTitle: Resource.msg('summary.meta.pagetitle''checkout''SiteGenesis Checkout')
});
// Paazl related changes
var params = {
    Basket: cart.object
};
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
var paazlStatus = paazlHelper.getPaazlStatus(cart.object && cart.object.defaultShipment);
params.paazlStatus = paazlStatus;
// Check whether or not Paazl is enabled
if (paazlStatus.active) {
    // If Paazl is active add paazl select shipping option info to the data model
    var paazlShippingModel = paazlHelper.getPaazlShippingModel(cart.object);
    params.paazlShipment = paazlShippingModel;
}
var viewContext = require('app_storefront_core/cartridge/scripts/common/extend').immutable(context, params);
app.getView(viewContext).render('checkout/summary/summary');

Storefront core

The files you need to modify are:

  • scripts/cart/calculate.js
  • templates/default/checkout/minisummary.isml
  • templates/default/checkout/pt_checkout.isml
  • templates/default/checkout/shipping/singleshipping.isml
  • templates/default/components/order/orderdetails.isml
  • js/pages/checkout/shipping.js
  • scss/default/_checkout.scss

You will find them under app_storefront_core>cartridge.

calculate.js

Modify calculate.js as follows.

Original
// line # 62
ShippingMgr.applyShippingCost(basket);
Modified
ShippingMgr.applyShippingCost(basket);
var paazlHelper = require('*/cartridge/scripts/helpers/paazlHelper');
paazlStatus = paazlHelper.getPaazlStatus(basket.defaultShipment);
// If Paazl is active, apply Paazl shipping rate to the current basket
if (paazlStatus.active) {
   paazlHelper.calculateShipping(basket);
}

minisummary.isml

Modify minisummary.isml as follows.

Original
// line # 48
<isinclude template="checkout/shipping/minishipments"/>
Modified
<iscomment>If Paazl enabled and selected , use the template paazl_minishipments to render the shipment summary</iscomment>
<isif condition="${pdict.paazlStatus && pdict.paazlStatus.active}" >
   <isinclude template="checkout/shipping/paazl_minishipments" />
<iselse/>
   <isinclude template="checkout/shipping/minishipments"/>
</isif>

pt_checkout.isml

Open pt_checkout.isml and add the following code to the <head></head> section of the template

<isif condition="${dw.system.Site.current.getCustomPreferenceValue('paazlEnabled') && dw.system.Site.current.getCustomPreferenceValue('paazlWidgetEndpoint')}">
    <script type="text/javascript" src="${dw.system.Site.current.getCustomPreferenceValue('paazlWidgetEndpoint')}"></script>
    <script src="${URLUtils.staticURL('/js/paazl.js')}" defer></script>
</isif>

Open pt_checkout.isml, and, just above the <isreplace/> tag in the <body></body> section, replace <div id="primary" class="primary-content"> with the following code:

<div id="primary" class="primary-content js-addressservice-url" data-addressservice-url="${URLUtils.https('Paazl-AddressNL')}">

Open pt_checkout.isml and add the following code to the <body></body> section of the template just below the <isreplace/> tag

<isreplace/>
<isif condition="${dw.system.Site.current.getCustomPreferenceValue('paazlEnabled')}" >
   <isinclude template="/checkout/initPaazlWidget" />
</isif>

singleshipping.isml

Modify singleshipping.isml as follows.

Original
// line # 24
<form action="${URLUtils.continueURL()}" method="post" id="${pdict.CurrentForms.singleshipping.shippingAddress.htmlName}" class="checkout-shipping address form-horizontal">
Modified
form action="${URLUtils.continueURL()}"method="post" id="${pdict.CurrentForms.singleshipping.shippingAddress.htmlName}" name="${pdict.CurrentForms.singleshipping.shippingAddress.htmlName}" class="checkout-shipping address form-horizontal ${pdict.paazlStatus && pdict.paazlStatus.applicable ? 'js-paazlwidget-form': ''}">

orderdetails.isml

Modify orderdetails.isml as follows.

Original
// line # 114
<isif condition="${!empty(shipment.shippingMethod)}">
   <div class="value"><isprint value="${shipment.shippingMethod.displayName}"/></div>
<iselse/>
   <div class="value"><isprint value="${shipment.shippingMethodID}"/></div>
</isif>
Modified
<isif condition="${pdict.paazlStatus && pdict.paazlStatus.active}">
   <iscomment>If paazl enableb, use passed pazzlShipment instead </iscomment>
   <div class="value"><isprint value="${pdict.paazlShipment.shippingMethodModel.description}"/></div>
<iselseif condition="${!empty(shipment.custom.paazlSelectedShippingMethod)}">
   <div class="value"><isprint value="${shipment.custom.paazlSelectedShippingMethod}"/></div>
<iselseif condition="${!empty(shipment.shippingMethod)}">
   <div class="value"><isprint value="${shipment.shippingMethod.displayName}"/></div>
<iselse/>
   <div class="value"><isprint value="${shipment.shippingMethodID}"/></div>
</isif>

And

Original
// line # 92
<isminishippingaddress p_shipment="${shipment}" p_editable="${false}" p_showmethod="${false}" p_showpromos="${false}"/>
Modified
<isif condition="${pdict.paazlStatus && pdict.paazlStatus.active}">
   <iscomment>If paazl enabled and selected, use the passed pazzlShipment object instead </iscomment>
   <isminishippingaddress p_shipment="${pdict.paazlShipment}" p_editable="${false}" p_showmethod="${false}" p_showpromos="${false}"/>
<iselse/>
   <isminishippingaddress p_shipment="${shipment}" p_editable="${false}" p_showmethod="${false}" p_showpromos="${false}"/>
</isif>

shipping.js

Open shipping.js and add the following lines of code code after the '}' at line 138.

//Paazl related changes
$('body').trigger('shipping:updateShippingMethods', {
    shipping: {
         shippingMethodID: $shippingMethodList.find('.input-radio:checked').val()
    }
});

Modify shipping.js as follows.

Original
// line # 124
$shippingMethodList.load(smlUrl, function () {
Modified
// line # 124
$shippingMethodList.load(smlUrl, function (data) {

Open shipping.js and add the following line of code after line 77.

//Paazl related changes
$('body').trigger('shipping:updateShippingMethods', { shipping : {shippingMethodID: shippingMethodID} });

_checkout.scss

Open _checkout.scss and add the following lines of code to the end of the file.

#paazl-checkout {
    footer {
        background-color: inherit;
    }

Step 4. Compile JS and CSS

The Paazl JS and CSS files are part of the int_paazl_core cartridge.

  1. Compile the JS and CSS code of the app_storefront_core cartridge as explained in SiteGenesis README.md.
  2. Compile the JS and CSS code of the int_paazl_core cartridge.
    1. Go to the top level of your project (just above the cartridges folder).
    2. Make sure that you are using the package.json and webpack.config.js files in the link_paazl repository in GitHub.
    3. Execute the following command:

      npm install

    4. Execute the following commands:

      npm run compile:js && npm run compile:scss

Was this article helpful?