Following Exclude some products from calculated additional fee in WooCommerce answer to my previous question, I have made some changes to the array from my previous code.
Then, I added a checkbox to the product edit page: If it is active (checked), tax will not be calculated for that product. And if it is inactive (unchecked by default) the tax will be calculated.
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, '');
}
}
}
Now I don't know if my method and codes are correct? Is there incompatibility with plugins, themes, or the core of WordPress and WooCommerce actually? Or will it not be created in new and future versions? Does it not damage the database? Is it possible to do this in a better, safer and easier way with cleaner and less code?
There are some mistakes and missing things in your code.
Try the following revised code version instead:
Code goes in functions.php file of your child theme (or in a plugin). Tested and works.