Изменение ставки налога на товары в кассе WooCommerce с помощью переключателей - PullRequest
4 голосов
/ 01 августа 2020

В WooCommerce я использую плагин [WooCommerce checkout addon] [1] и добавил на страницу оформления заказа дополнительное поле, состоящее из переключателей (множественный выбор). Я хотел бы изменить ставку налога, когда клиент выбирает конкретный вариант c в этом поле переключателей.

На основе Изменить налоговый класс товаров корзины Woocommerce в зависимости от выбранного метода оплаты код ответа, который изменяет налоговую ставку для указанного c способа оплаты, я пытался настроить код:

// Change Tax
add_action( 'woocommerce_before_calculate_totals', 'change_tax_class_based_on_radio_choice', 10, 1 );
function change_tax_class_based_on_radio_choice( $cart ) {
    $installation = WC()->session->get('wc_checkout_add_ons') ; // This code must be change 
    $value = 'pas-dinstallation' ; // the value of the radio button "woocommerce checkout addon" 
    $value2 = 'bacs' ; // value of payement methode
    $payement_methode = WC()->session->get('chosen_payment_method') ;
    //if ( $payement_methode !== $value2 ) //this one is ok for change tax if payement methode is bank transfert
        //return;
    if ( $installation !== $value ) // here i try to set the same condition with one of radio button "woocommerce checkout addon" 
    

    return;
    
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Loop through cart items
    foreach( $cart->get_cart() as $cart_item ){
        // We set "Zero rate" tax class
        $cart_item['data']->set_tax_class("Reduced rate");
    }
}

add_action('wp_footer', 'option_trigger_update_checkout');
function option_trigger_update_checkout() {
    if( is_checkout() && ! is_wc_endpoint_url() ) :
    ?>
    <script type="text/javascript">
        jQuery(function($){
            $( 'form.checkout' ).on('change', 'input[type="radio"]', function() {
                $(document.body).trigger('update_checkout');
            });
        });
    </script>
    <?php
    endif;
}

Но я еще не знаю, как заставить его работать в моем случае . Я понимаю, что:

$installation = WC()->session->get('wc_checkout_add_ons')

плохо реализовано. Что мне не хватает?

Обновление - добавление (связано с ответом ниже) :

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

// Only for a specific defined payment method
if ( ! in_array( WC()->session->get('chosen_payment_method'), $payment_ids ) )
    return;

Тогда код работает действительно хорошо, как я и ожидал.

Однако с плагином «WooCommerce checkout addon», когда выбран переключатель, я могу видеть в администрировании в краткое изложение заказа и в полученном электронном письме, какой выбор был сделан.

с этим кодом налог меняется, но у меня нет информации о выборе радио клиентом в админке или по электронной почте.

Есть ли решение?

Что-то еще:

Я хочу переместить переключатели перед оплатой.

Но когда я заменяю это:

