按照对上一个问题的Exclude some products from calculated additional fee in WooCommerce回答,我对前面代码中的数组进行了一些更改.
然后,我在产品编辑页面中添加了一个复选框:如果它处于活动状态(选中),则不会为该产品计税.如果该选项处于非活动状态(默认情况下未选中),则将计算该税.

1. Modify the Function to Include an Excluded Array:

// +9% tax add-fee on paypal
add_action( 'woocommerce_cart_calculate_fees', 'add_checkout_fee_for_gateway', 10, 1 );
function add_checkout_fee_for_gateway( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) 
        return;

    // Retrieve excluded product IDs from post meta
    $excluded_product_ids = get_option('excluded_product_ids', array());
    
    // Only on checkout page and for specific payment method ID
    if ( is_checkout() && ! is_wc_endpoint_url() 
    && WC()->session->get('chosen_payment_method') === 'paypal' ) {
        $percentage_rate      = 0.09; // Defined percentage rate
        $custom_subtotal      = 0; // Initializing
        
        // Loop through cart items
        foreach( $cart->get_cart() as $item ) {
            // Calculate items subtotal from non excluded products
            if( ! in_array($item['product_id'], $excluded_product_ids) ) {
                $custom_subtotal += (float) $item['line_subtotal'];
            }
        }

        if ( $custom_subtotal > 0 ) {
            $cart->add_fee( __('9% value added tax'), ($custom_subtotal * $percentage_rate), true, '' );
        }
    }
}

2. Add Checkbox to Product Edit Page:

// Add checkbox to product edit page
add_action('woocommerce_product_options_general_product_data', 'add_custom_product_field');
function add_custom_product_field() {
    global $post;

    // Checkbox field
    woocommerce_wp_checkbox(
        array(
            'id'            => 'exclude_from_tax',
            'wrapper_class' => 'show_if_simple',
            'label'         => __('Exclude from Tax Calculation'),
            'description'   => __('Check this box to exclude this product from tax calculation.'),
            'value'         => get_post_meta($post->ID, 'exclude_from_tax', true) ? 'yes' : 'no',
        )
    );
}

// Save checkbox value
add_action('woocommerce_process_product_meta', 'save_custom_product_field');
function save_custom_product_field($post_id) {
    // Checkbox field
    $checkbox = isset($_POST['exclude_from_tax']) ? 'yes' : 'no';
    update_post_meta($post_id, 'exclude_from_tax', $checkbox);
}

OR this: (combined version! (maybe better all in one))

add_action('woocommerce_cart_calculate_fees', 'add_checkout_fee_and_product_field', 10, 1);
function add_checkout_fee_and_product_field($cart) {
    if (is_admin() && !defined('DOING_AJAX'))
        return;

    // Retrieve excluded product IDs from post meta
    $excluded_product_ids = get_option('excluded_product_ids', array());

    // Add checkbox to product edit page
    add_action('woocommerce_product_options_general_product_data', 'add_custom_product_field');
    function add_custom_product_field() {
        global $post;

        // Checkbox field
        woocommerce_wp_checkbox(
            array(
                'id' => 'exclude_from_tax',
                'wrapper_class' => 'show_if_simple',
                'label' => __('Exclude from Tax Calculation'),
                'description' => __('Check this box to exclude this product from tax calculation.'),
                'value' => get_post_meta($post->ID, 'exclude_from_tax', true) ? 'yes' : 'no',
            )
        );
    }

    // Save checkbox value
    add_action('woocommerce_process_product_meta', 'save_custom_product_field');
    function save_custom_product_field($post_id) {
        // Checkbox field
        $checkbox = isset($_POST['exclude_from_tax']) ? 'yes' : 'no';
        update_post_meta($post_id, 'exclude_from_tax', $checkbox);
    }

    // Only on checkout page and for specific payment method ID
    if (is_checkout() && !is_wc_endpoint_url() && WC()->session->get('chosen_payment_method') === 'paypal') {
        $percentage_rate = 0.09; // Defined percentage rate
        $custom_subtotal = 0; // Initializing

        // Loop through cart items
        foreach ($cart->get_cart() as $item) {
            // Calculate items subtotal from non excluded products
            if (!in_array($item['product_id'], $excluded_product_ids)) {
                $custom_subtotal += (float)$item['line_subtotal'];
            }
        }

        if ($custom_subtotal > 0) {
            $cart->add_fee(__('9% value added tax'), ($custom_subtotal * $percentage_rate), true, '');
        }
    }
}

