Jump to content

Apply different tax rate based on customer roles


Lyse

Recommended Posts

One possible usage:

const PST_RATE = 0.15;
const GST_RATE = 0.10;

$taxes = ['Wholesale Customer'       =>  ['PST' => 1, 'GST' => 1],  
          'Wholesale Silvia Silver'  =>  ['PST' => 1, 'GST' => 1], 
          'Wholesale Silvia Gold'    =>  ['PST' => 1, 'GST' => 1], 
          'Wholesale Silvia Premium' =>  ['PST' => 1, 'GST' => 1], 
          'Wholesale Silvia Union'   =>  ['PST' => 1, 'GST' => 1],

          'wholesale_pst_exempt'                 =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_silver_pst_exempt'   =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_gold_pst_exempt'     =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_premium_pst_exempt'  =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_union_pst_exempt'    =>  ['PST' => 0, 'GST' => 1],
          
          'wholesale_tax_exempt'                 =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_silver_tax_exempt'   =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_gold_tax_exempt'     =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_premium_tax_exempt'  =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_union_tax_exempt'    =>  ['PST' => 0, 'GST' => 0]
         ];

$customer_role = 'Wholesale Silvia Silver';              // get role of current customer
         
$PST_payable = $taxes[$customer_role]['PST'];
$GST_payable = $taxes[$customer_role]['GST'];

$net_value = 100.00;
$pst = $net_value * PST_RATE * $PST_payable;             // calculate tax values
$gst = $net_value * GST_RATE * $GST_payable;

$total_payable = $net_value + $pst + $gst;

echo number_format($total_payable, 2)                    //--> 125.00

 

Link to comment
Share on other sites

My function looks like this:

/*
* APPLY DIFFERENT TAX RATE BASED ON CUSTOMER USER ROLE
* (Code compacted in one unique hook instead of 5 functions with the same hook)
*/

// in the original version, the $tax_class input is conditionally modified and returned. $product is not used.
function all_custom_tax_classes( $tax_class, $product ) {
    global $current_user; // used in isset() only

	// Getting the current user
    $curr_user = wp_get_current_user(); // not used in 'active' code
    $curr_user_data = get_userdata($current_user->ID); // not used in 'active' code

	// 1 customer_tax_exempt
	/* special tax rate: zero if role: Customer Tax Exempt */
	/*if ( in_array( 'customer_tax_exempt', $curr_user_data->roles ) )
		$tax_class = 'CustomerTaxExemptClass';

	// 2 customer_pst_exempt
	// special tax rate: charge only GST if role: Customer PST Exempt
	if ( in_array( 'customer_pst_exempt', $curr_user_data->roles ) )
		$tax_class = 'CustomerPSTExemptClass';
	*/
	
	// 3, 4 & 5 WHOLESLE SUITE SPECIAL WHOLESALE TAX RATES
	var_dump($arrayorobject);
	if (isset($current_user) && class_exists('WWP_Wholesale_Roles'))
	{
		$wwp_wholesale_roles = WWP_Wholesale_Roles::getInstance();
		$wwp_wholesale_role = $wwp_wholesale_roles->getUserWholesaleRole(); // get an array of the user roles - is there ever more than one element?
				
		// define an array that maps input values to output values - note: if the user role values were defined to be the same as the expected return values, this step wouldn't be needed
		$taxes = [
		  'Wholesale Customer'       =>  ['PST' => 1, 'GST' => 1],  
          'Wholesale Silvia Silver'  =>  ['PST' => 1, 'GST' => 1], 
          'Wholesale Silvia Gold'    =>  ['PST' => 1, 'GST' => 1], 
          'Wholesale Silvia Premium' =>  ['PST' => 1, 'GST' => 1], 
          'Wholesale Silvia Union'   =>  ['PST' => 1, 'GST' => 1],

          'wholesale_pst_exempt'                 =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_silver_pst_exempt'   =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_gold_pst_exempt'     =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_premium_pst_exempt'  =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_union_pst_exempt'    =>  ['PST' => 0, 'GST' => 1],
          
          'wholesale_tax_exempt'                 =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_silver_tax_exempt'   =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_gold_tax_exempt'     =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_premium_tax_exempt'  =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_union_tax_exempt'    =>  ['PST' => 0, 'GST' => 0]
         ];
		 
		$PST_payable = $taxes[$customer_role]['PST'];
		$GST_payable = $taxes[$customer_role]['GST'];
		
		if (!empty($wwp_wholesale_role))
		{
			// the following assumes that the 1st role value found is what is returned. if a user can have more than one role, this differs from the original logic, in that the last role found is what is returned.
			// loop over the map array
			foreach($map as $key=>$value)
			{
				// test if the key is in the role array
				if(in_array($key,$wwp_wholesale_role))
				{
					// if so, return the value corresponding to the key
					return $value;
				}
			}
		}
	}
		
	// if none of the role values was found in the user role(s), return the original $tax_class value to the calling code
	return $tax_class;
}

/* ADDITIONAL FILTERS TO ALTER THE SHIPPING TAX FOR DIFFERENT TAX CLASSES BASED ON CUSTOMER USER ROLE */
add_filter( 'woocommerce_product_get_tax_class', 'all_custom_tax_classes', 1, 2 ); // calls the above function
add_filter( 'woocommerce_product_variation_get_tax_class', 'all_custom_tax_classes', 1, 2 ); // calls the above function

