Force WooCommerce to sell and ship to ONLY one state - php

How do I force WooCommerce to sell and ship to only one state?
I can select a country but I can't find any way to allow selling and shipping only to one state/region.
Let's say I've selected only Canada and I want to sell only in Ontario. How can I achieve that? I probably have to add something to function.php to filter the states, but I don't know where to look for it...
Thanks!

I've found this solution, but probably it's not the "cleanest" way to achieve this.
Any suggestion?
add_filter( 'default_checkout_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_state', 'change_default_checkout_state' );
function change_default_checkout_country() {
return 'CA'; // country code
}
function change_default_checkout_state() {
return 'ON'; // state code
}
add_filter( 'woocommerce_states', 'custom_woocommerce_states' );
function custom_woocommerce_states( $states ) {
$states['CA'] = array(
'ON' => 'Ontario',
);
return $states;
}

Related

Keep state field as a dropdown when one allowed country on Woocommerce

I thought this would be easy but I'm not getting the results I want. Basically I have 2 countries in woocommerce CA and US. I'm trying to remove one conditionally, and I can do that with the following code below. However, when I go from 2 countries to 1, the dropdown menu still appears. An odd thing I'm noticing with the below code as well, is that if I go into my Woocommerce settings, then the country that is removed with this code is also removed from the "Sell to specific countries" options.... not sure what's going on. Thanks in advance.
add_filter( 'woocommerce_countries', 'custom_woocommerce_countries_limit');
function custom_woocommerce_countries_limit( $countries ) {
/*
will place a conditional here if x then remove country
*/
unset($countries['CA']);
$countries = array(
'US' => __( 'United States', 'woocommerce' )
);
return $countries;
}
EDIT: Using this hook may be close to the answer, but when I use this one, The states don't turn into a dropdown...?
add_filter( 'woocommerce_countries_allowed_countries', 'custom_woocommerce_countries_limit');
You can use woocommerce_countries_allowed_countries filter hook, but you should need some additional code to force the state fields to be a state dropdown (select field):
add_filter( 'woocommerce_countries_allowed_countries', 'filter_allowed_countries_conditionally');
function filter_allowed_countries_conditionally( $countries ) {
// will place a conditional here if x then remove country
if( true ) {
$countries = array( 'US' => __( 'United States', 'woocommerce' ) );
} else {
$countries = array( 'CA' => __( 'Canada', 'woocommerce' ) );
}
return $countries;
}
// Force billing state field type to be a dropdown
add_filter( 'woocommerce_billing_fields', 'filter_billing_state_fields', 100, 1 );
function filter_billing_state_fields( $fields ) {
$fields['billing_state']['type'] = 'state';
return $fields;
}
// Force shipping state field type to be a dropdown
add_filter( 'woocommerce_shipping_fields', 'filter_shipping_state_fields', 100, 1 );
function filter_shipping_state_fields( $fields ) {
$fields['shipping_state']['type'] = 'state';
return $fields;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Change default sorting order for multiple specific woocommerce product categories

I'm trying to change the default orderby for multiple product categories, but can't work out how to adapt the code found here Cant change default sorting order of specific woocommerce category to 'popularity' to apply the change to more than one category.
Here's the code I currently have that is changing the default orderby for my comic book preorders category:
add_filter( 'woocommerce_default_catalog_orderby', 'custom_default_catalog_orderby' );
function custom_default_catalog_orderby() {
$product_category = 'comic-book-pre-orders';
if ( is_product_category( $product_category ) ) {
return 'sku_asc';
}
else {
return 'date';
}
}
Ideally I'd be able to apply the custom orderby to my 'comic-book-subscriptions' category as well as a couple of others potentially.
Any help would be very much appreciated!
Kind regards,
JP
Think I managed to work it out!
Here's the code I'm now using:
add_filter( 'woocommerce_default_catalog_orderby', 'custom_default_catalog_orderby' );
function custom_default_catalog_orderby() {
$product_category = array( 'comic-book-pre-orders', 'comic-book-subscriptions' );
if ( is_product_category( $product_category ) ) {
return 'sku_asc';
}
else {
return 'date';
}
}
If anyone has a better approach please let me know :)

Changing currency on checkout with WooCommerce Multilingual Plugin

