Jump to content

[Résolu] Badge couleur sur champ personnalisé BO admin commande.


Recommended Posts

Bonjour à vous, 

J'ai besoin de votre aide pour un petit sujet sur lequel je planche. L'ajout de champs personnalisé dans le BO sur la page commandes, et plus particulièrement la colorisation de ces champs.
Avant tout été simple, car il suffisait de faire un overide de AdminOrdersController
J'avais réussi à ajouter des personnalisations comme cela :

  • Si le client choisi Chronopost, alors dans la BO l'ID de commande été badgé en bleu.
  • En fonction du groupe client, la couleur change (j'ai changé le nom des groupes client pour la capture.) . 
  • J'avais aussi ajouté d'autre champs comme les frais de port, ou le total des réductions, les codes de réduction etc.

image.png.51f48545742ce0844935fce0cdc8cbd5.png   image.png.aaaea02916dab0c7f865465e52ac96b1.png


Mon problème : 

Je suis en cours de mise à jour d'un site PrestaShop en version 1.7.8.8.
Et ce code a été déplacé dans un contrôleur Symfony dans src/PrestaShopBundle/Controller/Admin/Sell/Order

Je me suis donc appliquer a utilisé les nouveau Hook pour modifier la nouvelle page commande.  sauf que je ne parviens pas a ajouté les
couleurs a certain de mes nouveau champs. ni a modifier le champs ID. pour le badgé en bleu. 

Voila un petit exemple de ce que j'avais avant (en version 1.7.6.5) 
Pour la requête (désolé pour la qualité mais si je fait un code Snippet) je me fait bloquer part une sécurité) 

image.thumb.png.f310724baec5e04b0d48e17846f52e97.png

Et la modification des colonnes et champs 
 

