Prestashop : Restreindre un transporteur par code postal

Ce tutoriel est compatible avec les versions de Prestashop suivantes :
1.6 1.7 +

On pourrait également compléter le titre également par : « Ville / Nom … « 

C’est une demande qui revient assez régulièrement et qui est d’autant plus d’actualité avec le confinement actuel.
Comment restreindre un transporteur à un certain code postal ?

Ceci permets par exemple de créer un transporteur de clic and collect délimité à certains codes postaux.

C’est très facile à faire dans Prestashop, mais cela nécessite la création ou l’achat d’un module.

Nous allons voir comment procéder techniquement pour faire cela.
Ce tutoriel est valide à la fois pour les versions 1.6.x et 1.7.x de prestashop

Principe de fonctionnement général

Dans Prestashop les activations ou prix des transporteurs sont définis par zones géographiques :
Celles-ci sont visibles dans l’administration via « International / Zones Géographique »

Zones de livraisons

Il est ensuite possible de voir la corrélation entre les 2 lorsque nous allons éditer un transporteur.
Via « Livraison / Transporteur » , éditer un transporteur et dans l’onglet « Destination d’expéditions et coûts »
Par exemple le transporteur de la capture ci-dessous est actif uniquement pour les zones « Europe » et « Amérique du Nord »

Zones de livraison sur un transporteur

Comme le nom des zones est très explicite on peut aisément comprendre que les clients habitant en France feront automatiquement partie de la zone Europe , et c’est bien le cas dans la configuration de prestashop

 

La France est bien en zone Europe

Cependant il existe une possibilité disponible uniquement via le code qui est d’assigner automatiquement une zone à une adresse en fonction de ses paramètres.
Cette fonctionnalité est gérée via le hook actionGetIDZoneByAddressID

Mise en œuvre concrète

Maintenant que le fonctionnement global est connu c’est parti pour un exemple concret d’implémentation.
L’objectif va être le suivant :
Créer un nouveau transporteur « Clic and collect » et le rendre disponible uniquement pour les clients qui habitent dans dans le bas-rhin ( donc un code postal qui commence par 67 )

Pour commencer il faut donc créer :
– une nouvelle zone géographique « Click and Collect » en allant dans le menu « Internationnal / Zones géographique » et récupérer son identifiant technique qu’on va réutiliser plus tard
– créer un nouveau transporteur « Click and collect » qui est uniquement actif sur la zone « click and collect »

C’est parti ensuite pour la création d’un module qui va gérer le rattachement de la zone.
Nous allons l’appeler hh_clicandcollectdelivery

Pour ce module nous allons nous concentrer sur l’essentiel uniquement, toute la logique sera codée en dur pour expliquer le principe.
Le point  essentiel est l’implémentation du hook actionGetIDZoneByAddressID que je détaille ici

     /**
     * Récupération de l'identifiant de la zone
     * @see classes/Address.php:282
     * @param array $params
     * @return mixed
     */
    public function hookActionGetIDZoneByAddressID($params)
    {
	//Chargement de l'objet adresse à partir de son identifiant
	$address = new Address($params['id_address']);
 
        //Identifiant de la zone géographique clic and collect
        $id_zone = 9;
 
        //Dans mon cas je veux que la zone soit renvoyée uniquement pour les codes postaux du type
        // 67xxx (bas-rhin )    
	if (preg_match('#^67[0-9]{3}$#', $address->postcode)) {
			return $id_zone; //L'important est de retourner la zone ici
	}
 
	//Par contre ici vous avez accès à l'ensemble des champs de l'adresse
	//Du coup vous pouvez conditionner la zone à n'importe quel champ
	//Par exemple si la ville (city = 'Paris', le nom  = 'Hervé' ) ect ...
 
    }

Si on test en tant que client on peut voir que c’est bien fonctionnel :
Code postal qui commence par 67000
(Note : Comme vous le voyez les autres transporteurs ne sont pas disponibles , il faut penser à les activer également pour cette nouvelle zone )

Code postal qui commence par autre chose , seuls les autres transporteurs sont affichés.

Module basique

Voici donc le code le plus basique du module qui permets de gérer ça.

    class Hh_clicandcollectdelivery extends Module
{
 
    public function __construct()
    {
        $this->name = 'hh_clicandcollectdelivery';
        $this->tab = 'others';
        $this->version = '0.1.0';
        $this->author = 'hhennes';
        $this->bootstrap = true;
        parent::__construct();
 
        $this->displayName = $this->l('Hh Clic and collect delivery');
        $this->description = $this->l('Allow clic and collect to certain postcode');
    }
 
    /**
     * Installation du module
     * @return bool
     */
    public function install()
    {
        if (
            !parent::install()
            || !$this->registerHook('actionGetIDZoneByAddressID')
        ) {
            return false;
        }
 
        return true;
    } 
 
    /**
     * Récupération de l'identifiant de la zone
     * @see classes/Address.php:282
     * @param array $params
     * @return mixed
     */
    public function hookActionGetIDZoneByAddressID($params)
    {
	//Chargement de l'objet adresse à partir de son identifiant
	$address = new Address($params['id_address']);
 
        //Identifiant de la zone géographique clic and collect
        $id_zone = 9;
 
        //Dans mon cas je veux que la zone soit renvoyée uniquement pour les codes postaux du type
        // 67xxx (bas-rhin )    
	if (preg_match('#^67[0-9]{3}$#', $address->postcode)) {
			return $id_zone; //L'important est de retourner la zone ici
	}
 
	//Par contre ici vous avez accès à l'ensemble des champs de l'adresse
	//Du coup vous pouvez conditionner la zone à n'importe quel champ
	//Par exemple si la ville (city = 'Paris', le nom  = 'Hervé' ) ect ...
 
    }
}