I'm trying to implement currency change on checkout with WooCommerce Multilingual Plugin. I need a country with COP and the rest of countries with USD. First I tried to use the wcml_client_currency hook.
function modify_client_currency( $currency ) {
$country = WC()->customer->get_billing_country();
if ($country === 'CO') {
return 'COP';
} else {
return 'USD';
}
}
add_filter( 'wcml_client_currency', 'modify_client_currency', 10, 1 );
If I start with Colombia selected, the currency is in COP, but if I change to another country, the currency stay on COP. I need to change the country again to see the change.
I tried another approach with the woocommerce_checkout_update_order_review and analyzing how the multilingual plugin works.
function action_woocommerce_checkout_update_order_review( $post_data ) {
// This part will change dynamically based on the country contained in $post_data
$currency = 'COP';
global $woocommerce_wpml;
$woocommerce_wpml->multi_currency->set_client_currency($currency);
global $woocommerce, $current_user;
if(empty($woocommerce->session->data) && empty($current_user->ID)){
$woocommerce->session->set_customer_session_cookie(true);
}
do_action('wcml_switch_currency', $currency );
WC()->cart->calculate_totals();
}
add_action('woocommerce_checkout_update_order_review', 'action_woocommerce_checkout_update_order_review', 10, 1);
With this approach I have exactly the same problem, I need to change the country twice to see the currency change.

WooCommerce: Pre-select and restrict to one state and city on checkout

I'm setting up a store that only sells to one city. I'm trying to figure out how I can restrict the city option to a pre-filled field.
I've already limited the country and using the following code in my functions.php:
add_filter( 'default_checkout_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_state', 'change_default_checkout_state' );
function change_default_checkout_country() {
return 'PK'; // country code
}
function change_default_checkout_state() {
return 'SD'; // state code
}
And I've pre-selected the state using the following:
add_filter( 'woocommerce_states', 'bbloomer_custom_woocommerce_states' );
function bbloomer_custom_woocommerce_states( $states ) {
$states['PK'] = array(
'SD' => 'Sindh',
);
return $states;
}
But... Now comes the city and I am lost. I've tried using $fields['billing']['billing_city'] as well as $fields['billing']['billing_city']['value'] to no avail.
I want the customer to be limited to Karachi. I am not very familiar with WooCommerce filters, so I need help on achieving this.
Since woocommerce 3, default_checkout_country and default_checkout_state filter hooks are now deprecated and replaced.
Also in your last function, if you want to restrict just to one city, you should not include your city in the array of states. Instead you should return only one possible value.
So this will be your code:
// default checkout country
add_filter( 'default_checkout_billing_country', 'change_default_checkout_country' );
add_filter( 'default_checkout_shipping_country', 'change_default_checkout_country' );
function change_default_checkout_country() {
return 'PK'; // country code
}
// default checkout state
add_filter( 'default_checkout_billing_state', 'change_default_checkout_state' );
add_filter( 'default_checkout_shipping_state', 'change_default_checkout_state' );
function change_default_checkout_state() {
return 'SD'; // state code
}
// Setting one state only
add_filter( 'woocommerce_states', 'custom_woocommerce_state', 10, 1 );
function custom_woocommerce_state( $states ) {
// Returning a unique state
return array('PK' => array('SD' => 'Sindh'));
}
// Only one city at checkout
add_filter( 'woocommerce_checkout_fields', 'custom_checkout_fields', 10, 1 );
function custom_checkout_fields( $fields ) {
$fields['billing']['billing_city']['type'] = 'select';
$fields['billing']['billing_city']['options'] = array('Karachi' => 'Karachi');
$fields['shipping']['shipping_city']['type'] = 'select';
$fields['shipping']['shipping_city']['options'] = array('Karachi' => 'Karachi');
return $fields;
}
The Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works for wooCommerce versions 3+
Once added the code above and saved, you will need in WooCommerce > Settings > General to set locations this way:
Then you will get something like this on checkout:
Both dropdown have only one value… So you get what you are expecting.

wordpress woocommerce (2.6.9) override shipping

I need to dynamically get shipping costs at checkout from an external system. I've accessed the api and have the costs in variables and now want to 'overwrite' the costs coming from woocommerce with these new ones.
I'm hooking into the woocommerce_package_rates hook but don't seem to be able to get it to work. In the example below, I've just swapped out the variable for a number (100) for simplicity. Any ideas?
function flat_rates_cost( $rates, $package ) {
if ( isset( $rates['flat_rate:5'] ) ) {
$rates['flat_rate:5']->cost = 100;
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'flat_rates_cost', 10, 2 );
function flat_rates_cost( $rates, $package ) {
foreach($rates as $key => $rate){
// Put your desired slug here for API service
if($rate->method_id == 'flat_rate'){
// modify the value here
$rates[$key]->cost = 25;
}
}
return $rates;
}
add_filter( 'woocommerce_package_rates', 'flat_rates_cost', 10, 2 );
I can relate an article with exact same scenario. If you go through that article it will describe you how to change flat rates applying your own logic.

Categories