Shipping
- How do I set a custom order validator for shipping methods?
- How do I set a custom order validator for shipping rates?
- How do I set a custom order validator for shipping rates (for subscriptions)?
- How do I set a custom price totalizer for shipping rates?
- How do I set a custom applicable items filter for shipping rates?
- How do I set a custom item weight totalizer for shipping rates?
- How do I set a custom item volume totalizer for shipping rates?
- How do I set a custom item quantity totalizer for shipping rates?
- How do I set a custom item price totalizer for shipping rates?
How do I set a custom order validator for shipping methods?
Shipping methods can define an order validator to determine whether they are available for a particular order.
For example, you may only want to offer some shipping methods on certain days.
First we will define an availability setting for each day:
$days = collect([
'sunday' => false,
'monday' => true,
'tuesday' => true,
'wednesday' => true,
'thursday' => true,
'friday' => true,
'saturday' => false,
]);
\Aero\Cart\Models\ShippingMethod::settings('availability', function (\Aero\Common\Settings\ModelSettingGroup $group) use ($days) {
$days->each(function (bool $available, string $day) use ($group) {
$group->boolean("{$day}_delivery")->default($available);
});
});
The setOrderValidator method can then use these settings to determine whether the shipping method is available today:
\Aero\Cart\Models\ShippingMethod::setOrderValidator(function (\Aero\Cart\Models\ShippingMethod $method) use ($days) {
$day = $days->keys()[now()->dayOfWeek];
return $method->setting("availability.{$day}_delivery");
});
The validator receives the shipping method, order and order item group and should return true when it can be used for the order, or false when it should be excluded.
Parameters
| Parameter | Type | Description |
$method |
\Aero\Cart\Models\ShippingMethod |
The shipping method being validated. |
$order |
\Aero\Cart\Models\Order |
The order being validated. |
$orderItemGroup |
string|null |
The order item group being validated (null when not in a group). |
How do I set a custom order validator for shipping rates?
Shipping rates can define an order validator to determine whether they are available for a particular order.
For example, you may only want to offer a shipping rate only for certain customer groups.
First, define an availability setting to allow this:
\Aero\Cart\Models\ShippingRate::settings('availability', function (\Aero\Common\Settings\ModelSettingGroup $group) {
$group->boolean('restricted_by_customer_group')->default(false);
$group->eloquent('allowed_customer_groups', \Aero\Account\Models\CustomerGroup::class)->multiple()->dontLoadModels()
->showIf('settings.availability.restricted_by_customer_group', true);
$group->eloquent('disallowed_customer_groups', \Aero\Account\Models\CustomerGroup::class)->multiple()->dontLoadModels()
->showIf('settings.availability.restricted_by_customer_group', true);
});
The setOrderValidator method can then use these settings to determine whether the shipping rate is available for a customer:
\Aero\Cart\Models\ShippingRate::setOrderValidator(function (\Aero\Cart\Models\ShippingRate $rate) {
if (! $rate->settings('availability.restricted_by_customer_group')) {
return true;
}
$disallowedGroups = $rate->settings('availability.disallowed_customer_groups') ?? [];
$allowedGroups = $rate->settings('availability.allowed_customer_groups') ?? [];
$customerGroupId = optional($rate->shippingMethod->order->customer)->customer_group_id ?? null;
if (in_array($customerGroupId, $disallowedGroups)) {
return false;
}
if (empty($allowedGroups)) {
return true;
}
return in_array($customerGroupId, $allowedGroups);
});
The validator receives the shipping rate, order and order item group and should return true when it can be used for the order, or false when it should be excluded.
Parameters
| Parameter | Type | Description |
$rate |
\Aero\Cart\Models\ShippingRate |
The shipping rate being validated. |
$order |
\Aero\Cart\Models\Order |
The order being validated. |
$items |
\Aero\Common\Eloquent\JavaScriptableCollection |
The items of the order, or the order item group. |
How do I set a custom order validator for shipping rates (for subscriptions)?
Shipping rates can define a subscription order validator to determine whether they are available for a particular subscription order.
For example, you may want to make a shipping rate available for one-time orders but explicitly opt it into subscription orders.
First, define an availability setting:
\Aero\Cart\Models\ShippingRate::settings('availability', function (\Aero\Common\Settings\ModelSettingGroup $group) {
$group->boolean('for_subscription_orders')->default(false);
});
The setSubscriptionOrderValidator method can then use this setting to determine whether the shipping rate is available for subscription orders:
\Aero\Cart\Models\ShippingRate::setSubscriptionOrderValidator(function (\Aero\Cart\Models\ShippingRate $rate) {
return $rate->setting('availability.for_subscription_orders');
});
The validator receives the shipping rate, order and subscription plan and should return true when it can be used for the order, or false when it should be excluded.
Parameters
| Parameter | Type | Description |
$rate |
\Aero\Cart\Models\ShippingRate |
The shipping rate being validated. |
$order |
\Aero\Cart\Models\Order |
The order being validated. |
$plan |
\Aero\Subscription\Models\SubscriptionPlan |
The subscription plan being validated. |
How do I set a custom price totalizer for shipping rates?
Shipping rates can define a custom price totalizer to adjust the calculated shipping price before it is returned to the customer.
For example, you may want to add a fixed cost for each item in the order.
First, define the cost per item on the shipping method:
\Aero\Cart\Models\ShippingMethod::settings('extras', function (\Aero\Common\Settings\ModelSettingGroup $group) {
$group->float('cost_per_item');
});
The setPriceTotalizer method can then add the per-item cost to the shipping rate's calculated price:
\Aero\Cart\Models\ShippingRate::setPriceTotalizer(function ($price, \Aero\Cart\Models\ShippingRate $rate) {
$costPerItem = $rate->setting('extras.cost_per_item')
?? $rate->shippingMethod->setting('extras.cost_per_item');
if (! $costPerItem) {
return null;
}
$itemAmount = $rate->order->items->sum('quantity');
return $price + ($itemAmount * $costPerItem * 100);
});
The totalizer receives the price and the shipping rate as parameters and should return the total in pence or null.
Returning null means that the default price totalizer will be used.
Parameters
| Parameter | Type | Description |
$price |
float |
The total price in pence. |
$rate |
\Aero\Cart\Models\ShippingRate |
The shipping rate being evaluated. |
How do I set a custom applicable items filter for shipping rates?
Shipping rates can define a custom-applicable items filter to control which order items are considered when determining whether a rate is applicable.
For example, you may want to restrict a shipping method to products from specific manufacturers.
First, define settings for enabling manufacturer restrictions and selecting the allowed and disallowed manufacturers:
\Aero\Cart\Models\ShippingMethod::settings('availability', function (\Aero\Common\Settings\ModelSettingGroup $group) {
$group->boolean('restricted_by_manufacturer')->default(false);
$group->eloquent('allowed_manufacturers', \Aero\Catalog\Models\Manufacturer::class)->multiple()->dontLoadModels()
->showIf('settings.availability.restricted_by_manufacturer', true);
$group->eloquent('disallowed_manufacturers', \Aero\Catalog\Models\Manufacturer::class)->multiple()->dontLoadModels()
->showIf('settings.availability.restricted_by_manufacturer', true);
});
The setApplicableItemsFilter method can then filter out items that don't meet the manufacturer restrictions:
\Aero\Cart\Models\ShippingRate::setApplicableItemsFilter(function ($items, \Aero\Cart\Models\ShippingRate $rate) {
if (! $rate->shippingMethod->setting('availability.restricted_by_manufacturer')) {
return $items;
}
$allowedManufacturerIds = $rate->shippingMethod->setting('availability.allowed_manufacturers');
$disallowedManufacturerIds = $rate->shippingMethod->setting('availability.disallowed_manufacturers');
$hasDisallowedItem = $items->some(function (\Aero\Cart\Models\OrderItem $item) use ($allowedManufacturerIds, $disallowedManufacturerIds) {
if (in_array($item->buyable->manufacturer_id, $disallowedManufacturerIds)) {
return true;
}
if (empty($allowedManufacturerIds)) {
return false;
}
return ! in_array($item->buyable->manufacturer_id, $allowedManufacturerIds);
}
if ($hasDisallowedItem) {
return collect();
}
return $items;
});
The filter receives the order price and the shipping rate as parameters and should return a collection of applicable items.
Parameters
| Parameter | Type | Description |
$items |
\Aero\Common\Eloquent\JavaScriptableCollection |
The order items being evaluated. |
$rate |
\Aero\Cart\Models\ShippingRate |
The shipping rate being evaluated. |
How do I set a custom item weight totalizer for shipping rates?
Shipping rates can define a custom item weight totalizer to control how item weights are calculated when determining whether a rate is applicable.
For example, you may want certain product variants to be exempt from the shipping weight calculation.
First, add a setting to the variant:
\Aero\Catalog\Models\Variant::settings('shipping', function (\Aero\Common\Settings\ModelSettingGroup $group) {
$group->boolean('is_weight_exempt')->default(false);
});
The setItemWeightTotalizer method can then exclude weight-exempt variants when calculating the total weight:
\Aero\Cart\Models\ShippingRate::setItemWeightTotalizer(function ($items) {
return $items
->reject(function (\Aero\Cart\Models\OrderItem $item) {
return $item->buyable->setting('shipping.is_weight_exempt');
})
->sum(function (\Aero\Cart\Models\OrderItem $item) {
return $item->buyable->weight;
});
});
The totalizer receives the order items and the shipping rate as parameters and should return the total weight of the items or null.
Returning null means the default item weight totalizer will be used.
Parameters
| Parameter | Type | Description |
$items |
\Aero\Common\Eloquent\JavaScriptableCollection |
The order items being evaluated. |
$rate |
\Aero\Cart\Models\ShippingRate |
The shipping rate being evaluated. |
How do I set a custom item volume totalizer for shipping rates?
Shipping rates can define a custom item volume totalizer to control how item volumes are calculated when determining whether a rate is applicable.
For example, you may want to account for additional packaging space by applying a percentage allowance to the volume of each item.
First, define the packaging allowance on the shipping method:
\Aero\Cart\Models\ShippingMethod::settings('extras', function (\Aero\Common\Settings\ModelSettingGroup $group) {
$group->integer('packaging_allowance')->default(20);
});
The setItemVolumeTotalizer method can then apply the allowance when calculating the total volume:
\Aero\Cart\Models\ShippingRate::setItemVolumeTotalizer(function ($items, \Aero\Cart\Models\ShippingRate $rate) {
$packagingAllowance = 1 + ($rate->shippingMethod->setting('extras.packaging_allowance') / 100);
return $items->sum(function (\Aero\Cart\Models\OrderItem $item) use ($packagingAllowance) {
return $item->buyable->volume * $packagingAllowance;
});
});
The totalizer receives the order items and the shipping rate as parameters and should return the total volume of the items or null.
Returning null means the default item volume totalizer will be used.
Parameters
| Parameter | Type | Description |
$items |
\Aero\Common\Eloquent\JavaScriptableCollection |
The order items being evaluated. |
$rate |
\Aero\Cart\Models\ShippingRate |
The shipping rate being evaluated. |
How do I set a custom item quantity totalizer for shipping rates?
Shipping rates can define a custom item quantity totalizer to control how item quantities are calculated when determining whether a rate is applicable.
For example, you may want sample products to be excluded from the item quantity used when evaluating quantity-based shipping rules.
First, define a setting on the variant:
\Aero\Catalog\Models\Variant::settings(function (\Aero\Common\Settings\ModelSettingGroup $group) {
$group->boolean('is_sample')->default(false);
});
The setItemQuantityTotalizer method can then exclude sample products when calculating the total quantity:
\Aero\Cart\Models\ShippingRate::setItemQuantityTotalizer(function ($items) {
return $items
->reject(function (\Aero\Cart\Models\OrderItem $item) {
return $item->buyable->setting('is_sample');
})
->sum('quantity');
});
The totalizer receives the order items and the shipping rate as parameters and should return the total quantity of the items or null.
Returning null means that the default item quantity totalizer will be used.
Parameters
| Parameter | Type | Description |
$items |
\Aero\Common\Eloquent\JavaScriptableCollection |
The order items being evaluated. |
$rate |
\Aero\Cart\Models\ShippingRate |
The shipping rate being evaluated. |
How do I set a custom item price totalizer for shipping rates?
Shipping rates can define a custom item price totalizer to control how the total item price is calculated when determining whether a rate is applicable.
For example, you may want to calculate the shipping rate's price threshold using the original item prices rather than the discounted prices.
First, add settings to control whether discounts should be excluded:
\Aero\Cart\Models\ShippingRate::settings('extras', function (\Aero\Settings\Models\ModelSettingGroup $group) {
$group->boolean('exclude_discount_from_total');
});
The setItemPriceTotalizer method can then calculate the total using the items' original prices when both the shipping rate has this option enabled:
\Aero\Cart\Models\ShippingRate::setItemPriceTotalizer(function ($items, \Aero\Cart\Models\ShippingRate $rate) {
if (! $rate->setting('extras.exclude_discount_from_total')) {
return null;
}
$total = $items->sum(function (\Aero\Cart\Models\OrderItem $item) {
return $item->subtotal_price->inc()->value;
});
return round($total);
});
The totalizer receives the order items and the shipping rate as parameters and should return the total in pence or null
Returning null means the default item price totalizer will be used.
Parameters
| Parameter | Type | Description |
$items |
\Aero\Common\Eloquent\JavaScriptableCollection |
The order items being evaluated. |
$rate |
\Aero\Cart\Models\ShippingRate |
The shipping rate being evaluated. |