【问题标题】:Get a dynamic calculated fee based on postcode input in Woocommerce根据 Woocommerce 中输入的邮政编码获取动态计算费用
【发布时间】:2018-02-13 17:12:35
【问题描述】:

我试图在woocommerce_cart_calculate_fees 钩子中传递一个变量,但是这段代码不起作用。当我尝试在变量中传递静态值时,它可以工作。

这是我的代码:

add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees', 20, 1);
function add_custom_fees( WC_Cart $cart){

    $final_discount; // storing ajax value
    $static_value = 5; // static value

    if ($final_discount) {
       /**
        * custom discount for the cart in woocommerce
        */
        // Hook before calculate fees
        add_action('woocommerce_cart_calculate_fees', 'add_custom_fees');

        /**
         * Add custom fee if more than three article
         * @param WC_Cart $cart
         */
        function add_custom_fees(WC_Cart $cart) {
            // Calculate the amount to reduce
            global $final_discount;
            $discount = $cart->subtotal * $final_discount / 100;
            $cart->add_fee('10% discount has been added.', -$discount);
        }
    }
}

编辑:

现在我要在woocommerce_cart_calculate_fees 钩子中传递一个WC_Session 值,代码有效但会话变量在页面刷新之前不会更新。

会话变量存储自 woocommerce 结帐页面的 billing_postcode 字段的 onchange ajax 值。

我的 jQuery 代码(Ajax):

jQuery(document).ready(function () {
    jQuery('#billing_postcode').on('change', function (event) {
        //alert( this.value );
        event.preventDefault();
        var billing_postcode = jQuery('#billing_postcode').val();

        console.log(billing_postcode);
        var data = {
            action: 'woocommerce_apply_state',
            security: wc_checkout_params.apply_state_nonce,
            billing_postcode: billing_postcode
        };

        jQuery.ajax({
            type: "POST",
            data: data,
            url: wc_checkout_params.ajax_url,
            success: function (code) {
                console.log(code);
                if (code === '0') {
                    jQuery('body').trigger('update_checkout');
                }
            },
            dataType: 'html'
        });
    });
});

我的主题的functions.php文件中的PHP代码:

wp_enqueue_script('zip_code', get_template_directory_uri() . '/assets/js/zipcode.js', array('jquery'));
wp_localize_script('zip_code', 'wc_checkout_params', array('ajaxurl' => admin_url('admin-ajax.php')));

add_action('wp_ajax_woocommerce_apply_state', 'discount', 10);
add_action('wp_ajax_nopriv_woocommerce_apply_state', 'discount', 10);

function discount() {
    if(isset($_POST['billing_postcode'])){
        $billing_postcode = isset($_POST['billing_postcode'])?$_POST['billing_postcode']:'not yet';
        global $wpdb;
        $zipcodes = $wpdb->get_results( 
            $wpdb->prepare( "
                SELECT * FROM wp_zip_codes_value 
                WHERE zip_code_value = %d", 
                $billing_postcode
            ) 
        );

        $zip_for_discount = array();
        foreach ( $zipcodes as $zipcode ){
            $zip_for_discount = $zipcode->zip_code_id;
        }

        $find_discount = $wpdb->get_results( 
            $wpdb->prepare( "
                SELECT * FROM wp_zip_codes 
                WHERE zip_code = %d", 
                $zip_for_discount
            ) 
        );

        $final_discount = array();
        if($find_discount){
            foreach ( $find_discount as $discount ){
                $final_discount[] = $discount->discount;
            }
        }
        $final_discount[0];
        WC()->session->set( 'final_discount', $final_discount[0] );
    }
}

add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees', 20, 1);

function add_custom_fees( WC_Cart $cart){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
    $percent = WC()->session->get( 'final_discount' );
    if( $percent > 0 ){
        $discount = $cart->subtotal * $percent / 100;
        $cart->add_fee( __('Zip Code Discount', 'woocommerce' ) . " ($percent%)", -$discount);
    }
}

