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_OrderAdjustmentModel
s which describe the adjustment(s) made by the adjuster.
Here's a super simple example adjuster:
<?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 &$order, array $lineItems = []){
$myAdjuster = new Commerce_OrderAdjustmentModel();
$order->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!