Стандартные средства настройки зоны доставки предоставляют на выбор страны а также ограничивают зону почтовыми индексами. Но на практике это не удобно, т.к. пользователь зачастую не знает своего индекса и не будет его вводить. Расширим функционал добавив вместо индекса список городов.
Изменение (перезагрузка) методов доставки происходит при изменении полей страна и область.
Cities Shipping Zones for WooCommerce (2000)
Плагин расширяет поле со страной добавляя в него перечень городов в каждой стране. Российских городов в нем нет.
States, Cities, and Places for WooCommerce (6000)
Функционал у этого плагина аналогичен предыдущему. Но в нем присутствуют области и города РФ.
Для удобства можно удалить ненужные города и области других стран. Для этого нужно удалить все файлы из папок states и places, кроме файлов с названием RU.php.
Работает так же как и со страной: создаем зону доставки, только вместо страны область(и) и задаем методы доставки. При этом в Оформлении обязательно должны быть выведены поля: страна, область, город. Поля область и город превращаются в выпадающие списки с выбором городов и при их изменении меняется набор методов доставки для выбранной зоны. Выбор Россия будет включать в себя все регионы.
Добавить собственную зону (страну) и области в ней
Создаем кастомную зону (страну) с помощью функции
add_filter( 'woocommerce_countries', 'worda_add_my_country' );
function worda_add_my_country( $countries ) {
$new_countries = array(
'MYCT' => __( 'My new country', 'woocommerce' ),
);
return array_merge( $countries, $new_countries );
}
add_filter( 'woocommerce_continents', 'worda_my_country_to_continents' );
function worda_my_country_to_continents( $continents ) {
$continents['EU']['countries'][] = 'NSNS';
return $continents;
}
Создаем области в кастомной зоне
add_filter( 'woocommerce_states', 'worda_woocommerce_states' );
function worda_woocommerce_states( $states ) {
$states['RU'] = array(
'RO' => __('Ростов-на-Дону', 'woocommerce') ,
'MO' => __('Москва', 'woocommerce') ,
'MU' => __('Мурманск', 'woocommerce') ,
'ST' => __('Ставрополь', 'woocommerce') ,
'VO' => __('Воронеж', 'woocommerce') ,
'SO' => __('Сочи', 'woocommerce') ,
'KR' => __('Краснодар', 'woocommerce') ,
'SP' => __('Санкт-Петербург', 'woocommerce') ,
'NN' => __('Нижний Новгород', 'woocommerce') ,
'EK' => __('Екатеринбург', 'woocommerce') ,
);
return $states;
}
Изменение методов доставки в зависимости от выбранной области
add_filter( 'woocommerce_package_rates', 'njengah_filter_shipping_methods', 10, 2 );
function njengah_filter_shipping_methods( $rates, $package ) {
$excluded_states = array( 'MU','SO' );
if( in_array( WC()->customer->get_billing_state(), $excluded_states ) ) {
unset( $rates['free_shipping:1'] );
unset( $rates['local_pickup:2'] );
}
return $rates;
}
WC()->customer->get_billing_state(); — вывод выбранной области плательщика.
Добавим в условия отключения методов доставки содержание у одно из товаров кастомного класса доставки luxmobily
add_filter( 'woocommerce_package_rates', 'njengah_filter_shipping_methods', 10, 2 );
function njengah_filter_shipping_methods( $rates, $package ) {
$found = false;
foreach( $package['contents'] as $cart_item ) {
if( $cart_item['data']->get_shipping_class() == 'luxmobily' )
$found = true;
}
$excluded_states = array( 'MU','SO' );
if( in_array( WC()->customer->get_billing_state(), $excluded_states ) && $found == true ) {
unset( $rates['free_shipping:1'] );
unset( $rates['local_pickup:2'] );
}
return $rates;
}
Выбор города в виде выпадающего списка
Возможно в будущем пригодится
// Поле Город в виде выпадающего списка
add_filter( 'woocommerce_checkout_fields' , 'override_checkout_city_fields' );
function override_checkout_city_fields( $fields ) {
// Define here in the array your desired cities (Here an example of cities)
$option_cities = array(
'' => __( 'Select your city' ),
'Karachi' => 'Karachi',
'Lahore' => 'Lahore',
'Faisalabad' => 'Faisalabad',
'Rawalpindi' => 'Rawalpindi',
'Gujranwala' => 'Gujranwala',
'Peshawar' => 'Peshawar',
'Multan' => 'Multan',
'Hyderabad' => 'Hyderabad',
'Islamabad' => 'Islamabad'
);
$fields['billing']['billing_city']['type'] = 'select';
$fields['billing']['billing_city']['options'] = $option_cities;
$fields['shipping']['shipping_city']['type'] = 'select';
$fields['shipping']['shipping_city']['options'] = $option_cities;
return $fields;
}
Отключение полей, если выбран определенный метод доставки
Это можно использовать для вывода поля Адрес (billing_address_1) при выборе метода «Доставка до адреса»
// Отключаем поле Адрес доставки, если не выбран данный вариант доставки
add_filter( 'woocommerce_checkout_fields', 'remove_billing_checkout_fields' );
function remove_billing_checkout_fields( $fields ) {
// Методы доставки при которых поле не отключается
$shipping_method = array( 'flat_rate:4' );
// Поля которые нужно отключить
$hide_fields = array( 'billing_address_1' );
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
foreach( $hide_fields as $field ) {
if ( ! in_array ($chosen_shipping , $shipping_method) ) {
$fields['billing'][$field]['required'] = false;
$fields['billing'][$field]['class'][] = 'hide';
}
$fields['billing'][$field]['class'][] = 'billing-dynamic';
}
return $fields;
}
add_action( 'wp_footer', 'cart_update_script', 999 );
function cart_update_script() {
if (is_checkout()) :
?>
<style>.hide {display: none!important;}</style>
<script>
jQuery( function( $ ) {
// woocommerce_params is required to continue, ensure the object exists
if ( typeof woocommerce_params === 'undefined' ) {
return false;
}
// Методы доставки при которых поле не отключается
var show = ['flat_rate:4'];
$(document).on( 'change', '#shipping_method input[type="radio"]', function() {
// console.log($.inArray($(this).val(), show));
if ($.inArray($(this).val(), show) > -1) { // >-1 if found in array
$('.billing-dynamic').removeClass('hide');
// console.log('show');
} else {
$('.billing-dynamic').addClass('hide');
// console.log('hide');
}
});
});
</script>
<?php
endif;
}
Переключение города доставки (jQuery)
Переключим при переходе в оформление на город указанный в шапке
$(document).ready(function () {
// Изменение города в оформлении от города выбранного в шапке
var word = $('#city-ajax').text();
$('#billing_state_field span.select2 .select2-selection__rendered').attr('title', word);
$('#billing_state_field span.select2 .select2-selection__rendered').text(word);
$('select#billing_state option:contains("'+word+'")').prop('selected', true);
jQuery(document.body).trigger("update_checkout");
});
Как определять и изменять город в шапке можно узнать здесь.
[site-socialshare]