> For the complete documentation index, see [llms.txt](https://developer.esw.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developer.esw.com/shopify/salesforce-commerce-cloud/cartridge-setup/sitegenesis.md).

# Sitegenesis

## Customizing the code

When customizing the ESW integration in SiteGenesis, you must ensure changes are applied to the correct cartridge and file paths.&#x20;

### <i class="fa-memo-circle-check" style="color:$primary;">:memo-circle-check:</i> Templates

{% tabs %}
{% tab title="header.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/components/header/header.isml`

#### Description

Loads ESW landing page, ESW header, app resources, and loader based on ESW module status and preferences.

{% code expandable="true" %}

```html
<iscontent type="text/html" charset="UTF-8" compact="true" />

<isset name="eswHelper" value="${require('*/cartridge/scripts/helper/eswHelper').getEswHelper()}" scope="page" /> <!-- [!code focus] -->

<div class="top-banner" role="banner">
<h1 class="primary-logo">
  <a href="${URLUtils.url('Home-Show')}">
    <img src="${URLUtils.staticURL('/images/logo.png')}" alt="Store" />
  </a>
</h1>

<nav id="navigation" role="navigation">
  <isif condition="${eswHelper.getEShopworldModuleEnabled() && eswHelper.getEnableLandingPage() && request.httpParameterMap.get(dw.system.Site.current.getCustomPreferenceValue('eswCountryUrlParam')).stringValue}"> <!-- [!code focus] -->
    <isinclude url="${URLUtils.url('EShopWorld-GetEswLandingPage')}" /> <!-- [!code focus] -->
  </isif> <!-- [!code focus] -->

<div class="header-search">
  <isinclude template="search/simplesearch" />
</div>
```

{% endcode %}
{% endtab %}

{% tab title="footer.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/components/footer/footer.isml`

#### Description

Loads ESW footer content if the ESW module is active.

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}">
  <isinclude url="${URLUtils.url('EShopWorld-GetEswFooter', 'pageContextType', pageContext.type, dw.system.Site.current.getCustomPreferenceValue('eswCountryUrlParam'), pdict.CurrentHttpParameterMap.get(dw.system.Site.current.getCustomPreferenceValue('eswCountryUrlParam')))}"/>
</isif>
```

{% endtab %}

{% tab title="footer\_UI.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/components/footer/footer_UI.isml`

#### Description

Injects ESW frontend scripts and styles.

```html
<script defer type="text/javascript" src="${URLUtils.staticURL('/js/EswHooks.js')}"></script>
<link rel="stylesheet" href="${URLUtils.staticURL('/css/EswCss.css')}" />
```

{% endtab %}

{% tab title="cart.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/checkout/cart/cart.isml`

#### Description

Controls checkout button rendering, ESW validation messages, and converted pricing display.\
Use the `EShopWorld-GetConvertedPrice` controller to convert prices.

```html
<button id="btnCheckout" class="button-fancy-large<isif condition="${eswHelper.getEShopWorldModuleEnabled() && eswHelper.isESWSupportedCountry()}"> btnCheckout</isif>" type="submit" value="${Resource.msg('global.checkout','locale',null)}" name="${pdict.CurrentForms.cart.checkoutCart.htmlName}">
```

```html
<button id="btnCheckout" class="button-fancy-large<isif condition="${eswHelper.getEShopWorldModuleEnabled() && eswHelper.isESWSupportedCountry()}"> btnCheckout</isif>" disabled="disabled" type="submit" value="${Resource.msg('global.checkout','locale',null)}" name="${pdict.CurrentForms.cart.checkoutCart.htmlName}">
```

```html
<iselseif condition="${pdict.BasketStatus.code != null && pdict.BasketStatus.code=='EswError'}">
  ${Resource.msg('cart.eswerror','esw',null)}
<iselseif condition="${pdict.BasketStatus.code != null && pdict.BasketStatus.code=='EswProductRestrictedError'}">
  ${Resource.msg('cart.esw.product.notavailable','esw',null)}
<iselse/>
</isif>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}"> 
  <span class="price-standard"><isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', StandardPrice, 'noAdjustment', false)}"/></span>
  <span class="price-sales"><isprint value="${eswHelper.getSubtotalObject(lineItem, false, false, true)}" /></span>
<iselse>
  <span class="price-standard"><isprint value="${StandardPrice}" /></span>
  <span class="price-sales"><isprint value="${SalesPrice}" /></span>
</isif>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}"> 
  <isprint value="${eswHelper.getSubtotalObject(lineItem, false, false, true)}" />
<iselse>
  <isprint value="${SalesPrice}" />
</isif>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}">
  <isprint value="${eswHelper.getSubtotalObject(lineItem,false, true)}" />
<iselse>
  <isprint value="${lineItem.getPrice()}" />
</isif>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}">
  <isprint value="${eswHelper.getSubtotalObject(lineItem,false)}" />
<iselse>
  <isprint value="${lineItem.getAdjustedPrice()}" />
</isif>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}">
  <isprint value="${eswHelper.getSubtotalObject(lineItem,false)}" />
<iselse>
  <isprint value="${lineItem.getAdjustedPrice()}" />
</isif>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}">
  <span class="price-standard"><isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', StandardPrice, 'noAdjustment', false)}"/></span>
  <span class="price-sales"><isprint value="${eswHelper.getSubtotalObject(lineItem, false, false, true)}" /></span>
<iselse>
  <span class="price-standard"><isprint value="${StandardPrice}" /></span>
  <span class="price-sales"><isprint value="${bonusProductPrice}"/></span>
</isif>
```

```html
<button class="button-fancy-large<isif condition="${eswHelper.getEShopWorldModuleEnabled() && eswHelper.isESWSupportedCountry()}"> btnCheckout</isif>" type="submit" value="${Resource.msg('global.checkout','locale',null)}" name="${pdict.CurrentForms.cart.checkoutCart.htmlName}">
  ${Resource.msg('global.checkout','locale',null)}
</button>

<button class="button-fancy-large<isif condition="${eswHelper.getEShopWorldModuleEnabled() && eswHelper.isESWSupportedCountry()}"> btnCheckout</isif>" disabled="disabled" type="submit" value="${Resource.msg('global.checkout','locale',null)}" name="${pdict.CurrentForms.cart.checkoutCart.htmlName}">
  ${Resource.msg('global.checkout','locale',null)}
</button>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled() && eswHelper.isESWSupportedCountry()}">
  <iscontentasset aid="esw-checkout-disclaimer-message" />
</isif>
```

{% endtab %}

{% tab title="minicart.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/checkout/cart/minicart.isml`

#### Description

Displays subtotal and checkout link, with logic for ESW subtotal and disclaimer message.\
`eswHelper.getSubtotalObject(pdict.Basket, true)` calculates order totals using ESW FX and adjustments.\
The `btnCheckout` class redirects to ESW Checkout when enabled and supported.

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}">
  <isprint value="${eswHelper.getSubtotalObject(pdict.Basket,true)}"/>
<iselse>
  <isprint value="${pdict.Basket.getAdjustedMerchandizeTotalPrice(false).add(pdict.Basket.giftCertificateTotalPrice)}"/>
</isif>
```

```html
<a class="mini-cart-link-checkout<isif condition="${eswHelper.getEShopWorldModuleEnabled() && eswHelper.isESWSupportedCountry()}"> btnCheckout</isif>" href="${URLUtils.https('COCustomer-Start')}" title="${Resource.msg('minicart.directcheckout','checkout',null)}">
  ${Resource.msg('minicart.directcheckout','checkout',null)} &raquo;
</a>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled() && eswHelper.isESWSupportedCountry()}">
  <iscontentasset aid="esw-checkout-disclaimer-message" />
</isif>
```

{% endtab %}

{% tab title="orderdetails.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/components/order/orderdetails.isml`

#### Description

Renders ESW payment values and tracking information per order context.

{% code expandable="true" %}

```html
<isscript>
  var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper();
  var formatMoney = require('dw/util/StringUtils').formatMoney;
  var eswOrderHistoryFlag = false;
  var eswModuleEnabled = eswHelper.getEShopWorldModuleEnabled();
  var isEswSupportedCountry = eswHelper.isESWSupportedCountry();
  if (eswModuleEnabled) {
    eswOrderHistoryFlag = eswHelper.isEswOrderHistory(Order);
  }
</isscript>
```

{% endcode %}

```html
<isif condition="${eswModuleEnabled && eswOrderHistoryFlag && !empty(Order.custom.eswShopperCurrencyCode)}">
  <isprint value="${dw.value.Money(Order.custom.eswShopperCurrencyPaymentAmount,Order.custom.eswShopperCurrencyCode)}"/>
<iselseif condition="${eswModuleEnabled && isEswSupportedCountry && !eswOrderHistoryFlag && empty(Order.custom.eswShopperCurrencyCode)}">
  <isprint value="${paymentInstr.paymentTransaction.custom.eswPaymentAmount}"/>
<iselse>
  <isprint value="${paymentInstr.paymentTransaction.amount}"/>
</isif>
```

{% code expandable="true" %}

```html
<isif condition="${!empty(Order.custom.eswPackageReference)}">
  <isset name="eswTrackingUrl" value="${!empty(dw.system.Site.current.preferences.custom.eswTrackingUrl) ? dw.system.Site.current.preferences.custom.eswTrackingUrl + Order.custom.eswPackageReference : '#'}" scope="page" />
  <div class="trackingnumber">
    <div class="label">${Resource.msg('order.orderdetails.tracking','order',null)}</div>
    <div class="value">
      <a target="_blank" href="${eswTrackingUrl}"><isprint value="${Order.custom.eswPackageReference}"/></a>
    </div>
  </div>
</isif>
<iselse>
  <isif condition="${!empty(shipment.trackingNumber)}">
    <div class="trackingnumber">
      <div class="label">${Resource.msg('order.orderdetails.tracking','order',null)}</div>
      <div class="value"><isprint value="${shipment.trackingNumber}"/></div>
    </div>
  </isif>
</isif>
```

{% endcode %}

```html
<isif condition="${eswOrderHistoryFlag && !empty(Order.custom.eswShopperCurrencyCode)}">
  <isscript>
    var price = new Number((productLineItem.custom.eswShopperCurrencyItemPriceInfo * productLineItem.quantityValue));
    var formatedPrice = formatMoney(new dw.value.Money(price, Order.custom.eswShopperCurrencyCode));
  </isscript>
  <div class="value">${formatedPrice}</div>
<iselse/>
```

{% endtab %}

{% tab title="ordertotals.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/components/order/ordertotals.isml`

#### Description

Displays ESW subtotal, shipping, discount, tax, and totals using ESW pricing logic.

```rb
<isscript>
  var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper();
  var eswOrderHistoryFlag = false;
  var eswModuleEnabled = eswHelper.getEShopWorldModuleEnabled();
  var isEswSupportedCountry = eswHelper.isESWSupportedCountry();
  if (eswModuleEnabled) {
    eswOrderHistoryFlag = eswHelper.isEswOrderHistory(LineItemCtnr);
    var getOrderTotals = require('*/cartridge/scripts/helper/orderHistoryTotals').orderTotals;
  }
</isscript>
```

```html
<isif condition="${eswModuleEnabled && eswOrderHistoryFlag}">
  <td><isprint value="${getOrderTotals(LineItemCtnr).subTotal}" /></td>
<iselseif condition="${eswModuleEnabled && isEswSupportedCountry && !eswOrderHistoryFlag}">
  <td><isprint value="${eswHelper.getSubtotalObject(LineItemCtnr,true)}" /></td>
<iselse>
  <td><isprint value="${LineItemCtnr.getAdjustedMerchandizeTotalPrice(false).add(LineItemCtnr.giftCertificateTotalPrice)}"/></td>
</isif>
```

```html
<isif condition="${!empty(orderDiscount) && orderDiscount.value > 0.0}">
  <tr class="order-discount discount">
    <td>${Resource.msg('order.ordersummary.orderdiscount','order',null)}</td>
    <td> - <isprint value="${(eswModuleEnabled) ? eswHelper.getOrderDiscount(LineItemCtnr) : orderDiscount }" /></td>
  </tr>
</isif>
<iscomment>render each single shipment or shipping total</iscomment>
<isif condition="${!eswModuleEnabled || !isEswSupportedCountry || eswOrderHistoryFlag}">
```

```html
<isif condition="${eswModuleEnabled && eswOrderHistoryFlag}">
  <isprint value="${getOrderTotals(LineItemCtnr).totalShippingCost}"/>
<iselseif condition="${eswModuleEnabled && isEswSupportedCountry && !eswOrderHistoryFlag}">
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', LineItemCtnr.shippingTotalPrice)}"/>
<iselse>
  <isprint value="${LineItemCtnr.shippingTotalPrice}"/>
</isif>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}">
  <td>- <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', shippingDiscount, 'noAdjustment', false)}"/></td>
<iselse>
  <td>- <isprint value="${shippingDiscount}"/></td>
</isif>
```

```html
<isif condition="${eswModuleEnabled}">
  <td>- <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', shippingDiscount)}"/></td>
<iselse>
  <td>- <isprint value="${shippingDiscount}"/></td>
</isif>
```

```html
<isif condition="${eswModuleEnabled && eswOrderHistoryFlag}">
  <isprint value="${getOrderTotals(LineItemCtnr).totalTax}"/>
<iselseif condition="${eswModuleEnabled && isEswSupportedCountry && !eswOrderHistoryFlag}">
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', LineItemCtnr.totalTax, 'noAdjustment', false)}"/>
<iselse>
  <isprint value="${LineItemCtnr.totalTax}"/>
</isif>
```

```html
<isif condition="${eswModuleEnabled && eswOrderHistoryFlag}">
  <isprint value="${getOrderTotals(LineItemCtnr).grandTotal}"/>
<iselseif condition="${eswModuleEnabled && isEswSupportedCountry && !eswOrderHistoryFlag}">
  <isprint value="${eswHelper.getFinalOrderTotalsObject()}"/>
<iselse>
  <isprint value="${orderTotalValue}"/>
</isif>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="minilineitems.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/checkout/components/minilineitems.isml`

#### Description

Renders converted price for a single mini-cart line item.

```html
<span class="mini-cart-price">
  <isprint value="${eswHelper.getSubtotalObject(productLineItem)}"/>
</span>
```

{% endtab %}

{% tab title="pricing.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/product/components/pricing.isml`

#### Description

Price display component with ESW conversions and ranges.

```rb
<isscript>  
  var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper();
  // for variation groups use the master, because all variants are available in detail page
  if (pdict.Product && pdict.Product.variationGroup) {
    pdict.Product = pdict.Product.masterProduct;
  }
</isscript>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}">
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', pdict.ProductSetSalesPrice, 'noAdjustment', false)}"/>
<iselse>
  <isprint value="${dw.util.StringUtils.formatMoney(dw.value.Money(pdict.ProductSetSalesPrice, pdict.CurrencyCode))}" />
</isif>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}">
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', pdict.Product.priceModel.minPrice, 'noAdjustment', false)}"/> - 
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', pdict.Product.priceModel.maxPrice)}"/>
<iselse>
  <isprint value="${pdict.Product.priceModel.minPrice}"/> - <isprint value="${pdict.Product.priceModel.maxPrice}"/>
</isif>
```

```html
<isif condition="${StandardPrice.valueOrNull != null && StandardPrice.valueOrNull > 0}">
  <isif condition="${eswHelper.getEShopWorldModuleEnabled()}"> 
    <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', StandardPrice)}"/>
  <iselse>
    <isprint value="${StandardPrice}"/>
  </isif>
<iselse/>
  ${Resource.msg('product.pricing.noprice','product',null)}
</isif>
```

```html
<isif condition="${eswHelper.getEShopWorldModuleEnabled()}"> 
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', SalesPrice)}"/>
<iselse>
  <isprint value="${SalesPrice}"/>
</isif>
```

{% endtab %}

{% tab title="producttile.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/product/producttile.isml`

#### Description

Tile pricing with ESW range handling and restriction checks.

```rb
<isscript>
  var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper();
</isscript>
```

```html
<isif condition="${showpricing && !eswHelper.isProductRestricted(Product)}">
```

```js
if (eswHelper.getEShopWorldModuleEnabled()) {
  price.value = dw.value.Money(pdict.CurrentHttpParameterMap.minprice, currencyCode) + ' - ' + dw.value.Money(pdict.CurrentHttpParameterMap.maxprice, currencyCode);
} else {
  price.value = dw.util.StringUtils.formatMoney(dw.value.Money(pdict.CurrentHttpParameterMap.minprice, currencyCode)) + ' - ' + dw.util.StringUtils.formatMoney(dw.value.Money(pdict.CurrentHttpParameterMap.maxprice, currencyCode));
}
```

```html
<isif condition="${(!empty(productPrice.value) && typeof productPrice.value !== 'string' && eswHelper.getEShopWorldModuleEnabled())}">
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', productPrice.value, 'noAdjustment', false)}"/>
<iselseif condition="${(typeof productPrice.value == 'string' && !Product.productSet && eswHelper.getEShopWorldModuleEnabled())}">
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', productPrice.value, 'noAdjustment', false, 'ranged', true)}"/>
<iselse>
  <isprint value="${productPrice.value}"/>
</isif>
```

{% endtab %}

{% tab title="productsearchbreadcrumbs.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/search/components/productsearchbreadcrumbs.isml`

#### Description

Price range breadcrumb using ESW money object.

```js
breadcrumbLabel = eswHelper.getMoneyObject(prdValues.iterator().next().valueFrom) + ' - ' + eswHelper.getMoneyObject(prdValues.iterator().next().valueTo);
```

{% endtab %}

{% tab title="productsearchrefinebar.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/search/components/productsearchrefinebar.isml`

#### Description

Price refinement links with converted ranges.

```html
<a class="refinement-link" title="${Resource.msg('global.remove','locale',null)} ${RefinementValue.getDisplayValue()}" href="${StringHelpers.unsanitizeOR(pdict.ProductSearchResult.urlRelaxPrice('Search-Show'))}">
  <i class="fa fa-check-square-o fa-lg"></i>
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', RefinementValue.valueFrom)}"/> - <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', RefinementValue.valueTo)}"/>
</a>
```

```html
<a class="refinement-link" title="${Resource.msg('global.pricerefinement.label.prefix','locale',null)} ${RefinementValue.getDisplayValue()}" href="${StringHelpers.unsanitizeOR(pdict.ProductSearchResult.urlRefinePrice('Search-Show',RefinementValue.getValueFrom(),RefinementValue.getValueTo()))}">
  <i class="fa fa-square-o fa-lg"></i>
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', RefinementValue.valueFrom)}"/> - <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', RefinementValue.valueTo)}"/>
</a>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="suggestions.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/search/suggestions.isml`

#### Description

Autocomplete “from” price with conversion.

```html
<div class="product-price">
  ${Resource.msg('search.suggest.from','search',null)} 
  <isinclude url="${URLUtils.url('EShopWorld-GetConvertedPrice', 'price', productSearchHit.getMinPrice())}"/>
</div>
```

{% endtab %}

{% tab title="productcontent.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/product/productcontent.isml`

#### Description

Product content with restriction & return-prohibited messaging.

```html
<isset name="eswHelper" value="${require('*/cartridge/scripts/helper/eswHelper').getEswHelper()}" scope="page"/>
```

```html
<isif condition="${!eswHelper.isProductRestricted(product)}">
  <isset name="showTieredPrice" value="${true}" scope="page"/>
  <isinclude template="product/components/pricing"/>
</isif>
```

```html
<isif condition="${eswHelper.isReturnProhibited(product)}">
  <iscontentasset aid="esw-display-return-prohibited-message"/>
</isif>
```

```html
<isif condition="${!eswHelper.isProductRestricted(product)}">
  <button id="add-to-cart" type="submit" title="${buttonTitle}" value="${buttonTitle}" class="button-fancy-large add-to-cart">${buttonTitle}</button>
  <isapplepay sku="${pdict.Product.ID}"></isapplepay>
<iselse>
  ${Resource.msg('esw.product.notavailable','esw',null)}
</isif>
```

```html
<isif condition="${!eswHelper.isProductRestricted(product)}">
  <button id="add-to-cart" type="button" title="${buttonTitleDisabledSelectVariation}" value="${buttonTitleDisabledSelectVariation}" class="button-fancy-large add-to-cart-disabled"<isprint value="${disabledAttr}" encoding="off"/>>${buttonTitle}</button>
<iselse>
  ${Resource.msg('esw.product.notavailable','esw',null)}
</isif>
```

{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="producttopcontentPS.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/product/producttopcontentPS.isml`

#### Description

Top content for product sets with ESW restriction messaging.

```html
<isinclude template="util/modules"/>
<isset name="eswHelper" value="${require('*/cartridge/scripts/helper/eswHelper').getEswHelper()}" scope="page"/>
```

```html
<isif condition="${eswHelper.isReturnProhibited(pdict.Product)}">
  <iscontentasset aid="esw-display-return-prohibited-message"/>
</isif>
```

```html
<isif condition="${!eswHelper.isProductRestricted(psProduct)}">
<iselse>
  ${Resource.msg('esw.product.notavailable','esw',null)}
</isif>
```

{% endtab %}

{% tab title="productsetproduct.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/product/components/productsetproduct.isml`

#### Description

Pricing inclusion for items within a product set.

```html
<isset name="eswHelper" value="${require('*/cartridge/scripts/helper/eswHelper').getEswHelper()}" scope="page"/>
<isif condition="${!eswHelper.isProductRestricted(pdict.Product)}">
  <isinclude template="product/components/pricing"/>
</isif>
```

{% endtab %}

{% tab title="displayliproduct.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/product/components/displayliproduct.isml`

#### Description

Cart line item “not available” message on restriction.

```html
<isif condition="${pdict.BasketStatus.code != null && pdict.BasketStatus.code=='EswProductRestrictedError' && productLineItem.productID == session.privacy.restrictedProductID}">
  <div class="product-not-available-msg-cart">
    ${Resource.msg('esw.product.notavailable','esw',null)}
  </div>
</isif>
```

{% endtab %}

{% tab title="orders.isml" %}

#### File Path

`SiteGenesis_core/cartridge/templates/default/account/orderhistory/orders.isml`

#### Description

Display order totals in ESW shopper currency when available.

```html
<isset name="eswHelper" value="${require('*/cartridge/scripts/helper/eswHelper').getEswHelper()}" scope="page"/>
<span class="value">
  <isprint value="${(eswHelper.getEShopWorldModuleEnabled() && !empty(order.object.custom.eswShopperCurrencyPaymentAmount)) ? dw.value.Money(order.object.custom.eswShopperCurrencyPaymentAmount,order.object.custom.eswShopperCurrencyCode) : order.object.totalGrossPrice}"/>
</span>
```

{% endtab %}
{% endtabs %}

### <i class="fa-joystick" style="color:$primary;">:joystick:</i> Controllers

{% tabs %}
{% tab title="Currency.js" %}

#### File Path

`SiteGenesis_controllers/cartridge/controllers/Currency.js`

#### Description

Returns whether a selected country is ESW-allowed and echoes language/currency from cookies; exports web-exposed methods.

{% code expandable="true" %}

```js
'use strict';

/**
 * This controller updates the current session currency.
 *
 * @module controllers/Currency
 */

/* API Includes */
var Currency = require('dw/util/Currency');
var Transaction = require('dw/system/Transaction');
var Site = require('dw/system/Site');

/* Script Modules */
var guard = require('~/cartridge/scripts/guard');
var Cart = require('~/cartridge/scripts/models/CartModel');

/**
 * This controller is used in an AJAX call to set the session variable 'currency'.
 */
function setSessionCurrency() {
  var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper();
  var currencyMnemonic = request.httpParameterMap.currencyMnemonic.value;
  var Response = require('~/cartridge/scripts/util/Response');
  var Countries = require('*/cartridge/scripts/util/Countries');
  var URLUtils = require('dw/web/URLUtils');
  var redirect = null;
  
  if (eswHelper.getEShopWorldModuleEnabled()) {
      var selectedCountry;
      var countryParam = request.httpParameterMap.get(Site.getCustomPreferenceValue('eswCountryUrlParam'));
      if (empty(countryParam)) {
          selectedCountry = countryParam;
      } else {
          selectedCountry = request.httpParameterMap.country.value;
      }

      var currencyCode = request.httpParameterMap.currency.value;
      var language = request.httpParameterMap.language.value;
      
      if (eswHelper.checkIsEswAllowedCountry(selectedCountry) != null) {
        if (request.setLocale(language)) {
          if (!eswHelper.overridePrice(selectedCountry)) {
            eswHelper.setAllAvailablePriceBooks();
            eswHelper.setBaseCurrencyPriceBook(eswHelper.getBaseCurrencyPreference());
          }
        }
        eswHelper.selectCountry(selectedCountry, currencyCode, language);
      } else {
        delete session.privacy.fxRate;
        var defaultCountryCurrencyMapping = eswHelper.getDefaultCountryCurrencyMapping();
        if (defaultCountryCurrencyMapping.length > 0) {
          eswHelper.createCookie('esw.location', selectedCountry, '/');
          var siteCountries = JSON.parse(defaultCountryCurrencyMapping);
          var foundCountry = siteCountries.filter(function(item) {
            // Set Currency and Locale if esw not allowed country found
            if (item.countryCode == selectedCountry) {
              // Set cookies
              eswHelper.createCookie('esw.currency', item.currencyCode, '/');
              eswHelper.createCookie('esw.LanguageIsoCode', language, '/');
              // Set Base currency Pricebook
              eswHelper.setAllAvailablePriceBooks();
              eswHelper.setBaseCurrencyPriceBook(item.currencyCode);
              // Set locale
              request.setLocale(language);
              return true;
            }
          });
          // Set Default Currency and Locale if esw not allowed country not found
          if (empty(foundCountry)) {
            eswHelper.setAllAvailablePriceBooks();
            eswHelper.setBaseCurrencyPriceBook(eswHelper.getBaseCurrencyPreference());
            eswHelper.createCookie('esw.currency', session.getCurrency(), '/');
            eswHelper.createCookie('esw.LanguageIsoCode', dw.system.Site.getCurrent().getDefaultLocale(), '/');
            request.setLocale(dw.system.Site.getCurrent().getDefaultLocale());
          }
        }
      }
      // redirect = eswHelper.getCurrent(request.getLocale());
  } else {
    if (currencyMnemonic) {
      currency = Currency.getCurrency(currencyMnemonic);
      if (currency) {
        session.setCurrency(currency);
        Transaction.wrap(function () {
          var currentCart = Cart.get();
          if (currentCart) {
            currentCart.updateCurrency();
            currentCart.calculate();
          }
        });
      }
    }
  }

  Response.renderJSON({
    redirectUrl: (redirect != null) ? redirect.toString() : '',
    success: true
  });
}

function getAllowedCountry() {
  var Response = require('~/cartridge/scripts/util/Response');
  var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper()
  
  var language = !empty(request.httpCookies['esw.LanguageIsoCode']) ? request.httpCookies['esw.LanguageIsoCode'].value : eswHelper.getAllowedLanguages()[0].value;
  var currency = !empty(request.httpCookies['esw.currency']) ? request.httpCookies['esw.currency'].value : eswHelper.getDefaultCurrencyForCountry(eswHelper.getAvailableCountry());
  var selectedCountry = request.httpParameterMap.country.value;
  var flag = false;
  
  if (eswHelper.getEShopWorldModuleEnabled() && eswHelper.checkIsEswAllowedCountry(selectedCountry)) {
    flag = true;
  }
  
  Response.renderJSON({
    success : flag,
    country : selectedCountry,
    language : language,
    currency : currency
  }); 
}

/*
 * Module exports
 */

/*
 * Web exposed methods
 */
/** @see module:controllers/Currency~setSessionCurrency */
exports.SetSessionCurrency = guard.ensure(['get'], setSessionCurrency);
exports.GetAllowedCountry = guard.ensure(['get'], getAllowedCountry);
```

{% endcode %}
{% endtab %}

{% tab title="Cart.js" %}

#### File Path

`SiteGenesis_controllers/cartridge/controllers/Cart.js`

#### Description

Renders the cart; when ESW is enabled and supported, applies ESW shipping method, recalculates, and adjusts threshold discounts.

{% code expandable="true" %}

```js
/**
 * Invalidates the login and shipment forms. Renders the checkout/cart/cart template.
 */
function show() {
  var eswServiceHelper = require('*/cartridge/scripts/helper/serviceHelper');
  var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper();
  
  if (eswHelper.getEShopWorldModuleEnabled() && eswHelper.isESWSupportedCountry()) {
    var cart = app.getModel('Cart').goc();
    if (!empty(cart)) {
      Transaction.wrap(function () {
        if (eswHelper.getShippingServiceType(cart.object) === 'POST') {
          eswServiceHelper.applyShippingMethod(cart.object, 'POST', eswHelper.getAvailableCountry(), true);
        } else {
          eswServiceHelper.applyShippingMethod(cart.object, 'EXP2', eswHelper.getAvailableCountry(), true);
        }
        cart.calculate();
        eswHelper.adjustThresholdDiscounts(cart);
      });
    }
  }
  var cartForm = app.getForm('cart');
  app.getForm('login').invalidate();

  cartForm.get('shipments').invalidate();

  app.getView('Cart', {
    cart: app.getModel('Cart').get(),
    RegistrationStatus: false
  }).render('checkout/cart/cart');
} 
```

{% endcode %}
{% endtab %}

{% tab title="COCustomer.js" %}

#### File Path

`SiteGenesis_controllers/cartridge/controllers/COCustomer.js`

#### Description

Login form handler; routes unregistered checkout to ESW Pre-Order when module is enabled and country is allowed.

{% code expandable="true" %}

```js
/**
 * Form handler for the login form. Handles the following actions:
 * - __login__ - Calls the {@link module:controllers/Login~process|Login controller Process function}. If this returns successfully, calls
 *   the {@link module:controllers/COShipping~Start|COShipping controller Start function}.
 * - __register__ - Calls the {@link module:controllers/Account~StartRegister|Account controller StartRegister function}.
 * - __unregistered__ - Calls the {@link module:controllers/COShipping~Start|COShipping controller Start function}.
 */
function showLoginForm() {
  var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper();
  var loginForm = app.getForm('login');
  
  session.custom.TargetLocation = URLUtils.https('COShipping-Start').toString();
  if (eswHelper.getEShopWorldModuleEnabled() && eswHelper.checkIsEswAllowedCountry(request.httpCookies['esw.location'].value)) {
    session.custom.TargetLocation = URLUtils.https('EShopWorld-PreOrderRequest').toString();
  }
  loginForm.handleAction({
    login: function () {
      app.getController('Login').LoginForm();
    },
    register: function () {
      response.redirect(URLUtils.https('Account-StartRegister'));
    },
    unregistered: function () {
      if (eswHelper.getEShopWorldModuleEnabled()) {
        session.custom.guestCheckout = true;
        response.redirect(session.custom.TargetLocation);
      } else {
        response.redirect(URLUtils.https('COShipping-Start'));
      }
    }
  });
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

***

## Customizing The Pipeline

* To enable the ESW SFCC plugin, the retailers' technical team needs to compare listed controllers from 1.2 ‘Customizing the controllers’ section, with SG pipelines and make the required customizations/changes. ESW does not support the siteGenesis pipelines version.
* siteGenesis custom controllers can be found on the following path for comparison:

**Path:**

* `SiteGenesis_controllers/cartridge/controllers/Cart.js`
* `SiteGenesis_controllers/cartridge/controllers/Currency.js`
* `SiteGenesis_controllers/cartridge/controllers/COCustomer.js`<br>

### <i class="fa-file-brackets-curly" style="color:$primary;">:file-brackets-curly:</i> Scripts and JSON

{% tabs %}
{% tab title="Resource.ds" %}

#### File Path

`SiteGenesis_core/cartridge/scripts/util/Resource.ds`

#### Description

Key URL selectors used by ESW flows.

```js
Selectors : URLUtils.url('Currency-SetSessionCurrency').toString(),
preparePreOrderRequest : URLUtils.url('EShopWorld-PreOrderRequest').toString(),
getAllowedCountry : URLUtils.url('Currency-GetAllowedCountry').toString(),
getDefaultCurrency: URLUtils.url('EShopWorld-GetDefaultCurrency').toString(),
getEswLandingPage : URLUtils.url('EShopWorld-GetEswLandingPage').toString()
```

{% endtab %}

{% tab title="OnRequest.js" %}

#### File Path

`SiteGenesis_controllers/cartridge/scripts/request/OnRequest.js`

#### Description

Global `onRequest` hook to handle ESW redirects and locale syncing.

{% code expandable="true" %}

```js
'use strict';

/**
 * The onRequest hook is called with every top-level request in a site. This happens both for requests to cached and non-cached pages.
 * For performance reasons the hook function should be kept short.
 *
 * @module  request/OnRequest
 */

var Status = require('dw/system/Status');

/**
 * The onRequest hook function.
 */
exports.onRequest = function () {
    var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper(),
        selectedFxRate = JSON.parse(session.privacy.fxRate);
    if (eswHelper.getEShopWorldModuleEnabled()) {
        if (!selectedFxRate && selectedFxRate !== null) {
            var url = eswHelper.checkRedirect();
            if (!empty(url) && request.httpMethod != 'POST'){
                response.redirect(url); 
            }
        } else {
            var isAjax = Object.hasOwnProperty.call(request.httpHeaders, 'x-requested-with');
            if (!isAjax && request.httpCookies['esw.LanguageIsoCode'] != null && request.getLocale() !== request.httpCookies['esw.LanguageIsoCode'].value) {
                request.setLocale(request.httpCookies['esw.LanguageIsoCode'].value);
                var url = eswHelper.getCurrent(request.httpCookies['esw.LanguageIsoCode'].value);
                if (request.httpMethod != 'POST') {
                    response.redirect(url);
                }
            }
        }
    }

    return new Status(Status.OK);
}
```

{% endcode %}

**ISML helper include (place at top of your `.isml`):**

```js
var eswHelper = require('int_eshopworld_controllers/cartridge/scripts/helper/eswHelper').getEswHelper();
```

{% endtab %}

{% tab title="ValidateCartForCheckout.js" %}

#### File Path

`SiteGenesis_core/cartridge/scripts/cart/ValidateCartForCheckout.js`

#### Description

Sets `pdict.BasketStatus` on ESW error or restricted-product error.

```js
} else if(request.httpParameterMap.eswfail.value != null &&  request.httpParameterMap.eswfail) {
  pdict.BasketStatus = new Status(Status.ERROR, 'EswError');
  return pdict;
} else if(!empty(session.privacy.eswProductRestricted) && session.privacy.eswProductRestricted) {
  pdict.BasketStatus = new Status(Status.ERROR, 'EswProductRestrictedError');
  delete session.privacy.eswProductRestricted;
  return pdict;
}
```

{% endtab %}
{% endtabs %}

<br>

{% tabs %}
{% tab title="GetMoneyObject" %}

#### Name

`GetMoneyObject(price, noAdjustment, formatted, noRounding)`

#### Description

Helper used wherever prices are calculated or displayed

GetMoneyObject (price, noAdjustment, formatted, noRounding)

* **price:** This can be a number or a money object, for example, price.
* **noAdjustment:** Boolean value. If true, no adjustment will be applied.
* **formatted:** Boolean value. If true, it returns a string value with currency code, for example, $10.00. If false, it returns money object with the currency and the price.
* **noRounding:** Boolean value. If true, no rounding rule will be applied.

This function is a helper function that is used anywhere prices need to be calculated or displayed. It checks whether a country is a Fixed price country or an FX price country. It applies FX conversions when applicable. It also applies adjustments, duty, and tax where required.
{% endtab %}

{% tab title="calculate.js" %}

#### File Path

`SG_core/cartridge/scripts/cart/calculate.js`

#### Description

During ESW order calculation, avoid applying platform promotions.

```js
var eswHelper = require('*/cartridge/scripts/helper/eswHelper').getEswHelper();
```

```js
exports.calculate = function (basket, isESWOrderCalculate) {
```

```js
if (!eswHelper.getEShopWorldModuleEnabled() || !isESWOrderCalculate) {
  PromotionMgr.applyDiscounts(basket);
}
```

```js
if (!eswHelper.getEShopWorldModuleEnabled() || !isESWOrderCalculate) {
  PromotionMgr.applyDiscounts(basket);
}
```

{% endtab %}

{% tab title="hooks.json" %}

#### File Path

`SG_core/cartridge/scripts/hooks.json`

#### Description

Override deprecated basket calculate hook to `dw.order.calculate`.
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developer.esw.com/shopify/salesforce-commerce-cloud/cartridge-setup/sitegenesis.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
