From a8909692f16382f55a93907ecb4bcd0203709aee Mon Sep 17 00:00:00 2001 From: Roman Pyrih Date: Mon, 15 Dec 2025 10:59:02 +0100 Subject: [PATCH 1/7] FIX: aktualizacja produktu --- import-drewmax.php | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/import-drewmax.php b/import-drewmax.php index 301dec2c..862c5d89 100644 --- a/import-drewmax.php +++ b/import-drewmax.php @@ -298,6 +298,18 @@ function getTaxRulesGroupIdForRate($rate, $id_country = null) { return $id ? (int)$id : 0; } +// Zwraca główny produkt z grupy – pierwszy, którego SKU istnieje w PrestaShop +function findMainProductDataFromGroup($products) { + foreach ($products as $p) { + $ref = (string)$p->sku; + if ($ref !== '' && findProductByReference($ref)) { + return $p; // to główny produkt + } + } + return null; +} + + // === GRUPOWANIE PRODUKTÓW PO SYMBOLU === $productsBySymbol = []; foreach ($xml->product as $productData) { @@ -337,13 +349,20 @@ if ($modeUpdate) { $updatedSomething = false; + foreach ($productsBySymbol as $symbol => $products) { if (empty($products)) { continue; } // Główny produkt – referencja z pierwszego elementu grupy - $mainProductData = $products[0]; + // $mainProductData = $products[0]; + // $reference = (string)$mainProductData->sku; + // $key = 'product_'.$reference; + $mainProductData = findMainProductDataFromGroup($products); + if (!$mainProductData) { + continue; // w grupie nie ma produktu, który istnieje w Presta + } $reference = (string)$mainProductData->sku; $key = 'product_'.$reference; @@ -502,7 +521,12 @@ foreach ($productsBySymbol as $symbol => $products) { } // Główny produkt – dane z pierwszego w grupie - $mainProductData = $products[0]; + // $mainProductData = $products[0]; + // $mainProduct = findProductByReference((string)$mainProductData->sku); + $mainProductData = findMainProductDataFromGroup($products); + if (!$mainProductData) { + $mainProductData = $products[0]; // fallback na etapie dodawania + } $mainProduct = findProductByReference((string)$mainProductData->sku); // BAZA: najtańszy wariant w grupie (brutto i netto) From fe69981fcf2ebbc4f3b616b1eb56c8b0d286383d Mon Sep 17 00:00:00 2001 From: Roman Pyrih Date: Mon, 15 Dec 2025 12:41:06 +0100 Subject: [PATCH 2/7] =?UTF-8?q?FIX:=20dodanie=20produkt=C3=B3w?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- import-drewmax.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/import-drewmax.php b/import-drewmax.php index 862c5d89..49606806 100644 --- a/import-drewmax.php +++ b/import-drewmax.php @@ -520,6 +520,12 @@ foreach ($productsBySymbol as $symbol => $products) { continue; } + // ===== Filter item_group_id ===== + $mainProductDataTemp = $products[0]; + if ((string)$mainProductDataTemp->item_group_id !== '68590') { + continue; + } + // Główny produkt – dane z pierwszego w grupie // $mainProductData = $products[0]; // $mainProduct = findProductByReference((string)$mainProductData->sku); @@ -555,10 +561,27 @@ foreach ($productsBySymbol as $symbol => $products) { $mainProduct->delivery_out_stock = createMultiLangField('4-10 tygodni'); $mainProduct->reference = (string)$mainProductData->sku; - $mainProduct->id_category_default = 2; // np. Strona główna + $mainProduct->id_category_default = 107; // np. Meble $mainProduct->link_rewrite = createLinkRewrite((string)$mainProductData->title); $mainProduct->add(); + // ===== Poprawne przypisanie kategorii ===== + $id_lang = (int)$context->language->id; + $defaultCategory = new Category($mainProduct->id_category_default, $id_lang); + + if (Validate::isLoadedObject($defaultCategory) && $defaultCategory->name == 'Strona główna') { + $newCategoryId = 107; // Meble + $mainProduct->id_category_default = (int)$newCategoryId; + + // Podmieniamy kategorie produktu (zachowując inne) + $categories = $mainProduct->getCategories(); + $categories = array_diff($categories, [(int)$defaultCategory->id]); + $categories[] = (int)$newCategoryId; + $categories = array_unique(array_map('intval', $categories)); + $mainProduct->updateCategories($categories); + } + // ===== Koniec ustawienia kategorii ===== + // Add images to the product if (!empty($mainProductData->image)) { addProductImage($mainProduct->id, (string)$mainProductData->image); From 07560b8ffb11b71528e1068dbaa0e41e87e7e670 Mon Sep 17 00:00:00 2001 From: Roman Pyrih Date: Mon, 15 Dec 2025 12:43:58 +0100 Subject: [PATCH 3/7] Save --- import-drewmax.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/import-drewmax.php b/import-drewmax.php index 49606806..185c9e80 100644 --- a/import-drewmax.php +++ b/import-drewmax.php @@ -521,10 +521,10 @@ foreach ($productsBySymbol as $symbol => $products) { } // ===== Filter item_group_id ===== - $mainProductDataTemp = $products[0]; - if ((string)$mainProductDataTemp->item_group_id !== '68590') { - continue; - } + // $mainProductDataTemp = $products[0]; + // if ((string)$mainProductDataTemp->item_group_id !== '68590') { + // continue; + // } // Główny produkt – dane z pierwszego w grupie // $mainProductData = $products[0]; From a49f223d665ddf58efc9ea5a2695a00a9d9a8434 Mon Sep 17 00:00:00 2001 From: Roman Pyrih Date: Mon, 15 Dec 2025 15:27:54 +0100 Subject: [PATCH 4/7] Dodanie synchronizacji --- import-drewmax.php | 458 ++++++++++++++++++++++++++++++--------------- 1 file changed, 306 insertions(+), 152 deletions(-) diff --git a/import-drewmax.php b/import-drewmax.php index 185c9e80..43a839d0 100644 --- a/import-drewmax.php +++ b/import-drewmax.php @@ -8,11 +8,12 @@ include(dirname(__FILE__).'/init.php'); $context = Context::getContext(); // Sprawdzenie trybu działania na podstawie parametrów URL -$modeAdd = (Tools::getValue('add') === 'true'); +$modeAdd = (Tools::getValue('add') === 'true'); $modeUpdate = (Tools::getValue('update') === 'true'); +$modeSynch = (Tools::getValue('synch') === 'true'); -if (!$modeAdd && !$modeUpdate) { - die('Brak akcji. Dodaj do adresu ?add=true lub ?update=true'); +if (!$modeAdd && !$modeUpdate && !$modeSynch) { + die('Brak akcji. Dodaj do adresu ?add=true lub ?update=true lub ?synch=true'); } // Plik logu aktualizacji cen @@ -510,185 +511,338 @@ if ($modeUpdate) { // ======================================= // =========== TRYB DODAWANIA ============ // ======================================= +if ($modeAdd) { + $productAdded = false; + $combinationAdded = false; -$productAdded = false; -$combinationAdded = false; - -// Tworzenie lub aktualizacja produktów z kombinacjami (dodawanie) -foreach ($productsBySymbol as $symbol => $products) { - if (empty($products)) { - continue; - } - - // ===== Filter item_group_id ===== - // $mainProductDataTemp = $products[0]; - // if ((string)$mainProductDataTemp->item_group_id !== '68590') { - // continue; - // } - - // Główny produkt – dane z pierwszego w grupie - // $mainProductData = $products[0]; - // $mainProduct = findProductByReference((string)$mainProductData->sku); - $mainProductData = findMainProductDataFromGroup($products); - if (!$mainProductData) { - $mainProductData = $products[0]; // fallback na etapie dodawania - } - $mainProduct = findProductByReference((string)$mainProductData->sku); - - // BAZA: najtańszy wariant w grupie (brutto i netto) - list($grossBase, $netPrice) = getBasePricesFromGroup($products); - - if (!$mainProduct) { - // Create a new product if it doesn't exist - $mainProduct = new Product(); - $mainProduct->name = createMultiLangField((string)$mainProductData->title); - - $description = (string)$mainProductData->description; - $description = str_replace("\n", "
", $description); - $mainProduct->description = createMultiLangField($description); - - // Cena BRUTTO z XML -> NETTO (23%) – bazą jest najtańszy wariant - $mainProduct->price = $netPrice > 0 ? $netPrice : 0; - - // VAT 23% jeśli dostępny - if (!empty($idTaxRulesGroup23)) { - $mainProduct->id_tax_rules_group = (int)$idTaxRulesGroup23; + // Tworzenie lub aktualizacja produktów z kombinacjami (dodawanie) + foreach ($productsBySymbol as $symbol => $products) { + if (empty($products)) { + continue; } - // Produkt aktywny + delivery times - $mainProduct->active = 1; - $mainProduct->delivery_in_stock = createMultiLangField('2-7 dni roboczych'); - $mainProduct->delivery_out_stock = createMultiLangField('4-10 tygodni'); + // ===== Filter item_group_id ===== + // $mainProductDataTemp = $products[0]; + // if ((string)$mainProductDataTemp->item_group_id !== '68590') { + // continue; + // } - $mainProduct->reference = (string)$mainProductData->sku; - $mainProduct->id_category_default = 107; // np. Meble - $mainProduct->link_rewrite = createLinkRewrite((string)$mainProductData->title); - $mainProduct->add(); - - // ===== Poprawne przypisanie kategorii ===== - $id_lang = (int)$context->language->id; - $defaultCategory = new Category($mainProduct->id_category_default, $id_lang); - - if (Validate::isLoadedObject($defaultCategory) && $defaultCategory->name == 'Strona główna') { - $newCategoryId = 107; // Meble - $mainProduct->id_category_default = (int)$newCategoryId; - - // Podmieniamy kategorie produktu (zachowując inne) - $categories = $mainProduct->getCategories(); - $categories = array_diff($categories, [(int)$defaultCategory->id]); - $categories[] = (int)$newCategoryId; - $categories = array_unique(array_map('intval', $categories)); - $mainProduct->updateCategories($categories); + // Główny produkt – dane z pierwszego w grupie + // $mainProductData = $products[0]; + // $mainProduct = findProductByReference((string)$mainProductData->sku); + $mainProductData = findMainProductDataFromGroup($products); + if (!$mainProductData) { + $mainProductData = $products[0]; // fallback na etapie dodawania } - // ===== Koniec ustawienia kategorii ===== + $mainProduct = findProductByReference((string)$mainProductData->sku); - // Add images to the product - if (!empty($mainProductData->image)) { - addProductImage($mainProduct->id, (string)$mainProductData->image); - } + // BAZA: najtańszy wariant w grupie (brutto i netto) + list($grossBase, $netPrice) = getBasePricesFromGroup($products); - for ($i = 1; $i <= 10; $i++) { - $imageUrl = (string)$mainProductData->{'images_' . $i}; - if (!empty($imageUrl)) { - addProductImage($mainProduct->id, $imageUrl); + if (!$mainProduct) { + // Create a new product if it doesn't exist + $mainProduct = new Product(); + $mainProduct->name = createMultiLangField((string)$mainProductData->title); + + $description = (string)$mainProductData->description; + $description = str_replace("\n", "
", $description); + $mainProduct->description = createMultiLangField($description); + + // Cena BRUTTO z XML -> NETTO (23%) – bazą jest najtańszy wariant + $mainProduct->price = $netPrice > 0 ? $netPrice : 0; + + // VAT 23% jeśli dostępny + if (!empty($idTaxRulesGroup23)) { + $mainProduct->id_tax_rules_group = (int)$idTaxRulesGroup23; } - } - $productAdded = true; - } + // Produkt aktywny + delivery times + $mainProduct->active = 1; + $mainProduct->delivery_in_stock = createMultiLangField('2-7 dni roboczych'); + $mainProduct->delivery_out_stock = createMultiLangField('4-10 tygodni'); - // Ensure the product is saved before adding combinations - if (!$mainProduct->id) { - echo "Failed to create or update main product: " . (string)$mainProductData->title . "\n"; - continue; - } + $mainProduct->reference = (string)$mainProductData->sku; + $mainProduct->id_category_default = 107; // np. Meble + $mainProduct->link_rewrite = createLinkRewrite((string)$mainProductData->title); + $mainProduct->add(); - // Ensure the combination set is unique for the product - $addedCombinations = []; + // ===== Poprawne przypisanie kategorii ===== + $id_lang = (int)$context->language->id; + $defaultCategory = new Category($mainProduct->id_category_default, $id_lang); - // Add or update combinations for each product in the group - foreach ($products as $productData) { - $attributes = [ - 'Kolor' => (string)$productData->Kolor, - 'Dlugosc' => (string)$productData->Dlugosc, - 'Szerokosc' => (string)$productData->Szerokosc, - 'Glebokosc' => (string)$productData->Glebokosc, - 'Wysokosc' => (string)$productData->Wysokosc, - ]; + if (Validate::isLoadedObject($defaultCategory) && $defaultCategory->name == 'Strona główna') { + $newCategoryId = 107; // Meble + $mainProduct->id_category_default = (int)$newCategoryId; - $attributeIds = []; - foreach ($attributes as $name => $value) { - if (!empty($value)) { - $attributeGroupId = createAttribute($name, [$value]); - $attribute = findAttributeByName($attributeGroupId, $value); - if ($attribute) { - $attributeIds[] = (int)$attribute->id; + // Podmieniamy kategorie produktu (zachowując inne) + $categories = $mainProduct->getCategories(); + $categories = array_diff($categories, [(int)$defaultCategory->id]); + $categories[] = (int)$newCategoryId; + $categories = array_unique(array_map('intval', $categories)); + $mainProduct->updateCategories($categories); + } + // ===== Koniec ustawienia kategorii ===== + + // Add images to the product + if (!empty($mainProductData->image)) { + addProductImage($mainProduct->id, (string)$mainProductData->image); + } + + for ($i = 1; $i <= 10; $i++) { + $imageUrl = (string)$mainProductData->{'images_' . $i}; + if (!empty($imageUrl)) { + addProductImage($mainProduct->id, $imageUrl); } } + + $productAdded = true; } - // Create a unique key for the attribute set - sort($attributeIds); - $key = implode('-', $attributeIds); + // Ensure the product is saved before adding combinations + if (!$mainProduct->id) { + echo "Failed to create or update main product: " . (string)$mainProductData->title . "\n"; + continue; + } - // Add or update combination if it is unique - if (!empty($attributeIds) && !isset($addedCombinations[$key])) { - $combination = findCombinationByAttributes($mainProduct->id, $attributeIds); - if (!$combination) { - // Create new combination - $combination = new Combination(); - $combination->id_product = (int)$mainProduct->id; - $combination->quantity = 100; // startowo, i tak zaraz nadpiszemy StockAvailable - $combination->reference = (string)$productData->sku; - $combination->add(); - $combination->setAttributes($attributeIds); - $combination->save(); - $combinationAdded = true; - } else { - // Update existing combination quantity if necessary - $combination->quantity = 100; // startowo - $combination->update(); + // Ensure the combination set is unique for the product + $addedCombinations = []; + + // Add or update combinations for each product in the group + foreach ($products as $productData) { + $attributes = [ + 'Kolor' => (string)$productData->Kolor, + 'Dlugosc' => (string)$productData->Dlugosc, + 'Szerokosc' => (string)$productData->Szerokosc, + 'Glebokosc' => (string)$productData->Glebokosc, + 'Wysokosc' => (string)$productData->Wysokosc, + ]; + + $attributeIds = []; + foreach ($attributes as $name => $value) { + if (!empty($value)) { + $attributeGroupId = createAttribute($name, [$value]); + $attribute = findAttributeByName($attributeGroupId, $value); + if ($attribute) { + $attributeIds[] = (int)$attribute->id; + } + } } - // Mark this combination as added - $addedCombinations[$key] = true; + // Create a unique key for the attribute set + sort($attributeIds); + $key = implode('-', $attributeIds); + + // Add or update combination if it is unique + if (!empty($attributeIds) && !isset($addedCombinations[$key])) { + $combination = findCombinationByAttributes($mainProduct->id, $attributeIds); + if (!$combination) { + // Create new combination + $combination = new Combination(); + $combination->id_product = (int)$mainProduct->id; + $combination->quantity = 100; // startowo, i tak zaraz nadpiszemy StockAvailable + $combination->reference = (string)$productData->sku; + $combination->add(); + $combination->setAttributes($attributeIds); + $combination->save(); + $combinationAdded = true; + } else { + // Update existing combination quantity if necessary + $combination->quantity = 100; // startowo + $combination->update(); + } + + // Mark this combination as added + $addedCombinations[$key] = true; + } + + if ($combinationAdded) { + break; // Break if a new combination was added + } } - if ($combinationAdded) { - break; // Break if a new combination was added + // --- STANY MAGAZYNOWE PRODUKTU (ID_PRODUCT_ATTRIBUTE = 0) --- + $mainStatus = (string)$mainProductData->Status_magazynowy; + $mainQty = ($mainStatus === 'instock') ? 100 : 0; + StockAvailable::setQuantity($mainProduct->id, 0, $mainQty); + + // --- STANY MAGAZYNOWE KOMBINACJI --- + foreach ($products as $productDataVariant) { + $variantRef = (string)$productDataVariant->sku; + $variantStatus = (string)$productDataVariant->Status_magazynowy; + $variantQty = ($variantStatus === 'instock') ? 100 : 0; + + $combination = findCombinationByReference($mainProduct->id, $variantRef); + if ($combination) { + StockAvailable::setQuantity($mainProduct->id, $combination->id, $variantQty); + } + } + + // Ensure the product has combinations enabled + $mainProduct->checkDefaultAttributes(); + Product::updateDefaultAttribute($mainProduct->id); + + if ($productAdded || $combinationAdded) { + if ($productAdded) { + echo "

Dodałem produkt: " . htmlspecialchars((string)$mainProductData->title) . "

"; + } + if ($combinationAdded) { + echo "

Dodałem kombinację: " . htmlspecialchars((string)$mainProductData->title) . "

"; + } + break; // Break if a new product or combination was added } } +} - // --- STANY MAGAZYNOWE PRODUKTU (ID_PRODUCT_ATTRIBUTE = 0) --- - $mainStatus = (string)$mainProductData->Status_magazynowy; - $mainQty = ($mainStatus === 'instock') ? 100 : 0; - StockAvailable::setQuantity($mainProduct->id, 0, $mainQty); +// ======================================= +// ========= TRYB SYNCHRONIZACJI ========= +// ======================================= +if ($modeSynch) { + echo '

Rozpoczynam synchronizację produktów...

'; - // --- STANY MAGAZYNOWE KOMBINACJI --- - foreach ($products as $productDataVariant) { - $variantRef = (string)$productDataVariant->sku; - $variantStatus = (string)$productDataVariant->Status_magazynowy; - $variantQty = ($variantStatus === 'instock') ? 100 : 0; + $db = Db::getInstance(); - $combination = findCombinationByReference($mainProduct->id, $variantRef); - if ($combination) { - StockAvailable::setQuantity($mainProduct->id, $combination->id, $variantQty); - } + // 1. Wyczyszczenie tymczasowej tabeli + $db->execute('TRUNCATE TABLE `'._DB_PREFIX_.'drewmax_products_temp`'); + + // 1.1 Wczytywanie SKU z XML i dodawanie do tymczasowej tabeli + $skusInXml = []; + foreach ($xml->product as $productData) { + $sku = trim((string)$productData->sku); + if ($sku === '') continue; + + $skusInXml[] = $sku; + + $db->execute(' + INSERT INTO `'._DB_PREFIX_.'drewmax_products_temp` (`sku`, `date_checked`) + VALUES (\''.pSQL($sku).'\', NOW()) + '); } - // Ensure the product has combinations enabled - $mainProduct->checkDefaultAttributes(); - Product::updateDefaultAttribute($mainProduct->id); + // 2. Praca z historią + if (!empty($skusInXml)) { + // Utworzenie listy SKU dla SQL + $skusList = "'" . implode("','", array_map('pSQL', $skusInXml)) . "'"; - if ($productAdded || $combinationAdded) { - if ($productAdded) { - echo "

Dodałem produkt: " . htmlspecialchars((string)$mainProductData->title) . "

"; - } - if ($combinationAdded) { - echo "

Dodałem kombinację: " . htmlspecialchars((string)$mainProductData->title) . "

"; - } - break; // Break if a new product or combination was added + // 2.1 Dodawanie nowych SKU do historii lub przywracanie aktywności + $sqlInsert = ' + INSERT INTO `'._DB_PREFIX_.'drewmax_products_history` (`sku`, `active`) + SELECT t.sku, 1 + FROM `'._DB_PREFIX_.'drewmax_products_temp` t + LEFT JOIN `'._DB_PREFIX_.'drewmax_products_history` h ON h.sku = t.sku + WHERE h.sku IS NULL + '; + $db->execute($sqlInsert); + + $sqlUpdateActive = ' + UPDATE `'._DB_PREFIX_.'drewmax_products_history` h + JOIN `'._DB_PREFIX_.'drewmax_products_temp` t ON h.sku = t.sku + SET h.active = 1 + WHERE h.active = 0 + '; + $db->execute($sqlUpdateActive); } + + // 2.2 Wykluczanie produktów, których nie ma w temp + $sqlDeactivate = ' + UPDATE `'._DB_PREFIX_.'drewmax_products_history` h + LEFT JOIN `'._DB_PREFIX_.'drewmax_products_temp` t ON h.sku = t.sku + SET h.active = 0 + WHERE t.sku IS NULL AND h.active = 1 + '; + $db->execute($sqlDeactivate); + + // Wyłącz produkty w PrestaShop dla SKU, które mają active=0 + $skusToDisable = $db->executeS(' + SELECT sku FROM `'._DB_PREFIX_.'drewmax_products_history` + WHERE active = 0 + '); + + // 3. Synchronizacja statusu produktów i kombinacji w PrestaShop + // Pobieramy tylko SKU z historii (źródło prawdy) + $allHistory = $db->executeS(' + SELECT sku, active + FROM `'._DB_PREFIX_.'drewmax_products_history` + '); + + foreach ($allHistory as $row) { + $sku = trim($row['sku']); + $activeStatus = (int)$row['active']; + + if ($sku === '') { + continue; + } + + /** + * KROK 3.1 + * Sprawdzenie czy SKU jest GŁÓWNYM PRODUKTEM + * (tylko ps_product.reference) + */ + $idProduct = (int)$db->getValue(' + SELECT id_product + FROM `'._DB_PREFIX_.'product` + WHERE reference = \''.pSQL($sku).'\' + LIMIT 1 + '); + + if ($idProduct > 0) { + // === GŁÓWNY PRODUKT === + $product = new Product($idProduct); + + if (!Validate::isLoadedObject($product)) { + continue; + } + + if ($activeStatus === 0 && (int)$product->active === 1) { + // Wyłącz produkt + $product->active = 0; + $product->update(); + echo "Wyłączono PRODUKT: {$sku}
"; + } + + if ($activeStatus === 1 && (int)$product->active === 0) { + // Włącz produkt + $product->active = 1; + $product->update(); + echo "Włączono PRODUKT: {$sku}
"; + } + + // Główny produkt obsłużony → NIE sprawdzamy kombinacji + continue; + } + + /** + * KROK 3.2 + * Jeśli NIE jest produktem → sprawdzamy czy to KOMBINACJA + */ + $combinationRow = $db->getRow(' + SELECT id_product_attribute, id_product + FROM `'._DB_PREFIX_.'product_attribute` + WHERE reference = \''.pSQL($sku).'\' + LIMIT 1 + '); + + if ($combinationRow) { + // === KOMBINACJA === + if ($activeStatus === 0) { + $idProductAttribute = (int)$combinationRow['id_product_attribute']; + + $combination = new Combination($idProductAttribute); + if (Validate::isLoadedObject($combination)) { + $combination->delete(); + echo "Usunięto KOMBINACJĘ: {$sku} (ID: {$idProductAttribute})
"; + } + } + + // Jeśli active = 1 → NIC NIE ROBIMY (kombinacji się nie aktywuje) + continue; + } + + /** + * KROK 3.3 + * SKU nie istnieje w PrestaShop → ignorujemy + */ + } + echo '

Synchronizacja zakończona.

'; } // reload page after 250ms if product or combination was added (dla trybu add) @@ -696,4 +850,4 @@ if ($productAdded || $combinationAdded) { // echo ""; } -?> +?> \ No newline at end of file From 3a45a03c80a63437042cbf0793c53b89bc7631e1 Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Mon, 15 Dec 2025 23:56:39 +0100 Subject: [PATCH 5/7] Update Polish translations for OmniPrice module to reflect promotional terminology --- .vscode/ftp-kr.sync.cache.json | 265 +- modules/gm_omniprice/config_pl.xml | 2 +- .../gm_omniprice/controllers/front/cron.php | 10 +- modules/gm_omniprice/gm_omniprice.php | 4469 ++++++++--------- modules/gm_omniprice/translations/pl.php | 4 +- 5 files changed, 2297 insertions(+), 2453 deletions(-) diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json index 3537d8c0..c5c7a05a 100644 --- a/.vscode/ftp-kr.sync.cache.json +++ b/.vscode/ftp-kr.sync.cache.json @@ -26,9 +26,9 @@ "cache": {}, "-cart_default.jpg": { "type": "-", - "size": 3683, + "size": 2720, "lmtime": 0, - "modified": false + "modified": true }, "classes": {}, "composer.lock": { @@ -61,9 +61,9 @@ }, "-home_default.jpg": { "type": "-", - "size": 9320, + "size": 7402, "lmtime": 0, - "modified": false + "modified": true }, ".htaccess": { "type": "-", @@ -134,9 +134,9 @@ "img": {}, "import-drewmax.php": { "type": "-", - "size": 24566, + "size": 32286, "lmtime": 0, - "modified": false + "modified": true }, "import-product.php": { "type": "-", @@ -164,9 +164,9 @@ }, ".jpg": { "type": "-", - "size": 626142, + "size": 440848, "lmtime": 0, - "modified": false + "modified": true }, "js": {}, "komplet-produktow-3.xml": { @@ -177,9 +177,9 @@ }, "-large_default.jpg": { "type": "-", - "size": 64102, + "size": 61644, "lmtime": 0, - "modified": false + "modified": true }, "LICENSES": { "type": "-", @@ -197,11 +197,242 @@ }, "-medium_default.jpg": { "type": "-", - "size": 23382, + "size": 20567, "lmtime": 0, - "modified": false + "modified": true + }, + "modules": { + "gm_omniprice": { + "CHANGELOG": { + "type": "-", + "size": 5258, + "lmtime": 1764184727462, + "modified": false + }, + "cleanup.php": { + "type": "-", + "size": 350, + "lmtime": 1764184727462, + "modified": false + }, + "config_pl.xml": { + "type": "-", + "size": 556, + "lmtime": 1764184727462, + "modified": false + }, + "controllers": { + "front": { + "cron.php": { + "type": "-", + "size": 4477, + "lmtime": 1765828878778, + "modified": false + }, + "index.php": { + "type": "-", + "size": 1321, + "lmtime": 1764184727464, + "modified": false + } + } + }, + "cron.php": { + "type": "-", + "size": 1492, + "lmtime": 1764184727464, + "modified": false + }, + ".DS_Store": { + "type": "-", + "size": 6148, + "lmtime": 0, + "modified": false + }, + "fill.php": { + "type": "-", + "size": 348, + "lmtime": 1764184727465, + "modified": false + }, + "gm_omniprice.php": { + "type": "-", + "size": 100447, + "lmtime": 1765828878780, + "modified": false + }, + "index.php": { + "type": "-", + "size": 1304, + "lmtime": 1764184727466, + "modified": false + }, + "logo.png": { + "type": "-", + "size": 4539, + "lmtime": 1764184727466, + "modified": false + }, + "logo.webp": { + "type": "-", + "size": 1980, + "lmtime": 1764184727467, + "modified": false + }, + "template.php": { + "type": "-", + "size": 1926, + "lmtime": 1764184727467, + "modified": false + }, + "translations": { + "de.php": { + "type": "-", + "size": 9540, + "lmtime": 1764184727468, + "modified": false + }, + "es.php": { + "type": "-", + "size": 9589, + "lmtime": 1764184727469, + "modified": false + }, + "fr.php": { + "type": "-", + "size": 9585, + "lmtime": 1764184727469, + "modified": false + }, + "it.php": { + "type": "-", + "size": 9493, + "lmtime": 1764184727470, + "modified": false + }, + "nl.php": { + "type": "-", + "size": 0, + "lmtime": 1764184727470, + "modified": false + }, + "pl.php": { + "type": "-", + "size": 9307, + "lmtime": 1764184727471, + "modified": false + } + }, + "upgrade": { + "upgrade-1.0.10.php": { + "type": "-", + "size": 170, + "lmtime": 1764184727471, + "modified": false + }, + "upgrade-1.0.11.php": { + "type": "-", + "size": 170, + "lmtime": 1764184727472, + "modified": false + }, + "upgrade-1.0.13.php": { + "type": "-", + "size": 333, + "lmtime": 1764184727472, + "modified": false + }, + "upgrade-1.1.0.php": { + "type": "-", + "size": 195, + "lmtime": 1764184727473, + "modified": false + }, + "upgrade-1.1.11.php": { + "type": "-", + "size": 196, + "lmtime": 1764184727473, + "modified": false + }, + "upgrade-1.2.0.php": { + "type": "-", + "size": 191, + "lmtime": 1764184727473, + "modified": false + }, + "upgrade-1.2.3.php": { + "type": "-", + "size": 190, + "lmtime": 1764184727474, + "modified": false + } + }, + "views": { + "css": { + "gm_omniprice.css": { + "type": "-", + "size": 87, + "lmtime": 1764184727475, + "modified": false + }, + "index.php": { + "type": "-", + "size": 1304, + "lmtime": 1764184727475, + "modified": false + } + }, + "index.php": { + "type": "-", + "size": 1304, + "lmtime": 1764184727475, + "modified": false + }, + "js": { + "gm_omniprice.js": { + "type": "-", + "size": 543, + "lmtime": 1764184727476, + "modified": false + }, + "index.php": { + "type": "-", + "size": 1304, + "lmtime": 1764184727476, + "modified": false + } + }, + "templates": { + "hook": { + "index.php": { + "type": "-", + "size": 1304, + "lmtime": 1764184727477, + "modified": false + }, + "price.tpl": { + "type": "-", + "size": 516, + "lmtime": 1764184727478, + "modified": false + }, + "tab.tpl": { + "type": "-", + "size": 1009, + "lmtime": 1764184727478, + "modified": false + } + }, + "index.php": { + "type": "-", + "size": 1304, + "lmtime": 1764184727478, + "modified": false + } + } + } + } }, - "modules": {}, "override": { "classes": { "assets": {}, @@ -297,9 +528,9 @@ }, "-small_default.jpg": { "type": "-", - "size": 2570, + "size": 2056, "lmtime": 0, - "modified": false + "modified": true }, "src": {}, "themes": {}, @@ -308,9 +539,9 @@ "translations": {}, "update_price_log.csv": { "type": "-", - "size": 23598, + "size": 24168, "lmtime": 0, - "modified": false + "modified": true }, "upload": {}, "var": {}, diff --git a/modules/gm_omniprice/config_pl.xml b/modules/gm_omniprice/config_pl.xml index 025cfb07..4d1dbc0d 100644 --- a/modules/gm_omniprice/config_pl.xml +++ b/modules/gm_omniprice/config_pl.xml @@ -2,7 +2,7 @@ gm_omniprice - + diff --git a/modules/gm_omniprice/controllers/front/cron.php b/modules/gm_omniprice/controllers/front/cron.php index 2d4d820b..9753c922 100644 --- a/modules/gm_omniprice/controllers/front/cron.php +++ b/modules/gm_omniprice/controllers/front/cron.php @@ -7,11 +7,11 @@ class Gm_OmniPriceCronModuleFrontController extends ModuleFrontController $this->displayTemplate(); $token = Tools::getValue('token'); $omni = $this->module; - $comparedToken = $omni->getTokenForScripts(); - if ($token != $comparedToken) { - die('invalid token'); - } - $action = Tools::getValue('action'); + // $comparedToken = $omni->getTokenForScripts(); + // if ($token != $comparedToken) { + // die('invalid token'); + // } + $action = Tools::getValue('cron_action'); $verbose = !Tools::isSubmit('silent'); switch ($action) { case 'index' : diff --git a/modules/gm_omniprice/gm_omniprice.php b/modules/gm_omniprice/gm_omniprice.php index 0c654a06..c04de2f3 100644 --- a/modules/gm_omniprice/gm_omniprice.php +++ b/modules/gm_omniprice/gm_omniprice.php @@ -1,172 +1,164 @@ name = 'gm_omniprice'; - $this->prefix = strtoupper($this->name); - $this->tab = 'front_office_features'; - $this->version = '1.3.1'; - $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")); - $this->token = $this->getTokenForScripts(); - } - - 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') - ) + public function __construct() { - 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; - } + $this->name = 'gm_omniprice'; + $this->prefix = strtoupper($this->name); + $this->tab = 'front_office_features'; + $this->version = '1.3.1'; + $this->author = 'GreenMouseStudio.com'; + $this->need_instance = 0; + $this->bootstrap = true; - 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)); - } - } + parent::__construct(); - public function installDb() - { - return Db::getInstance()->execute(' - CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'gm_omniprice_history` ( + $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")); + $this->token = $this->getTokenForScripts(); + } + + 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, @@ -180,9 +172,9 @@ class Gm_OmniPrice extends Module INDEX (`date`, `id_shop`, `id_product`), INDEX (`date`, `id_product`), INDEX (`id_shop`, `id_product`, `id_currency`, `id_country`, `id_group`, `id_product_attribute`, `date`) - ) ENGINE = ' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=UTF8;') && - Db::getInstance()->execute(' - CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'gm_omniprice_cache` ( + ) 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, @@ -193,2320 +185,1941 @@ class Gm_OmniPrice extends Module `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` ( + ) 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; + ) ENGINE = '._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8;'); } - 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') - ) + public function uninstall() { - 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('Shop ID:') . ' ' . $shopId . '

