Palletizr for Craft CMS

Usage

The simulator

Palletizr → Simulator is the fastest way to understand what the engine will do. Give it carton sizes and quantities, choose pallets and options, and it builds the load — through the same Palletizer::build() call a real order uses — and draws every layer looking down at the deck.

Worth trying, because it is the whole argument for the plugin: 24 cases of 500 × 300 × 300 mm on a Euro pallet.

Deck patternPalletsCartons per layerDensityFreight class
Block248.11 lb/ft³110
Optimised1611.66 lb/ft³92.5

Same cartons, same pallet. One fewer handling unit and two classes cheaper.

A real order

php craft palletizr 1a2b3c4d

prints the build sheet: every pallet, its layers, its size and gross weight, its freight class, and anything worth knowing about it. Add --explain to see every rule that was evaluated and why each one did or did not apply — which is the question to ask when an order palletized differently from how you expected.

--carrier=fedex-freight builds for a specific carrier's limits rather than the store default.

In templates

{% set load = craft.palletizr.palletize(cart) %}

{% if load.palletized %}
    <h3>This order ships on {{ load.palletCount }} pallet{{ load.palletCount == 1 ? '' : 's' }}</h3>

    <dl>
        <dt>Handling units</dt><dd>{{ load.handlingUnitCount }}</dd>
        <dt>Freight class</dt><dd>{{ load.freightClass ?? 'not classified' }}</dd>
        <dt>Linear feet</dt><dd>{{ load.linearFeet|round(1) }}</dd>
    </dl>

    {% for warning in load.allWarnings %}
        <p class="warning">{{ warning }}</p>
    {% endfor %}
{% endif %}

Other calls:

{{ craft.palletizr.quote(cart, 'ltl').total }}      {# under one of your own tariffs #}
{{ craft.palletizr.freightClassForDensity(18.4) }}  {# 70 #}
{{ craft.palletizr.pallets()|length }}
{{ craft.palletizr.postieAvailable() }}

Everything on craft.palletizr is read-only. A template that could change how an order palletizes would be a template that can disagree with the checkout.

Reading a finished order

A Palletizr tariff writes its working into the order's shipping adjustment, under sourceSnapshot.options: the pallet count, the handling-unit count, how many cartons shipped loose, the freight class, the linear feet, every warning, and the full price breakdown. That is where anyone reconciling against a carrier invoice — or telling the warehouse what to build — should look.

Moving configuration between environments

Pallets, rules and tariffs live in the database rather than in project config, the same call Commerce makes for its own shipping methods: a warehouse correcting a pallet's tare weight is operational data, not a schema change, and should not need a deploy.

# on staging
php craft palletizr/pallets/export --file=palletizr.json

# on production
php craft palletizr/pallets/import --file=palletizr.json

Import matches pallets and tariffs on handle and rules on name, updating what it finds and creating what it does not. Nothing is ever deleted — an import that silently removed the pallet a live order is quoted against would be a very bad afternoon.

docs/example-config.json is a working two-rule example.