Jump to content

Faire une règle d'affichage des produits par groupes


Recommended Posts

Bonjour, 

 

J'ai un client qui me demande de pouvoir afficher certain produits que aux pros (groupe clients 4) et certains que aux particuliers (groupe clients 3) et d'autres à tout le monde.

 

y a t'il une solution native à ce probleme ??

 

je n'ai pas trouvé la solution j'ai donc fait comme suit

 

j'ai ajouté cette fonction pour pouvoir savoir à quel groupe appartient le client

        public function hookHeader()
        {
                global $smarty;
                $context = Context::getContext();
                $id_lang = $context->cart->id_lang;
                $customer = $context->customer;
                $id_customer = $customer->id;
                $groups = Db::getInstance()->executeS("SELECT " ._DB_PREFIX_. "customer_group.id_group , " ._DB_PREFIX_. "group_lang.name
				FROM " ._DB_PREFIX_. "customer_group
                                LEFT JOIN " ._DB_PREFIX_. "group_lang ON " ._DB_PREFIX_. "group_lang.id_group = " ._DB_PREFIX_. "customer_group.id_group
                                WHERE " ._DB_PREFIX_. "customer_group.id_customer = '$id_customer' AND " ._DB_PREFIX_. "group_lang.id_lang = '$id_lang'");
                if(!isset($groups[0])) $groups = FALSE;
                $smarty->assign('customerGroups', $groups);
        }

Grace à cela j'obtiens la variable $customerGroups[0]['id_group']   si elle est = à 4, le client est professionnel si elle est inférieur ou égale à 3 le client est particulier 

 

ensuite j'utilise le champs UPC de prestashop comme suit:

 

vide = on montre le produit à tout le monde 

1 = on ne le montre que aux particuliers

2 = on ne montre le produit que aux pros

 

Ma question :  comment modifier la requete qui charge la product-list pour lui dire de ne pas prendre les produits avec le champs UPC à 1 si je suis pro (groupe client 4) ou les produits avec le champs UPC à 2 si je suis particuliers  ??

 

j'ai essayé de faire ceci dans la page product list 

 

{if isset($product.upc) && $product.upc == "1" && $customerGroups[0]['id_group'] == '4'}{continue} {/if}  
{if isset($product.upc) && $product.upc == "2" && $customerGroups[0]['id_group'] <= '3'}{continue} {/if} 
 
{continue} veut dire qu'on saute et on enchaine sur la prochaine bouclie du foreach mais du coup j'obtiens un bug avec le css et le nombre de pages de la pagination 
 
 
je suis preneur de tous les conseils 
Link to comment
Share on other sites

Concernant l'affichage sur la page catégorie, ça va se passer dans CategoryController.php

 

Dans la function assignProductList() on voit que la liste des produits est récupérée par $this->category->getProducts

Il faut donc overrider la function getProducts de la class Category en y ajoutant vos conditions

ou créer une autre fonction geProductsbyGroup et modifier CategoryController pour se servir de celle-ci

 

Par contre, ça n'empêchera pas d'accéder à la fiche produit via son URL.

Ni de l'afficher dans d'autres modules qui n'utiliseraient pas cette fonction.

Link to comment
Share on other sites

Excellent merci beaucoup pour votre aide si précieuse , j'ai donc réussi à modifier la requete en dur mais j'ai un probleme quand je veux mettre cette condition 

		if ($customerGroups[0]['id_group'] == 4){
			$sql.= 'AND p.upc != 1 ';
		}

j'obtiens cette erreur 

Notice: Undefined variable: customerGroups in /var/www/newdiscount/classes/Category.php on line 779

donc comment faire pour récupérer le groupe du client  "en cours" dans la page category.php ?? 

Link to comment
Share on other sites

category.php n'est pas une page

 

Vous pouvez probablement instancier le context et y récupérer l'id_customer mais il parait plus logique et propre de le faire dans le Controller.

 

donc dans CategoryController, au moment de l'appel de $this->category->getProducts, vous lui passez un paramètre supplémentaire.

(ou votre autre fonction, si vous avez choisi d'en faire une autre)

 

grâce à $this->context->customer->id vous allez récupérer l'id customer

à partir de la, vous pouvez verifier ses groupes.

et passer votre paramètre à l'appel de getProducts, en fonction de vos conditions.

 

Du coup, obligé d'overrider à la fois Category et CategoryController.

Link to comment
Share on other sites

Merci encore pour votre réponse mais ca ne marche pas, pouvez vous développer un tout petit peu la marche à suivre car dans la fonction getproducts du categorycontroller il n'arrive pas à prendre $this->context->customer->id 

 

est ce normal ?

 

ps: je sais que c'est pas bien mais je ne passes pas par l'override, je le fais directement dans les fichiers concernés, cela peut il avoir un impact sur mon probleme ? 

 

merci encore pour la réactivité et l'efficacité de vos réponses

Link to comment
Share on other sites

C'est une très mauvaise idée de modifier les fichiers du Core.

Mais non, ça ne vous empêche pas de faire ce que vous voulez.

(mais vous vous en mordrez les doigts un jour)

 

Avant de faire le getproducts, vous faites ceci

$id_customer=$this->context->customer->id;

à partir de l'id_customer, vous faites votre traitement pour récupérer la condition d'affichage, $pro_only par exemple.

 

Ensuite vous modifiez l'appel par

$this->cat_products = $this->category->getProducts($this->context->language->id, (int)$this->p, (int)$this->n, $this->orderBy, $this->orderWay, false, true, false, 1, true, null, $pro_only);

Ce qui impose de modifier la déclaration de la fonction getProducts de la class Category pour y ajouter le paramètre supplémentaire. (proprement, par un override)

C'est pour ça que faire une autre fonction aurait peut être été mieux.

public function getProducts($id_lang, $p, $n, $order_by = null, $order_way = null, $get_total = false, $active = true, $random = false, $random_number_products = 1, $check_access = true, Context $context = null, $pro_only = false) {
   ...
   if ($pro_only == true) {
      $sql.= 'AND p.upc != 1 ';

Link to comment
Share on other sites

        // The hook was not executed, standard working
        if (!$hook_executed) {
			$id_customer = $this->context->customer->id;
            $this->context->smarty->assign('categoryNameComplement', '');
            $this->nbProducts = $this->category->getProducts(null, null, null, $this->orderBy, $this->orderWay, true,$id_customer);
            $this->pagination((int)$this->nbProducts); // Pagination must be call after "getProducts"
            $this->cat_products = $this->category->getProducts($this->context->language->id, (int)$this->p, (int)$this->n, $this->orderBy, $this->orderWay,$id_customer);
        }

Ce qui me donne ça, mais j'ai essayé de définir la variable en dehors de toutes les fonctions ca ne marche pas non plus j'obtiens 

Warning: Missing argument 12 for CategoryCore::getProducts(), called in /var/www/monsite/controllers/front/CategoryController.php on line 228 and defined in /var/www/monsite/classes/Category.php on line 688

Warning: Missing argument 12 for CategoryCore::getProducts(), called in /var/www/monsite/controllers/front/CategoryController.php on line 230 and defined in /var/www/monsite/classes/Category.php on line 688

Notice: Undefined variable: groupeclient in /var/www/monsite/classes/Category.php on line 779

j'ai l'impression que prestashop ne veut pas de $this->context->customer->id  dans categorycontroller.php je me trompe ? 

Link to comment
Share on other sites

Si vous avez rajouté l'argument $pro_only à la déclaration de la function getProducts de la class Category, vous vous retrouvez avec 11 arguments.

bizarrement il vous en demande 12 donc la il y a déjà une erreur

En plus, si vous avez bien mis $pro_only=false alors l'argument ne devrait pas être obligatoire et on ne devrait pas avoir ce warning

 

Ensuite, à l'appel de getProducts, vous avez juste rajouté $id_customer comme 6ème argument.

Ce qu'il fait qu'il récupère l'id_customer à la place de $get_total

 

Vous avez tout en main maintenant, il n'y a qu'à appliquer.

Link to comment
Share on other sites

Le problème c'est que je ne peux pas le faire en fonction $pro_only car je ne peux pas savoir dans le categorycontroller quel est le champs upc du produit qui va être récupéré... de plus il y a deux lignes avec la fonction getproducts et j'utilises les 2 lignes laquelle est la plus appropriée ? 

 

merci encore du temps que vous me consacrez et de la réactivité 

Link to comment
Share on other sites

oui effectivement, vous devez passer donc l'id_customer et faire votre traitement dans getProducts.

 

La première ligne appelant getproducts dans assignProductList  est celle qui va chercher le nombre de produits et qui va donc servir pour la pagination (ligne en dessous)

ceci grace au paramètre get_total

@param boolean $get_total return the number of results instead of the results themself

la seconde est celle qui va chercher les infos des produits.

Link to comment
Share on other sites

Je comprends mais je touche presque la fin, juste soyez plus explicite dans votre réponse car je n'arrive pas bien à comprendre comment faire passer ce fameux id_customer j'ai essayé pleins de choses en attendant votre réponse et je ne trouves vraiment rien, je veux pas abuser de votre gentillesse mais juste un petit peu plus et j'y suis ;)

 

merci encore pour tout ce temps accordé

Link to comment
Share on other sites

J'essaie au mieux de vous guider dans votre reflexion pour que vous trouviez vous même comment répondre à une problématique, ce qui vous aidera lorsque vous rencontrerez un problème similaire.

En aucun cas, je ne vais faire ce travail à votre place.

 

D'autant plus que :

J'ai un client qui me demande ...

Vous avez un client qui vous a fait une demande et auquel vous avez donc répondu "ok, pas de problème, je sais faire ça, je m'en occupe".
Puisque vous avez accepté cette demande, et que vous allez facturer ce travail.

Vous avez tout en main, relisez avec attention ce qui a été dit, et vous allez y arriver.

  • Like 1
Link to comment
Share on other sites

ChDUP, un grand merci pour votre aide, votre patience et votre réactivité, j'ai bien tout relu au calme et j'ai finalement réussi à le faire grâce à vous, je postes la solution si jamais ca peut aider quelqu'un ;)

 

/classes/category.php

 public function getProducts($id_lang, $p, $n, $order_by = null, $order_way = null, $get_total = false, $active = true, $random = false, $random_number_products = 1, $check_access = true, Context $context = null)
    {
		
		
		if (!$context) {
            $context = Context::getContext();
        }
		
		$groups = FrontController::getCurrentCustomerGroups();
		$mongroupe = (count($groups) ? 'IN ('.implode(',', $groups).')' : '='.(int)Group::getCurrent()->id);
		$groupepro = 0;
		
		
		if( (int)Group::getCurrent()->id == 4){
			$groupepro = 1;
		}else{
			$groupepro = 0;
		}
		
        if ($check_access && !$this->checkAccess($context->customer->id)) {
            return false;
        }

        $front = in_array($context->controller->controller_type, array('front', 'modulefront'));
        $id_supplier = (int)Tools::getValue('id_supplier');

        /** Return only the number of products */
        if ($get_total) {
            $sql = 'SELECT COUNT(cp.`id_product`) AS total
					FROM `'._DB_PREFIX_.'product` p
					'.Shop::addSqlAssociation('product', 'p').'
					LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON p.`id_product` = cp.`id_product`
					WHERE cp.`id_category` = '.(int)$this->id.
                ($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '').
                ($active ? ' AND product_shop.`active` = 1' : '').
                ($id_supplier ? 'AND p.id_supplier = '.(int)$id_supplier : '')
				.($groupepro == 1 ? ' AND p.upc != 1' : ' AND p.upc != 2');

            return (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
        }

        if ($p < 1) {
            $p = 1;
        }

        /** Tools::strtolower is a fix for all modules which are now using lowercase values for 'orderBy' parameter */
        $order_by  = Validate::isOrderBy($order_by)   ? Tools::strtolower($order_by)  : 'position';
        $order_way = Validate::isOrderWay($order_way) ? Tools::strtoupper($order_way) : 'ASC';

        $order_by_prefix = false;
        if ($order_by == 'id_product' || $order_by == 'date_add' || $order_by == 'date_upd') {
            $order_by_prefix = 'p';
        } elseif ($order_by == 'name') {
            $order_by_prefix = 'pl';
        } elseif ($order_by == 'manufacturer' || $order_by == 'manufacturer_name') {
            $order_by_prefix = 'm';
            $order_by = 'name';
        } elseif ($order_by == 'position') {
            $order_by_prefix = 'cp';
        }

        if ($order_by == 'price') {
            $order_by = 'orderprice';
        }

        $nb_days_new_product = Configuration::get('PS_NB_DAYS_NEW_PRODUCT');
        if (!Validate::isUnsignedInt($nb_days_new_product)) {
            $nb_days_new_product = 20;
        }
		
        $sql = 'SELECT p.*, product_shop.*, stock.out_of_stock, IFNULL(stock.quantity, 0) AS quantity'.(Combination::isFeatureActive() ? ', IFNULL(product_attribute_shop.id_product_attribute, 0) AS id_product_attribute,
					product_attribute_shop.minimal_quantity AS product_attribute_minimal_quantity' : '').', pl.`description`, pl.`description_short`, pl.`available_now`,
					pl.`available_later`, pl.`link_rewrite`, pl.`meta_description`, pl.`meta_keywords`, pl.`meta_title`, pl.`name`, image_shop.`id_image` id_image,
					il.`legend` as legend, m.`name` AS manufacturer_name, cl.`name` AS category_default,
					DATEDIFF(product_shop.`date_add`, DATE_SUB("'.date('Y-m-d').' 00:00:00",
					INTERVAL '.(int)$nb_days_new_product.' DAY)) > 0 AS new, product_shop.price AS orderprice
				FROM `'._DB_PREFIX_.'category_product` cp
				LEFT JOIN `'._DB_PREFIX_.'product` p
					ON p.`id_product` = cp.`id_product`
				'.Shop::addSqlAssociation('product', 'p').
                (Combination::isFeatureActive() ? ' LEFT JOIN `'._DB_PREFIX_.'product_attribute_shop` product_attribute_shop
				ON (p.`id_product` = product_attribute_shop.`id_product` AND product_attribute_shop.`default_on` = 1 AND product_attribute_shop.id_shop='.(int)$context->shop->id.')':'').'
				'.Product::sqlStock('p', 0).'
				LEFT JOIN `'._DB_PREFIX_.'category_lang` cl
					ON (product_shop.`id_category_default` = cl.`id_category`
					AND cl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('cl').')
				LEFT JOIN `'._DB_PREFIX_.'product_lang` pl
					ON (p.`id_product` = pl.`id_product`
					AND pl.`id_lang` = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl').')
				LEFT JOIN `'._DB_PREFIX_.'image_shop` image_shop
					ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop='.(int)$context->shop->id.')
				LEFT JOIN `'._DB_PREFIX_.'image_lang` il
					ON (image_shop.`id_image` = il.`id_image`
					AND il.`id_lang` = '.(int)$id_lang.')
				LEFT JOIN `'._DB_PREFIX_.'manufacturer` m
					ON m.`id_manufacturer` = p.`id_manufacturer`
				WHERE product_shop.`id_shop` = '.(int)$context->shop->id.'
					AND cp.`id_category` = '.(int)$this->id
                    .($active ? ' AND product_shop.`active` = 1' : '')
                    .($front ? ' AND product_shop.`visibility` IN ("both", "catalog")' : '')
                    .($id_supplier ? ' AND p.id_supplier = '.(int)$id_supplier : '')
					.($groupepro == 1 ? ' AND p.upc != 1' : 'AND p.upc != 2');


Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...