// calls the in-line function. the $option_value input is returned if none of the logic returns first.
add_filter( 'option_woocommerce_shipping_tax_class' , function( $option_value )
{
	global $wc_wholesale_prices;

	if ( $wc_wholesale_prices && is_a( $wc_wholesale_prices , 'WooCommerceWholeSalePrices' ) )
	{
		$wwp_wholesale_role = $wc_wholesale_prices->wwp_wholesale_roles->getUserWholesaleRole(); // get an array of the user roles - is there ever more than one element?
		
		// define an array that maps input values to output values - note: if the user role values were defined to be the same as the expected return values, this step wouldn't be needed
		// use the same definition as above (you would actually do this through configuration data so as to not repeat it)
		// i'm assuming that the same letter-case values used above will work here. if not, alter this data as needed.
		$taxes = [
		  'Wholesale Customer'       =>  ['PST' => 1, 'GST' => 1],  
          'Wholesale Silvia Silver'  =>  ['PST' => 1, 'GST' => 1], 
          'Wholesale Silvia Gold'    =>  ['PST' => 1, 'GST' => 1], 
          'Wholesale Silvia Premium' =>  ['PST' => 1, 'GST' => 1], 
          'Wholesale Silvia Union'   =>  ['PST' => 1, 'GST' => 1],

          'wholesale_pst_exempt'                 =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_silver_pst_exempt'   =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_gold_pst_exempt'     =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_premium_pst_exempt'  =>  ['PST' => 0, 'GST' => 1],
          'wholesale_silvia_union_pst_exempt'    =>  ['PST' => 0, 'GST' => 1],
          
          'wholesale_tax_exempt'                 =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_silver_tax_exempt'   =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_gold_tax_exempt'     =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_premium_tax_exempt'  =>  ['PST' => 0, 'GST' => 0],
          'wholesale_silvia_union_tax_exempt'    =>  ['PST' => 0, 'GST' => 0]
         ];
		 
		$PST_payable = $taxes[$customer_role]['PST'];
		$GST_payable = $taxes[$customer_role]['GST'];

		if (!empty($wwp_wholesale_role))
		{
			// the following assumes that the 1st role value found is what is returned. this is the same operation as the original code here.
			// loop over the map array
			foreach($map as $key=>$value)
			{
				// test if the key is in the role array
				if(in_array($key,$wwp_wholesale_role))
				{
					// if so, return the value corresponding to the key
					return $value;
				}
			}
		}
	}

	return $option_value;

} , 10 , 1 );

with a syntax error on the $taxes line

But I don't know how to integrate your solution into my code to make this work. Sorry but I'm not very PHP proficient.

Link to comment
Share on other sites

4 hours ago, Lyse said:

Would my array look like this:


		$map = [];
		$map['wholesale_customer','wholesale_silvia_silver','wholesale_silvia_gold','wholesale_silvia_premium','wholesale_silvia_union'] = 'WholesalePSTGST'; // charge both PST and GST
		$map['wholesale_pst_exempt','wholesale_silvia_silver_pst_exempt','wholesale_silvia_gold_pst_exempt','wholesale_silvia_premium_pst_exempt','wholesale_silvia_union_pst_exempt'] = 'WholesalePSTExempt'; // charge only GST
		$map['wholesale_tax_exempt','wholesale_silvia_silver_tax_exempt','wholesale_silvia_gold_tax_exempt','wholesale_silvia_premium_tax_exempt','wholesale_silvia_union_tax_exempt'] = 'WholesaleZeroTax'; // charge neither

 

no. $map is an array, with an element/line for each input/output mapping. starting what what i posted, to avoid making even more changes, add a line for each of your new role names and tax classes -

$map['wholesale_silvia_silver'] = 'WholesalePSTGST';
$map['wholesale_silvia_gold']  = 'WholesalePSTGST';
...

 

Edited by mac_gyver
Link to comment
Share on other sites

I must be missing something because I cannot see the point in having a chain of functions which convert one cryptic string value into another one. Eventually you are going to have to to decide on a YES/NO value as to whether a tax is included or not. Why not go straight there?

Just my 0.02 worth. I'll shut up now.

Link to comment
Share on other sites

Like so:

		$map = []; 
		// charge both PST and GST
		$map['wholesale_customer'] = 'WholesalePSTGST'; 
		$map['wholesale_silvia_silver'] = 'WholesalePSTGST';
		$map['wholesale_silvia_gold'] = 'WholesalePSTGST';
		$map['wholesale_silvia_premium'] = 'WholesalePSTGST';
		$map['wholesale_silvia_union'] = 'WholesalePSTGST'; 
		// charge only GST
		$map['wholesale_pst_exempt'] = 'WholesalePSTExempt'; 
		$map['wholesale_silvia_silver_pst_exempt'] = 'WholesalePSTExempt'; 
		$map['wholesale_silvia_gold_pst_exempt'] = 'WholesalePSTExempt'; 
		$map['wholesale_silvia_premium_pst_exempt'] = 'WholesalePSTExempt'; 
		$map['wholesale_silvia_union_pst_exempt'] = 'WholesalePSTExempt'; 
		// charge neither
		$map['wholesale_tax_exempt'] = 'WholesaleZeroTax';
		$map['wholesale_silvia_silver_tax_exempt'] = 'WholesaleZeroTax';
		$map['wholesale_silvia_gold_tax_exempt'] = 'WholesaleZeroTax';
		$map['wholesale_silvia_premium_tax_exempt'] = 'WholesaleZeroTax';
		$map['wholesale_silvia_union_tax_exempt'] = 'WholesaleZeroTax';

 

Link to comment
Share on other sites

I've implemented the function on my testing server and it works very well. I appreciate so so much all of the time and effort you have provided to support my needs. It's been a wonderful first time experience using this platform for help.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.