Jump to content

Réduire l'affichage des commandes clients dans le BO?


Recommended Posts

Bonjour,

Nous possédons une boutique en ligne de vente de modélisme. Nous souhaitons réduire la visibilité d'anciennes commandes, au niveau back office dans un premier temps. Côté back office, cela ralenti quelque peu le chargement de la page d'un client, lorsque toutes ses commandes sont chargées et affichées, et n'a pas de réel intérêt pour nous. Nous souhaitons afficher uniquement les dernières commandes les plus récentes.

J'ai fait quelques recherches, sans succès jusqu'à présent, même si je me doute qu'il faudra très certainement utiliser une requête SQL.

Mais si quelqu'un a des pistes, je suis preneuse. :)

Merci.

Edited by Laurine_srd (see edit history)
Link to comment
Share on other sites

Bonjour,

merci de ta réponse!

Il faut forcément effacer les lignes? N'y a-t-il pas un moyen de les garder et juste de ne pas les afficher/charger sur la page?

N'es-ce pas un peu risqué, malgré la sauvegarde, d'effacer des données comme ceci?

Merci

Link to comment
Share on other sites

1) Dans ps_orders on ajoute une colonne nommée "active" de type INT avec pour valeur par defaut 1

2) on crée un override de AdminOrdersController.php

3) on modifie la function construct

