Jump to content

Multi Zone Country


Dariush

Recommended Posts

Hi 

I have a problem,

The problem is a country can only have one zone in selection...

If add another country it'll be a big trouble because it will also appear In the registration field...

How can change this?

in *_country table in database, I add new "id_zone2". and I think , I should change AdminCountriesController.php ...

				array(
					'type' => 'select',
					'label' => $this->l('Zone2'),
					'name' => 'id_zone2',
					'options' => array(
						'query' => Zone::getZones(),
						'id' => 'id_zone2',
						'name' => 'name'
					),
					'hint' => $this->l('Geographical region.')
				),

and now I add one new zone filed in backend, but I can't save it :P

 

please help me to fix this problem...

Thanks

 

Link to comment
Share on other sites

Probably need to define a public variable $id_zone2 in classes/Country.php as well:

 

Edit this file and add just below:

 

    /** @var integer Zone id which country belongs */
    public $id_zone;
 

 

your new variable:

 

    /** @var integer Zone id to which country belongs */
    public $id_zone2;

 

 

 

then, in same file a  little down, you see this code. Add your id_zone2 here as well:

 

    /**
     * @see ObjectModel::$definition
     */
    public static $definition = array(
        'table' => 'country',
        'primary' => 'id_country',
        'multilang' => true,
        'fields' => array(
            'id_zone' =>                     array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
            'id_zone2' =>                     array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
            'id_currency' =>                 array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'call_prefix' =>                 array('type' => self::TYPE_INT, 'validate' => 'isInt'),

...

 

 

 

Maybe add a function to get the zone2:

 

Find function public static function getIdZone($id_country)

and just below this function add a similar one:

 

    public static function getIdZone2($id_country)
    {
        if (!Validate::isUnsignedId($id_country))
            die(Tools::displayError());

        if (isset(self::$_idZones[$id_country]))
            return self::$_idZones[$id_country];

        $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow('
        SELECT `id_zone2`
        FROM `'._DB_PREFIX_.'country`
        WHERE `id_country` = '.(int)$id_country);

        self::$_idZones[$id_country] = $result['id_zone2'];
        return $result['id_zone2'];
    }

 

 

and maybe you need this function for your zone2 as well:

    public static function getCountriesByZoneId($id_zone, $id_lang)

    {
        if (empty($id_zone) || empty($id_lang))
            die(Tools::displayError());

        $sql = ' SELECT DISTINCT c.*, cl.*
                FROM `'._DB_PREFIX_.'country` c
                '.Shop::addSqlAssociation('country', 'c', false).'
                LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_country` = c.`id_country`)
                LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (c.`id_country` = cl.`id_country`)
                WHERE (c.`id_zone` = '.(int)$id_zone.' OR s.`id_zone` = '.(int)$id_zone.')
                AND `id_lang` = '.(int)$id_lang;
        return Db::getInstance()->executeS($sql);
    }
 

 

 

 

add a similar one (N.B. I took out the state-check (blue code above), not sure if we need to add the id_zone2 to states as well. Give it a thought):

 

    public static function getCountriesByZone2Id($id_zone2, $id_lang)
    {
        if (empty($id_zone2) || empty($id_lang))
            die(Tools::displayError());

        $sql = ' SELECT DISTINCT c.*, cl.*
                FROM `'._DB_PREFIX_.'country` c
                '.Shop::addSqlAssociation('country', 'c', false).'
                LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_country` = c.`id_country`)
                LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (c.`id_country` = cl.`id_country`)
                WHERE (c.`id_zone2` = '.(int)$id_zone2.')
                AND `id_lang` = '.(int)$id_lang;
        return Db::getInstance()->executeS($sql);
    }

 

 

Hope this does the trick,

pascal.

 

P.S. Can you describe why you need a second zone? Maybe there's another way to solve the problem.

  • Like 1
Link to comment
Share on other sites

Hi Dear Pascal

I did all the steps.

Under the new conditions in backend, when a country edited and save, I get an error message. "The field id_zone2 is required"

I changed True to False in this code:

            'id_zone2' =>                     array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),

In this mode, the page closed and saved But the ZONE2 field does not change.

One test:

When I change  value of "id_zone2" (for Exp "15") in one country (in phpmyadmin). In backend change not effect.

Thank you and I look forward to your tips.

 

And, in my country there are several courier company.(DHL, TNT, ARAMEX ,...) Their prices are varied and I want to give customers the power of choice. Each company has its own zoning. For example, England in DHL zone 3 and in TNT in zone 2 . 

 

Dariush

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

Hmm, I think you can fix this without adding any zone2:

 

If I understand you well, you have the following problem:

 

Some countries of for example Europe are in zone 2 for TNT (like England) but for DHL in zone 3 pricing, BUT NOT ALL European countries. Right?

 

So for example:

France, Netherlands, Germany, Belgium, Luxembourg, England are in zone 2 for TNT

Italy, Spain, Portugal, Switzerland, Norway, Sweden are in zone 3 for TNT

 

France, Netherlands, Germany, Belgium, Italy, Spain are in zone 2 for DHL

Luxembourg, England, Portugal, Switzerland, Norway, Sweden are in zone 3 for DHL

 

So when having a zone Europe_zone_2 and Europe_zone_3 you have the problem you described above.

 

 

Possible solution:

 

Make some new zone(s): 

First:

Make a zone Europe_zone_2 with only France, Netherlands, Germany, Belgium in it (i.e. with all the countries that are zone2 in both DHL/TNT). So edit each of these countries and change the zone to Europe_zone_2.

 

Make a zone Europe_zone_3 with only Portugal, Switzerland, Norway, Sweden in it (with all the countries that are zone3 in both DHL/TNT). So edit each of these countries and change the zone to Europe_zone_3.

 
 
 

Then, make some additional zone(s): (for all countries that need to be in different DHL/TNT zones):

 

Add a new zone Zone 'England', Then edit country England, and move this country to zone 'England' (Or maybe better name it 'United Kingdom'??)

Zone 'Luxembourg', Then edit country Luxembourg, and move this country to zone 'Luxembourg'.

Zone 'Spain', Then edit country Spain, and move this country to zone 'Spain'.

Zone 'Italy', Then edit country Italy, and move this country to zone 'Italy'.

 

(N.B. Be careful if you need to change USA, Canada, Mexico, Argentina, Italy, Indonesia or Japan, as these Countries have States. Then also change the zone in each state!)

 

 

Then when adding a carrier DHL:

Select zone Europe_zone_3, England, Luxembourg (and add a DHL Zone 3 price), and Europe_zone_2, Italy, Spain  (and add a DHL Zone 2 price)

 

And when adding a carrier TNT:

Select zone Europe_zone_3, Italy, Spain (and add a TNT Zone 3 price), and Europe_zone_2, England, Luxembourg   (and add a TNT Zone 2 price)

 
I think that should do the trick.
 
Maybe some more work to set it up (one time), but MUCH less problems with upgrading PrestaShop, no programming etc.
 
Give it a thought,
pascal.
  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

Thanks for your help.

It is too complicated for me.

I am working with four companies each have many differences.

And because I like most of the countries covered, Your method is extremely complex. Maybe I every country should define a zone! 

:(

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Hi Dear Pascal

I did all the steps.

Under the new conditions in backend, when a country edited and save, I get an error message. "The field id_zone2 is required"

I changed True to False in this code:

            'id_zone2' =>                     array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),

In this mode, the page closed and saved But the ZONE2 field does not change.

One test:

When I change  value of "id_zone2" (for Exp "15") in one country (in phpmyadmin). In backend change not effect.

Thank you and I look forward to your tips.

 

Dear Pascal

 

My problem persists. And solve the problem for me is very important.

Is this way true?

 

...

in *_country table in database, I add new "id_zone2". and I think , I should change AdminCountriesController.php ...

				array(
					'type' => 'select',
					'label' => $this->l('Zone2'),
					'name' => 'id_zone2',
					'options' => array(
						'query' => Zone::getZones(),
						'id' => 'id_zone2',
						'name' => 'name'
					),
					'hint' => $this->l('Geographical region.')
				),

...

Link to comment
Share on other sites

Dariush,

My first code-solution was only part of the solution, an addition to the Original Post, so ONLY my code won't work.

 

I do believe my second solution, just with built in functionality does work, as described in post #4

http://www.prestashop.com/forums/topic/350355-multi-zone-country/?do=findComment&comment=1767306

 

IT may be quite some work, though, as you need to move countries out of zones in to newly created zones, to separate them from continents (the current zones are set up as continents, or parts of continents etc)

 

I suggest to use this method, as it is less error prone, and the code above is not complete.

 

My 2 cents,

Pascal.

Link to comment
Share on other sites

  • 3 years later...

Hello guys I am facing the same problem. I thought about the solution given by Pascal. That is really interesting but as a B2B company it is hard to work out 100 weight columns for each 20 zones. I will also have to calculate real fees for each of them and add some extra fees for possible calculation errors and to compensate some area where delivery is harder and more expensive that the fee that correspond on weight and zone.

So I use dynamic fees, but the big drawback is that it slowwwwww down a lot the shop. 7-8 secs for adding a product or to load a page because Prestashop is recalculating everytime.

I looking up for a solution now  for that as well now :(

Multizone (should be implemented anyway) can be a fast way too but in some situation you may pay more than what your customer pays.

 

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