• Никакой политики на форуме. Иначе - бан!
  • Вопрос без рабочей ссылки на проблему считается риторическим. Без ссылки и скриншота - провокацией!
  • Темы озаглавленные с маленькой буквы или капсом удаляются без предупреждения!

Решено Как избавится от заполнения всех полей при Самовывозе?

EliteWars

Новичок
Ты же в методах доставки в настройках woocommerce указываешь допустим , что(Пример: При самовывозе используется "Оплата наличными", а при доставке "Наложенный платеж") вот этим ты их и связываешь, а потом они уже как я показал на скрине выше взаимодействуют.
Тоесть где я выберу "Наложенный платеж" эти поля будут отображаться при выборе способа доставки "Доставка бла бла бла", там где я выбрал "Оплата наличными" эти поля будут отображаться при выборе способа доставки "Самовывоз".)
 

leksus

Новичок
Да чего ты споришь) 1 +2 = 3 и 2 + 1 = 3 роль то не играет.
Что ты для "доставки способ оплаты" хотел сделать определенный, что для "оплаты сделать способ доставки" определенный.
Тебе же главное чтобы при выборе доставки у тебя отображало определенные поля для заполнения.
Ну вот и настраивай как показали, так и делается)
Ээээ, я не хочу сделать определенный вид формы для способа оплаты. Твой способ - кривой, и работает он только при двух способах оплаты и двух способах доставки. Тупо добавить еще один способ просто невозможно.

Мне нужно делать разные формы для разных способов доставки. Для самовывоза - имя и телефон, при этом покупатель может оплатить как наличкой, так и сразу онлайн. Для транспортной компании - ФИО, город, телефон и номер паспорта. Для курьерской службы - ФИО, полный адрес, телефон. Для Почты России - ФИО, полный адрес с индексом. И для всех этих способов покупателю надо предложить все способы оплаты.

Ну-ка, покажи как мне настроить этот супер-плагин, где 1+2=3 и 2+1=3 :)
 

EliteWars

Новичок
Ээээ, я не хочу сделать определенный вид формы для способа оплаты. Твой способ - кривой, и работает он только при двух способах оплаты и двух способах доставки. Тупо добавить еще один способ просто невозможно.

Мне нужно делать разные формы для разных способов доставки. Для самовывоза - имя и телефон, при этом покупатель может оплатить как наличкой, так и сразу онлайн. Для транспортной компании - ФИО, город, телефон и номер паспорта. Для курьерской службы - ФИО, полный адрес, телефон. Для Почты России - ФИО, полный адрес с индексом. И для всех этих способов покупателю надо предложить все способы оплаты.

Ну-ка, покажи как мне настроить этот супер-плагин, где 1+2=3 и 2+1=3 :)

) Не ну суть осталась ведь неизменной по сути? Ты можешь просто для каждого способа оплаты (связанного с доставкой) разные поля делать нужными. Допустим: Поле город доступно для способов оплаты 1 и 2 ну и тд. ))
 

EliteWars

Новичок
А по поводу ограничения способов доставки и оплаты другая песня надо подумать
 

EliteWars

Новичок
Сейчас разберусь с checkout а то после обновления woocommerce перестал работать...
 

leksus

Новичок
) Не ну суть осталась ведь неизменной по сути? Ты можешь просто для каждого способа оплаты (связанного с доставкой) разные поля делать нужными. Допустим: Поле город доступно для способов оплаты 1 и 2 ну и тд. ))
Я не знаю, как по-другому тебе объяснить. Твой способ - привязка способа оплаты к способу доставки. Он подходит если у тебя два способа доставки и оплаты. Либо для каждого способа доставки делать свой способ оплаты? Это вообще как? Зачем? Это же бред! Еще раз. Данным плагином нельзя управлять отображением полей для разных способов доставки. Только для разных способов оплаты. И твой способ - это некий костыль, который подходит только под один случай.

А по поводу ограничения способов доставки и оплаты другая песня надо подумать
И это не "совсем другая песня". Это - суть данного топика. Возможность менять поля при изменении способов доставки. Это основа обсуждаемой проблемы. А не "другая песня".
 

EliteWars

Новичок
Я не знаю, как по-другому тебе объяснить. Твой способ - привязка способа оплаты к способу доставки. Он подходит если у тебя два способа доставки и оплаты. Либо для каждого способа доставки делать свой способ оплаты? Это вообще как? Зачем? Это же бред! Еще раз. Данным плагином нельзя управлять отображением полей для разных способов доставки. Только для разных способов оплаты. И твой способ - это некий костыль, который подходит только под один случай.