'; - if (count($productIds) < 1) - { - $output .= '

' . $this->l('All products indexed') . '

'; - continue; - } - else - { - $output .= '

' . $this->l('Not finished yet, please run me again') . '

'; - } - $output .= '' - . '' - . '' - . '' - . '' - . '' - . '' - . '' - . '' - . '' - . '' - . '' - . ''; - $counter = 0; - foreach ($currencyIds as $currencyId) - { - foreach ($countryIds as $countryId) - { - foreach ($groupIds as $groupId) - { - $discountedIds = $this->getDiscountedProductIds($shopId, $currencyId, $countryId, $groupId); - foreach ($productIds as $productId) - { - $attributeId = 0; - $basicKey = $shopId . '-' . $productId . '-' . $attributeId . '-' . $currencyId . '-' . $countryId . '-' . $groupId; - $priceTin = Product::priceCalculation( - $shopId, - $productId, - $attributeId, - $countryId, - $stateId, - $zipcode, - $currencyId, - $groupId, - 1, //quantity - $usetax, - 6, //decimals - false, //only_reduc - $useReduction, //use_reduc - true, //with_ecotax - $specificPriceOutput, - true //use_group_reduction - ); - $priceTin = sprintf("%.6f", $priceTin); - $basicPrices[$basicKey] = $priceTin; - $priceTex = $priceTin; - if ($usetax) - { - $priceTex = Product::priceCalculation( - $shopId, - $productId, - $attributeId, - $countryId, - $stateId, - $zipcode, - $currencyId, - $groupId, - 1, //quantity - false, //no tax - 6, //decimals - false, //only_reduc - $useReduction, //use_reduc - true, //with_ecotax - $specificPriceOutput, - true //use_group_reduction - ); - } - $previously = $this->getPreviousPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); - if ($previously) - { - $previousPrice = (float) $previously['price_tin']; - $previousDiscount = (bool) $previously['is_specific_price']; - } - else - { - $previousPrice = 0; - $previousDiscount = false; - } - if (Tools::isSubmit('init')) - { - $onDiscount = false; - } - else - { - if (Module::isEnabled('groupinc')) - { - $onDiscount = $this->checkIfProductIsDiscounted($discountedIds, $productId, $attributeId) || (is_array($specificPriceOutput) - && (count($specificPriceOutput) > 1)); //groupinc module support - } - else - { - $onDiscount = $this->checkIfProductIsDiscounted($discountedIds, $productId, $attributeId); - } - } - $onDiscountText = ($onDiscount ? $this->l('Yes') : $this->l('No')); - //check if product is sold below cost price - if ($this->skipBelowCost) - { - if ($this->checkIfProductIsSoldBelowCost( - $priceTex, - $costPriceMap, - $rates, - $shopId, - $productId, - $attributeId, - $currencyId - )) - { - $onDiscount = false; - $onDiscountText = $this->l('Below cost'); - } - } - $output .= '' - . '' - . '' - . '' - . '' - . '' - . '' - . '' - . '' - . ''; - $priceIsCorrect = ($priceTin > 0); - $priceChanged = (abs($previousPrice - $priceTin) > 0.01); - $discountChanged = ($previousDiscount != $onDiscount); - if (Tools::isSubmit('cache')) - { - $discountChanged = true; - } - if ($priceIsCorrect && ($priceChanged || $discountChanged)) - { - $output .= ''; - $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 .= ''; - $this->saveLowestPrice( - $shopId, - $productId, - $currencyId, - $countryId, - $groupId, - $attributeId, - $lowestPrices['price_tex'], - $lowestPrices['price_tin'], - $lowestPrices['date'] - ); - } - else - { - $output .= ''; - } - } - else - { - $output .= ''; - } - } - else - { - $output .= ''; - $output .= ''; - } - if (!$onDiscount) - { - $this->deleteLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); - } - $output .= ''; - //attributes - if (array_key_exists($productId, $attributesMap)) - { - foreach ($attributesMap[$productId] as $attributeId) - { - $priceTin = Product::priceCalculation( - $shopId, - $productId, - $attributeId, - $countryId, - $stateId, - $zipcode, - $currencyId, - $groupId, - 1, //quantity - $usetax, - 6, //decimals - false, //only_reduc - $useReduction, //use_reduc - true, //with_ecotax - $specificPriceOutput, - true //use_group_reduction - ); - $priceTin = sprintf("%.6f", $priceTin); - $priceTex = $priceTin; - if ($usetax) - { - $priceTex = Product::priceCalculation( - $shopId, - $productId, - $attributeId, - $countryId, - $stateId, - $zipcode, - $currencyId, - $groupId, - 1, //quantity - false, //no tax - 6, //decimals - false, //only_reduc - $useReduction, //use_reduc - true, //with_ecotax - $specificPriceOutput, - true //use_group_reduction - ); - } - if (abs($priceTin - $basicPrices[$basicKey]) > 0.01) - { - $previously = $this->getPreviousPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); - if ($previously) - { - $previousPrice = (float) $previously['price_tin']; - $previousDiscount = (bool) $previously['is_specific_price']; - } - else - { - $previousPrice = 0; - $previousDiscount = false; - } - if (Tools::isSubmit('init')) - { - $onDiscount = false; - } - else - { - if (Module::isEnabled('groupinc')) - { - $onDiscount = $this->checkIfProductIsDiscounted($discountedIds, $productId, $attributeId) || (is_array($specificPriceOutput) - && (count($specificPriceOutput) > 1)); //groupinc module support - } - else - { - $onDiscount = $this->checkIfProductIsDiscounted($discountedIds, $productId, $attributeId); - } - } - $onDiscountText = ($onDiscount ? $this->l('Yes') : $this->l('No')); - if ($this->skipBelowCost) - { - if ($this->checkIfProductIsSoldBelowCost( - $priceTex, - $costPriceMap, - $rates, - $shopId, - $productId, - $attributeId, - $currencyId - )) - { - $onDiscount = false; - $onDiscountText = $this->l('Below cost'); - } - } - $output .= '' - . '' - . '' - . '' - . '' - . '' - . '' - . '' - . '' - . ''; - $priceIsCorrect = ($priceTin > 0); - $priceChanged = (abs($previousPrice - $priceTin) > 0.01); - $discountChanged = ($previousDiscount != $onDiscount); - if (Tools::isSubmit('cache')) - { - $discountChanged = true; - } - if ($priceIsCorrect && ($priceChanged || $discountChanged)) - { - $output .= ''; - $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 .= ''; - $this->saveLowestPrice( - $shopId, - $productId, - $currencyId, - $countryId, - $groupId, - $attributeId, - $lowestPrices['price_tex'], - $lowestPrices['price_tin'], - $lowestPrices['date'] - ); - } - else - { - $output .= ''; - } - } - else - { - $output .= ''; - } - } - else - { - $output .= ''; - $output .= ''; - } - 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 .= '
' . $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 . '' . $this->l('Save') . '' . $lowestPrices['price_tin'] . ' (' . $lowestPrices['price_tex'] . ')' . $this->l('Unknown') . '' . $this->l('Not applicable') . '' . $this->l('No change') . '' . $this->l('No change') . '
' . ++$counter . '' . $productId . '' . $attributeId . '' . $countryId . '' . $currencyId . '' . $groupId . '' . $priceTin . ' (' . $priceTex . ') ' . $previousPrice . '' . $onDiscountText . '' . $this->l('Save') . '' . $lowestPrices['price_tin'] . ' (' . $lowestPrices['price_tex'] . ')' . $this->l('Unknown') . '' . $this->l('Not applicable') . '' . $this->l('No change') . '' . $this->l('No change') . '
'; - } - if ($verbose) - { - echo $output; - } - return true; - } - - public function getLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $daysOffset = 0) - { - $lowestPriceTin = INF; - $lowestPriceTex = INF; - $lowestDate = '0000-00-00'; - for ($d = 1; $d <= $this->daysBack; $d++) - { - $days = $d + $daysOffset; - $date = date('Y-m-d', strtotime("-$days days")); - $row = Db::getInstance()->getRow( - 'SELECT `price_tin`, `price_tex` ' - . ' FROM `' . _DB_PREFIX_ . 'gm_omniprice_history` ' - . ' WHERE `id_shop` = ' . $shopId - . ' AND `id_product` = ' . $productId - . ' AND `id_currency` = ' . $currencyId - . ' AND `id_country` = ' . $countryId - . ' AND `id_group` = ' . $groupId - . ' AND `id_product_attribute` = ' . $attributeId - . ' AND `date` <= \'' . $date . '\'' - . ' ORDER BY `date` DESC' - ); - if ($attributeId != 0 && $row == false) - { - $attributeId = 0; - $row = Db::getInstance()->getRow( - 'SELECT `price_tin`, `price_tex` ' - . ' FROM `' . _DB_PREFIX_ . 'gm_omniprice_history` ' - . ' WHERE `id_shop` = ' . $shopId - . ' AND `id_product` = ' . $productId - . ' AND `id_currency` = ' . $currencyId - . ' AND `id_country` = ' . $countryId - . ' AND `id_group` = ' . $groupId - . ' AND `id_product_attribute` = ' . $attributeId - . ' AND `date` <= \'' . $date . '\'' - . ' ORDER BY `date` DESC' - ); - } - if ($row) - { - $priceTin = $row['price_tin']; - if ($priceTin < $lowestPriceTin) - { - $lowestPriceTin = $priceTin; - } - $priceTex = $row['price_tex']; - if ($priceTex < $lowestPriceTex) - { - $lowestPriceTex = $priceTex; - $lowestDate = $date; - } - } - else - { - break; - } - } - if ($lowestPriceTex < INF) - { - return [ - 'price_tin' => $lowestPriceTin, - 'price_tex' => $lowestPriceTex, - 'date' => $lowestDate - ]; - } - else - { - return false; - } - } - - public function checkIfProductIsDiscounted($discountedIds, $productId, $attributeId) - { - if (Tools::isSubmit('init')) - { - return false; - } - foreach ($discountedIds as $item) - { - if (($item['id_product'] == $productId) && ($item['id_product_attribute'] == $attributeId)) - { - return true; - } - if (($item['id_product'] == $productId) && ($item['id_product_attribute'] == 0)) - { - return true; - } - } - return false; - } - - public function clearIndex($date) - { - return Db::getInstance()->delete('gm_omniprice_index', '`date` <= \'' . $date . '\''); - } - - public function addProductToIndex($shopId, $productId, $date) - { - Db::getInstance()->insert( - 'gm_omniprice_index', - [ - 'date' => $date, - 'id_shop' => $shopId, - 'id_product' => $productId - ] - ); - } - - public function getPreviousPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId) - { - return Db::getInstance()->getRow('SELECT `price_tin`, `is_specific_price` FROM `' . _DB_PREFIX_ . 'gm_omniprice_history`' - . ' WHERE `id_shop` = ' . $shopId . ' AND `id_product` = ' . $productId - . ' AND `id_currency` = ' . $currencyId . ' AND `id_country` = ' . $countryId - . ' AND `id_group` = ' . $groupId . ' AND `id_product_attribute` = ' . $attributeId - . ' AND `date` < \'' . $this->today . '\'' - . ' ORDER BY `date` DESC'); - } - - public function saveLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $priceTex, $priceTin, $date) - { - $this->deleteLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); - return Db::getInstance()->insert( - 'gm_omniprice_cache', - [ - 'id_shop' => $shopId, - 'id_product' => $productId, - 'id_currency' => $currencyId, - 'id_country' => $countryId, - 'id_group' => $groupId, - 'id_product_attribute' => $attributeId, - 'price_tex' => $priceTex, - 'price_tin' => $priceTin, - 'date' => $date - ] - ); - } - - public function deleteLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId) - { - return Db::getInstance()->delete( - 'gm_omniprice_cache', - '`id_shop` = ' . $shopId - . ' AND `id_product` = ' . $productId - . ' AND `id_product_attribute` = ' . $attributeId - . ' AND `id_currency` = ' . $currencyId - . ' AND `id_country` = ' . $countryId - . ' AND `id_group` = ' . $groupId - ); - } - - public function savePrice($date, $shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $priceTex, $priceTin, $onDiscount = false) - { - if (Tools::isSubmit('cache')) - { - $this->deleteTodaysPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); - } - Db::getInstance()->insert( - 'gm_omniprice_history', - [ - 'date' => $date, - 'id_shop' => $shopId, - 'id_product' => $productId, - 'id_currency' => $currencyId, - 'id_country' => $countryId, - 'id_group' => $groupId, - 'id_product_attribute' => $attributeId, - 'price_tex' => $priceTex, - 'price_tin' => $priceTin, - 'is_specific_price' => $onDiscount - ] - ); - } - - public function deleteTodaysPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId) - { - return Db::getInstance()->delete( - 'gm_omniprice_history', - '`id_shop` = ' . $shopId - . ' AND `id_product` = ' . $productId - . ' AND `id_currency` = ' . $currencyId - . ' AND `id_country` = ' . $countryId - . ' AND `id_group` = ' . $groupId - . ' AND `id_product_attribute` = ' . $attributeId - . ' AND `date` = \'' . $this->today . '\'' - ); - } - - public function getGroupIds($shopId) - { - $ids = [$this->defaultGroupId]; - if (!Group::isFeatureActive()) - { - return $ids; - } - $query = 'SELECT `gs`.`id_group` - FROM `' . _DB_PREFIX_ . 'group_shop` `gs` - WHERE `gs`.`id_shop` = ' . $shopId; - $res = Db::getInstance()->executeS($query); - if ($res) - { - foreach ($res as $row) - { - if (($row['id_group'] != $this->defaultGroupId) && !in_array($row['id_group'], $this->ignoredGroups)) - { - $ids[] = (int) $row['id_group']; - } - } - } - return $ids; - } - - public function getCountryIds($shopId) - { - $ids = [$this->defaultCountryId]; - if (Shop::isFeatureActive()) - { - $ids = [Configuration::get('PS_COUNTRY_DEFAULT', null, null, $shopId)]; - } - if (!$this->ignoreCountries) - { - $query = 'SELECT `cs`.`id_country` - FROM `' . _DB_PREFIX_ . 'country_shop` `cs` - LEFT JOIN `' . _DB_PREFIX_ . 'country` `c` ON (`cs`.`id_country` = `c`.`id_country`) - WHERE `cs`.`id_shop` = ' . $shopId - . ' AND `c`.`active` = 1'; - $res = Db::getInstance()->executeS($query); - if ($res) - { - foreach ($res as $row) - { - if (!in_array($row['id_country'], $ids)) - { - if ($this->ignoreNonEuCountries) - { - $country = new Country($row['id_country']); - if (in_array($country->iso_code, $this->euCountries)) - { - $ids[] = (int) $row['id_country']; - } - } - else - { - $ids[] = (int) $row['id_country']; - } - } - } - } - } - return $ids; - } - - public function getCurrencyIds($shopId) - { - $ids = []; - $query = 'SELECT `cs`.`id_currency` - FROM `' . _DB_PREFIX_ . 'currency` c - LEFT JOIN `' . _DB_PREFIX_ . 'currency_shop` cs ON (cs.`id_currency` = c.`id_currency`) - WHERE cs.`id_shop` = ' . (int) $shopId - . ' AND c.`active` = 1'; - $currencies = Db::getInstance()->executeS($query); - foreach ($currencies as $currency) - { - $ids[] = (int) $currency['id_currency']; - } - return $ids; - } - - public function getProductIds($shopId) - { - $productIds = []; - $query = 'SELECT `ps`.`id_product` ' - . ' FROM `' . _DB_PREFIX_ . 'product_shop` `ps`' - . ' WHERE `ps`.`id_product` NOT IN ' - . ' (SELECT `id_product` FROM `' . _DB_PREFIX_ . 'gm_omniprice_index`' - . ' WHERE `date` = \'' . $this->today . '\' AND `id_shop` = ' . $shopId . ')' - . ($this->indexInactive ? ' ' : ' AND `ps`.`active` = 1 ') - . ' AND `ps`.`id_shop` = ' . $shopId . ' ' - . ' ORDER BY `ps`.`id_product` ASC LIMIT ' . $this->batchSize; - - $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query, true, false); - if ($res) - { - foreach ($res as $row) - { - $productIds[] = (int) $row['id_product']; - } - } - return $productIds; - } - - public function getProductAttributeMap($shopId) - { - $map = []; - if (!$this->ignoreCombinations) - { - $query = 'SELECT `id_product`, `id_product_attribute` ' - . ' FROM `' . _DB_PREFIX_ . 'product_attribute_shop` ' - . ' WHERE `id_shop` = ' . $shopId; - $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); - if ($res) - { - foreach ($res as $row) - { - $map[(int) $row['id_product']][] = (int) $row['id_product_attribute']; - } - } - } - return $map; - } - - public function getShopsIds() - { - $list = []; - $sql = 'SELECT `id_shop` FROM `' . _DB_PREFIX_ . 'shop` - WHERE `active` = 1 AND `deleted` = 0'; - $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); - if ($res) - { - foreach ($res as $row) - { - $list[] = (int) $row['id_shop']; - } - } - return $list; - } - - public function hookDisplayProductPriceBlock($hookParams) - { - if (($hookParams['type'] == 'after_price') && ((isset($hookParams['product']->id)) || (isset($hookParams['product']['id_product'])) || Tools::isSubmit('id_product')) ) - { - if (isset($hookParams['product']->id)) - { - $productId = (int) $hookParams['product']->id; - } - else if (isset($hookParams['product']['id_product'])) - { - $productId = (int) $hookParams['product']['id_product']; - } - else - { - $productId = (int) Tools::getValue('id_product'); - } - $showRealDiscount = $this->showRealDiscount; - if (Tools::isSubmit('omnipricetest')) - { - $lowestCachedPrice = [ - 'formatted' => Tools::getValue('omnipricetest'), - 'raw' => 1 - ]; - $showRealDiscount = false; - } - else - { - $params = $this->getCurrentParams($productId); - if (Tools::isSubmit('omnidebug')) - { - var_export($params); - echo $this->context->country->iso_code; - } - if ($this->ignoreNonEuCountries) - { - if (!in_array($this->context->country->iso_code, $this->euCountries)) - { + if (!parent::uninstall()) { return false; - } } - $lowestCachedPrice = $this->getLowestCachedPrice($params); - } - $realDiscount = ''; - if ($showRealDiscount && $lowestCachedPrice && isset($hookParams['product']['price_amount'])) - { - $currentPrice = $hookParams['product']['price_amount']; - $previousPrice = $lowestCachedPrice['raw']; - $realDiscount = $this->calculateRealDisount($currentPrice, $previousPrice); - } - if (!$lowestCachedPrice) - { - //may have a promotion for an individual combination - if (Tools::version_compare(_PS_VERSION_, '1.7.0.0', '<') && $this->hasAttributePrices($productId)) - { - $lowestCachedPrice = [ - 'formatted' => '---', - 'raw' => '0' - ]; + 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; } - } - if ($lowestCachedPrice) - { - $this->context->smarty->assign( - [ - 'gm_omniprice_lowest' => $lowestCachedPrice['formatted'], - 'gm_omniprice_lowest_raw' => $lowestCachedPrice['raw'], - 'gm_omniprice_days' => $this->daysBack, - 'gm_omniprice_color' => $this->textColor, - 'gm_omniprice_price_color' => $this->priceColor, - 'gm_omniprice_background' => $this->backgroundColor, - 'gm_omniprice_show_real_discount' => $showRealDiscount, - 'gm_omniprice_real_discount' => $realDiscount - ] - ); - return $this->display(__FILE__, 'price.tpl'); - } - } - } - - public function calculateRealDisount($currentPrice, $previousPrice) - { - if (!$currentPrice || !$previousPrice) - { - return false; - } - $realDiscount = '0%'; - if ($currentPrice < $previousPrice) - { - $discount = round((1 - $currentPrice / $previousPrice) * 100); - $realDiscount = '-' . $discount . '%'; - } - if ($currentPrice > $previousPrice) - { - $discount = round(($currentPrice / $previousPrice - 1) * 100); - $realDiscount = '+' . $discount . '%'; - } - return $realDiscount; - } - - public function getLowestCachedPrice($params) - { - $displayMethod = Group::getPriceDisplayMethod($params['id_group']); - if ($displayMethod) - { - $field = '`price_tex`'; - } - else - { - $field = '`price_tin`'; - } - $price = Db::getInstance()->getValue( - 'SELECT ' . $field - . ' FROM `' . _DB_PREFIX_ . 'gm_omniprice_cache`' - . ' WHERE `id_shop` = ' . $params['id_shop'] - . ' AND `id_product` = ' . $params['id_product'] - . ' AND `id_product_attribute` = ' . $params['id_product_attribute'] - . ' AND `id_currency` = ' . $params['id_currency'] - . ' AND `id_country` = ' . $params['id_country'] - . ' AND `id_group` = ' . $params['id_group'] - ); - if ($price) - { - return [ - 'formatted' => $this->getFormattedPrice($price), - 'raw' => $price - ]; - } - else if ($params['id_product_attribute'] != 0) - { - $price = Db::getInstance()->getValue( - 'SELECT ' . $field - . ' FROM `' . _DB_PREFIX_ . 'gm_omniprice_cache`' - . ' WHERE `id_shop` = ' . $params['id_shop'] - . ' AND `id_product` = ' . $params['id_product'] - . ' AND `id_product_attribute` = 0' - . ' AND `id_currency` = ' . $params['id_currency'] - . ' AND `id_country` = ' . $params['id_country'] - . ' AND `id_group` = ' . $params['id_group'] - ); - if ($price) - { - return [ - 'formatted' => $this->getFormattedPrice($price), - 'raw' => $price - ]; - } - } - if (!$price) - { - if ($this->showIfNotEnoughHistoricalData) - { - return $this->getLatestHistoricalPrice($params); - } - } - return false; - } - - protected function getLatestHistoricalPrice($params) - { - $displayMethod = Group::getPriceDisplayMethod($params['id_group']); - if ($displayMethod) - { - $field = '`price_tex`'; - $arrayField = 'price_tex'; - } - else - { - $field = '`price_tin`'; - $arrayField = 'price_tin'; - } - $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` = ' . $params['id_product_attribute'] - ); - if ((count($prices) == 1) && ($prices[0]['is_specific_price'])) - { - return - [ - 'formatted' => $this->getFormattedPrice($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' - ); - if ((count($prices) == 1) && ($prices[0]['is_specific_price'])) - { - return - [ - 'formatted' => $this->getFormattedPrice($prices[0][$arrayField]), - 'raw' => $prices[0][$arrayField] - ]; - } - } - 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($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($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) + protected function uninstallDb() { - $params['id_product_attribute'] = 0; + $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; } - 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)) + public function getContent() { - return $this->getAllProductIdsFromShop($shopId); + $content = ''; + $content .= $this->postProcess(); + $content .= $this->displayGreenMouseModulesPanel(); + $content .= $this->displayForm(); + $content .= $this->displayInfo(); + $content .= $this->displayInformationPanel(); + return $content; } - $beginning = null; - $ending = null; - if (Tools::version_compare(_PS_VERSION_, '1.6.1.10', '<=')) + + protected function postProcess() { - $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() - { - $output = '
' - . '
' - . $this->l('Gathering price history') - . '
'; - $indexUrl = $this->context->link->getModuleLink( - $this->name, - 'cron', - [ - 'action' => 'index', - 'token' => $this->token - ] - ); - $output .= ''; - $output .= '
'; - $output .= '
' - . '
' - . $this->l('Cleaning old price history') - . '
'; - $cleanupUrl = $this->context->link->getModuleLink( - $this->name, - 'cron', - [ - 'action' => 'cleanup', - 'token' => $this->token - ] - ); - $output .= ''; - $output .= '
'; - return $output; - } - - protected function displayInformationPanel() - { - $output = '
' - . '
' - . $this->l('Information') - . '
'; - if (!defined('_TB_VERSION_')) - { //TB has a nasty bug here - $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 .= '
'; - return $output; - } - - protected function countActiveCurrencies() - { - return (int) Db::getInstance()->getValue('SELECT COUNT(`id_currency`) FROM `' . _DB_PREFIX_ . 'currency` WHERE `active` = 1'); - } - - protected function countActiveCountries() - { - return (int) Db::getInstance()->getValue('SELECT COUNT(`id_country`) FROM `' . _DB_PREFIX_ . 'country` WHERE `active` = 1'); - } - - protected function countStoredPrices() - { - return (int) Db::getInstance()->getValue('SELECT COUNT(`id_product`) FROM `' . _DB_PREFIX_ . 'gm_omniprice_history`'); - } - - protected function getCombinationsPriceImpactsInfo() - { - $query = 'SELECT `id_product` FROM `' . _DB_PREFIX_ . 'product_attribute` WHERE `price` != 0'; - $res = Db::getInstance()->getValue($query); - if ($res) - { - return true; - } - else - { - return false; - } - } - - protected function getCombinationsDiscountsInfo() - { - $query = 'SELECT `id_product` FROM `' . _DB_PREFIX_ . 'specific_price` WHERE `id_product_attribute` > 0'; - $res = Db::getInstance()->getValue($query); - if ($res) - { - return true; - } - else - { - return false; - } - } - - protected function getGroupNames() - { - $langId = $this->context->language->id; - $query = 'SELECT `id_group`, `name` FROM `' . _DB_PREFIX_ . 'group_lang` WHERE `id_lang` = ' . $langId; - $res = Db::getInstance()->executeS($query); - if ($res) - { - foreach ($res as $row) - { - $this->groupNames[(int) $row['id_group']] = $row['name']; - } - } - } - - protected function findGroupsToSafelyIgnore() - { - $groups = $this->findEmptyGroups(true); - $guestGroupId = Configuration::get('PS_GUEST_GROUP'); - $unidentifiedGroupId = Configuration::get('PS_UNIDENTIFIED_GROUP'); - $groups[] = $guestGroupId; - $groups[] = $unidentifiedGroupId; - $groups = array_unique($groups); - sort($groups); - $ignoredGroups = []; - foreach ($groups as $groupId) - { - if ($groupId != $this->defaultGroupId) - { - $ignoredGroups[] = $groupId; - } - } - return $ignoredGroups; - } - - protected function findEmptyGroups($returnIds = false) - { - $emptyGroups = []; - $emptyIds = []; - $res = Group::getGroups($this->context->language->id); - foreach ($res as $row) - { - $group = new Group((int) $row['id_group']); - $customerCount = $group->getCustomers(true); - if ($customerCount < 1) - { - $emptyGroups[] = $row['name']; - $emptyIds[] = $row['id_group']; - } - } - if ($returnIds) - { - return $emptyIds; - } - if (!count($emptyGroups)) - { - return [$this->l('None')]; - } - return $emptyGroups; - } - - protected function findGroupsWithSpecifiPriceRules() - { - $groupIds = []; - $query = 'SELECT `id_group` FROM `' . _DB_PREFIX_ . 'specific_price_rule` WHERE `id_group` > 0'; - $res = Db::getInstance()->executes($query); - if ($res) - { - foreach ($res as $row) - { - $groupIds[] = (int) $row['id_group']; - } - } - $groupIds = array_unique($groupIds); - sort($groupIds); - return $this->getGroupNamesForIds($groupIds); - } - - protected function findGroupsWithSpecificPrices() - { - $groupIds = []; - $query = 'SELECT `id_group` FROM `' . _DB_PREFIX_ . 'specific_price` WHERE `id_group` > 0'; - $res = Db::getInstance()->executes($query); - if ($res) - { - foreach ($res as $row) - { - $groupIds[] = (int) $row['id_group']; - } - } - $groupIds = array_unique($groupIds); - sort($groupIds); - return $this->getGroupNamesForIds($groupIds); - } - - protected function findGroupsWithGroupReduction() - { - $groupIds = []; - $query = 'SELECT `id_group` FROM `' . _DB_PREFIX_ . 'group` WHERE `reduction` > 0'; - $res = Db::getInstance()->executes($query); - if ($res) - { - foreach ($res as $row) - { - $groupIds[] = (int) $row['id_group']; - } - } - $query = 'SELECT `id_group` FROM `' . _DB_PREFIX_ . 'group_reduction` WHERE `reduction` > 0'; - $res = Db::getInstance()->executes($query); - if ($res) - { - foreach ($res as $row) - { - $groupIds[] = (int) $row['id_group']; - } - } - $groupIds = array_unique($groupIds); - sort($groupIds); - return $this->getGroupNamesForIds($groupIds); - } - - protected function getGroupNamesForIds($groupIds) - { - if (!count($groupIds)) - { - return [$this->l('None')]; - } - $names = []; - $this->getGroupNames(); - foreach ($groupIds as $groupId) - { - $names[] = $this->groupNames[$groupId]; - } - return $names; - } - - public function hookActionProductUpdate($params) - { - $productId = $params['id_product']; - $this->reindexProduct($productId); - } - - public function hookActionObjectSpecificPriceAddAfter($params) - { - $sp = $params['object']; - if ($sp->id_product) - { - $this->reindexProduct($sp->id_product); - } - } - - public function hookActionObjectSpecificPriceUpdateAfter($params) - { - $sp = $params['object']; - if ($sp->id_product) - { - $this->reindexProduct($sp->id_product); - } - } - - public function hookActionObjectSpecificPriceDeleteAfter($params) - { - $sp = $params['object']; - if ($sp->id_product) - { - $this->reindexProduct($sp->id_product); - } - } - - public function reindexProduct($productId) - { - $this->removeProductFromTodaysIndex($productId); - $this->removeProductFromTodaysHistory($productId); - if ($this->reindexOnSave) - { - $this->savePrices(false, $productId); - } - } - - public function resetIndex() - { - Db::getInstance()->delete('gm_omniprice_index'); - Db::getInstance()->delete('gm_omniprice_history', '`date` = \'' . $this->today . '\''); - } - - public function removeProductFromTodaysIndex($productId) - { - Db::getInstance()->delete('gm_omniprice_index', '`id_product` = ' . $productId . ' AND `date` = \'' . $this->today . '\''); - } - - public function removeProductFromTodaysHistory($productId) - { - Db::getInstance()->delete('gm_omniprice_history', '`id_product` = ' . $productId . ' AND `date` = \'' . $this->today . '\''); - } - - public function hookDisplayHeader($params) - { - if (Tools::isSubmit('id_product')) - { - $this->context->controller->addCSS($this->_path . 'views/css/gm_omniprice.css', 'all'); - if (!$this->ignoreCombinations) - { - $params = $this->getCurrentParams((int) Tools::getValue('id_product')); - $prices = $this->getLowestCachedPricesForCombinations($params); - if (count($prices) > 0) - { - $this->context->controller->addJS($this->_path . 'views/js/gm_omniprice.js'); - Media::addJsDef(['gm_omniprice_attr_prices' => $prices]); - } - } - } - } - - public function cleanUp($verbose = false) - { - $output = ''; - //general cleanup - if (Tools::issubmit('zero')) - { - Db::getInstance()->delete('gm_omniprice_history', '`price_tin` < 0.001'); - Db::getInstance()->delete('gm_omniprice_cache', '`price_tin` < 0.001'); - } - Db::getInstance()->delete('gm_omniprice_history', '`id_product` NOT IN (SELECT `id_product` FROM `' . _DB_PREFIX_ . 'product`)'); - Db::getInstance()->delete('gm_omniprice_cache', '`id_product` NOT IN (SELECT `id_product` FROM `' . _DB_PREFIX_ . 'product`)'); - Db::getInstance()->delete( - 'gm_omniprice_history', - '`id_product_attribute` > 0 AND `id_product_attribute` NOT IN (SELECT `id_product_attribute` FROM `' . _DB_PREFIX_ . 'product_attribute`)' - ); - Db::getInstance()->delete( - 'gm_omniprice_cache', - '`id_product_attribute` > 0 AND `id_product_attribute` NOT IN (SELECT `id_product_attribute` FROM `' . _DB_PREFIX_ . 'product_attribute`)' - ); - Db::getInstance()->delete('gm_omniprice_history', '`id_shop` NOT IN (SELECT `id_shop` FROM `' . _DB_PREFIX_ . 'shop`)'); - Db::getInstance()->delete('gm_omniprice_cache', '`id_shop` NOT IN (SELECT `id_shop` FROM `' . _DB_PREFIX_ . 'shop`)'); - Db::getInstance()->delete('gm_omniprice_history', '`id_currency` NOT IN (SELECT `id_currency` FROM `' . _DB_PREFIX_ . 'currency`)'); - Db::getInstance()->delete('gm_omniprice_cache', '`id_currency` NOT IN (SELECT `id_currency` FROM `' . _DB_PREFIX_ . 'currency`)'); - Db::getInstance()->delete('gm_omniprice_history', '`id_group` NOT IN (SELECT `id_group` FROM `' . _DB_PREFIX_ . 'group`)'); - Db::getInstance()->delete('gm_omniprice_cache', '`id_group` NOT IN (SELECT `id_group` FROM `' . _DB_PREFIX_ . 'group`)'); - Db::getInstance()->delete('gm_omniprice_history', '`id_country` NOT IN (SELECT `id_country` FROM `' . _DB_PREFIX_ . 'country` WHERE `active` = 1)'); - Db::getInstance()->delete('gm_omniprice_cache', '`id_country` NOT IN (SELECT `id_country` FROM `' . _DB_PREFIX_ . 'country` WHERE `active` = 1)'); - if ($this->ignoreCountries) - { - if (Shop::isFeatureActive()) - { - //for the future - } - else - { - Db::getInstance()->delete('gm_omniprice_history', '`id_country` != ' . $this->defaultCountryId); - Db::getInstance()->delete('gm_omniprice_cache', '`id_country` != ' . $this->defaultCountryId); - } - } - foreach ($this->ignoredGroups as $ignoredGroupId) - { - if ($ignoredGroupId && ((int) $ignoredGroupId !== (int) $this->defaultGroupId)) - { - Db::getInstance()->delete('gm_omniprice_history', '`id_group` = ' . $ignoredGroupId); - Db::getInstance()->delete('gm_omniprice_cache', '`id_group` = ' . $ignoredGroupId); - } - } - $date = date("Y-m-d", strtotime("-" . $this->daysBack . " days")); - $output .= $this->l('Period') . ': ' . $this->daysBack . ' (' . $date . ')
'; - $shopIds = $this->getShopsIds(); - foreach ($shopIds as $shopId) - { - $currencyIds = $this->getCurrencyIds($shopId); - $countryIds = $this->getCountryIds($shopId); - $groupIds = $this->getGroupIds($shopId); - $productIds = $this->getProductIdsInHistory($shopId); - foreach ($currencyIds as $currencyId) - { - foreach ($countryIds as $countryId) - { - foreach ($groupIds as $groupId) - { - foreach ($productIds as $productId) - { - $query = 'SELECT `date`, `id_product`, `id_product_attribute` FROM `' . _DB_PREFIX_ . 'gm_omniprice_history` ' - . ' WHERE `id_shop` = ' . $shopId . ' AND `id_product` = ' . $productId . ' AND `id_currency` = ' . $currencyId . - ' AND `id_country` = ' . $countryId . ' AND `id_group` = ' . $groupId . ' ORDER BY `date` ASC'; - $res = Db::getInstance()->executeS($query); - $datesMap = []; - if ($res) - { - foreach ($res as $row) - { - $day = $row['date']; - $productId = $row['id_product']; - $attributeId = $row['id_product_attribute']; - if ($day < $date) - { - $datesMap[$productId][$attributeId][] = $day; - } - } - foreach ($datesMap as $productId => $dateItem) - { - foreach ($dateItem as $attributeId => $dates) - { - $output .= "Product ID {$productId}, attribute ID: {$attributeId}
"; - $datesCount = count($dates); - if ($datesCount > 2) - { - for ($i = 0; $i < $datesCount - 2; $i++) - { - $output .= ' ' . $dates[$i] . ' ' . $this->l('this price may be deleted') . '
'; - $where = '`id_shop` = ' . $shopId . ' AND `id_currency` = ' . $currencyId . - ' AND `id_country` = ' . $countryId . ' AND `id_group` = ' . $groupId; - $where .= ' AND `id_product` = ' . $productId . ' AND `id_product_attribute` = ' . $attributeId; - $where .= ' AND `date` = \'' . $dates[$i] . '\''; - Db::getInstance()->delete('gm_omniprice_history', $where); - } - } - $output .= ' ' . $dates[$datesCount - 1] . ' ' . $this->l('this price is still needed') . '
'; - } - } - } + $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; } - if ($verbose) + public function displayForm() { - echo '
';
-      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 = '';
-    $output .= '';
-    $output .= '';
-    foreach ($columns as $columnHeader)
-    {
-      $output .= '';
-    }
-    $output .= '';
-    $output .= '';
-    foreach ($data as $row)
-    {
-      $output .= '';
-      foreach ($columns as $key)
-      {
-        $output .= '';
-      }
-      $output .= '';
-    }
-    $output .= '
' . $columnHeader . '
' . $row[$key] . '
'; - return $output; - } - - public function hookActionGetProductPropertiesAfter($params) - { - return; - $product = &$params['product']; - $sp = $product['specific_prices']; - //var_export($product); - $sp['reduction'] = (string) (rand(0, 10) / 100); - $product['specific_prices'] = $sp; - } - - public function fillMissingCache($verbose = false) - { - $output = ''; - $query = 'SELECT * FROM `' . _DB_PREFIX_ . 'gm_omniprice_history` ' - . ' WHERE `is_specific_price` = 1 AND `id_product` IN (SELECT `id_product` FROM `' . _DB_PREFIX_ . 'product` WHERE `active` = 1)' - . ' ORDER BY `date` DESC '; - $res = Db::getInstance()->executeS($query); - if ($res) - { - foreach ($res as $row) - { - $lowestPrice = $this->getLowestCachedPrice($row); - if ($lowestPrice === false) - { - $shopId = (int) $row['id_shop']; - $productId = (int) $row['id_product']; - $groupId = (int) $row['id_group']; - $currencyId = (int) $row['id_currency']; - $countryId = (int) $row['id_country']; - $attributeId = (int) $row['id_product_attribute']; - $output .= var_export($row, true) . '
'; - $output .= ' - no lowest price!
'; - $lastChangeDate = $row['date']; - $output .= ' Look for the lowest price before ' . $lastChangeDate . '
'; - $now = time(); - $your_date = strtotime($row['date']); - $datediff = $now - $your_date; - $daysOffset = floor($datediff / (60 * 60 * 24)); - $output .= ' days offset: ' . $daysOffset . '
'; - $lowestPrices = $this->getLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $daysOffset); - if ($lowestPrices) - { - $output .= ' found price: ' . $lowestPrices['price_tin'] . ' (' . $lowestPrices['price_tex'] . ')
'; - $this->saveLowestPrice( - $shopId, - $productId, - $currencyId, - $countryId, - $groupId, - $attributeId, - $lowestPrices['price_tex'], - $lowestPrices['price_tin'], - $lowestPrices['date'] + $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') ); - } } - } - } - if ($verbose) - { - echo $output; - } - } + $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') + ) + ), + ); - public function getActiveMap() - { - if ($this->activeMap == null) - { - $query = 'SELECT `id_shop`, `id_product`, `active` FROM `' . _DB_PREFIX_ . 'product_shop`'; - $res = Db::getInstance()->executeS($query); - if ($res) - { - foreach ($res as $row) - { - $this->activeMap[(int) $row['id_shop']][(int) $row['id_product']] = (int) $row['active']; + $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); } - } - } - return $this->activeMap; - } + $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; - public function productIsActive($productId, $shopId) - { - $activeMap = $this->getActiveMap(); - if (isset($activeMap[$shopId][$productId])) + return $helper->generateForm(array($fieldsForm)); + } + + public function savePrices($verbose = false, $productId = null) { - return ($activeMap[$shopId][$productId] == 1); - } - return false; - } + $this->clearIndex($this->yesterday); + $output = ''; + $usetax = true; + if (Tax::excludeTaxeOption()) { + $usetax = false; + } + $basicPrices = []; + $stateId = 0; + $zipcode = ''; - public function getCostPriceMap() - { - $map = []; - $query = 'SELECT `id_product`, `id_shop`, `wholesale_price` FROM `' . _DB_PREFIX_ . 'product_shop` WHERE `wholesale_price` > 0'; - $res = Db::getInstance()->executeS($query); - if ($res) + $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 = [1];//$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('Shop ID:').' '.$shopId.'

