• Resolved hotcookie

    (@hotcookie)


    Woocommerce Zone processing does not allow for a local pickup option when customers are not shipping. We have customers from other countries who enter their address for purchasing. The only way to enable a zone for local pickup is if “Ship to specific countries” has the country of the billing address. For actual shipping, we only allow shipping in the US.

    Woocommerce has a function in wc-core-functions.php called wc_get_shipping_zone. In fact wc-core-functions.php checks to see if that function is defined before it defines the default. I could create my own zone processing if I can define my own wc_get_shipping_zone function. It would first call WC_Shipping_Zones::get_zone_matching_package( $package ); and if there were no match would default to zone_id = 0, the Locations not covered by your other zones option. Ideally this should be the case anyway. But the current implementation does not select any zones that are not including in the Ship to specific countries setting. I don’t want all countries in that setting because then they appear as possible countries to ship to on the checkout form.

    Woocommerce core should always default to zone_id 0 if no other zones are selected. Alternatively, Woocommerce can add a filter after WC_Shipping_Zones::get_zone_matching_package( $package ); where I can force zone_id 0.

    I consider this a bug. This is the first time I’ll have to alter a core woocommerce file (i.e. not a template) to get what I consider obvious. The ability to always have my Local Pickup processing called.

    The page I need help with: [log in to see the link]

Viewing 4 replies - 1 through 4 (of 4 total)
  • Thread Starter hotcookie

    (@hotcookie)

    After digging deaper, the wc_get_shipping_zones is not relevant. I hacked together the following code that seems to work.

    function force_default_shipping ($packages) {
      if (sizeof($packages[0]['rates']) != 0) {
        return $packages;
      }
      unset($packages[0]['rates']);
      $packages_default = $packages;
      $packages_default[0]['destination']['country'] = 'default';
      add_filter('woocommerce_countries_shipping_countries','force_hack_countries');
      $packages_default[0] = WC_Shipping::instance()->calculate_shipping_for_package ($packages_default[0], 0);
      remove_filter('woocommerce_countries_shipping_countries', 'hotcookie_hack_countries');  
      return $packages_default;
    }
    
    function force_hack_countries($countries) {
      $countries = array('default' => 'default');
      return $countries;
    }
    add_filter('woocommerce_shipping_packages', 'force_default_shipping', 10, 2); 

    It forces the “is_package_shippable” check in class-wc-shipping.php to return true but forces the zone search to the “Locations not covered by your other zones” zone. Any shipping options enabled there then come up. All that’s necessary is to add a “local pickup” shipping option to “Locations not covered by your other zones”.

    Woocommerce should not require coding this hack to make this concept work.

    Thread Starter hotcookie

    (@hotcookie)

    One additional hack necessary. Checkout class has a check to determine if the Billing Country (in this case also the shipping country) is in the General settings Shipping country. Created this to override.

    function force_hack_country() {
      $country = WC()->customer->get_shipping_country();
      $countries = array($country => $country);
      return $countries;
    }
    
    function force_hack_default_country() {
      $packages = WC()->shipping->get_packages();
      $shipping_zone = wc_get_shipping_zone($packages[0]);
      if ($shipping_zone->get_id() == '0') { // Hack to make Default zone work
        add_filter('woocommerce_countries_shipping_countries', 'force_hack_country');
      }
    }
    add_filter('woocommerce_checkout_process','force_hack_default_country');
    Thread Starter hotcookie

    (@hotcookie)

    Some more changes after testing. This one works.

    function hotcookie_default_shipping ($packages) {
      if (sizeof($packages[0]['rates']) != 0) {
        return $packages;
      }
      unset($packages[0]['rates']);
      $packages_default = $packages;
      $shipping_country = $packages_default[0]['destination']['country'];
      $packages_default[0]['destination']['country'] = 'default';
      add_filter('woocommerce_countries_shipping_countries','hotcookie_hack_countries');
      $packages_default[0] = WC_Shipping::instance()->calculate_shipping_for_package ($packages_default[0], 0);
      remove_filter('woocommerce_countries_shipping_countries', 'hotcookie_hack_countries');  
      $packages_default[0]['destination']['country'] = $shipping_country;
      return $packages_default;
    }
    
    function hotcookie_hack_countries($countries) {
      $country = 'default';
      $countries = array($country => $country);
      return $countries;
    }
    
    add_filter('woocommerce_shipping_packages', 'hotcookie_default_shipping', 10, 2); 
    
    function hotcookie_hack_country($countries) {
      $packages = WC()->shipping->get_packages();
      if (empty($packages)) {
        return $countries;
      }
      $shipping_zone = wc_get_shipping_zone($packages[0]);
      if ($shipping_zone->get_id() == '0') { // Hack to make Default zone work
        $country = WC()->customer->get_shipping_country();
        $countries = array($country => $country);
      }
      return $countries;
    }
    
    function hotcookie_hack_default_country() {
      add_filter('woocommerce_countries_shipping_countries', 'hotcookie_hack_country');
    }
    add_filter('woocommerce_checkout_process','hotcookie_hack_default_country');
    Plugin Support Shameem R. a11n

    (@shameemreza)

    Hi @hotcookie

    I’m glad you were able to find a solution to your inquiry and thanks for sharing it with the community too! ??

    I will be marking this thread as resolved. Should you have further inquiries, kindly create a new topic here.

    Thanks!

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Zone processing override for Local Pickup’ is closed to new replies.