Skip to content

Product Shipping Prices

This webcomponent is responsible for rendering a lowest shipping price of a given product. It listens to shipping costs changes made across the application and automatically updates the component.

Attributes

Attribute name Type Default Required Description
product-id number null yes Id of the product to which this webcomponent should refer
variant-id number null yes Id of the default product stock to which this webcomponent should refer
default-countries string null yes An array of available countries in a JSON format. Read more about the specificity of the JSON below
default-available-shipping string null yes An array of available shippings in a JSON format. Read more about the specificity of the JSON below
default-shippings-in-countries string null yes An array of available shippings in countries in a JSON format. Read more about the specificity of the JSON below

default-countries attribute

Default countries should be in a form of an array containing objects with certain fields. The whole object should look like this:

[
    {
        "countryId": 179,
        "countryName": "Polska"
    }
]

but be formatted to a JSON format. We can do this with a json_encode method from Twig like this:

{% set product = ObjectApi.getProduct(product_id) %}

{% set defaultVariant = product.variant %}

{% set defaultCountries = [] %}

{% for countryShippingCost in defaultVariant.countryShippingCosts %}
    {% set countryId = countryShippingCost.country.id %}
    {% set countryName = countryShippingCost.country.name %}

    {% set defaultCountries = defaultCountries|merge([{ countryId, countryName }]) %}
{% endfor %}

{% set defaultCountries = defaultCountries|json_encode %}

default-available-shipping attribute

Default available shippings should be in a form of an array containing objects with certain fields. The whole object should look like this:

[
    {
        "description": "odbiór w siedzibie firmy",
        "shippingType": "personal",
        "name": "odbiór osobisty",
        "id": 1
    }
]

but be formatted to a JSON format. We can do this with a json_encode method from Twig like this:

{% set product = ObjectApi.getProduct(product_id) %}

{% set defaultVariant = product.variant %}

{% set availableShippings = [] %}

{% for countryShippingCost in defaultVariant.countryShippingCosts %}
    {% for shippingCost in countryShippingCost.shippingCosts %}
        {% set isShippingAlreadyAdded = availableShippings|filter(shipping => shipping.id == shippingCost.shipping.id)|length > 0 %}

        {% if not isShippingAlreadyAdded %}
            {% set description = shippingCost.shipping.description %}
            {% if shippingCost.shipping.isPersonalCollect %}
                {% set shippingType = 'personal' %}
            {% elseif shippingCost.shipping.isPickupPointDelivery %}
                {% set shippingType = 'pickupPoint' %}
            {% else %}
                {% set shippingType = '' %}
            {% endif %}
            {% set name = shippingCost.shipping.name %}
            {% set id = shippingCost.shipping.id %}

            {% set availableShippings = availableShippings|merge([{ description, shippingType, name, id }]) %}
        {% endif %}
    {% endfor %}
{% endfor %}

{% set availableShippings = availableShippings|json_encode %}

default-shippings-in-countries attribute

Default shippings in countries should be in a form of an array containing objects with certain fields. The whole object should look like this:

[
    {
        "countryId": 179,
        "shippingCosts": [
            {
                "lowestCost": "0,00 zł",
                "lowestCostFloat": 0,
                "id": 1
            }
        ]
    }
]

but be formatted to a JSON format. We can do this with a json_encode method from Twig like this:

{% set product = ObjectApi.getProduct(product_id) %}

{% set defaultVariant = product.variant %}

{% set shippingsInCountries = [] %}

{% for countryShippingCost in defaultVariant.countryShippingCosts %}
    {% set countryId = countryShippingCost.country.id %}

    {% set shippingCosts = [] %}
    {% for shippingCost in countryShippingCost.shippingCosts %}
        {% set lowestCost = shippingCost.price.formatGross %}
        {% set lowestCostFloat = shippingCost.price.grossValue %}
        {% set id = shippingCost.shipping.id %}

        {% set shippingCosts = shippingCosts|merge([{ lowestCost, lowestCostFloat, id }]) %}
    {% endfor %}

    {% set shippingsInCountries = shippingsInCountries|merge([{ countryId, shippingCosts }]) %}
{% endfor %}

{% set shippingsInCountries = shippingsInCountries|json_encode %}

Event Bus events

This webcomponent listens to the following events with the Event Bus:

Example

This example is taken from the product_shipping_prices module. Here we define the default JSON attributes, then create templates for different price scenarios and finally wrap everything up inside a product-shipping-prices webcomponent.

{% set product = ObjectApi.getProduct(product_id) %}

{% set defaultVariant = product.variant %}

{% set hasMultipleVariants = product.variants|length > 1 %}

{% set defaultCountries = [] %}

{% for countryShippingCost in defaultVariant.countryShippingCosts %}
    {% set countryId = countryShippingCost.country.id %}
    {% set countryName = countryShippingCost.country.name %}

    {% set defaultCountries = defaultCountries|merge([{ countryId, countryName }]) %}
{% endfor %}

{% set availableShippings = [] %}