И это не "совсем другая песня". Это - суть данного топика. Возможность менять поля при изменении способов доставки. Это основа обсуждаемой проблемы. А не "другая песня".

Ладно давай искать другой способ
 

M0HAX

Новичок
Тоже пришлось озадачиться... В итоге оказалось боле менее подходящим решением, это решение от yaspis . Но:

Уберем обязательность заполнения полей.
Это можно сделав переопределив необходимые вам поля в файле functions.php вашей темы:

// Хук
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Все $fields в этой функции будут пропущены через фильтр
function custom_override_checkout_fields( $fields ) {
$fields['billing']['billing_state_name']['required'] = false;
$fields['billing']['billing_address_1']['required'] = false;
$fields['billing']['billing_address_2']['required'] = false;
return $fields; }


... - не срабатывает(((
Точнее не срабатывают именно

$fields['billing']['billing_state_name']['required'] = false;
$fields['billing']['billing_address_1']['required'] = false;
$fields['billing']['billing_address_2']['required'] = false;


т.к. если добавить еще
unset($fields['billing']['billing_company']);

то поле с названием компании исчезает, соответственно через фильтры все проходит...
Но поля все равно считаются обязательными...
И пропускать через фильтр тоже желательно при выборе метода доставки Самовывоза (local_pickup) . Может кто-нибудь допилил уже этот скрипт?
P.S. Или, как вариант, у меня блокируется это WooChekcout - ом?
 
Последнее редактирование:

Zoten

Форумчанин
Была похожая задача: сделать возможность создания доставок, с расчётом стоимости по параметру (вес) и с привязкой к зонам доставки. При этом для каждой доставки нужен был свой набор полей или селектов (для выбора ПВЗ использовали). И вишенкой на торте была реализация пошагового оформления заказа: Контактные данные -> Выбор способа доставки -> Выбор способа оплаты
Я решил так:
1) отключил все billing-поля кроме Имя, Фамилия, телефон, email, регион.
2) подключил два плагина
https://codecanyon.net/item/woocommerce-advanced-shipping/8634573 - с помощью него создавал доставки
https://shopplugins.com/plugins/extra-shipping-options-woocommerce/ - с помощью него привязывал нужные мне поля, а также селекты к доставкам

Причём второй плагин можно в теории заменить вот этим, если способов доставки не много: https://shopplugins.com/plugins/advanced-checkout-fields-woocommerce/ - там вроде можно логику работы полей задавать
 

M0HAX

Новичок
Zoten Спасибо. Но загружать лишний раз плагинами тоже не айс... Вопрос то уперся всего лишь в строки вида:
$fields['billing']['billing_state_name']['required'] = false;
вот что там не так то?
 

M0HAX

Новичок
P.S. Или, как вариант, у меня блокируется это WooChekcout - ом?
Как оказалось - именно так!
Хак от yaspis абсолютно рабочий! Деактивация WooChekcout все расставило на свои места!
Но хочется все-таки еще "допилить" код для functions.php ... Чтобы исполнение хака отмены обязательных полей происходило только при выборе Самовывоз (local_pickup) ....
 

Otherdude

Новичок
Прикрутил к сайту скрипт (статья автора) который прячет поля. Если стоит чекбокс "Самовывоз" скрипт должен прятать поля адреса(в случае если заказывает гость вписывает в значение в поле, так как оно обязательно), а так же спрятано поле индекса до тех пор пока не выбран метод "Почта России". Индекс прячет и показывает, а вот если выбираю "Самовывоз" текст вставляет в поле, но не скрывает его. В чем может быть проблема, может кто сталкивался?
Код:
jQuery( 'body' ).on('updated_checkout', function () {//говорим, что при обновлении формы checkout надо дёрнуть нашу функцию
   var method = woocommerce_params.chosen_shipping_method;
      jQuery( 'select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]' ).each( function( index, input ) {
        method = jQuery( this ).val();
        } );
        switch (true) { //начинаем перебор вариантов и проверяем их
            case (method.indexOf('local_pickup:6') >= 0 ):  //если наш метод Самовывоз будем выполнять этот участок кода
                jQuery( '#billing_address_1_field, #billing_state_name_field, #billing_address_2_field, #billing_postcode_field, #billing_city_field').hide(); //Прячем адрес
                if (jQuery('#billing_address_1').val() === ''){ //если клиент не авторизован или у него нет адреса, нам что-то надо передать,т.к. поле адрес обязательное
                    jQuery('#billing_address_1').attr('value', 'Самовывоз'); //передадим туда строку "самовывоз"
                }
                break;
            case ( method.indexOf('free_shipping:15') >= 0 ): // если наш метод доставки ПОчта России
               jQuery( '#billing_address_1_field, #billing_state_name_field, #billing_address_2_field, #billing_postcode_field, #billing_city_field').show(); //Показываем все
                break;
            default: // во всех остальных случаях прячем Почтовый индекс
                jQuery('#billing_postcode_field').hide();
                jQuery( '#billing_address_1_field, #billing_address_2_field, #billing_state_name_field, #billing_city_field').show(); //Показываем всё кроме индекса   
                  }           
} );
Далее подключаю скрипт в файле функций шаблона:
Код:
add_action( 'wp_enqueue_scripts', 'hide_fields_script' );
function hide_fields_script() {
    wp_enqueue_script( 'hide_shipping_fields', get_template_directory_uri() . "/js/hide_shipping_fields.js", array( 'jquery' ), GENERATE_VERSION, true );

}
 
  • Like
Реакции: D&B

studnet

Новичок
Добрый день! Тоже мучаюсь с настройкой доставки. Есть самовывоз и доставка в городе за 200р. Магазин работает только в одном городе. Как сделать форму оформления заказа такой, чтобы Сначала шли поля - ФИО, телефон, email, затем выбор доставки. Если выбираем самовывоз, то отображается информация, откуда можно забрать товар. Если выбираем Доставка, то отображаются поля адреса. Заранее всем спасибо. Сайт можно глянуть - http://redmiuwt.beget.tech
 

rred

Новичок
Добрый день! Тоже мучаюсь с настройкой доставки. Есть самовывоз и доставка в городе за 200р. Магазин работает только в одном городе. Как сделать форму оформления заказа такой, чтобы Сначала шли поля - ФИО, телефон, email, затем выбор доставки. Если выбираем самовывоз, то отображается информация, откуда можно забрать товар. Если выбираем Доставка, то отображаются поля адреса. Заранее всем спасибо.
Поздравляю Вас, коллега, Вы изменили направление этой древней темы в нужное русло, т.к. правильно поставленный вопрос уже содержит в себе половину ответа.

Этой теме уже 4 года, прочитал её всю внимательно, как и ещё 100500 хаков по данному вопросу. И вот к чему пришёл. Проблема терзает людей до сих пор и все в едином порыве смотрят в сторону "магии jQuery". По всему выходит, что разработчики WooCommerce что-то недоработали или скоро доработают. Ведь блок с заказом и доставкой обновляется аяксом, а поля - нет. Значит, рано или поздно должны доработать. Ничего подобного, не должны и не доработают. Поскольку логика формы заказа цельная и здравая: сначала пользователь указывает кому и куда, а потом разбирается с доставкой и оплатой. При всём уважении к yaspis и действительно работающему методу, это костыль. А костыль - это не дело.

Посудите сами. Если у вас по умолчанию Самовывоз, пользователь пишет только ФИО и контакты. Далее он смотрит на варианты доставки, а там можно ещё и курьером. Он думает: "Хм.. а пусть будет лучше курьером". Он жмёт на "Курьерская доставка" и... тадам! Где-то там наверху появляются новые поля с адресом! Теперь пользователю надо к ним вернуться и заполнить. Если он их сразу заметит, конечно. Это неудобно, это нелогично. Пользователь не должен метаться туда-обратно, заполнение полей должно происходить строго в порядке их следования. И решение здесь может быть только одно: выбрав метод доставки, требующий дополнительных данных, пользователь должен увидеть их здесь же, сразу под названием выбранной доставки.

На самом деле, не нужно писать JavaScript, не нужно отключать обязательность полей, не нужно даже лезть в шаблоны. В WC уже всё есть, чтобы достаточно просто реализовать описанный товарищем studnet функционал.

Действительно:
1) Вывод дополнительной информации к методу доставки - событие woocommerce_after_shipping_rate
2) Отключение ненужных полей - фильтр woocommerce_checkout_fields
3) Получить текущий выбранный метод доставки - WC()->session->get( 'chosen_shipping_methods' );
4) Вывод полей начинается с woocommerce_before_checkout_form и заканчивается woocommerce_after_checkout_form
5) Отображение итогов корзины, соответственно - woocommerce_before_cart_totals и woocommerce_after_cart_totals
6) Поле отображается на странице функцией woocommerce_form_field