$this->fields_list = array(
            'id_order' => array(
                'title' => $this->trans('ID', array(), 'Admin.Global'),
                'align' => 'text-center',
                'class' => 'fixed-width-xs',
                'color' => 'color3',
            ),
...

 ...          
         /*AJOUT DU N° DE COMMANDE */
            'invoice_number' => array(
                'title' => $this->l('N° Facture'),
                'havingFilter' => true,
            ),
            /*AJOUT CODE PROMO*/
            'lecode' => array(
                'title' => $this->l('Code Reduction'),
                'havingFilter' => true,
            ),
            'total_discounts' => array(
                'title' => $this->l('Total Reduction'),
            ),
            /*AJOUT GROUPE*/
            'Groupe' => array(
                'title' => $this->l('Groupe'),
                'type' => 'select',
                'color' => 'color2',
                'list' => $this->groupes_array,
                'filter_key' => 'c!id_default_group',
                'filter_type' => 'int',
                'order_key' => 'id_default_group',
            ),
...


Voilà le code que j'ai fait, je rajoute les champs un par un, pour que ce soit plus facile pour moi de voir où j'en suis et si je ne me trompe pas dans la requête (si j'ajoute tout d'un coup et qu'il y a un problème, il sera plus compliqué de savoir ce qui ne vas pas). 

Pour le moment, j'ai réussi à ajouter avec succès Code Réduction et ai moitié Group client.

   

 /**
     * Hook allows to modify Order grid definition since 1.7.7.0
     *
     * @param array $params
     */
    public function hookActionOrderGridDefinitionModifier(array $params)
    {
        if (empty($params['definition'])) {
            return;
        }

        $definitionCode = $params['definition'];
            $column = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('lecode');
            $column->setName($this->l('Code Reduction'));
            $column->setOptions([
                'field' => 'lecode',
            ]);
        $definitionCode
            ->getColumns()
            ->addAfter(
                'payment',
                $column
            );
        $definitionCode->getFilters()->add(
            (new PrestaShop\PrestaShop\Core\Grid\Filter\Filter('lecode', Symfony\Component\Form\Extension\Core\Type\TextType::class))
                ->setAssociatedColumn('lecode')
                ->setTypeOptions([
                    'required' => false,
                    'translation_domain' => false,
                ])
        );

        $groupes = Group::getGroups($this->context->language->id);
        foreach ($groupes as $groupe) {
            $this->groupes_array[$groupe['name']] = $groupe['id_group'];
        }

        $definitionGroupe = $params['definition'];
        $column = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('Groupe');
        $column->setName($this->l('Code Reduction'));
        $column->setOptions([
            'field' => 'Groupe',
        ]);
        $definitionGroupe
            ->getColumns()
            ->addAfter(
                'lecode',
                $column
            );
        $definitionGroupe->getFilters()->add(
            (new PrestaShop\PrestaShop\Core\Grid\Filter\Filter('Groupe', Symfony\Component\Form\Extension\Core\Type\ChoiceType::class))
                ->setAssociatedColumn('Groupe')
                ->setTypeOptions([
                    'required' => false,
                    'choices' => $this->groupes_array,
                    'translation_domain' => false,
                ])
        );

    }

    /**
     * Hook allows to modify Order query builder and add custom sql statements since 1.7.7.0
     *
     * @param array $params
     */
    public function hookActionOrderGridQueryBuilderModifier(array $params)
    {
        if (empty($params['search_query_builder']) || empty($params['search_criteria'])) {
            return;
        }
        $searchQueryBuilder = $params['search_query_builder'];
        $searchCriteria = $params['search_criteria'];


        /*---  CODE REDUCTION  ---*/
        $searchQueryBuilder->addSelect(
            'GROUP_CONCAT(cr.`code` SEPARATOR \'\n\') as `lecode`'
        );
        $searchQueryBuilder->leftJoin(
            'o',
            '`' . _DB_PREFIX_ . 'order_cart_rule`',
            'ocr',
            'ocr.`id_order` = o.`id_order`'
        );
        $searchQueryBuilder->leftJoin(
            'ocr',
            '`' . _DB_PREFIX_ . 'cart_rule`',
            'cr',
            'cr.`id_cart_rule` = ocr.`id_cart_rule`'
        );

        /*---  GROUPE  ---*/
        $searchQueryBuilder->addSelect(
            'GL.`name` AS Groupe, 
         CASE
           WHEN cu.`id_default_group` IN (1,2,3,10) THEN \'#A5D878\'
           WHEN cu.`id_default_group` IN (8,16,17,18,20,22,23,28,29,30,31,32,33,37) THEN \'#78D8CC\'
           WHEN cu.`id_default_group` IN (34,36) THEN \'#D8A753\'
           WHEN cu.`id_default_group` IN (7) THEN \'#788ED8\'
           WHEN cu.`id_default_group` IN (15) THEN \'#8578D8\'
           WHEN cu.`id_default_group` IN (11,19,21,24) THEN \'#C878D8\'
         END AS color2'
        );
        $searchQueryBuilder->leftJoin(
            'c',
            '`' . _DB_PREFIX_ . 'group_lang`',
            'GL',
            'GL.`id_group` = cu.`id_default_group` AND GL.`id_lang` = '.(int)$this->context->language->id
        );

        if ('id_cart_rule' === $searchCriteria->getOrderBy()) {
            $searchQueryBuilder->orderBy('cr.`id_cart_rule`', $searchCriteria->getOrderWay());
        }
        if ('Groupe' === $searchCriteria->getOrderBy()) {
            $searchQueryBuilder->orderBy('GL.`name`', $searchCriteria->getOrderWay());
        }

        foreach ($searchCriteria->getFilters() as $filterName => $filterValue) {
            if ('lecode' === $filterName) {
                $searchQueryBuilder->andWhere('cr.`code` = :id_cart_rule');
                $searchQueryBuilder->setParameter('id_cart_rule', $filterValue);
            }
            if ('Groupe' === $filterName) {
                $searchQueryBuilder->andWhere('cu.`id_default_group` = :Groupe');
                $searchQueryBuilder->setParameter('Groupe', $filterValue);
            }
        }
        $searchQueryBuilder->groupBy('id_order');
    }


Voilà donc maintenant, ce que je cherche à faire et de rappliquer les couleurs sur mes champs de groupe client 
Ce qui me donne ceci. 

image.png

J'ai bien mes codes (qui se concatène bien s'il y en a plusieurs) et mes groupes clients. Mais je n'ai plus de couleur pour les groupes clients et je ne parviens pas à les remettre. 

 

Si vous pouviez m'aider sur ce sujet ? 

 

Merci par avance pour votre aide !

Edited by croual
ajout code (see edit history)
Link to comment
Share on other sites

Bien le le bonjour à vous,
J'ai résolu mon problème ! Et vue que je suis sympa, je vais partager ma solution.

Si jamais une autre personne dans ce vaste monde cherche une solution similaire à la mienne, voilà comment j'ai fait.  

Mise en contexte : j'ai besoin d'ajouter au tableau des informations : le groupe client, le total des réductions, le total HT de la commande, le ou les codes de réductions utilisés, les numéraux de facture (avec préfixe) et enfin le total des frais de port. 

Pour qu'il soit plus facile de repérer les groupes, je les colorise différemment. 
Pour que les commande Chronopost soit plus facilement repérable, je les colore aussi. 
Voilà le rendu final :  (Si Chronopost, la référence est colorées en bleu. Et en fonction du groupe client, la couleur change. Vert pour les clients) 

image.thumb.png.412e7498029e6760824e35865bb2197c.png

J'ai utilisé un module pour modifier le tableau des commandes. 
Vous aurez donc besoin de ces deux Hook : 

  • actionOrderGridDefinitionModifier
  • actionOrderGridQueryBuilderModifier
  • ActionAdminControllerSetMedia


Dans un 1er temps j'ai ajouté les champs dans hookActionOrderGridDefinitionModifier
 

public function hookActionOrderGridDefinitionModifier(array $params)
    {
        if (empty($params['definition'])) {
            return;
        }

        $definitionRef = $params['definition'];
        $column = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('invoice_number');
        $column->setName($this->l('N° Facture'));
        $column->setOptions([
            'field' => 'invoice_number',
        ]);
        $definitionRef
            ->getColumns()
            ->addAfter(
                'payment',
                $column
            );
        $definitionRef->getFilters()->add(
            (new PrestaShop\PrestaShop\Core\Grid\Filter\Filter('invoice_number', Symfony\Component\Form\Extension\Core\Type\TextType::class))
                ->setAssociatedColumn('invoice_number')
                ->setTypeOptions([
                    'required' => false,
                    'translation_domain' => false,
                ])
        );

        $definitionCode = $params['definition'];
            $column = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('lecode');
            $column->setName($this->l('Code Reduction'));
            $column->setOptions([
                'field' => 'lecode',
            ]);
        $definitionCode
            ->getColumns()
            ->addAfter(
                'payment',
                $column
            );
        $definitionCode->getFilters()->add(
            (new PrestaShop\PrestaShop\Core\Grid\Filter\Filter('lecode', Symfony\Component\Form\Extension\Core\Type\TextType::class))
                ->setAssociatedColumn('lecode')
                ->setTypeOptions([
                    'required' => false,
                    'translation_domain' => false,
                ])
        );

        $groupes = Group::getGroups($this->context->language->id);
        foreach ($groupes as $groupe) {
            $this->groupes_array[$groupe['name']] = $groupe['id_group'];
        }

        $definitionGroupe = $params['definition'];
        $column = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('Groupe');
        $column->setName($this->l('Groupe'));
        $column->setOptions([
            'field' => 'Groupe',
        ]);
        $definitionGroupe
            ->getColumns()
            ->addAfter(
                'payment',
                $column
            );
        $definitionGroupe->getFilters()->add(
            (new PrestaShop\PrestaShop\Core\Grid\Filter\Filter('Groupe', Symfony\Component\Form\Extension\Core\Type\ChoiceType::class))
                ->setAssociatedColumn('Groupe')
                ->setTypeOptions([
                    'required' => false,
                    'choices' => $this->groupes_array,
                    'translation_domain' => false,
                ])
        );
        $columnColor = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('color2');
        $columnColor->setName($this->l('Color2'));
        $columnColor->setOptions([
            'field' => 'color2',
        ]);
        $definitionGroupe->getColumns()->addAfter('Groupe', $columnColor);


        $definitionReduction = $params['definition'];
        $column = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('total_discounts');
        $column->setName($this->l('Total Reduction'));
        $column->setOptions([
            'field' => 'total_discounts',
        ]);
        $definitionReduction
            ->getColumns()
            ->addAfter(
                'payment',
                $column
            );
        $definitionReduction->getFilters()->add(
            (new PrestaShop\PrestaShop\Core\Grid\Filter\Filter('total_discounts', Symfony\Component\Form\Extension\Core\Type\TextType::class))
                ->setAssociatedColumn('total_discounts')
                ->setTypeOptions([
                    'required' => false,
                    'translation_domain' => false,
                ])
        );

        $definitionHT = $params['definition'];
        $column = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('total_paid_tax_excl');
        $column->setName($this->l('Total HT'));
        $column->setOptions([
            'field' => 'total_paid_tax_excl',
        ]);
        $definitionHT
            ->getColumns()
            ->addAfter(
                'payment',
                $column
            );
        $definitionHT->getFilters()->add(
            (new PrestaShop\PrestaShop\Core\Grid\Filter\Filter('total_paid_tax_excl', Symfony\Component\Form\Extension\Core\Type\TextType::class))
                ->setAssociatedColumn('total_paid_tax_excl')
                ->setTypeOptions([
                    'required' => false,
                    'translation_domain' => false,
                ])
        );

        $definitionShipping = $params['definition'];
        $column = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('total_shipping');
        $column->setName($this->l('FDP'));
        $column->setOptions([
            'field' => 'total_shipping',
        ]);
        $definitionShipping
            ->getColumns()
            ->addAfter(
                'payment',
                $column
            );
        $definitionShipping->getFilters()->add(
            (new PrestaShop\PrestaShop\Core\Grid\Filter\Filter('total_shipping', Symfony\Component\Form\Extension\Core\Type\TextType::class))
                ->setAssociatedColumn('total_shipping')
                ->setTypeOptions([
                    'required' => false,
                    'translation_domain' => false,
                ])
        );
        $definitionColor2 = $params['definition'];
        $columnColor2 = new PrestaShop\PrestaShop\Core\Grid\Column\Type\DataColumn('color3');
        $columnColor2->setName($this->l('Color3'));
        $columnColor2->setOptions([
            'field' => 'color3',
        ]);
        $definitionColor2->getColumns()->addAfter('id_order', $columnColor2);

    }

Noté, qu'il y a deux champs supplémentaires : color2 et color3. 
color étant déjà utilisé dans la requête de base (en-tout-cas en 1.7.6 donc j'ai déduit que ce devrais aussi être le cas ici en 1.7.8)

color2 : va me servir pour donner une couleur au client.
color3 : va me servir pour donner une couleur au client qui a choisi Chronopost pour la livraison. 

Par la suite, il va falloir modifier la requête pour ajouté nos nouveaux champs. Pour cela, il faut utiliser le Hook hookActionOrderGridQueryBuilderModifier

/*CODE POUR LES FACTURE A INSERE A LA PLACE DES COMMENTAIRE 
*/

Quote

/*---  FACTURE  ---*/
EDIT LE CODE ET BLOQUER DONC VOILÀ UNE CAPTURE ÉCRAN
image.thumb.png.58115e2940c3b7fc0cf3ef774c8f3a52.png
/* --- CODE REDUCTION  ---*/

 

public function hookActionOrderGridQueryBuilderModifier(array $params)
    {
        if (empty($params['search_query_builder']) || empty($params['search_criteria'])) {
            return;
        }
        $searchQueryBuilder = $params['search_query_builder'];
        $searchCriteria = $params['search_criteria'];
        $id_lang = Context::getContext()->language->id;
        $id_shop = Context::getContext()->shop->id;

        /*---  FACTURE  ---*/
 /************** VOIRE CODE PLUS HAUTE DANS LE POST **************/
/*    Le code fait planté la balise code de prestashop...       */

        /*---  CODE REDUCTION  ---*/
        $searchQueryBuilder->addSelect(
            'GROUP_CONCAT(cr.`code` SEPARATOR \'\n\') as `lecode`, cu.id_default_group'
        );
        $searchQueryBuilder->leftJoin(
            'o',
            '`' . _DB_PREFIX_ . 'order_cart_rule`',
            'ocr',
            'ocr.`id_order` = o.`id_order`'
        );
        $searchQueryBuilder->leftJoin(
            'ocr',
            '`' . _DB_PREFIX_ . 'cart_rule`',
            'cr',
            'cr.`id_cart_rule` = ocr.`id_cart_rule`'
        );

        /*---  GROUPE  ---*/
        $searchQueryBuilder->addSelect(
            'GL.`name` AS Groupe, 
         CASE
           WHEN cu.`id_default_group` IN (1,2,3,10) THEN \'#A5D878\'
           WHEN cu.`id_default_group` IN (8,16,17,18,20,22,23,28,29,30,31,32,33,37) THEN \'#78D8CC\'
           WHEN cu.`id_default_group` IN (34,36) THEN \'#D8A753\'
           WHEN cu.`id_default_group` IN (7) THEN \'#788ED8\'
           WHEN cu.`id_default_group` IN (15) THEN \'#8578D8\'
           WHEN cu.`id_default_group` IN (11,19,21,24) THEN \'#C878D8\'
         END AS color2'
        );
        /*---  ChronoPost  ---*/
        $searchQueryBuilder->addSelect(
            ' CASE 
            WHEN (SELECT car.id_reference 
                FROM `' . _DB_PREFIX_ . 'carrier` car
                WHERE car.id_carrier = o.id_carrier AND car.active = 1
                ) = 993 THEN \'#13C2F1\'
            END AS color3'
        );
        $searchQueryBuilder->leftJoin(
            'c',
            '`' . _DB_PREFIX_ . 'group_lang`',
            'GL',
            'GL.`id_group` = cu.`id_default_group` AND GL.`id_lang` = '.(int)$this->context->language->id
        );

        /*---  Total Reduction  ---*/
        $searchQueryBuilder->addSelect(
            'ROUND(o.`total_discounts`, 2) AS `total_discounts`'
        );
        /*---  Total HT  ---*/
        $searchQueryBuilder->addSelect(
            'ROUND(o.`total_paid_tax_excl`, 2) AS `total_paid_tax_excl`'
        );
        /*---  FDP  ---*/
        $searchQueryBuilder->addSelect(
            'ROUND(o.`total_shipping`, 2) AS `total_shipping`'
        );

        if ('id_cart_rule' === $searchCriteria->getOrderBy()) {
            $searchQueryBuilder->orderBy('cr.`id_cart_rule`', $searchCriteria->getOrderWay());
        }
        if ('Groupe' === $searchCriteria->getOrderBy()) {
            $searchQueryBuilder->orderBy('GL.`name`', $searchCriteria->getOrderWay());
        }
        if ('invoice_number' === $searchCriteria->getOrderBy()) {
            $searchQueryBuilder->orderBy('o.`invoice_number`', $searchCriteria->getOrderWay());
        }
        if ('Total Reduction' === $searchCriteria->getOrderBy()) {
            $searchQueryBuilder->orderBy('o.`total_discounts`', $searchCriteria->getOrderWay());
        }
        if ('Total HT' === $searchCriteria->getOrderBy()) {
            $searchQueryBuilder->orderBy('o.`total_paid_tax_excl`', $searchCriteria->getOrderWay());
        }
        if ('FDP' === $searchCriteria->getOrderBy()) {
            $searchQueryBuilder->orderBy('o.`total_shipping`', $searchCriteria->getOrderWay());
        }

        foreach ($searchCriteria->getFilters() as $filterName => $filterValue) {
            if ('lecode' === $filterName) {
                $searchQueryBuilder->andWhere('cr.`code` = :id_cart_rule');
                $searchQueryBuilder->setParameter('id_cart_rule', $filterValue);
            }
            if ('Groupe' === $filterName) {
                $searchQueryBuilder->andWhere('cu.`id_default_group` = :Groupe');
                $searchQueryBuilder->setParameter('Groupe', $filterValue);
            }
            if ('N° Facture' === $filterName) {
                $searchQueryBuilder->andWhere('o.`invoice_number` = :N° Facture');
                $searchQueryBuilder->setParameter('N° Facture', $filterValue);
            }
            if ('Total Reduction' === $filterName) {
                $searchQueryBuilder->andWhere('o.`total_discounts` = :Total Reduction');
                $searchQueryBuilder->setParameter('Total Reduction', $filterValue);
            }
            if ('Total HT' === $filterName) {
                $searchQueryBuilder->andWhere('o.`total_paid_tax_excl` = :Total HT');
                $searchQueryBuilder->setParameter('Total HT', $filterValue);
            }
            if ('FDP' === $filterName) {
                $searchQueryBuilder->andWhere('o.`total_shipping` = :FDP');
                $searchQueryBuilder->setParameter('FDP', $filterValue);
            }
        }
        $searchQueryBuilder->groupBy('id_order');
    }

 

Par la suite, il faudra ajouter du JS et du CSS ce qui est permis avec le hook ActionAdminControllerSetMedia

public function hookActionAdminControllerSetMedia() {
    $this->context->controller->addCSS($this->_path . 'views/css/admin.css');
    $this->context->controller->addJS($this->_path . 'views/js/admin.js');
}

Dans le CSS : il faut cacher les colonnes que nous ne voulons pas afficher. (dans mon cas les colonnes des couleurs)

/*Nom colonne*/
#order_grid_table > thead > tr.column-headers > th:nth-child(14),
#order_grid_table > thead > tr.column-headers > th:nth-child(3),
/*champ de recherche*/
#order_grid_table > thead > tr.column-filters > td:nth-child(13),
#order_grid_table > thead > tr.column-filters > td:nth-child(3),
/*ligne de résultats*/
.column-color2, .column-color3 {
  display: none;
}

 Et dans le JS nous allons modifier les cellules pour ajouté un span et un background (il est largement possible d'optimisé ce JS) 

document.addEventListener('DOMContentLoaded', function () {
  const groupeCells = document.querySelectorAll('td.column-Groupe');
  groupeCells.forEach(function (cell) {
    const colorCell = cell.nextElementSibling;
    if (colorCell && colorCell.classList.contains('column-color2')) {
      const color = colorCell.textContent.trim();
      const txt = cell.textContent.trim();
      if (color) {
        // Créer les nouveaux éléments HTML
        const div = document.createElement('div');
        div.classList.add('text-left');
        const span = document.createElement('span');
        span.classList.add('badge', 'rounded');
        span.style.backgroundColor = color;
        span.textContent = txt;
        // Insérer les nouveaux éléments dans la cellule
        div.appendChild(span);
        cell.innerHTML = '';
        cell.appendChild(div);
      }
    }
  });
});

// Code pour les cellules avec la classe "column-color3"
document.addEventListener('DOMContentLoaded', function () {
  const groupeCells = document.querySelectorAll('td.column-reference');
  groupeCells.forEach(function (cell) {
    const colorCell = cell.previousElementSibling;
    if (colorCell && colorCell.classList.contains('column-color3')) {
      const color = colorCell.textContent.trim();
      const txt = cell.textContent.trim();
      if (color) {
        // Créer les nouveaux éléments HTML
        const div = document.createElement('div');
        div.classList.add('text-left');
        const span = document.createElement('span');
        span.classList.add('badge', 'rounded');
        span.style.backgroundColor = color;
        span.textContent = txt;
        // Insérer les nouveaux éléments dans la cellule
        div.appendChild(span);
        cell.innerHTML = '';
        cell.appendChild(div);
      }
    }
  });
});


Voilà, si vous avez bien suivi ce « tutoriel », vous devrez avoir des nouveaux champs dans le tableau des commandes, et aussi une couleur pour les différents groupes.

ATTENTION pour le transporteur, il faut que vous vérifiiez l'ID du transporteur pour lequel vous voulez voir un badge sur la référence de la commande (il est aussi possible d'avoir plusieurs couleurs pour plusieurs transporteurs.) 

j'espère que cela pourras vous aidé. Vous pouvez adapté ce code a vos besoins spécifique. fait toute te fois attention avec le CSS de bien sélectionné les bon élément, de même avec le JS.

P.S désolé pour la capture d'écrans du code, mais impossible de le donné sans être bloqué...
image.thumb.png.0843bca240c673338feb31778a049636.png

Link to comment
Share on other sites

  • croual changed the title to [Résolu] Badge couleur sur champ personnalisé BO admin commande.

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