From 5cefdc42d4e4c11a7eb4eb65860843c28dece986 Mon Sep 17 00:00:00 2001
From: Jacek Pyziak
Date: Mon, 16 Mar 2026 00:25:33 +0100
Subject: [PATCH] update
---
.vscode/ftp-kr.sync.cache.json | 190 +++++++++++++++++-
changelog/2026-03-16.md | 12 ++
modules/omnibuseufree/omnibuseufree.php | 105 +++++++++-
.../hook/presta_studio_omnibus_price.tpl | 21 +-
4 files changed, 316 insertions(+), 12 deletions(-)
create mode 100644 changelog/2026-03-16.md
diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json
index 25c6b7bf..e1d86a0b 100644
--- a/.vscode/ftp-kr.sync.cache.json
+++ b/.vscode/ftp-kr.sync.cache.json
@@ -43,7 +43,119 @@
"lmtime": 0,
"modified": false
},
- "app": {},
+ "app": {
+ "config": {
+ "addons": {},
+ "config_dev.yml": {
+ "type": "-",
+ "size": 1541,
+ "lmtime": 0,
+ "modified": false
+ },
+ "config_legacy_dev.yml": {
+ "type": "-",
+ "size": 47,
+ "lmtime": 0,
+ "modified": false
+ },
+ "config_legacy_prod.yml": {
+ "type": "-",
+ "size": 163,
+ "lmtime": 0,
+ "modified": false
+ },
+ "config_legacy_test.yml": {
+ "type": "-",
+ "size": 47,
+ "lmtime": 0,
+ "modified": false
+ },
+ "config_legacy.yml": {
+ "type": "-",
+ "size": 590,
+ "lmtime": 0,
+ "modified": false
+ },
+ "config.php": {
+ "type": "-",
+ "size": 4886,
+ "lmtime": 0,
+ "modified": false
+ },
+ "config_prod.yml": {
+ "type": "-",
+ "size": 715,
+ "lmtime": 0,
+ "modified": false
+ },
+ "config_test.yml": {
+ "type": "-",
+ "size": 1001,
+ "lmtime": 0,
+ "modified": false
+ },
+ "config.yml": {
+ "type": "-",
+ "size": 4094,
+ "lmtime": 0,
+ "modified": false
+ },
+ "doctrine.yml": {
+ "type": "-",
+ "size": 880,
+ "lmtime": 0,
+ "modified": false
+ },
+ "parameters.php": {
+ "type": "-",
+ "size": 1019,
+ "lmtime": 1773273531115,
+ "modified": false
+ },
+ "parameters.yml": {
+ "type": "-",
+ "size": 11,
+ "lmtime": 0,
+ "modified": false
+ },
+ "parameters.yml.dist": {
+ "type": "-",
+ "size": 983,
+ "lmtime": 0,
+ "modified": false
+ },
+ "routing_dev.yml": {
+ "type": "-",
+ "size": 1132,
+ "lmtime": 0,
+ "modified": false
+ },
+ "routing.yml": {
+ "type": "-",
+ "size": 315,
+ "lmtime": 0,
+ "modified": false
+ },
+ "security.yml": {
+ "type": "-",
+ "size": 631,
+ "lmtime": 0,
+ "modified": false
+ },
+ "services.yml": {
+ "type": "-",
+ "size": 258,
+ "lmtime": 0,
+ "modified": false
+ },
+ "set_parameters.php": {
+ "type": "-",
+ "size": 3096,
+ "lmtime": 0,
+ "modified": false
+ }
+ }
+ },
"autoload.php": {
"type": "-",
"size": 1316,
@@ -116,13 +228,13 @@
},
"google-merchant_id-1.xml": {
"type": "-",
- "size": 62638554,
+ "size": 63312722,
"lmtime": 0,
"modified": true
},
"google-merchant_id-2.xml": {
"type": "-",
- "size": 2733981,
+ "size": 2750870,
"lmtime": 0,
"modified": true
},
@@ -318,8 +430,8 @@
},
"omnibuseufree.php": {
"type": "-",
- "size": 29375,
- "lmtime": 1772663858543,
+ "size": 29553,
+ "lmtime": 1773275484740,
"modified": false
},
"Readme.md": {
@@ -597,8 +709,8 @@
},
"presta_studio_omnibus_price.tpl": {
"type": "-",
- "size": 1401,
- "lmtime": 1772663725687,
+ "size": 1444,
+ "lmtime": 1773275495347,
"modified": false
}
},
@@ -749,7 +861,63 @@
"lmtime": 0,
"modified": false
},
- "themes": {},
+ "themes": {
+ "leo_lulandia": {
+ "assets": {
+ "css": {
+ "components": {},
+ "dr_materac.css": {
+ "type": "-",
+ "size": 84199,
+ "lmtime": 1773276500555,
+ "modified": false
+ },
+ "dr_materac.css.map": {
+ "type": "-",
+ "size": 32543,
+ "lmtime": 1773276500556,
+ "modified": false
+ },
+ "dr_materac.scss": {
+ "type": "-",
+ "size": 101907,
+ "lmtime": 1773276500559,
+ "modified": false
+ },
+ "index.php": {
+ "type": "-",
+ "size": 1277,
+ "lmtime": 0,
+ "modified": false
+ },
+ "rtl.css": {
+ "type": "-",
+ "size": 61948,
+ "lmtime": 0,
+ "modified": false
+ },
+ "theme.css": {
+ "type": "-",
+ "size": 433723,
+ "lmtime": 0,
+ "modified": false
+ },
+ "theme.css.map": {
+ "type": "-",
+ "size": 1360187,
+ "lmtime": 0,
+ "modified": false
+ },
+ "theme.scss": {
+ "type": "-",
+ "size": 640895,
+ "lmtime": 0,
+ "modified": false
+ }
+ }
+ }
+ }
+ },
"tools": {},
"translations": {},
"upload": {},
@@ -761,6 +929,12 @@
"size": 448,
"lmtime": 0,
"modified": false
+ },
+ "AGENTS.md": {
+ "type": "-",
+ "size": 2807,
+ "lmtime": 1773273811171,
+ "modified": false
}
}
},
diff --git a/changelog/2026-03-16.md b/changelog/2026-03-16.md
new file mode 100644
index 00000000..1c629e8f
--- /dev/null
+++ b/changelog/2026-03-16.md
@@ -0,0 +1,12 @@
+# 2026-03-16
+
+## Co zrobiono
+- Naprawiono wyświetlanie ceny w fallbacku modułu `omnibuseufree` i dopasowano zaokrąglanie do sposobu prezentacji cen na froncie.
+- Dodano tryb debug uruchamiany parametrem `omnibuseufree_debug=1`, aby podejrzeć wartości wejściowe i wyliczone (`price`, `price_amount`, `regular_price`, fallback, minimalna).
+- Uporządkowano logikę braku historii: gdy brak historii do wyświetlenia, moduł pokazuje cenę regularną (bez promocji).
+- Dodano warunek dla promocji: jeśli w historii z okresu nie ma ceny różnej od bieżącej ceny promocyjnej, moduł traktuje to jako brak historii „sprzed obniżki” i wymusza fallback na cenę regularną.
+- Zweryfikowano na przypadkach testowych poprawne wyjście (w tym przypadki z wcześniejszym błędem 4 067,52 / 4 068,00 oraz z historią zawierającą tylko aktualną cenę promocyjną).
+
+## Zmienione pliki
+- `modules/omnibuseufree/omnibuseufree.php`
+- `modules/omnibuseufree/views/templates/hook/presta_studio_omnibus_price.tpl`
diff --git a/modules/omnibuseufree/omnibuseufree.php b/modules/omnibuseufree/omnibuseufree.php
index b6673096..b78db343 100644
--- a/modules/omnibuseufree/omnibuseufree.php
+++ b/modules/omnibuseufree/omnibuseufree.php
@@ -148,14 +148,95 @@ class OmnibusEuFree extends Module
return (!empty($sqlResult)) ? $sqlResult[0] : array();
}
+ protected function hasDifferentHistoricalPrice($id_product, $id_product_attribute, $currency, $currentPrice)
+ {
+ $info_version = Configuration::get('OMNIBUSEUFREE_INFORMATION_VERSION', null, null, null, 2);
+ $numberOfDays = (int) Configuration::get('OMNIBUSEUFREE_DAYS', null, null, null, 30);
+
+ $date = new DateTime();
+ $date->modify('-' . $numberOfDays . ' days');
+ $cutOffDate = $date->format('Y-m-d');
+
+ $sql = new DbQuery();
+ $sql->select('id_omnibuseufree');
+ $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('date_add >= "' . pSQL($cutOffDate . ' 00:00:00') . '"');
+ $sql->where('ABS(price - ' . (float) $currentPrice . ') > 0.000001');
+
+ if ($info_version == 2) {
+ $sql->where('is_last = 0');
+ }
+
+ $sql->limit(1);
+
+ return (bool) Db::getInstance()->getValue($sql);
+ }
+
+ protected function formatDisplayPrice($price, $currency, $precisionOverride = null)
+ {
+ if ($precisionOverride !== null) {
+ $priceDisplayPrecision = (int) $precisionOverride;
+ } else {
+ $priceDisplayPrecision = (int) Configuration::get('PS_PRICE_DISPLAY_PRECISION', null, null, null, _PS_PRICE_DISPLAY_PRECISION_);
+ }
+ $roundedPrice = Tools::ps_round((float) $price, $priceDisplayPrecision);
+
+ return PrestashopCompatibility::formatPrice(_PS_VERSION_, $roundedPrice, $currency);
+ }
+
public function hookDisplayOmnibusEuFree($params)
{
$currency = $this->context->currency;
- $lastMinimalPrice = $this->getLastMinimalPrice($params['product']['id_product'], $params['product']['id_product_attribute'], $currency->id);
+ $debugEnabled = (bool) Tools::getValue('omnibuseufree_debug');
+ $idProduct = isset($params['product']['id_product']) ? (int) $params['product']['id_product'] : 0;
+ $idProductAttribute = isset($params['product']['id_product_attribute']) ? (int) $params['product']['id_product_attribute'] : 0;
+ $lastMinimalPrice = $this->getLastMinimalPrice($idProduct, $idProductAttribute, $currency->id);
$regularPrice = isset($params['product']['regular_price']) ? $params['product']['regular_price'] : null;
+ $displayPrecisionOverride = null;
+ $forcedFallbackNoPreDiscountHistory = false;
+
+ if (isset($params['product']['price_amount']) && is_numeric($params['product']['price_amount'])) {
+ $priceAmount = (float) $params['product']['price_amount'];
+ if (abs($priceAmount - round($priceAmount)) < 0.000001) {
+ $displayPrecisionOverride = 0;
+ }
+ }
+
+ $fallbackPrice = null;
+ if (is_string($regularPrice) && $regularPrice !== '') {
+ // Prefer the already prepared regular (non-discounted) price from product presenter.
+ $fallbackPrice = $regularPrice;
+ } elseif ($idProduct > 0) {
+ // Compute regular (without reduction) price if presenter did not provide it.
+ $useTax = Product::getTaxCalculationMethod((int) $this->context->customer->id) != PS_TAX_EXC;
+ $regularRaw = Product::getPriceStatic($idProduct, $useTax, $idProductAttribute, 6, null, false, false);
+ $fallbackPrice = $this->formatDisplayPrice((float) $regularRaw, $currency, $displayPrecisionOverride);
+ } elseif (isset($params['product']['price_amount']) && is_numeric($params['product']['price_amount'])) {
+ // Last resort if product id is missing in hook params.
+ $fallbackPrice = $this->formatDisplayPrice((float) $params['product']['price_amount'], $currency, $displayPrecisionOverride);
+ } elseif (isset($params['product']['price']) && is_numeric($params['product']['price'])) {
+ $fallbackPrice = $this->formatDisplayPrice((float) $params['product']['price'], $currency, $displayPrecisionOverride);
+ } elseif (isset($params['product']['price']) && is_string($params['product']['price']) && $params['product']['price'] !== '') {
+ $fallbackPrice = $params['product']['price'];
+ }
if (!empty($lastMinimalPrice)) {
- $minimalPrice = PrestashopCompatibility::formatPrice(_PS_VERSION_, $lastMinimalPrice['price'], $currency);
+ if (
+ !empty($params['product']['has_discount']) &&
+ isset($params['product']['price_amount']) &&
+ is_numeric($params['product']['price_amount']) &&
+ !$this->hasDifferentHistoricalPrice($idProduct, $idProductAttribute, $currency->id, (float) $params['product']['price_amount'])
+ ) {
+ $lastMinimalPrice = array();
+ $forcedFallbackNoPreDiscountHistory = true;
+ }
+ }
+
+ if (!empty($lastMinimalPrice)) {
+ $minimalPrice = $this->formatDisplayPrice($lastMinimalPrice['price'], $currency, $displayPrecisionOverride);
}
else {
$minimalPrice = null;
@@ -166,8 +247,26 @@ class OmnibusEuFree extends Module
'OmnibuseufreeProductPriceMin' => $minimalPrice,
'OmnibuseufreeProductPriceCurrent' => $params['product']['price'],
'OmnibuseufreeProductPriceRegular' => $regularPrice,
+ 'OmnibuseufreeProductPriceFallback' => $fallbackPrice,
'OmnibuseufreeProductDiscount' => (bool) $params['product']['has_discount'],
'OmnibuseufreeNumberOfDays' => (int) Configuration::get('OMNIBUSEUFREE_DAYS', null, null, null, 30),
+ 'OmnibuseufreeDebugEnabled' => $debugEnabled,
+ 'OmnibuseufreeDebugData' => [
+ 'marker' => 'omnibuseufree-debug-2026-03-16',
+ 'product_id' => $idProduct,
+ 'product_attribute_id' => $idProductAttribute,
+ 'currency_id' => isset($currency->id) ? (int) $currency->id : null,
+ 'currency_iso' => isset($currency->iso_code) ? (string) $currency->iso_code : '',
+ 'price_display_precision' => (int) Configuration::get('PS_PRICE_DISPLAY_PRECISION', null, null, null, _PS_PRICE_DISPLAY_PRECISION_),
+ 'display_precision_override' => $displayPrecisionOverride === null ? 'null' : (string) $displayPrecisionOverride,
+ 'param_price' => isset($params['product']['price']) ? (string) $params['product']['price'] : null,
+ 'param_price_amount' => isset($params['product']['price_amount']) ? (string) $params['product']['price_amount'] : null,
+ 'param_regular_price' => isset($params['product']['regular_price']) ? (string) $params['product']['regular_price'] : null,
+ 'computed_fallback' => (string) $fallbackPrice,
+ 'computed_minimal' => (string) $minimalPrice,
+ 'has_discount' => !empty($params['product']['has_discount']) ? '1' : '0',
+ 'forced_fallback_no_pre_discount_history' => $forcedFallbackNoPreDiscountHistory ? '1' : '0',
+ ],
]);
return $this->display(__FILE__, '/views/templates/hook/presta_studio_omnibus_price.tpl');
@@ -194,7 +293,7 @@ class OmnibusEuFree extends Module
foreach ($rowValue as $key => $value) {
if (isset($OmnibusData[$rowId]['price']) && $key == 'id_currency') {
$currency = Currency::getCurrencyInstance((int) $value);
- $OmnibusData[$rowId]['price_locale'] = PrestashopCompatibility::formatPrice(_PS_VERSION_, $OmnibusData[$rowId]['price'], $currency);
+ $OmnibusData[$rowId]['price_locale'] = $this->formatDisplayPrice($OmnibusData[$rowId]['price'], $currency);
$OmnibusData[$rowId]['currency_iso_code'] = $currency->iso_code;
}
elseif ($key == 'id_product_attribute') {
diff --git a/modules/omnibuseufree/views/templates/hook/presta_studio_omnibus_price.tpl b/modules/omnibuseufree/views/templates/hook/presta_studio_omnibus_price.tpl
index 16192490..660c98d1 100644
--- a/modules/omnibuseufree/views/templates/hook/presta_studio_omnibus_price.tpl
+++ b/modules/omnibuseufree/views/templates/hook/presta_studio_omnibus_price.tpl
@@ -21,7 +21,7 @@
{l s='Lowest price in %d days before discount: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}{$OmnibuseufreeProductPriceMin}
{else}
{* when history is empty *}
- {l s='Lowest price in %d days: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}{$OmnibuseufreeProductPriceRegular|default:$OmnibuseufreeProductPriceCurrent}
+ {l s='Lowest price in %d days: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}{$OmnibuseufreeProductPriceFallback|default:$OmnibuseufreeProductPriceCurrent}
{/if}
{else}
{l s='Lowest price in %d days: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}{$OmnibuseufreeProductPriceMin}
@@ -29,3 +29,22 @@
{/if}
+
+{if isset($OmnibuseufreeDebugEnabled) && $OmnibuseufreeDebugEnabled && isset($OmnibuseufreeDebugData)}
+
+
+ OMNIBUS DEBUG
+ marker: {$OmnibuseufreeDebugData.marker}
+ product_id: {$OmnibuseufreeDebugData.product_id}, attr_id: {$OmnibuseufreeDebugData.product_attribute_id}
+ currency: {$OmnibuseufreeDebugData.currency_iso} ({$OmnibuseufreeDebugData.currency_id}), precision: {$OmnibuseufreeDebugData.price_display_precision}
+ precision_override: {$OmnibuseufreeDebugData.display_precision_override}
+ has_discount: {$OmnibuseufreeDebugData.has_discount}
+ param price: {$OmnibuseufreeDebugData.param_price}
+ param price_amount: {$OmnibuseufreeDebugData.param_price_amount}
+ param regular_price: {$OmnibuseufreeDebugData.param_regular_price}
+ computed fallback: {$OmnibuseufreeDebugData.computed_fallback}
+ computed minimal: {$OmnibuseufreeDebugData.computed_minimal}
+ forced_fallback_no_pre_discount_history: {$OmnibuseufreeDebugData.forced_fallback_no_pre_discount_history}
+
+
+{/if}