Это всё, что нам нужно, остальное - дело техники. Приведённый ниже код можно скопировать в functions.php вашей темы и он сразу работает. Должен, во всяком случае (WooCommerce 3.4.4). Для тестирования у вас должно быть два метода доставки "Единая ставка" (flat_rate) и "Самовывоз" (local_pickup). Для первого метода будут показаны поля адреса, а для второго - индекс. Это для теста, настройка вся вынесена в функцию "get_shipping_method_fields()". В ней вы можете указывать как метод доставки в формате "flat_rate", так и выделить конкретный метод: "flat_rate:5". Работает и так и эдак.


Код:
/**
* Настройка привязки полей к методам доставки.
*
* Функция возвращает массив полей заказа, которые актуальны
* только для указанных методов доставки и неприменимы для других методов.
*
* Указанные в массиве поля не будут отображаться в стандартных блоках оплаты и доставки.
* Вместо этого они будут выведены после наименования метода доставки
* и только когда он выбран.
*
* Если к определённому виду доставки привязано обязательное поле, но
* выбрана другая доставка, проблем с валидацией не будет, поскольку
* в этом случае поле исключается из обрабатываемых полей стандартным способом.
*
* Массив двумерный: поля сгруппированы по блокам, в соответствии с документацией
* https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/#section-2
*
* Например, как сделать, чтобы поля адреса были применимы
* только к методу доставки "Единая ставка":
*
       return array(
         'billing' => array(
             'billing_address_1' => array( 'flat_rate' ),
             'billing_address_2' => array( 'flat_rate' )
         )
       );
*/
function get_shipping_method_fields() {
    return array(
        'billing' => array(
            'billing_address_1' => array( 'flat_rate' ),
            'billing_address_2' => array( 'flat_rate' ),
            'billing_postcode' => array( 'local_pickup' ),
        )
    );
}
/**
* Проверяет наличие метода доставки в формате типа 'flat_rate:3'
* в массиве методов доставки (method_id - в формате типа 'flat_rate' )
*
* @param type $chosen_shipping
* @param type $methods
* @return type
*/
function in_methods_array($chosen_shipping_id, $method_ids)
{
    $found = FALSE;
    $i = 0;
    $count = count($method_ids);
    while ( !$found && ( $i < $count ) ){
        $method_id = $method_ids[$i];
        $found = ( strpos($chosen_shipping_id, $method_id) !== FALSE );
        $i++;
    }
    return $found;
}

