<p>Best way to collate this sort of feedback or request is here, Steven: <a href="http://feedback.craftcms.com/forums/285221-feature-requests" rel="nofollow">http://feedback.craftcms.com/forums/285221-feature-requests</a></p>

<p>Let us know where you add it, so we can back it too...</p>

<p>Hope it helps</p>

CC BY-SA 3.0
2016-03-13T15:46:44.043Z
2016-03-13T15:46:44.043Z
Matt P
<p>The documentation for adjusters is here:</p>

<p><a href="https://craftcommerce.com/docs/adjusters" rel="nofollow noreferrer">https://craftcommerce.com/docs/adjusters</a>
and
<a href="https://craftcommerce.com/docs/order-adjustment-model" rel="nofollow noreferrer">https://craftcommerce.com/docs/order-adjustment-model</a></p>

<p>Essentially your plugin creates a class that fulfils the interface at:
<code>plugins/commerce/Commerce/Adjusters/Commerce_AdjusterInterface.php</code> - which is very simple:</p>

<pre><code>interface Commerce_AdjusterInterface
{
    /**
     * The adjust method modifies the order values (like baseShippingCost),
     * and records all adjustments by returning one or more orderAdjusterModels
     * to be saved on the order.
     *
     * @param Commerce_OrderModel $order
     * @param array $lineItems
     *
     * @return \Craft\Commerce_OrderAdjustmentModel[]
     */
    public function adjust(Commerce_OrderModel &amp;$order, array $lineItems = []);
}
</code></pre>

<p>Your plugin (in your main plugin .php file) then just registers your new adjuster to hook it up.  I'd suggest storing your actual adjuster classes in files in an <code>Adjusters</code> folder, lime Commerce itself does.</p>

<pre><code>//at the top, to include your class
require_once('Adjusters/BusinessLogic_TestAdjuster.php');

...

//this registers the adjuster with Commerce so it will be applied to carts
public function commerce_registerOrderAdjusters(){
  return [
    new \Commerce\Adjusters\BusinessLogic_TaxRemover
  ];
}
</code></pre>

<p>The adjuster (as you can see) has access to the order and line items and you can basically use any code you like to implement your discount offer, e.g. checking if the qty of something is over 3, and then reducing the price.  It builds &amp; returns <code>Commerce_OrderAdjustmentModel</code>s which describe the adjustment(s) made by the adjuster.  </p>

<p>Here's a super simple example adjuster:</p>

<pre><code>&lt;?php

namespace Commerce\Adjusters;
use Craft\Commerce_LineItemModel;
use Craft\Commerce_OrderAdjustmentModel;
use Craft\Commerce_OrderModel;

class BusinessLogic_TaxRemover implements Commerce_AdjusterInterface {

 public function adjust(Commerce_OrderModel &amp;$order, array $lineItems = []){

    $myAdjuster = new Commerce_OrderAdjustmentModel();

    $order-&gt;baseDiscount = $order-&gt;baseDiscount - 5;

    $myAdjuster-&gt;type = "Test";
    $myAdjuster-&gt;name = "Test Adjuster";
    $myAdjuster-&gt;description = "Takes $5 off the order";
    $myAdjuster-&gt;amount = -5.0;
    $myAdjuster-&gt;orderId = $order-&gt;id;
    //if your Adjuster affects lineItems rather than the total, you record the ids here
    $myAdjuster-&gt;optionsJson = ['lineItemsAffected'=&gt;null];
    $myAdjuster-&gt;included = false;

    return [$myAdjuster];

   }

}
</code></pre>

<p>My advice is to being it to generate plugin scaffolding using: <a href="http://pluginfactory.io/" rel="nofollow noreferrer">http://pluginfactory.io/</a> - to get you started - removes a lot of the pain points in getting started (such as the cursed capitilisation issues which I swear are the hardest part about getting started with plugins!).</p>

<p>Alternatively, you can take the scaffolding from <a href="https://github.com/lindseydiloreto/craft-businesslogic" rel="nofollow noreferrer">https://github.com/lindseydiloreto/craft-businesslogic</a> - and put in there, which makes good sense as this pretty much the textbook definition of business logic.  Just clone that, add your adjuster class, and do the registration and away you go!</p>

<p>As long as you're comfortable with PHP implementing a discounter like you describe is really quite simple.  If you're not then it's a perfect way to get more comfortable and I'm sure folks will be happy to help along the way!</p>

CC BY-SA 3.0
2016-03-14T10:27:59.540Z
I guess it's time to start getting my hands dirty with plugins. I'm a front-end guy and writing plugins scares me :)
Steven Grant
CC BY-SA 3.0
2016-03-14T11:04:13.300Z
Find us on Slack if you need help as you go.  You'll get there! :)
Jeremy Daalder
CC BY-SA 3.0
2016-03-15T03:57:48.020Z
Nice Answer. Craft Commerce is pretty new too, I'd imagine they'll be some handy plugins with nice UIs for this sort of thing to make of the pain easier ;)
RitterKnight
CC BY-SA 3.0
2016-03-16T01:17:01.437Z
@StevenGrant Perhaps accept this answer?  Although I agree with the above, likely a good discounts plugin is in Commerce's future, for now you'd have to do it like this.
Jeremy Daalder
CC BY-SA 3.0
2016-03-14T01:41:36.573Z
2017-04-05T11:22:02.030Z
2017-04-05T11:22:02.030Z
Jeremy Daalder
<p>I'm looking for a way to offer "3 for 2 / 2 for 1" type options with Commerce.</p>

