Discounts
- How do I add a custom amount resolver?
- How can I intercept discount code handling?
- How can I apply multiple discount types using one code?
How do I add a custom amount resolver?
The cart discount implementations use the \Aero\Cart\Traits\DeterminesAmount trait, which allows you to set a custom amount resolver for a discount type
For example you can set a limit for percentage discounts:
\Aero\Cart\PercentageDiscount::resolveAmount(function (\Aero\Cart\CartDiscount $discount, float $percentage, $items) {
// Limit in pence, e.g. 100 = £1
$limit = $discount->model->additional('percentage_discount_limit');
if (! $limit) {
return $percentage;
}
$itemsTotal = $items->sum(function (\Aero\Cart\CartItem $item) use ($percentage) {
return $item->total()->inc()->value;
});
$discountTotal = $itemsTotal * ($percentage / 100);
return $discountTotal > $limit
? ($limit / $itemsTotal) * 100
: $percentage;
});
By default if multiple amounts are resolved for a discount by resolvers (e.g. if you had another custom resolver for percentage discounts) the largest amount is resolved. This can be changed to instead prioritise the smallest amount:
\Aero\Cart\PercentageDiscount::giveMinResolvedAmount();
In fact, you can even take full control over which amount would be resolved. For example, you could resolve the largest amount for customers but the lowest amount for guests:
\Aero\Cart\PercentageDiscount::determineResolvedAmount(function(array $amounts) {
$customer = \Aero\Cart\Facades\Cart::customer();
return $customer ? max($amounts) : min($amounts);
});
How can I intercept discount code handling?
You can use the addCodeHandler() method to add a discount handler to the cart, it will run the provided callback whenever a code is added to the cart:
\Aero\Cart\Cart::addCodeHandler(function (\Aero\Cart\Cart $cart, string $code) {
if ($code === 'acme') {
// Do external stuff...
return true;
}
return false;
});
Return true to handle the code yourself. Return false to let the Cart handle it normally.
How can I apply multiple discount types using one code?
There are two aerocargo modules that can be used to achieve this behaviour:
aerocargo/discount-groups
This module allows you to create a discount group with a code and specify the discounts you want to be applied when that code is applied to the cart.
So you can create a group that adds a 20% off discount & a free shipping discount, while maintaining the flexibility of both being able to be added separately.
aerocargo/connected-discounts
This module allows you to connect a discount to another one via the discount edit page. Then when a code that has any connected discounts is applied, all connected discounts will also be applied.
So you can connect a free shipping discount to a 20% off discount, meaning when the 20% off discount is added so is free shipping.
Unless you also connect the 20% off discount to the free shipping as well, it wont work both ways.