Last active
September 20, 2019 14:37
-
-
Save hendrikeng/4e02199fda7c4171fb31fb53b2ff0520 to your computer and use it in GitHub Desktop.
Discount Plugin and Adjuster
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 | |
/** | |
* Friendsdiscount plugin for Craft CMS 3.x | |
* | |
* Price adjuster that gives discount if a specific product type has been purchased in a specific time frame | |
* | |
* @link https://github.com/hendrikeng | |
* @copyright Copyright (c) 2018 Hendrik Werner | |
*/ | |
namespace hendrikeng\friendsdiscount; | |
use Craft; | |
use craft\base\Plugin; | |
use craft\services\Plugins; | |
use craft\events\PluginEvent; | |
use craft\commerce\services\OrderAdjustments; | |
use craft\events\RegisterComponentTypesEvent; | |
use hendrikeng\friendsdiscount\adjusters\FriendsDiscountAdjuster; | |
use yii\base\Event; | |
/** | |
* Craft plugins are very much like little applications in and of themselves. We’ve made | |
* it as simple as we can, but the training wheels are off. A little prior knowledge is | |
* going to be required to write a plugin. | |
* | |
* For the purposes of the plugin docs, we’re going to assume that you know PHP and SQL, | |
* as well as some semi-advanced concepts like object-oriented programming and PHP namespaces. | |
* | |
* https://craftcms.com/docs/plugins/introduction | |
* | |
* @author Hendrik Werner | |
* @package Friendsdiscount | |
* @since 1.0.0 | |
* | |
*/ | |
class Friendsdiscount extends Plugin | |
{ | |
// Static Properties | |
// ========================================================================= | |
/** | |
* Static property that is an instance of this plugin class so that it can be accessed via | |
* Friendsdiscount::$plugin | |
* | |
* @var Friendsdiscount | |
*/ | |
public static $plugin; | |
// Public Properties | |
// ========================================================================= | |
/** | |
* To execute your plugin’s migrations, you’ll need to increase its schema version. | |
* | |
* @var string | |
*/ | |
public $schemaVersion = '1.0.0'; | |
// Public Methods | |
// ========================================================================= | |
/** | |
* Set our $plugin static property to this class so that it can be accessed via | |
* Friendsdiscount::$plugin | |
* | |
* Called after the plugin class is instantiated; do any one-time initialization | |
* here such as hooks and events. | |
* | |
* If you have a '/vendor/autoload.php' file, it will be loaded for you automatically; | |
* you do not need to load it in your init() method. | |
* | |
*/ | |
public function init() | |
{ | |
parent::init(); | |
self::$plugin = $this; | |
// Do something after we're installed | |
Event::on( | |
Plugins::class, | |
Plugins::EVENT_AFTER_INSTALL_PLUGIN, | |
function(PluginEvent $event) { | |
if ($event->plugin === $this) { | |
// We were just installed | |
} | |
} | |
); | |
Event::on( | |
OrderAdjustments::class, | |
OrderAdjustments::EVENT_REGISTER_ORDER_ADJUSTERS, | |
function(RegisterComponentTypesEvent $event) { | |
$event->types[] = FriendsDiscountAdjuster::class; | |
} | |
); | |
/** | |
* Logging in Craft involves using one of the following methods: | |
* | |
* Craft::trace(): record a message to trace how a piece of code runs. This is mainly for development use. | |
* Craft::info(): record a message that conveys some useful information. | |
* Craft::warning(): record a warning message that indicates something unexpected has happened. | |
* Craft::error(): record a fatal error that should be investigated as soon as possible. | |
* | |
* Unless `devMode` is on, only Craft::warning() & Craft::error() will log to `craft/storage/logs/web.log` | |
* | |
* It's recommended that you pass in the magic constant `__METHOD__` as the second parameter, which sets | |
* the category to the method (prefixed with the fully qualified class name) where the constant appears. | |
* | |
* To enable the Yii debug toolbar, go to your user account in the AdminCP and check the | |
* [] Show the debug toolbar on the front end & [] Show the debug toolbar on the Control Panel | |
* | |
* http://www.yiiframework.com/doc-2.0/guide-runtime-logging.html | |
*/ | |
Craft::info( | |
Craft::t( | |
'friendsdiscount', | |
'{name} plugin loaded', | |
['name' => $this->name] | |
), | |
__METHOD__ | |
); | |
} | |
// Protected Methods | |
// ========================================================================= | |
} |
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 craft\commerce\adjusters; | |
use Craft; | |
use craft\commerce\base\AdjusterInterface; | |
use craft\commerce\elements\Order; | |
use craft\commerce\models\OrderAdjustment; | |
use craft\commerce\Plugin; | |
class FriendsDiscountAdjuster implements AdjusterInterface | |
{ | |
/** | |
* Check if the customer has lineItems with product.type 'donation' | |
* in his current cart and if the donation is more than $75. | |
*/ | |
public function checkIfInCart($order) | |
{ | |
// get current cart | |
$cart = Plugin::getInstance()->getCart(); | |
$didDonate = false; | |
// get lineItems from current cart and check if rules apply | |
foreach ($cart->getLineItems() as $lineItem) { | |
$purchable = $lineItem->getPurchasable(); | |
if ($purchable && $purchable instanceof \craft\commerce\elements\Variant && $purchable->getProduct()->getType()->handle == 'donation' && $purchable->getPrice() >= '75') { | |
$didDonate = true; | |
} | |
} | |
return $didDonate; | |
} | |
/** | |
* Check if the customer has bought a lineItem with product.type 'donation' | |
* in his previous orders and if the donation was more than $75. | |
* and not older than 365 days | |
*/ | |
public function checkIfDonated($order) | |
{ | |
// get users email | |
$email = $order->getEmail(); | |
if (!$email) { | |
return false; | |
} | |
// get previous orders by users email | |
$orders = Plugin::getInstance()->getOrders()->getOrdersByEmail($email); | |
$didDonate = false; | |
// get pervious orders and check if rules apply | |
foreach ($orders as $previousOrder) { | |
// get amount of days since the order has been placed | |
$timeDiff = abs(strtotime(date('Y/m/d', time())) - strtotime($previousOrder->dateOrdered->format('Y/m/d'))); | |
$numberDays = intval($timeDiff / 86400); | |
// if order is not older than 365 days return didDontate with true | |
if ($numberDays <= '365') { | |
foreach ($previousOrder->getLineItems() as $lineItem) { | |
$purchable = $lineItem->getPurchasable(); | |
if ($purchable && $purchable instanceof \craft\commerce\elements\Variant && $purchable->getProduct()->getType()->handle == 'donation' && $purchable->getPrice() >= '75' && $purchable) { | |
$didDonate = true; | |
} | |
} | |
} | |
} | |
return $didDonate; | |
} | |
/** | |
* Apply dicount if customer donated | |
*/ | |
public function adjust(Order $order): array | |
{ | |
// get the current cart | |
$cart = Plugin::getInstance()->getCart(); | |
// check if a donation is in current cart or in a previous order | |
if ($this->checkIfInCart($order) == true || $this->checkIfDonated($order) == true) { | |
// get lineitems from cart to apply discount on | |
foreach ($cart->getLineItems() as $lineItem) { | |
$purchable = $lineItem->getPurchasable(); | |
$quantity = $lineItem->qty; | |
// check if lineitems belong to the productype shop | |
if ($purchable && $purchable instanceof \craft\commerce\elements\Variant && $purchable->getProduct()->getType()->handle == 'shop') { | |
// apply discount | |
$purchablePrice = $purchable->getPrice(); | |
$discountValues[] = $purchablePrice * 0.4 * $quantity; | |
} | |
} | |
// sum up all dicountValues | |
$totalDiscount = array_sum($discountValues); | |
// set new OrderAdjustment $friendAdjuster | |
$friendsDiscountAdjuster = new OrderAdjustment(); | |
$friendsDiscountAdjuster->type = "Freundesrabatt"; | |
$friendsDiscountAdjuster->name = "40% Freundesrabatt"; | |
$friendsDiscountAdjuster->amount = -$totalDiscount; | |
$friendsDiscountAdjuster->description = $friendsDiscountAdjuster->amount; | |
$friendsDiscountAdjuster->orderId = $order->id; | |
$friendsDiscountAdjuster->included = false; | |
return [$friendsDiscountAdjuster]; | |
} | |
return []; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment