In order to calculate a discount based on quantity of items in the cart that will take in consideration also the different weight of modifiers (suppose I sell the same product in different containers weighing from 1 to 210kg), I came up with an extension which grabs the $item->$item_qty at every order update, multiplies that value with the $item->sku, adds to the total of Kg being orderd and, based on a table of different discounts hardcoded with conditionals in the extension's php file, calculates the discount to be applied.
I can't seem to pass the $order->$order_discount to the actual order. When I submit the form, the order total doesn't take into account the calculated discount.
Here's my code
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Store Discount Extension
*
* @package ExpressionEngine
* @subpackage Addons
* @category Extension
* @author Milksamsa
* @link http://
*/
class Store_discount_ext {
public $settings = array();
public $description = 'Force discount based on item quantity and SKU multiplier';
public $docs_url = 'http://';
public $name = 'SKUdiscount';
public $settings_exist = 'n';
public $version = '1.0';
private $EE;
/**
* Constructor
*
* @param mixed Settings array or empty string if none exist.
*/
public function __construct($settings = '')
{
$this->EE =& get_instance();
$this->settings = $settings;
}
// ----------------------------------------------------------------------
/**
* Activate Extension
*
* This function enters the extension into the exp_extensions table
*
* @see http://codeigniter.com/user_guide/database/index.html for
* more information on the db class.
*
* @return void
*/
public function activate_extension()
{
// Setup custom settings in this array.
$this->settings = array();
// Add hooks
$data = array(
'class' => __CLASS__,
'method' => 'update_cart',
'hook' => 'store_order_recalculate_end',
'settings' => serialize($this->settings),
'priority' => 10,
'version' => $this->version,
'enabled' => 'y'
);
$this->EE->db->insert('extensions', $data);
}
// ----------------------------------------------------------------------
/**
* Disable Extension
*
* This method removes information from the exp_extensions table
*
* @return void
*/
function disable_extension()
{
$this->EE->db->where('class', __CLASS__);
$this->EE->db->delete('extensions');
}
// ----------------------------------------------------------------------
/**
* Update Extension
*
* This function performs any necessary db updates when the extension
* page is visited
*
* @return mixed void on update / false if none
*/
function update_extension($current = '')
{
if ($current == '' OR $current == $this->version)
{
return FALSE;
}
$this->EE->db->where('class', __CLASS__);
$this->EE->db->update(
'extensions',
array('version' => $this->version)
);
}
// ----------------------------------------------------------------------
/**
* Responds to the store_cart_update_end hook in Exp:resso Store
* to apply a discount to each product, as needed
*
* @return array of cart items
*/
function update_cart($order)
{
if ($this->EE->extensions->last_call)
{
$order = $this->EE->extensions->last_call;
}
// Get the number of products currently in the user's cart
$order->order_discount = 0;
$total_q = 0;
foreach ($order->items as $item) {
$sku = $item->sku;
$item_q = $item->item_qty * $sku;
$total_q = $total_q + $item_q;
}
if ($total_q >= 24 && $total_q < 30){
$order->order_discount = $total_q * 0.5;
}
if ($total_q >= 30 && $total_q < 60){
$order->order_discount = $total_q * 0.6;
}
if ($total_q >= 60 && $total_q < 100){
$order->order_discount = $total_q * 0.95;
}
if ($total_q >= 100 && $total_q < 200){
$order->order_discount = $total_q * 1.5;
}
if ($total_q >= 200 && $total_q < 210){
$order->order_discount = $total_q * 1.55;
}
if ($total_q >= 210){
$order->order_discount = $total_q * 1.7;
}
return $order_discount;
}
}
/* End of file ext.store_discount.php */
/* Location: /third_party/store_discount/ext.store_discount_batch.php */
//UPDATE
I've followed this procedure: https://gist.github.com/bryantAXS/10882383 Not sure where to go from here. I've not included the calculations for now, for testing purpose I've limited the discount amount to 4.
- I created a new folder in third_party named store_helpers
- I created a new folder in there named store_helpers/classes
- I created a CustomDiscountAdjuster.php class inside it
- I created a ext.store_helpers.php file in third_party/store_helpers
My CustomDiscountAdjuster.php file contains:
<?php
// Inside our custom third_party addon folder, /third_party/store_helpers, we have a folder called "classes."
// Within the classes directory we have this file, which holds our custom build Adjuster Class.
//
// You should be able to see how this class is passed our $order object, and then instantiates a new
// Order Adjustment object, which we use to make the adjustment. There are a few properties on the Order Adjustment
// object (nane, type, amount, etc..) that define the adjustment. The adjustment is then returned and processed.
namespace Store\Adjuster;
require PATH_THIRD.'store'.'/autoload.php';
use Store\Model\Order;
use Store\Model\OrderAdjustment;
/**
* Calculate handling surcharge applicable to an order
*/
class CustomDiscountAdjuster implements AdjusterInterface
{
public function adjust(Order $order)
{
$adjustment = new OrderAdjustment();
$adjustment->name = "Custom Discount Adjuster";
$adjustment->type = 'Custom Discount';
$adjustment->amount = 10;
$adjustment->taxable = 1;
$adjustment->included = 1;
return array($adjustment);
return array();
}
}
My ext.store_helpers.php file contains:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Store Discount Extension
*
* @package ExpressionEngine
* @subpackage Addons
* @category Extension
* @author Milksamsa
* @link http://
*/
class Store_helpers_ext {
public $settings = array();
public $description = 'Force discount based on item quantity and SKU multiplier';
public $docs_url = 'http://';
public $name = 'Store Custom EQ Discounts';
public $settings_exist = 'n';
public $version = '1.0';
private $EE;
/**
* Constructor
*
* @param mixed Settings array or empty string if none exist.
*/
public function __construct($settings = '')
{
$this->EE =& get_instance();
$this->settings = $settings;
}
// ----------------------------------------------------------------------
/**
* Activate Extension
*
* This function enters the extension into the exp_extensions table
*
* @see http://codeigniter.com/user_guide/database/index.html for
* more information on the db class.
*
* @return void
*/
public function activate_extension()
{
// Setup custom settings in this array.
$this->settings = array();
// Add hooks
$data = array(
'class' => __CLASS__,
'method' => 'update_cart',
'hook' => 'store_order_adjusters',
'settings' => serialize($this->settings),
'priority' => 10,
'version' => $this->version,
'enabled' => 'y'
);
$this->EE->db->insert('extensions', $data);
}
// ----------------------------------------------------------------------
/**
* Disable Extension
*
* This method removes information from the exp_extensions table
*
* @return void
*/
function disable_extension()
{
$this->EE->db->where('class', __CLASS__);
$this->EE->db->delete('extensions');
}
// ----------------------------------------------------------------------
/**
* Update Extension
*
* This function performs any necessary db updates when the extension
* page is visited
*
* @return mixed void on update / false if none
*/
public function store_order_adjusters($adjusters)
{
$adjusters[40] = new Store\Adjuster\CustomDiscountAdjuster;
return $adjusters;
}
// ----------------------------------------------------------------------
/**
* Responds to the store_cart_update_end hook in Exp:resso Store
* to apply a discount to each product, as needed
*
* @return array of cart items
*/
}
/* End of file ext.store_discount.php */
/* Location: /third_party/store_helpers/ext.store_helpers.php */
Definitely something's going one, since taxes no longer get calculated when store_helpers extension is enabled