name = 'gm_omniprice';
$this->prefix = strtoupper($this->name);
$this->tab = 'front_office_features';
$this->version = '1.2.11';
$this->author = 'GreenMouseStudio.com';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('OmniPrice - Omnibus Directive price compliancy');
$this->description = $this->l('Displays lowest price before current promotion for discounted products');
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
$this->getConfiguration();
}
public function getConfiguration()
{
$this->ignoredGroups = explode(',', Configuration::get($this->prefix . '_GROUPS'));
$this->daysBack = Configuration::get($this->prefix . '_DAYS');
$this->batchSize = Configuration::get($this->prefix . '_BATCH');
$this->ignoreCountries = Configuration::get($this->prefix . '_IGNORE_COUNTRIES');
$this->ignoreNonEuCountries = Configuration::get($this->prefix . '_IGNORE_NON_EU');
$this->ignoreCombinations = Configuration::get($this->prefix . '_IGNORE_COMBINATIONS');
$this->reindexOnSave = Configuration::get($this->prefix . '_REINDEX');
$this->textColor = Configuration::get($this->prefix . '_TEXT_COLOR');
$this->priceColor = Configuration::get($this->prefix . '_PRICE_COLOR');
$this->backgroundColor = Configuration::get($this->prefix . '_BG_COLOR');
$this->showIfNotEnoughHistoricalData = Configuration::get($this->prefix . '_SHOW_IF_NO_HISTORY');
$this->showRealDiscount = Configuration::get($this->prefix . '_SHOW_REAL_DISCOUNT');
$this->indexInactive = Configuration::get($this->prefix . '_INDEX_INACTIVE');
$this->skipBelowCost = Configuration::get($this->prefix . '_SKIP_BELOW_COST');
$this->defaultShopId = (int) Configuration::get('PS_SHOP_DEFAULT');
$this->defaultCountryId = (int) Configuration::get('PS_COUNTRY_DEFAULT');
$this->defaultGroupId = (int) Configuration::get('PS_CUSTOMER_GROUP');
$this->defaultCurrencyId = (int) Configuration::get('PS_CURRENCY_DEFAULT');
$this->today = date('Y-m-d');
$this->yesterday = date('Y-m-d', strtotime("-1 days"));
}
public function install()
{
if (
parent::install() && $this->installDb() &&
$this->registerHook('displayProductPriceBlock') &&
$this->registerHook('displayAdminProductsExtra') &&
$this->registerHook('actionProductUpdate') &&
$this->registerHook('actionObjectSpecificPriceAddAfter') &&
$this->registerHook('actionObjectSpecificPriceUpdateAfter') &&
$this->registerHook('actionObjectSpecificPriceDeleteAfter')
)
{
Configuration::updateValue($this->prefix . '_DAYS', 30);
Configuration::updateValue($this->prefix . '_BATCH', 100);
Configuration::updateValue($this->prefix . '_IGNORE_COUNTRIES', true);
Configuration::updateValue($this->prefix . '_IGNORE_NON_EU', true);
Configuration::updateValue($this->prefix . '_REINDEX', true);
Configuration::updateValue($this->prefix . '_SHOW_IF_NO_HISTORY', false);
Configuration::updateValue($this->prefix . '_SHOW_REAL_DISCOUNT', false);
Configuration::updateValue($this->prefix . '_INDEX_INACTIVE', false);
Configuration::updateValue($this->prefix . '_SKIP_BELOW_COST', false);
Configuration::updateValue($this->prefix . '_TEXT_COLOR', '#666666');
Configuration::updateValue($this->prefix . '_PRICE_COLOR', '#666666');
Configuration::updateValue($this->prefix . '_BG_COLOR', '#FFFFFF');
if (Tools::version_compare(_PS_VERSION_, '1.7.0.0', '<'))
{
$this->registerHook('displayHeader');
}
else
{
$this->registerHook('actionFrontControllerSetMedia');
}
$this->autoConfig();
return true;
}
return false;
}
public function autoConfig()
{
$combinationsHaveDiscountsOrImpacts = $this->getCombinationsDiscountsInfo() || $this->getCombinationsPriceImpactsInfo();
Configuration::updateValue($this->prefix . '_IGNORE_COMBINATIONS', !$combinationsHaveDiscountsOrImpacts);
if (!defined('_TB_VERSION_'))
{ //TB has a nasty bug here
$groupsToSafelyIgnore = $this->findGroupsToSafelyIgnore();
Configuration::updateValue($this->prefix . '_GROUPS', implode(',', $groupsToSafelyIgnore));
}
}
public function installDb()
{
return Db::getInstance()->execute('
CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'gm_omniprice_history` (
`date` DATE NOT NULL,
`id_shop` INT(10) UNSIGNED NOT NULL,
`id_product` INT(10) UNSIGNED NOT NULL,
`id_product_attribute` INT(10) UNSIGNED NOT NULL,
`id_currency` INT(10) UNSIGNED NOT NULL,
`id_country` INT(10) UNSIGNED NOT NULL,
`id_group` INT(10) UNSIGNED NOT NULL,
`price_tex` DECIMAL(20,6),
`price_tin` DECIMAL(20,6),
`is_specific_price` TINYINT(1),
INDEX (`date`, `id_shop`, `id_product`),
INDEX (`date`, `id_product`)
) ENGINE = ' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8;') &&
Db::getInstance()->execute('
CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'gm_omniprice_cache` (
`id_shop` INT(10) UNSIGNED NOT NULL,
`id_product` INT(10) UNSIGNED NOT NULL,
`id_product_attribute` INT(10) UNSIGNED NOT NULL,
`id_currency` INT(10) UNSIGNED NOT NULL,
`id_country` INT(10) UNSIGNED NOT NULL,
`id_group` INT(10) UNSIGNED NOT NULL,
`price_tex` DECIMAL(20,6),
`price_tin` DECIMAL(20,6),
`date` DATE NOT NULL,
INDEX (`id_shop`, `id_product`, `id_product_attribute`, `id_currency`, `id_country`, `id_group`, `date`)
) ENGINE = ' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8;') &&
Db::getInstance()->execute('
CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'gm_omniprice_index` (
`date` DATE NOT NULL,
`id_shop` INT(10) UNSIGNED NOT NULL,
`id_product` INT(10) UNSIGNED NOT NULL,
INDEX (`date`, `id_shop`)
) ENGINE = ' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8;');
}
public function uninstall()
{
if (!parent::uninstall())
{
return false;
}
if (
!$this->uninstallDB() ||
!Configuration::deleteByName($this->prefix . '_GROUPS') ||
!Configuration::deleteByName($this->prefix . '_DAYS') ||
!Configuration::deleteByName($this->prefix . '_BATCH') ||
!Configuration::deleteByName($this->prefix . '_BG_COLOR') ||
!Configuration::deleteByName($this->prefix . '_TEXT_COLOR') ||
!Configuration::deleteByName($this->prefix . '_PRICE_COLOR') ||
!Configuration::deleteByName($this->prefix . '_IGNORE_COUNTRIES') ||
!Configuration::deleteByName($this->prefix . '_IGNORE_NON_EU') ||
!Configuration::deleteByName($this->prefix . '_IGNORE_COMBINATIONS') ||
!Configuration::deleteByName($this->prefix . '_TEXT_COLOR') ||
!Configuration::deleteByName($this->prefix . '_PRICE_COLOR') ||
!Configuration::deleteByName($this->prefix . '_BG_COLOR') ||
!Configuration::deleteByName($this->prefix . '_SHOW_IF_NO_HISTORY') ||
!Configuration::deleteByName($this->prefix . '_SHOW_REAL_DISCOUNT') ||
!Configuration::deleteByName($this->prefix . '_INDEX_INACTIVE') ||
!Configuration::deleteByName($this->prefix . '_REINDEX')
)
{
return false;
}
return true;
}
protected function uninstallDb()
{
$res = Db::getInstance()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'gm_omniprice_history`');
$res &= Db::getInstance()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'gm_omniprice_cache`');
$res &= Db::getInstance()->execute('DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'gm_omniprice_index`');
return $res;
}
public function getContent()
{
$content = '';
$content .= $this->postProcess();
$content .= $this->displayGreenMouseModulesPanel();
$content .= $this->displayForm();
$content .= $this->displayInfo();
$content .= $this->displayInformationPanel();
return $content;
}
protected function postProcess()
{
$output = '';
if (Tools::isSubmit('submit' . $this->name))
{
$this->ignoredGroups = Tools::getValue('groupBox');
if (!is_array($this->ignoredGroups))
{
$this->ignoredGroups = [];
}
$groupsString = implode(',', $this->ignoredGroups);
Configuration::updateValue($this->prefix . '_GROUPS', $groupsString);
$this->daysBack = Tools::getValue($this->prefix . '_DAYS');
Configuration::updateValue($this->prefix . '_DAYS', $this->daysBack);
$this->batchSize = Tools::getValue($this->prefix . '_BATCH');
Configuration::updateValue($this->prefix . '_BATCH', $this->batchSize);
$this->ignoreCountries = Tools::getValue($this->prefix . '_IGNORE_COUNTRIES');
Configuration::updateValue($this->prefix . '_IGNORE_COUNTRIES', $this->ignoreCountries);
$this->ignoreNonEuCountries = Tools::getValue($this->prefix . '_IGNORE_NON_EU');
Configuration::updateValue($this->prefix . '_IGNORE_NON_EU', $this->ignoreNonEuCountries);
$this->ignoreCombinations = Tools::getValue($this->prefix . '_IGNORE_COMBINATIONS');
Configuration::updateValue($this->prefix . '_IGNORE_COMBINATIONS', $this->ignoreCombinations);
$this->reindexOnSave = Tools::getValue($this->prefix . '_REINDEX');
Configuration::updateValue($this->prefix . '_REINDEX', $this->reindexOnSave);
$this->textColor = Tools::getValue($this->prefix . '_TEXT_COLOR');
Configuration::updateValue($this->prefix . '_TEXT_COLOR', $this->textColor);
$this->priceColor = Tools::getValue($this->prefix . '_PRICE_COLOR');
Configuration::updateValue($this->prefix . '_PRICE_COLOR', $this->priceColor);
$this->backgroundColor = Tools::getValue($this->prefix . '_BG_COLOR');
Configuration::updateValue($this->prefix . '_BG_COLOR', $this->backgroundColor);
$this->showIfNotEnoughHistoricalData = Tools::getValue($this->prefix . '_SHOW_IF_NO_HISTORY');
Configuration::updateValue($this->prefix . '_SHOW_IF_NO_HISTORY', $this->showIfNotEnoughHistoricalData);
$this->showRealDiscount = Tools::getValue($this->prefix . '_SHOW_REAL_DISCOUNT');
Configuration::updateValue($this->prefix . '_SHOW_REAL_DISCOUNT', $this->showRealDiscount);
$this->indexInactive = Tools::getValue($this->prefix . '_INDEX_INACTIVE');
Configuration::updateValue($this->prefix . '_INDEX_INACTIVE', $this->indexInactive);
$this->skipBelowCost = Tools::getValue($this->prefix . '_SKIP_BELOW_COST');
Configuration::updateValue($this->prefix . '_SKIP_BELOW_COST', $this->skipBelowCost);
$output .= $this->displayConfirmation($this->l('Settings updated'));
}
return $output;
}
public function displayForm()
{
$helper = new HelperForm();
$groups = Group::getGroups($this->context->language->id);
$inputs = array(
array(
'type' => 'text',
'label' => $this->l('Period'),
'desc' => $this->l('Number of days before promotion start to analyze'),
'name' => $this->prefix . '_DAYS',
'class' => 'fixed-width-md',
),
array(
'type' => 'switch',
'label' => $this->l('Ignore countries'),
'name' => $this->prefix . '_IGNORE_COUNTRIES',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
),
'hint' => $this->l('Analyze prices only for the default country, customers from other countries will see prices of the default country'),
'desc' => $this->l('Analyze prices only for the default country, customers from other countries will see prices of the default country')
),
array(
'type' => 'switch',
'label' => $this->l('Ignore non EU countries'),
'name' => $this->prefix . '_IGNORE_NON_EU',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
),
'hint' => $this->l('Skip non EU countries totally, customers from non EU countries will not see any message about previous price'),
'desc' => $this->l('Skip non EU countries totally, customers from non EU countries will not see any message about previous price')
),
array(
'type' => 'switch',
'label' => $this->l('Ignore combinations'),
'name' => $this->prefix . '_IGNORE_COMBINATIONS',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
),
'hint' => $this->l('Analyze prices only for the default combination, recommended if combinations don\'t have price impacts'),
'desc' => $this->l('Analyze prices only for the default combination, recommended if combinations don\'t have price impacts')
),
array(
'type' => 'group',
'label' => $this->l('Ignored groups'),
'name' => 'groupBox',
'values' => $groups,
'hint' => $this->l('Ignore selected groups, customers from ignored groups will see prices for the default group (Customer), recommended if no group discounts in use'),
'desc' => $this->l('Ignore selected groups, customers from ignored groups will see prices for the default group (Customer), recommended if no group discounts in use')
),
array(
'type' => 'text',
'label' => $this->l('Batch size'),
'desc' => $this->l('Number of products to process in a single CRON task run'),
'name' => $this->prefix . '_BATCH',
'class' => 'fixed-width-md',
),
array(
'type' => 'switch',
'label' => $this->l('Reindex on product save'),
'name' => $this->prefix . '_REINDEX',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
),
'hint' => $this->l('Reindex product on save'),
'desc' => $this->l('Reindex product on save')
),
array(
'type' => 'color',
'label' => $this->l('Background color'),
'name' => $this->prefix . '_BG_COLOR',
),
array(
'type' => 'color',
'label' => $this->l('Text color'),
'name' => $this->prefix . '_TEXT_COLOR',
),
array(
'type' => 'color',
'label' => $this->l('Price color'),
'name' => $this->prefix . '_PRICE_COLOR',
),
array(
'type' => 'switch',
'label' => $this->l('Show label even if not enough history'),
'name' => $this->prefix . '_SHOW_IF_NO_HISTORY',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
),
'hint' => $this->l('For discounted products, if previous price is unknown, shows the current discounted price as the lowest one'),
'desc' => $this->l('For discounted products, if previous price is unknown, shows the current discounted price as the lowest one')
),
array(
'type' => 'switch',
'label' => $this->l('Index inactive products'),
'name' => $this->prefix . '_INDEX_INACTIVE',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
),
'hint' => $this->l('Store price history even if the product is not active'),
'desc' => $this->l('Store price history even if the product is not active'),
),
);
if (Tools::version_compare(_PS_VERSION_, '1.7.0.0', '>='))
{
$inputs[] = array(
'type' => 'switch',
'label' => $this->l('Show real discount from the previous price'),
'name' => $this->prefix . '_SHOW_REAL_DISCOUNT',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
),
'hint' => $this->l('Display price change percentage after the lowest previous price'),
'desc' => $this->l('Display price change percentage after the lowest previous price')
);
}
$inputs[] = array(
'type' => 'switch',
'label' => $this->l('Skip products sold below cost price'),
'name' => $this->prefix . '_SKIP_BELOW_COST',
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Yes')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('No')
)
),
);
$fieldsForm = array(
'form' => array(
'legend' => array(
'title' => $this->l('Settings'),
'icon' => 'icon-cogs'
),
'input' => $inputs,
'submit' => array(
'title' => $this->l('Save')
)
),
);
$helper->show_toolbar = true;
$helper->toolbar_scroll = true;
$helper->table = $this->table;
$helper->default_form_language = (int) Configuration::get('PS_LANG_DEFAULT');
$helper->module = $this;
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
$helper->identifier = $this->identifier;
$helper->submit_action = 'submit' . $this->name;
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false) . '&configure=' . $this->name . '&tab_module=' . $this->tab . '&module_name=' . $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
foreach ($groups as $group)
{
$helper->fields_value['groupBox_' . $group['id_group']] = in_array($group['id_group'], $this->ignoredGroups);
}
$helper->fields_value[$this->prefix . '_DAYS'] = $this->daysBack;
$helper->fields_value[$this->prefix . '_BATCH'] = $this->batchSize;
$helper->fields_value[$this->prefix . '_IGNORE_COUNTRIES'] = $this->ignoreCountries;
$helper->fields_value[$this->prefix . '_IGNORE_NON_EU'] = $this->ignoreNonEuCountries;
$helper->fields_value[$this->prefix . '_IGNORE_COMBINATIONS'] = $this->ignoreCombinations;
$helper->fields_value[$this->prefix . '_REINDEX'] = $this->reindexOnSave;
$helper->fields_value[$this->prefix . '_TEXT_COLOR'] = $this->textColor;
$helper->fields_value[$this->prefix . '_PRICE_COLOR'] = $this->priceColor;
$helper->fields_value[$this->prefix . '_BG_COLOR'] = $this->backgroundColor;
$helper->fields_value[$this->prefix . '_SHOW_REAL_DISCOUNT'] = $this->showRealDiscount;
$helper->fields_value[$this->prefix . '_INDEX_INACTIVE'] = $this->indexInactive;
$helper->fields_value[$this->prefix . '_SKIP_BELOW_COST'] = $this->skipBelowCost;
$helper->fields_value[$this->prefix . '_SHOW_IF_NO_HISTORY'] = $this->showIfNotEnoughHistoricalData;
return $helper->generateForm(array($fieldsForm));
}
public function savePrices($verbose = false, $productId = null)
{
$this->clearIndex($this->yesterday);
$output = '';
$usetax = true;
if (Tax::excludeTaxeOption())
{
$usetax = false;
}
$basicPrices = [];
$stateId = 0;
$zipcode = '';
$output .= $this->today . '
';
$output .= $this->l('Batch size') . ': ' . $this->batchSize . '
';
$output .= $this->l('Default country ID:') . ' ' . $this->defaultCountryId . '
';
$output .= $this->l('Default group ID:') . ' ' . $this->defaultGroupId . '
';
$shopIds = $this->getShopsIds();
$useReduction = true;
if (Tools::isSubmit('init'))
{
$useReduction = false;
}
if ($this->skipBelowCost)
{
$rates = $this->getConversionRates();
$costPriceMap = $this->getCostPriceMap();
}
$specificPriceOutput = null;
foreach ($shopIds as $shopId)
{
$currencyIds = $this->getCurrencyIds($shopId);
$countryIds = $this->getCountryIds($shopId);
$groupIds = $this->getGroupIds($shopId);
$lastCurrencyId = end($currencyIds);
$lastCountryId = end($countryIds);
$lastGroupId = end($groupIds);
$attributesMap = $this->getProductAttributeMap($shopId);
if (!$productId)
{
$productIds = $this->getProductIds($shopId);
}
else
{
if (!$this->indexInactive && !$this->productIsActive($productId, $shopId))
{
continue;
}
$productIds = [$productId];
}
$output .= '
' . $this->l('All products indexed') . '
'; continue; } else { $output .= '' . $this->l('Not finished yet, please run me again') . '
'; } $output .= '| ' . ' | ' . $this->l('Product ID') . ' | ' . '' . $this->l('Attribute ID') . ' | ' . '' . $this->l('Country ID') . ' | ' . '' . $this->l('Currency ID') . ' | ' . '' . $this->l('Group ID') . ' | ' . '' . $this->l('Price') . ' | ' . '' . $this->l('Previous price') . ' | ' . '' . $this->l('Is discounted') . ' | ' . '' . $this->l('Action') . ' | ' . '' . $this->l('Lowest price') . ' | ' . '||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ' . ++$counter . ' | ' . '' . $productId . ' | ' . '' . $attributeId . ' | ' . '' . $countryId . ' | ' . '' . $currencyId . ' | ' . '' . $groupId . ' | ' . '' . $priceTin . ' (' . $priceTex . ') | ' . '' . $previousPrice . ' | ' . '' . $onDiscountText . ' | '; $priceIsCorrect = ($priceTin > 0); $priceChanged = (abs($previousPrice - $priceTin) > 0.01); $discountChanged = ($previousDiscount != $onDiscount); if (Tools::isSubmit('cache')) { $discountChanged = true; } if ($priceIsCorrect && ($priceChanged || $discountChanged)) { $output .= '' . $this->l('Save') . ' | '; $this->savePrice( $this->today, $shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $priceTex, $priceTin, $onDiscount ); //calculate lowest price and add it to the cache if ($onDiscount) { $lowestPrices = $this->getLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); if ($lowestPrices) { $output .= '' . $lowestPrices['price_tin'] . ' (' . $lowestPrices['price_tex'] . ') | '; $this->saveLowestPrice( $shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $lowestPrices['price_tex'], $lowestPrices['price_tin'], $lowestPrices['date'] ); } else { $output .= '' . $this->l('Unknown') . ' | '; } } else { $output .= '' . $this->l('Not applicable') . ' | '; } } else { $output .= '' . $this->l('No change') . ' | '; $output .= '' . $this->l('No change') . ' | '; } if (!$onDiscount) { $this->deleteLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); } $output .= '
| ' . ++$counter . ' | ' . '' . $productId . ' | ' . '' . $attributeId . ' | ' . '' . $countryId . ' | ' . '' . $currencyId . ' | ' . '' . $groupId . ' | ' . '' . $priceTin . ' (' . $priceTex . ') | ' . '' . $previousPrice . ' | ' . '' . $onDiscountText . ' | '; $priceIsCorrect = ($priceTin > 0); $priceChanged = (abs($previousPrice - $priceTin) > 0.01); $discountChanged = ($previousDiscount != $onDiscount); if (Tools::isSubmit('cache')) { $discountChanged = true; } if ($priceIsCorrect && ($priceChanged || $discountChanged)) { $output .= '' . $this->l('Save') . ' | '; $this->savePrice( $this->today, $shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $priceTex, $priceTin, $onDiscount ); if ($onDiscount) { $lowestPrices = $this->getLowestPrice( $shopId, $productId, $currencyId, $countryId, $groupId, $attributeId ); if ($lowestPrices) { $output .= '' . $lowestPrices['price_tin'] . ' (' . $lowestPrices['price_tex'] . ') | '; $this->saveLowestPrice( $shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $lowestPrices['price_tex'], $lowestPrices['price_tin'], $lowestPrices['date'] ); } else { $output .= '' . $this->l('Unknown') . ' | '; } } else { $output .= '' . $this->l('Not applicable') . ' | '; } } else { $output .= '' . $this->l('No change') . ' | '; $output .= '' . $this->l('No change') . ' | '; } if (!$onDiscount) { $this->deleteLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); } } else { //skip analyzing attribute if price is the same as basic //delete if the attribute is not on discount $onDiscount = $this->checkIfProductIsDiscounted($discountedIds, $productId, $attributeId); if (!$onDiscount) { $this->deleteLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); } } } } if ($currencyId == $lastCurrencyId && $groupId == $lastGroupId && $countryId == $lastCountryId) { $this->addProductToIndex($shopId, $productId, $this->today); } } } } } $output .= '
'; print_r($prices); echo ''; if ((count($prices) == 1) && ($prices[0]['is_specific_price'])) { return [ 'formatted' => $this->getFormattedPrice(round($prices[0][$arrayField])), 'raw' => $prices[0][$arrayField] ]; } // else if ($params['id_product_attribute'] != 0) // { // $prices = Db::getInstance()->executeS( // 'SELECT ' . $field . ', `is_specific_price`' // . ' FROM `' . _DB_PREFIX_ . 'gm_omniprice_history`' // . ' WHERE `id_shop` = ' . $params['id_shop'] // . ' AND `id_product` = ' . $params['id_product'] // . ' AND `id_currency` = ' . $params['id_currency'] // . ' AND `id_country` = ' . $params['id_country'] // . ' AND `id_group` = ' . $params['id_group'] // . ' AND `id_product_attribute` = 0' // . ' AND date >= \'' . $date_history . '\'' // ); // if ((count($prices) == 1) && ($prices[0]['is_specific_price'])) // { // return // [ // 'formatted' => $this->getFormattedPrice(round($prices[0][$arrayField])), // 'raw' => $prices[0][$arrayField] // ]; // } // } $price_1 = Product::getPriceStatic( $params['id_product'], true, $params['id_product_attribute'], 2, null, false, false ); $price_2 = Product::getPriceStatic( $params['id_product'], true, $params['id_product_attribute'], 2, null, false, true ); if ( $price_1 != $price_2 ) return [ 'formatted' => $this->getFormattedPrice( round( $price_1 ) ) ]; return false; } public function getLowestCachedPricesForCombinations($params) { $prices = []; $displayMethod = Group::getPriceDisplayMethod($params['id_group']); if ($displayMethod) { $field = '`price_tex`'; } else { $field = '`price_tin`'; } $result = Db::getInstance()->executeS( 'SELECT ' . $field . ' AS `price`, `id_product_attribute` ' . ' FROM `' . _DB_PREFIX_ . 'gm_omniprice_cache`' . ' WHERE `id_shop` = ' . $params['id_shop'] . ' AND `id_product` = ' . $params['id_product'] . ' AND `id_currency` = ' . $params['id_currency'] . ' AND `id_country` = ' . $params['id_country'] . ' AND `id_group` = ' . $params['id_group'] ); if ($result) { foreach ($result as $row) { $prices[$row['id_product_attribute']] = $this->getFormattedPrice(round($row['price'])); } } else { if ($this->showIfNotEnoughHistoricalData) { $result = Db::getInstance()->executeS( 'SELECT ' . $field . ' AS `price`, `id_product_attribute` ' . ' FROM `' . _DB_PREFIX_ . 'gm_omniprice_history`' . ' WHERE `id_shop` = ' . $params['id_shop'] . ' AND `id_product` = ' . $params['id_product'] . ' AND `id_currency` = ' . $params['id_currency'] . ' AND `id_country` = ' . $params['id_country'] . ' AND `id_group` = ' . $params['id_group'] . ' AND `is_specific_price` = 1 ' ); if ($result) { foreach ($result as $row) { $prices[$row['id_product_attribute']] = $this->getFormattedPrice(round($row['price'])); } } } } return $prices; } public function getFormattedPrice($price) { $context = Context::getContext(); if (isset($context->currentLocale)) { return $context->currentLocale->formatPrice($price, $context->currency->iso_code); } else { return Tools::displayPrice($price); } } public function hasAttributePrices($productId) { $res = Db::getInstance()->getValue('SELECT `id_product` FROM `' . _DB_PREFIX_ . 'gm_omniprice_cache` ' . ' WHERE `id_product` = ' . $productId . ' AND `id_product_attribute` > 0'); if ($res == $productId) { return true; } if ($this->showIfNotEnoughHistoricalData) { $res = Db::getInstance()->getValue('SELECT `id_product` FROM `' . _DB_PREFIX_ . 'gm_omniprice_history` ' . ' WHERE `id_product` = ' . $productId . ' AND `id_product_attribute` > 0 AND `is_specific_price` = 1'); if ($res == $productId) { return true; } } return false; } public function getCurrentParams($productId) { $params = []; $params['id_shop'] = (int) $this->context->shop->id; $params['id_currency'] = (int) $this->context->currency->id; $params['id_product'] = (int) $productId; if ($this->ignoreCombinations) { $params['id_product_attribute'] = 0; } else { $params['id_product_attribute'] = $this->getIdProductAttribute($params['id_product']); } if ($this->ignoreCountries) { $params['id_country'] = $this->defaultCountryId; if (Shop::isFeatureActive()) { $params['id_country'] = Configuration::get('PS_COUNTRY_DEFAULT', null, null, $params['id_shop']); } } else { $params['id_country'] = $this->context->country->id; } $currentGroup = $this->context->customer->id_default_group; if (in_array($currentGroup, $this->ignoredGroups)) { $params['id_group'] = $this->defaultGroupId; } else { $params['id_group'] = $currentGroup; } return $params; } public function getDiscountedProductIds($shopId, $currencyId, $countryId, $groupId) { if ($this->globalRuleExists($shopId, $currencyId, $countryId, $groupId)) { return $this->getAllProductIdsFromShop($shopId); } $beginning = null; $ending = null; if (Tools::version_compare(_PS_VERSION_, '1.6.1.10', '<=')) { $now = date('Y-m-d H:i:00'); $beginning = $now; $ending = $now; } $ids = SpecificPrice::getProductIdByDate($shopId, $currencyId, $countryId, $groupId, $beginning, $ending, 0, true); return $ids; } protected function getAllProductIdsFromShop($shopId) { $ids = []; $query = 'SELECT `id_product` FROM `' . _DB_PREFIX_ . 'product_shop` WHERE `id_shop` = ' . $shopId; $res = Db::getInstance()->executeS($query); if ($res) { foreach ($res as $row) { $ids[] = [ 'id_product' => (int) $row['id_product'], 'id_product_attribute' => 0 ]; } } return $ids; } public function globalRuleExists($shopId, $currencyId, $countryId, $groupId) { $query = 'SELECT `id_specific_price` FROM `' . _DB_PREFIX_ . 'specific_price` ' . ' WHERE (`id_shop` = 0 OR `id_shop` = ' . $shopId . ') ' . ' AND (`id_currency` = 0 OR `id_currency` = ' . $currencyId . ') ' . ' AND (`id_country` = 0 OR `id_country` = ' . $countryId . ') ' . ' AND (`id_group` = 0 OR `id_group` = ' . $groupId . ') ' . ' AND (`from` <= NOW() OR `from` = \'0000-00-00 00:00:00\') ' . ' AND (`to` >= NOW() OR `to` = \'0000-00-00 00:00:00\' ) ' . ' AND `id_product` = 0 ' . ' AND `id_product_attribute` = 0 ' . ' AND `from_quantity` > 0 '; $result = (int) Db::getInstance()->getValue($query); return ($result > 0); } public function getIdProductAttribute($productId) { $idProductAttribute = $this->getIdProductAttributeByGroup($productId); if (null === $idProductAttribute) { $idProductAttribute = (int) Tools::getValue('id_product_attribute'); } if (!$idProductAttribute) { $idProductAttribute = $this->getDefaultAttributeIdForProduct($productId); } return $idProductAttribute; } protected function getDefaultAttributeIdForProduct($productId) { $shopId = $this->context->shop->id; return (int) Db::getInstance()->getValue('SELECT `id_product_attribute` FROM `' . _DB_PREFIX_ . 'product_attribute_shop` ' . ' WHERE `default_on` = 1 AND `id_shop` = ' . $shopId . ' AND `id_product` = ' . $productId); } protected function getIdProductAttributeByGroup($productId) { $groups = Tools::getValue('group'); if (empty($groups)) { return null; } return (int) Product::getIdProductAttributeByIdAttributes( $productId, $groups, true ); } public function hookActionFrontControllerSetMedia($params) { $this->context->controller->registerStylesheet( 'module-gm_omniprice-style', 'modules/' . $this->name . '/views/css/gm_omniprice.css', [ 'media' => 'all', 'priority' => 200, ] ); } protected function displayInfo() { $token = Tools::getAdminToken($this->name); $output = '
' . $this->l('Groups with no customers:') . ' ' . implode(', ', $this->findEmptyGroups()) . '
'; } $output .= '' . $this->l('Groups with group reductions:') . ' ' . implode(', ', $this->findGroupsWithGroupReduction()) . '
'; $output .= '' . $this->l('Groups with specific prices:') . ' ' . implode(', ', $this->findGroupsWithSpecificPrices()) . '
'; $output .= '' . $this->l('Groups with specific price rules:') . ' ' . implode(', ', $this->findGroupsWithSpecifiPriceRules()) . '
'; $output .= '' . $this->l('Products have combinations with price impacts:') . ' ' . ($this->getCombinationsPriceImpactsInfo() ? $this->l('Yes') : $this->l('No')) . '
'; $output .= '' . $this->l('Individual combinations have discounts:') . ' ' . ($this->getCombinationsDiscountsInfo() ? $this->l('Yes') : $this->l('No')) . '
'; $output .= '' . $this->l('Number of active countries:') . ' ' . $this->countActiveCountries() . '
'; $output .= '' . $this->l('Number of active currencies:') . ' ' . $this->countActiveCurrencies() . '
'; $output .= '' . $this->l('Number of prices stored in history:') . ' ' . $this->countStoredPrices() . '
'; $output .= '';
echo $output;
}
}
protected function getProductIdsInHistory($shopId)
{
$ids = [];
$query = 'SELECT DISTINCT `id_product` FROM `' . _DB_PREFIX_ . 'gm_omniprice_history` '
. ' WHERE `id_shop` = ' . $shopId;
$res = Db::getInstance()->executeS($query);
if ($res)
{
foreach ($res as $row)
{
$ids[] = (int) $row['id_product'];
}
}
return $ids;
}
public function hookDisplayAdminProductsExtra(array $params)
{
$data = [];
if (isset($params['id_product']))
{
$productId = (int) $params['id_product'];
}
else
{
$productId = (int) Tools::getValue('id_product');
}
$shopId = (int) $this->context->shop->id;
$currencyId = (int) $this->defaultCurrencyId;
if (Shop::isFeatureActive())
{
$currencyId = Configuration::get('PS_CURRENCY_DEFAULT', null, null, $shopId);
}
$countryId = (int) $this->defaultCountryId;
if (Shop::isFeatureActive())
{
$countryId = Configuration::get('PS_COUNTRY_DEFAULT', null, null, $shopId);
}
$groupId = (int) $this->defaultGroupId;
$attributeId = 0;
$query = 'SELECT `date`, `price_tin`, `is_specific_price` '
. ' FROM `' . _DB_PREFIX_ . 'gm_omniprice_history`'
. ' WHERE `id_shop` = ' . $shopId
. ' AND `id_product` = ' . $productId
. ' AND `id_product_attribute` = ' . $attributeId
. ' AND `id_currency` = ' . $currencyId
. ' AND `id_country` = ' . $countryId
. ' AND `id_group` = ' . $groupId
. ' ORDER BY `date` DESC';
$res = Db::getInstance()->executeS($query);
if ($res)
{
foreach ($res as $row)
{
$data[$row['date']] = [
'date' => $row['date'],
'price_tin' => $row['price_tin'],
'is_specific_price' => $row['is_specific_price'],
'type' => ($row['is_specific_price'] ? $this->l('Reduced price') : $this->l('Regular price'))
];
}
}
$query = 'SELECT `date`, `price_tin` '
. ' FROM `' . _DB_PREFIX_ . 'gm_omniprice_cache`'
. ' WHERE `id_shop` = ' . $shopId
. ' AND `id_product` = ' . $productId
. ' AND `id_product_attribute` = ' . $attributeId
. ' AND `id_currency` = ' . $currencyId
. ' AND `id_country` = ' . $countryId
. ' AND `id_group` = ' . $groupId
. ' ORDER BY `date` DESC';
$res = Db::getInstance()->executeS($query);
if ($res)
{
foreach ($res as $row)
{
if (!array_key_exists($row['date'], $data))
{
$data[$row['date']] = [
'date' => $row['date'],
'price_tin' => $row['price_tin'],
'is_specific_price' => '',
'type' => $this->l('Lowest previous price')
];
}
}
}
krsort($data);
$indexed = (int) Db::getInstance()->getValue('SELECT `id_product` FROM `' . _DB_PREFIX_ . 'gm_omniprice_index` WHERE `id_product` = ' . $productId .
' AND `date` = \'' . $this->today . '\'');
$this->context->smarty->assign(array(
'historyData' => $data,
'indexedToday' => $indexed
));
$debug = '';
if (Tools::isSubmit('omnidebug'))
{
$res = Db::getInstance()->executeS('SELECT * FROM `' . _DB_PREFIX_ . 'gm_omniprice_history` WHERE `id_product` = ' . $productId . ' ORDER BY `date` DESC');
if ($res)
{
$debug = $this->displayTable($res, array_keys($res[0]));
}
}
return $this->display(__FILE__, 'tab.tpl') . $debug;
}
public function displayTable($data, $columns)
{
$output = '| ' . $columnHeader . ' | '; } $output .= '
|---|
| ' . $row[$key] . ' | '; } $output .= '
' . $message . '
'; return $content; } }