{% for countryShippingCost in defaultVariant.countryShippingCosts %}
    {% for shippingCost in countryShippingCost.shippingCosts %}
        {% set isShippingAlreadyAdded = availableShippings|filter(shipping => shipping.id == shippingCost.shipping.id)|length > 0 %}

        {% if not isShippingAlreadyAdded %}
            {% set description = shippingCost.shipping.description %}
            {% if shippingCost.shipping.isPersonalCollect %}
                {% set shippingType = 'personal' %}
            {% elseif shippingCost.shipping.isPickupPointDelivery %}
                {% set shippingType = 'pickupPoint' %}
            {% else %}
                {% set shippingType = '' %}
            {% endif %}
            {% set name = shippingCost.shipping.name %}
            {% set id = shippingCost.shipping.id %}

            {% set availableShippings = availableShippings|merge([{ description, shippingType, name, id }]) %}
        {% endif %}
    {% endfor %}
{% endfor %}

{% set shippingsInCountries = [] %}

{% for countryShippingCost in defaultVariant.countryShippingCosts %}
    {% set countryId = countryShippingCost.country.id %}

    {% set shippingCosts = [] %}
    {% for shippingCost in countryShippingCost.shippingCosts %}
        {% set lowestCost = shippingCost.price.formatGross %}
        {% set lowestCostFloat = shippingCost.price.grossValue %}
        {% set id = shippingCost.shipping.id %}

        {% set shippingCosts = shippingCosts|merge([{ lowestCost, lowestCostFloat, id }]) %}
    {% endfor %}

    {% set shippingsInCountries = shippingsInCountries|merge([{ countryId, shippingCosts }]) %}
{% endfor %}

{% set shopLanguageCountryShippingCosts = defaultVariant.countryShippingCosts|filter((countryShippingCosts) => countryShippingCosts.country.id == 179) %}

{% if shopLanguageCountryShippingCosts|length == 0 %}
    {% set defaultCountryShippingCosts = defaultVariant.countryShippingCosts[0] %}
    {% set isDefaultCountryDifferentThanShopLanguage = true %}
{% else %}
    {% set defaultCountryShippingCosts = shopLanguageCountryShippingCosts|first %}
{% endif %}

{% set defaultShippingCosts = defaultCountryShippingCosts.shippingCosts[0] %}

{% set doesShipToMultipleCountries = defaultVariant.countryShippingCosts|length > 1 %}
{% set hasMultipleShippingMethods = doesShipToMultipleCountries or defaultCountryShippingCosts.shippingCosts|length > 1 %}
{% set isPersonalCollect = defaultShippingCosts.shipping.isPersonalCollect %}

{% set modalName = 'product-shipping-prices-modal-' ~ moduleInstance %}

{% set shippingMethodsBasicInfo %}
    <strong class="product-shipping-prices__shipping-info-price">
        {% if hasMultipleShippingMethods %}
            {{ translate('from') }}
            {{ defaultShippingCosts.price.formatGross }}
        {% elseif defaultShippingCosts.price.isZero and isPersonalCollect %}
            {{ translate('free <<shipping_prices personal collect>>') }}
        {% elseif defaultShippingCosts.price.isZero %}
            {{ translate('free <<shipping_prices delivery>>') }}
        {% else %}
            {{ translate('from') }}
            {{ defaultShippingCosts.price.formatGross }}
        {% endif %}
    </strong>

    {% if not isPersonalCollect %}
        -
        {{ defaultShippingCosts.shipping.name }}
    {% endif %}

    {% if doesShipToMultipleCountries or isDefaultCountryDifferentThanShopLanguage %}
        ({{ translate(defaultCountryShippingCosts.country.name) }})
    {% endif %}
{% endset %}

{% set shippingMethodsSimple %}
    {{ icon('icon-package', {
        classNames: ['icon_xs', 'product-shipping-prices__icon']
    }) }}

    <div class="product-shipping-prices__shipping-method-wrapper">
        <span class="product-shipping-prices__shipping-method">
            {% if isPersonalCollect %}
                {{ translate('Pick up in person') }}
            {% else %}
                {{ translate('Shipping') }}
            {% endif %}
        </span>

        <h-modal-opener
            class="
                product-shipping-prices__shipping-info
                product-shipping-prices__shipping-info_multiple-shippings
                link
                link_secondary
            "
            name="{{ modalName }}"
        >
            {{ shippingMethodsBasicInfo }}
        </h-modal-opener>

        <span
            class="product-shipping-prices__shipping-info product-shipping-prices__shipping-info_single-shipping"
        >
            {{ shippingMethodsBasicInfo }}
        </span>

        <p class="product-shipping-prices__description p_xs color_secondary">{{ defaultShippingCosts.shipping.description }}</p>
    </div>
{% endset %}

<product-shipping-prices
    product-id="{{ product.id }}"
    variant-id="{{ product.variant.id }}"
    default-countries="{{ defaultCountries|json_encode }}"
    default-available-shippings="{{ availableShippings|json_encode }}"
    default-shippings-in-countries="{{ shippingsInCountries|json_encode }}"
>
    <div class="product-shipping-prices">
        {{ shippingMethodsSimple }}
    </div>

    {{ product_shipping_prices_modal({
        countryShippingCosts: defaultVariant.countryShippingCosts,
        modalName,
        moduleInstanceId: moduleInstance,
        hasMultipleVariants,
        doesShipToMultipleCountries
    }) }}
</product-shipping-prices>

Webcomponents reference

Macros reference

ObjectApi methods reference