Shonen Posted September 23 Share Posted September 23 Bonjour à tous, Je tombe sur un problème étrange, qui ne m'avais jamais dérangé jusque là et qui pourtant est présent sur tous mes sites Prestashop 1.6. Contexte : Préférence Produit > Refuser les commandes en cas de rupture de stock Création de plusieurs attributs (peu importe, ici exemple Date pour des cours de cuisine) Association des attributs à mon produit, et gestion des quantités manuelle. Je définis ma déclinaison par défaut à la date la plus proche, j'ai donc ici 3 décli, avec le 25 octobre par défaut pour que mon produit propose cette date en premier, cf capture d'écran. Ensuite je me dirige dans les quantités, la ligne en bleue est différente mais je ne m'en inquiète pas plus que ça, je définis mes quantité en prenant soin de mettre une déclinaison à 0 quantité pour mon test. Ici 13 novembre. Je me dirige vers l'aperçu du produit, et que n'est pas ma surprise, le produit sans quantité est le 20 décembre, rien à voir avec mon backoffice. Pour corriger le problème, je suis obligé de sélectionner en attribut par défaut le produit qui est en bleu dans l'onglet quantité, donc 20 décembre comme vu sur ma capture d'écran. Si je procède ainsi, alors seulement les quantités sont correctement alignées. Et je peux reproduire ce bug sur TOUS mes sites. Est-ce que je fais quelque chose dans le mauvais ordre ? J'ai essayé de créer mes déclinaisons une par une ou via le générateur, j'ai le même problème. J'ai aussi essayé de changer l'ordre des attributs dans l'onglet Attributs et valeurs, mais ça ne corrige rien et surtout l'ordre est celui que je souhaite. Je suis paumé ! Je vais me créer un Presta vierge 1.6 pour le triturer, mais si quelqu'un a déjà eu le problème je suis preneur d'une solution ou d'un tuto, merci ! Link to comment Share on other sites More sharing options...
Nemesis tech Posted September 23 Share Posted September 23 Bonjour, Normalement, il faut sélectionner un attribut par défault. Si cela ne fonctionne pas après avoir vidé le cache de PrestaShop & autre, alors, il y a sûrement un problème au niveau du thème. Link to comment Share on other sites More sharing options...
Eolia Posted September 23 Share Posted September 23 Pas de cache serveur derrière type varnish, speedcache, litespeed ou cloudflare ? Link to comment Share on other sites More sharing options...
Eolia Posted September 23 Share Posted September 23 il y a une heure, Nemesis tech a dit : Bonjour, Normalement, il faut sélectionner un attribut par défault. Si cela ne fonctionne pas après avoir vidé le cache de PrestaShop & autre, alors, il y a sûrement un problème au niveau du thème. Non, le thème ne fait qu'afficher les données envoyées par le contrôleur. Si le thème avait un souci les données ne seraient jamais correctes. Link to comment Share on other sites More sharing options...
Shonen Posted September 25 Author Share Posted September 25 Merci de vos réponses On 9/23/2024 at 5:42 PM, Eolia said: Pas de cache serveur derrière type varnish, speedcache, litespeed ou cloudflare ? Non aucun cache d'installé, j'ai testé sur un hébergement OVH, un hébergement O2switch et en local sans différence. J'ai essayé sur un site installé à l'instant ce matin en local, récupéré sur le site de Prestashop version 1.6.1.19 donc site vierge. Produit par défaut, sans rien changer sauf la quantité et le problème est exactement le même (cf capture). Version PHP 7.1.33, il s'agit donc bien d'un problème sur tous les presta je pense. C'est assez improbable que je n'ai jamais vu le problème avec la masse de sites 1.6 que j'ai installé pour des clients, en général mes clients autorisent la commande hors stock mais là comme il s'agit de cours de cuisine limités, les stocks sont importants. C'est une première pour moi et là ça me dépasse. Link to comment Share on other sites More sharing options...
Eolia Posted September 26 Share Posted September 26 Je n'arrive pas à reproduire votre bug. La seule différence avec vous c'est que mes sites 1.6 sont restés en PHP 5.6 vu que les versions 1.6 et même la 1.6.1.24 n'ont jamais été complètement compatibles PHP 7. Link to comment Share on other sites More sharing options...
Shonen Posted September 26 Author Share Posted September 26 Alors je ne peux rien tester en 5.6 tout du moins pas sur wamp. Je ne peux pas ouvrir phpmyadmin avec cette version de PHP. Sur OVH je suis passé en 5.6 pour mon site qui affiche cet problème, et je n'ai aucun changement sur le comportement. Pour arriver à reproduire l'erreur, il me suffit de définir une déclinaison par défaut différente de la déclinaison qui est en bleu dans l'onglet Quantités (toujours la dernière déclinaison semble-t-il). Ensuite, la déclinaison qui affiche la rupture de stock est toujours en décalé par rapport au backoffice. Par contre si je définis la déclinaison par défaut sur la même valeur que la déclinaison sur fond bleu dans l'onglet Quantité, je n'ai plus de problème. Sauf que bien évidemment ça ne m'arrange pas du tout car la déclinaison côté Quantité n'est pas celle que je souhaite. Link to comment Share on other sites More sharing options...
Nemesis tech Posted September 26 Share Posted September 26 @Shonen avec un PrestaShop clean, de test, est-ce que vous arrivez à reproduire le problème ? Ou tout fonctionne correctement ? Link to comment Share on other sites More sharing options...
Eolia Posted September 26 Share Posted September 26 Quand je crée des déclis c'est toujours la 1ère qui est en bleu que ce soit dans l'onglet déclinaison et l'onglet quantité. Le code est d'ailleurs clair à ce sujet: on commence par assigner $default_on à 1. On l'applique à la 1ère décli et on l'assigne à 0 Toutes les suivantes seront donc à 0. 1 Link to comment Share on other sites More sharing options...
Shonen Posted September 27 Author Share Posted September 27 17 hours ago, Nemesis tech said: @Shonen avec un PrestaShop clean, de test, est-ce que vous arrivez à reproduire le problème ? Ou tout fonctionne correctement ? Prestashop clean comme mentionné plus haut, et le problème persiste même avec les produits par défauts (non créés par moi même). @Eolia J'ai pourtant le même code source que vous. Dans l'onglet Déclinaisons c'est bien Couleur Orange, Taille S qui est en bleu, ce qui correspond bien à ma base de données. Et pourtant onglet Quantités c'est toujours le dernier qui est en bleu. Pourtant dans mon quantities.tpl je vois bien qu'il appelle le bon bout de code... Ca n'arrive vraiment qu'à moi ? Mais alors pourquoi sur tous mes Prestashop, peut importe la configuration ? Cela peut-il venir du fait que dans mon DOM et dans ma base, l'ordre dans lequel sont appelés les quantités est un peu étrange ? On commence par le qty_2 et on termine par le qty_1, alors que qty_1 devrait logiquement être Taille S couleur Orange dans mon cas puisque c'est id_product_attribute = 1. Le var_dump de la variable $attributes : celui-ci n'est pas bon puisque chaque id_product_attribute est décalé. Le problème doit venir de là mais je ne sais pas comment vérifier. C:\wamp64\www\ps6\tools\smarty\sysplugins\smarty_internal_templatebase.php(171) : eval()'d code:213: array (size=6) 0 => array (size=18) 'id_product_attribute' => string '2' (length=1) 'id_product' => string '1' (length=1) 'reference' => string '' (length=0) 'supplier_reference' => string '' (length=0) 'location' => string '' (length=0) 'ean13' => string '' (length=0) 'upc' => string '' (length=0) 'wholesale_price' => string '0.000000' (length=8) 'price' => string '0.000000' (length=8) 'ecotax' => string '0.000000' (length=8) 'quantity' => int 300 'weight' => string '0.000000' (length=8) 'unit_price_impact' => string '0.000000' (length=8) 'default_on' => null 'minimal_quantity' => string '1' (length=1) 'available_date' => string '0000-00-00' (length=10) 'id_shop' => string '1' (length=1) 'attribute_designation' => string 'Taille - S, Couleur - Orange' (length=28) 1 => array (size=18) 'id_product_attribute' => string '3' (length=1) 'id_product' => string '1' (length=1) 'reference' => string '' (length=0) 'supplier_reference' => string '' (length=0) 'location' => string '' (length=0) 'ean13' => string '' (length=0) 'upc' => string '' (length=0) 'wholesale_price' => string '0.000000' (length=8) 'price' => string '0.000000' (length=8) 'ecotax' => string '0.000000' (length=8) 'quantity' => int 300 'weight' => string '0.000000' (length=8) 'unit_price_impact' => string '0.000000' (length=8) 'default_on' => null 'minimal_quantity' => string '1' (length=1) 'available_date' => string '0000-00-00' (length=10) 'id_shop' => string '1' (length=1) 'attribute_designation' => string 'Taille - S, Couleur - Bleu' (length=26) 2 => array (size=18) 'id_product_attribute' => string '4' (length=1) 'id_product' => string '1' (length=1) 'reference' => string '' (length=0) 'supplier_reference' => string '' (length=0) 'location' => string '' (length=0) 'ean13' => string '' (length=0) 'upc' => string '' (length=0) 'wholesale_price' => string '0.000000' (length=8) 'price' => string '0.000000' (length=8) 'ecotax' => string '0.000000' (length=8) 'quantity' => int 0 'weight' => string '0.000000' (length=8) 'unit_price_impact' => string '0.000000' (length=8) 'default_on' => null 'minimal_quantity' => string '1' (length=1) 'available_date' => string '0000-00-00' (length=10) 'id_shop' => string '1' (length=1) 'attribute_designation' => string 'Taille - M, Couleur - Orange' (length=28) 3 => array (size=18) 'id_product_attribute' => string '5' (length=1) 'id_product' => string '1' (length=1) 'reference' => string '' (length=0) 'supplier_reference' => string '' (length=0) 'location' => string '' (length=0) 'ean13' => string '' (length=0) 'upc' => string '' (length=0) 'wholesale_price' => string '0.000000' (length=8) 'price' => string '0.000000' (length=8) 'ecotax' => string '0.000000' (length=8) 'quantity' => int 300 'weight' => string '0.000000' (length=8) 'unit_price_impact' => string '0.000000' (length=8) 'default_on' => null 'minimal_quantity' => string '1' (length=1) 'available_date' => string '0000-00-00' (length=10) 'id_shop' => string '1' (length=1) 'attribute_designation' => string 'Taille - M, Couleur - Bleu' (length=26) 4 => array (size=18) 'id_product_attribute' => string '6' (length=1) 'id_product' => string '1' (length=1) 'reference' => string '' (length=0) 'supplier_reference' => string '' (length=0) 'location' => string '' (length=0) 'ean13' => string '' (length=0) 'upc' => string '' (length=0) 'wholesale_price' => string '0.000000' (length=8) 'price' => string '0.000000' (length=8) 'ecotax' => string '0.000000' (length=8) 'quantity' => int 300 'weight' => string '0.000000' (length=8) 'unit_price_impact' => string '0.000000' (length=8) 'default_on' => null 'minimal_quantity' => string '1' (length=1) 'available_date' => string '0000-00-00' (length=10) 'id_shop' => string '1' (length=1) 'attribute_designation' => string 'Taille - L, Couleur - Orange' (length=28) 5 => array (size=18) 'id_product_attribute' => string '1' (length=1) 'id_product' => string '1' (length=1) 'reference' => string '' (length=0) 'supplier_reference' => string '' (length=0) 'location' => string '' (length=0) 'ean13' => string '' (length=0) 'upc' => string '' (length=0) 'wholesale_price' => string '0.000000' (length=8) 'price' => string '0.000000' (length=8) 'ecotax' => string '0.000000' (length=8) 'quantity' => int 0 'weight' => string '0.000000' (length=8) 'unit_price_impact' => string '0.000000' (length=8) 'default_on' => string '1' (length=1) 'minimal_quantity' => string '1' (length=1) 'available_date' => string '0000-00-00' (length=10) 'id_shop' => string '1' (length=1) 'attribute_designation' => string 'Taille - L, Couleur - Bleu' (length=26) Link to comment Share on other sites More sharing options...
Eolia Posted September 27 Share Posted September 27 les attributs de quantity.tpl arrivent de la fonction initFormQuantities($obj): $attributes = $obj->getAttributesResume($this->context->language->id); Pas d'override de Product, pas de foreach par référence où il manquerait un unset() final ? Cette fonction vous renvoie bien les attributs dans le bon ordre ? 1 Link to comment Share on other sites More sharing options...
Nemesis tech Posted September 27 Share Posted September 27 @Shonen Est-ce que vous avez la possibilité de faire le même test sur une version récente de PrestaShop (clean) ? Link to comment Share on other sites More sharing options...
Shonen Posted September 30 Author Share Posted September 30 On 9/27/2024 at 10:32 AM, Eolia said: les attributs de quantity.tpl arrivent de la fonction initFormQuantities($obj): $attributes = $obj->getAttributesResume($this->context->language->id); Pas d'override de Product, pas de foreach par référence où il manquerait un unset() final ? Cette fonction vous renvoie bien les attributs dans le bon ordre ? Merci énormément @Eolia pour toutes vos réponses, avec votre aide j'ai pu trouver le problème. Comme vous disiez, les attributs sont gérés dans la fonction getAttributesResume de la classe Product. La requête SQL en PHP, une fois décryptée donne ceci : SELECT pa.*, ps_product_attribute_shop.* FROM `ps_product_attribute` pa LEFT JOIN `ps_product_attribute_shop` ON `ps_product_attribute_shop`.`id_product_attribute` = pa.`id_product_attribute` WHERE pa.`id_product` = 1 GROUP BY pa.`id_product_attribute` Sauf que le résultat ressemble à ça chez moi (encore une fois, sur un Prestashop VIERGE de toute modification / override) : Le problème est que ensuite les autres fonctions de Prestashop ajoutent la quantité sur l'index dans l'ordre d'apparition, se basant sur le fait que la première valeur est forcément l'ID 1, ce qui n'est pas le cas chez moi (problème avec ma version de mysql ?). J'ai donc réalisé un override de ma fonction getAttributesResume pour ajouter ORDER BY, et dorénavant tout fonctionne normalement. <?php class Product extends ProductCore { /** * Get all available product attributes resume * * @param int $id_lang Language id * @return array Product attributes combinations */ public function getAttributesResume($id_lang, $attribute_value_separator = ' - ', $attribute_separator = ', ') { if (!Combination::isFeatureActive()) { return array(); } /* Ajout du ORDER BY pour corriger mon problème d'attributs */ $combinations = Db::getInstance()->executeS('SELECT pa.*, product_attribute_shop.* FROM `'._DB_PREFIX_.'product_attribute` pa '.Shop::addSqlAssociation('product_attribute', 'pa').' WHERE pa.`id_product` = '.(int)$this->id.' GROUP BY pa.`id_product_attribute` ORDER BY pa.`id_product_attribute`'); /* Fin de la correction */ if (!$combinations) { return false; } $product_attributes = array(); foreach ($combinations as $combination) { $product_attributes[] = (int)$combination['id_product_attribute']; } $lang = Db::getInstance()->executeS('SELECT pac.id_product_attribute, GROUP_CONCAT(agl.`name`, \''.pSQL($attribute_value_separator).'\',al.`name` ORDER BY agl.`id_attribute_group` SEPARATOR \''.pSQL($attribute_separator).'\') as attribute_designation FROM `'._DB_PREFIX_.'product_attribute_combination` pac LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute` LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group` LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)$id_lang.') LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)$id_lang.') WHERE pac.id_product_attribute IN ('.implode(',', $product_attributes).') GROUP BY pac.id_product_attribute'); foreach ($lang as $k => $row) { $combinations[$k]['attribute_designation'] = $row['attribute_designation']; } //Get quantity of each variations foreach ($combinations as $key => $row) { $cache_key = $row['id_product'].'_'.$row['id_product_attribute'].'_quantity'; if (!Cache::isStored($cache_key)) { $result = StockAvailable::getQuantityAvailableByProduct($row['id_product'], $row['id_product_attribute']); Cache::store( $cache_key, $result ); $combinations[$key]['quantity'] = $result; } else { $combinations[$key]['quantity'] = Cache::retrieve($cache_key); } } return $combinations; } Donc merci encore à tous pour vos lectures et votre aide, si jamais ce post peut aider quelqu'un d'autre... Link to comment Share on other sites More sharing options...
Eolia Posted September 30 Share Posted September 30 Ca c'est parce que vous êtes sur un MySQL 8 qui n'utilise plus l'auto-incrément comme ordre de tri par défaut. Link to comment Share on other sites More sharing options...
Eolia Posted September 30 Share Posted September 30 Vous devriez mettre à jour vos 1.6 en PhenixSuite et vous n'auriez plus ce genre de souci^^ Link to comment Share on other sites More sharing options...
Eolia Posted September 30 Share Posted September 30 Code de Phenix pour cette fonction: public function getAttributesResume($id_lang, $attribute_value_separator = ' - ', $attribute_separator = ', ') { if(!Combination::isFeatureActive()) { return array(); } $combinations = Db::getInstance()->executeS(' SELECT pa.*, product_attribute_shop.* FROM `'._DB_PREFIX_.'product_attribute` pa '.Shop::addSqlAssociation('product_attribute', 'pa').' WHERE pa.`id_product` = '.(int)$this->id.' GROUP BY pa.`id_product_attribute` ORDER BY pa.`id_product_attribute` '); if(!$combinations) { return array(); } $product_attributes = array(); foreach($combinations as $combination) { $product_attributes[] = (int)$combination['id_product_attribute']; } $lang = Db::getInstance()->executeS(' SELECT pac.`id_product_attribute`, GROUP_CONCAT(agl.`name`, \''.pSQL($attribute_value_separator).'\', al.`name` ORDER BY agl.`name` SEPARATOR \''.pSQL($attribute_separator).'\') as attribute_designation FROM `'._DB_PREFIX_.'product_attribute_combination` pac INNER JOIN `'._DB_PREFIX_.'attribute` a ON(a.`id_attribute` = pac.`id_attribute`) INNER JOIN `'._DB_PREFIX_.'attribute_group` ag ON(ag.`id_attribute_group` = a.`id_attribute_group`) INNER JOIN `'._DB_PREFIX_.'attribute_lang` al ON(a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)$id_lang.') INNER JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON(ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)$id_lang.') WHERE pac.`id_product_attribute` IN ('.implode(',', $product_attributes).') GROUP BY pac.`id_product_attribute` ORDER BY pac.`id_product_attribute` '); foreach($lang as $k => $row) { $combinations[$k]['attribute_designation'] = $row['attribute_designation']; } // Get parcels and quantity of each variations foreach($combinations as $key => $row) { // Parcels $combinations[$key]['parcels'] = array(); $existing_parcels = StockAvailable::getParcels( $row['id_product'], $row['id_product_attribute'] ); if(count($existing_parcels)) { $combinations[$key]['parcels'] = $existing_parcels; } // Quantity $cache_key = $row['id_product'].'_'.$row['id_product_attribute'].'_quantity'; if(!Cache::isStored($cache_key)) { $result = StockAvailable::getQuantityAvailableByProduct( $row['id_product'], $row['id_product_attribute'] ); Cache::store( $cache_key, $result ); $combinations[$key]['quantity'] = $result; } else { $combinations[$key]['quantity'] = Cache::retrieve($cache_key); } } return $combinations; } Il vous manque un deuxième ORDER BY pour info^^ 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now