roykin/modules/giveagift/giveagift.php

1076 lines
38 KiB
PHP

<?php
/**
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com>
* @copyright 2007-2016 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (!defined('_PS_VERSION_')) exit;
class GiveAGift extends Module
{
public $errors = array();
protected $html = '';
/* maximum timestamp for 32 bits systems */
const MAX_DATE = '2038-01-19 03:14:07';
public function __construct()
{
$this->name = 'giveagift';
$this->tab = 'merchandizing';
$this->version = '2.1.2';
$this->author = 'StudioCloud';
$this->bootstrap = true;
$this->module_key = 'e16dba5968963e720be9e9062a37f186';
$this->confirmUninstall = $this->l('Are you sure you want to uninstall ?');
$this->ps_versions_compliancy = array('min' => '1.5.0.0', 'max' => '1.6.99.99');
parent::__construct();
$this->displayName = $this->l('Give a gift');
$this->description = $this->l('This module allows the customer to choose a gift depending on the total price of his order.');
}
public function install($keep_data = false)
{
include(dirname(__FILE__).'/sql/install.php');
if (!$keep_data)
{
Configuration::updateValue('GIFT_ID_CURRENCY', (int)$this->context->currency->id);
Configuration::updateValue('GIFT_ONLY_FIRST_ORDER', 0);
Configuration::updateValue('GIFT_MIN_LEFT', 0);
Configuration::updateValue('GIFT_TAX_DISPLAY', 1);
Configuration::updateValue('PS_CART_RULE_FEATURE_ACTIVE', 1);
}
if (!parent::install() ||
!$this->registerHook('displayShoppingCartFooter') ||
!$this->registerHook('hookAfterDeleteCartRule') ||
!$this->registerHook('hookAfterDeleteCartRule') ||
!$this->registerHook('actionBeforeAjaxDieCartControllerdisplayAjax') ||
!$this->registerHook('backOfficeHeader') ||
!$this->registerHook('hookMobileHeader') ||
!$this->registerhook('header'))
return false;
return true;
}
public function uninstall($keep_data = false)
{
if (!$keep_data)
{
foreach ($this->getAllGifts(false) as $gift)
{
$cart_rule = new CartRule((int)$gift['id_cart_rule']);
$cart_rule->delete();
}
include(dirname(__FILE__).'/sql/uninstall.php');
Configuration::deleteByName('GIFT_ID_CURRENCY');
Configuration::deleteByName('GIFT_MIN_LEFT');
Configuration::deleteByName('GIFT_TAX_DISPLAY');
Configuration::deleteByName('GIFT_ONLY_FIRST_ORDER');
}
return parent::uninstall();
}
public function reset()
{
if ($this->uninstall(true))
return $this->install(true);
}
public function enable($force_all = false)
{
$db = Db::getInstance();
if (parent::enable($force_all))
foreach ($this->getAllGifts(false) as $gift)
$db->update('cart_rule', array('active' => 1), '`id_cart_rule` = '.(int)$gift['id_cart_rule']);
}
public function disable($force_all = false)
{
parent::disable($force_all);
$db = Db::getInstance();
foreach ($this->getAllGifts(false) as $gift)
$db->update('cart_rule', array('active' => 0), '`id_cart_rule` = '.(int)$gift['id_cart_rule']);
}
public function getContent()
{
$this->postProcess();
$helper = new HelperForm();
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->identifier = $this->identifier;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;
$helper->toolbar_scroll = true;
$helper->title = $this->displayName;
$helper->submit_action = 'submitConfiguration';
$languages = Language::getLanguages(false);
foreach ($languages as $k => $language)
$languages[$k]['is_default'] = (int)$language['id_lang'] == Configuration::get('PS_LANG_DEFAULT');
$helper->languages = $languages;
$helper->default_form_language = (int)Configuration::get('PS_LANG_DEFAULT');
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
// global configuration
$this->fields_form[0]['form'] = array(
'legend' => array(
'title' => $this->l('Global configuration'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => 'radio',
'label' => $this->l('Method of display of the minimum amount :'),
'name' => 'GIFT_TAX_DISPLAY',
'desc' => $this->l('In all cases, the rules apply to the total amount of the products, shipping excluded.'),
'class' => 't',
'values' => array(
array(
'id' => 'tax_display_on',
'value' => 1,
'label' => $this->l('Tax incl.')
),
array(
'id' => 'tax_display_off',
'value' => 0,
'label' => $this->l('Tax excl.')
)
),
),
array(
'type' => 'select',
'label' => $this->l('Currency used to manage the price ranges :'),
'name' => 'GIFT_ID_CURRENCY',
'options' => array(
'query' => Currency::getCurrencies(),
'id' => 'id_currency',
'name' => 'name'
),
),
array(
'type' => 'text',
'label' => $this->l('Minimum amount left to show the gifts (percent of the minimum amount) :'),
'desc' => $this->l('If you choose 60% with a minimum amount of 150€, the gifts will be shown when the amount is greater than 90€.').'<br/>'
.$this->l('Choose 0 if you want to always show the list of gifts.'),
'name' => 'GIFT_MIN_LEFT',
'suffix' => '%',
'class' => 'fixed-width-xs'
),
array(
'type' => version_compare(_PS_VERSION_, '1.6', '>=') ? 'switch' : 'radio',
'label' => $this->l('Only on customer\'s first order :'),
'name' => 'GIFT_ONLY_FIRST_ORDER',
'is_bool' => true,
'class' => 't',
'values' => array(
array(
'id' => 'first_order_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'first_order_off',
'value' => 0,
'label' => $this->l('No')
)
),
),
// ticket 12890
array(
'type' => 'select',
'label' => $this->l('Customers groups allowed to get a gift :'),
'name' => 'GIFT_CUSTOMER_GROUPS',
'options' => array(
'query' => $this->getGroupsSortedByName($this->context->language->id),
'id' => 'id_group',
'name' => 'name'
),
'multiple' => true,
'required' => true,
'size' => 25
)
),
'submit' => array(
'title' => $this->l('Save'),
'name' => 'submitGlobalConf'
)
);
$helper->fields_value = $this->getConfigFieldsValues();
$this->context->smarty->assign(array(
'ranges' => $this->getRanges(true, false),
'currency' => new Currency((int)Configuration::get('GIFT_ID_CURRENCY')),
'static_token' => Tools::getAdminToken($this->name.$this->context->employee->id),
//link without domain to avoid multishop conflicts
'giveagift_ajax_url' => preg_replace(
'#https?://([^/])+/#',
'/',
$this->context->link->getModuleLink('giveagift', 'ajax', array(), Configuration::get('PS_SSL_ENABLED_EVERYWHERE'))
),
'multishop_active' => Shop::isFeatureActive(),
'manufacturers_list' => Db::getInstance()->executeS(
'SELECT `id_manufacturer`, `name`
FROM `'._DB_PREFIX_.'manufacturer`'
)
));
$this->html = $this->context->smarty->fetch($this->local_path.'views/templates/admin/errors.tpl').
$helper->generateForm($this->fields_form);
if (version_compare(_PS_VERSION_, '1.6', '<'))
{
$this->html .= $this->context->smarty->fetch($this->local_path.'views/templates/admin/list_1.5.tpl').
$this->context->smarty->fetch($this->local_path.'views/templates/admin/add_1.5.tpl');
}
else
{
$this->html .= $this->context->smarty->fetch($this->local_path.'views/templates/admin/list.tpl').
$this->context->smarty->fetch($this->local_path.'views/templates/admin/add.tpl');
}
return $this->html;
}
/**
* ticket 12890
* @return indexed array of associated rows of groups sorted by names with 'name' as 'id - name'
*/
public function getGroupsSortedByName($id_lang)
{
$groups = array();
foreach(Group::getGroupsSortedByName($id_lang) as $row) {
$groups[] = array(
'id_group'=>$row['id_group'],
'name' => $row['id_group'].' - '.$row['name']
);
}
return $groups;
}
/**
* ticket 12890
* @return indexed array of module selected id_group
*/
public function getConfigCustomerGroups()
{
$groups = Configuration::get('GIFT_CUSTOMER_GROUPS');
if (empty($groups)) {
return array();
}
$groups = unserialize($groups);
if (!is_array($groups)) {
return array($groups);
}
return $groups;
}
public function getConfigFieldsValues()
{
return array(
'GIFT_TAX_DISPLAY' => (int)Tools::getValue('GIFT_TAX_DISPLAY', Configuration::get('GIFT_TAX_DISPLAY')),
'GIFT_ID_CURRENCY' => (int)Tools::getValue('GIFT_ID_CURRENCY', Configuration::get('GIFT_ID_CURRENCY')),
'GIFT_MIN_LEFT' => (float)Tools::getValue('GIFT_MIN_LEFT', Configuration::get('GIFT_MIN_LEFT')),
'GIFT_ONLY_FIRST_ORDER' => (int)Tools::getValue('GIFT_ONLY_FIRST_ORDER', Configuration::get('GIFT_ONLY_FIRST_ORDER')),
// ticket 12890
'GIFT_CUSTOMER_GROUPS[]' => Tools::getValue('GIFT_CUSTOMER_GROUPS', $this->getConfigCustomerGroups()),
);
}
public function postProcess()
{
$db = Db::getInstance();
if (Tools::isSubmit('submitGlobalConf'))
{
// ticket 12890
if (!Tools::getValue('GIFT_CUSTOMER_GROUPS')) {
$this->errors[] = $this->l('At least one customer group must be selected.');
}
else {
Configuration::updateValue('GIFT_TAX_DISPLAY', (int)Tools::getValue('GIFT_TAX_DISPLAY', 1));
Configuration::updateValue('GIFT_ID_CURRENCY', (int)Tools::getValue('GIFT_ID_CURRENCY', (int)$this->context->currency->id));
Configuration::updateValue('GIFT_MIN_LEFT', (float)Tools::getValue('GIFT_MIN_LEFT', 0));
Configuration::updateValue('GIFT_ONLY_FIRST_ORDER', (int)Tools::getValue('GIFT_ONLY_FIRST_ORDER', 0));
// ticket 12890
Configuration::updateValue('GIFT_CUSTOMER_GROUPS', serialize(Tools::getValue('GIFT_CUSTOMER_GROUPS')));
// change the configuration of the cart_rules
$db->update(
'cart_rule',
array(
'minimum_amount_tax' => (int)Tools::getValue('GIFT_TAX_DISPLAY', 1),
'minimum_amount_currency' => (int)Tools::getValue('GIFT_ID_CURRENCY', (int)$this->context->currency->id),
),
'`code` LIKE "GIFT%" AND `partial_use` = 0 AND `id_customer` = 0'
);
Tools::redirectAdmin(
$this->context->link->getAdminLink('AdminModules').
'&configure='.$this->name.'&conf=4'
);
}
}
if (Tools::isSubmit('submitDelete') && ($id_cart_rules = Tools::getValue('id_cart_rules', array())))
{
$id_cart_rules = implode(',', array_map('intval', $id_cart_rules));
$db->delete('cart_rule_shop', '`id_cart_rule` IN('.$id_cart_rules.')');
$db->delete('cart_rule', '`id_cart_rule` IN('.$id_cart_rules.')');
$db->delete('giveagift', '`id_cart_rule` IN('.$id_cart_rules.')');
Tools::redirectAdmin(
$this->context->link->getAdminLink('AdminModules').
'&configure='.$this->name.'&conf=1'
);
}
if (Tools::isSubmit('submitNewProduct'))
{
$id_product = (int)Tools::getValue('id_product', 0);
$id_product_attribute = (int)Tools::getValue('id_product_attribute', Product::getDefaultAttribute($id_product));
$minimum_amount = str_replace(',', '.', Tools::getValue('minimum_amount', ''));
$maximum_amount = str_replace(',', '.', Tools::getValue('maximum_amount', ''));
$id_manufacturer = (int)Tools::getValue('id_manufacturer', 0);
$date_from = Tools::getValue('date_from') ? Tools::getValue('date_from') : '1970-01-01 00:00:00';
$date_to = Tools::getValue('date_to') ? Tools::getValue('date_to') : self::MAX_DATE;
$product = new Product($id_product);
if ($id_product_attribute)
$combination = new Combination($id_product_attribute);
if ($id_manufacturer)
$manufacturer = new Manufacturer($id_manufacturer);
// controls on product
if (empty($product->id))
$this->errors[] = $this->l('Unable to load the product.');
elseif ($id_product_attribute && (empty($combination->id) || (int)$combination->id_product !== (int)$product->id))
$this->errors[] = $this->l('Unable to load the product combination.');
elseif (!$product->active || !$product->available_for_order)
$this->errors[] = $this->l('The product must be active and available for order.');
elseif ($this->giftExists($id_product, $id_product_attribute, $minimum_amount, $maximum_amount, $date_from, $date_to))
$this->errors[] = $this->l('This product is already a gift in this range of prices and for those dates.');
// controls on range
if ($minimum_amount !== '' && !is_numeric($minimum_amount))
$this->errors[] = $this->l('Invalid minimum amount.');
elseif ($maximum_amount !== '' && !is_numeric($maximum_amount))
$this->errors[] = $this->l('Invalid maximum amount.');
elseif ((float)$minimum_amount > (float)$maximum_amount && (float)$maximum_amount > 0)
$this->errors[] = $this->l('Invalid amount range.');
// controls on manufacturer
if ($id_manufacturer && empty($manufacturer->id))
$this->errors[] = $this->l('Unable to load the manufacturer.');
// controls on dates
if (($date_from && !Validate::isDate($date_from)) ||
($date_to && !Validate::isDate($date_to)) ||
($date_to && $date_from >= $date_to))
$this->errors[] = $this->l('Invalid range of dates.');
if (($date_from && defined('PHP_INT_SIZE') && PHP_INT_SIZE === 4 && $date_from > self::MAX_DATE) ||
($date_to && defined('PHP_INT_SIZE') && PHP_INT_SIZE === 4 && $date_to > self::MAX_DATE))
$this->errors[] = sprintf($this->l('Your system does not allow dates greater than %s.'), self::MAX_DATE);
if (empty($this->errors))
{
$cart_rule = new CartRule();
$cart_rule->id_customer = 0;
$cart_rule->date_from = pSQL($date_from);
$cart_rule->date_to = pSQL($date_to);
$cart_rule->description = pSQL(sprintf(
$this->l('Gift : %s'),
$product->name[$this->context->language->id]
));
$cart_rule->name[$this->context->language->id] = $cart_rule->description;
$cart_rule->quantity = 999999999;
$cart_rule->quantity_per_user = 999999999;
$cart_rule->priority = 1;
$cart_rule->partial_use = 0;
$cart_rule->code = 'GIFTTMP';
$cart_rule->minimum_amount = (float)$minimum_amount;
$cart_rule->minimum_amount_tax = (int)Configuration::get('GIFT_TAX_DISPLAY');
$cart_rule->minimum_amount_currency = (int)Configuration::get('GIFT_ID_CURRENCY');
$cart_rule->minimum_amount_shipping = 0;
$cart_rule->free_shipping = 0;
$cart_rule->gift_product = (int)$product->id;
$cart_rule->gift_product_attribute = (int)$id_product_attribute;
if (version_compare(_PS_VERSION_, '1.5.3', '>='))
$cart_rule->highlight = 0;
$cart_rule->active = 1;
$cart_rule->shop_restriction = 1;
if ($cart_rule->add() && !empty($cart_rule->id))
{
$result = $db->insert('giveagift', array(
'id_cart_rule' => (int)$cart_rule->id,
'maximum_amount' => (float)$maximum_amount,
'id_manufacturer' => (int)$id_manufacturer,
'date_add' => date('Y-m-d H:i:s')
));
//assigns unique code
$cart_rule->code = 'GIFT'.$db->Insert_ID();
$cart_rule->update();
//adds shop restrictions
foreach ($this->context->shop->getContextListShopID() as $id_shop)
$result &= $db->insert('cart_rule_shop', array('id_cart_rule' => (int)$cart_rule->id, 'id_shop' => (int)$id_shop));
if (!$result)
{
$this->errors[] = $this->l('An error occurred while saving the gift data.');
$db->delete('giveagift', '`id_cart_rule` = '.(int)$cart_rule->id);
$cart_rule->delete();
}
}
else
$this->errors[] = $this->l('An error occurred while saving the cart_rule.');
if (empty($this->errors))
Tools::redirectAdmin(
$this->context->link->getAdminLink('AdminModules').
'&configure='.$this->name.'&conf=3'
);
}
}
$this->context->smarty->assign('errors', $this->errors);
}
public function hookBackOfficeHeader()
{
if (Tools::strtolower(Tools::getValue('controller')) === 'adminmodules' && Tools::getValue('configure') === $this->name)
{
$this->context->controller->addJquery();
$this->context->controller->addJqueryPlugin('autocomplete');
$this->context->controller->addJS($this->_path.'views/js/back.js');
$this->context->controller->addCSS($this->_path.'views/css/back.css');
//datetimepicker
$this->context->controller->addJqueryUI(array('ui.slider', 'ui.datepicker'));
$this->context->controller->addJS(_PS_JS_DIR_.'jquery/plugins/timepicker/jquery-ui-timepicker-addon.js');
$this->context->controller->addCSS(_PS_JS_DIR_.'jquery/plugins/timepicker/jquery-ui-timepicker-addon.css');
}
}
public function hookMobileHeader()
{
return $this->hookHeader();
}
public function hookHeader()
{
if ($this->context->controller instanceOf ParentOrderController)
{
CartRule::autoRemoveFromCart($this->context);
$this->checkCartRules();
if (version_compare(_PS_VERSION_, '1.6', '<'))
$this->context->controller->addCSS($this->_path.'views/css/front_1.5.css');
$this->context->controller->addCSS($this->_path.'views/css/front.css');
$this->context->controller->addJS($this->_path.'views/js/front.js');
}
}
public function hookAfterDeleteCartRule($params)
{
if (empty($params['id_cart_rule']))
return;
Db::getInstance()->delete('giveagift', '`id_cart_rule` = '.(int)$params['id_cart_rule']);
}
public function hookAfterUpdateCartRule($params)
{
if (empty($params['id_cart_rule']) || !isset($params['minimum_amount']))
return;
$gift = Db::getInstance()->getRow(
'SELECT `id_gift`, `maximum_amount`
FROM `'._DB_PREFIX_.'giveagift`
WHERE `id_cart_rule` = '.(int)$params['id_cart_rule']
);
if ($gift)
{
// minimum_amount can't be greater than maximum_amount
if ((float)$params['minimum_amount'] > (float)$gift['maximum_amount'] && (float)$gift['maximum_amount'] > 0)
Db::getIntance()->update(
'giveagift',
array('maximum_amount' => 0),
'`id_gift` = '.(int)$gift['id_gift']
);
// replaces the tax method and currency with the ones from the module configuration
Db::getIntance()->update(
'cart_rule',
array(
'minimum_amount_tax' => (int)Configuration::get('GIFT_TAX_DISPLAY'),
'minimum_amount_currency' => (int)Configuration::get('GIFT_ID_CURRENCY'),
),
'`id_gift` = '.(int)$gift['id_gift']
);
}
}
// ticket 12890 : get all default categories of all products present in cart
public function getDefaultCategoriesFromCart($cart)
{
$cart_products = $cart->getProducts();
$cart_category_ids = array();
if (is_array($cart_products) && count($cart_products)>0) {
$cart_category_ids = Db::getInstance()->executeS('
SELECT product_shop.`id_category_default`
FROM `'._DB_PREFIX_.'product` p
'.Shop::addSqlAssociation('product', 'p').'
WHERE p.`id_product` IN ('.implode(',', array_column($cart->getProducts(), 'id_product')).')'
);
}
return array_column($cart_category_ids, 'id_category_default');
}
public function hookDisplayShoppingCartFooter()
{
//equivalent of hookActionBeforeAjaxDieCartControllerdisplayAjax for PS 1.5
if (version_compare(_PS_VERSION_, '1.6', '<') && Tools::getIsset('ajax') && $this->checkCartRules()){
die(Tools::jsonEncode(array('refresh' => true)));
}
// ticket 12890
if (!Validate::isLoadedObject($this->context->customer)) {
return '';
}
// forces the activation of the cart rule feature
Configuration::updateValue('PS_CART_RULE_FEATURE_ACTIVE', 1);
$cart_products = $this->context->cart->getProducts();
$cart_category_ids = $this->getDefaultCategoriesFromCart($this->context->cart);
$use_tax = (int)Configuration::get('GIFT_TAX_DISPLAY') === 1;
$gift_currency = new Currency((int)Configuration::get('GIFT_ID_CURRENCY'));
$on_first_order = (int)Configuration::get('GIFT_ONLY_FIRST_ORDER');
$min_left = (float)Configuration::get('GIFT_MIN_LEFT') / 100;
// ticket 12890 : filter ranges
$ranges = $this->getRangesFilteredBy($cart_category_ids, $this->context->customer, true, true, $cart_products);
$total_order = Tools::ps_round(
Tools::convertPriceFull(
$this->context->cart->getOrderTotal($use_tax, Cart::BOTH_WITHOUT_SHIPPING),
$this->context->currency,
$gift_currency
), 2
);
if (!empty($ranges) &&
(empty($this->context->customer->id) || (!$on_first_order || count(Order::getCustomerOrders($this->context->customer->id)) == 0)))
{
$gift_available = false; // at least one gift available ?
$gift_visible = false; // at least one gift visible ?
$gift_min_amount = false; // minimum amout to reach to get a gift
$ranges_available = 0;
foreach ($ranges as $i => &$range)
{
// we can select one gift per range
$range['selected'] = 0;
$range['visible'] = false;
$range['available'] = false;
$range['amount_left'] = false; // amount left to reach the next price range
$range['maximum_amount'] = Tools::ps_round((float)$range['maximum_amount'], 2);
$range['minimum_amount'] = Tools::ps_round((float)$range['minimum_amount'], 2);
if (!$gift_min_amount || $gift_min_amount > $range['minimum_amount'])
$gift_min_amount = $range['minimum_amount'];
foreach ($range['gifts'] as $j => &$gift)
{
$product = new Product((int)$gift['gift_product']);
// ticket 12890 : skip the gift when it is not belong to the cart default categories
//if (!in_array($product->id_category_default, $cart_category_ids)) {
// continue;
//}
if (Validate::isLoadedObject($product) && $product->checkQty(1) && $product->active && $product->available_for_order)
{
// gift has been selected
$gift['selected'] = self::giftIsUsed($gift['id_cart_rule']);
if ($gift['selected'])
$range['selected'] = (int)$gift['id_gift'];
// check if product is visible or available
if ($total_order >= $range['minimum_amount'] * $min_left)
{
if (!empty($gift['id_manufacturer']))
{
$total_m = 0;
foreach ($cart_products as $p)
if ((int)$p['id_manufacturer'] === (int)$gift['id_manufacturer'])
$total_m += $use_tax ? (float)$p['total_wt'] : (float)$p['total'];
$total_m = Tools::ps_round(Tools::convertPriceFull($total_m, $this->context->currency, $gift_currency), 2);
$gift['visible'] = $total_m > 0 && ($total_m < $range['maximum_amount'] || $range['maximum_amount'] <= 0);
$gift['available'] = $total_m && $total_m >= $range['minimum_amount'] &&
($total_m < $range['maximum_amount'] || $range['maximum_amount'] <= 0) &&
$gift['date_from'] <= date('Y-m-d H:i:s') && $gift['date_to'] >= date('Y-m-d H:i:s');
if ($gift['available'] && !$range['available'])
{
$range['available'] = true;
$ranges_available++;
}
if ($gift['visible'] && !$gift['available'] && (!$range['amount_left'] || $range['amount_left'] > $range['minimum_amount'] - $total_m))
$range['amount_left'] = $range['minimum_amount'] - $total_m;
}
else
{
$gift['visible'] = $total_order < $range['maximum_amount'] || $range['maximum_amount'] <= 0;
$gift['available'] = $total_order >= $range['minimum_amount'] &&
($total_order < $range['maximum_amount'] || $range['maximum_amount'] <= 0) &&
$gift['date_from'] <= date('Y-m-d H:i:s') && $gift['date_to'] >= date('Y-m-d H:i:s');
if ($gift['visible'] && !$gift['available'] && (!$range['amount_left'] || $range['amount_left'] > ($range['minimum_amount'] - $total_order)))
$range['amount_left'] = $range['minimum_amount'] - $total_order;
}
}
else
{
$gift['visible'] = false;
$gift['available'] = false;
}
$gift_available |= $gift['available'];
$gift_visible |= $gift['visible'];
$range['visible'] |= $gift['visible'];
$image_type = version_compare(_PS_VERSION_, '1.5.3', '<') ? 'home' : ImageType::getFormatedName('small');
$image = Image::getCover((int)$gift['gift_product']);
if (!empty($image['id_image']))
$gift['image'] = $this->context->link->getImageLink(
$gift['link_rewrite'],
(int)$gift['gift_product'].'-'.(int)$image['id_image'],
$image_type
);
else
$gift['image'] = false;
$gift['link'] = $this->context->link->getProductLink((int)$gift['gift_product']);
}
elseif (count($ranges[$i]['gifts']) === 1)
unset($ranges[$i]);
else
unset($ranges[$i]['gifts'][$j]);
}
$range['amount_left'] = $range['amount_left'] ? Tools::convertPriceFull($range['amount_left'], $gift_currency, $this->context->currency) : false;
if (!$range['visible'])
unset($ranges[$i]);
}
if (!$gift_visible)
return;
$this->context->smarty->assign(array(
'ranges' => $ranges,
'use_tax' => $use_tax,
'gift_min_amount' => $gift_min_amount ? Tools::convertPriceFull($gift_min_amount, $gift_currency, $this->context->currency) : false,
'gift_available' => $gift_available,
'ranges_available' => $ranges_available,
'gift_img_path' => '/modules/'.$this->name.'/views/img/gift.png',
'currency' => $this->context->currency,
//link without domain to avoid multishop conflicts
'giveagift_ajax_url' => preg_replace(
'#https?://([^/])+/#',
'/',
$this->context->link->getModuleLink('giveagift', 'ajax', array(), Configuration::get('PS_SSL_ENABLED'))
)
));
return $this->display(__FILE__, 'shoppingCart.tpl');
}
}
public function getAllGifts($full_informations = false, $active = false)
{
$db = Db::getInstance();
$gifts = $db->executeS(
'SELECT g.*, cr.`gift_product`, cr.`gift_product_attribute`, cr.`minimum_amount`, cr.`date_from`,
cr.`date_to`, pl.`name`, pl.`link_rewrite`, p.`reference`, m.`name` as `manufacturer_name`
FROM `'._DB_PREFIX_.'product_lang` pl, `'._DB_PREFIX_.'product` p, `'._DB_PREFIX_.'cart_rule` cr, `'._DB_PREFIX_.'giveagift` g
LEFT JOIN `'._DB_PREFIX_.'cart_rule_shop` crs ON (crs.`id_cart_rule` = g.`id_cart_rule`)
LEFT JOIN `'._DB_PREFIX_.'manufacturer` m ON (m.`id_manufacturer` = g.`id_manufacturer`)
WHERE g.`id_cart_rule` = cr.`id_cart_rule`
AND pl.`id_product` = cr.`gift_product`
AND pl.`id_product` = p.`id_product`
AND pl.`id_lang` = '.(int)$this->context->language->id.'
AND pl.`id_shop` = '.(int)$this->context->shop->id.'
'.($active === true ? 'AND cr.`active` = 1 AND cr.`date_from` < "'.date('Y-m-d H:i:s').'" AND cr.`date_to` > "'.date('Y-m-d H:i:s').'"' : '').'
AND (
cr.`shop_restriction` = 0
OR crs.`id_shop` IN (0, '.implode(', ', array_map('intval', $this->context->shop->getContextListShopID())).')
)'
);
// get lang and combinations informations
if (!empty($gifts) && $full_informations)
{
foreach ($gifts as &$g)
{
$sql = 'SELECT pa.`id_product_attribute`, pa.`reference`, ag.`id_attribute_group`,
agl.`name` AS group_name, al.`name` AS attribute_name, a.`id_attribute`
FROM `'._DB_PREFIX_.'product_attribute` pa
'.Shop::addSqlAssociation('product_attribute', 'pa').'
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group`
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)$this->context->language->id.')
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (
ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)$this->context->language->id.'
)
WHERE pa.`id_product_attribute` = '.(int)$g['gift_product_attribute'].'
GROUP BY ag.`id_attribute_group`';
// check if product has combinations
if ($g['gift_product_attribute'] && Combination::isFeatureActive() && ($combinations = $db->executeS($sql)))
{
foreach ($combinations as $combination)
{
$g['name'] .= ' '.$combination['group_name'].'-'.$combination['attribute_name'];
if (!empty($combination['reference']))
$g['reference'] = $combination['reference'];
}
}
if ($this->context->controller instanceOf AdminController && !empty($g['reference']))
$g['name'] .= ' '.sprintf($this->l('(ref: %s)'), $g['reference']);
}
}
return empty($gifts) ? array() : $gifts;
}
/**
* Get a list of all the gifts grouped by price ranges.
*
* @access public
* @return array
*/
public function getRanges($full_informations = false, $active = false)
{
$ranges = array();
$gifts = $this->getAllGifts($full_informations, $active);
foreach ($gifts as $gift)
{
$range = Tools::ps_round((float)$gift['minimum_amount'], 2).
'|'.Tools::ps_round((float)$gift['maximum_amount'], 2).
'|'.(int)$gift['id_manufacturer'];
if (isset($ranges[$range]['gifts']))
$ranges[$range]['gifts'][] = $gift;
else
$ranges[$range] = array(
'gifts' => array($gift),
'minimum_amount' => Tools::ps_round((float)$gift['minimum_amount'], 2),
'maximum_amount' => Tools::ps_round((float)$gift['maximum_amount'], 2),
'id_manufacturer' => (int)$gift['id_manufacturer'],
'manufacturer_name' => $gift['manufacturer_name']
);
}
ksort($ranges, SORT_NATURAL);
return $ranges;
}
/**
* Ticket 12890
* Get a list of all the gifts filtered by given categories, customer and configured groups.
* Result grouped by price ranges
*
* @access public
* @return array
*/
public function getRangesFilteredBy(array $category_ids, $customer, $full_informations = false, $active = false, array& $cart_products)
{
// checked if gifts are allowed to be displayed for this customer
$keys_config_group_ids = array_flip($this->getConfigCustomerGroups());
$is_allowed = false;
foreach ($customer->getGroups() as $id_group) {
if (isset($keys_config_group_ids[$id_group])) {
$is_allowed = true;
}
}
if (!$is_allowed) {
return array();
}
// get all gifts for the given categories
$ranges = array();
$gifts = $this->getAllGifts($full_informations, $active);
// exclude "PLV"
$is_plv_in_cart = false;
foreach ($cart_products as $p) {
if (preg_match('/plv/i', $p['name']) === 1) {
$is_plv_in_cart = true;
}
}
foreach ($gifts as $gift)
{
$product = new Product($gift['gift_product']);
// product must be in the given categories and the group categories
if (!in_array($product->id_category_default, $category_ids)) {
continue;
}
if ($is_plv_in_cart && preg_match('/plv/i', $product->name[1]) === 1) {
continue;
}
$range = Tools::ps_round((float)$gift['minimum_amount'], 2).
'|'.Tools::ps_round((float)$gift['maximum_amount'], 2).
'|'.(int)$gift['id_manufacturer'];
if (isset($ranges[$range]['gifts']))
$ranges[$range]['gifts'][] = $gift;
else
$ranges[$range] = array(
'gifts' => array($gift),
'minimum_amount' => Tools::ps_round((float)$gift['minimum_amount'], 2),
'maximum_amount' => Tools::ps_round((float)$gift['maximum_amount'], 2),
'id_manufacturer' => (int)$gift['id_manufacturer'],
'manufacturer_name' => $gift['manufacturer_name']
);
}
ksort($ranges, SORT_NATURAL);
return $ranges;
}
/**
* Checks if a gift can be added to cart.
*
* @access public
* @param mixed $minimum_amount
* @param mixed $maximum_amount
* @param mixed $id_manufacturer
* @param mixed $use_tax
* @param mixed $gift_currency
* @return boolean
*/
public function giftIsAvailable($minimum_amount, $maximum_amount, $date_from, $date_to, $id_manufacturer, $use_tax, $gift_currency)
{
$available = false;
if (!empty($id_manufacturer))
{
$total_m = 0;
foreach ($this->context->cart->getProducts() as $p)
if ((int)$p['id_manufacturer'] === (int)$id_manufacturer)
$total_m += $use_tax ? (float)$p['total_wt'] : (float)$p['total'];
$total_m = Tools::ps_round(Tools::convertPriceFull($total_m, $this->context->currency, $gift_currency), 2);
$available = $total_m && $total_m >= $minimum_amount &&
($total_m < $maximum_amount || $maximum_amount <= 0) &&
$date_from <= date('Y-m-d H:i:s') && $date_to >= date('Y-m-d H:i:s');
}
else
{
$total_order = Tools::ps_round(
Tools::convertPriceFull(
$this->context->cart->getOrderTotal($use_tax, Cart::BOTH_WITHOUT_SHIPPING),
$this->context->currency,
$gift_currency
), 2
);
$available = $total_order < $maximum_amount || $maximum_amount <= 0 && $total_order >= $minimum_amount &&
$date_from <= date('Y-m-d H:i:s') && $date_to >= date('Y-m-d H:i:s');
}
return $available;
}
/**
* Checks if this product is already in the list of gifts.
*
* @access public
* @param mixed $id_product
* @param int $id_product_attribute (default: 0)
* @return void
*/
public function giftExists($id_product, $id_product_attribute, $minimum_amount, $maximum_amount, $date_from, $date_to)
{
return (int)Db::getInstance()->getValue(
'SELECT COUNT(g.`id_gift`)
FROM `'._DB_PREFIX_.'giveagift` g, `'._DB_PREFIX_.'cart_rule` cr
WHERE cr.`id_cart_rule` = g.`id_cart_rule`
AND cr.`gift_product` = '.(int)$id_product.'
AND cr.`gift_product_attribute` = '.(int)$id_product_attribute.'
AND ROUND(cr.`minimum_amount`, 2) = '.Tools::ps_round((float)$minimum_amount, 2).'
AND ROUND(g.`maximum_amount`, 2) = '.Tools::ps_round((float)$maximum_amount, 2).'
AND (
("'.pSQL($date_from).'" >= cr.`date_from` && "'.pSQL($date_from).'" <= cr.`date_to`) OR
("'.pSQL($date_to).'" >= cr.`date_from` && "'.pSQL($date_to).'" <= cr.`date_to`) OR
(cr.`date_from` >= "'.pSQL($date_from).'" && cr.`date_to` <= "'.pSQL($date_to).'") OR
("'.pSQL($date_from).'" >= cr.`date_from` && "'.pSQL($date_to).'" <= cr.`date_to`)
)'
) > 0;
}
/**
* Checks if the gift is already in the cart.
*
* @access public
* @static
* @param int $id_cart_rule
* @return bool
*/
public static function giftIsUsed($id_cart_rule)
{
static $cart_rules = null;
if ($cart_rules === null)
$cart_rules = Context::getContext()->cart->getCartRules();
if (!empty($cart_rules))
foreach ($cart_rules as $c)
if ((int)$c['id_cart_rule'] === (int)$id_cart_rule)
return true;
return false;
}
/**
* ANTADIS ADDITION 12411
* Check if a gift has been selected.
*
* @access public
* @static
* @return int The id_cart_rule of the gift selected in that range
*/
public static function getCurrentSelection()
{
return (int)Db::getInstance()->getValue(
'SELECT cr.`id_cart_rule`
FROM `'._DB_PREFIX_.'giveagift` g, `'._DB_PREFIX_.'cart_rule` cr, `'._DB_PREFIX_.'cart_cart_rule` ccr
WHERE g.`id_cart_rule` = cr.`id_cart_rule`
AND ccr.`id_cart_rule` = cr.`id_cart_rule`
AND ccr.`id_cart` = '.(int)Context::getContext()->cookie->id_cart
);
}
/**
* Check if a gift has been selected in the specified range.
*
* @access public
* @static
* @param float $minimum_amount
* @param float $maximum_amount
* @return int The id_cart_rule of the gift selected in that range
*/
public static function rangeIsUsed($minimum_amount, $maximum_amount)
{
return (int)Db::getInstance()->getValue(
'SELECT cr.`id_cart_rule`
FROM `'._DB_PREFIX_.'giveagift` g, `'._DB_PREFIX_.'cart_rule` cr, `'._DB_PREFIX_.'cart_cart_rule` ccr
WHERE g.`id_cart_rule` = cr.`id_cart_rule`
AND ccr.`id_cart_rule` = cr.`id_cart_rule`
AND ccr.`id_cart` = '.(int)Context::getContext()->cookie->id_cart.'
AND ROUND(cr.`minimum_amount`, 2) = '.Tools::ps_round((float)$minimum_amount, 2).'
AND ROUND(g.`maximum_amount`, 2) = '.Tools::ps_round((float)$maximum_amount, 2)
);
}
/**
* Check if the applied cart rules are still available.
*
* @access public
* @return boolean true if cart rules have been removed from cart
*/
public function checkCartRules()
{
$removed = false;
$gift_currency = new Currency((int)Configuration::get('GIFT_ID_CURRENCY'));
$use_tax = (int)Configuration::get('GIFT_TAX_DISPLAY') === 1;
$db = Db::getInstance();
if (!empty($this->context->customer->id) &&
Configuration::get('GIFT_ONLY_FIRST_ORDER') &&
count(Order::getCustomerOrders($this->context->customer->id)) > 0)
$remove_all = true;
else
$remove_all = false;
foreach ($this->context->cart->getCartRules() as $c)
{
if (empty($c['id_cart_rule']))
continue;
$gift = $db->getRow(
'SELECT g.`maximum_amount`, g.`id_manufacturer`
FROM `'._DB_PREFIX_.'giveagift` g, `'._DB_PREFIX_.'cart_rule` cr
WHERE cr.`id_cart_rule` = g.`id_cart_rule`
AND cr.`id_cart_rule` = '.(int)$c['id_cart_rule']
);
if (!empty($gift) && ($remove_all || !$this->giftIsAvailable(
$c['minimum_amount'],
$gift['maximum_amount'],
$c['date_from'],
$c['date_to'],
$gift['id_manufacturer'],
$use_tax,
$gift_currency)))
{
$this->context->cart->removeCartRule((int)$c['id_cart_rule']);
$removed = true;
}
}
return $removed;
}
/**
* PS 1.6 : Refresh the cart summary if the change of quantity removes a cart rule.
*
* @access public
* @param mixed $params
* @return void
*/
public function hookActionBeforeAjaxDieCartControllerDisplayAjax($params)
{
if (!empty($params['value']))
{
$json = Tools::jsonDecode($params['value'], true);
if ((!empty($json['refresh']) && count($json) > 1) || (empty($json['refresh']) && $this->checkCartRules()))
die(Tools::jsonEncode(array('refresh' => true)));
}
}
}