Skip to content

Instantly share code, notes, and snippets.

@AugustMiller
Last active January 26, 2021 23:09
Show Gist options
  • Save AugustMiller/d18ea519665016648b593bdc31985e63 to your computer and use it in GitHub Desktop.
Save AugustMiller/d18ea519665016648b593bdc31985e63 to your computer and use it in GitHub Desktop.
Reduces the current Cart/Order's total by some percentage of the combined total of the previous 6 orders.
<?php
namespace dpdx\plugin\adjusters;
use Craft;
use craft\base\Component;
use craft\helpers\ArrayHelper;
use craft\commerce\Plugin as Commerce;
use craft\commerce\base\AdjusterInterface;
use craft\commerce\elements\Order;
use craft\commerce\models\OrderAdjustment;
use Exception;
/**
* Frequent Buyer Adjuster
*
* @author oof. Studio <hello@oof.studio>
* @since 0.0.1
*/
class FrequentBuyer extends Component implements AdjusterInterface
{
// Constants
// =========================================================================
/**
* @inheritdoc
*/
const ADJUSTMENT_TYPE = 'frequent-buyer';
/**
* @var int Interval at which the discount is applied.
*/
const ADJUSTMENT_ORDER_INTERVAL = 6;
/**
* @var int Percentage (as a value between 0 and 1) used as a factor in calculating the discount.
*/
const ADJUSTMENT_MULTIPLIER = 0.05;
// Public Methods
// =========================================================================
/**
* @inheritdoc
*/
public function adjust(Order $order): array
{
$orders = Order::find()
->customer($order->getCustomer())
->isCompleted(true)
->orderBy('dateOrdered DESC')
->all();
// Modulo will tell us if the current order is the "Nth + 1" (when this returns `0`, the user has a multiple of `ADJUSTMENT_ORDER_INTERVAL` completed Orders):
if (count($orders) % self::ADJUSTMENT_ORDER_INTERVAL) {
// Bail early; nothing to apply!
return [];
}
$mostRecentOrders = array_slice($orders, 0, self::ADJUSTMENT_ORDER_INTERVAL);
$adjustment = new OrderAdjustment([
'type' => self::ADJUSTMENT_TYPE,
'name' => 'Frequent customer discount',
'description' => 'We appreciate your business!',
'sourceSnapshot' => [
'applicableOrderIds' => ArrayHelper::getColumn($orders, 'id')
]
]);
$adjustment->setOrder($order);
$adjustment->amount = -1 * self::ADJUSTMENT_MULTIPLIER * array_reduce($mostRecentOrders, function ($total, $order) {
return $total + $order->getTotal();
}, 0.0);
return [$adjustment];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment