WooCommerce 结帐期间多个自定义字段产生的额外费用

问题描述 投票:0回答:1

我在我的网站上添加了一些自定义字段,这些字段显示在结帐中。这是关于夏令营的儿童注册。

它们是选择字段:

function person_details( $checkout ) {
    global $woocommerce;

    $count = $woocommerce->cart->cart_contents_count;
    $i = 0;

    for( $k=1; $k<= $count; $k++ ) {
        $i++;
        
        print ('<h3>Gegevens van kind #'.$i.'</h3>');

        woocommerce_form_field( 'cstm_care'.$i, array(
            'type'                       => 'select',
            'required'                   => true,
            'class'                      => array( 'my-field-class form-row-last' ),
            'label'                      => __( 'Voor- en na zorg' ),
            'options'                    => array(
                    'Geen'                   => __( 'Geen', 'njengah' ),
                    'Voorzorg'               => __( 'Pre-care (€30)', 'njengah' ),
                    'Nazorg'                 => __( 'Aftercare (€30)', 'njengah' ),
                    'Voor- en na zorg'       => __( 'Pre- & Aftercare (€50)', 'njengah' )
        )), $checkout->get_value( 'cstm_care'.$i ));
    }
}

我想根据所选选项更改结账时的总数:

  • 前期护理(30 欧元)
  • 善后护理(30欧元)
  • 术前和术后护理(50 欧元)

我怎样才能实现这个目标?还可能吗?

php jquery ajax session woocommerce
1个回答
0
投票

它需要使用 WooCommerce 会话、JavaScript 和 Ajax,根据所选选项设置计算费用。

尝试以下操作:

// Utility function 
function get_care_data( $type ) {
    if ( $type === 'options' ) {
        // Return options for the select fields
        return array(
            'geen'      => __( 'Geen', 'woocommerce' ),
            'voorzorg'  => __( 'Voorzorg (€30)', 'woocommerce' ),
            'nazorg'    => __( 'Nazorg (€30)', 'woocommerce' ),
            'beide'     => __( 'Voor- en nazorg (€50)', 'woocommerce' ),
        );
    } else {
        // Return pricing by option
        return array(
            'geen'      => 0,
            'voorzorg'  => 30,
            'nazorg'    => 30,
            'beide'     => 50,
        );
    }
}

// Display fields
add_action( 'woocommerce_after_order_notes', 'display_custom_select_fields' );
function display_custom_select_fields( $checkout ) {
    $count = WC()->cart->get_cart_contents_count();

    for( $i = 1; $i <= $count; $i++ ) {
        echo '<h3>' . esc_html__('Gegevens van kind', 'woocommerce') . ' #' . $i . '</h3>';

        woocommerce_form_field( 'cstm_care'.$i, array(
            'type'      => 'select',
            'class'     => array('form-row-wide'),
            'label'     => esc_html__('Voor- en nazorg', 'woocommerce'),
            'required'  => true,
            'options'   => get_care_data('options'),
        ) );
    }
}

// Javascript / Ajax
add_action( 'woocommerce_checkout_init', 'checkout_care_js' );
function checkout_care_js() {
    $count = WC()->cart->get_cart_contents_count();

    wc_enqueue_js("if (typeof wc_checkout_params === 'undefined') {
        return false;
    }
    
    function processCare( index, selectedValue ) {
        $.ajax({
            type: 'POST',
            url: wc_checkout_params.ajax_url,
            data: {
                'action': 'get_selected_care',
                'field_index': index,
                'selected_care': selectedValue
            },
            success: function (response) {
                $(document.body).trigger('update_checkout');
            }
        });
    }
    
    for( let i = 1; i <= {$count}; i++ ) {
        $('#cstm_care'+i).on('change', function() {
            processCare( i, $(this).val() );
        });
    }");
}

// Get Ajax request and saving selected values to a WC Session variable
add_action( 'wp_ajax_get_selected_care', 'set_selected_care_to_wc_session' );
add_action( 'wp_ajax_nopriv_get_selected_care', 'set_selected_care_to_wc_session' );
function set_selected_care_to_wc_session() {
    if ( isset($_POST['field_index']) && isset($_POST['selected_care']) ) {
        $care_data = (array) WC()->session->get('care_data');

        $care_data[intval($_POST['field_index'])] = esc_attr($_POST['selected_care']);

        WC()->session->set('care_data', $care_data);
    }
    wp_die();
}

// Add a calculated fee based on selected options
add_action( 'woocommerce_cart_calculate_fees','add_cumulated_care_fees', 10 );
function add_cumulated_care_fees( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }

    if ( is_checkout() && !is_wc_endpoint_url() ) {
        $care_data  = (array) WC()->session->get('care_data');
        $care_costs = get_care_data('costs');
        $fees_total = 0;

        // Loop through selected care data
        foreach ( $care_data as $selected_care ) {
            $fees_total += $care_costs[$selected_care]; // Sum the cost of each selected care option
        }

        if( $fees_total > 0 ) {
            $cart->add_fee( esc_html__('Care fees'), $fees_total, false ); // Add the calculated fee
        } 
    }
}

// Save the selected care data in a multi-dimensional array (optional)
add_action('woocommerce_checkout_create_order', 'save_custom_select_fields_values', 22, 2 );
function save_custom_select_fields_values( $order, $data ) {
    $items_count = WC()->cart->get_cart_contents_count();
    $selected_care_data = array('count' => $items_count);

    // Loop through care fields
    for( $i = 1; $i <= $items_count; $i++ ) {
        if ( isset($_POST['cstm_care'.$i]) ) {
            $selected_care_data['fields'][$i] = esc_attr($_POST['cstm_care'.$i]); // Add each selected option
        }
    }
    $order->update_meta_data( '_care_options', $selected_care_data ); // save data
}

代码位于子主题的functions.php 文件中(或插件中)。已测试并有效。

© www.soinside.com 2019 - 2024. All rights reserved.