• Hi,

    I know that someone posted something similar for Italy’s Island…

    But it would be great to be able to choose given states/provinces for a specific Country.

    I live in Canada (province of Quebec) and we have a company that offers very good rates but ONLY for provinces of Ontario and Quebec… So it would be great to have the option to choose specific provinces!

    Otherwise, what a great plugin! 🙂

    http://wordpress.org/extend/plugins/awd-weightcountry-shipping/

Viewing 15 replies - 16 through 30 (of 34 total)
  • Yes! Finally I figured it out. There’s indeed a close curly bracket in a function of sync_states that has not been deleted. However, I still have a problem mantish. Upon entering the number of groups of states, nothing appears on the fields. By the way, I’ve added a PH.php in the /i18n/states folder in woocommerce as I noticed that there is no available for my country(Philippines). I just copied one the files there and renamed accordingly. Hope this helps. Hope to hear from you again soon. Thank you so much.

    By the way, I already set the base location in the General Options to my country(Philippines) and also the allowed countries to ‘specific’ and enter ‘Philippines’ in the specific countries field. I notice the result of my adding the PH.php file because now, upon selecting my Base Location, the states I’ve entered in the PH.php file already appear under my country(Philippines). However, when I go to Shipping tab and AWD Weigh/state, still the states don’t appear. When I try to type something, it always gives me a “No results match…” message. I’ve also tried to change the specific allowed country to the US but still the same result.

    florbv, you can put your code in github.
    By the way, adding the states (or any othe customization) inside the plugin folder is not recommended, as it may get lost whan you upgrade the plugin.
    You can add the states in your theme functions.php like this:

    add_filter( 'woocommerce_states', 'custom_woocommerce_states' );
    function custom_woocommerce_states( $states )
    {
    	$states['PH'] = array(
    		'XXX' => 'Xxxxx',
    		...
    	);
    	return $states;
    }

    I just published my code here: https://gist.github.com/Mantish/5658280
    You can compare to see if there’s something odd

    Thanks mantish! I’ve tried copying your codes and they worked! Great! Just have some more followup questions though. I have a theme child. where do I put those customizations so as not to be overwritten during upgrade. I’ve tried creating a functions.php file in my theme child directory and copied the code above but it just gave me an error. So I tried copying the whole functions.php from my parent theme to my child theme, added the coded above, and deleted the original functions.php in my parent theme directory and it worked. Did I do it right?

    Re shipping-awd.php file, I’ve tried creating a directory in my child theme and it looks like this: /twentyeleven_child/awd-weightcountry-shipping and tried to place your shipping-awd.php file there but it didn’t work. The entire AWD Weight/State shipping option disappeared in the Shipping tab of WooCommerce settings so what I did was just put it in the plugin’s original location folder(plugins/awd-weightcountry-shipping) and it worked. What should I suppose to do to protect it from future upgrades?

    Thank you so much for being kind. Really appreciate it. Am just a newbie in this field.:)

    One more thing mantish, is it possible for me to add another similar shipping method like this? Now with another shipping courier with different computations(still weight and state-based) to give my customers more options which shipping courier they like based on their shipping address coz sometimes their location is not covered by a certain courier. Hope to hear from you again. Thank you.

    Hello mantish! Glad I did it! Last question solved already. All I wanna know right now is how to keep safe these customized files from future updates/upgrades. Thank you so much!

    florbv, I haven’t work with child themes, so I wouldn’t know what’s the right way to go. You can check wordpress documentation.

    As for the customized files, I was talking about Woocommerce, which is common to have it updated once in a while. Regarding this shipping plugin, we’re actually hacking it, so we have to overwrite the shipping-awd.php and NEVER update it.

    Thanks mantish. will refer to wordpress documentation then. Are there options on setting plugin updates not to update automatically?

    cool! Can you share that on github florbv? do you have a gist of it? …

    I can’t input state names. How did you do it?

    Thanks for this post. This feature must be added to the plugin or a separate plugin must be developed for state/province based pricing for shipping. Many people are looking for this.

    I made some changes to the plugin and mantish code for spanish users. Now we can use a different shipping rate for Ceuta and Melilla, Baleares, Canarias and the rest of Spain, Portugal and Andorra.

    Now you can select state and/or country, and use more than one state or country at same time in the shipping rates (comma separated).

    Here you have the full new code. Please, enjoy it:

    <?php
    /**
     * Plugin Name: AWD Weight/State/Country Shipping
     * Plugin URI: http://www.andyswebdesign.ie/blog/free-woocommerce-weight-and-country-based-shipping-extension-plugin/
     * Description: Weight and State/Country based shipping method for Woocommerce.
     * Version: 1.0.1
     * Author: Andy_P (modified by Mantish to make it state based) Art Project Group final version
    /*  Copyright 2012  andyswebdesign.ie
    
        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License, version 2, as
        published by the Free Software Foundation.
    
        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.
    
        You should have received a copy of the GNU General Public License
        along with this program; if not, write to the Free Software
        Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    */
    
    add_action('plugins_loaded', 'init_awd_shipping', 0);
    
    function init_awd_shipping() {
    
        if ( ! class_exists( 'WC_Shipping_Method' ) ) return;
    
        class awd_Shipping extends WC_Shipping_Method {
    
            function __construct() {
    
                $this->id                       = 'awd_shipping';
                $this->method_title             = __( 'AWD Weight/State', 'woocommerce' );
    
                $this->admin_page_heading       = __( 'Weight based shipping', 'woocommerce' );
                $this->admin_page_description   = __( 'Define shipping by weight and state', 'woocommerce' );
    
                add_action( 'woocommerce_update_options_shipping_' . $this->id, array( &$this, 'sync_countries' ) );
                add_action( 'woocommerce_update_options_shipping_' . $this->id, array( &$this, 'process_admin_options' ) );
    
                $this->init();
                $this->display_state_groups();
    	        $this->display_country_groups();
            }
    
            /**
             * init function
             */
            function init() {
    
                $this->init_form_fields();
                $this->init_settings();
    
                $this->enabled                  = $this->settings['enabled'];
                $this->title                    = $this->settings['title'];
                $this->state_group_no           = $this->settings['state_group_no'];
                $this->country_group_no   		= $this->settings['country_group_no'];
                $this->sync_countries 			= $this->settings['sync_countries'];
                $this->availability             = 'specific';
                $this->states                   = $this->settings['states'];
    			$this->countries 	  			= $this->settings['countries'];
                $this->type                     = 'order';
                $this->tax_status               = $this->settings['tax_status'];
                $this->fee                      = $this->settings['fee'];
                $this->options                  = isset( $this->settings['options'] ) ? $this->settings['options'] : '';
                $this->options                  = (array) explode( "\n", $this->options );
            }
    
            function init_form_fields() {
    
                global $woocommerce;
    
                $this->form_fields = array(
                    'enabled' => array(
                        'title'                 => __( 'Enable/Disable', 'woocommerce' ),
                        'type'                  => 'checkbox',
                        'label'                 => __( 'Enable this shipping method', 'woocommerce' ),
                        'default'               => 'no',
                        ),
                    'title' => array(
                        'title'                 => __( 'Method Title', 'woocommerce' ),
                        'type'                  => 'text',
                        'description'   		=> __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
                        'default'               => __( 'Weight Based Shipping', 'woocommerce' ),
                        ),
    
                    'tax_status' => array(
                     'title'                	=> __( 'Tax Status', 'woocommerce' ),
                     'type'                     => 'select',
                     'description' 				=> '',
                     'default'              	=> 'taxable',
                     'options'             		=> array(
                        'taxable'       		=> __( 'Taxable', 'woocommerce' ),
                        'none'          		=> __( 'None', 'woocommerce' ),
                        ),
                     ),
                    'fee' => array(
                        'title'                 => __( 'Handling Fee', 'woocommerce' ),
                        'type'                  => 'text',
                        'description'   		=> __( 'Fee excluding tax. Enter an amount, e.g. 2.50. Leave blank to disable.', 'woocommerce' ),
                        'default'               => '',
                        ),
                    'options' => array(
                        'title'                 => __( 'Shipping Rates', 'woocommerce' ),
                        'type'                  => 'textarea',
                        'description'   		=> __( 'Set your weight based rates for state groups (one per line). Example: <code>Max weight|Cost|state/country group number separated by comma</code>. Example: <code>100|6.95|S1,C3</code>.', 'woocommerce' ),
                        'default'               => '',
                        ),
                    'state_group_no' => array(
                        'title'                 => __( 'Number of state groups', 'woocommerce' ),
                        'type'                  => 'text',
                        'description'  			=> __( 'Number of groups of states sharing delivery rates (hit "Save changes" button after you have changed this setting).' ),
                        'default'               => '3',
                        ),
                    'country_group_no' => array(
                        'title'                 => __( 'Number of country groups', 'woocommerce' ),
                        'type'                 	=> 'text',
                        'description'			=> __( 'Number of groups of countries sharing delivery rates (hit "Save changes" button after you have changed this setting).' ),
                        'default' 				=> '3',
                        ),
                    'sync_countries' => array(
                        'title'                 => __( 'Add countries to allowed', 'woocommerce' ),
                        'type'                 	=> 'checkbox',
                        'label' 				=> __( 'Countries added to country groups will be automatically added to Allowed Countries
    												in <a href="/wp-admin/admin.php?page=woocommerce_settings&tab=general">General settings tab.</a>
    												This makes sure countries defined in country groups are visible on checkout.
    												Deleting country from country group will not delete country from Allowed Countries.', 'woocommerce' ),
                        'default' 				=> 'no',
                        ),
                    );
            }
    
            /*
            * Displays state group selects in shipping method's options
            */
            function display_state_groups() {
    
                global $woocommerce;
            //   echo prp($this->settings['countries1']);
                $number = $this->state_group_no;
    
                $base_country = $woocommerce->countries->get_base_country();
    
                for($counter = 1; $number >= $counter; $counter++) {
    
                    $this->form_fields['S'.$counter] =  array(
                        'title'     => sprintf(__( 'State Group %s', 'woocommerce' ), $counter),
                        'type'      => 'multiselect',
                        'class'     => 'chosen_select',
                        'css'       => 'width: 450px;',
                        'default'   => '',
                        'options'   => $woocommerce->countries->get_states( $base_country )
                        );
                }
            }
    
            /*
    	    * Displays country group selects in shipping method's options
    	    */
        	function display_country_groups() {
    
    	        global $woocommerce;
       		//   echo prp($this->settings['countries1']);
    	        $number = $this->country_group_no;
    
    			for($counter = 1; $number >= $counter; $counter++) {
    
        	        $this->form_fields['C'.$counter] =  array(
            	            'title'     => sprintf(__( 'Country Group %s', 'woocommerce' ), $counter),
    	                    'type'      => 'multiselect',
    	                    'class'     => 'chosen_select',
        	                'css'       => 'width: 450px;',
    	                    'default'   => '',
    	                    'options'   => $woocommerce->countries->countries
    	            );
    	        }
    	    }
    
            /*
            * This method is called when shipping is calculated (or re-calculated)
            */
            function calculate_shipping($package = array()) {
    
                global $woocommerce;
    
    			$group = $this->get_group($package);
    			$rates = $this->get_rates_by_group($group);
    			if ($group[0] == 'S') $destination = $package['destination']['state'];
    			else $destination = $package['destination']['country'];
    
                $weight = $woocommerce->cart->cart_contents_weight;
                $final_rate = $this->pick_smallest_rate($rates, $weight);
    
                if ($final_rate === false) return false;
    
                $taxable = ($this->tax_status == 'taxable') ? true : false;
    
                if ($this->fee > 0 && $destination) $final_rate = $final_rate + $this->fee;
    
                $rate = array(
                    'id'        => $this->id,
                    'label'     => $this->title,
                    'cost'      => $final_rate,
                    'taxes'     => '',
                    'calc_tax'  => 'per_order'
                    );
    
                $this->add_rate( $rate );
            }
    
            /*
            * Retrieves the number of state/country group for state selected by user on checkout
            */
            function get_group($package = array()) {
    
                $counter = 1;
    
                while(is_array($this->settings['S'.$counter])) {
                    if (in_array($package['destination']['state'], $this->settings['S'.$counter])) $group = 'S'.$counter;
    
                    $counter++;
                }
    
                if (isset($group)) return $group;
    
                $counter = 1;
    
                while(is_array($this->settings['C'.$counter])) {
                    if (in_array($package['destination']['country'], $this->settings['C'.$counter])) $group = 'C'.$counter;
    
                    $counter++;
                }
    
                return $group;
            }
    
        	/*
    	    * Retrieves all rates available for selected group
    	    */
            function get_rates_by_group($group = null) {
    
                $rates = array();
                if ( sizeof( $this->options ) > 0) foreach ( $this->options as $option => $value ) {
    
                    $rate = preg_split( '~\s*\|\s*~', trim( $value ) );
    
                    if ( sizeof( $rate ) !== 3 )  {
                        continue;
                    } else {
                        $rates[] = $rate;
                    }
                }
    
                foreach($rates as $key) {
    				$groups = explode(",", $key[2]);
    				foreach($groups as $group_key)
    				{
    	                if ($group_key == $group) {
        	                $group_rate[] = $key;
            	        }
    				}
                }
                return $group_rate;
            }
    
            /*
            * Picks the right rate from available rates based on cart weight
            */
            function pick_smallest_rate($rates,$weight) {
    
                if ($weight == 0) return 0; // no shipping for cart without weight
    
                if (sizeof($rates) > 0) foreach ($rates as $key => $value) {
    
                    if ($weight <= $value[0]) {
                        $postage[] = $value[1];
                    }
                    $postage_all_rates[] = $value[1];
                }
    
                if (sizeof($postage) > 0) {
                    return min($postage);
                } else {
                    if (sizeof($postage_all_rates) > 0) return max($postage_all_rates);
                }
                return false;
            }
    
            function etz($etz) {
    
                if(empty($etz) || !is_numeric($etz)) {
                    return 0.00;
                }
            }
    
    	    /*
    	    * Uptades Allowed Countries with countries added to country groups
    	    */
    	    function sync_countries() {
    
    	        if ($this->settings['sync_countries'] == 'yes') {
    	            $countries = $this->get_cg_countries();
    	            update_option('woocommerce_specific_allowed_countries', $countries);
    	        }
    	    }
    
    	    /*
    	     * Retrieves countries from country groups and merges them with Allowed Countries array
    	     */
        	function get_cg_countries() {    
    
                $counter = 1;
                $countries = array();
    
                while(is_array($this->settings['countries'.$counter])) {
                    $countries = array_merge($countries, $this->settings['countries'.$counter]);
    
                	$counter++;
                }
    
                $allowed_countries = get_option( 'woocommerce_specific_allowed_countries' );
    
                if (is_array($allowed_countries)) $countries = array_merge($countries, $allowed_countries);
                $countries = array_unique($countries);
            	return $countries;
        	}
    
            public function admin_options() {
    
                ?>
                <h3><?php _e('Weight and State based shipping', 'woocommerce'); ?></h3>
                <p><?php _e('Lets you calculate shipping based on State and weight of the cart. Lets you set unlimited weight bands on per state basis and group states
                that share same delivery cost/bands. For help and how to use go <a href="http://www.andyswebdesign.ie/blog/free-woocommerce-weight-and-country-based-shipping-extension-plugin/" target="_blank">here</a>', 'woocommerce'); ?></p>
                <table class="form-table">
                   <?php
                        // Generate the HTML For the settings form.
                   $this->generate_settings_html();
                   ?>
                </table><!--/.form-table-->
                <?php
            }
    
        } // end awd_Shipping
    }
    
    /**
     * Add shipping method to WooCommerce
     **/
    function add_awd_shipping( $methods ) {
        $methods[] = 'awd_shipping'; return $methods;
    }
    
    add_filter( 'woocommerce_shipping_methods', 'add_awd_shipping' );
    
    ?>

    Emilio José Calvo,
    That is brilliant! Works perfectly. Thank you!

    I’m awaiting approval from WordPress for publishing a new plugin called WooCommerce – APG Weight and Postcode/State/Country Shipping with that code and more options, like groups by postalcode, different taxes for groups and unlimited shipping companies. Fully translate in english and spanish. And totally FREE.

    Please wait until WordPress approve it. You can get more information on http://www.artprojectgroup.es/plugins-para-wordpress/woocommerce-apg-weight-and-postcodestatecountry-shipping.

    In this weekend I’ll publish a tutorial, in spanish only, to know how to use it.

    I hope you enjoy it.

Viewing 15 replies - 16 through 30 (of 34 total)
  • The topic ‘Separate shipping for states/provinces’ is closed to new replies.