update
This commit is contained in:
@@ -109,7 +109,7 @@ class OmnibusEuFree extends Module
|
||||
return $tab->delete();
|
||||
}
|
||||
|
||||
protected function getLastMinimalPrice($id_product = null, $id_product_attribute = 0, $currency = null)
|
||||
protected function getLastMinimalPrice($id_product = null, $id_product_attribute = 0, $currency = null, $hasDiscountNow = null)
|
||||
{
|
||||
if (!isset($id_product)) {
|
||||
throw new Exception('Missing parameter: $id_product');
|
||||
@@ -117,39 +117,149 @@ class OmnibusEuFree extends Module
|
||||
|
||||
if (!isset($currency)) {
|
||||
$defaultCurrency = Currency::getDefaultCurrency();
|
||||
$currency = $defaultCurrency->id;
|
||||
$currency = (int)$defaultCurrency->id;
|
||||
}
|
||||
|
||||
$info_version = Configuration::get('OMNIBUSEUFREE_INFORMATION_VERSION', null, null, null, 2);
|
||||
$info_version = (int) Configuration::get('OMNIBUSEUFREE_INFORMATION_VERSION', null, null, null, 2);
|
||||
$NumberOfDays = (int) Configuration::get('OMNIBUSEUFREE_DAYS', null, null, null, 30);
|
||||
|
||||
// Jeżeli v2 ma sens tylko przy rabacie - jeśli nie ma rabatu, nie pokazuj
|
||||
if ($info_version === 2) {
|
||||
if ($hasDiscountNow === null) {
|
||||
// pewne sprawdzenie: porównaj regular vs sale w tej walucie
|
||||
$snap = $this->getPricesSnapshot((int)$id_product, (int)$id_product_attribute, (int)$currency);
|
||||
$hasDiscountNow = (bool)$snap['has_discount'];
|
||||
}
|
||||
|
||||
if (!$hasDiscountNow) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 1) data ostatniego wpisu (bieżący stan)
|
||||
$sqlLast = new DbQuery();
|
||||
$sqlLast->select('date_add');
|
||||
$sqlLast->from('omnibus_eu_free');
|
||||
$sqlLast->where('id_product = ' . (int)$id_product);
|
||||
$sqlLast->where('id_product_attribute = ' . (int)$id_product_attribute);
|
||||
$sqlLast->where('id_currency = ' . (int)$currency);
|
||||
$sqlLast->where('is_default_currency = 1');
|
||||
$sqlLast->where('is_last = 1');
|
||||
$lastRow = Db::getInstance()->getRow($sqlLast);
|
||||
|
||||
if (empty($lastRow['date_add'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$lastDate = $lastRow['date_add'];
|
||||
|
||||
// 2) znajdź ostatni moment przed lastDate, kiedy rabatu NIE było (has_discount=0)
|
||||
$sqlPrevNoDisc = new DbQuery();
|
||||
$sqlPrevNoDisc->select('MAX(date_add) AS prev_no_disc');
|
||||
$sqlPrevNoDisc->from('omnibus_eu_free');
|
||||
$sqlPrevNoDisc->where('id_product = ' . (int)$id_product);
|
||||
$sqlPrevNoDisc->where('id_product_attribute = ' . (int)$id_product_attribute);
|
||||
$sqlPrevNoDisc->where('id_currency = ' . (int)$currency);
|
||||
$sqlPrevNoDisc->where('is_default_currency = 1');
|
||||
$sqlPrevNoDisc->where('date_add < "' . pSQL($lastDate) . '"');
|
||||
$sqlPrevNoDisc->where('has_discount = 0');
|
||||
$rowPrev = Db::getInstance()->getRow($sqlPrevNoDisc);
|
||||
|
||||
// 3) start rabatu = pierwszy rekord z has_discount=1 po prev_no_disc
|
||||
// jeśli nigdy nie było has_discount=0, start = pierwszy rekord w historii z has_discount=1
|
||||
if (!empty($rowPrev['prev_no_disc'])) {
|
||||
$sqlStart = new DbQuery();
|
||||
$sqlStart->select('MIN(date_add) AS disc_start');
|
||||
$sqlStart->from('omnibus_eu_free');
|
||||
$sqlStart->where('id_product = ' . (int)$id_product);
|
||||
$sqlStart->where('id_product_attribute = ' . (int)$id_product_attribute);
|
||||
$sqlStart->where('id_currency = ' . (int)$currency);
|
||||
$sqlStart->where('is_default_currency = 1');
|
||||
$sqlStart->where('has_discount = 1');
|
||||
$sqlStart->where('date_add > "' . pSQL($rowPrev['prev_no_disc']) . '"');
|
||||
$rowStart = Db::getInstance()->getRow($sqlStart);
|
||||
} else {
|
||||
$sqlStart = new DbQuery();
|
||||
$sqlStart->select('MIN(date_add) AS disc_start');
|
||||
$sqlStart->from('omnibus_eu_free');
|
||||
$sqlStart->where('id_product = ' . (int)$id_product);
|
||||
$sqlStart->where('id_product_attribute = ' . (int)$id_product_attribute);
|
||||
$sqlStart->where('id_currency = ' . (int)$currency);
|
||||
$sqlStart->where('is_default_currency = 1');
|
||||
$sqlStart->where('has_discount = 1');
|
||||
$rowStart = Db::getInstance()->getRow($sqlStart);
|
||||
}
|
||||
|
||||
if (empty($rowStart['disc_start'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$discStart = $rowStart['disc_start'];
|
||||
|
||||
// okno 30 dni przed startem rabatu
|
||||
$startDateTime = (new DateTime($discStart))->modify('-' . $NumberOfDays . ' days')->format('Y-m-d H:i:s');
|
||||
|
||||
// minimalna cena REGULARNA w oknie przed rabatem
|
||||
$sqlMin = new DbQuery();
|
||||
$sqlMin->select('MIN(price_regular) AS price');
|
||||
$sqlMin->from('omnibus_eu_free');
|
||||
$sqlMin->where('id_product = ' . (int)$id_product);
|
||||
$sqlMin->where('id_product_attribute = ' . (int)$id_product_attribute);
|
||||
$sqlMin->where('id_currency = ' . (int)$currency);
|
||||
$sqlMin->where('is_default_currency = 1');
|
||||
$sqlMin->where('date_add >= "' . pSQL($startDateTime) . '"');
|
||||
$sqlMin->where('date_add < "' . pSQL($discStart) . '"');
|
||||
|
||||
$minRow = Db::getInstance()->getRow($sqlMin);
|
||||
|
||||
if (empty($minRow) || !isset($minRow['price']) || $minRow['price'] === null) {
|
||||
|
||||
$sqlStartPrice = new DbQuery();
|
||||
$sqlStartPrice->select('price_regular AS price');
|
||||
$sqlStartPrice->from('omnibus_eu_free');
|
||||
$sqlStartPrice->where('id_product = ' . (int)$id_product);
|
||||
$sqlStartPrice->where('id_product_attribute = ' . (int)$id_product_attribute);
|
||||
$sqlStartPrice->where('id_currency = ' . (int)$currency);
|
||||
$sqlStartPrice->where('is_default_currency = 1');
|
||||
$sqlStartPrice->where('has_discount = 1');
|
||||
$sqlStartPrice->orderBy('date_add ASC, id_omnibuseufree ASC');
|
||||
|
||||
$startPriceRow = Db::getInstance()->getRow($sqlStartPrice, false);
|
||||
|
||||
return (!empty($startPriceRow) && isset($startPriceRow['price'])) ? $startPriceRow : [];
|
||||
}
|
||||
|
||||
return (!empty($minRow) && isset($minRow['price'])) ? $minRow : [];
|
||||
}
|
||||
|
||||
// v1: najniższa z ostatnich X dni (tu możesz liczyć po regularnej albo po sale – zależnie od interpretacji)
|
||||
$date = new DateTime();
|
||||
$date->modify('-' . $NumberOfDays . ' days');
|
||||
$CutOffDate = $date->format('Y-m-d');
|
||||
|
||||
$sql = new DbQuery();
|
||||
$sql->select('price');
|
||||
$sql->select('MIN(price_sale) AS price');
|
||||
$sql->from('omnibus_eu_free');
|
||||
$sql->where('id_product = ' . (int) $id_product);
|
||||
$sql->where('id_product_attribute = ' . (int) $id_product_attribute);
|
||||
$sql->where('id_currency = ' . (int) $currency);
|
||||
$sql->where('id_product = ' . (int)$id_product);
|
||||
$sql->where('id_product_attribute = ' . (int)$id_product_attribute);
|
||||
$sql->where('id_currency = ' . (int)$currency);
|
||||
$sql->where('is_default_currency = 1');
|
||||
$sql->where('date_add >= "'.$CutOffDate.' 00:00:00"');
|
||||
|
||||
if ($info_version == 2) {
|
||||
$sql->where('is_last = 0');
|
||||
}
|
||||
$row = Db::getInstance()->getRow($sql);
|
||||
|
||||
$sql->orderBy('price ASC');
|
||||
$sql->limit(1);
|
||||
$sqlResult = Db::getInstance()->executeS($sql);
|
||||
|
||||
return (!empty($sqlResult)) ? $sqlResult[0] : array();
|
||||
return (!empty($row) && isset($row['price'])) ? $row : [];
|
||||
}
|
||||
|
||||
|
||||
public function hookDisplayOmnibusEuFree($params)
|
||||
{
|
||||
$currency = $this->context->currency;
|
||||
$lastMinimalPrice = $this->getLastMinimalPrice($params['product']['id_product'], $params['product']['id_product_attribute'], $currency->id);
|
||||
$lastMinimalPrice = $this->getLastMinimalPrice(
|
||||
(int)$params['product']['id_product'],
|
||||
(int)$params['product']['id_product_attribute'],
|
||||
(int)$currency->id,
|
||||
(bool)$params['product']['has_discount']
|
||||
);
|
||||
|
||||
if (!empty($lastMinimalPrice)) {
|
||||
$minimalPrice = PrestashopCompatibility::formatPrice(_PS_VERSION_, $lastMinimalPrice['price'], $currency);
|
||||
@@ -506,91 +616,249 @@ class OmnibusEuFree extends Module
|
||||
return $ToChange == 0 ? false : true;
|
||||
}
|
||||
|
||||
protected function getLastSnapshot($id_product = 0, $id_product_attribute = 0, $id_currency = null)
|
||||
{
|
||||
$sql = new DbQuery();
|
||||
$sql->select('price_regular, price_sale, has_discount, currency_conversion_rate');
|
||||
$sql->from('omnibus_eu_free');
|
||||
$sql->where('id_product = ' . (int)$id_product);
|
||||
$sql->where('id_product_attribute = ' . (int)$id_product_attribute);
|
||||
$sql->where('is_last = 1');
|
||||
$sql->where('is_default_currency = 1');
|
||||
|
||||
if ($id_currency !== null) {
|
||||
$sql->where('id_currency = ' . (int)$id_currency);
|
||||
}
|
||||
|
||||
$sql->limit(1);
|
||||
return Db::getInstance()->getRow($sql);
|
||||
}
|
||||
|
||||
protected function getPricesSnapshot($id_product, $id_product_attribute, $id_currency)
|
||||
{
|
||||
$context = Context::getContext();
|
||||
|
||||
$oldCurrency = $context->currency;
|
||||
if ((int)$id_currency > 0) {
|
||||
$context->currency = new Currency((int)$id_currency);
|
||||
}
|
||||
|
||||
// regularna (bez redukcji)
|
||||
$regular = (float) Product::getPriceStatic(
|
||||
(int)$id_product,
|
||||
true,
|
||||
(int)$id_product_attribute,
|
||||
6,
|
||||
null,
|
||||
false,
|
||||
false // use_reduction = false
|
||||
);
|
||||
|
||||
// sprzedażowa (z redukcją)
|
||||
$sale = (float) Product::getPriceStatic(
|
||||
(int)$id_product,
|
||||
true,
|
||||
(int)$id_product_attribute,
|
||||
6,
|
||||
null,
|
||||
false,
|
||||
true // use_reduction = true
|
||||
);
|
||||
|
||||
// przywróć walutę
|
||||
$context->currency = $oldCurrency;
|
||||
|
||||
$hasDiscount = ($sale > 0 && $regular > 0 && ($sale + 0.0001) < $regular) ? 1 : 0;
|
||||
$diff = $hasDiscount ? ($regular - $sale) : 0.0;
|
||||
|
||||
return [
|
||||
'regular' => $regular,
|
||||
'sale' => $sale,
|
||||
'has_discount' => $hasDiscount,
|
||||
'diff' => $diff,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
protected function normalizeCurrency($currency)
|
||||
{
|
||||
if (is_array($currency)) {
|
||||
return [
|
||||
'id' => (int) ($currency['id_currency'] ?? $currency['id'] ?? 0),
|
||||
'rate' => (float) ($currency['conversion_rate'] ?? $currency['rate'] ?? 0),
|
||||
];
|
||||
}
|
||||
|
||||
// obiekt Currency
|
||||
return [
|
||||
'id' => (int) ($currency->id ?? 0),
|
||||
'rate' => (float) ($currency->conversion_rate ?? 0),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
protected function addProductPrice($id_product = null)
|
||||
{
|
||||
if (!isset($id_product)) {
|
||||
throw new Exception('Missing parameter: $id_product');
|
||||
}
|
||||
|
||||
$product = new Product($id_product);
|
||||
$product_price = $product->getPrice();
|
||||
$id_product = (int)$id_product;
|
||||
|
||||
if($product_price != 0){
|
||||
$omnibus_price = array();
|
||||
$omnibus_price = $this->getLastPrice($id_product, 0);
|
||||
$currencies = Currency::getCurrencies(true, true);
|
||||
$defaultCurrency = Currency::getDefaultCurrency();
|
||||
|
||||
// snapshot w default walucie do porównania (żeby nie dopisywać non stop)
|
||||
$snapDefault = $this->getPricesSnapshot($id_product, 0, (int)$defaultCurrency->id);
|
||||
|
||||
if ((float)$snapDefault['sale'] != 0.0) {
|
||||
$last = $this->getLastSnapshot($id_product, 0);
|
||||
|
||||
$check_currency = $this->checkCurrencyConversionRate($id_product, 0);
|
||||
|
||||
if (empty($omnibus_price) || $product_price != $omnibus_price[0]['price'] || (bool) $check_currency == true) {
|
||||
$this->clearLastPrice($id_product);
|
||||
$currencies = Currency::getCurrencies();
|
||||
$defaultCurrency = Currency::getDefaultCurrency();
|
||||
$changed =
|
||||
empty($last)
|
||||
|| abs((float)$last['price_regular'] - (float)$snapDefault['regular']) > 0.0001
|
||||
|| abs((float)$last['price_sale'] - (float)$snapDefault['sale']) > 0.0001
|
||||
|| (int)$last['has_discount'] !== (int)$snapDefault['has_discount']
|
||||
|| (bool)$check_currency === true;
|
||||
|
||||
if ($changed) {
|
||||
$this->clearLastPrice($id_product, 0);
|
||||
|
||||
foreach ($currencies as $currency) {
|
||||
if ($currency['id_currency'] == $defaultCurrency->id) {
|
||||
$isDefaultCurrency = 1;
|
||||
$product_price_currency = $product_price;
|
||||
}
|
||||
else {
|
||||
$isDefaultCurrency = 0;
|
||||
$product_price_currency = Tools::convertPrice($product_price, $currency);
|
||||
$c = $this->normalizeCurrency($currency);
|
||||
|
||||
$id_currency = (int)$c['id'];
|
||||
$conversion_rate = (float)$c['rate'];
|
||||
|
||||
if ($id_currency <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->insertToOmnibusTable($id_product, 0, $product_price_currency, $currency['id_currency'], $isDefaultCurrency, $currency['conversion_rate']);
|
||||
$isDefaultCurrency = ($id_currency === (int)$defaultCurrency->id) ? 1 : 0;
|
||||
|
||||
$snap = $this->getPricesSnapshot($id_product, 0, $id_currency);
|
||||
|
||||
if ((float)$snap['sale'] <= 0.0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->insertToOmnibusTable(
|
||||
$id_product,
|
||||
0,
|
||||
$snap,
|
||||
$id_currency,
|
||||
$isDefaultCurrency,
|
||||
$conversion_rate
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function addProductPriceWithCombinations($id_product = null)
|
||||
{
|
||||
if (!isset($id_product)) {
|
||||
throw new Exception('Missing parameter: $id_product');
|
||||
if (!isset($id_product))
|
||||
{
|
||||
throw new Exception('Missing parameter: $id_product');
|
||||
}
|
||||
|
||||
$id_product = (int)$id_product;
|
||||
|
||||
Product::flushPriceCache();
|
||||
|
||||
$defaultCurrency = Currency::getDefaultCurrency();
|
||||
$id_default_currency = (int)$defaultCurrency->id;
|
||||
|
||||
// Najstabilniejsza lista kombinacji (bez powtórek)
|
||||
$attributeRows = Product::getProductAttributesIds($id_product);
|
||||
if (empty($attributeRows))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Lista walut (aktywnych)
|
||||
$currencies = Currency::getCurrencies(true, true);
|
||||
|
||||
foreach ($attributeRows as $row)
|
||||
{
|
||||
$id_product_attribute = (int)$row['id_product_attribute'];
|
||||
|
||||
// Snapshot w default walucie do porównania zmian
|
||||
$snapDefault = $this->getPricesSnapshot($id_product, $id_product_attribute, $id_default_currency);
|
||||
|
||||
if ((float)$snapDefault['sale'] <= 0.0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$product = new Product($id_product);
|
||||
$product_combinations = $product->getAttributeCombinations();
|
||||
$last = $this->getLastSnapshot($id_product, $id_product_attribute);
|
||||
$check_currency = $this->checkCurrencyConversionRate($id_product, $id_product_attribute);
|
||||
|
||||
if (!empty($product_combinations)) {
|
||||
$currencies = Currency::getCurrencies(); unset( $currencies[0] ); unset( $currencies[2] );
|
||||
$defaultCurrency = Currency::getDefaultCurrency();
|
||||
$changed =
|
||||
empty($last)
|
||||
|| abs((float)$last['price_regular'] - (float)$snapDefault['regular']) > 0.0001
|
||||
|| abs((float)$last['price_sale'] - (float)$snapDefault['sale']) > 0.0001
|
||||
|| (int)$last['has_discount'] !== (int)$snapDefault['has_discount']
|
||||
|| (bool)$check_currency === true;
|
||||
|
||||
foreach ($product_combinations as $combination) {
|
||||
$product_price = $product->getPrice(true, $combination['id_product_attribute'] );
|
||||
|
||||
if($product_price != 0){
|
||||
$omnibus_price = array();
|
||||
$omnibus_price = $this->getLastPrice($id_product, $combination['id_product_attribute']);
|
||||
|
||||
$check_currency = $this->checkCurrencyConversionRate($id_product, $combination['id_product_attribute']);
|
||||
|
||||
if (empty($omnibus_price) || $product_price != $omnibus_price[0]['price'] || (bool) $check_currency == true) {
|
||||
$this->clearLastPrice($id_product, $combination['id_product_attribute']);
|
||||
|
||||
foreach ($currencies as $currency) {
|
||||
if ($currency['id_currency'] == $defaultCurrency->id) {
|
||||
$isDefaultCurrency = 1;
|
||||
$product_price_currency = $product_price;
|
||||
}
|
||||
else {
|
||||
$isDefaultCurrency = 0;
|
||||
$product_price_currency = Tools::convertPrice($product_price, $currency);
|
||||
}
|
||||
|
||||
$this->insertToOmnibusTable($id_product, $combination['id_product_attribute'], $product_price_currency, $currency['id_currency'], $isDefaultCurrency, $currency['conversion_rate']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$changed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Zerujemy is_last dla tej kombinacji (dla wszystkich walut)
|
||||
$this->clearLastPrice($id_product, $id_product_attribute);
|
||||
|
||||
// Wstawiamy nowe snapshoty dla wszystkich walut
|
||||
foreach ($currencies as $currency)
|
||||
{
|
||||
$c = $this->normalizeCurrency($currency);
|
||||
$id_currency = (int)$c['id'];
|
||||
$conversion_rate = (float)$c['rate'];
|
||||
|
||||
if ($id_currency <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$isDefaultCurrency = ($id_currency === $id_default_currency) ? 1 : 0;
|
||||
|
||||
$snap = $this->getPricesSnapshot($id_product, $id_product_attribute, $id_currency);
|
||||
|
||||
if ((float)$snap['sale'] <= 0.0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->insertToOmnibusTable(
|
||||
$id_product,
|
||||
$id_product_attribute,
|
||||
$snap,
|
||||
$id_currency,
|
||||
$isDefaultCurrency,
|
||||
$conversion_rate
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function insertToOmnibusTable($id_product = 0, $id_product_attribute = 0, $product_price = 0, $currency = 0, $isDefaultCurrency = 0, $CurrencyConversionRate = 0)
|
||||
protected function insertToOmnibusTable($id_product = 0, $id_product_attribute = 0, $snap = [], $currency = 0, $isDefaultCurrency = 0, $CurrencyConversionRate = 0)
|
||||
{
|
||||
$result = Db::getInstance()->insert('omnibus_eu_free', [
|
||||
return Db::getInstance()->insert('omnibus_eu_free', [
|
||||
'id_product' => (int) $id_product,
|
||||
'id_product_attribute' => (int) $id_product_attribute,
|
||||
'price' => pSQL($product_price),
|
||||
|
||||
// zostaw stare price jako "sale" dla kompatybilności szablonu / starego kodu
|
||||
'price' => pSQL($snap['sale']),
|
||||
|
||||
'price_regular' => pSQL($snap['regular']),
|
||||
'price_sale' => pSQL($snap['sale']),
|
||||
'has_discount' => (int) $snap['has_discount'],
|
||||
'discount_diff' => pSQL($snap['diff']),
|
||||
|
||||
'id_currency' => (int) $currency,
|
||||
'is_default_currency' => (int) $isDefaultCurrency,
|
||||
'is_last' => 1,
|
||||
@@ -656,6 +924,7 @@ class OmnibusEuFree extends Module
|
||||
public function removeOldDataFromOmnibusTable()
|
||||
{
|
||||
$NumberOfDays = (int) Configuration::get('OMNIBUSEUFREE_DAYS', null, null, null, 30);
|
||||
$NumberOfDays = 90;
|
||||
|
||||
$date = new DateTime();
|
||||
$date->modify('-' . $NumberOfDays . ' days');
|
||||
|
||||
Reference in New Issue
Block a user