Setting up taxes and tax rates is one of the first tasks you want to perform when setting up a store. However, the tax calculation gets carried out by WooCommerc. This document might help you further in how WooCommerce handles the tax :
Therefore, the tax will be either calculated as per admin’s location or customer’s location.
However, for a multivendor site, sometimes a vendor needs to earn tax as per the law in their own state.
As a workaround, this following code will let the vendor add tax per product.
add_action( 'mvx_frontend_dashboard_product_options_stock_status', 'mvx_extra_fields_in_products_grouped',10,3 );
function mvx_extra_fields_in_products_grouped($post__ID, $product_object, $post){
$get_tax_rate = get_post_meta($post__ID,'_extra_tax_per_product_key',true);
?>
<div class="form-group">
<label class="control-label col-sm-3 col-md-3" for="_extra_tax_per_product"><?php echo __( 'Per product tax', 'woocommerce' ); ?></label>
<div class="col-md-6 col-sm-9">
<input type="text" id="_extra_tax_per_product" name="_extra_tax_per_product" value="<?php print_r($get_tax_rate); ?>" class="form-control">
</div>
</div>
<?php
}
add_action( 'mvx_frontend_dashboard_after_general_product', 'mvx_extra_fields_in_products',10,3);
function mvx_extra_fields_in_products($post__ID, $product_object, $post){
$get_tax_rate = get_post_meta($post__ID,'_extra_tax_per_product_key',true);
?>
<div class="form-group">
<label class="control-label col-sm-3 col-md-3" for="_extra_tax_per_product"><?php echo __( 'Per product tax', 'woocommerce' ); ?></label>
<div class="col-md-6 col-sm-9">
<input type="text" id="_extra_tax_per_product" name="_extra_tax_per_product" value="<?php print_r($get_tax_rate); ?>" class="form-control">
</div>
</div>
<?php
}
This code will add a section like this screenshot:
Now, we also add a checking, if a vendor hasn’t added per product tax, then WooCommerce’s tax rule will be applied. For this use this code :
/**
** Per product on tax setting woocommerce
**/
add_filter( 'woocommerce_tax_settings', 'vendor_based_tax' );
function vendor_based_tax( $settings ){
$settings[2]['options']['per_product'] = __('Per product tax','dc-woocommerce-multi-vendor');
return $settings;
}
/**
** Extra fields save in cluding product tax rate
**/
add_action('mvx_process_product_object','save_tax_rate', 10, 2);
function save_tax_rate($product, $post){
$per_tax_price = $post['_extra_tax_per_product'];
update_post_meta($product->get_id(),'_extra_tax_per_product_key',$per_tax_price);
$tax_rate_id = get_post_meta( $product->get_id() , 'product_tax_rate_id' ,true );
if ( metadata_exists( 'post', $product->get_id(), 'product_tax_rate_id' ) && $tax_rate_id ) {
$tax_rate = array(
'tax_rate_country' => '',
'tax_rate_state' => '',
'tax_rate' => $per_tax_price,
'tax_rate_name' => __( 'Per Product Tax('.$product->get_name().')', 'dc-woocommerce-multi-vendor'),
'tax_rate_priority' => 1,
'tax_rate_compound' => 0,
'tax_rate_shipping' => 1,
'tax_rate_order' => 3,
);
WC_Tax::_update_tax_rate( $tax_rate_id, $tax_rate );
} else {
$tax_rate = array(
'tax_rate_country' => '',
'tax_rate_state' => '',
'tax_rate' => $per_tax_price,
'tax_rate_name' => __( 'Per Product Tax('.$product->get_name().')', 'dc-woocommerce-multi-vendor'),
'tax_rate_priority' => 1,
'tax_rate_compound' => 0,
'tax_rate_shipping' => 1,
'tax_rate_order' => 3,
);
$tax_rate_id = WC_Tax::_insert_tax_rate( $tax_rate );
update_post_meta($product->get_id(),'product_tax_rate_id',$tax_rate_id);
}
}
/**
** Add tax on parent order
**/
add_filter( 'woocommerce_cart_totals_get_item_tax_rates', 'woocommerce_cart_totals_get_item_tax_rates_per_product' , 10 , 3 );
function woocommerce_cart_totals_get_item_tax_rates_per_product( $item_tax_rates, $items, $cart ){
// check per product tax is enable or not
$tax_based_on = get_option( 'woocommerce_tax_based_on' );
if( 'per_product' !== $tax_based_on ) return $item_tax_rates;
$find_rate = array();
$product_tax_rate = get_post_meta( $items->object['product_id'] , 'product_tax_rate_id' ,true );
if( !$product_tax_rate ) return $item_tax_rates;
$get_tax_rate = WC_Tax::_get_tax_rate( $product_tax_rate );
$find_rate[$get_tax_rate['tax_rate_id']] = array(
'rate' => $get_tax_rate['tax_rate'],
'label' => $get_tax_rate['tax_rate_name'],
'shipping' => 'yes',
'compound' => 'no'
);
return $find_rate;
}
/**
*** Add shipping on parent order
**/
add_filter( 'woocommerce_shipping_method_add_rate', 'vendor_based_shipping_rate_per_product', 10 , 3 );
function vendor_based_shipping_rate_per_product( $rate, $args, $package ){
// check per product tax is enable or not
$tax_based_on = get_option( 'woocommerce_tax_based_on' );
if( 'per_product' !== $tax_based_on ) return $rate;
$taxes = $args['taxes'];
$total_cost = is_array( $args['cost'] ) ? array_sum( $args['cost'] ) : $args['cost'];
if ( $args['package'] ) {
foreach ( $args['package']['contents'] as $item ) {
$product = $item['data'];
$product_tax_rate = get_post_meta( $product->get_id() , 'product_tax_rate_id' ,true );
if( $product_tax_rate ){
$get_tax_rate = WC_Tax::_get_tax_rate( $product_tax_rate );
$find_rate[$get_tax_rate['tax_rate_id']] = array(
'rate' => $get_tax_rate['tax_rate'],
'label' => $get_tax_rate['tax_rate_name'],
'shipping' => 'yes',
'compound' => 'no'
);
if ( ! is_array( $taxes ) && false !== $taxes && $total_cost > 0 && $package->is_taxable() ) {
$taxes = 'per_item' === $args['calc_tax'] ? $package->get_taxes_per_item( $args['cost'] ) : WC_Tax::calc_shipping_tax( $total_cost, $find_rate );
}
$total_cost = wc_format_decimal( $total_cost, $args['price_decimals'] );
$rate->set_taxes( $taxes );
}
}
}
return $rate;
}
/**
*** Add tax on sub order
**/
add_action( 'woocommerce_order_item_after_calculate_taxes', 'calculate_tax_for_per_product', 10 , 2 );
function calculate_tax_for_per_product( $item, $calculate_tax_for ){
// check per product tax is enable or not
$tax_based_on = get_option( 'woocommerce_tax_based_on' );
if( 'per_product' !== $tax_based_on ) return $item;
$product_tax_rate = get_post_meta( $item->get_product_id() , 'product_tax_rate_id' ,true );
if( !$product_tax_rate ) return $item;
$get_tax_rate = WC_Tax::_get_tax_rate( $product_tax_rate );
$find_rate[$get_tax_rate['tax_rate_id']] = array(
'rate' => $get_tax_rate['tax_rate'],
'label' => $get_tax_rate['tax_rate_name'],
'shipping' => 'yes',
'compound' => 'no'
);
$tax_rates = $find_rate;
$taxes = WC_Tax::calc_tax( $item->get_total(), $tax_rates, false );
if ( method_exists( $item, 'get_subtotal' ) ) {
$subtotal_taxes = WC_Tax::calc_tax( $item->get_subtotal(), $tax_rates, false );
$item->set_taxes(
array(
'total' => $taxes,
'subtotal' => $subtotal_taxes,
)
);
} else {
$item->set_taxes( array( 'total' => $taxes ) );
}
return $item;
}
/**
** Add shipping on sub order
**/
add_action( 'woocommerce_order_item_shipping_after_calculate_taxes', 'add_shipping_on_sub', 99 , 2 );
function add_shipping_on_sub( $item, $calculate_tax_for ){
// check per product tax is enable or not
$tax_based_on = get_option( 'woocommerce_tax_based_on' );
if( 'per_product' !== $tax_based_on ) return $item;
$order = wc_get_order( $item->get_order_id() );
$items = $order->get_items();
$find_rate = array();
foreach ( $items as $itemt ) {
$product_tax_rate = get_post_meta( $itemt['product_id'] , 'product_tax_rate_id' ,true );
if( $product_tax_rate ){
$get_tax_rate = WC_Tax::_get_tax_rate( $product_tax_rate );
$find_rate[$get_tax_rate['tax_rate_id']] = array(
'rate' => $get_tax_rate['tax_rate'],
'label' => $get_tax_rate['tax_rate_name'],
'shipping' => 'yes',
'compound' => 'no'
);
}
}
if ( wc_tax_enabled() && $find_rate ) {
$taxes = WC_Tax::calc_tax( $item->get_total(), $find_rate, false );
$item->set_taxes( array( 'total' => $taxes ) );
} else {
$item->set_taxes( false );
}
return $item;
}
Leave a Reply
You must be logged in to post a comment.