public function __construct()
    {
        $this->bootstrap = true;
        $this->table = 'order';
        $this->className = 'Order';
        $this->lang = false;
        $this->addRowAction('view');
        $this->explicitSelect = true;
        $this->allow_export = true;
        $this->deleted = false;
        $this->context = Context::getContext();

        $this->_select = '
		a.id_currency,
		a.id_order AS id_pdf,
		CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) AS `customer`,
		osl.`name` AS `osname`,
		os.`color`,
                a.`active`,
		IF((SELECT so.id_order FROM `'._DB_PREFIX_.'orders` so WHERE so.id_customer = a.id_customer AND so.id_order < a.id_order LIMIT 1) > 0, 0, 1) as new,
		country_lang.name as cname,
		IF(a.valid, 1, 0) badge_success';

        $this->_join = '
		LEFT JOIN `'._DB_PREFIX_.'customer` c ON (c.`id_customer` = a.`id_customer`)
		LEFT JOIN `'._DB_PREFIX_.'address` address ON address.id_address = a.id_address_delivery
		LEFT JOIN `'._DB_PREFIX_.'country` country ON address.id_country = country.id_country
		LEFT JOIN `'._DB_PREFIX_.'country_lang` country_lang ON (country.`id_country` = country_lang.`id_country` AND country_lang.`id_lang` = '.(int)$this->context->language->id.')
		LEFT JOIN `'._DB_PREFIX_.'order_state` os ON (os.`id_order_state` = a.`current_state`)
		LEFT JOIN `'._DB_PREFIX_.'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = '.(int)$this->context->language->id.')';
        $this->_where = 'AND a.`active` = 1';
        $this->_orderBy = 'id_order';
        $this->_orderWay = 'DESC';

        $this->_use_found_rows = true;

        $statuses = OrderState::getOrderStates((int)$this->context->language->id);
        foreach ($statuses as $status) {
            $this->statuses_array[$status['id_order_state']] = $status['name'];
        }

        $this->fields_list = array(
            'id_order' => array(
                'title' => $this->l('ID'),
                'align' => 'text-center',
                'class' => 'fixed-width-xs'
            ),
            'active' => array(
                'title' => $this->l('Active')
            ),
            'reference' => array(
                'title' => $this->l('Reference')
            ),
            'new' => array(
                'title' => $this->l('New client'),
                'align' => 'text-center',
                'type' => 'bool',
                'tmpTableFilter' => true,
                'orderby' => false,
                'callback' => 'printNewCustomer'
            ),
            'customer' => array(
                'title' => $this->l('Customer'),
                'havingFilter' => true,
            ),
        );

        if (Configuration::get('PS_B2B_ENABLE')) {
            $this->fields_list = array_merge($this->fields_list, array(
                'company' => array(
                    'title' => $this->l('Company'),
                    'filter_key' => 'c!company'
                ),
            ));
        }

        $this->fields_list = array_merge($this->fields_list, array(
            'total_paid_tax_incl' => array(
                'title' => $this->l('Total'),
                'align' => 'text-right',
                'type' => 'price',
                'currency' => true,
                'callback' => 'setOrderCurrency',
                'badge_success' => true
            ),
            'payment' => array(
                'title' => $this->l('Payment')
            ),
            'osname' => array(
                'title' => $this->l('Status'),
                'type' => 'select',
                'color' => 'color',
                'list' => $this->statuses_array,
                'filter_key' => 'os!id_order_state',
                'filter_type' => 'int',
                'order_key' => 'osname'
            ),
            'date_add' => array(
                'title' => $this->l('Date'),
                'align' => 'text-right',
                'type' => 'datetime',
                'filter_key' => 'a!date_add'
            ),
            'id_pdf' => array(
                'title' => $this->l('PDF'),
                'align' => 'text-center',
                'callback' => 'printPDFIcons',
                'orderby' => false,
                'search' => false,
                'remove_onclick' => true
            )
        ));

        if (Country::isCurrentlyUsed('country', true)) {
            $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
			SELECT DISTINCT c.id_country, cl.`name`
			FROM `'._DB_PREFIX_.'orders` o
			'.Shop::addSqlAssociation('orders', 'o').'
			INNER JOIN `'._DB_PREFIX_.'address` a ON a.id_address = o.id_address_delivery
			INNER JOIN `'._DB_PREFIX_.'country` c ON a.id_country = c.id_country
			INNER JOIN `'._DB_PREFIX_.'country_lang` cl ON (c.`id_country` = cl.`id_country` AND cl.`id_lang` = '.(int)$this->context->language->id.')
			ORDER BY cl.name ASC');

            $country_array = array();
            foreach ($result as $row) {
                $country_array[$row['id_country']] = $row['name'];
            }

            $part1 = array_slice($this->fields_list, 0, 3);
            $part2 = array_slice($this->fields_list, 3);
            $part1['cname'] = array(
                'title' => $this->l('Delivery'),
                'type' => 'select',
                'list' => $country_array,
                'filter_key' => 'country!id_country',
                'filter_type' => 'int',
                'order_key' => 'cname'
            );
            $this->fields_list = array_merge($part1, $part2);
        }

        $this->shopLinkType = 'shop';
        $this->shopShareDatas = Shop::SHARE_ORDER;

        if (Tools::isSubmit('id_order')) {
            // Save context (in order to apply cart rule)
            $order = new Order((int)Tools::getValue('id_order'));
            $this->context->cart = new Cart($order->id_cart);
            $this->context->customer = new Customer($order->id_customer);
        }

        $this->bulk_actions = array(
            'updateOrderStatus' => array('text' => $this->l('Change Order Status'), 'icon' => 'icon-refresh')
        );

        parent::__construct();
    }
Link to comment
Share on other sites

Bonsoir Alexandre

 

Je bosse avec Laurine sur ce sujet.

Et merci pour ton aide :)

 

J'ai mis en place la modification, mais elle intervient au niveau de la liste de commandes du backoffice.

 

Notre souhait est de limiter la liste des commandes (et  la liste des produits achetés) dans la page "client" du backoffice (la page d'informations liées au client)

Je pense que la modification que tu as suggéré pourrait aussi être utilisée pour cela, mais je ne sais pas trop où faire cette modification.

Est-ce dans le fichier AdminCustomersController.php   ?

 

Merci

 

Patrice

Link to comment
Share on other sites

Salut

 

Merci pour vos réponses.

 

okom3pom >> On a des clients avec effectivement plusieurs centaines de commandes réparties sur plusieurs années, Chaque commande ayant souvent plusieurs articles.

Je ne vois guère l’intérêt de charger une page qui me rappelle ce que la personne a commandé il y a 7 ans... D'où mon souhait d'alléger cette page comme la charge serveur pour ne plus avoir ces infos (les 2 dernières années me suffisent amplement).

 

Eolia >> Donc non, je ne connais pas LIMIT, mes compétences en SQL sont assez limitées (justement... :D )

 

Je vais chercher de ce côté, (mais je suis preneur si vous avez quelques suggestions quand à son emploi dans le cas qui nous occupe ?)

 

 

Merci de vos réponses

Link to comment
Share on other sites

LIMIT permet de limiter le nombre de résultats récupérés en bdd

 

Par exemple pour la fonction

    public function getBoughtProducts()
    {
        return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT * FROM `'._DB_PREFIX_.'orders` o
		LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
		WHERE o.valid = 1 AND o.`id_customer` = '.(int)$this->id);
    }

Vous pouvez la remplacer par 

    public function getBoughtProducts()
    {
        return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT * FROM `'._DB_PREFIX_.'orders` o
		LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
		WHERE o.valid = 1 AND o.`id_customer` = '.(int)$this->id.'
        ORDER BY o.date_add DESC LIMIT 50');
    }

Qui vous renverra les 50 derniers produits achetés par ce client

 

L'idéal étant de faire un override de ces 2 fonctions, de remplacer 50 par un paramètre configurable dans Préférences -> Clients^^

Edited by Eolia (see edit history)
Link to comment
Share on other sites

Salut Eolia,

 

Merci pour ces informations.

Je vais regarder cela le plus vite possible.

 

Faire un override, je crois que j'ai déjà fait ça  (et avec cette réponse vous voyez mon niveau... :blink: )

Mais par contre, le paramètre configurable alors là...  :unsure:  :unsure: 

 

Bon j'avance sur ça et je vous dis comment je m'en suis sorti ...   ou pas :D

 

Merci !

Link to comment
Share on other sites

Bonjour,

On planche toujours sur le sujet.

J'ai juste un petit soucis: quand je suis sur la page d'un client, dans le back office, il y a plusieurs blocs : par exemple, les commandes, les paniers, les produits achetés etc. J'ai trouvé le fichier AdminCustomerController.php pour modifier et faire l'override de la requête des produits achetés, en revanche, pas moyen de mettre la main sur celui des paniers... :blink: Comment se nomme-t-il? 

Quant à la solution d'Eolia, le LIMIT fonctionne bien, Il affiche bien que les derniers produits, en revanche il ne réduit pas le temps d'affichage.

Merci ;)

Link to comment
Share on other sites

  • 1 year later...
  • 1 year later...
On 4/26/2017 at 11:53 AM, Eolia said:

LIMIT permet de limiter le nombre de résultats récupérés en bdd

 

Par exemple pour la fonction


    public function getBoughtProducts()
    {
        return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT * FROM `'._DB_PREFIX_.'orders` o
		LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
		WHERE o.valid = 1 AND o.`id_customer` = '.(int)$this->id);
    }

Vous pouvez la remplacer par 


    public function getBoughtProducts()
    {
        return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT * FROM `'._DB_PREFIX_.'orders` o
		LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
		WHERE o.valid = 1 AND o.`id_customer` = '.(int)$this->id.'
        ORDER BY o.date_add DESC LIMIT 50);
    }

Qui vous renverra les 50 derniers produits achetés par ce client

 

L'idéal étant de faire un override de ces 2 fonctions, de remplacer 50 par un paramètre configurable dans Préférences -> Clients^^

Bonjour,

Je reviens sur ce sujet, ma question est peut-être idiote, mais ces modifications doivent bien être faites dans customer.php ?
Chaque fois que j'apporte cette modification, directement dans le customer.php ou en override, j'obtiens directement une erreur 500 en front et en back.

Merci pour votre aide.

Link to comment
Share on other sites

J'ai recommencé en faisant bien un copié collé du bloc indiqué et j'obtiens cette fois le message
 

Parse error: syntax error, unexpected 'PS_CUSTOMER_GROUP' (T_STRING) in "..."/classes/Customer.php on line 710

Si on regarde le code dans l'éditeur, on se rend compte que la fonction ajoutée ne semble pas se fermer.
Voir la capture.

customer php bis.jpg

Link to comment
Share on other sites

effectivement l'éditeur Presta a bouffé une apostrophe.

Le bon code est :

    public function getBoughtProducts()
    {
        return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT * FROM `'._DB_PREFIX_.'orders` o
		LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
		WHERE o.valid = 1 AND o.`id_customer` = '.(int)$this->id.'
        ORDER BY o.date_add DESC LIMIT 50');
    }

 

  • Thanks 1
Link to comment
Share on other sites

Il faut savoir que c'est surtout la fonction Cart::getCustomerCarts($customer->id) qui consome le plus de ressources et celle qui suit dans le code et essaye de trouver les produits souvent ajoutés aux paniers et jamais commandés. Pour celle-ci un return array(); suffit.

  • Like 1
Link to comment
Share on other sites

59 minutes ago, Eolia said:

effectivement l'éditeur Presta a bouffé une apostrophe.

Le bon code est :


    public function getBoughtProducts()
    {
        return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT * FROM `'._DB_PREFIX_.'orders` o
		LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
		WHERE o.valid = 1 AND o.`id_customer` = '.(int)$this->id.'
        ORDER BY o.date_add DESC LIMIT 50');
    }

 

Super, merci beaucoup.
Avec cette correction je n'ai plus d'erreur.
Par contre, comme vous le prédisiez dans votre message suivant il ne semble pas y avoir d'impact sur la vitesse de chargement de la page.

55 minutes ago, Eolia said:

Il faut savoir que c'est surtout la fonction Cart::getCustomerCarts($customer->id) qui consome le plus de ressources et celle qui suit dans le code et essaye de trouver les produits souvent ajoutés aux paniers et jamais commandés. Pour celle-ci un return array(); suffit.

Si je saisi bien, il s'agit des deux fonctions suivantes à modifier ?

    public function getLastCart($with_order = true)
    {
        $carts = Cart::getCustomerCarts((int)$this->id, $with_order);
        if (!count($carts)) {
            return false;
        }
        $cart = array_shift($carts);
        $cart = new Cart((int)$cart['id_cart']);
        return ($cart->nbProducts() === 0 ? (int)$cart->id : false);
    }

    public function getOutstanding()
    {
        $query = new DbQuery();
        $query->select('SUM(oi.total_paid_tax_incl)');
        $query->from('order_invoice', 'oi');
        $query->leftJoin('orders', 'o', 'oi.id_order = o.id_order');
        $query->groupBy('o.id_customer');
        $query->where('o.id_customer = '.(int)$this->id);
        $total_paid = (float)Db::getInstance()->getValue($query->build());

        $query = new DbQuery();
        $query->select('SUM(op.amount)');
        $query->from('order_payment', 'op');
        $query->leftJoin('order_invoice_payment', 'oip', 'op.id_order_payment = oip.id_order_payment');
        $query->leftJoin('orders', 'o', 'oip.id_order = o.id_order');
        $query->groupBy('o.id_customer');
        $query->where('o.id_customer = '.(int)$this->id);
        $total_rest = (float)Db::getInstance()->getValue($query->build());

        return $total_paid - $total_rest;
    }

Est-ce bien ceci et que modifier exactement ?

Merci beaucoup pour votre aide.

Link to comment
Share on other sites

Ben non, c'est dans la classe Cart.php, fonction getCustomerCarts();

à remplacer par:

    public static function getCustomerCarts($id_customer, $with_order = true)
    {
        return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
		SELECT *
		FROM '._DB_PREFIX_.'cart c
		WHERE c.`id_customer` = '.(int)$id_customer.'
		'.(!$with_order ? 'AND NOT EXISTS (SELECT 1 FROM '._DB_PREFIX_.'orders o WHERE o.`id_cart` = c.`id_cart`)' : '').'
		ORDER BY c.`date_add` DESC LIMIT 10');
    }

Et dans /controllers/admin/AdminCustomersController.php, remplacer 

        $interested = Db::getInstance()->executeS($sql);
        $total_interested = count($interested);
        for ($i = 0; $i < $total_interested; $i++) {
            $product = new Product($interested[$i]['id_product'], false, $this->default_form_language, $interested[$i]['id_shop']);
            if (!Validate::isLoadedObject($product)) {
                continue;
            }
            $interested[$i]['url'] = $this->context->link->getProductLink(
                $product->id,
                $product->link_rewrite,
                Category::getLinkRewrite($product->id_category_default, $this->default_form_language),
                null,
                null,
                $interested[$i]['cp_id_shop']
            );
            $interested[$i]['id'] = (int)$product->id;
            $interested[$i]['name'] = Tools::htmlentitiesUTF8($product->name);
        }

Par

        $interested = array();

 

  • Thanks 1
Link to comment
Share on other sites

Après application de ces modifications, c'est déjà bien mieux.
Lorsque je saisi une commande manuelle sur un client ayant des centaines de commandes à son actif, le nombre de commandes à charger ralentissent encore pas mal le chargement.
Comment faire en sorte de limiter aussi le nombre de commandes à charger dans ce cas de figure ?

Link to comment
Share on other sites

  • 3 years later...

Bonjour, je me permet de déterrer ce post car il m'intéresse fortement !

Nous avons le même problème sur notre site, certaines fiches clients du backoffice mettent plus de 60 secondes avant de charger c'est un vrai calvaire !!

Le problème c'est que je ne peux pas effectuer les mêmes modifications,

le fichier /controllers/admin/AdminCustomersController.php n'existe pas chez moi (je suis sur PS 1.7.8.X) 

Quelqu'un pourrait me donner un coup de main ?

J'aurais donc besoin de virer ou limiter le nombres de paniers et de produits achetés dans les fiches client du backoffice

ce serait super :) 

Merci d'avance

Link to comment
Share on other sites

  • 3 months later...
17 minutes ago, Blawdi said:

Pas en 1.7.8.2 en tout cas ?

 

Bizarre ça quand même.
Il est juste après le fichier AdminCustomerThreadsController.php

car CustomerS est au pluriel.
Vous êtes sûr ?

Mais ça ne résoud pas le soucis, car la fonction est appelée

 $products = $customer->getBoughtProducts();

mais elle est créée ailleurs.
Je poursuis mes recherches.
Si vous trouvez avant moi, je suis intéressée.

Link to comment
Share on other sites

On 10/27/2022 at 12:06 PM, Crabix said:

Bonjour, je me permet de déterrer ce post car il m'intéresse fortement !

Nous avons le même problème sur notre site, certaines fiches clients du backoffice mettent plus de 60 secondes avant de charger c'est un vrai calvaire !!

Le problème c'est que je ne peux pas effectuer les mêmes modifications,

le fichier /controllers/admin/AdminCustomersController.php n'existe pas chez moi (je suis sur PS 1.7.8.X) 

Quelqu'un pourrait me donner un coup de main ?

J'aurais donc besoin de virer ou limiter le nombres de paniers et de produits achetés dans les fiches client du backoffice

ce serait super :) 

Merci d'avance

Ce n'est pas dingo, mais vu qu'on a quasiment plus d'entre aide... voici ce que j'ai fait

dans /src/Adapter/Customer/QueryHandler/GetCustomerForViewingHandler.php a la ligne 805

j'ai commenté 

       

 //$carts = Cart::getCustomerCarts($customer->id);

et ajouté
        

$carts = array();

 

ça permet de ne plus afficher les paniers et donc un affichage quasi instantané. 

 

Link to comment
Share on other sites

On 2/10/2023 at 3:56 PM, Blawdi said:

Ce n'est pas dingo, mais vu qu'on a quasiment plus d'entre aide... voici ce que j'ai fait

dans /src/Adapter/Customer/QueryHandler/GetCustomerForViewingHandler.php a la ligne 805

j'ai commenté 

       

 //$carts = Cart::getCustomerCarts($customer->id);

et ajouté
        

$carts = array();

 

ça permet de ne plus afficher les paniers et donc un affichage quasi instantané. 

 

Merci Blawdi c'est vrai que poster une question sur ce forum équivaut à envoyer une bouteille à la mer, Merci beaucoup, personnellement j'ai fini par prendre un module hors de prix qui permet d'optimiser notre site web (il contient une option permettant de supprimer tous les paniers abandonnés) 

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...