This commit is contained in:
2026-03-16 00:25:33 +01:00
parent 6db4bbef56
commit 5cefdc42d4
4 changed files with 316 additions and 12 deletions

View File

@@ -43,7 +43,119 @@
"lmtime": 0, "lmtime": 0,
"modified": false "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": { "autoload.php": {
"type": "-", "type": "-",
"size": 1316, "size": 1316,
@@ -116,13 +228,13 @@
}, },
"google-merchant_id-1.xml": { "google-merchant_id-1.xml": {
"type": "-", "type": "-",
"size": 62638554, "size": 63312722,
"lmtime": 0, "lmtime": 0,
"modified": true "modified": true
}, },
"google-merchant_id-2.xml": { "google-merchant_id-2.xml": {
"type": "-", "type": "-",
"size": 2733981, "size": 2750870,
"lmtime": 0, "lmtime": 0,
"modified": true "modified": true
}, },
@@ -318,8 +430,8 @@
}, },
"omnibuseufree.php": { "omnibuseufree.php": {
"type": "-", "type": "-",
"size": 29375, "size": 29553,
"lmtime": 1772663858543, "lmtime": 1773275484740,
"modified": false "modified": false
}, },
"Readme.md": { "Readme.md": {
@@ -597,8 +709,8 @@
}, },
"presta_studio_omnibus_price.tpl": { "presta_studio_omnibus_price.tpl": {
"type": "-", "type": "-",
"size": 1401, "size": 1444,
"lmtime": 1772663725687, "lmtime": 1773275495347,
"modified": false "modified": false
} }
}, },
@@ -749,7 +861,63 @@
"lmtime": 0, "lmtime": 0,
"modified": false "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": {}, "tools": {},
"translations": {}, "translations": {},
"upload": {}, "upload": {},
@@ -761,6 +929,12 @@
"size": 448, "size": 448,
"lmtime": 0, "lmtime": 0,
"modified": false "modified": false
},
"AGENTS.md": {
"type": "-",
"size": 2807,
"lmtime": 1773273811171,
"modified": false
} }
} }
}, },

12
changelog/2026-03-16.md Normal file
View File

@@ -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`

View File

@@ -148,14 +148,95 @@ class OmnibusEuFree extends Module
return (!empty($sqlResult)) ? $sqlResult[0] : array(); 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) public function hookDisplayOmnibusEuFree($params)
{ {
$currency = $this->context->currency; $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; $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)) { 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 { else {
$minimalPrice = null; $minimalPrice = null;
@@ -166,8 +247,26 @@ class OmnibusEuFree extends Module
'OmnibuseufreeProductPriceMin' => $minimalPrice, 'OmnibuseufreeProductPriceMin' => $minimalPrice,
'OmnibuseufreeProductPriceCurrent' => $params['product']['price'], 'OmnibuseufreeProductPriceCurrent' => $params['product']['price'],
'OmnibuseufreeProductPriceRegular' => $regularPrice, 'OmnibuseufreeProductPriceRegular' => $regularPrice,
'OmnibuseufreeProductPriceFallback' => $fallbackPrice,
'OmnibuseufreeProductDiscount' => (bool) $params['product']['has_discount'], 'OmnibuseufreeProductDiscount' => (bool) $params['product']['has_discount'],
'OmnibuseufreeNumberOfDays' => (int) Configuration::get('OMNIBUSEUFREE_DAYS', null, null, null, 30), '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'); 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) { foreach ($rowValue as $key => $value) {
if (isset($OmnibusData[$rowId]['price']) && $key == 'id_currency') { if (isset($OmnibusData[$rowId]['price']) && $key == 'id_currency') {
$currency = Currency::getCurrencyInstance((int) $value); $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; $OmnibusData[$rowId]['currency_iso_code'] = $currency->iso_code;
} }
elseif ($key == 'id_product_attribute') { elseif ($key == 'id_product_attribute') {

View File

@@ -21,7 +21,7 @@
{l s='Lowest price in %d days before discount: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}<span class="presta-studio-price-history-price">{$OmnibuseufreeProductPriceMin}</span> {l s='Lowest price in %d days before discount: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}<span class="presta-studio-price-history-price">{$OmnibuseufreeProductPriceMin}</span>
{else} {else}
{* when history is empty *} {* when history is empty *}
{l s='Lowest price in %d days: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}<span class="presta-studio-price-history-price">{$OmnibuseufreeProductPriceRegular|default:$OmnibuseufreeProductPriceCurrent}</span> {l s='Lowest price in %d days: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}<span class="presta-studio-price-history-price">{$OmnibuseufreeProductPriceFallback|default:$OmnibuseufreeProductPriceCurrent}</span>
{/if} {/if}
{else} {else}
{l s='Lowest price in %d days: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}<span class="presta-studio-price-history-price">{$OmnibuseufreeProductPriceMin}</span> {l s='Lowest price in %d days: ' sprintf=[$OmnibuseufreeNumberOfDays] mod='omnibuseufree'}<span class="presta-studio-price-history-price">{$OmnibuseufreeProductPriceMin}</span>
@@ -29,3 +29,22 @@
</p> </p>
</div> </div>
{/if} {/if}
{if isset($OmnibuseufreeDebugEnabled) && $OmnibuseufreeDebugEnabled && isset($OmnibuseufreeDebugData)}
<div class="presta-studio-price-history" style="margin-top:6px;">
<p class="presta-studio-price-history-text" style="font-size:12px; line-height:1.35;">
<strong>OMNIBUS DEBUG</strong><br>
marker: {$OmnibuseufreeDebugData.marker}<br>
product_id: {$OmnibuseufreeDebugData.product_id}, attr_id: {$OmnibuseufreeDebugData.product_attribute_id}<br>
currency: {$OmnibuseufreeDebugData.currency_iso} ({$OmnibuseufreeDebugData.currency_id}), precision: {$OmnibuseufreeDebugData.price_display_precision}<br>
precision_override: {$OmnibuseufreeDebugData.display_precision_override}<br>
has_discount: {$OmnibuseufreeDebugData.has_discount}<br>
param price: {$OmnibuseufreeDebugData.param_price}<br>
param price_amount: {$OmnibuseufreeDebugData.param_price_amount}<br>
param regular_price: {$OmnibuseufreeDebugData.param_regular_price}<br>
computed fallback: {$OmnibuseufreeDebugData.computed_fallback}<br>
computed minimal: {$OmnibuseufreeDebugData.computed_minimal}<br>
forced_fallback_no_pre_discount_history: {$OmnibuseufreeDebugData.forced_fallback_no_pre_discount_history}
</p>
</div>
{/if}