/**
* Скрыть в корзине и блоках оплаты и доставки поля,
* которые имеют привязку к методам доставки.
* Установленная переменная используется в фильтре woocommerce_checkout_fields
*/
add_action('woocommerce_before_cart_totals',  'smf_before_checkout_form');
add_action('woocommerce_before_checkout_form',  'smf_before_checkout_form');
function smf_before_checkout_form(){
       set_query_var( 'smf_hide_fields', TRUE );
}
add_action('woocommerce_after_checkout_form',  'smf_after_checkout_form');
add_action('woocommerce_after_cart_totals',  'smf_after_checkout_form');
function smf_after_checkout_form(){
       set_query_var( 'smf_hide_fields', FALSE );
}

/**
* Отключить неприменимые к текущему методу доставки поля.
* Или отключить всё поля, привязанные к методам доставки,
* если идёт вывод checkout_form
*/
add_filter('woocommerce_checkout_fields', 'smf_remove_checkout_fields');
function smf_remove_checkout_fields($fields) {
    $smf_fields = get_shipping_method_fields();
    if ( !empty( $smf_fields ) ){
        $hideall = get_query_var('smf_hide_fields') === TRUE;
        $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
        $chosen_shipping_id = $chosen_methods[0];
        foreach ( $fields as $fieldset => $fieldlist ) {
            if ( key_exists( $fieldset, $smf_fields ) ) {
                foreach ( $fieldlist as $fieldkey => $field ) {
                    if ( key_exists($fieldkey, $smf_fields[$fieldset] ) ){

                        $method_ids = $smf_fields[$fieldset][$fieldkey];
                        if ( $hideall || !in_methods_array($chosen_shipping_id, $method_ids) ){

                            unset( $fields[$fieldset][$fieldkey] );

                        }
                    }
                }
            }
        }
    }
   
    return $fields;
}

