programing

라디오 버튼을 기준으로 WooCommerce 체크아웃에서 항목 세율 변경

oldcodes 2023. 10. 21. 10:49
반응형

라디오 버튼을 기준으로 WooCommerce 체크아웃에서 항목 세율 변경

WooCommerce에서 저는 플러그인 [WooCommerce 체크아웃 애드온][1]을 사용하고 체크아웃 페이지에 라디오 버튼(복수 선택)으로 구성된 필드를 추가했습니다.고객이 해당 라디오 버튼 필드에서 특정 옵션을 선택하면 세율을 변경하고 싶습니다.

Change Woocommerce 카트 아이템 세금 클래스 특정 결제수단에 대한 세율을 변경하는 선택된 결제수단 답변 코드에 기반하여 코드를 커스터마이징하려고 노력했습니다.

// 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 체크아웃 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 ) {

더 이상 작동이 안 돼요.왜 그런지 설명해 주실래요?어떻게 하면 될까요?

업데이트 2: Ajax와 훨씬 더 많은 코드가 필요하기 때문에 작동시키기가 훨씬 더 복잡합니다.

따라서 다음 내용을 통해 체크아웃 페이지의 카트 항목 세금 클래스를 다음에 따라 변경할 수 있습니다.

  • (선택사항)선택한 결제 게이트웨이(여기서는 빈 배열로 비활성화됨).
  • 선택한 라디오 버튼 값(사용자 지정 라디오 버튼에서).

사용자가 WooCommerce 체크아웃 Add-ons 상용 플러그인을 사용하지 않기 때문에 아래 코드는 체크아웃 페이지에 일부 라디오 버튼을 표시합니다.

코드를 보다 역동적으로 만들기 위해 필요한 모든 설정을 처리하는 사용자 지정 기능부터 시작합니다.

// 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


Ajax Part(jQuery Ajax PHP Admin Wordpress Ajax 송신자수신자 + WC Session 변수):

// 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
    ?>
    <script type="text/javascript">
    jQuery( function($){
        if (typeof wc_checkout_params === 'undefined')
            return false;

        var field = '#<?php echo $field_id; ?>_field input', fchecked = field+':checked';

        // Function that sen the Ajax request
        function sendAjaxRequest( value ) {
            $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: {
                    'action': '<?php echo $field_id; ?>',
                    'value': value
                },
                success: function (result) {
                    $(document.body).trigger('update_checkout'); // Refresh checkout
                }
            });
        }

        // On ready (DOM loaded)
        sendAjaxRequest( $(fchecked).val() );

        // On change event
        $(document.body).on( 'change', field, function(){
            sendAjaxRequest( $(fchecked).val() );
        });

        // Refresh checkout on payment method change
        $( 'form.checkout' ).on('change', 'input[name="payment_method"]', function() {
            $(document.body).trigger('update_checkout'); // Refresh checkout
        });
    });
    </script>
    <?php
    endif;
}

// The Wordpress Ajax PHP receiver
add_action( 'wp_ajax_additonal_services', 'get_additonal_services' );
add_action( 'wp_ajax_nopriv_additonal_services', 'get_additonal_services' );
function get_additonal_services() {
    if ( isset($_POST['value']) ){
        // Load settings and convert them in variables
        extract( change_tax_class_settings() );

        // Update session variable
        WC()->session->set($field_id, esc_attr($_POST['value']));

        // Send back the data to javascript (json encoded)
        echo $_POST['value']; // optional
        die();
    }
}

그러면 고객의 선택에 따라 카트 항목 세금 클래스를 조건부로 변경하는 기능:

// 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


관리 단일 주문 페이지에서:

enter image description here

언급URL : https://stackoverflow.com/questions/63204952/change-items-tax-rate-in-woocommerce-checkout-based-on-radio-buttons

반응형