【问题讨论】:

    标签: php wordpress woocommerce cart discount


    【解决方案1】:

    实现该功能的最佳方法是之前在另一个函数中使用 WC_Sessions 设置您的 $final_discount 变量,这样:

    WC()->session->set( 'final_discount', $final_discount );
    

    现在您可以在前端钩子或代码的任何地方使用:

    $final_discount = WC()->session->get( 'final_discount' );
    

    所以您的最终折扣(负费用)代码将类似于:

    add_action('woocommerce_cart_calculate_fees', 'add_custom_fee', 20, 1 );
    function add_custom_fee( $cart ){
        if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
    
        // Get the data from WC_Sessions
        $percent = WC()->session->get( 'final_discount' );
        
        if( $percent > 0 ){
            $discount = $cart->subtotal * $percent / 100;
            $cart->add_fee( __('Discount', 'woocommerce' ) . " ($percent%)" . $percent, -$discount);
        }
    }
    

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

    经过测试并且有效。


    关于您更新的问题的更新:

    这是一个 工作 Ajax 示例代码,与您的类似但简化了 (因为我没有类似的数据库自定义表来获取折扣百分比).

    可变折扣百分比基于估算的邮政编码值……

    PHP 代码:

    add_action( 'wp_enqueue_scripts', 'wc_zipcode_enqueue_scripts' );
    function wc_zipcode_enqueue_scripts() {
    
        // Only on front-end and checkout page
        if( is_admin() || ! is_checkout() ) return;
    
        // (For child themes use get_stylesheet_directory_uri() instead)
        wp_enqueue_script('zip_code', get_template_directory_uri() . '/assets/js/zipcode.js', array('jquery'));
        wp_localize_script('zip_code', 'wc_checkout_params', array('ajaxurl' => admin_url('admin-ajax.php')));
    }
    
    add_action('wp_ajax_woocommerce_apply_state', 'woocommerce_apply_state', 10 );
    add_action('wp_ajax_nopriv_woocommerce_apply_state', 'woocommerce_apply_state', 10 );
    function woocommerce_apply_state() {
        global $wpdb;
    
        if( isset($_POST['billing_postcode']) ){
            $billing_postcode = $_POST['billing_postcode'];
    
            if( empty($billing_postcode) || $billing_postcode == 0 ) die();
    
            if( $billing_postcode < 30000 )
                $final_discount = 10;
            elseif( $billing_postcode >= 30000 && $billing_postcode < 60000 )
                $final_discount = 15;
            else
                $final_discount = 20;
    
            WC()->session->set( 'final_discount', $final_discount );
            echo json_encode( WC()->session->get('final_discount' ) );
        }
        die(); // Alway at the end (to avoid server error 500)
    }
    
    add_action('woocommerce_cart_calculate_fees' , 'add_custom_discount', 20, 1);
    function add_custom_discount( WC_Cart $cart){
        if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
    
        // Get the data from WC_Sessions
        $percent = WC()->session->get( 'final_discount' );
    
        // If the billing postcode is not set we exit
        $billing_postcode = WC()->session->get('customer')['postcode'];
        if( empty($billing_postcode) ) return;
    
        if( $percent > 0 ){
            $discount = $cart->subtotal * $percent / 100;
            $cart->add_fee( __('Zip Code Discount', 'woocommerce' ) . " ($percent%)", -$discount);
        }
    }
    

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

    javascript代码:

    jQuery(document).ready(function($) {
        function postcodeAjax(){
            $.ajax({
                type: 'POST',
                data:  {
                    action: 'woocommerce_apply_state',
                    billing_postcode: $('#billing_postcode').val(),
                    security: wc_checkout_params.apply_state_nonce
               },
                url: wc_checkout_params.ajax_url,
                success: function (response) {
                    $('body').trigger('update_checkout');
                    console.log('updating checkout…');
                }
            });
        }
    
        if( $('#billing_postcode').val() > 0 )
            postcodeAjax();
    
        $('#billing_postcode').on('change blur', function(e){
            e.preventDefault();
            postcodeAjax();
            $('body').trigger('update_checkout');
        });
    });
    

    保存在主题文件夹/assets/js/zipcode.js

    中名为zipcode.js的文件中

    经过测试并完美运行

    【讨论】:

    • 谢谢。 :) 你的代码工作正常,但有点问题。页面刷新前折扣值不更新,页面刷新后显示折扣值。会取消会话吗?如何以及在哪里?
    • 好的,谢谢。现在我用详细信息代码编辑了我的问题。请检查一下好吗?
    • @rafiqislam 在我原来的回答之后更新……
    • @LoicTheAztec 这个答案很有帮助。 +1
    猜你喜欢
    • 2013-04-05
    • 2015-01-12
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多