/**
*  Вывести поля для метода доставки, если он выбран в данный момент
*/
add_action('woocommerce_after_shipping_rate', 'smf_after_shipping_rate');
function smf_after_shipping_rate( $method ) {
    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_shipping_id = $chosen_methods[0];

    $smf_fields = get_shipping_method_fields();
    if ( !empty( $smf_fields ) ){

        // это выбранный метод доставки?
        if ( strpos($chosen_shipping_id, $method->id) !== FALSE ){
           
            $checkout = WC()->checkout;
            foreach ($smf_fields as $fieldset => $fieldlist) {
                $allfields = $checkout->get_checkout_fields( $fieldset );
                $fieldkeys = array_keys($fieldlist);
                foreach ( $allfields as $fieldkey => $field ) {
                    $method_ids = $smf_fields[$fieldset][$fieldkey];
                    if (
                            in_array($fieldkey, $fieldkeys) &&
                            in_methods_array($chosen_shipping_id, $method_ids)
                       )
                    {
                        woocommerce_form_field( $fieldkey, $field, $checkout->get_value( $fieldkey ) );
                    }
                }
               
            }
        }
    }
}
 
Последнее редактирование:

roman001

Новичок
Поздравляю Вас, коллега, Вы изменили направление этой древней темы в нужное русло, т.к. правильно поставленный вопрос уже содержит в себе половину ответа.

Этой теме уже 4 года, прочитал её всю внимательно, как и ещё 100500 хаков по данному вопросу. И вот к чему пришёл. Проблема терзает людей до сих пор и все в едином порыве смотрят в сторону "магии jQuery". По всему выходит, что разработчики WooCommerce что-то недоработали или скоро доработают. Ведь блок с заказом и доставкой обновляется аяксом, а поля - нет. Значит, рано или поздно должны доработать. Ничего подобного, не должны и не доработают. Поскольку логика формы заказа цельная и здравая: сначала пользователь указывает кому и куда, а потом разбирается с доставкой и оплатой. При всём уважении к yaspis и действительно работающему методу, это костыль. А костыль - это не дело.

Посудите сами. Если у вас по умолчанию Самовывоз, пользователь пишет только ФИО и контакты. Далее он смотрит на варианты доставки, а там можно ещё и курьером. Он думает: "Хм.. а пусть будет лучше курьером". Он жмёт на "Курьерская доставка" и... тадам! Где-то там наверху появляются новые поля с адресом! Теперь пользователю надо к ним вернуться и заполнить. Если он их сразу заметит, конечно. Это неудобно, это нелогично. Пользователь не должен метаться туда-обратно, заполнение полей должно происходить строго в порядке их следования. И решение здесь может быть только одно: выбрав метод доставки, требующий дополнительных данных, пользователь должен увидеть их здесь же, сразу под названием выбранной доставки.

На самом деле, не нужно писать JavaScript, не нужно отключать обязательность полей, не нужно даже лезть в шаблоны. В WC уже всё есть, чтобы достаточно просто реализовать описанный товарищем studnet функционал.

Действительно:
1) Вывод дополнительной информации к методу доставки - событие woocommerce_after_shipping_rate
2) Отключение ненужных полей - фильтр woocommerce_checkout_fields
3) Получить текущий выбранный метод доставки - WC()->session->get( 'chosen_shipping_methods' );
4) Вывод полей начинается с woocommerce_before_checkout_form и заканчивается woocommerce_after_checkout_form
5) Отображение итогов корзины, соответственно - woocommerce_before_cart_totals и woocommerce_after_cart_totals
6) Поле отображается на странице функцией woocommerce_form_field

Это всё, что нам нужно, остальное - дело техники. Приведённый ниже код можно скопировать в functions.php вашей темы и он сразу работает. Должен, во всяком случае (WooCommerce 3.4.4). Для тестирования у вас должно быть два метода доставки "Единая ставка" (flat_rate) и "Самовывоз" (local_pickup). Для первого метода будут показаны поля адреса, а для второго - индекс. Это для теста, настройка вся вынесена в функцию "get_shipping_method_fields()". В ней вы можете указывать как метод доставки в формате "flat_rate", так и выделить конкретный метод: "flat_rate:5". Работает и так и эдак.