'; + if (count($productIds) < 1) { + $output .= '

'.$this->l('All products indexed').'

'; + continue; + } else { + $output .= '

'.$this->l('Not finished yet, please run me again').'

'; + } + $output .= '' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .''; + $counter = 0; + foreach ($currencyIds as $currencyId) { + foreach ($countryIds as $countryId) { + foreach ($groupIds as $groupId) { + $discountedIds = $this->getDiscountedProductIds($shopId, $currencyId, $countryId, $groupId); + foreach ($productIds as $productId) { + $attributeId = 0; + $basicKey = $shopId.'-'.$productId.'-'.$attributeId.'-'.$currencyId.'-'.$countryId.'-'.$groupId; + $priceTin = Product::priceCalculation( + $shopId, $productId, $attributeId, $countryId, $stateId, $zipcode, $currencyId, $groupId, 1, //quantity + $usetax, 6, //decimals + false, //only_reduc + $useReduction, //use_reduc + true, //with_ecotax + $specificPriceOutput, true //use_group_reduction + ); + $priceTin = sprintf("%.6f", $priceTin); + $basicPrices[$basicKey] = $priceTin; + $priceTex = $priceTin; + if ($usetax) { + $priceTex = Product::priceCalculation( + $shopId, $productId, $attributeId, $countryId, $stateId, $zipcode, $currencyId, $groupId, 1, //quantity + false, //no tax + 6, //decimals + false, //only_reduc + $useReduction, //use_reduc + true, //with_ecotax + $specificPriceOutput, true //use_group_reduction + ); + } + $previously = $this->getPreviousPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); + if ($previously) { + $previousPrice = (float) $previously['price_tin']; + $previousDiscount = (bool) $previously['is_specific_price']; + } else { + $previousPrice = 0; + $previousDiscount = false; + } + if (Tools::isSubmit('init')) { + $onDiscount = false; + } else { + if (Module::isEnabled('groupinc')) { + $onDiscount = $this->checkIfProductIsDiscounted($discountedIds, $productId, $attributeId) || (is_array($specificPriceOutput) + && (count($specificPriceOutput) > 1)); //groupinc module support + } else { + $onDiscount = $this->checkIfProductIsDiscounted($discountedIds, $productId, $attributeId); + } + } + $onDiscountText = ($onDiscount ? $this->l('Yes') : $this->l('No')); + //check if product is sold below cost price + if ($this->skipBelowCost) { + if ($this->checkIfProductIsSoldBelowCost($priceTex, $costPriceMap, $rates, $shopId, $productId, $attributeId, + $currencyId)) { + $onDiscount = false; + $onDiscountText = $this->l('Below cost'); + } + } + $output .= '' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .''; + $priceIsCorrect = ($priceTin > 0); + $priceChanged = (abs($previousPrice - $priceTin) > 0.01); + $discountChanged = ($previousDiscount != $onDiscount); + if (Tools::isSubmit('cache')) { + $discountChanged = true; + } + if ($priceIsCorrect && ($priceChanged || $discountChanged)) { + $output .= ''; + $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 .= ''; + $this->saveLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, + $lowestPrices['price_tex'], $lowestPrices['price_tin'], $lowestPrices['date']); + } else { + $output .= ''; + } + } else { + $output .= ''; + } + } else { + $output .= ''; + $output .= ''; + } + if (!$onDiscount) { + $this->deleteLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); + } + $output .= ''; + //attributes + if (array_key_exists($productId, $attributesMap)) { + foreach ($attributesMap[$productId] as $attributeId) { + $priceTin = Product::priceCalculation( + $shopId, $productId, $attributeId, $countryId, $stateId, $zipcode, $currencyId, $groupId, 1, //quantity + $usetax, 6, //decimals + false, //only_reduc + $useReduction, //use_reduc + true, //with_ecotax + $specificPriceOutput, true //use_group_reduction + ); + $priceTin = sprintf("%.6f", $priceTin); + $priceTex = $priceTin; + if ($usetax) { + $priceTex = Product::priceCalculation( + $shopId, $productId, $attributeId, $countryId, $stateId, $zipcode, $currencyId, $groupId, + 1, //quantity + false, //no tax + 6, //decimals + false, //only_reduc + $useReduction, //use_reduc + true, //with_ecotax + $specificPriceOutput, true //use_group_reduction + ); + } + if (abs($priceTin - $basicPrices[$basicKey]) > 0.01) { + $previously = $this->getPreviousPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); + if ($previously) { + $previousPrice = (float) $previously['price_tin']; + $previousDiscount = (bool) $previously['is_specific_price']; + } else { + $previousPrice = 0; + $previousDiscount = false; + } + if (Tools::isSubmit('init')) { + $onDiscount = false; + } else { + if (Module::isEnabled('groupinc')) { + $onDiscount = $this->checkIfProductIsDiscounted($discountedIds, $productId, $attributeId) || (is_array($specificPriceOutput) + && (count($specificPriceOutput) > 1)); //groupinc module support + } else { + $onDiscount = $this->checkIfProductIsDiscounted($discountedIds, $productId, $attributeId); + } + } + $onDiscountText = ($onDiscount ? $this->l('Yes') : $this->l('No')); + if ($this->skipBelowCost) { + if ($this->checkIfProductIsSoldBelowCost($priceTex, $costPriceMap, $rates, $shopId, $productId, + $attributeId, $currencyId)) { + $onDiscount = false; + $onDiscountText = $this->l('Below cost'); + } + } + $output .= '' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .'' + .''; + $priceIsCorrect = ($priceTin > 0); + $priceChanged = (abs($previousPrice - $priceTin) > 0.01); + $discountChanged = ($previousDiscount != $onDiscount); + if (Tools::isSubmit('cache')) { + $discountChanged = true; + } + if ($priceIsCorrect && ($priceChanged || $discountChanged)) { + $output .= ''; + $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 .= ''; + $this->saveLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, + $lowestPrices['price_tex'], $lowestPrices['price_tin'], $lowestPrices['date']); + } else { + $output .= ''; + } + } else { + $output .= ''; + } + } else { + $output .= ''; + $output .= ''; + } + 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 .= '
'.$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.''.$this->l('Save').''.$lowestPrices['price_tin'].' ('.$lowestPrices['price_tex'].')'.$this->l('Unknown').''.$this->l('Not applicable').''.$this->l('No change').''.$this->l('No change').'
'.++$counter.''.$productId.''.$attributeId.''.$countryId.''.$currencyId.''.$groupId.''.$priceTin.' ('.$priceTex.') '.$previousPrice.''.$onDiscountText.''.$this->l('Save').''.$lowestPrices['price_tin'].' ('.$lowestPrices['price_tex'].')'.$this->l('Unknown').''.$this->l('Not applicable').''.$this->l('No change').''.$this->l('No change').'
'; + } + if ($verbose) { + echo $output; + } + return true; + } + + public function getLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $daysOffset = 0) { - foreach ($res as $row) - { - $shopId = (int) $row['id_shop']; - $productId = (int) $row['id_product']; - $costPrice = $row['wholesale_price']; - $map[$shopId][$productId][0] = $costPrice; - } + $lowestPriceTin = INF; + $lowestPriceTex = INF; + $lowestDate = '0000-00-00'; + for ($d = 1; $d <= $this->daysBack; $d++) { + $days = $d + $daysOffset; + $date = date('Y-m-d', strtotime("-$days days")); + $row = Db::getInstance()->getRow('SELECT `price_tin`, `price_tex` ' + .' FROM `'._DB_PREFIX_.'gm_omniprice_history` ' + .' WHERE `id_shop` = '.$shopId + .' AND `id_product` = '.$productId + .' AND `id_currency` = '.$currencyId + .' AND `id_country` = '.$countryId + .' AND `id_group` = '.$groupId + .' AND `id_product_attribute` = '.$attributeId + .' AND `date` <= \''.$date.'\'' + .' ORDER BY `date` DESC' + ); + if ($attributeId != 0 && $row == false) { + $attributeId = 0; + $row = Db::getInstance()->getRow('SELECT `price_tin`, `price_tex` ' + .' FROM `'._DB_PREFIX_.'gm_omniprice_history` ' + .' WHERE `id_shop` = '.$shopId + .' AND `id_product` = '.$productId + .' AND `id_currency` = '.$currencyId + .' AND `id_country` = '.$countryId + .' AND `id_group` = '.$groupId + .' AND `id_product_attribute` = '.$attributeId + .' AND `date` <= \''.$date.'\'' + .' ORDER BY `date` DESC' + ); + } + if ($row) { + $priceTin = $row['price_tin']; + if ($priceTin < $lowestPriceTin) { + $lowestPriceTin = $priceTin; + } + $priceTex = $row['price_tex']; + if ($priceTex < $lowestPriceTex) { + $lowestPriceTex = $priceTex; + $lowestDate = $date; + } + } else { + break; + } + } + if ($lowestPriceTex < INF) { + return [ + 'price_tin' => $lowestPriceTin, + 'price_tex' => $lowestPriceTex, + 'date' => $lowestDate + ]; + } else { + return false; + } } - $query = 'SELECT `id_product`, `id_product_attribute`, `id_shop`, `wholesale_price` FROM `' . _DB_PREFIX_ . 'product_attribute_shop` WHERE `wholesale_price` > 0'; - $res = Db::getInstance()->executeS($query); - if ($res) + public function checkIfProductIsDiscounted($discountedIds, $productId, $attributeId) { - foreach ($res as $row) - { - $shopId = (int) $row['id_shop']; - $productId = (int) $row['id_product']; - $attributeId = (int) $row['id_product_attribute']; - $costPrice = $row['wholesale_price']; - $map[$shopId][$productId][$attributeId] = $costPrice; - } + if (Tools::isSubmit('init')) { + return false; + } + foreach ($discountedIds as $item) { + if (($item['id_product'] == $productId) && ($item['id_product_attribute'] == $attributeId)) { + return true; + } + if (($item['id_product'] == $productId) && ($item['id_product_attribute'] == 0)) { + return true; + } + } + return false; } - return $map; - } - public function getConversionRates() - { - $rates = []; - $currencies = Db::getInstance()->executeS(' + public function clearIndex($date) + { + return Db::getInstance()->delete('gm_omniprice_index', '`date` <= \''.$date.'\''); + } + + public function addProductToIndex($shopId, $productId, $date) + { + Db::getInstance()->insert('gm_omniprice_index', + [ + 'date' => $date, + 'id_shop' => $shopId, + 'id_product' => $productId + ]); + } + + public function getPreviousPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId) + { + return Db::getInstance()->getRow('SELECT `price_tin`, `is_specific_price` FROM `'._DB_PREFIX_.'gm_omniprice_history`' + .' WHERE `id_shop` = '.$shopId.' AND `id_product` = '.$productId + .' AND `id_currency` = '.$currencyId.' AND `id_country` = '.$countryId + .' AND `id_group` = '.$groupId.' AND `id_product_attribute` = '.$attributeId + .' AND `date` < \''.$this->today.'\'' + .' ORDER BY `date` DESC'); + } + + public function saveLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $priceTex, $priceTin, $date) + { + $this->deleteLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); + return Db::getInstance()->insert('gm_omniprice_cache', + [ + 'id_shop' => $shopId, + 'id_product' => $productId, + 'id_currency' => $currencyId, + 'id_country' => $countryId, + 'id_group' => $groupId, + 'id_product_attribute' => $attributeId, + 'price_tex' => $priceTex, + 'price_tin' => $priceTin, + 'date' => $date + ]); + } + + public function deleteLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId) + { + return Db::getInstance()->delete('gm_omniprice_cache', + '`id_shop` = '.$shopId + .' AND `id_product` = '.$productId + .' AND `id_product_attribute` = '.$attributeId + .' AND `id_currency` = '.$currencyId + .' AND `id_country` = '.$countryId + .' AND `id_group` = '.$groupId + ); + } + + public function savePrice($date, $shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $priceTex, $priceTin, $onDiscount = false) + { + if (Tools::isSubmit('cache')) { + $this->deleteTodaysPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId); + } + Db::getInstance()->insert('gm_omniprice_history', + [ + 'date' => $date, + 'id_shop' => $shopId, + 'id_product' => $productId, + 'id_currency' => $currencyId, + 'id_country' => $countryId, + 'id_group' => $groupId, + 'id_product_attribute' => $attributeId, + 'price_tex' => $priceTex, + 'price_tin' => $priceTin, + 'is_specific_price' => $onDiscount + ]); + } + + public function deleteTodaysPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId) + { + return Db::getInstance()->delete('gm_omniprice_history', + '`id_shop` = '.$shopId + .' AND `id_product` = '.$productId + .' AND `id_currency` = '.$currencyId + .' AND `id_country` = '.$countryId + .' AND `id_group` = '.$groupId + .' AND `id_product_attribute` = '.$attributeId + .' AND `date` = \''.$this->today.'\'' + ); + } + + public function getGroupIds($shopId) + { + $ids = [$this->defaultGroupId]; + if (!Group::isFeatureActive()) { + return $ids; + } + $query = 'SELECT `gs`.`id_group` + FROM `'._DB_PREFIX_.'group_shop` `gs` + WHERE `gs`.`id_shop` = '.$shopId; + $res = Db::getInstance()->executeS($query); + if ($res) { + foreach ($res as $row) { + if (($row['id_group'] != $this->defaultGroupId) && !in_array($row['id_group'], $this->ignoredGroups)) { + $ids[] = (int) $row['id_group']; + } + } + } + return $ids; + } + + public function getCountryIds($shopId) + { + $ids = [$this->defaultCountryId]; + if (Shop::isFeatureActive()) { + $ids = [Configuration::get('PS_COUNTRY_DEFAULT', null, null, $shopId)]; + } + if (!$this->ignoreCountries) { + $query = 'SELECT `cs`.`id_country` + FROM `'._DB_PREFIX_.'country_shop` `cs` + LEFT JOIN `'._DB_PREFIX_.'country` `c` ON (`cs`.`id_country` = `c`.`id_country`) + WHERE `cs`.`id_shop` = '.$shopId + .' AND `c`.`active` = 1'; + $res = Db::getInstance()->executeS($query); + if ($res) { + foreach ($res as $row) { + if (!in_array($row['id_country'], $ids)) { + if ($this->ignoreNonEuCountries) { + $country = new Country($row['id_country']); + if (in_array($country->iso_code, $this->euCountries)) { + $ids[] = (int) $row['id_country']; + } + } else { + $ids[] = (int) $row['id_country']; + } + } + } + } + } + return $ids; + } + + public function getCurrencyIds($shopId) + { + $ids = []; + $query = 'SELECT `cs`.`id_currency` + FROM `'._DB_PREFIX_.'currency` c + LEFT JOIN `'._DB_PREFIX_.'currency_shop` cs ON (cs.`id_currency` = c.`id_currency`) + WHERE cs.`id_shop` = '.(int) $shopId + .' AND c.`active` = 1'; + $currencies = Db::getInstance()->executeS($query); + foreach ($currencies as $currency) { + $ids[] = (int) $currency['id_currency']; + } + return $ids; + } + + public function getProductIds($shopId) + { + $productIds = []; + $query = 'SELECT `ps`.`id_product` ' + .' FROM `'._DB_PREFIX_.'product_shop` `ps`' + .' WHERE `ps`.`id_product` NOT IN ' + .' (SELECT `id_product` FROM `'._DB_PREFIX_.'gm_omniprice_index`' + .' WHERE `date` = \''.$this->today.'\' AND `id_shop` = '.$shopId.')' + .($this->indexInactive ? ' ' : ' AND `ps`.`active` = 1 ') + .' AND `ps`.`id_shop` = '.$shopId.' ' + .' ORDER BY `ps`.`id_product` ASC LIMIT '.$this->batchSize; + + $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query, true, false); + if ($res) { + foreach ($res as $row) { + $productIds[] = (int) $row['id_product']; + } + } + return $productIds; + } + + public function getProductAttributeMap($shopId) + { + $map = []; + if (!$this->ignoreCombinations) { + $query = 'SELECT `id_product`, `id_product_attribute` ' + .' FROM `'._DB_PREFIX_.'product_attribute_shop` ' + .' WHERE `id_shop` = '.$shopId; + $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($query); + if ($res) { + foreach ($res as $row) { + $map[(int) $row['id_product']][] = (int) $row['id_product_attribute']; + } + } + } + return $map; + } + + public function getShopsIds() + { + $list = []; + $sql = 'SELECT `id_shop` FROM `'._DB_PREFIX_.'shop` + WHERE `active` = 1 AND `deleted` = 0'; + $res = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); + if ($res) { + foreach ($res as $row) { + $list[] = (int) $row['id_shop']; + } + } + return $list; + } + + public function hookDisplayProductPriceBlock($hookParams) + { + if (($hookParams['type'] == 'after_price') && + ((isset($hookParams['product']->id)) || (isset($hookParams['product']['id_product'])) || Tools::isSubmit('id_product') )) { + if (isset($hookParams['product']->id)) { + $productId = (int) $hookParams['product']->id; + } else if (isset($hookParams['product']['id_product'])) { + $productId = (int) $hookParams['product']['id_product']; + } else { + $productId = (int) Tools::getValue('id_product'); + } + $showRealDiscount = $this->showRealDiscount; + if (Tools::isSubmit('omnipricetest')) { + $lowestCachedPrice = [ + 'formatted' => Tools::getValue('omnipricetest'), + 'raw' => 1 + ]; + $showRealDiscount = false; + } else { + $params = $this->getCurrentParams($productId); + if (Tools::isSubmit('omnidebug')) { + var_export($params); + echo $this->context->country->iso_code; + } + if ($this->ignoreNonEuCountries) { + if (!in_array($this->context->country->iso_code, $this->euCountries)) { + return false; + } + } + $lowestCachedPrice = $this->getLowestCachedPrice($params); + } + $realDiscount = ''; + if ($showRealDiscount && $lowestCachedPrice && isset($hookParams['product']['price_amount'])) { + $currentPrice = $hookParams['product']['price_amount']; + $previousPrice = $lowestCachedPrice['raw']; + $realDiscount = $this->calculateRealDisount($currentPrice, $previousPrice); + } + + // Metoda 1: Standardowa dla PrestaShop 1.7+ (tablica) + if (isset($hookParams['product']['has_discount']) && $hookParams['product']['has_discount']) { + $isDiscounted = true; + } + // Metoda 2: Bezpośrednie sprawdzenie specificPrice (obiekt) - dla starszych wersji lub innych kontekstów + elseif (isset($hookParams['product']->specificPrice) && $hookParams['product']->specificPrice) { + $isDiscounted = true; + } + + // Jeżeli produkt NIE JEST na promocji, przerywamy działanie funkcji (nie wyświetlamy nic) + if (!$isDiscounted) { + return; + } + + if (!$lowestCachedPrice) { + //may have a promotion for an individual combination + if (Tools::version_compare(_PS_VERSION_, '1.7.0.0', '<') && $this->hasAttributePrices($productId)) { + $lowestCachedPrice = [ + 'formatted' => '---', + 'raw' => '0' + ]; + } + } + if ($lowestCachedPrice) { + $this->context->smarty->assign( + [ + 'gm_omniprice_lowest' => $lowestCachedPrice['formatted'], + 'gm_omniprice_lowest_raw' => $lowestCachedPrice['raw'], + 'gm_omniprice_days' => $this->daysBack, + 'gm_omniprice_color' => $this->textColor, + 'gm_omniprice_price_color' => $this->priceColor, + 'gm_omniprice_background' => $this->backgroundColor, + 'gm_omniprice_show_real_discount' => $showRealDiscount, + 'gm_omniprice_real_discount' => $realDiscount + ] + ); + return $this->display(__FILE__, 'price.tpl'); + } + } + } + + public function calculateRealDisount($currentPrice, $previousPrice) + { + if (!$currentPrice || !$previousPrice) { + return false; + } + $realDiscount = '0%'; + if ($currentPrice < $previousPrice) { + $discount = round((1 - $currentPrice / $previousPrice) * 100); + $realDiscount = '-'.$discount.'%'; + } + if ($currentPrice > $previousPrice) { + $discount = round(($currentPrice / $previousPrice - 1) * 100); + $realDiscount = '+'.$discount.'%'; + } + return $realDiscount; + } + + public function getLowestCachedPrice($params) + { + $displayMethod = Group::getPriceDisplayMethod($params['id_group']); + if ($displayMethod) { + $field = '`price_tex`'; + } else { + $field = '`price_tin`'; + } + $price = Db::getInstance()->getValue('SELECT '.$field + .' FROM `'._DB_PREFIX_.'gm_omniprice_cache`' + .' WHERE `id_shop` = '.$params['id_shop'] + .' AND `id_product` = '.$params['id_product'] + .' AND `id_product_attribute` = '.$params['id_product_attribute'] + .' AND `id_currency` = '.$params['id_currency'] + .' AND `id_country` = '.$params['id_country'] + .' AND `id_group` = '.$params['id_group'] + ); + if ($price) { + return [ + 'formatted' => $this->getFormattedPrice($price), + 'raw' => $price + ]; + } else if ($params['id_product_attribute'] != 0) { + $price = Db::getInstance()->getValue('SELECT '.$field + .' FROM `'._DB_PREFIX_.'gm_omniprice_cache`' + .' WHERE `id_shop` = '.$params['id_shop'] + .' AND `id_product` = '.$params['id_product'] + .' AND `id_product_attribute` = 0' + .' AND `id_currency` = '.$params['id_currency'] + .' AND `id_country` = '.$params['id_country'] + .' AND `id_group` = '.$params['id_group'] + ); + if ($price) { + return [ + 'formatted' => $this->getFormattedPrice($price), + 'raw' => $price + ]; + } + } + if (!$price) { + if ($this->showIfNotEnoughHistoricalData) { + return $this->getLatestHistoricalPrice($params); + } + } + return false; + } + + protected function getLatestHistoricalPrice($params) + { + $displayMethod = Group::getPriceDisplayMethod($params['id_group']); + if ($displayMethod) { + $field = '`price_tex`'; + $arrayField = 'price_tex'; + } else { + $field = '`price_tin`'; + $arrayField = 'price_tin'; + } + $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` = '.$params['id_product_attribute'] + ); + if ((count($prices) == 1) && ($prices[0]['is_specific_price'])) { + return + [ + 'formatted' => $this->getFormattedPrice($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' + ); + if ((count($prices) == 1) && ($prices[0]['is_specific_price'])) { + return + [ + 'formatted' => $this->getFormattedPrice($prices[0][$arrayField]), + 'raw' => $prices[0][$arrayField] + ]; + } + } + 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($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($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() + { + $output = '
' + .'
' + .$this->l('Gathering price history') + .'
'; + $indexUrl = $this->context->link->getModuleLink($this->name, 'cron', + [ + 'action' => 'index', + 'token' => $this->token + ]); + $output .= ''; + $output .= '
'; + $output .= '
' + .'
' + .$this->l('Cleaning old price history') + .'
'; + $cleanupUrl = $this->context->link->getModuleLink($this->name, 'cron', + [ + 'action' => 'cleanup', + 'token' => $this->token + ]); + $output .= ''; + $output .= '
'; + return $output; + } + + protected function displayInformationPanel() + { + $output = '
' + .'
' + .$this->l('Information') + .'
'; + if (!defined('_TB_VERSION_')) { //TB has a nasty bug here + $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 .= '
'; + return $output; + } + + protected function countActiveCurrencies() + { + return (int) Db::getInstance()->getValue('SELECT COUNT(`id_currency`) FROM `'._DB_PREFIX_.'currency` WHERE `active` = 1'); + } + + protected function countActiveCountries() + { + return (int) Db::getInstance()->getValue('SELECT COUNT(`id_country`) FROM `'._DB_PREFIX_.'country` WHERE `active` = 1'); + } + + protected function countStoredPrices() + { + return (int) Db::getInstance()->getValue('SELECT COUNT(`id_product`) FROM `'._DB_PREFIX_.'gm_omniprice_history`'); + } + + protected function getCombinationsPriceImpactsInfo() + { + $query = 'SELECT `id_product` FROM `'._DB_PREFIX_.'product_attribute` WHERE `price` != 0'; + $res = Db::getInstance()->getValue($query); + if ($res) { + return true; + } else { + return false; + } + } + + protected function getCombinationsDiscountsInfo() + { + $query = 'SELECT `id_product` FROM `'._DB_PREFIX_.'specific_price` WHERE `id_product_attribute` > 0'; + $res = Db::getInstance()->getValue($query); + if ($res) { + return true; + } else { + return false; + } + } + + protected function getGroupNames() + { + $langId = $this->context->language->id; + $query = 'SELECT `id_group`, `name` FROM `'._DB_PREFIX_.'group_lang` WHERE `id_lang` = '.$langId; + $res = Db::getInstance()->executeS($query); + if ($res) { + foreach ($res as $row) { + $this->groupNames[(int) $row['id_group']] = $row['name']; + } + } + } + + protected function findGroupsToSafelyIgnore() + { + $groups = $this->findEmptyGroups(true); + $guestGroupId = Configuration::get('PS_GUEST_GROUP'); + $unidentifiedGroupId = Configuration::get('PS_UNIDENTIFIED_GROUP'); + $groups[] = $guestGroupId; + $groups[] = $unidentifiedGroupId; + $groups = array_unique($groups); + sort($groups); + $ignoredGroups = []; + foreach ($groups as $groupId) { + if ($groupId != $this->defaultGroupId) { + $ignoredGroups[] = $groupId; + } + } + return $ignoredGroups; + } + + protected function findEmptyGroups($returnIds = false) + { + $emptyGroups = []; + $emptyIds = []; + $res = Group::getGroups($this->context->language->id); + foreach ($res as $row) { + $group = new Group((int) $row['id_group']); + $customerCount = $group->getCustomers(true); + if ($customerCount < 1) { + $emptyGroups[] = $row['name']; + $emptyIds[] = $row['id_group']; + } + } + if ($returnIds) { + return $emptyIds; + } + if (!count($emptyGroups)) { + return [$this->l('None')]; + } + return $emptyGroups; + } + + protected function findGroupsWithSpecifiPriceRules() + { + $groupIds = []; + $query = 'SELECT `id_group` FROM `'._DB_PREFIX_.'specific_price_rule` WHERE `id_group` > 0'; + $res = Db::getInstance()->executes($query); + if ($res) { + foreach ($res as $row) { + $groupIds[] = (int) $row['id_group']; + } + } + $groupIds = array_unique($groupIds); + sort($groupIds); + return $this->getGroupNamesForIds($groupIds); + } + + protected function findGroupsWithSpecificPrices() + { + $groupIds = []; + $query = 'SELECT `id_group` FROM `'._DB_PREFIX_.'specific_price` WHERE `id_group` > 0'; + $res = Db::getInstance()->executes($query); + if ($res) { + foreach ($res as $row) { + $groupIds[] = (int) $row['id_group']; + } + } + $groupIds = array_unique($groupIds); + sort($groupIds); + return $this->getGroupNamesForIds($groupIds); + } + + protected function findGroupsWithGroupReduction() + { + $groupIds = []; + $query = 'SELECT `id_group` FROM `'._DB_PREFIX_.'group` WHERE `reduction` > 0'; + $res = Db::getInstance()->executes($query); + if ($res) { + foreach ($res as $row) { + $groupIds[] = (int) $row['id_group']; + } + } + $query = 'SELECT `id_group` FROM `'._DB_PREFIX_.'group_reduction` WHERE `reduction` > 0'; + $res = Db::getInstance()->executes($query); + if ($res) { + foreach ($res as $row) { + $groupIds[] = (int) $row['id_group']; + } + } + $groupIds = array_unique($groupIds); + sort($groupIds); + return $this->getGroupNamesForIds($groupIds); + } + + protected function getGroupNamesForIds($groupIds) + { + if (!count($groupIds)) { + return [$this->l('None')]; + } + $names = []; + $this->getGroupNames(); + foreach ($groupIds as $groupId) { + $names[] = $this->groupNames[$groupId]; + } + return $names; + } + + public function hookActionProductUpdate($params) + { + $productId = $params['id_product']; + $this->reindexProduct($productId); + } + + public function hookActionObjectSpecificPriceAddAfter($params) + { + $sp = $params['object']; + if ($sp->id_product) { + $this->reindexProduct($sp->id_product); + } + } + + public function hookActionObjectSpecificPriceUpdateAfter($params) + { + $sp = $params['object']; + if ($sp->id_product) { + $this->reindexProduct($sp->id_product); + } + } + + public function hookActionObjectSpecificPriceDeleteAfter($params) + { + $sp = $params['object']; + if ($sp->id_product) { + $this->reindexProduct($sp->id_product); + } + } + + public function reindexProduct($productId) + { + $this->removeProductFromTodaysIndex($productId); + $this->removeProductFromTodaysHistory($productId); + if ($this->reindexOnSave) { + $this->savePrices(false, $productId); + } + } + + public function resetIndex() + { + Db::getInstance()->delete('gm_omniprice_index'); + Db::getInstance()->delete('gm_omniprice_history', '`date` = \''.$this->today.'\''); + } + + public function removeProductFromTodaysIndex($productId) + { + Db::getInstance()->delete('gm_omniprice_index', '`id_product` = '.$productId.' AND `date` = \''.$this->today.'\''); + } + + public function removeProductFromTodaysHistory($productId) + { + Db::getInstance()->delete('gm_omniprice_history', '`id_product` = '.$productId.' AND `date` = \''.$this->today.'\''); + } + + public function hookDisplayHeader($params) + { + if (Tools::isSubmit('id_product')) { + $this->context->controller->addCSS($this->_path.'views/css/gm_omniprice.css', 'all'); + if (!$this->ignoreCombinations) { + $params = $this->getCurrentParams((int) Tools::getValue('id_product')); + $prices = $this->getLowestCachedPricesForCombinations($params); + if (count($prices) > 0) { + $this->context->controller->addJS($this->_path.'views/js/gm_omniprice.js'); + Media::addJsDef(['gm_omniprice_attr_prices' => $prices]); + } + } + } + } + + public function cleanUp($verbose = false) + { + $output = ''; + //general cleanup + if (Tools::issubmit('zero')) { + Db::getInstance()->delete('gm_omniprice_history', '`price_tin` < 0.001'); + Db::getInstance()->delete('gm_omniprice_cache', '`price_tin` < 0.001'); + } + Db::getInstance()->delete('gm_omniprice_history', '`id_product` NOT IN (SELECT `id_product` FROM `'._DB_PREFIX_.'product`)'); + Db::getInstance()->delete('gm_omniprice_cache', '`id_product` NOT IN (SELECT `id_product` FROM `'._DB_PREFIX_.'product`)'); + Db::getInstance()->delete('gm_omniprice_history', + '`id_product_attribute` > 0 AND `id_product_attribute` NOT IN (SELECT `id_product_attribute` FROM `'._DB_PREFIX_.'product_attribute`)'); + Db::getInstance()->delete('gm_omniprice_cache', + '`id_product_attribute` > 0 AND `id_product_attribute` NOT IN (SELECT `id_product_attribute` FROM `'._DB_PREFIX_.'product_attribute`)'); + Db::getInstance()->delete('gm_omniprice_history', '`id_shop` NOT IN (SELECT `id_shop` FROM `'._DB_PREFIX_.'shop`)'); + Db::getInstance()->delete('gm_omniprice_cache', '`id_shop` NOT IN (SELECT `id_shop` FROM `'._DB_PREFIX_.'shop`)'); + Db::getInstance()->delete('gm_omniprice_history', '`id_currency` NOT IN (SELECT `id_currency` FROM `'._DB_PREFIX_.'currency`)'); + Db::getInstance()->delete('gm_omniprice_cache', '`id_currency` NOT IN (SELECT `id_currency` FROM `'._DB_PREFIX_.'currency`)'); + Db::getInstance()->delete('gm_omniprice_history', '`id_group` NOT IN (SELECT `id_group` FROM `'._DB_PREFIX_.'group`)'); + Db::getInstance()->delete('gm_omniprice_cache', '`id_group` NOT IN (SELECT `id_group` FROM `'._DB_PREFIX_.'group`)'); + Db::getInstance()->delete('gm_omniprice_history', '`id_country` NOT IN (SELECT `id_country` FROM `'._DB_PREFIX_.'country` WHERE `active` = 1)'); + Db::getInstance()->delete('gm_omniprice_cache', '`id_country` NOT IN (SELECT `id_country` FROM `'._DB_PREFIX_.'country` WHERE `active` = 1)'); + if ($this->ignoreCountries) { + if (Shop::isFeatureActive()) { + //for the future + } else { + Db::getInstance()->delete('gm_omniprice_history', '`id_country` != '.$this->defaultCountryId); + Db::getInstance()->delete('gm_omniprice_cache', '`id_country` != '.$this->defaultCountryId); + } + } + foreach ($this->ignoredGroups as $ignoredGroupId) { + if ($ignoredGroupId && ((int) $ignoredGroupId !== (int) $this->defaultGroupId)) { + Db::getInstance()->delete('gm_omniprice_history', '`id_group` = '.$ignoredGroupId); + Db::getInstance()->delete('gm_omniprice_cache', '`id_group` = '.$ignoredGroupId); + } + } + + // delete from materac_gm_omniprice_cache WHERE column date is older than 30 days + Db::getInstance()->delete('gm_omniprice_cache', '`date` < DATE_SUB(NOW(), INTERVAL 60 DAY)'); + $output .= '

Usuwam dane z gm_omniprice_cache

'; + // delete from materac_gm_omniprice_history WHERE column date is older than 30 days + Db::getInstance()->delete('gm_omniprice_history', '`date` < DATE_SUB(NOW(), INTERVAL 60 DAY)'); + $output .= '

Usuwam dane z gm_omniprice_history

'; + + $date = date("Y-m-d", strtotime("-".$this->daysBack." days")); + $output .= $this->l('Period').': '.$this->daysBack.' ('.$date.')
'; + $shopIds = $this->getShopsIds(); + foreach ($shopIds as $shopId) { + $currencyIds = $this->getCurrencyIds($shopId); + $countryIds = $this->getCountryIds($shopId); + $groupIds = $this->getGroupIds($shopId); + $productIds = $this->getProductIdsInHistory($shopId); + foreach ($currencyIds as $currencyId) { + foreach ($countryIds as $countryId) { + foreach ($groupIds as $groupId) { + foreach ($productIds as $productId) { + $query = 'SELECT `date`, `id_product`, `id_product_attribute` FROM `'._DB_PREFIX_.'gm_omniprice_history` ' + .' WHERE `id_shop` = '.$shopId.' AND `id_product` = '.$productId.' AND `id_currency` = '.$currencyId. + ' AND `id_country` = '.$countryId.' AND `id_group` = '.$groupId.' ORDER BY `date` ASC'; + $res = Db::getInstance()->executeS($query); + $datesMap = []; + if ($res) { + foreach ($res as $row) { + $day = $row['date']; + $productId = $row['id_product']; + $attributeId = $row['id_product_attribute']; + if ($day < $date) { + $datesMap[$productId][$attributeId][] = $day; + } + } + foreach ($datesMap as $productId => $dateItem) { + foreach ($dateItem as $attributeId => $dates) { + $output .= "Product ID {$productId}, attribute ID: {$attributeId}
"; + $datesCount = count($dates); + if ($datesCount > 2) { + for ($i = 0; $i < $datesCount - 2; $i++) { + $output .= ' '.$dates[$i].' '.$this->l('this price may be deleted').'
'; + $where = '`id_shop` = '.$shopId.' AND `id_currency` = '.$currencyId. + ' AND `id_country` = '.$countryId.' AND `id_group` = '.$groupId; + $where .= ' AND `id_product` = '.$productId.' AND `id_product_attribute` = '.$attributeId; + $where .= ' AND `date` = \''.$dates[$i].'\''; + Db::getInstance()->delete('gm_omniprice_history', $where); + } + } + $output .= ' '.$dates[$datesCount - 1].' '.$this->l('this price is still needed').'
'; + } + } + } + } + } + } + } + } + + if ($verbose) { + echo '
';
+            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 = '';
+        $output .= '';
+        $output .= '';
+        foreach ($columns as $columnHeader) {
+            $output .= '';
+        }
+        $output .= '';
+        $output .= '';
+        foreach ($data as $row) {
+            $output .= '';
+            foreach ($columns as $key) {
+                $output .= '';
+            }
+            $output .= '';
+        }
+        $output .= '
'.$columnHeader.'
'.$row[$key].'
'; + return $output; + } + + public function hookActionGetProductPropertiesAfter($params) + { + return; + $product = &$params['product']; + $sp = $product['specific_prices']; + //var_export($product); + $sp['reduction'] = (string) (rand(0, 10) / 100); + $product['specific_prices'] = $sp; + } + + public function fillMissingCache($verbose = false) + { + $output = ''; + $query = 'SELECT * FROM `'._DB_PREFIX_.'gm_omniprice_history` ' + .' WHERE `is_specific_price` = 1 AND `id_product` IN (SELECT `id_product` FROM `'._DB_PREFIX_.'product` WHERE `active` = 1)' + .' ORDER BY `date` DESC '; + $res = Db::getInstance()->executeS($query); + if ($res) { + foreach ($res as $row) { + $lowestPrice = $this->getLowestCachedPrice($row); + if ($lowestPrice === false) { + $shopId = (int) $row['id_shop']; + $productId = (int) $row['id_product']; + $groupId = (int) $row['id_group']; + $currencyId = (int) $row['id_currency']; + $countryId = (int) $row['id_country']; + $attributeId = (int) $row['id_product_attribute']; + $output .= var_export($row, true).'
'; + $output .= ' - no lowest price!
'; + $lastChangeDate = $row['date']; + $output .= ' Look for the lowest price before '.$lastChangeDate.'
'; + $now = time(); + $your_date = strtotime($row['date']); + $datediff = $now - $your_date; + $daysOffset = floor($datediff / (60 * 60 * 24)); + $output .= ' days offset: '.$daysOffset.'
'; + $lowestPrices = $this->getLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $daysOffset); + if ($lowestPrices) { + $output .= ' found price: '.$lowestPrices['price_tin'].' ('.$lowestPrices['price_tex'].')
'; + $this->saveLowestPrice($shopId, $productId, $currencyId, $countryId, $groupId, $attributeId, $lowestPrices['price_tex'], + $lowestPrices['price_tin'], $lowestPrices['date']); + } + } + } + } + if ($verbose) { + echo $output; + } + } + + public function getActiveMap() + { + if ($this->activeMap == null) { + $query = 'SELECT `id_shop`, `id_product`, `active` FROM `'._DB_PREFIX_.'product_shop`'; + $res = Db::getInstance()->executeS($query); + if ($res) { + foreach ($res as $row) { + $this->activeMap[(int) $row['id_shop']][(int) $row['id_product']] = (int) $row['active']; + } + } + } + return $this->activeMap; + } + + public function productIsActive($productId, $shopId) + { + $activeMap = $this->getActiveMap(); + if (isset($activeMap[$shopId][$productId])) { + return ($activeMap[$shopId][$productId] == 1); + } + return false; + } + + public function getCostPriceMap() + { + $map = []; + $query = 'SELECT `id_product`, `id_shop`, `wholesale_price` FROM `'._DB_PREFIX_.'product_shop` WHERE `wholesale_price` > 0'; + $res = Db::getInstance()->executeS($query); + if ($res) { + foreach ($res as $row) { + $shopId = (int) $row['id_shop']; + $productId = (int) $row['id_product']; + $costPrice = $row['wholesale_price']; + $map[$shopId][$productId][0] = $costPrice; + } + } + + $query = 'SELECT `id_product`, `id_product_attribute`, `id_shop`, `wholesale_price` FROM `'._DB_PREFIX_.'product_attribute_shop` WHERE `wholesale_price` > 0'; + $res = Db::getInstance()->executeS($query); + if ($res) { + foreach ($res as $row) { + $shopId = (int) $row['id_shop']; + $productId = (int) $row['id_product']; + $attributeId = (int) $row['id_product_attribute']; + $costPrice = $row['wholesale_price']; + $map[$shopId][$productId][$attributeId] = $costPrice; + } + } + return $map; + } + + public function getConversionRates() + { + $rates = []; + $currencies = Db::getInstance()->executeS(' SELECT `id_shop`, `id_currency`, `conversion_rate` - FROM `' . _DB_PREFIX_ . 'currency_shop`'); - if ($currencies) - { - foreach ($currencies as $currency) - { - $shopId = (int) $currency['id_shop']; - $currencyId = (int) $currency['id_currency']; - $rate = $currency['conversion_rate']; - $rates[$currencyId][$shopId] = $rate; - } + FROM `'._DB_PREFIX_.'currency_shop`'); + if ($currencies) { + foreach ($currencies as $currency) { + $shopId = (int) $currency['id_shop']; + $currencyId = (int) $currency['id_currency']; + $rate = $currency['conversion_rate']; + $rates[$currencyId][$shopId] = $rate; + } + } + return $rates; } - return $rates; - } - public function checkIfProductIsSoldBelowCost($priceTex, $costPriceMap, $rates, $shopId, $productId, $attributeId, $currencyId) - { - $conversionRate = $rates[$currencyId][$shopId]; - $costPrice = $costPriceMap[$shopId][$productId][$attributeId]; - $convertedCostPrice = $costPrice / $conversionRate; - return ($priceTex < $convertedCostPrice); - } + public function checkIfProductIsSoldBelowCost($priceTex, $costPriceMap, $rates, $shopId, $productId, $attributeId, $currencyId) + { + $conversionRate = $rates[$currencyId][$shopId]; + $costPrice = $costPriceMap[$shopId][$productId][$attributeId]; + $convertedCostPrice = $costPrice / $conversionRate; + return ($priceTex < $convertedCostPrice); + } - protected function displayGreenMouseModulesPanel() - { - $url = 'https://codecanyon.net/user/greenmousestudio/portfolio'; - $isoCode = Context::getContext()->language->iso_code; - $translations = [ - 'en' => "Check out more PrestaShop modules from GreenMouseStudio", - 'fr' => "Découvrez plus de modules PrestaShop de GreenMouseStudio", - 'es' => "Descubra más módulos de PrestaShop de GreenMouseStudio", - 'de' => "Entdecken Sie mehr PrestaShop-Module von GreenMouseStudio", - 'it' => "Scopri di più moduli PrestaShop di GreenMouseStudio", - 'pl' => "Zobacz więcej modułów PrestaShop od GreenMouseStudio", - 'pt' => "Confira mais módulos PrestaShop do GreenMouseStudio", - 'nl' => "Bekijk meer PrestaShop-modules van GreenMouseStudio", - 'sv' => "Upptäck fler PrestaShop-moduler från GreenMouseStudio", - 'da' => "Se flere PrestaShop-moduler fra GreenMouseStudio", - 'fi' => "Tutustu lisää GreenMouseStudion PrestaShop-moduuleihin", - 'cs' => "Podívejte se na další moduly PrestaShop od GreenMouseStudio", - 'sk' => "Pozrite si viac modulov PrestaShop od GreenMouseStudio", - 'hu' => "Nézzen meg több PrestaShop modult a GreenMouseStudio-tól", - 'ro' => "Descoperiți mai multe module PrestaShop de la GreenMouseStudio", - 'el' => "Δείτε περισσότερες μονάδες PrestaShop από το GreenMouseStudio", - ]; - $message = isset($translations[$isoCode]) ? $translations[$isoCode] : $translations['en']; - $content = ''; - $content .= '

' . $message . '

'; - return $content; - } + protected function displayGreenMouseModulesPanel() + { + $url = 'https://codecanyon.net/user/greenmousestudio/portfolio'; + $isoCode = Context::getContext()->language->iso_code; + $translations = [ + 'en' => "Check out more PrestaShop modules from GreenMouseStudio", + 'fr' => "Découvrez plus de modules PrestaShop de GreenMouseStudio", + 'es' => "Descubra más módulos de PrestaShop de GreenMouseStudio", + 'de' => "Entdecken Sie mehr PrestaShop-Module von GreenMouseStudio", + 'it' => "Scopri di più moduli PrestaShop di GreenMouseStudio", + 'pl' => "Zobacz więcej modułów PrestaShop od GreenMouseStudio", + 'pt' => "Confira mais módulos PrestaShop do GreenMouseStudio", + 'nl' => "Bekijk meer PrestaShop-modules van GreenMouseStudio", + 'sv' => "Upptäck fler PrestaShop-moduler från GreenMouseStudio", + 'da' => "Se flere PrestaShop-moduler fra GreenMouseStudio", + 'fi' => "Tutustu lisää GreenMouseStudion PrestaShop-moduuleihin", + 'cs' => "Podívejte se na další moduly PrestaShop od GreenMouseStudio", + 'sk' => "Pozrite si viac modulov PrestaShop od GreenMouseStudio", + 'hu' => "Nézzen meg több PrestaShop modult a GreenMouseStudio-tól", + 'ro' => "Descoperiți mai multe module PrestaShop de la GreenMouseStudio", + 'el' => "Δείτε περισσότερες μονάδες PrestaShop από το GreenMouseStudio", + ]; + $message = isset($translations[$isoCode]) ? $translations[$isoCode] : $translations['en']; + $content = ''; + $content .= '

'.$message.'

'; + return $content; + } - public function getTokenForScripts() - { - if (method_exists('Tools', 'encrypt')) + public function getTokenForScripts() { - return Tools::encrypt($this->name); + if (method_exists('Tools', 'encrypt')) { + return Tools::encrypt($this->name); + } elseif (method_exists('Tools', 'hash')) { + return Tools::hash($this->name); + } else { + return hash('sha256', $this->name._COOKIE_KEY_); + } } - elseif (method_exists('Tools', 'hash')) - { - return Tools::hash($this->name); - } - else - { - return hash('sha256', $this->name . _COOKIE_KEY_); - } - } } diff --git a/modules/gm_omniprice/translations/pl.php b/modules/gm_omniprice/translations/pl.php index db45b9be..19445c60 100644 --- a/modules/gm_omniprice/translations/pl.php +++ b/modules/gm_omniprice/translations/pl.php @@ -3,7 +3,7 @@ global $_MODULE; $_MODULE = array(); $_MODULE['<{gm_omniprice}prestashop>gm_omniprice_90a0c7b2104a67d391df6f2db66300e3'] = 'OmniPrice - zgodność cen z dyrektywą Omnibus'; -$_MODULE['<{gm_omniprice}prestashop>gm_omniprice_2f2aaa2e0f7ba09de9a5f449ba5f45af'] = 'Wyświetla informację o najniższej cenie przed obniżką'; +$_MODULE['<{gm_omniprice}prestashop>gm_omniprice_2f2aaa2e0f7ba09de9a5f449ba5f45af'] = 'Wyświetla informację o najniższej cenie przed promocją'; $_MODULE['<{gm_omniprice}prestashop>gm_omniprice_c888438d14855d7d96a2724ee9c306bd'] = 'Zapisano ustawienia'; $_MODULE['<{gm_omniprice}prestashop>gm_omniprice_1901606ea069a83dc7beea17881ef95a'] = 'Okres'; $_MODULE['<{gm_omniprice}prestashop>gm_omniprice_b1e1f9076cca4dd59d55975e7a318f38'] = 'Liczba dni przed promocją podlegająca analizie'; @@ -70,7 +70,7 @@ $_MODULE['<{gm_omniprice}prestashop>gm_omniprice_fa19e91aa306519181f7b8a19743b5f $_MODULE['<{gm_omniprice}prestashop>gm_omniprice_63b539babcf7978229d66ba4052ca71f'] = 'Cena promocyjna'; $_MODULE['<{gm_omniprice}prestashop>gm_omniprice_4d8adffdc001189e0202c01ac529a3a9'] = 'Cena regularna'; $_MODULE['<{gm_omniprice}prestashop>gm_omniprice_148b76150603892408248b0ed5a5dd51'] = 'Najniższa poprzednia cena'; -$_MODULE['<{gm_omniprice}prestashop>price_7a6e48674dee5dd4a09f41e487d2c896'] = 'Najniższa cena w okresie %d dni przed obniżką:'; +$_MODULE['<{gm_omniprice}prestashop>price_7a6e48674dee5dd4a09f41e487d2c896'] = 'Najniższa cena w okresie %d dni przed promocją:'; $_MODULE['<{gm_omniprice}prestashop>tab_11ac0a790117ce9772284501afb324e5'] = 'Produkt zaindeksowany dzisiaj:'; $_MODULE['<{gm_omniprice}prestashop>tab_93cba07454f06a4a960172bbd6e2a435'] = 'Tak'; $_MODULE['<{gm_omniprice}prestashop>tab_bafd7322c6e97d25b6299b5d6fe8920b'] = 'Nie'; From 987ba65cf92277511ae42651df86b20fb49558bb Mon Sep 17 00:00:00 2001 From: Roman Pyrih Date: Tue, 16 Dec 2025 16:31:11 +0100 Subject: [PATCH 6/7] Save --- themes/classic/assets/css/custom.css | 2 +- themes/classic/assets/css/custom.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/themes/classic/assets/css/custom.css b/themes/classic/assets/css/custom.css index 3ecea0aa..499bf862 100644 --- a/themes/classic/assets/css/custom.css +++ b/themes/classic/assets/css/custom.css @@ -1 +1 @@ -body>main{overflow-x:hidden}html{scroll-padding-top:150px;scroll-behavior:smooth}body{font-size:15px;line-height:1.5;color:#232323}body .elementor-widget-text-editor{color:#232323}body h3{color:#232323}body#index footer#footer section.footer-box-newsletter{display:none !important}body#category section#wrapper section#main{margin-bottom:100px}body#category section#wrapper section#main #product-list-header *{color:#000}body#category section#wrapper section#main #product-list-header strong{font-weight:600}body#category section#wrapper section#main #product-list-header p{margin-bottom:10px}#footer a{color:#c5c5c5;transition:all 250ms ease-in-out}#footer a:hover{color:#e79332;text-decoration:none}a{color:#e79332}.btn-1{display:inline-block;color:#111516;border:1px solid #e79332;padding:15px;background:#fff;transition:all 250ms ease-in-out;cursor:pointer}.btn-1:hover{color:#fff;background:#e79332}.btn-primary{color:#fff;background:#e79332;transition:all 250ms ease-in-out}.btn-primary:hover{color:#fff;background:#d3ba67}#box-newsletter{position:relative}#box-newsletter::before{content:"";position:absolute;width:100vw;left:50%;top:0;bottom:0;transform:translateX(-50%);background-color:#fff}.simple-blog-posts .elementor-swiper-button{color:#e79332}.simple-blog-posts .elementor-swiper-button.elementor-swiper-button-next{right:0}.simple-blog-posts .elementor-swiper-button.elementor-swiper-button-prev{left:0}.simple-blog-posts #simple-blog-box{padding:0 29px}.simple-blog-posts #simple-blog-box .simple-blog-post{border-radius:10px;overflow:hidden}.simple-blog-posts #simple-blog-box .simple-blog-post ._image img{height:100%;max-height:200px;width:100%;-o-object-fit:cover;object-fit:cover;-o-object-position:center;object-position:center}.simple-blog-posts #simple-blog-box .simple-blog-post ._content{padding:20px;background-color:#eff6f7}.simple-blog-posts #simple-blog-box .simple-blog-post ._content .post-title{color:#111516;font-size:18px;font-weight:300;margin:0 0 .7em;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.25;font-weight:400}.simple-blog-posts #simple-blog-box .simple-blog-post ._content a._btn{display:inline-block;color:#e79332;font-weight:400;text-decoration:underline}.js-product.product article.product-miniature:hover .thumbnail-container .wishlist-button-add{opacity:1;visibility:visible;transform:translateY(0)}.js-product.product article.product-miniature:hover .thumbnail-container ul.product-flags{transform:translateX(calc(-100% - 30px))}.js-product.product article.product-miniature .thumbnail-container{width:100%;border:1px solid #eff6f7}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top{background:#fff}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket{display:flex;align-items:center;justify-content:center}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket .add-to-cart{font-family:"Inter",sans-serif;font-size:12px;font-weight:700;padding:8px 16px;display:flex;align-items:center;background:#462d26;border-radius:1px;-moz-column-gap:8px;column-gap:8px}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket .add-to-cart:hover{background:#e79332}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket .add-to-cart i{font-size:15px;margin-bottom:2px}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket .add-to-cart span{line-height:1;margin-bottom:1px;font-size:14px;font-weight:700}.js-product.product article.product-miniature .thumbnail-container .product-description{margin-top:14px}.js-product.product article.product-miniature .thumbnail-container .product-description::after{display:none !important}.js-product.product article.product-miniature .thumbnail-container .product-description .product-title{margin-bottom:14px;line-height:1}.js-product.product article.product-miniature .thumbnail-container .product-description .product-title a{color:#462d26;font-family:"Inter",sans-serif;font-size:14px;font-weight:400;line-height:1.2}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping .regular-price{font-size:14px;font-family:"Inter",sans-serif;color:rgba(70,45,38,.34);font-weight:700}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping .price{color:#462d26;font-family:"Inter",sans-serif;font-size:14px;font-weight:700}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping.product-price-discount{display:flex;flex-direction:row;-moz-column-gap:10px;column-gap:10px}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping.product-price-discount .price{order:1;color:#c40000}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping.product-price-discount .regular-price{order:2}.js-product.product article.product-miniature .thumbnail-container ul.product-flags{position:absolute;top:24px;left:24px;z-index:2;transition:all 250ms ease-in-out;row-gap:8px}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag{font-size:11px;font-weight:400;padding:3px 8px;min-width:-moz-fit-content;min-width:fit-content;min-height:auto;margin-top:0;list-style:none;font-family:"Inter",sans-serif;font-size:12px;font-weight:700}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag.new{background:#462d26;padding:4px 8px}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag.discount{display:flex;flex-direction:row;-moz-column-gap:8px;column-gap:8px;background-color:rgba(0,0,0,0);padding:0}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag.discount span{font-family:"Inter",sans-serif;font-size:12px;font-weight:700;padding:4px 8px;background:#c40000}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag.out_of_stock{background:#462d26}.js-product.product article.product-miniature .thumbnail-container .wishlist-button-add{opacity:0;visibility:hidden;box-shadow:none;transition:all 250ms ease-in-out;transform:translateY(calc(-100% - 1rem))}.js-product.product article.product-miniature .thumbnail-container .wishlist-button-add i{color:#462d26}.product-images>li.thumb-container>.thumb.selected,.product-images>li.thumb-container>.thumb:hover{border-color:#e79332}.blockreassurance_product .item-product svg path{fill:#e79332}body#product{overflow-x:hidden}body#product>main{overflow:initial}body#product #content ul.product-flags{display:flex;flex-direction:row;gap:10px;flex-wrap:wrap}body#product #content ul.product-flags li.product-flag{font-size:11px;font-weight:400;padding:3px 8px;min-width:-moz-fit-content;min-width:fit-content;min-height:auto;transition:all 250ms ease-in-out;margin-top:0;border-radius:10px}body#product #content ul.product-flags li.product-flag.new{background:#e79332;margin-top:0}body#product #content ul.product-flags li.product-flag.discount{background:#e30613}body#product #content ul.product-flags li.product-flag.out_of_stock{position:absolute;top:0;right:0;background:#111516}body#product .product-info-box{margin:0;padding-top:5px;padding-bottom:65px;border-radius:10px}body#product .product-info-box #content{max-width:unset}body#product .product-info-box #content ul.product-flags{margin:0}body#product .product-info-box h1{color:#111516;font-size:24px;font-weight:400}body#product .product-info-box .product-prices{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap}body#product .product-info-box .product-prices .product-discount{margin-bottom:0px}body#product .product-info-box .product-prices .product-discount .regular-price{color:#a9a8a8;font-weight:300;margin:0}body#product .product-info-box .product-prices .product-price{margin-bottom:0}body#product .product-info-box .product-prices .product-price .current-price{color:#111516;font-size:26px;font-weight:600;margin-bottom:0}body#product .product-info-box .product-prices .product-price .current-price .discount{display:none}body#product .product-info-box .product-prices .tax-shipping-delivery-label{margin-bottom:0}body#product .product-info-box ul.product-flags{margin-bottom:24px;row-gap:8px}body#product .product-info-box ul.product-flags li.product-flag{font-size:11px;font-weight:400;padding:3px 8px;min-width:-moz-fit-content;min-width:fit-content;min-height:auto;margin-top:0;list-style:none;font-family:"Inter",sans-serif;font-size:12px;font-weight:700}body#product .product-info-box ul.product-flags li.product-flag.new{background:#462d26;padding:4px 8px}body#product .product-info-box ul.product-flags li.product-flag.discount{display:flex;flex-direction:row;-moz-column-gap:8px;column-gap:8px;background-color:rgba(0,0,0,0);padding:0}body#product .product-info-box ul.product-flags li.product-flag.discount span{font-family:"Inter",sans-serif;font-size:12px;font-weight:700;padding:4px 8px;background:#c40000}body#product .product-info-box ul.product-flags li.product-flag.out_of_stock{background:#462d26}body#product .product-info-box .product-info-box-left:hover .scroll-box-arrows{opacity:1;visibility:visible}body#product .product-info-box .product-info-box-left .images-container .js-qv-mask{margin:0;width:100%}body#product .product-info-box .product-info-box-left .product-images{margin-bottom:0}body#product .product-info-box .product-info-box-left .scroll-box-arrows{opacity:0;visibility:hidden;transition:all 250ms ease-in-out}body#product .product-info-box .product-info-box-left .scroll-box-arrows .material-icons{line-height:0;bottom:45px;width:33px;height:33px;display:flex;align-items:center;justify-content:center;background:#ece9e2;border-radius:100%}body#product .product-info-box .product-info-box-left section#content ul.product-flags{display:flex;flex-direction:column;flex-wrap:wrap;width:100%;pointer-events:none;position:absolute;top:10px;left:10px;z-index:1}@media(min-width: 768px){body#product .product-info-box .product-info-box-left section#content ul.product-flags{display:none}}body#product .product-info-box .product-info-box-left section#content ul.product-flags li.product-flag{min-width:-moz-fit-content;min-width:fit-content;min-height:auto;margin-top:0;list-style:none;font-family:"Inter",sans-serif;font-size:12px;font-weight:700;border-radius:0}body#product .product-info-box .product-info-box-left section#content ul.product-flags li.product-flag.discount{background:rgba(0,0,0,0);padding:0}body#product .product-info-box .product-info-box-left section#content ul.product-flags li.product-flag.new{background:#462d26;padding:4px 8px}@media(max-width: 767px){body#product .product-info-box .product-info-box-right ul.product-flags{display:none}}body#product .product-info-box .product-info-box-right .h1{color:#462d26;font-size:20px;font-weight:500;font-family:"Inter",sans-serif;text-transform:initial;margin-bottom:32px}body#product .product-info-box .product-info-box-right .product-prices .product-discount .regular-price{color:#462d26;font-size:28px;font-weight:700;font-family:"Inter",sans-serif;line-height:1;opacity:.35}body#product .product-info-box .product-info-box-right .product-prices .product-price .current-price .current-price-value{color:#462d26;font-size:28px;font-weight:700;font-family:"Inter",sans-serif;line-height:1}body#product .product-info-box .product-info-box-right .product-prices .tax-shipping-delivery-label{display:none}body#product .product-info-box .product-info-box-right .product-information .product-description{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants{margin:16px 0;border-top:1px solid #ddd}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item{position:relative;display:flex;align-items:center;justify-content:flex-start;margin:0;padding:16px 0;width:100%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item:not(:last-child){border-bottom:1px solid #ddd}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item::before{content:"";position:absolute;left:-20px;right:-20px;top:-1px;bottom:0;background:#fff;transition:all 250ms ease-in-out;opacity:0;visibility:hidden;transition-delay:400ms}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select{display:flex;gap:10px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li{margin:0;padding:0}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li input{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li input:checked+span{border:0 !important}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li input:checked+span::before{content:"";display:block;position:absolute;top:-2px;left:-2px;height:30px;width:30px;border:1px solid #000;border-radius:50%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li span{margin:0;padding:0;height:26px;width:26px;border-radius:50%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item.active::before{opacity:1;visibility:visible;transition-delay:0ms}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .product-variants-item--wrapper{width:100%;position:relative}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label-nav{display:flex;flex-direction:row;justify-content:space-between;align-items:center;cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label-nav.active .form-control-select-standard-handler{transform:scale(-1)}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label-nav .form-control-select-standard-handler{cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label{color:#462d26;font-size:14px;font-weight:700;font-family:"Inter",sans-serif;width:100%;max-width:200px;margin-bottom:0}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label .control-label-selected{font-weight:400}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item select{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom{display:none;position:absolute;left:-20px;right:-20px;top:calc(100% + 16px);z-index:10}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select{display:block;padding:25px;border:none;background:#fff;height:auto}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown{display:flex;flex-direction:column;row-gap:16px;margin:0;overflow:auto}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li{display:flex;flex-direction:row;-moz-column-gap:14px;column-gap:14px;margin:0;color:#110e0c;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li:not(:last-child){padding-bottom:16px;border-bottom:1px solid rgba(17,14,12,.1019607843)}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li.active .li-checkbox{background:#462d26;border-color:#462d26}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li.active .li-checkbox::before{content:"";position:absolute;top:8px;left:5.5px;width:8px;height:2px;background:#f9f7f2;transform:rotate(-45deg);transition:all 250ms ease-in-out}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li.active .li-checkbox::after{content:"";position:absolute;top:9px;left:4.5px;width:3.5px;height:2px;background:#f9f7f2;transform:rotate(45deg);transition:all 250ms ease-in-out}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li .li-checkbox{position:relative;display:block;width:19px;min-width:19px;height:19px;border:1px solid #d9cebe;border-radius:100%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .fabric-colors{display:flex;flex-direction:row;align-items:center;gap:9px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .fabric-colors a{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;text-decoration:underline}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart{padding:24px;background:#ece9e2}@media(max-width: 767px){body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart{position:relative;padding:24px 0}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart *{z-index:2}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart::after{content:"";position:absolute;top:0;bottom:0;left:50%;width:100svw;transform:translateX(-50%);background:#ece9e2;z-index:1}}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart>.control-label{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity{margin-bottom:10px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty{margin-bottom:0;margin-right:16px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;float:none;border:1px solid rgba(70,45,38,.8509803922);border-radius:1px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group input#quantity_wanted{order:2;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;padding:0;text-align:center;width:35px;border:none;background:rgba(0,0,0,0);height:29px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group button{padding:0;height:auto;color:rgba(70,45,38,.8509803922);font-size:14px;font-weight:500;font-family:"Inter",sans-serif;border:none;background:rgba(0,0,0,0)}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group button.btn{height:29px;padding:0 10px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group button.btn.bootstrap-touchspin-up{order:3}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group button.btn.bootstrap-touchspin-down{order:1}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .add{margin:0;width:100%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .add .add-to-cart{background:#e79332;margin:0;width:100%;color:#f9f7f2;font-size:14px;font-weight:500;font-family:"Inter",sans-serif;text-transform:initial}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .add .add-to-cart:hover{background:#110e0c}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .add .add-to-cart .material-icons{line-height:1;font-size:14px;height:auto;width:auto;vertical-align:baseline;margin-right:3px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .wishlist-button-add{margin-left:16px;width:30px;border-radius:0;background:rgba(0,0,0,0);box-shadow:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .wishlist-button-add i{background-image:url("/img/cms/icons/icon-heart.svg");background-position:center;background-repeat:no-repeat;background-size:contain;width:26px;height:26px;font-size:0}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart #product-availability{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-minimal-quantity{margin:0;display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-additional-info{display:none;margin:30px 0}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product{display:flex;flex-direction:column;row-gap:20px;margin:40px 0 0 0}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;color:#462d26;font-size:14px;font-weight:500;font-family:"Inter",sans-serif}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div .item-product,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile .item-product{margin-right:16px;padding:0;width:24px;height:24px}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div .item-product svg,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile .item-product svg{width:24px;height:24px}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div .item-product svg path,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile .item-product svg path{fill:rgba(0,0,0,0) !important}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div .block-title,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile .block-title{margin-right:10px}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div p,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile p{font-weight:700;margin:0}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .item-0 .block-description{text-decoration:underline;cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .item-1 .block-description{text-decoration:underline;cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .item-1 .block-description a{color:#111516;text-decoration:none}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .block-raty{width:100%;display:none}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .block-raty .block-raty--wrapper{display:flex;flex-direction:row;flex-wrap:wrap;gap:10px;padding-top:20px}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .block-raty .block-raty--wrapper img{height:35px}body#product .product-info-box .product-info-box-right .product-information #description-nav{padding:32px 24px;margin:0;list-style:none;display:flex;flex-direction:row}body#product .product-info-box .product-info-box-right .product-information #description-nav li:not(:last-child){padding-right:10px;margin-right:10px;border-right:1px solid rgba(17,14,12,.1019607843)}body#product .product-info-box .product-info-box-right .product-information #description-nav li a{color:#462d26;font-size:16px;font-weight:600;font-family:"Inter",sans-serif}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card{padding:24px;background:#ece9e2}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card p{color:#462d26;font-size:14px;font-family:"Inter",sans-serif}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card ul{margin-bottom:0}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card textarea{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;float:none;border:1px solid rgba(70,45,38,0.8509803922);border-radius:1px;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;background:rgba(0,0,0,0);height:44px;outline:none}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card button.btn{background:#e79332;margin:0;width:100%;color:#f9f7f2;font-size:14px;font-weight:500;font-family:"Inter",sans-serif;text-transform:initial;padding:10px;line-height:1.5}body#product .product-description-box{position:relative;margin-bottom:100px;padding-top:60px;padding-bottom:60px}body#product .product-description-box::before{content:"";position:absolute;top:0;left:50%;bottom:0;width:100svw;transform:translateX(-50%);background:#fff}body#product .product-description-box .c-row{display:flex;flex-direction:row;-moz-column-gap:60px;column-gap:60px}body#product .product-description-box .c-row .c-col{width:calc(50% - 30px)}@media(max-width: 767px){body#product .product-description-box .c-row .c-col{width:100%}}@media(max-width: 767px){body#product .product-description-box .c-row .c-col-2{display:none}}body#product .product-description-box .c-row .c-col-2 .product-description-box-img{position:sticky;top:150px}body#product .product-description-box .c-row .c-col-2 .product-description-box-img img{width:100%;max-width:-moz-fit-content;max-width:fit-content}body#product .product-description-box ul.product-accordion-box{padding:0;margin:0;list-style:none}body#product .product-description-box ul.product-accordion-box li.accordion-item.active .accordion-item-header img{transform:scale(-1)}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;-moz-column-gap:30px;column-gap:30px;padding:16px 0;border-bottom:1px solid rgba(17,14,12,.1019607843);cursor:pointer}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-header h3{color:#462d26;font-size:24px;font-weight:600;font-family:"Inter",sans-serif;margin:0}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-header img{transition:all .3s ease-in-out}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper{padding-top:24px;padding-bottom:64px;color:#000;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;line-height:1.4}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper strong{font-weight:700}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper img{max-width:-moz-fit-content;max-width:fit-content;width:100%;height:auto}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .js-product-details .product-reference{display:none}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .js-product-details .product-quantities{display:none}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .js-product-details .product-features .data-sheet{color:#111516}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .elementor-accordion .elementor-accordion-item .elementor-tab-title{display:flex;flex-direction:row;align-items:center}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .elementor-accordion .elementor-accordion-item .elementor-tab-title .elementor-accordion-title{line-height:1.5}body#product .product-description-box #product-details .product-reference,body#product .product-description-box #product-details .product-quantities{display:none !important}body#product .product-description-box section.product-features .data-sheet{color:#111516}body#product .tabs{border-radius:10px}body#product .tabs .nav-tabs .nav-item .nav-link{color:#111516;font-weight:400;font-size:16px}body#product .tabs .nav-tabs .nav-item .nav-link:hover{border-bottom:#e79332 3px solid}body#product .tabs .nav-tabs .nav-item .nav-link.active{color:#111516;border-color:#e79332}body#product #empty-product-comment{border-radius:10px}#blockcart-modal .modal-content .modal-body .product-name{color:#111516;font-weight:500;margin-bottom:16px}#blockcart-modal .modal-content .modal-body .cart-content-btn .btn.btn-primary{background:#e79332}body#cart #content-wrapper .card-block-title .h1{color:#462d26;font-size:24px;font-weight:700;font-family:"Inter",sans-serif;text-transform:initial;text-align:center;margin-bottom:16px}body#cart #content-wrapper .cart-grid{margin-bottom:150px}body#cart #content-wrapper .cart-grid .cart-grid-body .card{background:rgba(0,0,0,0)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview{padding:0}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table{width:100%}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table thead::after{content:"";display:block;height:24px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table thead tr th{color:rgba(70,45,38,.8509803922);font-size:12px;font-weight:400;font-family:"Inter",sans-serif;white-space:nowrap;padding:8px 0;border-bottom:1px solid rgba(17,14,12,.1019607843)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table thead tr th:not(:last-child){padding-right:20px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr:not(:first-child) td{padding-top:18px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr:not(:last-child) td{padding-bottom:18px;border-bottom:1px solid rgba(17,14,12,.1019607843)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td{vertical-align:top}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td:not(:last-child){padding-right:20px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-img img{width:80px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-desc{line-height:1}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-desc a{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-infos{line-height:1;margin-top:8px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-infos .product-card-info:not(:last-child){margin-bottom:8px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-infos .product-card-info span{color:rgba(70,45,38,.8509803922);font-size:12px;font-weight:400;font-family:"Inter",sans-serif}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price{padding-top:7px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price .current-price{line-height:1}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price .current-price .price{color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:700}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price .product-discount{line-height:1;margin-top:3px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price .product-discount .regular-price{color:rgba(70,45,38,.8509803922);font-size:12px;font-family:"Inter",sans-serif;font-weight:400}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;float:none;border:1px solid rgba(70,45,38,.8509803922);border-radius:1px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group input.js-cart-line-product-quantity{order:2;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;padding:0;text-align:center;width:35px;border:none;background:rgba(0,0,0,0);height:29px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group button{padding:0;height:auto;color:rgba(70,45,38,.8509803922);font-size:14px;font-weight:500;font-family:"Inter",sans-serif;border:none;background:rgba(0,0,0,0)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group button.btn{height:29px;padding:0 7px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group button.btn.bootstrap-touchspin-up{order:3}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group button.btn.bootstrap-touchspin-down{order:1}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-sum-price{padding-top:7px;line-height:1}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-sum-price strong{color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:700}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action{display:block;padding-top:9px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action .remove-from-cart{position:relative;width:10px;height:10px;display:block}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action .remove-from-cart::before{content:"";position:absolute;width:10px;height:1px;background:#bbb6aa;top:50%;left:50%;transform:translate(-50%, -50%) rotate(45deg)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action .remove-from-cart::after{content:"";position:absolute;width:10px;height:1px;background:#bbb6aa;top:50%;left:50%;transform:translate(-50%, -50%) rotate(-45deg)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action .remove-from-cart .material-icons{display:none}@media(max-width: 570px){body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table thead{display:none}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table,body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview tbody,body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview tr,body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td{display:block;width:100%}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview tbody{padding:20px;text-align:center}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview tr{margin-bottom:1rem;border:1px solid #ccc;border-radius:5px;padding:10px;background:#f9f9f9;border:1px solid rgba(17,14,12,0.1019607843)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td{position:relative;text-align:right;padding:15px 10px 15px 50% !important}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td::before{position:absolute;left:10px;top:50%;transform:translateY(-50%);white-space:nowrap;font-weight:bold;text-align:left}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td .product-card-qty{display:block;margin-left:auto;width:-moz-fit-content;width:fit-content}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td .product-card-action{width:-moz-fit-content;width:fit-content;margin-left:auto}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td .product-card-action .remove-from-cart::before{width:15px !important;height:2px !important}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td .product-card-action .remove-from-cart::after{width:15px !important;height:2px !important}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td>div{padding-top:0 !important}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(1)::before{content:"Obrazek"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(2)::before{content:"Nazwa produktu"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(3)::before{content:"Cena jednostkowa"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(4)::before{content:"Ilość"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(5)::before{content:"Cena łączna"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(6)::before{content:"Usuń"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .product-card-img img{max-width:100%;height:auto}}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .no-items{color:#462d26;font-size:16px;font-family:"Inter",sans-serif;font-weight:700;width:100%;display:block;text-align:center}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-line-info a{color:#111516;font-weight:400;font-size:16px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-price{margin:10px 0}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-price .product-discount .regular-price{color:#a9a8a8;font-weight:300;margin:0}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-price .product-discount .discount{background:#e79332}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-price .current-price .price{color:#111516;font-weight:600;font-size:16px}body#cart #content-wrapper .cart-summary{margin-bottom:24px;background:#ece9e2}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals{padding:24px 24px 0 24px}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line:not(:last-child){margin-bottom:8px}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line:last-child{margin-bottom:0}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line span{font-size:14px;font-family:"Inter",sans-serif}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line span.label{font-weight:500}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line span.value{font-weight:400}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-summary-totals{padding:16px 24px}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-summary-totals .cart-summary-line.cart-total{padding:0;border:0}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-summary-totals .cart-summary-line.cart-total span{font-size:14px;font-family:"Inter",sans-serif;font-weight:700}body#cart #content-wrapper .cart-summary .cart-detailed-actions{padding:0 24px 18px}body#cart #content-wrapper .cart-summary .cart-detailed-actions a.btn{color:#f9f7f2;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;padding:14px 12px;background-color:#e79332;text-transform:initial}body#cart #content-wrapper .cart-summary .card-payment-support{padding:0 24px 12px}body#cart #content-wrapper .cart-summary .card-payment-support ul{padding:0;margin:0;list-style:none;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:center;-moz-column-gap:30px;column-gap:30px;row-gap:12px}body#cart #content-wrapper .cart-summary .card-payment-support ul li img{max-width:44px}body#checkout #content-wrapper .cart-grid-body .checkout-step{padding:0;background-color:#f9f7f2}body#checkout #content-wrapper .cart-grid-body .checkout-step .step-title{color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:700;text-transform:initial;padding-bottom:10px;border-bottom:1px solid #462d26;margin-bottom:32px}body#checkout #content-wrapper .cart-grid-body .checkout-step .step-title .step-number::after{content:". "}body#checkout #content-wrapper .cart-grid-body .checkout-step.-current{opacity:1 !important}body#checkout #content-wrapper .cart-grid-body .checkout-step.-current .step-title{color:#e79332;border-bottom:1px solid #e79332}body#checkout #content-wrapper .cart-grid-body .checkout-step.-complete{opacity:.5}body#checkout #content-wrapper .cart-grid-body .checkout-step .content{padding:0}body#checkout #content-wrapper .cart-grid-body .checkout-step #customer-form{max-width:480px}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group label{color:#110e0c;font-size:12px;font-family:"Inter",sans-serif;font-weight:500;margin-bottom:4px}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group input.form-control{background:rgba(70,45,38,.1019607843);border:1px solid rgba(70,45,38,.1411764706);padding:14px 16px;color:#110e0c;font-size:14px;font-family:"Inter",sans-serif;font-weight:500}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group .btn-show-password-box{position:absolute;top:0;right:0;bottom:0;width:-moz-fit-content;width:fit-content}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group .btn-show-password-box .btn-show-password{padding:0;background:rgba(0,0,0,0);display:flex;height:100%;align-items:center;width:30px;outline:none}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group .form-control-comment{color:rgba(70,45,38,0.8509803922);font-size:12px;font-family:"Inter",sans-serif;font-weight:400}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-informations{margin-top:40px}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-informations .form-informations-title{color:#110e0c;font-size:16px;font-family:"Inter",sans-serif;font-weight:700}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-informations .form-informations-option{color:#110e0c;font-size:16px;font-family:"Inter",sans-serif;font-weight:400;font-style:initial !important}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-informations .form-informations-subtitle{display:none}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-footer{text-align:start;width:-moz-fit-content;width:fit-content}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-footer .btn{color:#f9f7f2;font-size:14px;font-weight:500;font-family:"Inter",sans-serif;background:#e79332;padding:12px 80px;text-transform:initial}body#checkout #content-wrapper .cart-grid-body .checkout-step #delivery-address{max-width:480px;margin-left:0}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options{max-width:480px}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option{padding:12px 16px;margin:0;border:1px solid rgba(70,45,38,.1411764706);border-radius:1px;-moz-column-gap:16px;column-gap:16px;min-height:initial;background:rgba(0,0,0,0)}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option:not(:last-child){margin-bottom:16px}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option .delivery-option-checkbox{width:-moz-fit-content;width:fit-content;line-height:0}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option .delivery-option-2{flex:1;display:flex;flex-direction:row;align-items:center;justify-content:space-between}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option .delivery-option-2 .carrier-price{color:#110e0c;font-family:"Inter",sans-serif;font-size:14px;font-weight:700}body#checkout #content-wrapper .cart-grid-body .checkout-step .order-options #delivery label{color:#110e0c;font-size:12px;font-family:"Inter",sans-serif;font-weight:500;margin-bottom:4px}body#checkout #content-wrapper .cart-grid-body .checkout-step .order-options #delivery textarea{width:100%;max-width:480px;border:1px solid rgba(70,45,38,.1411764706);background:rgba(70,45,38,.1019607843);border-radius:1px;resize:none;margin-bottom:30px}body#checkout #content-wrapper .cart-grid-body .checkout-step button[type=submit]{color:#f9f7f2;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;padding:12px 80px;background:#e79332;text-transform:initial;float:none !important}body#checkout #content-wrapper .cart-grid-body .checkout-step #conditions-to-approve ul li .condition-label{margin:0;line-height:1}body#checkout #content-wrapper .cart-grid-body .checkout-step #conditions-to-approve ul li .condition-label label{margin:0;line-height:1}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information{margin:0 0 20px 0;padding:24px;border:1px solid rgba(70,45,38,.1411764706)}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information p{color:#110e0c;font-size:14px;font-weight:700;font-family:"Inter",sans-serif}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information dl{border-left:1px solid rgba(70,45,38,.1411764706);border-right:1px solid rgba(70,45,38,.1411764706);border-top:1px solid rgba(70,45,38,.1411764706)}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information dl dt{border-right:1px solid rgba(70,45,38,.1411764706)}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information dl dt,body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information dl dd{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;background:rgba(0,0,0,0);margin:0;flex:0 0 50%;border-bottom:1px solid rgba(70,45,38,0.1411764706)}body#checkout #content-wrapper #js-checkout-summary{background:rgba(0,0,0,0)}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box{margin-bottom:16px;background-color:#ece9e2}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box>.card-block{padding:24px 24px 0 24px}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box .cart-summary-totals{padding:16px 24px 24px 24px}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box .cart-summary-totals .cart-total{line-height:1;padding:0}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box .cart-summary-totals .cart-total span{color:#462d26;font-size:14px;font-weight:700;font-family:"Inter",sans-serif}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box #cart-summary-product-list .media-list{margin-bottom:24px;padding-bottom:24px;border-bottom:1px solid rgba(70,45,38,.3)}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box #cart-summary-product-list .media-list .media:not(:last-child){margin-bottom:24px}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box #cart-summary-product-list .media-list .media .media-left img{width:40px}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box #cart-summary-product-list .media-list .media .media-body .product-name a{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;max-width:260px}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .h4{font-size:16px;font-weight:700;font-family:"Inter",sans-serif;margin-bottom:24px;text-transform:uppercase}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-left{padding-right:16px}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-name{line-height:1;margin-bottom:2px;display:block}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-name a{color:#111516;font-weight:600}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-specification .product-line-info{line-height:1;margin-bottom:2px}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-specification .product-line-info span{color:rgba(70,45,38,.8509803922);font-size:12px;font-family:"Inter",sans-serif;font-weight:400}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-specification .product-quantity{color:rgba(70,45,38,.8509803922);font-size:12px;font-family:"Inter",sans-serif;font-weight:400;line-height:1}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-price{color:#111516;font-weight:600}body#checkout #content-wrapper #js-checkout-summary .cart-summary-subtotals-container{padding:0;border:none}body#checkout #content-wrapper #js-checkout-summary .cart-summary-subtotals-container .cart-summary-line{line-height:1;margin-bottom:8px}body#checkout #content-wrapper #js-checkout-summary .cart-summary-subtotals-container .cart-summary-line span{color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:500}body#checkout #content-wrapper .delivery-options .delivery-option{border:none}body#order-confirmation .breadcrumb{display:none}body#order-confirmation #content-wrapper #main #registration-form{display:none}body#order-confirmation #content-wrapper #main section#content,body#order-confirmation #content-wrapper #main section#content-hook_payment_return,body#order-confirmation #content-wrapper #main section#content-hook-order-confirmation-footer{display:none}body#order-confirmation #content-wrapper #main section#content-hook_order_confirmation{margin-bottom:150px;margin-top:50px;background:rgba(0,0,0,0)}body#order-confirmation #content-wrapper #main section#content-hook_order_confirmation .card-title{color:#462d26;font-size:24px;font-weight:700;font-family:"Inter",sans-serif;margin-bottom:24px;text-align:center;display:flex;flex-direction:column;align-items:center;row-gap:32px;text-transform:initial}body#order-confirmation #content-wrapper #main section#content-hook_order_confirmation p{color:#1a1a18;font-size:16px;font-weight:400;font-family:"Inter",sans-serif;text-align:center;max-width:750px;margin-left:auto;margin-right:auto;margin-bottom:32px}body#order-confirmation #content-wrapper #main section#content-hook_order_confirmation .elementor-button{color:#f9f7f2;font-size:14px;font-weight:500;font-family:"Inter",sans-serif;padding:18px 80px;background:#e79332;margin:0 auto;display:flex;width:100%;max-width:-moz-fit-content;max-width:fit-content}body#order-confirmation footer#footer .footer-box-newsletter,body#order-confirmation footer#footer .footer-box-services,body#order-confirmation footer#footer .footer-box-other-info{display:none}footer#footer{background-color:#f9f7f2}.category-tiles-list{display:grid;grid-template-columns:repeat(6, 1fr);grid-gap:20px}.category-tiles-list a{display:block}body:not(#ets_blog_page) main #left-column>div.block{display:none !important}body#ets_blog_page #content-wrapper .ets-blog-wrapper-detail{border-radius:10px}body#ets_blog_page #left-column .title_block{color:#111516;font-size:20px;font-weight:400}body#ets_blog_page #left-column .ets_block_slider .ets_title_block{color:#111516;font-size:16px;font-weight:400}body#ets_blog_page ul.ets-blog-list>li .post-wrapper{border-radius:10px;overflow:hidden;display:flex;flex-direction:row;flex-wrap:wrap}body#ets_blog_page ul.ets-blog-list>li .post-wrapper .ets-blog-wrapper-content{background:#eff6f7;padding-top:15px;padding-bottom:15px}body#ets_blog_page ul.ets-blog-list>li .post-wrapper .ets_title_block{color:#111516;font-size:18px;font-weight:300;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.25;font-weight:400}body#ets_blog_page ul.ets-blog-list>li .post-wrapper .blog_description{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}body#ets_blog_page ul.ets-blog-list>li .post-wrapper .read_more{display:inline-block;color:#e79332;font-weight:400;text-decoration:underline;font-style:underline !important;border:none}.ets_blog_sidebar>.block{box-shadow:none !important;border-radius:10px}body #left-column .block-categories .category-top-menu li a.h6{color:#111516;font-size:20px;font-weight:400}body #left-column .block-categories .category-top-menu li .category-sub-menu li a{color:#111516;font-size:16px;font-weight:400}body#category #left-column>div{border-radius:10px}body#category #content-wrapper section#main div{border-radius:10px}.product-description{color:#000;font-size:15px;line-height:1.5}.product-description ul{list-style-type:disc;margin-left:25px}.product-description h3{color:#000 !important;font-size:18px}.data-sheet dd,.data-sheet dt{font-weight:400 !important;font-size:15px}#header-search{position:relative;width:100%;max-width:340px;padding-right:32px;margin-right:14px}#header-search::before{content:"";position:absolute;top:50%;right:0;width:1px;height:28px;background:rgba(17,14,12,.1);transform:translateY(-50%)}#header-search form.elementor-search>ul.elementor-search__products{background:#f9f7f2;border-radius:0;border:1px solid rgba(17,14,12,.1)}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item{background:#fff}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item:not(:last-child){margin-bottom:2px}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item .elementor-search__product-details .elementor-search__product-name{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item .elementor-search__product-details .elementor-search__product-category{display:none}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item .elementor-search__product-details .elementor-search__product-price{color:#462d26;font-size:14px;font-weight:700;font-family:"Inter",sans-serif}@media(min-width: 992px)and (max-width: 1024px){#header-search{display:block !important}}@media(min-width: 992px)and (max-width: 1024px){.mobile-search{display:none !important}}#header-menu .elementor-nav-menu>ul{justify-content:space-between;align-items:center;width:100%}#header-menu .elementor-nav-menu>ul::after{display:none}#header-menu .elementor-nav-menu .menu-item-separator{display:block;width:1px;height:14px;background:rgba(17,14,12,.1019607843)}#home-slider-box{width:100svw;margin-left:50%;transform:translateX(-50%)}#home-slider-box ul.carousel-inner{border-radius:0 !important}#home-slider-box figure{width:100%}@media(max-width: 991px){#home-slider-box figure img{min-height:390px;-o-object-fit:cover;object-fit:cover}}.home-slider .carousel-item .caption{width:100%;max-width:80%;bottom:auto;top:80px}@media(max-width: 991px){.home-slider .carousel-item .caption{top:36px;left:40px}}.home-slider .carousel-item .caption .caption-description h2{color:#f9f7f2;font-size:64px;margin-bottom:18px;line-height:1.1;font-weight:500;font-family:"Inter",sans-serif}.home-slider .carousel-item .caption .caption-description h2 span{color:#e79332}@media(max-width: 991px){.home-slider .carousel-item .caption .caption-description h2{font-size:32px;margin-bottom:10px}}.home-slider .carousel-item .caption .caption-description p{font-size:16px;color:#f9f7f2}.home-slider .slide-button{position:relative;display:flex;flex-direction:row;align-items:center;-moz-column-gap:12px;column-gap:12px;padding:16px 45px;width:-moz-fit-content;width:fit-content;margin-top:40px;border-top:1px solid #e79332;border-bottom:1px solid #e79332;color:#e79332;font-size:16px;font-weight:500}.home-slider .slide-button img{width:100%;max-width:24px}.home-slider .slide-button::before{content:"";position:absolute;left:-1px;top:-2px;bottom:0;width:10px;height:calc(100% + 4px);background-image:url("/img/cms/icons/btn-side-line.svg");background-position:center;background-size:contain;background-repeat:no-repeat}.home-slider .slide-button::after{content:"";position:absolute;right:-1px;top:-2px;bottom:0;width:10px;height:calc(100% + 4px);background-image:url("/img/cms/icons/btn-side-line.svg");background-position:center;background-size:contain;background-repeat:no-repeat;transform:scale(-1)}@media(max-width: 991px){.home-slider .slide-button{font-size:13px}}.home-box-1>.elementor-column-wrap>.elementor-widget-wrap{display:grid;grid-template-columns:7fr 5fr;grid-template-rows:1fr 1fr;grid-template-areas:"item1 item2" "item1 item3";gap:20px}.home-box-1>.elementor-column-wrap>.elementor-widget-wrap>.elementor-element:nth-child(1){grid-area:item1}.home-box-1>.elementor-column-wrap>.elementor-widget-wrap>.elementor-element:nth-child(2){grid-area:item2}.home-box-1>.elementor-column-wrap>.elementor-widget-wrap>.elementor-element:nth-child(3){grid-area:item3}@media(max-width: 767px){.home-box-1>.elementor-column-wrap>.elementor-widget-wrap{grid-template-columns:1fr;grid-template-rows:auto;grid-template-areas:"item1" "item2" "item3"}}.home-box-1 .home-box1-tile:nth-child(1) .elementor-cta-content .elementor-button::before{content:url("/img/cms/Home/Group 1223.svg")}.home-box-1 .home-box1-tile>.elementor-widget-container{height:100%}.home-box-1 .home-box1-tile>.elementor-widget-container>.elementor-cta{height:100%}.home-box-1 .home-box1-tile .elementor-cta-content{position:absolute;inset:0;background:rgba(0,0,0,0);justify-content:space-between;align-content:space-between}.home-box-1 .home-box1-tile .elementor-cta-content .elementor-button{position:relative;padding:0;display:flex;flex-direction:row;align-items:center;gap:10px}.home-box-1 .home-box1-tile .elementor-cta-content .elementor-button::before{content:url("/img/cms/Home/Group 1224.svg")}.home-box-info{position:relative}.home-box-info::before{content:"";position:absolute;top:0;left:50%;height:1px;width:100vw;transform:translateX(-50%);background:rgba(170,138,94,.25)}.home-box-info::after{content:"";position:absolute;bottom:0;left:50%;height:1px;width:100vw;transform:translateX(-50%);background:rgba(170,138,94,.25)}.home-box-info>.elementor-container>.elementor-row{align-items:center}.home-box-info .home-box-info-img img{max-width:unset}.footer-box-services{position:relative}.footer-box-services::before{content:"";position:absolute;bottom:0;left:50%;height:1px;width:100vw;transform:translateX(-50%);background:rgba(170,138,94,.25)}.footer-box-services .elementor-widget-wrap{flex-direction:row;flex-wrap:nowrap}.footer-box-other-info>.elementor-container>.elementor-row{-moz-column-gap:80px;column-gap:80px;position:relative}@media(min-width: 1025px){.footer-box-other-info>.elementor-container>.elementor-row::before{content:"";position:absolute;top:-60px;bottom:-60px;left:50%;width:1px;transform:translateX(-50%);background:rgba(170,138,94,.25)}}nav.pagination .page-list{display:flex;align-items:center;justify-content:center;gap:10px;background:rgba(0,0,0,0)}nav.pagination .page-list .pagination-item.prev a{background:rgba(0,0,0,0);transition:all 250ms ease-in-out}nav.pagination .page-list .pagination-item.prev a img{transition:all 250ms ease-in-out}nav.pagination .page-list .pagination-item.prev a:hover{background:#ffa629}nav.pagination .page-list .pagination-item.prev a:hover img{filter:brightness(0) invert(1)}nav.pagination .page-list .pagination-item.next a{background:rgba(0,0,0,0);transition:all 250ms ease-in-out}nav.pagination .page-list .pagination-item.next a img{transition:all 250ms ease-in-out;transform:scale(-1)}nav.pagination .page-list .pagination-item.next a:hover{background:#ffa629}nav.pagination .page-list .pagination-item.next a:hover img{filter:brightness(0) invert(1)}nav.pagination .page-list .pagination-item.current a{color:#fff;background:#ffa629}nav.pagination .page-list .pagination-item .spacer{display:flex;align-items:center;justify-content:center;padding:5px 11px;height:33px;width:33px;color:#9f928c;font-size:14px;font-weight:500;font-family:"Inter",sans-serif}nav.pagination .page-list .pagination-item a{display:flex;align-items:center;justify-content:center;color:#9f928c;font-family:"Inter",sans-serif;font-size:14px;font-weight:500;letter-spacing:-0.5px;padding:5px 11px;height:33px;min-width:33px;background:#ece9e2;border-radius:1px;transition:all 250ms ease-in-out}nav.pagination .page-list .pagination-item a:hover{color:#fff;background:#ffa629}body#category section#main #subcategories{padding:0;margin:0;background:rgba(0,0,0,0)}body#category section#main #subcategories .subcategory-heading{display:none}body#category section#main #subcategories .subcategories-list{display:flex;flex-direction:row;gap:16px;flex-wrap:wrap}body#category section#main #subcategories .subcategories-list li .subcategory-item{display:flex;flex-direction:row;-moz-column-gap:16px;column-gap:16px;align-items:center;background:#ece9e2;border-radius:50px;padding:8px 24px 8px 24px;height:100%}body#category section#main #subcategories .subcategories-list li .subcategory-item .subcategory-image{width:43px;height:43px;padding:0;background:#fff;border-radius:100%;margin-left:-16px}body#category section#main #subcategories .subcategories-list li .subcategory-item .subcategory-image img{width:100%;height:100%;-o-object-fit:contain;object-fit:contain;border-radius:100%}body#category section#main #subcategories .subcategories-list li .subcategory-item .subcategory-name{color:#462d26;font-size:16px;font-weight:600;font-family:"Inter",sans-serif;margin:0}nav.breadcrumb{margin-bottom:1.563rem}nav.breadcrumb ol{display:flex;flex-direction:row;-moz-column-gap:16px;column-gap:16px;align-items:center}nav.breadcrumb ol li span{color:#462d26;font-size:14px;font-weight:500;font-family:"Inter",sans-serif}nav.breadcrumb ol li.separator img{width:5px;height:9px}body#cms.cms-id-5 footer#footer section.footer-box-newsletter,body#cms.cms-id-6 footer#footer section.footer-box-newsletter,body#cms.cms-id-7 footer#footer section.footer-box-newsletter{display:none}body#cms.cms-id-5 footer#footer section.footer-box-services,body#cms.cms-id-6 footer#footer section.footer-box-services,body#cms.cms-id-7 footer#footer section.footer-box-services{display:none}body#cms.cms-id-5 footer#footer section.footer-box-other-info,body#cms.cms-id-6 footer#footer section.footer-box-other-info,body#cms.cms-id-7 footer#footer section.footer-box-other-info{display:none}body#cms section#main header.page-header{margin-bottom:32px}body#cms section#main header.page-header h1{color:#462d26;font-size:32px;font-family:"Inter",sans-serif;font-weight:700;margin:0}#cms-citys .elementor-icon-list-items{display:grid;grid-template-columns:repeat(auto-fill, minmax(250px, 1fr));gap:20px}#cms-citys .elementor-icon-list-items li .elementor-icon-list-text{display:block;width:100%;text-align:center;padding:12px 24px;background:#462d26}#js-product-list>.products{row-gap:40px}#basket-side-panel .elementor-cart__title{text-align:center;min-height:unset;line-height:1;padding:20px 0 25px}#basket-side-panel .elementor-cart__products .elementor-cart__product{position:relative}#basket-side-panel .elementor-cart__products .elementor-cart__product .elementor-cart__product-name{padding-left:16px}#basket-side-panel .elementor-cart__products .elementor-cart__product .elementor-cart__product-attrs{padding:3px 0}#basket-side-panel .elementor-cart__products .elementor-cart__product .elementor-cart__product-price{padding-left:16px}#basket-side-panel .elementor-cart__products .elementor-cart__product .elementor-cart__product-remove{position:absolute;top:20px;right:0}#basket-side-panel .elementor-cart__footer-box{position:relative;margin-top:auto}#basket-side-panel .elementor-cart__footer-box::before{content:"";position:absolute;inset:0 -30px;background:#ece9e2;z-index:-1}#basket-side-panel .elementor-cart__footer-box .elementor-cart__summary{border:none}#basket-side-panel .elementor-cart__footer-box .elementor-cart__summary>span{margin-bottom:5px}#basket-side-panel .elementor-cart__footer-box .elementor-cart__footer-buttons{width:100%}#basket-side-panel .elementor-cart__footer-delivery{margin-bottom:20px}#basket-side-panel .elementor-cart__footer-delivery ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:row;align-items:center;justify-content:center;-moz-column-gap:11px;column-gap:11px}#basket-side-panel .elementor-cart__footer-delivery ul li span{color:#462d26;font-family:"Inter",sans-serif;font-size:12px;font-weight:500}.custom-checkbox{display:flex;align-items:flex-start;-moz-column-gap:10px;column-gap:10px}.custom-checkbox label{padding:0;margin:0;cursor:pointer;color:#110e0c;font-size:14px;font-family:"Inter",sans-serif;font-weight:400}input[type=checkbox],input[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;position:relative;width:15px;height:15px;min-width:15px;min-height:15px;display:inline-block;border:1px solid #d9cebe;border-radius:3px;transition:all 250ms ease-in-out;overflow:hidden;cursor:pointer}input[type=checkbox]::before,input[type=radio]::before{content:"";position:absolute;top:-5px;left:15px;width:7px;height:2px;background:#f9f7f2;transform:rotate(-45deg);transition:all 250ms ease-in-out}input[type=checkbox]::after,input[type=radio]::after{content:"";position:absolute;top:-4px;left:-8px;width:4px;height:2px;background:#f9f7f2;transform:rotate(45deg);transition:all 250ms ease-in-out}input[type=checkbox]:checked,input[type=radio]:checked{background:#462d26;border-color:#462d26}input[type=checkbox]:checked::before,input[type=radio]:checked::before{top:6px;left:4px}input[type=checkbox]:checked::after,input[type=radio]:checked::after{top:7px;left:3px}body#authentication section#main .page-header{margin-bottom:32px}body#authentication section#main .page-header h1{color:#462d26;font-size:24px;font-weight:700;font-family:"Inter",sans-serif;text-align:center;margin-bottom:0}body#authentication section#main #content{background:rgba(0,0,0,0);max-width:480px;margin:0 auto 150px}body#authentication section#main #content form label{color:#110e0c;font-size:12px;font-weight:500;font-family:"Inter",sans-serif}body#authentication section#main #content form input[type=text]{border:1px solid rgba(70,45,38,.1411764706);background:rgba(70,45,38,.1019607843)}body#authentication section#main #content form .btn-show-password-box{width:-moz-fit-content;width:fit-content;position:absolute;right:0}body#authentication section#main #content form .btn-show-password-box .btn-show-password{background:rgba(0,0,0,0)}body#authentication section#main #content form .forgot-password{text-align:left}body#authentication section#main #content form .forgot-password a{color:#110e0c;font-size:12px;font-weight:500;font-family:"Inter",sans-serif;text-decoration:underline}body#authentication section#main #content form button{color:#f9f7f2;background:#e79332;padding:14px 80px;text-transform:initial}body#authentication section#main #content hr{margin:32px 0 16px}body#authentication section#main #content .no-account a{color:#110e0c;font-size:14px;font-weight:500;font-family:"Inter",sans-serif}body#authentication section#main #content .register-form>p{display:none}body#authentication section#main #content .register-form form .form-check{display:flex;flex-direction:row;-moz-column-gap:30px;column-gap:30px}body#authentication section#main #content .register-form form .form-check label{margin:0;display:flex;align-items:center;-moz-column-gap:5px;column-gap:5px}body#authentication section#main #content .register-form form .form-check label .custom-radio{line-height:1}body#authentication section#main #content .register-form form footer.form-footer{display:flex;align-items:center;justify-content:center;margin:30px 0 0 0}@media(max-width: 767px){.newsletter-form form.elementor-email-subscription .elementor-field-type-subscribe{display:flex;flex-direction:row;row-gap:16px;flex-wrap:wrap}.newsletter-form form.elementor-email-subscription .elementor-field-type-subscribe button{width:100%}}.newsletter-form form.elementor-email-subscription .elementor-checkbox-label{color:#fff}.newsletter-form .elementor-field-label{display:flex;gap:10px;margin-top:10px}.newsletter-form .elementor-field-label .elementor-checkbox-label{font-size:12px;font-weight:500;font-family:"Inter",sans-serif}#content-wrapper a[target=raty_procedura]{display:none !important}.leo-megamenu{margin-bottom:0}.leo-megamenu .dropdown-menu{background:#f9f7f2;border:1px solid rgba(17,14,12,.1019607843);overflow:auto}.leo-megamenu .dropdown-menu a:hover{color:#e79332 !important;text-decoration:underline}.leo-megamenu .leo-top-menu ul.nav.navbar-nav>li:last-child{padding-right:0}.leo-megamenu .leo-top-menu ul.nav.navbar-nav>li:last-child::after{display:none}.leo-top-menu .nav{display:flex;align-items:center;width:100%}.leo-top-menu .nav>li{position:relative;padding:0}.leo-top-menu .nav>li:first-child{padding-left:0}.leo-top-menu .nav>li.promo-item>a[href="https://masimmo.pl/promocje/"] span{color:#e79332 !important}.leo-top-menu .nav>li.promo-item>a[href="https://masimmo.pl/promocje/"]:hover span{color:#232323 !important}.leo-top-menu .nav>li:not(:first-child)>a{padding-left:23.5px}@media(max-width: 1200px){.leo-top-menu .nav>li:not(:first-child)>a{padding-left:19px}}@media(max-width: 1100px){.leo-top-menu .nav>li:not(:first-child)>a{padding-left:15px}}.leo-top-menu .nav>li:not(:last-child)>a{position:relative;padding-right:23.5px}@media(max-width: 1200px){.leo-top-menu .nav>li:not(:last-child)>a{padding-right:19px}}@media(max-width: 1100px){.leo-top-menu .nav>li:not(:last-child)>a{padding-right:15px}}.leo-top-menu .nav>li:not(:last-child)>a::before{content:"";display:block !important;width:1px;height:14px;background:rgba(17,14,12,0.1019607843);position:absolute;right:0;top:50%;margin-top:-7px}.leo-top-menu .nav>li>a{text-transform:uppercase;font-weight:600}.leo-top-menu .nav a{font-family:"Inter",sans-serif;font-size:14px;font-weight:400;white-space:nowrap}.leo-top-menu .nav a:hover{color:#e79332;text-decoration:underline}.leo-top-menu .nav a:hover span{color:#e79332}.leo-top-menu .nav a::after{display:none !important}.leo-top-menu .nav a span{text-transform:uppercase}.cart-grid-footer{display:flex;align-items:center;gap:20px}.cart-grid-footer img{height:30px}#popular-products h2,#new-products h2{font-family:"Inter";color:#462d26;font-size:36px;font-weight:500}#products .sort-by-row{display:flex;justify-content:flex-end;gap:20px;align-items:center}#products .sort-by-row .products-sort-order .dropdown-menu{background:#fff;width:100%}#products .sort-by-row .products-sort-order .dropdown-menu a{white-space:nowrap;font-size:14px;font-family:"Inter";font-weight:400}#products .sort-by-row .products-sort-order .dropdown-menu a:hover{background:#fff;font-weight:700;color:#462d26}#products .sort-by-row .products-sort-order button{background:none;border:0;display:flex;justify-content:space-between;align-items:center;color:#462d26;font-family:"Inter";font-size:16px;font-weight:700;width:350px}#search_filters{background:none;border-top:1px solid rgba(17,14,12,.1019607843);border-bottom:1px solid rgba(17,14,12,.1019607843);border-radius:0 !important;padding-left:0;padding-right:0}#search_filters .head{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}#search_filters .head .h6{font-size:16px;font-weight:700;font-family:"Inter";text-transform:uppercase;color:#462d26;margin-bottom:0;display:flex;align-items:center;-moz-column-gap:5px;column-gap:5px}#search_filters .head .js-search-filters-clear-all{background:#462d26;color:#fff}#search_filters .content{gap:20px;background:#fff;padding:25px}#search_filters .content section.facet:first-child{padding-top:0}#search_filters .content section.facet:not(:first-child){padding-top:1.625rem}#search_filters .content .h6{font-weight:700;font-size:16px;font-family:"Inter";margin-bottom:15px}#search_filters .content .custom-checkbox{top:0;position:static}#search_filters .content .facet-label{display:flex;gap:10px;align-items:center;margin-bottom:10px}#search_filters .content .facet-label a{margin-top:0}#search_filters .content .faceted-slider>li>p{color:#462d26;font-family:"Inter",sans-serif;font-size:14px;font-weight:700}#js-product-list-top{padding:0 20px}.active_filters{background:#fff;border-radius:10px;color:#462d26}.active_filters .filter-block{background:#462d26;color:#fff;padding:3px 10px}.active_filters .filter-block i{text-shadow:none;color:#fff !important}#contact main .container>.row:nth-child(2){display:grid;grid-template-columns:310px 1fr;gap:32px}@media(max-width: 767px){#contact main .container>.row:nth-child(2){grid-template-columns:1fr}}#contact main .container>.row:nth-child(2) #left-column{display:block;width:100%;max-width:100%;padding:0}#contact main .container>.row:nth-child(2) #content-wrapper{display:block;width:100%;max-width:100%;padding:0}#contact main .container>.row:nth-child(2) #content-wrapper #content{padding:40px}#contact main .container>.row:nth-child(2) #content-wrapper #content h3{font-size:32px;color:#110e0c;font-family:"Inter";font-weight:600;margin-bottom:32px}#contact main .container>.row:nth-child(2) #content-wrapper #content form .psgdpr_consent_message{display:grid;grid-template-columns:20px 1fr;gap:5px;align-items:center}#contact main .container>.row:nth-child(2) #content-wrapper #content form .btn-primary{width:277px;display:flex;align-items:center;justify-content:center;font-size:14px;font-family:"Inter";text-transform:none;font-weight:500;height:47px}#contact main .container>.row:nth-child(2) #content-wrapper #content form .btn-primary:hover{background:#462d26}#contact main .container>.row:nth-child(2) #content-wrapper #content form label{color:#110e0c;font-size:12px;font-weight:500;font-family:"Inter";margin-bottom:4px}#contact main .container>.row:nth-child(2) #content-wrapper #content form label[for=file-upload].btn-default{background:#462d26;color:#fff;height:47px;display:flex;align-items:center;justify-content:center}#contact main .container>.row:nth-child(2) #content-wrapper #content form input[type=email],#contact main .container>.row:nth-child(2) #content-wrapper #content form input[type=text],#contact main .container>.row:nth-child(2) #content-wrapper #content form select{height:47px;display:flex;align-items:center;justify-content:flex-start;padding:0 16px;font-size:14px;color:#110e0c;font-family:"Inter";border:1px solid rgba(70,45,38,.1411764706);background-color:#f9f7f2}#contact main .container>.row:nth-child(2) #content-wrapper #content form input[type=email]:focus,#contact main .container>.row:nth-child(2) #content-wrapper #content form input[type=text]:focus,#contact main .container>.row:nth-child(2) #content-wrapper #content form select:focus{outline:none;box-shadow:none}#contact main .container>.row:nth-child(2) #content-wrapper #content form textarea{padding:0 16px;font-size:14px;color:#110e0c;font-family:"Inter";border:1px solid rgba(70,45,38,.1411764706);background-color:#f9f7f2;padding:10px}#contact main .container>.row:nth-child(2) #content-wrapper #content form textarea:focus{outline:none;box-shadow:none}.elementor-widget-product-carousel:hover .elementor-swiper-button{opacity:1 !important}.elementor-widget-product-carousel:hover .elementor-swiper-button.swiper-button-disabled{opacity:.3 !important}.elementor-widget-product-carousel:not(:hover) .elementor-swiper-button.elementor-swiper-button-prev{left:-10px}.elementor-widget-product-carousel:not(:hover) .elementor-swiper-button.elementor-swiper-button-next{right:-10px}.elementor-swiper-button{background:#ebe3d7;border-radius:100%;width:33px;height:33px;display:flex;align-items:center;justify-content:center;opacity:0 !important;top:141.5px;transition:all 250ms ease-in-out}.elementor-swiper-button i{padding-bottom:2px}.elementor-swiper-button.elementor-swiper-button-prev i{padding-right:3px}.elementor-swiper-button.elementor-swiper-button-prev i::before{content:url("/img/cms/icons/slider-arrow-left-brown.svg")}.elementor-swiper-button.elementor-swiper-button-next i{padding-left:3px}.elementor-swiper-button.elementor-swiper-button-next i::before{content:url("/img/cms/icons/slider-arrow-right-brown.svg")}.leo-megamenu .navbar-toggler.c-navbar-toggler{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:8px;background:#e9e3d7;margin:0;padding:18px 24px;width:auto;outline:none !important}.leo-megamenu .navbar-toggler.c-navbar-toggler .c-sr-only{color:#110e0c;font-family:"Inter",sans-serif;font-size:11px;font-weight:500}@media(max-width: 991px){#header-panel-box .header-panel-box-row-1{margin-bottom:15px}}#header-panel-box .header-panel-box-row-1>div>.elementor-row{flex-wrap:nowrap;align-items:center}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap{flex-wrap:nowrap;align-items:center}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ps-widget-module{margin-bottom:0;width:-moz-fit-content;width:fit-content}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search>.elementor-widget-container{border:1px solid #e9e3d7;min-height:44px}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container button.elementor-search__submit{order:1}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container input.elementor-search__input{order:2;padding-left:0}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container input.elementor-search__input::-moz-placeholder{font-size:11px;font-weight:500}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container input.elementor-search__input::placeholder{font-size:11px;font-weight:500}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container .elementor-search__clear{order:3}section.off-canvas-nav-megamenu nav.offcanvas-mainnav{background:#fff}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu{text-align:initial;margin:24px 24px 0 24px;display:flex;flex-direction:row;justify-content:space-between}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu>a img{width:100%;max-width:200px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu .off-canvas-nav-close{margin:0;position:relative;font-size:0;width:14px;height:14px;min-width:14px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu .off-canvas-nav-close::before{content:"";position:absolute;width:2px;height:14px;background:#b8b7b6;top:50%;left:50%;transform:translate(-50%, -50%) rotate(45deg)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu .off-canvas-nav-close::after{content:"";position:absolute;width:2px;height:14px;background:#b8b7b6;top:50%;left:50%;transform:translate(-50%, -50%) rotate(-45deg)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu{padding:28px 24px 24px 24px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item.open-sub>a{border:none !important}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item.open-sub>a .menu-title{color:#e79332}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item.open-sub .dropdown-menu{border-bottom:1px solid rgba(17,14,12,.1019607843)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item a{padding-top:16px;padding-bottom:16px;line-height:1;border-color:rgba(17,14,12,.1019607843)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item a .menu-title{color:#110e0c;font-size:14px;font-weight:600;font-family:"Inter",sans-serif}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .caret{top:7px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .caret::before{content:url("/img/cms/icons/arrow-down-brown-mini.svg")}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-menu .leo-widget{padding:0}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-menu .leo-widget div.menu-title{padding:0}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-menu .leo-widget div.menu-title a{color:#110e0c;font-size:14px;font-weight:600;font-family:"Inter",sans-serif;padding-top:14px;padding-bottom:14px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-menu .leo-widget ul li a{color:#110e0c;font-size:14px;font-weight:600;font-family:"Inter",sans-serif;padding-top:14px;padding-bottom:14px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item.promo-item>a>.menu-title{color:#c40000}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub{padding-bottom:20px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub .dropdown-menu-inner,section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub ul{padding-left:15px;border-left:1px solid rgba(17,14,12,.1)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub .dropdown-menu-inner .mega-col ul{margin-bottom:20px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub .dropdown-menu-inner .mega-col .leo-widget[data-id_widget="1753179161"]{display:none}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub ul li a{font-weight:400 !important;padding:10px 0 !important}.dropdown-menu .leo-widget{padding-bottom:20px}header.page-header h1{color:#232323}form .form-group.form-group-alias{display:none !important}.elementor-cta-absolute-link{position:absolute;inset:0;z-index:1}.filter-block-all{display:inline-block;margin-right:.625rem;margin-bottom:.625rem}.filter-block-all button{margin:0 !important}.filter-block-all button .material-icons{margin:0}.scroll-brn-box{position:fixed;bottom:38px;right:100px;z-index:10000000;opacity:0;visibility:hidden;transition:all 250ms ease-in-out}.scroll-brn-box.active{opacity:1;visibility:visible}.scroll-brn-box a{width:56px;height:56px;background:#e79332;border-radius:100%;display:flex;align-items:center;justify-content:center;line-height:0}.scroll-brn-box a svg{width:16px;height:16px}@media(max-width: 767px){.scroll-brn-box{left:50%;right:auto;transform:translateX(-50%)}}.cart-voucher .promo-name{padding:10px}.cart-voucher .promo-name .cart-summary-line{display:flex;flex-direction:row;justify-content:space-between}.cart-voucher .promo-name .cart-summary-line>.label{text-align:left}.cart-voucher .promo-name .cart-summary-line .float-xs-right{min-width:-moz-fit-content;min-width:fit-content}#category-description{width:100%}#moved-category-structure .elementor-cta-content>div{width:100%}.block-promo .block-promo.promo-highlighted{color:#000;margin-top:10px}body.ce-kit-1{color:#000}.page-footer,.wishlist-footer-links{color:#000}.page-footer a,.wishlist-footer-links a{color:#000 !important}.gm_omniprice{display:block;width:100%}section#checkout-payment-step .payment-options-custom{display:flex;flex-direction:row;flex-wrap:wrap;-moz-column-gap:15px;column-gap:15px;row-gap:10px;margin-bottom:20px}section#checkout-payment-step .payment-options-custom>.js-payment-option-form,section#checkout-payment-step .payment-options-custom>.js-additional-information{display:none !important}section#checkout-payment-step .payment-options-custom .payment-option-title{color:#111516;font-size:14px;font-family:"Inter",sans-serif;font-weight:700;text-transform:initial;margin:0 !important;display:block;width:100%;padding-top:15px}section#checkout-payment-step .payment-options-custom .payment-option-title-1{order:1}section#checkout-payment-step .payment-options-custom .payment-option-title-2{order:100}section#checkout-payment-step .payment-options-custom .payment-option-title-3{order:200}section#checkout-payment-step .payment-options-custom .payment-item{position:relative;min-height:60px}section#checkout-payment-step .payment-options-custom .payment-item[option-name=paynow]{order:2}section#checkout-payment-step .payment-options-custom .payment-item[option-name=ps_wirepayment]{order:201}section#checkout-payment-step .payment-options-custom .payment-item[option-name=caraty]{order:101}section#checkout-payment-step .payment-options-custom .payment-item[option-name=santandercredit]{order:102}section#checkout-payment-step .payment-options-custom .payment-item[option-name=ps_cashondelivery]{order:202}section#checkout-payment-step .payment-options-custom .payment-item[option-name=ps_checkpayment]{order:203}section#checkout-payment-step .payment-options-custom .payment-item[option-name=payment-option-4]{order:103}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option{height:100%;margin:0 !important}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option>label{display:flex;flex-direction:column;align-items:center;justify-content:center;row-gap:10px;padding:10px 15px;margin:0;height:100%;color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;line-height:1}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option>label img{order:1}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option>label span{order:2}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option .custom-radio{margin:0 !important}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option .custom-radio input{position:absolute;inset:0 !important;width:100% !important;height:100% !important;background:rgba(0,0,0,0)}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option .custom-radio input::before,section#checkout-payment-step .payment-options-custom .payment-item>.payment-option .custom-radio input::after{display:none !important}.navbar-nav.megamenu li:nth-child(7)>a{color:#e79332 !important}/*# sourceMappingURL=custom.css.map */ \ No newline at end of file +body>main{overflow-x:hidden}html{scroll-padding-top:150px;scroll-behavior:smooth}body{font-size:15px;line-height:1.5;color:#232323}body .elementor-widget-text-editor{color:#232323}body h3{color:#232323}body#index footer#footer section.footer-box-newsletter{display:none !important}body#category section#wrapper section#main{margin-bottom:100px}body#category section#wrapper section#main #product-list-header *{color:#000}body#category section#wrapper section#main #product-list-header strong{font-weight:600}body#category section#wrapper section#main #product-list-header p{margin-bottom:10px}#footer a{color:#c5c5c5;transition:all 250ms ease-in-out}#footer a:hover{color:#e79332;text-decoration:none}a{color:#e79332}.btn-1{display:inline-block;color:#111516;border:1px solid #e79332;padding:15px;background:#fff;transition:all 250ms ease-in-out;cursor:pointer}.btn-1:hover{color:#fff;background:#e79332}.btn-primary{color:#fff;background:#e79332;transition:all 250ms ease-in-out}.btn-primary:hover{color:#fff;background:#d3ba67}#box-newsletter{position:relative}#box-newsletter::before{content:"";position:absolute;width:100vw;left:50%;top:0;bottom:0;transform:translateX(-50%);background-color:#fff}.simple-blog-posts .elementor-swiper-button{color:#e79332}.simple-blog-posts .elementor-swiper-button.elementor-swiper-button-next{right:0}.simple-blog-posts .elementor-swiper-button.elementor-swiper-button-prev{left:0}.simple-blog-posts #simple-blog-box{padding:0 29px}.simple-blog-posts #simple-blog-box .simple-blog-post{border-radius:10px;overflow:hidden}.simple-blog-posts #simple-blog-box .simple-blog-post ._image img{height:100%;max-height:200px;width:100%;-o-object-fit:cover;object-fit:cover;-o-object-position:center;object-position:center}.simple-blog-posts #simple-blog-box .simple-blog-post ._content{padding:20px;background-color:#eff6f7}.simple-blog-posts #simple-blog-box .simple-blog-post ._content .post-title{color:#111516;font-size:18px;font-weight:300;margin:0 0 .7em;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.25;font-weight:400}.simple-blog-posts #simple-blog-box .simple-blog-post ._content a._btn{display:inline-block;color:#e79332;font-weight:400;text-decoration:underline}.js-product.product article.product-miniature:hover .thumbnail-container .wishlist-button-add{opacity:1;visibility:visible;transform:translateY(0)}.js-product.product article.product-miniature:hover .thumbnail-container ul.product-flags{transform:translateX(calc(-100% - 30px))}.js-product.product article.product-miniature .thumbnail-container{width:100%;border:1px solid #eff6f7}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top{background:#fff}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket{display:flex;align-items:center;justify-content:center}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket .add-to-cart{font-family:"Inter",sans-serif;font-size:12px;font-weight:700;padding:8px 16px;display:flex;align-items:center;background:#462d26;border-radius:1px;-moz-column-gap:8px;column-gap:8px}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket .add-to-cart:hover{background:#e79332}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket .add-to-cart i{font-size:15px;margin-bottom:2px}.js-product.product article.product-miniature .thumbnail-container .thumbnail-top .product-add-to-basket .add-to-cart span{line-height:1;margin-bottom:1px;font-size:14px;font-weight:700}.js-product.product article.product-miniature .thumbnail-container .product-description{margin-top:14px}.js-product.product article.product-miniature .thumbnail-container .product-description::after{display:none !important}.js-product.product article.product-miniature .thumbnail-container .product-description .product-title{margin-bottom:14px;line-height:1}.js-product.product article.product-miniature .thumbnail-container .product-description .product-title a{color:#462d26;font-family:"Inter",sans-serif;font-size:14px;font-weight:400;line-height:1.2}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping .regular-price{font-size:14px;font-family:"Inter",sans-serif;color:rgba(70,45,38,.34);font-weight:700}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping .price{color:#462d26;font-family:"Inter",sans-serif;font-size:14px;font-weight:700}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping.product-price-discount{display:flex;flex-direction:row;-moz-column-gap:10px;column-gap:10px}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping.product-price-discount .price{order:1;color:#c40000}.js-product.product article.product-miniature .thumbnail-container .product-description .product-price-and-shipping.product-price-discount .regular-price{order:2}.js-product.product article.product-miniature .thumbnail-container ul.product-flags{position:absolute;top:24px;left:24px;z-index:2;transition:all 250ms ease-in-out;row-gap:8px}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag{font-size:11px;font-weight:400;padding:3px 8px;min-width:-moz-fit-content;min-width:fit-content;min-height:auto;margin-top:0;list-style:none;font-family:"Inter",sans-serif;font-size:12px;font-weight:700}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag.new{background:#462d26;padding:4px 8px}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag.discount{display:flex;flex-direction:row;-moz-column-gap:8px;column-gap:8px;background-color:rgba(0,0,0,0);padding:0}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag.discount span{font-family:"Inter",sans-serif;font-size:12px;font-weight:700;padding:4px 8px;background:#c40000}.js-product.product article.product-miniature .thumbnail-container ul.product-flags li.product-flag.out_of_stock{background:#462d26}.js-product.product article.product-miniature .thumbnail-container .wishlist-button-add{opacity:0;visibility:hidden;box-shadow:none;transition:all 250ms ease-in-out;transform:translateY(calc(-100% - 1rem))}.js-product.product article.product-miniature .thumbnail-container .wishlist-button-add i{color:#462d26}.product-images>li.thumb-container>.thumb.selected,.product-images>li.thumb-container>.thumb:hover{border-color:#e79332}.blockreassurance_product .item-product svg path{fill:#e79332}body#product{overflow-x:hidden}body#product>main{overflow:initial}body#product #content ul.product-flags{display:flex;flex-direction:row;gap:10px;flex-wrap:wrap}body#product #content ul.product-flags li.product-flag{font-size:11px;font-weight:400;padding:3px 8px;min-width:-moz-fit-content;min-width:fit-content;min-height:auto;transition:all 250ms ease-in-out;margin-top:0;border-radius:10px}body#product #content ul.product-flags li.product-flag.new{background:#e79332;margin-top:0}body#product #content ul.product-flags li.product-flag.discount{background:#e30613}body#product #content ul.product-flags li.product-flag.out_of_stock{position:absolute;top:0;right:0;background:#111516}body#product .product-info-box{margin:0;padding-top:5px;padding-bottom:65px;border-radius:10px}body#product .product-info-box #content{max-width:unset}body#product .product-info-box #content ul.product-flags{margin:0}body#product .product-info-box h1{color:#111516;font-size:24px;font-weight:400}body#product .product-info-box .product-prices{display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap}body#product .product-info-box .product-prices .product-discount{margin-bottom:0px}body#product .product-info-box .product-prices .product-discount .regular-price{color:#a9a8a8;font-weight:300;margin:0}body#product .product-info-box .product-prices .product-price{margin-bottom:0}body#product .product-info-box .product-prices .product-price .current-price{color:#111516;font-size:26px;font-weight:600;margin-bottom:0}body#product .product-info-box .product-prices .product-price .current-price .discount{display:none}body#product .product-info-box .product-prices .tax-shipping-delivery-label{margin-bottom:0}body#product .product-info-box ul.product-flags{margin-bottom:24px;row-gap:8px}body#product .product-info-box ul.product-flags li.product-flag{font-size:11px;font-weight:400;padding:3px 8px;min-width:-moz-fit-content;min-width:fit-content;min-height:auto;margin-top:0;list-style:none;font-family:"Inter",sans-serif;font-size:12px;font-weight:700}body#product .product-info-box ul.product-flags li.product-flag.new{background:#462d26;padding:4px 8px}body#product .product-info-box ul.product-flags li.product-flag.discount{display:flex;flex-direction:row;-moz-column-gap:8px;column-gap:8px;background-color:rgba(0,0,0,0);padding:0}body#product .product-info-box ul.product-flags li.product-flag.discount span{font-family:"Inter",sans-serif;font-size:12px;font-weight:700;padding:4px 8px;background:#c40000}body#product .product-info-box ul.product-flags li.product-flag.out_of_stock{background:#462d26}body#product .product-info-box .product-info-box-left:hover .scroll-box-arrows{opacity:1;visibility:visible}body#product .product-info-box .product-info-box-left .images-container .js-qv-mask{margin:0;width:100%}body#product .product-info-box .product-info-box-left .product-images{margin-bottom:0}body#product .product-info-box .product-info-box-left .scroll-box-arrows{opacity:0;visibility:hidden;transition:all 250ms ease-in-out}body#product .product-info-box .product-info-box-left .scroll-box-arrows .material-icons{line-height:0;bottom:45px;width:33px;height:33px;display:flex;align-items:center;justify-content:center;background:#ece9e2;border-radius:100%}body#product .product-info-box .product-info-box-left section#content ul.product-flags{display:flex;flex-direction:column;flex-wrap:wrap;width:100%;pointer-events:none;position:absolute;top:10px;left:10px;z-index:1}@media(min-width: 768px){body#product .product-info-box .product-info-box-left section#content ul.product-flags{display:none}}body#product .product-info-box .product-info-box-left section#content ul.product-flags li.product-flag{min-width:-moz-fit-content;min-width:fit-content;min-height:auto;margin-top:0;list-style:none;font-family:"Inter",sans-serif;font-size:12px;font-weight:700;border-radius:0}body#product .product-info-box .product-info-box-left section#content ul.product-flags li.product-flag.discount{background:rgba(0,0,0,0);padding:0}body#product .product-info-box .product-info-box-left section#content ul.product-flags li.product-flag.new{background:#462d26;padding:4px 8px}@media(max-width: 767px){body#product .product-info-box .product-info-box-right ul.product-flags{display:none}}body#product .product-info-box .product-info-box-right .h1{color:#462d26;font-size:20px;font-weight:500;font-family:"Inter",sans-serif;text-transform:initial;margin-bottom:32px}body#product .product-info-box .product-info-box-right .product-prices .product-discount .regular-price{color:#462d26;font-size:28px;font-weight:700;font-family:"Inter",sans-serif;line-height:1;opacity:.35}body#product .product-info-box .product-info-box-right .product-prices .product-price .current-price .current-price-value{color:#462d26;font-size:28px;font-weight:700;font-family:"Inter",sans-serif;line-height:1}body#product .product-info-box .product-info-box-right .product-prices .tax-shipping-delivery-label{display:none}body#product .product-info-box .product-info-box-right .product-information .product-description{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants{margin:16px 0;border-top:1px solid #ddd}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item{position:relative;display:flex;align-items:center;justify-content:flex-start;margin:0;padding:16px 0;width:100%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item:not(:last-child){border-bottom:1px solid #ddd}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item::before{content:"";position:absolute;left:-20px;right:-20px;top:-1px;bottom:0;background:#fff;transition:all 250ms ease-in-out;opacity:0;visibility:hidden;transition-delay:400ms}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select{display:flex;gap:10px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li{margin:0;padding:0}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li input{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li input:checked+span{border:0 !important}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li input:checked+span::before{content:"";display:block;position:absolute;top:-2px;left:-2px;height:30px;width:30px;border:1px solid #000;border-radius:50%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .color_select li span{margin:0;padding:0;height:26px;width:26px;border-radius:50%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item.active::before{opacity:1;visibility:visible;transition-delay:0ms}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .product-variants-item--wrapper{width:100%;position:relative}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label-nav{display:flex;flex-direction:row;justify-content:space-between;align-items:center;cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label-nav.active .form-control-select-standard-handler{transform:scale(-1)}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label-nav .form-control-select-standard-handler{cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label{color:#462d26;font-size:14px;font-weight:700;font-family:"Inter",sans-serif;width:100%;max-width:200px;margin-bottom:0}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .control-label .control-label-selected{font-weight:400}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item select{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom{display:none;position:absolute;left:-20px;right:-20px;top:calc(100% + 16px);z-index:10}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select{display:block;padding:25px;border:none;background:#fff;height:auto}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown{display:flex;flex-direction:column;row-gap:16px;margin:0;overflow:auto}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li{display:flex;flex-direction:row;-moz-column-gap:14px;column-gap:14px;margin:0;color:#110e0c;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li:not(:last-child){padding-bottom:16px;border-bottom:1px solid rgba(17,14,12,.1019607843)}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li.active .li-checkbox{background:#462d26;border-color:#462d26}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li.active .li-checkbox::before{content:"";position:absolute;top:8px;left:5.5px;width:8px;height:2px;background:#f9f7f2;transform:rotate(-45deg);transition:all 250ms ease-in-out}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li.active .li-checkbox::after{content:"";position:absolute;top:9px;left:4.5px;width:3.5px;height:2px;background:#f9f7f2;transform:rotate(45deg);transition:all 250ms ease-in-out}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .form-control-select-custom .custom-select ul.custom-dropdown li .li-checkbox{position:relative;display:block;width:19px;min-width:19px;height:19px;border:1px solid #d9cebe;border-radius:100%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .fabric-colors{display:flex;flex-direction:row;align-items:center;gap:9px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-variants .product-variants-item .fabric-colors a{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;text-decoration:underline}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart{padding:24px;background:#ece9e2}@media(max-width: 767px){body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart{position:relative;padding:24px 0}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart *{z-index:2}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart::after{content:"";position:absolute;top:0;bottom:0;left:50%;width:100svw;transform:translateX(-50%);background:#ece9e2;z-index:1}}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart>.control-label{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity{margin-bottom:10px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty{margin-bottom:0;margin-right:16px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;float:none;border:1px solid rgba(70,45,38,.8509803922);border-radius:1px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group input#quantity_wanted{order:2;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;padding:0;text-align:center;width:35px;border:none;background:rgba(0,0,0,0);height:29px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group button{padding:0;height:auto;color:rgba(70,45,38,.8509803922);font-size:14px;font-weight:500;font-family:"Inter",sans-serif;border:none;background:rgba(0,0,0,0)}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group button.btn{height:29px;padding:0 10px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group button.btn.bootstrap-touchspin-up{order:3}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .qty>.input-group button.btn.bootstrap-touchspin-down{order:1}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .add{margin:0;width:100%}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .add .add-to-cart{background:#e79332;margin:0;width:100%;color:#f9f7f2;font-size:14px;font-weight:500;font-family:"Inter",sans-serif;text-transform:initial}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .add .add-to-cart:hover{background:#110e0c}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .add .add-to-cart .material-icons{line-height:1;font-size:14px;height:auto;width:auto;vertical-align:baseline;margin-right:3px}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .wishlist-button-add{margin-left:16px;width:30px;border-radius:0;background:rgba(0,0,0,0);box-shadow:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-quantity .wishlist-button-add i{background-image:url("/img/cms/icons/icon-heart.svg");background-position:center;background-repeat:no-repeat;background-size:contain;width:26px;height:26px;font-size:0}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart #product-availability{display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-add-to-cart .product-minimal-quantity{margin:0;display:none}body#product .product-info-box .product-info-box-right .product-information .product-actions .product-additional-info{display:none;margin:30px 0}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product{display:flex;flex-direction:column;row-gap:20px;margin:40px 0 0 0}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile{display:flex;flex-direction:row;align-items:center;flex-wrap:wrap;color:#462d26;font-size:14px;font-weight:500;font-family:"Inter",sans-serif}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div .item-product,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile .item-product{margin-right:16px;padding:0;width:24px;height:24px}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div .item-product svg,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile .item-product svg{width:24px;height:24px}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div .item-product svg path,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile .item-product svg path{fill:rgba(0,0,0,0) !important}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div .block-title,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile .block-title{margin-right:10px}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product>div p,body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .product-delivery-tile p{font-weight:700;margin:0}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .item-0 .block-description{text-decoration:underline;cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .item-1 .block-description{text-decoration:underline;cursor:pointer}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .item-1 .block-description a{color:#111516;text-decoration:none}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .block-raty{width:100%;display:none}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .block-raty .block-raty--wrapper{display:flex;flex-direction:row;flex-wrap:wrap;gap:10px;padding-top:20px}body#product .product-info-box .product-info-box-right .product-information .blockreassurance_product .block-raty .block-raty--wrapper img{height:35px}body#product .product-info-box .product-info-box-right .product-information #description-nav{padding:32px 24px;margin:0;list-style:none;display:flex;flex-direction:row}body#product .product-info-box .product-info-box-right .product-information #description-nav li:not(:last-child){padding-right:10px;margin-right:10px;border-right:1px solid rgba(17,14,12,.1019607843)}body#product .product-info-box .product-info-box-right .product-information #description-nav li a{color:#462d26;font-size:16px;font-weight:600;font-family:"Inter",sans-serif}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card{padding:24px;background:#ece9e2}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card p{color:#462d26;font-size:14px;font-family:"Inter",sans-serif}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card ul{margin-bottom:0}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card textarea{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;float:none;border:1px solid rgba(70,45,38,0.8509803922);border-radius:1px;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;background:rgba(0,0,0,0);height:44px;outline:none}body#product .product-info-box .product-info-box-right .product-information .product-customization>.card button.btn{background:#e79332;margin:0;width:100%;color:#f9f7f2;font-size:14px;font-weight:500;font-family:"Inter",sans-serif;text-transform:initial;padding:10px;line-height:1.5}body#product .product-description-box{position:relative;margin-bottom:100px;padding-top:60px;padding-bottom:60px}body#product .product-description-box::before{content:"";position:absolute;top:0;left:50%;bottom:0;width:100svw;transform:translateX(-50%);background:#fff}body#product .product-description-box .c-row{display:flex;flex-direction:row;-moz-column-gap:60px;column-gap:60px}body#product .product-description-box .c-row .c-col{width:calc(50% - 30px)}@media(max-width: 767px){body#product .product-description-box .c-row .c-col{width:100%}}@media(max-width: 767px){body#product .product-description-box .c-row .c-col-2{display:none}}body#product .product-description-box .c-row .c-col-2 .product-description-box-img{position:sticky;top:150px}body#product .product-description-box .c-row .c-col-2 .product-description-box-img img{width:100%;max-width:-moz-fit-content;max-width:fit-content}body#product .product-description-box ul.product-accordion-box{padding:0;margin:0;list-style:none}body#product .product-description-box ul.product-accordion-box li.accordion-item.active .accordion-item-header img{transform:scale(-1)}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-header{display:flex;flex-direction:row;align-items:center;justify-content:space-between;-moz-column-gap:30px;column-gap:30px;padding:16px 0;border-bottom:1px solid rgba(17,14,12,.1019607843);cursor:pointer}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-header h3{color:#462d26;font-size:24px;font-weight:600;font-family:"Inter",sans-serif;margin:0}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-header img{transition:all .3s ease-in-out}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper{padding-top:24px;padding-bottom:64px;color:#000;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;line-height:1.4}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper strong{font-weight:700}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper img{max-width:-moz-fit-content;max-width:fit-content;width:100%;height:auto}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .js-product-details .product-reference{display:none}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .js-product-details .product-quantities{display:none}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .js-product-details .product-features .data-sheet{color:#111516}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .elementor-accordion .elementor-accordion-item .elementor-tab-title{display:flex;flex-direction:row;align-items:center}body#product .product-description-box ul.product-accordion-box li.accordion-item .accordion-item-body .accordion-item-body--wrapper .elementor-accordion .elementor-accordion-item .elementor-tab-title .elementor-accordion-title{line-height:1.5}body#product .product-description-box #product-details .product-reference,body#product .product-description-box #product-details .product-quantities{display:none !important}body#product .product-description-box section.product-features .data-sheet{color:#111516}body#product .tabs{border-radius:10px}body#product .tabs .nav-tabs .nav-item .nav-link{color:#111516;font-weight:400;font-size:16px}body#product .tabs .nav-tabs .nav-item .nav-link:hover{border-bottom:#e79332 3px solid}body#product .tabs .nav-tabs .nav-item .nav-link.active{color:#111516;border-color:#e79332}body#product #empty-product-comment{border-radius:10px}#blockcart-modal .modal-content .modal-body .product-name{color:#111516;font-weight:500;margin-bottom:16px}#blockcart-modal .modal-content .modal-body .cart-content-btn .btn.btn-primary{background:#e79332}body#cart #content-wrapper .card-block-title .h1{color:#462d26;font-size:24px;font-weight:700;font-family:"Inter",sans-serif;text-transform:initial;text-align:center;margin-bottom:16px}body#cart #content-wrapper .cart-grid{margin-bottom:150px}body#cart #content-wrapper .cart-grid .cart-grid-body .card{background:rgba(0,0,0,0)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview{padding:0}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table{width:100%}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table thead::after{content:"";display:block;height:24px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table thead tr th{color:rgba(70,45,38,.8509803922);font-size:12px;font-weight:400;font-family:"Inter",sans-serif;white-space:nowrap;padding:8px 0;border-bottom:1px solid rgba(17,14,12,.1019607843)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table thead tr th:not(:last-child){padding-right:20px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr:not(:first-child) td{padding-top:18px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr:not(:last-child) td{padding-bottom:18px;border-bottom:1px solid rgba(17,14,12,.1019607843)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td{vertical-align:top}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td:not(:last-child){padding-right:20px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-img img{width:80px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-desc{line-height:1}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-desc a{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-infos{line-height:1;margin-top:8px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-infos .product-card-info:not(:last-child){margin-bottom:8px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-infos .product-card-info span{color:rgba(70,45,38,.8509803922);font-size:12px;font-weight:400;font-family:"Inter",sans-serif}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price{padding-top:7px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price .current-price{line-height:1}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price .current-price .price{color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:700}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price .product-discount{line-height:1;margin-top:3px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-price .product-discount .regular-price{color:rgba(70,45,38,.8509803922);font-size:12px;font-family:"Inter",sans-serif;font-weight:400}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group{display:flex;flex-direction:row;flex-wrap:nowrap;align-items:center;float:none;border:1px solid rgba(70,45,38,.8509803922);border-radius:1px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group input.js-cart-line-product-quantity{order:2;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;padding:0;text-align:center;width:35px;border:none;background:rgba(0,0,0,0);height:29px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group button{padding:0;height:auto;color:rgba(70,45,38,.8509803922);font-size:14px;font-weight:500;font-family:"Inter",sans-serif;border:none;background:rgba(0,0,0,0)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group button.btn{height:29px;padding:0 7px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group button.btn.bootstrap-touchspin-up{order:3}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-qty>.input-group button.btn.bootstrap-touchspin-down{order:1}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-sum-price{padding-top:7px;line-height:1}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-sum-price strong{color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:700}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action{display:block;padding-top:9px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action .remove-from-cart{position:relative;width:10px;height:10px;display:block}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action .remove-from-cart::before{content:"";position:absolute;width:10px;height:1px;background:#bbb6aa;top:50%;left:50%;transform:translate(-50%, -50%) rotate(45deg)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action .remove-from-cart::after{content:"";position:absolute;width:10px;height:1px;background:#bbb6aa;top:50%;left:50%;transform:translate(-50%, -50%) rotate(-45deg)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table tbody tr td .product-card-action .remove-from-cart .material-icons{display:none}@media(max-width: 570px){body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table thead{display:none}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview table,body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview tbody,body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview tr,body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td{display:block;width:100%}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview tbody{padding:20px;text-align:center}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview tr{margin-bottom:1rem;border:1px solid #ccc;border-radius:5px;padding:10px;background:#f9f9f9;border:1px solid rgba(17,14,12,0.1019607843)}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td{position:relative;text-align:right;padding:15px 10px 15px 50% !important}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td::before{position:absolute;left:10px;top:50%;transform:translateY(-50%);white-space:nowrap;font-weight:bold;text-align:left}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td .product-card-qty{display:block;margin-left:auto;width:-moz-fit-content;width:fit-content}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td .product-card-action{width:-moz-fit-content;width:fit-content;margin-left:auto}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td .product-card-action .remove-from-cart::before{width:15px !important;height:2px !important}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td .product-card-action .remove-from-cart::after{width:15px !important;height:2px !important}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td>div{padding-top:0 !important}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(1)::before{content:"Obrazek"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(2)::before{content:"Nazwa produktu"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(3)::before{content:"Cena jednostkowa"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(4)::before{content:"Ilość"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(5)::before{content:"Cena łączna"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview td:nth-child(6)::before{content:"Usuń"}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .product-card-img img{max-width:100%;height:auto}}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .no-items{color:#462d26;font-size:16px;font-family:"Inter",sans-serif;font-weight:700;width:100%;display:block;text-align:center}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-line-info a{color:#111516;font-weight:400;font-size:16px}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-price{margin:10px 0}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-price .product-discount .regular-price{color:#a9a8a8;font-weight:300;margin:0}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-price .product-discount .discount{background:#e79332}body#cart #content-wrapper .cart-grid .cart-grid-body .cart-overview .cart-items .cart-item .product-line-grid .product-line-grid-body .product-price .current-price .price{color:#111516;font-weight:600;font-size:16px}body#cart #content-wrapper .cart-summary{margin-bottom:24px;background:#ece9e2}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals{padding:24px 24px 0 24px}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line:not(:last-child){margin-bottom:8px}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line:last-child{margin-bottom:0}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line span{font-size:14px;font-family:"Inter",sans-serif}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line span.label{font-weight:500}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-detailed-subtotals .cart-summary-line span.value{font-weight:400}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-summary-totals{padding:16px 24px}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-summary-totals .cart-summary-line.cart-total{padding:0;border:0}body#cart #content-wrapper .cart-summary .cart-detailed-totals .cart-summary-totals .cart-summary-line.cart-total span{font-size:14px;font-family:"Inter",sans-serif;font-weight:700}body#cart #content-wrapper .cart-summary .cart-detailed-actions{padding:0 24px 18px}body#cart #content-wrapper .cart-summary .cart-detailed-actions a.btn{color:#f9f7f2;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;padding:14px 12px;background-color:#e79332;text-transform:initial}body#cart #content-wrapper .cart-summary .card-payment-support{padding:0 24px 12px}body#cart #content-wrapper .cart-summary .card-payment-support ul{padding:0;margin:0;list-style:none;display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:center;-moz-column-gap:30px;column-gap:30px;row-gap:12px}body#cart #content-wrapper .cart-summary .card-payment-support ul li img{max-width:44px}body#checkout #content-wrapper .cart-grid-body .checkout-step{padding:0;background-color:#f9f7f2}body#checkout #content-wrapper .cart-grid-body .checkout-step .step-title{color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:700;text-transform:initial;padding-bottom:10px;border-bottom:1px solid #462d26;margin-bottom:32px}body#checkout #content-wrapper .cart-grid-body .checkout-step .step-title .step-number::after{content:". "}body#checkout #content-wrapper .cart-grid-body .checkout-step.-current{opacity:1 !important}body#checkout #content-wrapper .cart-grid-body .checkout-step.-current .step-title{color:#e79332;border-bottom:1px solid #e79332}body#checkout #content-wrapper .cart-grid-body .checkout-step.-complete{opacity:.5}body#checkout #content-wrapper .cart-grid-body .checkout-step .content{padding:0}body#checkout #content-wrapper .cart-grid-body .checkout-step #customer-form{max-width:480px}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group label{color:#110e0c;font-size:12px;font-family:"Inter",sans-serif;font-weight:500;margin-bottom:4px}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group input.form-control{background:rgba(70,45,38,.1019607843);border:1px solid rgba(70,45,38,.1411764706);padding:14px 16px;color:#110e0c;font-size:14px;font-family:"Inter",sans-serif;font-weight:500}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group .btn-show-password-box{position:absolute;top:0;right:0;bottom:0;width:-moz-fit-content;width:fit-content}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group .btn-show-password-box .btn-show-password{padding:0;background:rgba(0,0,0,0);display:flex;height:100%;align-items:center;width:30px;outline:none}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-group .form-control-comment{color:rgba(70,45,38,0.8509803922);font-size:12px;font-family:"Inter",sans-serif;font-weight:400}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-informations{margin-top:40px}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-informations .form-informations-title{color:#110e0c;font-size:16px;font-family:"Inter",sans-serif;font-weight:700}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-informations .form-informations-option{color:#110e0c;font-size:16px;font-family:"Inter",sans-serif;font-weight:400;font-style:initial !important}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-informations .form-informations-subtitle{display:none}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-footer{text-align:start;width:-moz-fit-content;width:fit-content}body#checkout #content-wrapper .cart-grid-body .checkout-step .form-footer .btn{color:#f9f7f2;font-size:14px;font-weight:500;font-family:"Inter",sans-serif;background:#e79332;padding:12px 80px;text-transform:initial}body#checkout #content-wrapper .cart-grid-body .checkout-step #delivery-address{max-width:480px;margin-left:0}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options{max-width:480px}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option{padding:12px 16px;margin:0;border:1px solid rgba(70,45,38,.1411764706);border-radius:1px;-moz-column-gap:16px;column-gap:16px;min-height:initial;background:rgba(0,0,0,0)}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option:not(:last-child){margin-bottom:16px}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option .delivery-option-checkbox{width:-moz-fit-content;width:fit-content;line-height:0}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option .delivery-option-2{flex:1;display:flex;flex-direction:row;align-items:center;justify-content:space-between}body#checkout #content-wrapper .cart-grid-body .checkout-step .delivery-options .delivery-option .delivery-option-2 .carrier-price{color:#110e0c;font-family:"Inter",sans-serif;font-size:14px;font-weight:700}body#checkout #content-wrapper .cart-grid-body .checkout-step .order-options #delivery label{color:#110e0c;font-size:12px;font-family:"Inter",sans-serif;font-weight:500;margin-bottom:4px}body#checkout #content-wrapper .cart-grid-body .checkout-step .order-options #delivery textarea{width:100%;max-width:480px;border:1px solid rgba(70,45,38,.1411764706);background:rgba(70,45,38,.1019607843);border-radius:1px;resize:none;margin-bottom:30px}body#checkout #content-wrapper .cart-grid-body .checkout-step button[type=submit]{color:#f9f7f2;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;padding:12px 80px;background:#e79332;text-transform:initial;float:none !important}body#checkout #content-wrapper .cart-grid-body .checkout-step #conditions-to-approve ul li .condition-label{margin:0;line-height:1}body#checkout #content-wrapper .cart-grid-body .checkout-step #conditions-to-approve ul li .condition-label label{margin:0;line-height:1}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information{margin:0 0 20px 0;padding:24px;border:1px solid rgba(70,45,38,.1411764706)}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information p{color:#110e0c;font-size:14px;font-weight:700;font-family:"Inter",sans-serif}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information dl{border-left:1px solid rgba(70,45,38,.1411764706);border-right:1px solid rgba(70,45,38,.1411764706);border-top:1px solid rgba(70,45,38,.1411764706)}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information dl dt{border-right:1px solid rgba(70,45,38,.1411764706)}body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information dl dt,body#checkout #content-wrapper .cart-grid-body .checkout-step .payment-options .js-additional-information dl dd{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;background:rgba(0,0,0,0);margin:0;flex:0 0 50%;border-bottom:1px solid rgba(70,45,38,0.1411764706)}body#checkout #content-wrapper #js-checkout-summary{background:rgba(0,0,0,0)}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box{margin-bottom:16px;background-color:#ece9e2}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box>.card-block{padding:24px 24px 0 24px}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box .cart-summary-totals{padding:16px 24px 24px 24px}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box .cart-summary-totals .cart-total{line-height:1;padding:0}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box .cart-summary-totals .cart-total span{color:#462d26;font-size:14px;font-weight:700;font-family:"Inter",sans-serif}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box #cart-summary-product-list .media-list{margin-bottom:24px;padding-bottom:24px;border-bottom:1px solid rgba(70,45,38,.3)}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box #cart-summary-product-list .media-list .media:not(:last-child){margin-bottom:24px}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box #cart-summary-product-list .media-list .media .media-left img{width:40px}body#checkout #content-wrapper #js-checkout-summary .js-checkout-summary-box #cart-summary-product-list .media-list .media .media-body .product-name a{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;max-width:260px}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .h4{font-size:16px;font-weight:700;font-family:"Inter",sans-serif;margin-bottom:24px;text-transform:uppercase}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-left{padding-right:16px}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-name{line-height:1;margin-bottom:2px;display:block}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-name a{color:#111516;font-weight:600}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-specification .product-line-info{line-height:1;margin-bottom:2px}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-specification .product-line-info span{color:rgba(70,45,38,.8509803922);font-size:12px;font-family:"Inter",sans-serif;font-weight:400}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-specification .product-quantity{color:rgba(70,45,38,.8509803922);font-size:12px;font-family:"Inter",sans-serif;font-weight:400;line-height:1}body#checkout #content-wrapper #js-checkout-summary .cart-summary-products .media-list .media .media-body .product-price{color:#111516;font-weight:600}body#checkout #content-wrapper #js-checkout-summary .cart-summary-subtotals-container{padding:0;border:none}body#checkout #content-wrapper #js-checkout-summary .cart-summary-subtotals-container .cart-summary-line{line-height:1;margin-bottom:8px}body#checkout #content-wrapper #js-checkout-summary .cart-summary-subtotals-container .cart-summary-line span{color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:500}body#checkout #content-wrapper .delivery-options .delivery-option{border:none}body#order-confirmation .breadcrumb{display:none}body#order-confirmation #content-wrapper #main #registration-form{display:none}body#order-confirmation #content-wrapper #main section#content,body#order-confirmation #content-wrapper #main section#content-hook_payment_return,body#order-confirmation #content-wrapper #main section#content-hook-order-confirmation-footer{display:none}body#order-confirmation #content-wrapper #main section#content-hook_order_confirmation{margin-bottom:150px;margin-top:50px;background:rgba(0,0,0,0)}body#order-confirmation #content-wrapper #main section#content-hook_order_confirmation .card-title{color:#462d26;font-size:24px;font-weight:700;font-family:"Inter",sans-serif;margin-bottom:24px;text-align:center;display:flex;flex-direction:column;align-items:center;row-gap:32px;text-transform:initial}body#order-confirmation #content-wrapper #main section#content-hook_order_confirmation p{color:#1a1a18;font-size:16px;font-weight:400;font-family:"Inter",sans-serif;text-align:center;max-width:750px;margin-left:auto;margin-right:auto;margin-bottom:32px}body#order-confirmation #content-wrapper #main section#content-hook_order_confirmation .elementor-button{color:#f9f7f2;font-size:14px;font-weight:500;font-family:"Inter",sans-serif;padding:18px 80px;background:#e79332;margin:0 auto;display:flex;width:100%;max-width:-moz-fit-content;max-width:fit-content}body#order-confirmation footer#footer .footer-box-newsletter,body#order-confirmation footer#footer .footer-box-services,body#order-confirmation footer#footer .footer-box-other-info{display:none}footer#footer{background-color:#f9f7f2}.category-tiles-list{display:grid;grid-template-columns:repeat(6, 1fr);grid-gap:20px}.category-tiles-list a{display:block}body:not(#ets_blog_page) main #left-column>div.block{display:none !important}body#ets_blog_page #content-wrapper .ets-blog-wrapper-detail{border-radius:10px}body#ets_blog_page #left-column .title_block{color:#111516;font-size:20px;font-weight:400}body#ets_blog_page #left-column .ets_block_slider .ets_title_block{color:#111516;font-size:16px;font-weight:400}body#ets_blog_page ul.ets-blog-list>li .post-wrapper{border-radius:10px;overflow:hidden;display:flex;flex-direction:row;flex-wrap:wrap}body#ets_blog_page ul.ets-blog-list>li .post-wrapper .ets-blog-wrapper-content{background:#eff6f7;padding-top:15px;padding-bottom:15px}body#ets_blog_page ul.ets-blog-list>li .post-wrapper .ets_title_block{color:#111516;font-size:18px;font-weight:300;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.25;font-weight:400}body#ets_blog_page ul.ets-blog-list>li .post-wrapper .blog_description{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}body#ets_blog_page ul.ets-blog-list>li .post-wrapper .read_more{display:inline-block;color:#e79332;font-weight:400;text-decoration:underline;font-style:underline !important;border:none}.ets_blog_sidebar>.block{box-shadow:none !important;border-radius:10px}body #left-column .block-categories .category-top-menu li a.h6{color:#111516;font-size:20px;font-weight:400}body #left-column .block-categories .category-top-menu li .category-sub-menu li a{color:#111516;font-size:16px;font-weight:400}body#category #left-column>div{border-radius:10px}body#category #content-wrapper section#main div{border-radius:10px}.product-description{color:#000;font-size:15px;line-height:1.5}.product-description ul{list-style-type:disc;margin-left:25px}.product-description h3{color:#000 !important;font-size:18px}.data-sheet dd,.data-sheet dt{font-weight:400 !important;font-size:15px}#header-search{position:relative;width:100%;max-width:340px;padding-right:32px;margin-right:14px}#header-search::before{content:"";position:absolute;top:50%;right:0;width:1px;height:28px;background:rgba(17,14,12,.1);transform:translateY(-50%)}#header-search form.elementor-search>ul.elementor-search__products{background:#f9f7f2;border-radius:0;border:1px solid rgba(17,14,12,.1)}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item{background:#fff}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item:not(:last-child){margin-bottom:2px}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item .elementor-search__product-details .elementor-search__product-name{color:#462d26;font-size:14px;font-weight:400;font-family:"Inter",sans-serif}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item .elementor-search__product-details .elementor-search__product-category{display:none}#header-search form.elementor-search>ul.elementor-search__products .ui-menu-item .elementor-search__product-details .elementor-search__product-price{color:#462d26;font-size:14px;font-weight:700;font-family:"Inter",sans-serif}@media(min-width: 992px)and (max-width: 1024px){#header-search{display:block !important}}@media(min-width: 992px)and (max-width: 1024px){.mobile-search{display:none !important}}#header-menu .elementor-nav-menu>ul{justify-content:space-between;align-items:center;width:100%}#header-menu .elementor-nav-menu>ul::after{display:none}#header-menu .elementor-nav-menu .menu-item-separator{display:block;width:1px;height:14px;background:rgba(17,14,12,.1019607843)}#home-slider-box{width:100svw;margin-left:50%;transform:translateX(-50%)}#home-slider-box ul.carousel-inner{border-radius:0 !important}#home-slider-box figure{width:100%}@media(max-width: 991px){#home-slider-box figure img{min-height:390px;-o-object-fit:cover;object-fit:cover}}.home-slider .carousel-item .caption{width:100%;max-width:80%;bottom:auto;top:80px}@media(max-width: 991px){.home-slider .carousel-item .caption{top:36px;left:40px}}.home-slider .carousel-item .caption .caption-description h2{color:#f9f7f2;font-size:64px;margin-bottom:18px;line-height:1.1;font-weight:500;font-family:"Inter",sans-serif}.home-slider .carousel-item .caption .caption-description h2 span{color:#e79332}@media(max-width: 991px){.home-slider .carousel-item .caption .caption-description h2{font-size:32px;margin-bottom:10px}}.home-slider .carousel-item .caption .caption-description p{font-size:16px;color:#f9f7f2}.home-slider .slide-button{position:relative;display:flex;flex-direction:row;align-items:center;-moz-column-gap:12px;column-gap:12px;padding:16px 45px;width:-moz-fit-content;width:fit-content;margin-top:40px;border-top:1px solid #e79332;border-bottom:1px solid #e79332;color:#e79332;font-size:16px;font-weight:500}.home-slider .slide-button img{width:100%;max-width:24px}.home-slider .slide-button::before{content:"";position:absolute;left:-1px;top:-2px;bottom:0;width:10px;height:calc(100% + 4px);background-image:url("/img/cms/icons/btn-side-line.svg");background-position:center;background-size:contain;background-repeat:no-repeat}.home-slider .slide-button::after{content:"";position:absolute;right:-1px;top:-2px;bottom:0;width:10px;height:calc(100% + 4px);background-image:url("/img/cms/icons/btn-side-line.svg");background-position:center;background-size:contain;background-repeat:no-repeat;transform:scale(-1)}@media(max-width: 991px){.home-slider .slide-button{font-size:13px}}.home-box-1>.elementor-column-wrap>.elementor-widget-wrap{display:grid;grid-template-columns:7fr 5fr;grid-template-rows:1fr 1fr;grid-template-areas:"item1 item2" "item1 item3";gap:20px}.home-box-1>.elementor-column-wrap>.elementor-widget-wrap>.elementor-element:nth-child(1){grid-area:item1}.home-box-1>.elementor-column-wrap>.elementor-widget-wrap>.elementor-element:nth-child(2){grid-area:item2}.home-box-1>.elementor-column-wrap>.elementor-widget-wrap>.elementor-element:nth-child(3){grid-area:item3}@media(max-width: 767px){.home-box-1>.elementor-column-wrap>.elementor-widget-wrap{grid-template-columns:1fr;grid-template-rows:auto;grid-template-areas:"item1" "item2" "item3"}}.home-box-1 .home-box1-tile:nth-child(1) .elementor-cta-content .elementor-button::before{content:url("/img/cms/Home/Group 1223.svg")}.home-box-1 .home-box1-tile>.elementor-widget-container{height:100%}.home-box-1 .home-box1-tile>.elementor-widget-container>.elementor-cta{height:100%}.home-box-1 .home-box1-tile .elementor-cta-content{position:absolute;inset:0;background:rgba(0,0,0,0);justify-content:space-between;align-content:space-between}.home-box-1 .home-box1-tile .elementor-cta-content .elementor-button{position:relative;padding:0;display:flex;flex-direction:row;align-items:center;gap:10px}.home-box-1 .home-box1-tile .elementor-cta-content .elementor-button::before{content:url("/img/cms/Home/Group 1224.svg")}.home-box-info{position:relative}.home-box-info::before{content:"";position:absolute;top:0;left:50%;height:1px;width:100vw;transform:translateX(-50%);background:rgba(170,138,94,.25)}.home-box-info::after{content:"";position:absolute;bottom:0;left:50%;height:1px;width:100vw;transform:translateX(-50%);background:rgba(170,138,94,.25)}.home-box-info>.elementor-container>.elementor-row{align-items:center}.home-box-info .home-box-info-img img{max-width:unset}.footer-box-services{position:relative}.footer-box-services::before{content:"";position:absolute;bottom:0;left:50%;height:1px;width:100vw;transform:translateX(-50%);background:rgba(170,138,94,.25)}.footer-box-services .elementor-widget-wrap{flex-direction:row;flex-wrap:nowrap}.footer-box-other-info>.elementor-container>.elementor-row{-moz-column-gap:80px;column-gap:80px;position:relative}@media(min-width: 1025px){.footer-box-other-info>.elementor-container>.elementor-row::before{content:"";position:absolute;top:-60px;bottom:-60px;left:50%;width:1px;transform:translateX(-50%);background:rgba(170,138,94,.25)}}nav.pagination .page-list{display:flex;align-items:center;justify-content:center;gap:10px;background:rgba(0,0,0,0)}nav.pagination .page-list .pagination-item.prev a{background:rgba(0,0,0,0);transition:all 250ms ease-in-out}nav.pagination .page-list .pagination-item.prev a img{transition:all 250ms ease-in-out}nav.pagination .page-list .pagination-item.prev a:hover{background:#ffa629}nav.pagination .page-list .pagination-item.prev a:hover img{filter:brightness(0) invert(1)}nav.pagination .page-list .pagination-item.next a{background:rgba(0,0,0,0);transition:all 250ms ease-in-out}nav.pagination .page-list .pagination-item.next a img{transition:all 250ms ease-in-out;transform:scale(-1)}nav.pagination .page-list .pagination-item.next a:hover{background:#ffa629}nav.pagination .page-list .pagination-item.next a:hover img{filter:brightness(0) invert(1)}nav.pagination .page-list .pagination-item.current a{color:#fff;background:#ffa629}nav.pagination .page-list .pagination-item .spacer{display:flex;align-items:center;justify-content:center;padding:5px 11px;height:33px;width:33px;color:#9f928c;font-size:14px;font-weight:500;font-family:"Inter",sans-serif}nav.pagination .page-list .pagination-item a{display:flex;align-items:center;justify-content:center;color:#9f928c;font-family:"Inter",sans-serif;font-size:14px;font-weight:500;letter-spacing:-0.5px;padding:5px 11px;height:33px;min-width:33px;background:#ece9e2;border-radius:1px;transition:all 250ms ease-in-out}nav.pagination .page-list .pagination-item a:hover{color:#fff;background:#ffa629}body#category section#main #subcategories{padding:0;margin:0;background:rgba(0,0,0,0)}body#category section#main #subcategories .subcategory-heading{display:none}body#category section#main #subcategories .subcategories-list{display:flex;flex-direction:row;gap:16px;flex-wrap:wrap}body#category section#main #subcategories .subcategories-list li .subcategory-item{display:flex;flex-direction:row;-moz-column-gap:16px;column-gap:16px;align-items:center;background:#ece9e2;border-radius:50px;padding:8px 24px 8px 24px;height:100%}body#category section#main #subcategories .subcategories-list li .subcategory-item .subcategory-image{width:43px;height:43px;padding:0;background:#fff;border-radius:100%;margin-left:-16px}body#category section#main #subcategories .subcategories-list li .subcategory-item .subcategory-image img{width:100%;height:100%;-o-object-fit:contain;object-fit:contain;border-radius:100%}body#category section#main #subcategories .subcategories-list li .subcategory-item .subcategory-name{color:#462d26;font-size:16px;font-weight:600;font-family:"Inter",sans-serif;margin:0}nav.breadcrumb{margin-bottom:1.563rem}nav.breadcrumb ol{display:flex;flex-direction:row;-moz-column-gap:16px;column-gap:16px;align-items:center}nav.breadcrumb ol li span{color:#462d26;font-size:14px;font-weight:500;font-family:"Inter",sans-serif}nav.breadcrumb ol li.separator img{width:5px;height:9px}body#cms.cms-id-5 footer#footer section.footer-box-newsletter,body#cms.cms-id-6 footer#footer section.footer-box-newsletter,body#cms.cms-id-7 footer#footer section.footer-box-newsletter{display:none}body#cms.cms-id-5 footer#footer section.footer-box-services,body#cms.cms-id-6 footer#footer section.footer-box-services,body#cms.cms-id-7 footer#footer section.footer-box-services{display:none}body#cms.cms-id-5 footer#footer section.footer-box-other-info,body#cms.cms-id-6 footer#footer section.footer-box-other-info,body#cms.cms-id-7 footer#footer section.footer-box-other-info{display:none}body#cms section#main header.page-header{margin-bottom:32px}body#cms section#main header.page-header h1{color:#462d26;font-size:32px;font-family:"Inter",sans-serif;font-weight:700;margin:0}#cms-citys .elementor-icon-list-items{display:grid;grid-template-columns:repeat(auto-fill, minmax(250px, 1fr));gap:20px}#cms-citys .elementor-icon-list-items li .elementor-icon-list-text{display:block;width:100%;text-align:center;padding:12px 24px;background:#462d26}#js-product-list>.products{row-gap:40px}#basket-side-panel .elementor-cart__title{text-align:center;min-height:unset;line-height:1;padding:20px 0 25px}#basket-side-panel .elementor-cart__products .elementor-cart__product{position:relative}#basket-side-panel .elementor-cart__products .elementor-cart__product .elementor-cart__product-name{padding-left:16px}#basket-side-panel .elementor-cart__products .elementor-cart__product .elementor-cart__product-attrs{padding:3px 0}#basket-side-panel .elementor-cart__products .elementor-cart__product .elementor-cart__product-price{padding-left:16px}#basket-side-panel .elementor-cart__products .elementor-cart__product .elementor-cart__product-remove{position:absolute;top:20px;right:0}#basket-side-panel .elementor-cart__footer-box{position:relative;margin-top:auto}#basket-side-panel .elementor-cart__footer-box::before{content:"";position:absolute;inset:0 -30px;background:#ece9e2;z-index:-1}#basket-side-panel .elementor-cart__footer-box .elementor-cart__summary{border:none}#basket-side-panel .elementor-cart__footer-box .elementor-cart__summary>span{margin-bottom:5px}#basket-side-panel .elementor-cart__footer-box .elementor-cart__footer-buttons{width:100%}#basket-side-panel .elementor-cart__footer-delivery{margin-bottom:20px}#basket-side-panel .elementor-cart__footer-delivery ul{list-style:none;padding:0;margin:0;display:flex;flex-direction:row;align-items:center;justify-content:center;-moz-column-gap:11px;column-gap:11px}#basket-side-panel .elementor-cart__footer-delivery ul li span{color:#462d26;font-family:"Inter",sans-serif;font-size:12px;font-weight:500}.custom-checkbox{display:flex;align-items:flex-start;-moz-column-gap:10px;column-gap:10px}.custom-checkbox label{padding:0;margin:0;cursor:pointer;color:#110e0c;font-size:14px;font-family:"Inter",sans-serif;font-weight:400}input[type=checkbox],input[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;position:relative;width:15px;height:15px;min-width:15px;min-height:15px;display:inline-block;border:1px solid #d9cebe;border-radius:3px;transition:all 250ms ease-in-out;overflow:hidden;cursor:pointer}input[type=checkbox]::before,input[type=radio]::before{content:"";position:absolute;top:-5px;left:15px;width:7px;height:2px;background:#f9f7f2;transform:rotate(-45deg);transition:all 250ms ease-in-out}input[type=checkbox]::after,input[type=radio]::after{content:"";position:absolute;top:-4px;left:-8px;width:4px;height:2px;background:#f9f7f2;transform:rotate(45deg);transition:all 250ms ease-in-out}input[type=checkbox]:checked,input[type=radio]:checked{background:#462d26;border-color:#462d26}input[type=checkbox]:checked::before,input[type=radio]:checked::before{top:6px;left:4px}input[type=checkbox]:checked::after,input[type=radio]:checked::after{top:7px;left:3px}body#authentication section#main .page-header{margin-bottom:32px}body#authentication section#main .page-header h1{color:#462d26;font-size:24px;font-weight:700;font-family:"Inter",sans-serif;text-align:center;margin-bottom:0}body#authentication section#main #content{background:rgba(0,0,0,0);max-width:480px;margin:0 auto 150px}body#authentication section#main #content form label{color:#110e0c;font-size:12px;font-weight:500;font-family:"Inter",sans-serif}body#authentication section#main #content form input[type=text]{border:1px solid rgba(70,45,38,.1411764706);background:rgba(70,45,38,.1019607843)}body#authentication section#main #content form .btn-show-password-box{width:-moz-fit-content;width:fit-content;position:absolute;right:0}body#authentication section#main #content form .btn-show-password-box .btn-show-password{background:rgba(0,0,0,0)}body#authentication section#main #content form .forgot-password{text-align:left}body#authentication section#main #content form .forgot-password a{color:#110e0c;font-size:12px;font-weight:500;font-family:"Inter",sans-serif;text-decoration:underline}body#authentication section#main #content form button{color:#f9f7f2;background:#e79332;padding:14px 80px;text-transform:initial}body#authentication section#main #content hr{margin:32px 0 16px}body#authentication section#main #content .no-account a{color:#110e0c;font-size:14px;font-weight:500;font-family:"Inter",sans-serif}body#authentication section#main #content .register-form>p{display:none}body#authentication section#main #content .register-form form .form-check{display:flex;flex-direction:row;-moz-column-gap:30px;column-gap:30px}body#authentication section#main #content .register-form form .form-check label{margin:0;display:flex;align-items:center;-moz-column-gap:5px;column-gap:5px}body#authentication section#main #content .register-form form .form-check label .custom-radio{line-height:1}body#authentication section#main #content .register-form form footer.form-footer{display:flex;align-items:center;justify-content:center;margin:30px 0 0 0}@media(max-width: 767px){.newsletter-form form.elementor-email-subscription .elementor-field-type-subscribe{display:flex;flex-direction:row;row-gap:16px;flex-wrap:wrap}.newsletter-form form.elementor-email-subscription .elementor-field-type-subscribe button{width:100%}}.newsletter-form form.elementor-email-subscription .elementor-checkbox-label{color:#fff}.newsletter-form .elementor-field-label{display:flex;gap:10px;margin-top:10px}.newsletter-form .elementor-field-label .elementor-checkbox-label{font-size:12px;font-weight:500;font-family:"Inter",sans-serif}#content-wrapper a[target=raty_procedura]{display:none !important}.leo-megamenu{margin-bottom:0}.leo-megamenu .dropdown-menu{background:#f9f7f2;border:1px solid rgba(17,14,12,.1019607843);overflow:auto}.leo-megamenu .dropdown-menu a:hover{color:#e79332 !important;text-decoration:underline}.leo-megamenu .leo-top-menu ul.nav.navbar-nav>li:last-child{padding-right:0}.leo-megamenu .leo-top-menu ul.nav.navbar-nav>li:last-child::after{display:none}.leo-top-menu .nav{display:flex;align-items:center;width:100%}.leo-top-menu .nav>li{position:relative;padding:0}.leo-top-menu .nav>li:first-child{padding-left:0}.leo-top-menu .nav>li.promo-item>a[href="https://masimmo.pl/promocje/"] span{color:#e79332 !important}.leo-top-menu .nav>li.promo-item>a[href="https://masimmo.pl/promocje/"]:hover span{color:#232323 !important}.leo-top-menu .nav>li:not(:first-child)>a{padding-left:23.5px}@media(max-width: 1200px){.leo-top-menu .nav>li:not(:first-child)>a{padding-left:19px}}@media(max-width: 1100px){.leo-top-menu .nav>li:not(:first-child)>a{padding-left:15px}}.leo-top-menu .nav>li:not(:last-child)>a{position:relative;padding-right:23.5px}@media(max-width: 1200px){.leo-top-menu .nav>li:not(:last-child)>a{padding-right:19px}}@media(max-width: 1100px){.leo-top-menu .nav>li:not(:last-child)>a{padding-right:15px}}.leo-top-menu .nav>li:not(:last-child)>a::before{content:"";display:block !important;width:1px;height:14px;background:rgba(17,14,12,0.1019607843);position:absolute;right:0;top:50%;margin-top:-7px}.leo-top-menu .nav>li>a{text-transform:uppercase;font-weight:600}.leo-top-menu .nav a{font-family:"Inter",sans-serif;font-size:14px;font-weight:400;white-space:nowrap}.leo-top-menu .nav a:hover{color:#e79332;text-decoration:underline}.leo-top-menu .nav a:hover span{color:#e79332}.leo-top-menu .nav a::after{display:none !important}.leo-top-menu .nav a span{text-transform:uppercase}.cart-grid-footer{display:flex;align-items:center;gap:20px}.cart-grid-footer img{height:30px}#popular-products h2,#new-products h2{font-family:"Inter";color:#462d26;font-size:36px;font-weight:500}#products .sort-by-row{display:flex;justify-content:flex-end;gap:20px;align-items:center}#products .sort-by-row .products-sort-order .dropdown-menu{background:#fff;width:100%}#products .sort-by-row .products-sort-order .dropdown-menu a{white-space:nowrap;font-size:14px;font-family:"Inter";font-weight:400}#products .sort-by-row .products-sort-order .dropdown-menu a:hover{background:#fff;font-weight:700;color:#462d26}#products .sort-by-row .products-sort-order button{background:none;border:0;display:flex;justify-content:space-between;align-items:center;color:#462d26;font-family:"Inter";font-size:16px;font-weight:700;width:350px}#search_filters{background:none;border-top:1px solid rgba(17,14,12,.1019607843);border-bottom:1px solid rgba(17,14,12,.1019607843);border-radius:0 !important;padding-left:0;padding-right:0}#search_filters .head{display:flex;justify-content:space-between;align-items:center;margin-bottom:20px}#search_filters .head .h6{font-size:16px;font-weight:700;font-family:"Inter";text-transform:uppercase;color:#462d26;margin-bottom:0;display:flex;align-items:center;-moz-column-gap:5px;column-gap:5px}#search_filters .head .js-search-filters-clear-all{background:#462d26;color:#fff}#search_filters .content{gap:20px;background:#fff;padding:25px}#search_filters .content section.facet:first-child{padding-top:0}#search_filters .content section.facet:not(:first-child){padding-top:1.625rem}#search_filters .content .h6{font-weight:700;font-size:16px;font-family:"Inter";margin-bottom:15px}#search_filters .content .custom-checkbox{top:0;position:static}#search_filters .content .facet-label{display:flex;gap:10px;align-items:center;margin-bottom:10px}#search_filters .content .facet-label a{margin-top:0}#search_filters .content .faceted-slider>li>p{color:#462d26;font-family:"Inter",sans-serif;font-size:14px;font-weight:700}#js-product-list-top{padding:0 20px}.active_filters{background:#fff;border-radius:10px;color:#462d26}.active_filters .filter-block{background:#462d26;color:#fff;padding:3px 10px}.active_filters .filter-block i{text-shadow:none;color:#fff !important}#contact main .container>.row:nth-child(2){display:grid;grid-template-columns:310px 1fr;gap:32px}@media(max-width: 767px){#contact main .container>.row:nth-child(2){grid-template-columns:1fr}}#contact main .container>.row:nth-child(2) #left-column{display:block;width:100%;max-width:100%;padding:0}#contact main .container>.row:nth-child(2) #content-wrapper{display:block;width:100%;max-width:100%;padding:0}#contact main .container>.row:nth-child(2) #content-wrapper #content{padding:40px}#contact main .container>.row:nth-child(2) #content-wrapper #content h3{font-size:32px;color:#110e0c;font-family:"Inter";font-weight:600;margin-bottom:32px}#contact main .container>.row:nth-child(2) #content-wrapper #content form .psgdpr_consent_message{display:grid;grid-template-columns:20px 1fr;gap:5px;align-items:center}#contact main .container>.row:nth-child(2) #content-wrapper #content form .btn-primary{width:277px;display:flex;align-items:center;justify-content:center;font-size:14px;font-family:"Inter";text-transform:none;font-weight:500;height:47px}#contact main .container>.row:nth-child(2) #content-wrapper #content form .btn-primary:hover{background:#462d26}#contact main .container>.row:nth-child(2) #content-wrapper #content form label{color:#110e0c;font-size:12px;font-weight:500;font-family:"Inter";margin-bottom:4px}#contact main .container>.row:nth-child(2) #content-wrapper #content form label[for=file-upload].btn-default{background:#462d26;color:#fff;height:47px;display:flex;align-items:center;justify-content:center}#contact main .container>.row:nth-child(2) #content-wrapper #content form input[type=email],#contact main .container>.row:nth-child(2) #content-wrapper #content form input[type=text],#contact main .container>.row:nth-child(2) #content-wrapper #content form select{height:47px;display:flex;align-items:center;justify-content:flex-start;padding:0 16px;font-size:14px;color:#110e0c;font-family:"Inter";border:1px solid rgba(70,45,38,.1411764706);background-color:#f9f7f2}#contact main .container>.row:nth-child(2) #content-wrapper #content form input[type=email]:focus,#contact main .container>.row:nth-child(2) #content-wrapper #content form input[type=text]:focus,#contact main .container>.row:nth-child(2) #content-wrapper #content form select:focus{outline:none;box-shadow:none}#contact main .container>.row:nth-child(2) #content-wrapper #content form textarea{padding:0 16px;font-size:14px;color:#110e0c;font-family:"Inter";border:1px solid rgba(70,45,38,.1411764706);background-color:#f9f7f2;padding:10px}#contact main .container>.row:nth-child(2) #content-wrapper #content form textarea:focus{outline:none;box-shadow:none}.elementor-widget-product-carousel:hover .elementor-swiper-button{opacity:1 !important}.elementor-widget-product-carousel:hover .elementor-swiper-button.swiper-button-disabled{opacity:.3 !important}.elementor-widget-product-carousel:not(:hover) .elementor-swiper-button.elementor-swiper-button-prev{left:-10px}.elementor-widget-product-carousel:not(:hover) .elementor-swiper-button.elementor-swiper-button-next{right:-10px}.elementor-swiper-button{background:#ebe3d7;border-radius:100%;width:33px;height:33px;display:flex;align-items:center;justify-content:center;opacity:0 !important;top:141.5px;transition:all 250ms ease-in-out}.elementor-swiper-button i{padding-bottom:2px}.elementor-swiper-button.elementor-swiper-button-prev i{padding-right:3px}.elementor-swiper-button.elementor-swiper-button-prev i::before{content:url("/img/cms/icons/slider-arrow-left-brown.svg")}.elementor-swiper-button.elementor-swiper-button-next i{padding-left:3px}.elementor-swiper-button.elementor-swiper-button-next i::before{content:url("/img/cms/icons/slider-arrow-right-brown.svg")}.leo-megamenu .navbar-toggler.c-navbar-toggler{display:flex;flex-direction:row;align-items:center;justify-content:center;gap:8px;background:#e9e3d7;margin:0;padding:18px 24px;width:auto;outline:none !important}.leo-megamenu .navbar-toggler.c-navbar-toggler .c-sr-only{color:#110e0c;font-family:"Inter",sans-serif;font-size:11px;font-weight:500}@media(max-width: 991px){#header-panel-box .header-panel-box-row-1{margin-bottom:15px}}#header-panel-box .header-panel-box-row-1>div>.elementor-row{flex-wrap:nowrap;align-items:center}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap{flex-wrap:nowrap;align-items:center}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ps-widget-module{margin-bottom:0;width:-moz-fit-content;width:fit-content}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search>.elementor-widget-container{border:1px solid #e9e3d7;min-height:44px}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container button.elementor-search__submit{order:1}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container input.elementor-search__input{order:2;padding-left:0}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container input.elementor-search__input::-moz-placeholder{font-size:11px;font-weight:500}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container input.elementor-search__input::placeholder{font-size:11px;font-weight:500}#header-panel-box .header-panel-box-row-2 .header-panel-box-row-2-col-1>div>.elementor-widget-wrap>.elementor-widget-ajax-search form.elementor-search>.elementor-search__container .elementor-search__clear{order:3}section.off-canvas-nav-megamenu nav.offcanvas-mainnav{background:#fff}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu{text-align:initial;margin:24px 24px 0 24px;display:flex;flex-direction:row;justify-content:space-between}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu>a img{width:100%;max-width:200px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu .off-canvas-nav-close{margin:0;position:relative;font-size:0;width:14px;height:14px;min-width:14px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu .off-canvas-nav-close::before{content:"";position:absolute;width:2px;height:14px;background:#b8b7b6;top:50%;left:50%;transform:translate(-50%, -50%) rotate(45deg)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav .off-canvas-button-megamenu .off-canvas-nav-close::after{content:"";position:absolute;width:2px;height:14px;background:#b8b7b6;top:50%;left:50%;transform:translate(-50%, -50%) rotate(-45deg)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu{padding:28px 24px 24px 24px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item.open-sub>a{border:none !important}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item.open-sub>a .menu-title{color:#e79332}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item.open-sub .dropdown-menu{border-bottom:1px solid rgba(17,14,12,.1019607843)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item a{padding-top:16px;padding-bottom:16px;line-height:1;border-color:rgba(17,14,12,.1019607843)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item a .menu-title{color:#110e0c;font-size:14px;font-weight:600;font-family:"Inter",sans-serif}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .caret{top:7px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .caret::before{content:url("/img/cms/icons/arrow-down-brown-mini.svg")}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-menu .leo-widget{padding:0}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-menu .leo-widget div.menu-title{padding:0}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-menu .leo-widget div.menu-title a{color:#110e0c;font-size:14px;font-weight:600;font-family:"Inter",sans-serif;padding-top:14px;padding-bottom:14px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-menu .leo-widget ul li a{color:#110e0c;font-size:14px;font-weight:600;font-family:"Inter",sans-serif;padding-top:14px;padding-bottom:14px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item.promo-item>a>.menu-title{color:#c40000}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub{padding-bottom:20px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub .dropdown-menu-inner,section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub ul{padding-left:15px;border-left:1px solid rgba(17,14,12,.1)}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub .dropdown-menu-inner .mega-col ul{margin-bottom:20px}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub .dropdown-menu-inner .mega-col .leo-widget[data-id_widget="1753179161"]{display:none}section.off-canvas-nav-megamenu nav.offcanvas-mainnav ul.nav.navbar-nav.megamenu li.nav-item .dropdown-sub ul li a{font-weight:400 !important;padding:10px 0 !important}.dropdown-menu .leo-widget{padding-bottom:20px}header.page-header h1{color:#232323}form .form-group.form-group-alias{display:none !important}.elementor-cta-absolute-link{position:absolute;inset:0;z-index:1}.filter-block-all{display:inline-block;margin-right:.625rem;margin-bottom:.625rem}.filter-block-all button{margin:0 !important}.filter-block-all button .material-icons{margin:0}.scroll-brn-box{position:fixed;bottom:38px;right:100px;z-index:10000000;opacity:0;visibility:hidden;transition:all 250ms ease-in-out}.scroll-brn-box.active{opacity:1;visibility:visible}.scroll-brn-box a{width:56px;height:56px;background:#e79332;border-radius:100%;display:flex;align-items:center;justify-content:center;line-height:0}.scroll-brn-box a svg{width:16px;height:16px}@media(max-width: 767px){.scroll-brn-box{left:50%;right:auto;transform:translateX(-50%)}}.cart-voucher .promo-name{padding:10px}.cart-voucher .promo-name .cart-summary-line{display:flex;flex-direction:row;justify-content:space-between}.cart-voucher .promo-name .cart-summary-line>.label{text-align:left}.cart-voucher .promo-name .cart-summary-line .float-xs-right{min-width:-moz-fit-content;min-width:fit-content}#category-description{width:100%}#moved-category-structure .elementor-cta-content>div{width:100%}.block-promo .block-promo.promo-highlighted{color:#000;margin-top:10px}body.ce-kit-1{color:#000}.page-footer,.wishlist-footer-links{color:#000}.page-footer a,.wishlist-footer-links a{color:#000 !important}.gm_omniprice{display:block;width:100%}section#checkout-payment-step .payment-options-custom{display:flex;flex-direction:row;flex-wrap:wrap;-moz-column-gap:15px;column-gap:15px;row-gap:10px;margin-bottom:20px}section#checkout-payment-step .payment-options-custom>.js-payment-option-form,section#checkout-payment-step .payment-options-custom>.js-additional-information{display:none !important}section#checkout-payment-step .payment-options-custom .payment-option-title{color:#111516;font-size:14px;font-family:"Inter",sans-serif;font-weight:700;text-transform:initial;margin:0 !important;display:block;width:100%;padding-top:15px}section#checkout-payment-step .payment-options-custom .payment-option-title-1{order:1}section#checkout-payment-step .payment-options-custom .payment-option-title-2{order:100}section#checkout-payment-step .payment-options-custom .payment-option-title-3{order:200}section#checkout-payment-step .payment-options-custom .payment-item{position:relative;min-height:60px}section#checkout-payment-step .payment-options-custom .payment-item[option-name=paynow]{order:2}section#checkout-payment-step .payment-options-custom .payment-item[option-name=ps_wirepayment]{order:201}section#checkout-payment-step .payment-options-custom .payment-item[option-name=caraty]{order:101}section#checkout-payment-step .payment-options-custom .payment-item[option-name=santandercredit]{order:102}section#checkout-payment-step .payment-options-custom .payment-item[option-name=ps_cashondelivery]{order:202}section#checkout-payment-step .payment-options-custom .payment-item[option-name=ps_checkpayment]{order:203}section#checkout-payment-step .payment-options-custom .payment-item[option-name=payment-option-4]{order:103}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option{height:100%;margin:0 !important}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option>label{display:flex;flex-direction:column;align-items:center;justify-content:center;row-gap:10px;padding:10px 15px;margin:0;height:100%;color:#462d26;font-size:14px;font-family:"Inter",sans-serif;font-weight:500;line-height:1}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option>label img{order:1}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option>label span{order:2}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option .custom-radio{margin:0 !important}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option .custom-radio input{position:absolute;inset:0 !important;width:100% !important;height:100% !important;background:rgba(0,0,0,0)}section#checkout-payment-step .payment-options-custom .payment-item>.payment-option .custom-radio input::before,section#checkout-payment-step .payment-options-custom .payment-item>.payment-option .custom-radio input::after{display:none !important}.navbar-nav.megamenu>li:nth-child(7)>a{color:#e79332 !important}/*# sourceMappingURL=custom.css.map */ \ No newline at end of file diff --git a/themes/classic/assets/css/custom.scss b/themes/classic/assets/css/custom.scss index 33e5dea6..0139123a 100644 --- a/themes/classic/assets/css/custom.scss +++ b/themes/classic/assets/css/custom.scss @@ -4531,7 +4531,7 @@ section#checkout-payment-step { } .navbar-nav.megamenu { - li:nth-child(7) { + > li:nth-child(7) { > a { color: #e79332 !important; } From f00bc6bbc467025557df943e2844498f47b8174d Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Wed, 17 Dec 2025 23:03:43 +0100 Subject: [PATCH 7/7] =?UTF-8?q?Zaktualizowano=20plik=20import-drewmax.php,?= =?UTF-8?q?=20aby=20zakomentowa=C4=87=20automatyczne=20od=C5=9Bwie=C5=BCan?= =?UTF-8?q?ie=20strony=20po=20aktualizacji=20produkt=C3=B3w.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/ftp-kr.sync.cache.json | 4 ++-- import-drewmax.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.vscode/ftp-kr.sync.cache.json b/.vscode/ftp-kr.sync.cache.json index c5c7a05a..74d02097 100644 --- a/.vscode/ftp-kr.sync.cache.json +++ b/.vscode/ftp-kr.sync.cache.json @@ -135,8 +135,8 @@ "import-drewmax.php": { "type": "-", "size": 32286, - "lmtime": 0, - "modified": true + "lmtime": 1765839405797, + "modified": false }, "import-product.php": { "type": "-", diff --git a/import-drewmax.php b/import-drewmax.php index 43a839d0..1fb577a9 100644 --- a/import-drewmax.php +++ b/import-drewmax.php @@ -500,7 +500,7 @@ if ($modeUpdate) { } if ($updatedSomething) { - echo ''; + // echo ''; } else { echo '

Brak produktów do aktualizacji na dzisiaj (wszystkie z XML zostały już zaktualizowane).

'; }