Jump to content
Laurine_srd

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)

Share this post


Link to post
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

Share this post


Link to post
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();
    }

Share this post


Link to post
Share on other sites

de la on peut mettre active a 0 dans les commandes qu'on ne veux pas afficher seules les commandes actives égales a 1 seront prisent dans la requete avec le

$this->_where = 'AND a.`active` = 1';

PS 1.6.11

 

cdt

Edited by Alexandre Carette (see edit history)

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

et LIMIT en sql, vous ne connaissez pas ? Parce que là ca sent l'usine à gaz votre truc^^

Share this post


Link to post
Share on other sites

Bonjour,

 

Il faudrait plus de précision, déjà le nombre de commandes affichées, votre hébergement.

 

J'ai des clients avec des 100ène de commande et pas de soucis.

 

Le problème vient du nombre de produit acheté et les paniers

Il vous suffit de faire ça : 

//$products = $customer->getBoughtProducts();
$products = false;


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

Share this post


Link to post
Share on other sites

La méthode d'Eolia est pérenne que la mienne surtout si vous avez besoin d'un peu d'historique.

Share this post


Link to post
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

Share this post


Link to post
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)

Share this post


Link to post
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 !

Share this post


Link to post
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 ;)

Share this post


Link to post
Share on other sites

okom vous a donné les 2 fonctions plus haut^^

  • Like 1

Share this post


Link to post
Share on other sites

En poussant un peu le truc on arrive à quelque chose de pas mal^^

image.thumb.png.10d26c3d687f903c2562788f42257ca5.png

Avec rechargement en ajax uniquement si nécessaire ;) 

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

vous devez avoir une erreur de syntaxe.

Affichez les erreurs et donnez-nous l'erreur

  • Like 1

Share this post


Link to post
Share on other sites

Voici l'erreur annoncée :

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

Et une capture du code renseigné.
 

customer php.jpg

Share this post


Link to post
Share on other sites

Vous avez remplacé le bloc comme je l'ai dit ou vous avez uniquement ajouté la ligne en oubliant d'enlever le ); à la ligne précédente ?

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
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 ?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More