Код:
/**
* Настройка привязки полей к методам доставки.
*
* Функция возвращает массив полей заказа, которые актуальны
* только для указанных методов доставки и неприменимы для других методов.
*
* Указанные в массиве поля не будут отображаться в стандартных блоках оплаты и доставки.
* Вместо этого они будут выведены после наименования метода доставки
* и только когда он выбран.
*
* Если к определённому виду доставки привязано обязательное поле, но
* выбрана другая доставка, проблем с валидацией не будет, поскольку
* в этом случае поле исключается из обрабатываемых полей стандартным способом.
*
* Массив двумерный: поля сгруппированы по блокам, в соответствии с документацией
* https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/#section-2
*
* Например, как сделать, чтобы поля адреса были применимы
* только к методу доставки "Единая ставка":
*
       return array(
         'billing' => array(
             'billing_address_1' => array( 'flat_rate' ),
             'billing_address_2' => array( 'flat_rate' )
         )
       );
*/
function get_shipping_method_fields() {
    return array(
        'billing' => array(
            'billing_address_1' => array( 'flat_rate' ),
            'billing_address_2' => array( 'flat_rate' ),
            'billing_postcode' => array( 'local_pickup' ),
        )
    );
}
/**
* Проверяет наличие метода доставки в формате типа 'flat_rate:3'
* в массиве методов доставки (method_id - в формате типа 'flat_rate' )
*
* @param type $chosen_shipping
* @param type $methods
* @return type
*/
function in_methods_array($chosen_shipping_id, $method_ids)
{
    $found = FALSE;
    $i = 0;
    $count = count($method_ids);
    while ( !$found && ( $i < $count ) ){
        $method_id = $method_ids[$i];
        $found = ( strpos($chosen_shipping_id, $method_id) !== FALSE );
        $i++;
    }
    return $found;
}

/**
* Скрыть в корзине и блоках оплаты и доставки поля,
* которые имеют привязку к методам доставки.
* Установленная переменная используется в фильтре woocommerce_checkout_fields
*/
add_action('woocommerce_before_cart_totals',  'smf_before_checkout_form');
add_action('woocommerce_before_checkout_form',  'smf_before_checkout_form');
function smf_before_checkout_form(){
       set_query_var( 'smf_hide_fields', TRUE );
}
add_action('woocommerce_after_checkout_form',  'smf_after_checkout_form');
add_action('woocommerce_after_cart_totals',  'smf_after_checkout_form');
function smf_after_checkout_form(){
       set_query_var( 'smf_hide_fields', FALSE );
}

/**
* Отключить неприменимые к текущему методу доставки поля.
* Или отключить всё поля, привязанные к методам доставки,
* если идёт вывод checkout_form
*/
add_filter('woocommerce_checkout_fields', 'smf_remove_checkout_fields');
function smf_remove_checkout_fields($fields) {
    $smf_fields = get_shipping_method_fields();
    if ( !empty( $smf_fields ) ){
        $hideall = get_query_var('smf_hide_fields') === TRUE;
        $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
        $chosen_shipping_id = $chosen_methods[0];
        foreach ( $fields as $fieldset => $fieldlist ) {
            if ( key_exists( $fieldset, $smf_fields ) ) {
                foreach ( $fieldlist as $fieldkey => $field ) {
                    if ( key_exists($fieldkey, $smf_fields[$fieldset] ) ){

                        $method_ids = $smf_fields[$fieldset][$fieldkey];
                        if ( $hideall || !in_methods_array($chosen_shipping_id, $method_ids) ){

                            unset( $fields[$fieldset][$fieldkey] );

                        }
                    }
                }
            }
        }
    }
 
    return $fields;
}

/**
*  Вывести поля для метода доставки, если он выбран в данный момент
*/
add_action('woocommerce_after_shipping_rate', 'smf_after_shipping_rate');
function smf_after_shipping_rate( $method ) {
    $chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
    $chosen_shipping_id = $chosen_methods[0];

    $smf_fields = get_shipping_method_fields();
    if ( !empty( $smf_fields ) ){

        // это выбранный метод доставки?
        if ( strpos($chosen_shipping_id, $method->id) !== FALSE ){
         
            $checkout = WC()->checkout;
            foreach ($smf_fields as $fieldset => $fieldlist) {
                $allfields = $checkout->get_checkout_fields( $fieldset );
                $fieldkeys = array_keys($fieldlist);
                foreach ( $allfields as $fieldkey => $field ) {
                    $method_ids = $smf_fields[$fieldset][$fieldkey];
                    if (
                            in_array($fieldkey, $fieldkeys) &&
                            in_methods_array($chosen_shipping_id, $method_ids)
                       )
                    {
                        woocommerce_form_field( $fieldkey, $field, $checkout->get_value( $fieldkey ) );
                    }
                }
             
            }
        }
    }
}