Module plus complet

C’est fonctionnel mais j’en conviens ce n’est pas vraiment adapté à une utilisation directement en production.
Car un peu trop manuel, vous pouvez donc télécharger ci-dessous un module un peu plus complet qui va ajouter les fonctionnalités suivantes :

  • Création automatique de la nouvelle zone lors de l’installation du module
  • Configuration de la plage de code postal directement depuis l’administration ( via une expression régulière )

Télécharger le module complet ( et gratuit ) sur la boutique

Le but de ce module reste très basique, pour des besoins plus complet allez voir sur addons il existe pleins de modules qui gèrent très bien ce sujet, dans le cas ou il est nécessaire d’avoir plus de règles !

17 réflexions sur “Prestashop : Restreindre un transporteur par code postal”

    1. Bonjour Cédric,

      Oui c’est possible mais pas de manière très intuitive car la condition est réalisé via une expression régulière 🙂
      Vous pouvez les tester sur ce site https://regex101.com/ .
      Par exemple pour autoriser les codes postaux qui commencent par 67 ou 68 l’expression serait sous cette forme ^6[7-8][0-9]{3}$

      Cordialement,
      Hervé

      1. Bonjour merci pour la réponse, j’ai essayé de l’adapter à mon cas mais je n’y suis pas parvenu, je voudrais autoriser spécifiquement les codes postaux 33400 33170 et 33600, est-ce possible ? Merci encore pour ce super module gratuit 🙂

    1. Bonjour Felipe,

      La configuration du module semble bonne.
      Après la configuration des transporteur est l’élément principal.
      Il ne faut activer les transporteurs que pour cette zone, sinon effectivement ils seront affichés partout.

      Cordialement,
      Hervé

  1. Bonjour,

    Comment faire pour rentrer 2 codes postaux différents qui ne commencent pas par le même chiffre ?

    Je souhaite rentrer 91,92,93,94,95 donc je rentre ^9 ça fonctionne très bien, mais comment rajouter 75 en plus ?

    Merci.

      1. Merci beaucoup Hervé ça fonctionne nickel !

        Encore une question, les clients avec un code postal 91,92,93,94,95 et 75 peuvent voir le transporteur spécifique pour leur zone, mais ils ne peuvent plus voir les autres, comment faire pour qu’il puisse voir ce transporteur spécifique pour l’Ile de France, mais aussi les autres transporteurs de base pour qu’ils puissent faire un choix entre tous ?

        Merci d’avance !

        1. Bonjour,

          Il faut penser également à activer les autres transporteurs et leur définir les mêmes tarifs sur la nouvelle zone de livraison.
          Si rien n’est défini ils ne seront effectivement pas disponibles.

          Cordialement,
          Hervé

  2. Bonjour et surtout merci pour ce code très précieux.
    En effet j’ai un client qui ne veut livrer que dans certaines villes et certains codes postaux.
    Car vous le savez, certaines villes ont le même code postale ce qui complique bien la chose 😉
    Deux petites questions, (j’ai certainement pas vu) où est ce qu’on doit saisir le code que tu as mentionné plus haut ?
    Et ma deuxième question, si je prends l’exemple suivant
    le code postal : 51500 correspond aux villes suivantes : Villers Allerand, Taissy, Sillery, Rilly la montagne, Mailly en champagne
    Si je veux ne prendre en compte que le CP : 51500 et les villes : Taissy et Sillery quel serait le code ?
    C’est histoire de me mettre le pied à l’étrier après je pourrai me débrouiller 🙂

    Merci d’avance

    1. Bonjour Xavier,

      Téléchargez ou créer le module et dans la fonction hookActionGetIDZoneByAddressID il vous suffira ensuite de vérifier également la ville
      Via un code du type

      //Dans mon cas je veux que la zone soit renvoyée uniquement pour les codes postaux du type
      // 67xxx (bas-rhin )
      if (preg_match('#^67[0-9]{3}$#', $address->postcode)) {
      //Rajout de conditions supplémentaires si le code postal matche
      if ( strtolower($address->city == 'ma ville a verif') || strtolower($address->city == 'autre ville'){
      return $id_zone; //L'important est de retourner la zone ici
      }
      }

      Cordialement,
      Hervé

        1. Hmmm désolé je dois être bête mais je ne vois pas dans quel fichier je dois mettre ce code (code du module basique avec votre modif)…
          J’avais l’habitude de programmer en PHP entre autre par le passé mais j’avoue que Prestashop est un grand mystère avec d’innombrables fichiers partout :/

          Pourriez-vous m’indiquer quel fichier je dois modifier ?
          J’aurais bien installé votre module, mais si j’ai bien compris, il ne prends pas en compte les villes (comme dans mon besoin très spécifique) snif

          Merci d’avance 🙂

          1. Bonjour,

            Désolé mais je peux difficilement être plus spécifique,si vous téléchargez le module éditez le fichier hh_clicandcollectdelivery.php
            Et faites la modification demandée dedans.
            Il n’y a rien de plus à faire 😉

            Cordialement,
            Hervé

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.