如果在WooCommerce Checkout中选中自定义复选框,则删除运费

时间:2018-01-08 18:56:47

标签: php jquery ajax woocommerce shipping

如果选中结帐字段中的复选框,我会尝试将运费价格设置为0.00美元。

当前尝试:

function no_shipping_for_own_ups($rates,$package) {
    foreach ($rates as $rate) {
        //Set the price
        $rate->cost = 0;
    }
    return $rates;
}

function woo_add_cart_ups_y_n_fee( $cart ){
    if ( ! $_POST || ( is_admin() && ! is_ajax() ) ) {
        return;
    }

    if ( isset( $_POST['post_data'] ) ) {
        parse_str( $_POST['post_data'], $post_data );
    } else {
        $post_data = $_POST;
    }

    if (isset($post_data['billing_ups_yn'])) {
        add_filter( 'woocommerce_package_rates','no_shipping_for_own_ups', 99, 2 );
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_ups_y_n_fee', 43, 1 );

由于$post_data['billing_ups_yn']是我设置为在触发时更新结帐的复选框。

如果选中该复选框,则应用过滤器将运费率设置为0 然而,这不起作用。

2 个答案:

答案 0 :(得分:1)

要在结帐页面中通过ajax对自定义javascript事件更改送货方式费用,这比有条件地更改费用或其他任何内容更加复杂,如下所示。

要存储ajax数据,我使用WC_Sessions并更改送货方式费用仅在您操纵送货会话数据时才有效

完整的工作代码:

// Add a Custom checkbox field for shipping options (just for testing)
add_action( 'woocommerce_after_checkout_billing_form', 'custom_billing_checkbox_for_testing', 10, 1 );
function custom_billing_checkbox_for_testing( $checkout ) {
    $field_id = 'billing_ups_yn';

    // Get the checked state if exist
    $billing_ups = WC()->session->get('billing_ups' );
    if(empty($billing_ups))
        $billing_ups = $checkout->get_value( $field_id );

    // Add the custom checkout field (checkbox)
    woocommerce_form_field( $field_id, array(
        'type' => 'checkbox',
        'class' => array( 'form-row-wide' ),
        'label' => __('Billing UPS'),
    ), $billing_ups );
}

// function that gets the Ajax data
add_action( 'wp_ajax_woo_get_ajax_data', 'woo_get_ajax_data' );
add_action( 'wp_ajax_nopriv_woo_get_ajax_data', 'woo_get_ajax_data' );
function woo_get_ajax_data() {
    if ( $_POST['billing_ups'] == '1' ){
        WC()->session->set('billing_ups', '1' );
    } else {
        WC()->session->set('billing_ups', '0' );
    }
    echo json_encode( WC()->session->get('billing_ups' ) );
    die(); // Alway at the end (to avoid server error 500)
}

// Conditionally changing the shipping methods costs
add_filter( 'woocommerce_package_rates','conditional_custom_shipping_cost', 90, 2 );
function conditional_custom_shipping_cost( $rates, $package ) {

    if ( WC()->session->get('billing_ups' ) == '1' ){
        foreach ( $rates as $rate_key => $rate_values ) {
            // Not for "Free Shipping method" (all others only)
            if ( 'free_shipping' !== $rate_values->method_id ) {

                // Set the rate cost
                $rates[$rate_key]->cost = 0;

                // Set taxes rate cost (if enabled)
                $taxes = array();
                foreach ($rates[$rate_key]->taxes as $key => $tax)
                    if( $rates[$rate_key]->taxes[$key] > 0 ) // set the new tax cost
                        $taxes[$key] = 0;
                $rates[$rate_key]->taxes = $taxes;
            }
        }
    }
    return $rates;
}

// Enabling, disabling and refreshing session shipping methods data
add_action( 'woocommerce_checkout_update_order_review', 'refresh_shipping_methods', 10, 1 );
function refresh_shipping_methods( $post_data ){
    $bool = true;
    if ( WC()->session->get('billing_ups' ) == '1' ) $bool = false;

    // Mandatory to make it work with shipping methods
    foreach ( WC()->cart->get_shipping_packages() as $package_key => $package ){
        WC()->session->set( 'shipping_for_package_' . $package_key, $bool );
    }
    WC()->cart->calculate_shipping();
}

// The Jquery script
add_action( 'wp_footer', 'custom_checkout_script' );
function custom_checkout_script() {
    ?>
    <script type="text/javascript">
        jQuery( function($){

            // update cart on delivery location checkbox option
            $('#billing_ups_yn_field input').change( function () {
                var checked = 0;
                if ( $('#billing_ups_yn').is(':checked') )
                    checked = 1;

                $.ajax({
                    type: 'POST',
                    url: wc_checkout_params.ajax_url,
                    data: {
                        'action': 'woo_get_ajax_data',
                        'billing_ups': checked,
                    },
                    success: function (result) {
                        $('body').trigger('update_checkout');
                        console.log('response: '+result); // just for testing
                    },
                    error: function(error){
                        console.log(error); // just for testing
                    }
                });
            });
        });
    </script>
    <?php
}

代码进入活动子主题(或活动主题)的function.php文件。

经过测试和工作。

与您的评论相关的更新:

如果您希望在加载时默认取消选中此复选框,则您将使用此替换第一个函数:

// Add a Custom checkbox field for shipping options (just for testing)
add_action( 'woocommerce_after_checkout_billing_form', 'custom_billing_checkbox_for_testing', 10, 1 );
function custom_billing_checkbox_for_testing( $checkout ) {
    $field_id = 'billing_ups_yn';

    // Add the custom checkout field (checkbox)
    woocommerce_form_field( $field_id, array(
        'type' => 'checkbox',
        'class' => array( 'form-row-wide' ),
        'label' => __('Billing UPS'),
    ), '' );
}

答案 1 :(得分:0)

我有大约3年前的类似项目,并有单选按钮和日期选择器,将修改和更新运输详细信息/金额更改时,单选按钮将修改运费附加,日期选择器将有-10折扣价格时从日历中选择星期六和星期五。

工作示例here

我假设你对PHP和AJax有所了解并且可以修改它,你只需要修改一些事情,比如会话值和计算以及那些jquery选择器和表单字段选择器

处理ajax请求的函数,目的是只分配$_SESSION

add_action('wp_ajax_woo_modify_charges', 'etq_calculate', 10);
add_action('wp_ajax_nopriv_woo_modify_charges', 'etq_calculate', 10);
function etq_calculate() {
    global $woocommerce;
    $charge = isset($_POST['billing_area']) ? $_POST['billing_area'] : 'no';
    $deldate = isset($_POST['jck_delivery_date']) ? $_POST['jck_delivery_date'] : '06/08/2015';
    $delday = strtotime(str_replace('/', '-', $deldate));
    $day = date('l', $delday);
    if ( $day === 'Saturday' || $day === 'Friday') $val = -10;
    else $val = 0;

    if ( $charge === 'no' ) $surchage = 0;
    else $surchage = 10; 

    if( !isset($_SESSION) ) session_start();
    $_SESSION['val'] = $val;
    $_SESSION['surcharge'] = $surchage;
}

下一个功能是将woocommerce_cart_calculate_fees的修改与$_SESSION的值挂钩..这是价格更新发生的地方

add_action('woocommerce_cart_calculate_fees', 'woo_change_cart_fee');
function woo_change_cart_fee() {
    if(!isset($_SESSION)) session_start();
    $surcharge = isset($_SESSION['surcharge']) ? $_SESSION['surcharge'] : 0;
    $discount = isset($_SESSION['val']) ? $_SESSION['val'] : 0;

    if ( $surcharge !== '0' ) WC()->cart->add_fee('Shipping Surchage', $surcharge, false, '');
    if ( $discount !== '0' ) WC()->cart->add_fee('Delivery Discount', $discount, false, '');
}

然后是处理ajax的jquery脚本

(function($){
    'use strict';
    $(document).ready( function() { 

        var $date_field = $('#jck_delivery_date');

        // update cart on delivery date changes
        $('#jck_delivery_date').bind('change', function () {
                if ($('#billing_area_yes').is(':checked')) {
                    var surcharge = $('#billing_area_yes').val();
                    $('#billing_area_yes').prop('checked', true);
                } else {
                    var surcharge = 'no';
                }

                var deldate = $('#jck_delivery_date').val();
                var data = {
                    action: 'woo_modify_charges',
                    jck_delivery_date: deldate,
                    billing_area: surcharge
                };

                $.ajax({
                    type: 'POST',
                    url: wc_checkout_params.ajax_url,
                    data: data,
                    success: function (code) {
                        console.log(code);
                        //jQuery('.woocommerce-error, .woocommerce-message').remove();

                        if (code === '0') {
                            //$form.before(code);
                            $('body').trigger('update_checkout');
                        }
                    },
                    dataType: 'html'
                });

                return false;
        });

        // update cart on delivery location checkbox option
        $('#billing_area_field input').change( function () {
            if ($('#billing_area_yes').is(':checked')) {
                var surcharge = $('#billing_area_yes').val();
            } else {
                var surcharge = 'no';
            }
            var deldate = $('#jck_delivery_date').val();
            console.log( surcharge );
            var data = {
                action: 'woo_modify_charges',
                billing_area: surcharge,
                jck_delivery_date: deldate,
            };

            $.ajax({
                type: 'POST',
                url: wc_checkout_params.ajax_url,
                data: data,
                success: function (code) {
                    console.log(code);
                    //jQuery('.woocommerce-error, .woocommerce-message').remove();

                    if (code === '0') {
                        //$form.before(code);
                        $('body').trigger('update_checkout');
                    }
                },
                dataType: 'html'
            });

            return false;
        });
    });
})(jQuery);