<p>I've been able to achieve this just by adding a default value to a coupon code input.</p>

<p>It works, kinda. If we need to stick with that then we'd be satisfied but where it fails is; say I have 6 items in the cart, I only get the offer on the first 3.</p>

<p>This is a small store with just a handful of items for sale so not a deal breaker but I can imagine other larger stores doing similar.</p>

<p>Adjusters have been mentioned on Twitter but unsure how to follow that through.</p>

CC BY-SA 3.0
2016-12-15T10:52:59.650Z
I built a plugin that does what it sounds like you're looking for: https://craftpl.us/plugins/product-deals
Stephen Hamilton
<plugin-craftcommerce><promotions>
3 for 2 etc with Craft Commerce
# 3 for 2 etc with Craft Commerce

(Asked by: username_0 on 2016-03-11)

I'm looking for a way to offer "3 for 2 / 2 for 1" type options with Commerce.

I've been able to achieve this just by adding a default value to a coupon code input.

It works, kinda. If we need to stick with that then we'd be satisfied but where it fails is; say I have 6 items in the cart, I only get the offer on the first 3.

This is a small store with just a handful of items for sale so not a deal breaker but I can imagine other larger stores doing similar.

Adjusters have been mentioned on Twitter but unsure how to follow that through.

**Tags:** plugin-craftcommerce, promotions

> **Comments:**
> **username_1**: I built a plugin that does what it sounds like you're looking for: https://craftpl.us/plugins/product-deals  

---

## 2 answers

### Answer by username_3 on 2016-03-14. Score: 7 | Accepted answer

The documentation for adjusters is here:
https://craftcommerce.com/docs/adjusters
and
https://craftcommerce.com/docs/order-adjustment-model
Essentially your plugin creates a class that fulfils the interface at:
plugins/commerce/Commerce/Adjusters/Commerce_AdjusterInterface.php - which is very simple:
interface Commerce_AdjusterInterface
{
    /**
     * The adjust method modifies the order values (like baseShippingCost),
     * and records all adjustments by returning one or more orderAdjusterModels
     * to be saved on the order.
     *
     * @param Commerce_OrderModel $order
     * @param array $lineItems
     *
     * @return \Craft\Commerce_OrderAdjustmentModel[]
     */
    public function adjust(Commerce_OrderModel &$order, array $lineItems = []);
}

Your plugin (in your main plugin .php file) then just registers your new adjuster to hook it up.  I'd suggest storing your actual adjuster classes in files in an Adjusters folder, lime Commerce itself does.
//at the top, to include your class
require_once('Adjusters/BusinessLogic_TestAdjuster.php');

...

//this registers the adjuster with Commerce so it will be applied to carts
public function commerce_registerOrderAdjusters(){
  return [
    new \Commerce\Adjusters\BusinessLogic_TaxRemover
  ];
}

The adjuster (as you can see) has access to the order and line items and you can basically use any code you like to implement your discount offer, e.g. checking if the qty of something is over 3, and then reducing the price.  It builds & returns Commerce_OrderAdjustmentModels which describe the adjustment(s) made by the adjuster.  
Here's a super simple example adjuster:
baseDiscount = $order->baseDiscount - 5;

    $myAdjuster->type = "Test";
    $myAdjuster->name = "Test Adjuster";
    $myAdjuster->description = "Takes $5 off the order";
    $myAdjuster->amount = -5.0;
    $myAdjuster->orderId = $order->id;
    //if your Adjuster affects lineItems rather than the total, you record the ids here
    $myAdjuster->optionsJson = ['lineItemsAffected'=>null];
    $myAdjuster->included = false;

    return [$myAdjuster];

   }

}

My advice is to being it to generate plugin scaffolding using: http://pluginfactory.io/ - to get you started - removes a lot of the pain points in getting started (such as the cursed capitilisation issues which I swear are the hardest part about getting started with plugins!).
Alternatively, you can take the scaffolding from https://github.com/lindseydiloreto/craft-businesslogic - and put in there, which makes good sense as this pretty much the textbook definition of business logic.  Just clone that, add your adjuster class, and do the registration and away you go!
As long as you're comfortable with PHP implementing a discounter like you describe is really quite simple.  If you're not then it's a perfect way to get more comfortable and I'm sure folks will be happy to help along the way!

> **Comments:**
> **username_0**: I guess it's time to start getting my hands dirty with plugins. I'm a front-end guy and writing plugins scares me :)  
> **username_3**: Find us on Slack if you need help as you go.  You'll get there! :)  
> **username_4**: Nice Answer. Craft Commerce is pretty new too, I'd imagine they'll be some handy plugins with nice UIs for this sort of thing to make of the pain easier ;)  
> **username_3**: @StevenGrant Perhaps accept this answer?  Although I agree with the above, likely a good discounts plugin is in Commerce's future, for now you'd have to do it like this.  

---

### Answer by username_2 on 2016-03-13. Score: 1

Best way to collate this sort of feedback or request is here, Steven: <http://feedback.craftcms.com/forums/285221-feature-requests>

Let us know where you add it, so we can back it too...

Hope it helps


---