Если честно то нечего не понял, что нужно сделать что бы реализовать то, что вы написали.
Если можно поэтапно- куда зайти в админке, что переключить, куда добавить.

P/S
У меня созданы два способа доставки:
самовывоз и фиксированная.
Далее я скопировал ваш код в functions.php
В блоке самовывоза появился обязательный пункт ИНДЕКС (вопрос как это убрать и что бы там был ФИО, номер телефона и емаил?)
Прошу не кидать в меня тапками. И можно все таки убрать сверху обязательные поля адреса со страницы самовывоза?
 
Последнее редактирование:

rred

Новичок
Если честно то нечего не понял, что нужно сделать что бы реализовать то, что вы написали.
Если можно поэтапно- куда зайти в админке, что переключить, куда добавить.

P/S
У меня созданы два способа доставки:
самовывоз и фиксированная.
Далее я скопировал ваш код в functions.php
Но НИЧЕГО не изменилось.
Поля для двух этих способов как были одинаковыми, так и остались.
Прошу не кидать в меня тапками.
Добрый вечер, без проблем, давайте возьмём простой пример на стандартных методах и полях.
1. В админке: WooCommerce - Настройки - Доставка - Зоны доставки - Добавить зону доставки:
1.1. Название зоны: Россия
1.2. Зоны: Россия
1.3. Методы доставки - Добавить метод доставки
1.3.1. "Единая ставка"
1.3.2. "Самовывоз"
1.4. Кнопка "Сохранить изменения"
2. Добавить приведенный код в functions.php
3. На сайте набрать товар в корзину и перейти к Оформлению заказа

Что должно измениться в результате добавления приведённого кода в functions.php.
Если раньше на странице оформления заказа все поля выводились общим строем в разделе "Оплата и доставка" или "Детали оплаты", то
теперь из общего списка полей должны исчезнуть:
1. Две строки для Адреса
2. Почтовый индекс

Вместо этого:
1. Когда выбрана доставка "Единая ставка", сразу под ней выводятся два поля адреса
2. Если выбрать доставку "Самовывоз", то поля для Адреса под "Единой ставкой" пропадают, а под Самовывозом появляется Почтовый индекс.

Чтобы указать, какие поля и для какой доставки надо показывать в вашем случае, редактируем функцию
get_shipping_method_fields из приведенного кода.

В моём случае это настроено так:
Оформление заказа.png

Оформление заказа 1.png


Если что непонятно, спрашивайте.
 

rred

Новичок
Да, ещё в админке:
WooCommerce - Настройки - Основные
Торговая точка(и): Продавать в определенные страны
Продавать в определенные страны: Россия
 

roman001

Новичок
Да, ещё в админке:
WooCommerce - Настройки - Основные
Торговая точка(и): Продавать в определенные страны
Продавать в определенные страны: Россия
Спасибо большое, немного разобрался но осталась главная проблема - как убрать не нужные поля из самовывоза?

Вот скрин, там стрелками указал:


Clip2net_180805003139.png

С уважением Роман
 

rred

Новичок
В блоке самовывоза появился обязательный пункт ИНДЕКС (вопрос как это убрать и что бы там был ФИО, номер телефона и емаил?)

Открываем functions.php, куда Вы добавили приведённый ранее код и ищем в самом начале этого кода следующую функцию:
Код:
function get_shipping_method_fields() {
    return array(
        'billing' => array(
            'billing_address_1' => array( 'flat_rate' ),
            'billing_address_2' => array( 'flat_rate' ),
            'billing_postcode' => array( 'local_pickup' ),
        )
    );
}

Чтобы в самовывозе было ФИО, номер телефона и емаил, эта функция должна выглядеть так:

Код:
function get_shipping_method_fields() {
    return array(
        'billing' => array(
            'billing_first_name ' => array( 'local_pickup' ),
            'billing_last_name ' => array( 'local_pickup' ),
            'billing_phone ' => array( 'local_pickup' ),
            'billing_email ' => array( 'local_pickup' )
        )
    );
}
 
Последнее редактирование:
Сверху Снизу