From b2deab536615d2e91cfde910aaad8fba13096534 Mon Sep 17 00:00:00 2001 From: Oscar Gomez Date: Mon, 18 Nov 2024 14:28:56 +0100 Subject: [PATCH] Some fixes to handle multiprice properly During update on save, the expected value for the multiprice is the map itself and not the CSV format for the multiprice. In addition, we should avoid sending a "" as multiprice because it causes problems in doofAPI. --- feeds/product.php | 4 +- src/Entity/DfProductBuild.php | 9 ++--- src/Entity/DfTools.php | 69 ++++++++++++++++++++++++++++++----- 3 files changed, 65 insertions(+), 17 deletions(-) diff --git a/feeds/product.php b/feeds/product.php index 509c40b..ccf73cd 100644 --- a/feeds/product.php +++ b/feeds/product.php @@ -295,7 +295,7 @@ function arrayMergeByIdProduct($array1 = [], $array2 = []) $variant_id = $row['id_product_attribute']; $product_price = DfTools::getPrice($product_id, $cfg_prices_w_taxes, $variant_id); $onsale_price = DfTools::getOnsalePrice($product_id, $cfg_prices_w_taxes, $variant_id); - $multiprice = DfTools::getMultiprice($product_id, $cfg_prices_w_taxes, $currencies, $variant_id); + $multiprice = DfTools::getFormattedMultiprice($product_id, $cfg_prices_w_taxes, $currencies, $variant_id); if ((int) $row['id_product'] > 0) { // ID, TITLE, LINK @@ -507,7 +507,7 @@ function arrayMergeByIdProduct($array1 = [], $array2 = []) $product_price = DfTools::getPrice($product_id, $cfg_prices_w_taxes); $onsale_price = DfTools::getOnsalePrice($product_id, $cfg_prices_w_taxes); - $multiprice = DfTools::getMultiprice($product_id, $cfg_prices_w_taxes, $currencies); + $multiprice = DfTools::getFormattedMultiprice($product_id, $cfg_prices_w_taxes, $currencies); if ($row['show_price']) { echo Tools::convertPrice($product_price, $currency); diff --git a/src/Entity/DfProductBuild.php b/src/Entity/DfProductBuild.php index f3c0d6e..96ea90b 100644 --- a/src/Entity/DfProductBuild.php +++ b/src/Entity/DfProductBuild.php @@ -136,7 +136,10 @@ private function buildProduct($product) if ($this->displayPrices) { $p['price'] = $this->getPrice($product); $p['sale_price'] = $this->getPrice($product, true); - $p['df_multiprice'] = $this->getMultiprice($product); + + if ($this->multipriceEnabled) { + $p['df_multiprice'] = $this->getMultiprice($product); + } } if ($this->showProductFeatures) { @@ -322,10 +325,6 @@ private function getPrice($product, $salePrice = false) private function getMultiprice($product) { - if (!$this->multipriceEnabled) { - return ''; - } - $productId = $product['id_product']; $idProductAttribute = $this->productVariations ? $product['id_product_attribute'] : null; diff --git a/src/Entity/DfTools.php b/src/Entity/DfTools.php index 6ac8e08..96bc570 100644 --- a/src/Entity/DfTools.php +++ b/src/Entity/DfTools.php @@ -1354,7 +1354,7 @@ public static function getMinVariantPrices($products, $includeTaxes, $currencies $variantId = $product['id_product_attribute']; $variantPrice = self::getPrice($productId, $includeTaxes, $variantId); $variantOnsalePrice = self::getOnsalePrice($productId, $includeTaxes, $variantId); - $variantMultiprice = self::getMultiprice($productId, $includeTaxes, $currencies, $variantId); + $variantMultiprice = self::getFormattedMultiprice($productId, $includeTaxes, $currencies, $variantId); if (key_exists($productId, $minPricesByProductId)) { $currentMinPrices = $minPricesByProductId[$productId]; @@ -1414,22 +1414,22 @@ public static function getOnsalePrice($productId, $includeTaxes, $variantId = nu } /** - * Given a product and a list of currencies, returns the multiprice field - * in the correct format to be processed by the indexing process. + * Given a product and a list of currencies, returns the multiprice map. * - * An example of a value for this field is: "price_EUR=33/sale_price_EUR=25/price_GBP=11/sale_price_GBP=8" + * An example of a value for this field is + * ["EUR" => ["price" => 5, "sale_price" => 3], "GBP" => ["price" => 4.3, "sale_price" => 2.7]] * for a list containing two currencies ["EUR", "GBP"]. * - * @param int $productId Id of the procut to calculate the multiprice for + * @param int $productId Id of the product to calculate the multiprice for * @param bool $includeTaxes Determines if taxes have to be included in the calculated prices * @param array $currencies List of currencies to consider for the multiprice calculation * @param int $variantId When specified, the multiprice will be calculated for that variant * - * @return string + * @return array */ public static function getMultiprice($productId, $includeTaxes, $currencies, $variantId = null) { - $multiprices = []; + $multiprice = []; $price = self::getPrice($productId, $includeTaxes, $variantId); $onsale_price = self::getOnsalePrice($productId, $includeTaxes, $variantId); @@ -1437,12 +1437,61 @@ public static function getMultiprice($productId, $includeTaxes, $currencies, $va if ($currency['deleted'] == 0 && $currency['active'] == 1) { $convertedPrice = \Tools::convertPrice($price, $currency); $convertedOnsalePrice = \Tools::convertPrice($onsale_price, $currency); - - $multiprices[] = $currency['iso_code'] . '_price=' . $convertedPrice; + $currencyCode = $currency['iso_code']; + $pricesMap = ["price" => $convertedPrice]; if ($convertedPrice != $convertedOnsalePrice) { - $multiprices[] = $currency['iso_code'] . '_sale_price=' . $convertedOnsalePrice; + $pricesMap["sale_price"] = $convertedOnsalePrice; } + + $multiprice[$currencyCode] = $pricesMap; + } + } + + return $multiprice; + } + + /** + * Given a product and a list of currencies, returns the multiprice field + * in the correct format to be used in the feed CSV. + * + * An example of a value for this field is + * "price_EUR=5/sale_price_EUR=3/price_GBP=4.3/sale_price_GBP=2.7" + * for a list containing two currencies ["EUR", "GBP"]. + * + * @param int $productId Id of the product to calculate the multiprice for + * @param bool $includeTaxes Determines if taxes have to be included in the calculated prices + * @param array $currencies List of currencies to consider for the multiprice calculation + * @param int $variantId When specified, the multiprice will be calculated for that variant + * + * @return string + */ + public static function getFormattedMultiprice($productId, $includeTaxes, $currencies, $variantId = null) + { + $multiprice = self::getMultiprice($productId, $includeTaxes, $currencies); + return self::formatMultiprice($multiprice); + } + + /** + * Transforms a given multiprice map into the correct format to be processed + * to the format required by the CSV feed. + * + * For an input like + * ["EUR" => ["price" => 5, "sale_price" => 3], "GBP" => ["price" => 4.3, "sale_price" => 2.7]] + * it would produce + * "price_EUR=5/sale_price_EUR=3/price_GBP=4.3/sale_price_GBP=2.7" + * + * @param int $multiprice Multiprice map to be formatted + * + * @return string + */ + private static function formatMultiprice($multiprice) + { + $multiprices = []; + + foreach ($multiprice as $currency => $prices) { + foreach ($prices as $price_name => $value) { + $multiprices[] = $currency . '_' . $price_name . '=' . $value; } }