# Discounts

# 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:

```php
\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:

```php
\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:

```php
\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:

```php
\Aero\Cart\Cart::addCodeHandler(function (\Aero\Cart\Cart $cart, string $code) {
    if ($code === 'acme') {
        // Do external stuff...

        return true;
    }

    return false;
});
```

<p class="callout info">Return `true` to handle the code yourself. Return `false` to let the Cart handle it normally.</p>

# How can I apply multiple discount types using one code?

There are two `aerocargo` modules that can be used to achieve this behaviour:

### `<a href="https://agora.aerocommerce.com/packages/aerocargo/discount-groups" rel="noopener" target="_blank">aerocargo/discount-groups</a>`  


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 &amp; a free shipping discount, while maintaining the flexibility of both being able to be added separately.

### [`aerocargo/connected-discounts`](https://agora.aerocommerce.com/packages/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.

<p class="callout warning">Unless you also connect the 20% off discount to the free shipping as well, it wont work both ways.</p>