现在我不知道我的方法和代码是否正确?是否与插件、主题或WordPress和WooCommerce的核心不兼容?或者它将不会在新的和future 的版本中创建?它不会损坏数据库吗?有没有可能用更干净、更少的代码,以更好、更安全、更容易的方式完成这项工作?

推荐答案

您的代码中存在一些错误和遗漏内容.

请try 以下修改后的代码版本:

// Percentage tax fee for defined payment methods IDs
add_action( 'woocommerce_cart_calculate_fees', 'add_checkout_fee_for_gateway' );
function add_checkout_fee_for_gateway( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) 
        return;

    $targeted_payment_methods = array('paypal', 'bacs', 'cheque'); // Define the payment method(s) ID(s)
    
    // Only on checkout page and for specific payment method ID
    if ( is_checkout() && ! is_wc_endpoint_url() 
    && in_array(WC()->session->get('chosen_payment_method'),  $targeted_payment_methods) ) {
        $percentage_rate  = 0.09; // Defined percentage rate
        $custom_subtotal  = 0; // Initializing
        
        // Loop through cart items
        foreach( $cart->get_cart() as $item ) {
            // Get the WC_Product object
            $product = wc_get_product( $item['product_id'] );
            // Check if the product is excluded from fee calculation
            if( $product->get_meta('_tax_fee_excluded') !== 'yes' ) {
                // Calculate items subtotal from non excluded products
                $custom_subtotal += (float) $item['line_subtotal'];
            }
        }

        if ( $custom_subtotal > 0 ) {
            $cart->add_fee( __('9% value added tax'), ($custom_subtotal * $percentage_rate), true, '' );
        }
    }
}

// Update checkout on payment method change
add_action( 'woocommerce_checkout_init', 'update_checkout_on_payment_method_change' );
function update_checkout_on_payment_method_change() {
    wc_enqueue_js("$('form.checkout').on( 'change', 'input[name=payment_method]', function(){
        $(document.body).trigger('update_checkout');
    });");
}

// Display a checkbox to Admin Product edit pages
add_action('woocommerce_product_options_general_product_data', 'add_admin_product_custom_field');
function add_admin_product_custom_field() {

    // Checkbox field
    woocommerce_wp_checkbox( array(
        'id'            => '_tax_fee_excluded',
        'wrapper_class' => 'show_if_simple',
        'label'         => __('Exclude from Tax Calculation'),
        'description'   => __('Check this box to exclude this product from tax calculation.')
    ) );
}

// Save checkbox value from product edit page
add_action('woocommerce_admin_process_product_object', 'save_admin_product_custom_field_value');
function save_admin_product_custom_field_value( $product ) {
    $product->update_meta_data('_tax_fee_excluded', isset($_POST['_tax_fee_excluded']) ? 'yes' : 'no');
}

代码放在子主题的functions.php文件中(或插件中).测试和作品.

Php相关问答推荐

WooCommerce拆分运输包裹上的商品数量增加运输成本

无法使用DOMPDF在PDF中呈现非ANSI字符

Symfony/Panther Web抓取不适用于登录后的内容(云功能)

显示WooCommerce当前产品类别或标签的短代码

通过注册在Laravel中分配角色

将文件添加到存档,而不重建存档

Apache只允许index.php-不从根目录工作

如何在php网站代码中清理浏览器缓存

使用php ZipArhive类将Zip压缩文件分成多个部分

是否有条件判断是否发布了另一个Wordpress页面?

Wordpress,配置一周第一天选项

PHP 支持 APNG 文件吗?

根据页面以及是否在促销,向 WooCommerce 中显示的价格添加前缀

woocommerce checkout 页面上的自定义字段

为什么 php 只能在我的 Nginx Web 服务器的某些目录中工作?

使用自定义规则进行 Livewire 验证不会显示错误

带有分类术语数组的 WordPress Elementor 自定义查询 - 如何要求所有术语都在返回的帖子中

Symfony:指定 data_class 时,提交的表单获取初始化前不得访问

如何使用 WhatsApp Cloud API 向 WhatsApp 发送消息,而无需在发送消息之前注册收件人号码?

如何在供应商名称后将自定义徽章添加到商品详情