Last active
January 26, 2021 23:09
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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 <[email protected]> | |
* @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