// Display radio buttons field (optional)
add_action( 'woocommerce_after_order_notes', 'installation_custom_radio_field' );
function installation_custom_radio_field( $checkout ) {

на

// Display radio buttons field (optional)
add_action( 'woocommerce_review_order_before_payment', 'installation_custom_radio_field' );
function installation_custom_radio_field( $checkout ) {

Больше не работает Вы можете объяснить почему? Как заставить работать?

1 Ответ

2 голосов
/ 01 августа 2020

Обновление 2: Заставить его работать гораздо сложнее, поскольку для этого требуется также Ajax и многое другое…

Таким образом, следующее позволит изменить налоговый класс товаров тележки на странице оформления заказа, в зависимости от:

  • (необязательно) Выбранный платежный шлюз (здесь он отключен с пустым массивом).
  • Выбранное значение переключателя (из настраиваемых переключателей) .

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

Чтобы сделать код больше динамики c, мы начинаем с пользовательской функции, которая будет обрабатывать все необходимые настройки:

// Custom function that handle your settings
function change_tax_class_settings(){
    return array(
        'payment_ids'   => array(), // (optional) Your targeted payment method Id(s) | Leave an empty array to disable.
        'tax_class'     => 'Reduced rate', // The desired tax rate
        'field_id'      => 'additonal_services', // the Field Id (from property name ="?????")
        'field_value'   => 'no-dinstallation', // The field targetted option key (value)

        // The below lines are optional (used for the radio buttons field display)
        'field_type'    => 'radio', // Field type
        'field_title'   =>  __('Additional services', 'woocommerce'),
        'field_default' => 'basic-installation', // The field targetted option key (value)
        'field_options' => array(
            'basic-installation' => __('Basic Installation', 'woocommerce'),
            'premium-installation' => __('Premium Installation', 'woocommerce'),
            'no-dinstallation' => __('No Installation', 'woocommerce'),
        ),
    );
}

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

Затем переключатели отображаются перед разделом проверки способов оплаты:

// Display radio buttons field (optional)
add_action( 'woocommerce_review_order_before_payment', 'installation_custom_radio_field' );
function installation_custom_radio_field() {
    extract( change_tax_class_settings() ); // Load settings and convert them in variables

    echo "<style>.$field_id-wrapper{padding:1em 1.41575em;background-color:#f5f5f5;margin-bottom:24px;}
    .form-row.$field_id-$field_type span label{display:inline-block;margin:0 18px 0 6px;}
    .$field_id-wrapper h3{font-weight:bold;}</style>";
    echo '<div class="'.$field_id.'-wrapper">
    <h3>'.$field_title.'</h3>';

    // Get WC Session variable value
    $value = WC()->session->get($field_id);

    woocommerce_form_field( $field_id, array(
        'type'     => $field_type,
        'label'    => '',
        'class'    => array('form-row-wide ' . $field_id . '-' . $field_type ),
        'options'  => $field_options,
        'default'  => $field_default,
        'required' => true,
    ), empty($value) ? WC()->checkout->get_value('_'.$field_id) : $value );

    echo '</div>';
}

enter image description here


The Ajax Part (jQuery Ajax and PHP Admin Wordpress Ajax sender and receiver + WC Session variable):

// jQuery code (client side) - Ajax sender
add_action('wp_footer', 'installation_checkout_js_script');
function installation_checkout_js_script() {
    if( is_checkout() && ! is_wc_endpoint_url() ) :
    // Load settings and convert them in variables
    extract( change_tax_class_settings() );

    // jQuery Ajax code
    ?>
     jQuery (function ($) {if (typeof wc_checkout_params === 'undefined') return ложь; var field = '# _field input ', fchecked = field +': checked '; // Функция, которая отправляет Ajax запрос, функция sendAjaxRequest (value) {$. ajax ({type: 'POST', url: wc_checkout_params.ajax_url, data: {'action': ' ',' значение ': значение}, успех: функция (результат) {$ (document.body) .trigger (' update_checkout '); // Refre sh checkout}}); } // По готовности (DOM загружен) sendAjaxRequest ($ (fchecked) .val ()); // При событии изменения $ (document.body) .on ('change', field, function () {sendAjaxRequest ($ (fchecked) .val ());}); // Refre sh проверка при изменении способа оплаты $ ('form.checkout') .on ('change', 'input [name = "payment_method"]', function () {$ (document.body) .trigger ( 'update_checkout'); // Refre sh checkout}); });  сессия-> установить ($ field_id, esc_attr ($ _ POST ['значение'])); // Отправляем данные обратно в javascript (json в кодировке) echo $ _POST ['value']; // необязательно d ie (); }} 

Затем функция, которая изменяет налоговый класс элемента корзины условно в зависимости от выбора покупателя:

// Change the tax class conditionally
add_action( 'woocommerce_before_calculate_totals', 'change_tax_class_conditionally', 1000 );
function change_tax_class_conditionally( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    extract( change_tax_class_settings() ); // Load settings and convert them in variables

    // Only for a specific defined payment methods (can be disabled in the settings, with an empty array)
    if ( ! empty($payment_ids) && ! in_array( WC()->session->get('chosen_payment_method'), $payment_ids ) )
        return;

    $choice = WC()->session->get($field_id);

    // Loop through cart items
    foreach( $cart->get_cart() as $cart_item ){
        if( $choice === $field_value ) {
            $cart_item['data']->set_tax_class($tax_class);
        }
    }
}

Дополнение: Сохранение выбора клиента в заказ и отображение этого повсюду в заказах во внешнем интерфейсе, администраторе и в уведомлениях по электронной почте:

// Save custom field as order meta data
add_action( 'woocommerce_checkout_create_order', 'save_additonal_services_as_order_meta' );
function save_additonal_services_as_order_meta( $order ) {
    // Load settings and convert them in variables
    extract( change_tax_class_settings() );

    $choice = WC()->session->get($field_id);

    if( ! empty( $choice ) ) {
        $order->update_meta_data( '_'.$field_id, $choice );
    }
}

// Display additonal services choice before payment method everywhere (orders and emails)
add_filter( 'woocommerce_get_order_item_totals', 'display_additonal_services_on_order_item_totals', 1000, 3 );
function display_additonal_services_on_order_item_totals( $total_rows, $order, $tax_display ){
    // Load settings and convert them in variables
    extract( change_tax_class_settings() );

    $choice = $order->get_meta( '_'.$field_id ); // Get additonal services choice

    if( ! empty($choice) ) {
        $new_total_rows = [];

        // Loop through order total rows
        foreach( $total_rows as $key => $values ) {
            // Inserting the pickp store under shipping method
            if( $key === 'payment_method' ) {
                $new_total_rows[$field_id] = array(
                    'label' => $field_title,
                    'value' => esc_html($field_options[$choice]),
                );
            }
            $new_total_rows[$key] = $values;
        }
        return $new_total_rows;
    }
    return $total_rows;
}


// Display additonal services choice in Admin order pages
add_action( 'woocommerce_admin_order_data_after_billing_address', 'admin_order_display_additonal_services', 1000 );
function admin_order_display_additonal_services( $order ) {
    // Load settings and convert them in variables
    extract( change_tax_class_settings() );

    $choice = $order->get_meta( '_'.$field_id ); // Get additonal services choice

    if( ! empty($choice) ) {
        // Display
        echo '<p><strong>' . $field_title . '</strong>: ' . $field_options[$choice] . '</p>';
    }
}

Весь код работает. php файл вашей активной дочерней темы (или темы). Проверено и работает.

Отображаемый выбор в заказах и уведомлениях по электронной почте (здесь, на странице полученного заказа)

enter image description here


On Admin Single Orders pages:

введите описание изображения здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...