<?php

class B2bking_Public{

	function __construct() {

		// Include dynamic rules code
		require_once ( B2BKING_DIR . 'public/class-b2bking-dynamic-rules.php' );

		// filter to remove B2BKing in all API requests:
		$run_in_api_requests = true;
		if (apply_filters('b2bking_force_cancel_api_requests', false)){
			if (b2bking()->is_rest_api_request()){
				$run_in_api_requests = false;
			}
		}

		if ($run_in_api_requests){
			add_action('plugins_loaded', function(){

				// Only load if WooCommerce is activated
				if ( defined( 'WC_PLUGIN_FILE' ) && defined('B2BKINGCORE_DIR')) {

					// Add classes to body
					add_filter('body_class', array( $this, 'b2bking_body_classes' ));
					if (apply_filters('b2bking_enable_user_cookies', false)){
						add_action('init', array($this,'b2bking_user_cookies'), 1);
					}

					// check if current user has been switched to from
					add_action('wp_footer', array($this, 'b2bking_switched_to'));

					// Load colors
					add_action( 'wp_head', array( $this, 'b2bking_custom_color' ) );

					$user_data_current_user_id = get_current_user_id();
					$user_data_current_user_id = b2bking()->get_substitute_user_id($user_data_current_user_id);

					$account_type = get_user_meta($user_data_current_user_id,'b2bking_account_type', true);
					if ($account_type === 'subaccount'){

						$user_data_current_user_id = b2bking()->get_top_parent_account($user_data_current_user_id);

						// Mention in order notes that order is placed by subaccount and point to main accounts
						add_action( 'woocommerce_thankyou', array( $this, 'b2bking_subaccount_order_note') );
					}

					// captcha integration Recaptcha for WooCommerce
					if (function_exists('rcfwc_field')){
						remove_action('woocommerce_register_form','rcfwc_field');
						add_action('woocommerce_register_form','rcfwc_field', 100000);
					}


					$user_data_current_user_b2b = get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true);

					$user_data_current_user_group = b2bking()->get_user_group($user_data_current_user_id);

					// Check that plugin is enabled
					if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

						// Modify suffix based on VAT
						add_action('init', array($this,'b2bking_modify_suffix_vat'));		

						// register post types in frontend, for API access
						require_once ( B2BKING_DIR . 'admin/class-b2bking-admin.php' );
						add_action( 'init', array('B2bking_Admin', 'b2bking_register_post_type_customer_groups'), 0 );
						add_action( 'init', array('B2bking_Admin', 'b2bking_register_post_type_conversation'), 0 );
						add_action( 'init', array('B2bking_Admin', 'b2bking_register_post_type_offer'), 0 );
						add_action( 'init', array('B2bking_Admin', 'b2bking_register_post_type_dynamic_rules'), 0 );
						add_action( 'init', array('B2bking_Admin', 'b2bking_register_post_type_custom_role'), 0 );
						add_action( 'init', array('B2bking_Admin', 'b2bking_register_post_type_custom_field'), 0 );

						// set hidden categories transient
						add_action('init', function(){
							$this->b2bking_init_set_excluded_categories();
						});

						// after the user tried to view a restricted page, the user logs in, redirect to page
						add_filter( 'woocommerce_login_redirect', array($this, 'b2bking_login_redirect_to'), 10, 1 );

						// Bulk Variations Table
						// below product
						add_action('woocommerce_after_single_product_summary', array($this, 'b2bking_bulk_variations_table'), 1);
						// replacing form
						add_action('woocommerce_before_add_to_cart_form', array($this, 'b2bking_bulk_variations_table_replace_before'), 1);
						add_action('woocommerce_after_add_to_cart_form', array($this, 'b2bking_bulk_variations_table_replace_after'), 1);

						/* Coupons */
						// check coupon is valid based on user role
						add_filter( 'woocommerce_coupon_is_valid', array($this, 'b2bking_filter_woocommerce_coupon_is_valid'), 10, 3 );

						// validate vat button at checkout blocks
						add_action('wp_footer', [$this, 'validate_vat_button_blocks_checkout']);


						if (intval(get_option('b2bking_disable_registration_setting', 0)) === 0){

							// ADD Vat Validate button to billing VAT if registration is not enabled in checkout
							add_action('woocommerce_after_checkout_billing_form', array($this, 'b2bking_validate_vat_registration_disabled'));

							// Custom user registration fields
							add_action( 'woocommerce_register_form', array($this,'b2bking_custom_registration_fields'));

							// only show registration at checkout if user is not already logged in
							if (!is_user_logged_in()){
								if ( intval(get_option('b2bking_registration_at_checkout_setting', 0)) === 1 ){
									add_action( 'woocommerce_after_checkout_billing_form', array($this,'b2bking_custom_registration_fields_checkout') );

									// ajax file uploads
									add_action('wp_head', array($this, 'b2bking_checkout_file_upload_ajax'));
								}
							}

							// Check registration form for errors
							add_filter( 'woocommerce_process_registration_errors', array($this,'b2bking_custom_registration_fields_check_errors'), 10, 3 );
							// Save custom registration data
							// use user_register hook as well, seems to fix issues in certain installations
							add_action('woocommerce_created_customer', array($this,'b2bking_save_custom_registration_fields') );
							add_action('user_register', array($this,'b2bking_save_custom_registration_fields') );
							// Add B2B registration shortcodes
							add_action( 'init', array($this, 'b2bking_b2b_registration_shortcode'));
							add_action( 'init', array($this, 'b2bking_b2b_registration_only_shortcode'));
							add_action( 'init', array($this, 'b2bking_b2b_registration_separate_shortcode'));

							// redirect in case of different my account page
							add_action( 'template_redirect', array($this, 'b2bking_separate_myaccount_redirect'), 20 );
							add_filter( 'option_woocommerce_myaccount_page_id', array($this,'b2bking_separate_page_registration_b2b'), 10, 1 );

							// If user approval is manual, stop automatic login on registration
							add_action('woocommerce_registration_redirect', array($this,'b2bking_check_user_approval_on_registration'), 2);
							// Allow file upload in registration form for WooCommerce
							add_action( 'woocommerce_register_form_tag', array($this,'b2bking_custom_registration_fields_allow_file_upload') );
							// Check for approval meta on login
							if (!apply_filters('b2bking_allow_logged_in_register_b2b', false)){
								add_filter('woocommerce_process_login_errors', array($this,'b2bking_check_user_approval_on_login'), 10, 3);
								// check user approval in general to prevent somehow the user getting access
								add_action('init', array($this,'b2bking_check_user_approval_general'));
								add_action('wp_login', array($this,'b2bking_check_user_approval_on_login2'), 10, 2);

							}
				
							if ( intval(get_option('b2bking_registration_at_checkout_setting', 0)) === 1 ){
								add_action( 'woocommerce_thankyou', array($this,'b2bking_check_user_approval_on_registration_checkout'));
							}
							if (!apply_filters('b2bking_allow_logged_in_register_b2b', false)){
								// Modify new account email to include notice of manual account approval, if needed
								add_action( 'woocommerce_email_footer', array($this,'b2bking_modify_new_account_email'), 10, 1 );
							}

							// Vendor application pending
							add_action('woocommerce_account_dashboard', array($this, 'b2bking_b2b_application_pending'), 10);

							// add custom fields to order meta
							add_action( 'woocommerce_checkout_update_order_meta', array($this,'b2bking_save_billing_details') );
							// save custom fields data entered at checkout to user meta
							add_action( 'woocommerce_checkout_update_user_meta', array($this, 'b2bking_save_checkout_entered_billing_fields'), 10, 2 );
						}

						// Add b2bking content shortcode
						add_action( 'init', array($this, 'b2bking_content_shortcode'));
						// quote shortcode
						add_action( 'init', array($this, 'b2bking_quote_form_shortcode'));


						// Hide offer post from normal product query (hidden already due to category visibility, but just to be safe)
						add_filter('parse_query', array($this, 'b2bking_hide_offer_post'));

						// If Multisite option is enabled and user is not B2B, but visiting the B2B website, do not give access to my account page. Log User out directly
						if (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'){
							add_action( 'template_redirect', array($this, 'b2bking_multisite_logout_user_myaccount'), 20 );
						}

						// Add Request a Quote button
						add_action('wp', function(){
							if ($this->user_has_offer_in_cart() !== 'yes'){
								// cannot request quotes on offers
								// if marketking is defined, pro must be defined as well
								if (!defined('MARKETKINGCORE_DIR') || (defined('MARKETKINGCORE_DIR') && defined('MARKETKINGPRO_DIR'))){
									add_action( 'woocommerce_cart_actions', array($this, 'b2bking_add_request_quote_button') );
									add_filter('render_block', array($this, 'b2bking_add_request_quote_button_cart_block'), 10, 2);
								}
							}

							// optional quote button on product page
							add_action('woocommerce_after_add_to_cart_button', array($this,'b2bking_quote_button_product_page'));

							// purchase lists on product page
							if (intval(get_option('b2bking_enable_purchase_lists_setting', 1)) === 1 && intval(get_option('b2bking_purchaselists_productpage_setting', 0)) === 1){
								add_action('woocommerce_after_add_to_cart_button', array($this, 'b2bking_purchaselists_productpage_button'));
							}

						});
						
						/* Guest access restriction settings: */
						// Hide prices
						if (!is_user_logged_in()){
							if (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'hide_prices'){	
								add_filter( 'woocommerce_get_price_html', array($this, 'b2bking_hide_prices_guest_users'), 99999, 2 );
								add_filter( 'woocommerce_variation_get_price_html', array($this, 'b2bking_hide_prices_guest_users'), 99999, 2 );

								// bundles compatibility
								add_filter('woocommerce_bundle_empty_price_html', array($this, 'b2bking_hide_prices_guest_users'), 99999, 2 );
								add_action('wp_footer', array($this, 'b2bking_hide_prices_guest_users_bundle_components'));

								// Hide add to cart button as well / purchasable capabilities
								add_filter( 'woocommerce_is_purchasable', array($this, 'b2bking_disable_purchasable_guest_users'));
								add_filter( 'woocommerce_variation_is_purchasable', array($this, 'b2bking_disable_purchasable_guest_users'));
								// Code that removes the button completely for variations
								remove_action( 'woocommerce_single_variation', 'woocommerce_single_variation_add_to_cart_button', 20 );
								// Hide prices from google search
								if (intval(get_option('b2bking_return_empty_structured_data', 1)) === 1){
									add_filter( 'woocommerce_structured_data_product_offer', '__return_empty_array' );
								}

								// bricks builder
								add_filter('bricks/dynamic_data/format_value', array($this, 'bricks_logged_out_hide_prices'), 10, 5);

							}

							// Hide website
							if (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'hide_website'){

								// hide bulkorder form
								add_filter('b2bking_bulkorder_content', function($content){
									return '';
								}, 10, 1);

								if (intval(get_option('b2bking_guest_access_restriction_setting_website_redirect', 0)) === 1){
									add_action('template_redirect', array($this, 'b2bking_always_redirect_to_shop'), 100);
								}

								if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){
									if (intval(get_option( 'b2bking_hidden_has_priority_setting', 0 )) === 0){
										// Hide Categories
										if (intval(get_option( 'b2bking_completely_category_restrict', 1 )) === 1){
											add_filter( 'get_terms_args', array($this,'b2bking_categories_restrict'), 10, 2 );
										}
									}
								}
								// Hide Products
								add_action( 'woocommerce_product_query', array($this, 'b2bking_hide_products') );
								add_action( 'woocommerce_shortcode_products_query', array($this, 'b2bking_hide_products_shortcode'), 99999, 1 );
								add_filter( 'woocommerce_products_widget_query_args', array($this, 'b2bking_hide_products_shortcode'), 99999, 1);
								add_filter( 'woocommerce_product_related_posts_query', array($this, 'b2bking_hide_products') );
								add_filter( 'woocommerce_recently_viewed_products_widget_query_args', array($this, 'b2bking_hide_products_shortcode'), 99999, 1);
								add_filter( 'woocommerce_top_rated_products_widget_args', array($this, 'b2bking_hide_products_shortcode'), 99999, 1);
								// Display products not categories on shop page
								if (!is_user_logged_in()){
									add_filter('option_woocommerce_shop_page_display', function($val){
										return '';
									});
									add_action( 'elementor/widget/render_content', function( $content, $widget ) {
										$widgets = array('ucaddon_woocommerce_product_list', 'wc-archive-products', 'jet-listing-grid');
									   	if ( in_array ($widget->get_name(), $widgets) ) {
										   	ob_start();
										   	echo $this->b2bking_show_login();
										   	$content = ob_get_contents();
										   	ob_end_clean();
									   }										   
									   return $content;
									}, 10, 2 );

								}

								// Replace "No products found" with "Please login to see B2B Portal" and show Login 
								add_action( 'woocommerce_no_products_found', array($this, 'b2bking_show_login'), 9 );
								add_action( 'woocommerce_shortcode_products_loop_no_results', array($this, 'b2bking_show_login'), 9 );
								// If go directly to product page, redirect to my account
								add_action( 'template_redirect', array($this, 'b2bking_product_redirection_to_account'), 100 );

							}
							// Hide website completely ( force login )
							if (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'hide_website_completely'){
								add_action( 'wp', array($this, 'b2bking_member_only_site') );
							}
						}




						// Replace with Request a Quote
						if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes')) ){

							if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){
								// Hide prices
								add_filter( 'woocommerce_get_price_html', array($this, 'b2bking_hide_prices_request_quote'), 9999, 2 );
								add_filter( 'woocommerce_variation_get_price_html', array($this, 'b2bking_hide_prices_request_quote'), 9999, 2 );

								if (apply_filters('b2bking_remove_tiered_table_quote_mode', true)){
									add_filter('b2bking_disable_price_table', '__return_true');
								}

								add_action( 'wp_head', array($this, 'b2bking_blocks_cart_hide_prices_quote'));

								// structured data 
								// Hide prices from google search
								if (intval(get_option('b2bking_return_empty_structured_data', 1)) === 1){
									add_filter( 'woocommerce_structured_data_product_offer', '__return_empty_array' );
								}

							}

							// Change other texts such as 'view cart' to 'view quote'
							add_filter('gettext', array($this, 'b2bking_cart_to_quote_text'), 20, 3);
							add_filter('wc_add_to_cart_message_html', array($this, 'b2bking_modify_add_to_cart_message'), 10, 3);


							// Replace "Add to cart" with "Request a quote"
							add_filter('woocommerce_product_single_add_to_cart_text', array($this,'b2bking_replace_add_to_cart_text'));
							add_filter('woocommerce_product_add_to_cart_text', array($this,'b2bking_replace_add_to_cart_text'));

							add_action('wp_loaded', function(){
								$offer_in_cart = 'no';
								if ($this->user_has_offer_in_cart() === 'yes'){
									$offer_in_cart = 'yes';
								}
								if ($offer_in_cart === 'no'){

									if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){
										// Hide prices on cart page
										add_filter( 'woocommerce_cart_item_price', array($this, 'b2bking_hide_prices_cart'), 1000, 3 );
										add_filter( 'woocommerce_cart_item_subtotal', array($this, 'b2bking_hide_prices_cart'), 1000, 3 );
										add_filter( 'woocommerce_cart_subtotal', array($this, 'b2bking_hide_prices_cart'), 1000, 3 );
										add_filter( 'woocommerce_cart_total', array($this, 'b2bking_hide_prices_cart'), 1000, 3 );
									}

									// If go to checkout page, redirect to cart
									add_action( 'template_redirect', array($this, 'b2bking_checkout_redirect_to_cart'), 100 );
									// Hide proceed to checkout button regular cart
									remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 ); 
									// hide proceed to checkout button blocks cart
									add_action('wp_head', array($this,'b2bking_hide_proceed_checkout_blocks'));

									if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1 or !apply_filters('b2bking_show_prices_quote_shows_cart_totals', true)){

										// Hide cart totals entirely
										remove_action( 'woocommerce_cart_collaterals', 'woocommerce_cart_totals', 10 );
										add_action('woocommerce_before_cart_totals', function(){
											ob_start();
										});
										add_action('woocommerce_after_cart_totals', function(){
											$discard = ob_get_clean();
										});
									}
								}
							});


							// Hide "on sale" flash badge
							if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){

								add_filter( 'woocommerce_sale_flash', '__return_false' );
							}
							// Hide coupon
							add_filter( 'woocommerce_coupons_enabled', '__return_false' );


							// If user is logged in, disable offers, bulk order form, purchase lists as they no longer apply
							add_action('wp_loaded', function(){
								if (is_user_logged_in()){
									
									// Get current user
									$user_id = get_current_user_id();

							    	$user_id = b2bking()->get_top_parent_account($user_id);
							    	set_transient('b2bking_replace_prices_quote_user_'.$user_id, 'yes');

							    	// check if the user has an offer in CART. IF YES, make all other items except offers unpurchasable and disable purchase restrictions

							    	if ($this->user_has_offer_in_cart() === 'yes'){
							    		
							    		// make all other items unpurchasable
							    		add_filter( 'woocommerce_is_purchasable', array($this, 'b2bking_disable_purchasable_except_offers'), 9999, 2);
							    		add_filter( 'woocommerce_variation_is_purchasable', array($this, 'b2bking_disable_purchasable_except_offers'), 9999, 2);

							    		// show message in cart that other products can't be added to quote while you have an offer in cart
							    		add_action( 'woocommerce_before_cart', array($this,'b2bking_cannot_quote_offer_cart_message'), 100);

							    		// remove quote button in cart
							    		remove_action( 'woocommerce_cart_actions', array($this, 'b2bking_add_request_quote_button') );
							    		remove_filter('render_block', array($this, 'b2bking_add_request_quote_button_cart_block'), 10, 2);

							    		// show message on single product page 
							    		add_action( 'woocommerce_single_product_summary', array($this, 'unavailable_product_display_message'), 20 );
							    		
							    	}
								
								}
							});
							

						}
						

						/* Groups */
						// Set up product/category user/user group visibility rules
						if (intval(get_option('b2bking_disable_visibility_setting', 0)) === 0){
							if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){
								// Hide Categories
								// if caching is enabled
								if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){
									if (intval(get_option( 'b2bking_hidden_has_priority_setting', 0 )) === 0){
										if (intval(get_option( 'b2bking_completely_category_restrict', 1 )) === 1){
											add_filter( 'get_terms_args', array($this,'b2bking_categories_restrict'), 10, 2 );
										}
									}
								}

								// Apply in wordpress regular posts search
								add_filter('pre_get_posts', array($this, 'b2bking_visibility_wordpress_posts'), 9999, 2);

								// Uncode theme compatibility
								add_action( 'uncode_get_uncode_index_args', array($this, 'b2bking_product_categories_visibility_rules_shortcode'), 9999, 1 );

								// Hide products
								add_action( 'woocommerce_product_query', array($this, 'b2bking_product_categories_visibility_rules'), 9999, 1 );
								add_action( 'woocommerce_product_related_posts_query', array($this, 'b2bking_product_categories_visibility_rules'), 9999, 1 );
								add_action( 'woocommerce_shortcode_products_query', array($this, 'b2bking_product_categories_visibility_rules_shortcode'), 9999, 1 );
								add_filter( 'woocommerce_products_widget_query_args', array($this, 'b2bking_product_categories_visibility_rules_shortcode'), 99999, 1);
								add_filter( 'woocommerce_top_rated_products_widget_args', array($this, 'b2bking_product_categories_visibility_rules_shortcode'), 99999, 1);
								add_filter( 'woocommerce_recently_viewed_products_widget_query_args', array($this, 'b2bking_product_categories_visibility_rules_shortcode'), 99999, 1);

								// general product is visible filter ( works for upsells, crosssells and more )
								add_filter('woocommerce_product_is_visible', array($this, 'b2bking_product_categories_visibility_rules_productfilter'), 100, 2);

								// Change category count
								// can be deactivated to improve speed for product visibility
								if (apply_filters('b2bking_apply_category_count', false)){
									add_filter( 'get_terms', array($this, 'b2bking_category_count_filter'), 9999, 2 );
								}
								
								// If user/group accesses invisible product, redirect to my account
								add_action( 'template_redirect', array($this, 'b2bking_invisible_product_redirection_to_account'), 100 );

								// add compatibility with bricks builder queries
								add_filter( 'bricks/posts/query_vars', array($this, 'bricks_postin'), 10, 3);
							}
						}

						// bricks builder compatibility for logged out user options
						add_filter( 'bricks/posts/query_vars', array($this, 'bricks_postin_loggedout'), 10, 3);

						// Page visibility
						add_filter( 'wp_page_menu_args', array($this, 'hide_invisible_pages_menu'), 999, 1 );
						add_filter( 'wp_get_nav_menu_items', array($this, 'hide_invisible_pages_menu_2'), null, 3 );

						add_action( 'template_redirect', array($this, 'b2bking_invisible_page_redirection_to_account'), 100 );


						// enable dynamic rules IF: plugin is in B2B mode, OR hybrid mode + b2b user OR hybrid mode + option
						if (get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled'){

							$run_in_api_requests = true;
							if (apply_filters('b2bking_force_cancel_api_requests', false)){
								if (b2bking()->is_rest_api_request()){
									$run_in_api_requests = false;
								}
							}

							if ($run_in_api_requests){
								/* Dynamic Rules */
								// Dynamic rule Discounts via fees 
								if (intval(get_option('b2bking_disable_dynamic_rule_discount_setting', 0)) === 0){
									if (get_option('b2bking_have_discount_rules', 'yes') === 'yes'){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_discount_rules_list', 'yes');
										if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){
											add_action('woocommerce_cart_calculate_fees' , array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_cart_discount'));

										}
									}
								}
								// Dynamic rule BOGO discounts
								if (get_option('b2bking_have_bogo_discount_rules', 'yes') === 'yes'){
									// check if the user's ID or group is part of the list.
									$list = get_option('b2bking_have_bogo_discount_rules_list', 'yes');
									if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){
										add_action('woocommerce_cart_calculate_fees' , array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_bogo_discount'));
									}
								}
								// Dynamic rule discounts via sale/regular price
								// Generate "regular price" dynamically
								if (intval(get_option('b2bking_disable_dynamic_rule_discount_sale_setting', 0)) === 0){
									if (get_option('b2bking_have_discount_everywhere_rules', 'yes') === 'yes'){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_discount_everywhere_rules_list', 'yes');

										if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){

											add_filter( 'woocommerce_product_get_regular_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_regular_price'), 9999, 2 );
											add_filter( 'woocommerce_product_variation_get_regular_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_regular_price'), 9999, 2 );
											// Generate "sale price" dynamically
											add_filter( 'woocommerce_product_get_sale_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_sale_price'), 99999, 2 );
											add_filter( 'woocommerce_product_variation_get_sale_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_sale_price'), 99999, 2 );
											add_filter( 'woocommerce_variation_prices_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_sale_price'), 99999, 2 );
											add_filter( 'woocommerce_variation_prices_sale_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_sale_price'), 99999, 2 );
											add_filter( 'woocommerce_get_variation_prices_hash', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_sale_price_variation_hash'), 99, 1);

											// Displayed formatted regular price + sale price
											add_filter( 'woocommerce_get_price_html', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_display_dynamic_price'), 9999, 2 );
											// Set sale price in Cart
											add_action( 'woocommerce_before_calculate_totals', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_display_dynamic_price_in_cart'), 99999, 1 );
											// Function to make this work for MiniCart as well
											add_filter('woocommerce_cart_item_price',array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_display_dynamic_price_in_cart_item'),9999,3);
											
											// Change "Sale!" badge text
											add_filter('woocommerce_sale_flash', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_display_dynamic_sale_badge'), 999999, 3);
											// woodmart integration - sets the product sale flash for woodmart
											add_filter('woodmart_product_label_output', array($this, 'woodmart_b2bking_product_badge'), 10, 1);

											// allow negative discounts
											add_filter('b2bking_dynamic_recalculate_sale_price_display', array($this, 'b2bking_allow_negative_discounts'), 10, 3);
											// fix for variable products with same price on all variations
											add_filter('woocommerce_variable_price_html', array($this,'b2bking_negative_discount_variation_price_fix'), 10, 2);
											// mark these products as NOT on sale
											add_filter('woocommerce_product_is_on_sale', array($this, 'b2bking_not_on_sale_raise_price'), 1000, 2);

										}
									}
								}
								
								if (intval(get_option('b2bking_disable_dynamic_rule_addtax_setting', 0)) === 0){
									// check the number of rules saved in the database
									if (get_option('b2bking_have_add_tax_rules', 'yes') === 'yes'){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_add_tax_rules_list', 'yes');
										if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){
											// Dynamic rule add tax / fee (percentage)
											add_action('woocommerce_cart_calculate_fees' , array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_add_tax_fee'));
										}
									}
								}
								if (intval(get_option('b2bking_disable_dynamic_rule_fixedprice_setting', 0)) === 0){
									// check the number of rules saved in the database
									if (get_option('b2bking_have_fixed_price_rules', 'yes') === 'yes'){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_fixed_price_rules_list', 'yes');
										if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){
											// Simple, grouped and external products
											add_filter('woocommerce_product_get_price', array( 'B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_fixed_price' ), 9999, 2 );
											add_filter('woocommerce_product_get_regular_price', array( 'B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_fixed_price' ), 9999, 2 );
											// Variations 
											add_filter('woocommerce_product_variation_get_regular_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_fixed_price' ), 9999, 2 );
											add_filter('woocommerce_product_variation_get_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_fixed_price' ), 9999, 2 );
											add_filter( 'woocommerce_variation_prices_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_fixed_price'), 9999, 2 );
											add_filter( 'woocommerce_variation_prices_regular_price', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_fixed_price'), 9999, 2 );

											// variable cache bust
											add_filter('woocommerce_variable_price_html', array($this,'b2bking_variable_cache_bust'), 10, 2);

										}
									}
								}


								if (intval(get_option('b2bking_disable_dynamic_rule_freeshipping_setting', 0)) === 0){
									if (get_option('b2bking_have_free_shipping_rules', 'yes') === 'yes'){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_free_shipping_rules_list', 'yes');
										if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){
											// Dynamic rule Free Shipping
											WC_Cache_Helper::get_transient_version( 'shipping', true );
											add_filter( 'woocommerce_shipping_free_shipping_is_available', array('B2bking_Dynamic_Rules','b2bking_dynamic_rule_free_shipping'), 99999, 3 );

										
										}
									}
								}
								
								if (intval(get_option('b2bking_disable_dynamic_rule_hiddenprice_setting', 0)) === 0){
									if (get_option('b2bking_have_hidden_price_rules', 'yes') === 'yes'){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_hidden_price_rules_list', 'yes');
										if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){
											// Dynamic rule Hidden price
											add_filter( 'woocommerce_get_price_html', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_hidden_price'), 99999, 2 );
											add_filter( 'woocommerce_variation_price_html', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_hidden_price'), 99999, 2 );
											// Dynamic rule Hidden price - disable purchasable
											add_filter( 'woocommerce_is_purchasable', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_hidden_price_disable_purchasable'), 10, 2);
											add_filter( 'woocommerce_variation_is_purchasable', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_hidden_price_disable_purchasable'), 10, 2);
										}
									}
								}

								// Quotes on Specific Products
								if (get_option('b2bking_have_quotes_products_rules', 'yes') === 'yes'){
									// check if the user's ID or group is part of the list.
									$list = get_option('b2bking_have_quotes_products_rules_list', 'yes');
									if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){

										// Hide prices on quote products
										if (apply_filters('b2bking_quote_products_rules_hide_price', true)){
											if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){
												// Hide prices
												add_filter( 'woocommerce_get_price_html', array($this, 'b2bking_hide_prices_request_quote_products'), 99999, 2 );
												add_filter( 'woocommerce_variation_get_price_html', array($this, 'b2bking_hide_prices_request_quote_products'), 99999, 2 );
											}
										}

										// Replace add to cart with quote on these products
										add_filter('woocommerce_product_single_add_to_cart_text', array($this,'b2bking_replace_add_to_cart_text_products'), 10, 2);
										add_filter('woocommerce_product_add_to_cart_text', array($this,'b2bking_replace_add_to_cart_text_products'), 10, 2);

										
										add_filter('woocommerce_product_get_stock_status', array($this,'b2bking_quote_product_stock_status'), 10, 2);
										add_filter('woocommerce_product_variation_get_stock_status', array($this,'b2bking_quote_product_stock_status'), 10, 2);

										// Make products unpurchasable alternatively
										if (apply_filters('b2bking_remove_tiered_table_quote_mode', true)){
											if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){
												add_filter('b2bking_disable_price_table', array($this,'b2bking_disable_tiered_price_table_quote_products'), 10, 2);
											}
										}

										// Hide "on sale" flash badge
										if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){
											add_filter( 'woocommerce_sale_flash', array($this,'b2bking_hide_sale_flash_quote_products'), 10, 3);
										}
																	
										add_action('wp_loaded', function(){
											// if have quote product in cart
											if (b2bking()->user_has_p_in_cart('quote') === 'yes'){

												// hide "sorry we do not have enough" in cart message
												add_filter('woocommerce_cart_item_required_stock_is_not_enough','__return_false');

												if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){
													// Hide prices on cart page
													add_filter( 'woocommerce_cart_item_price', array($this, 'b2bking_hide_prices_cart'), 1000, 3 );
													add_filter( 'woocommerce_cart_item_subtotal', array($this, 'b2bking_hide_prices_cart'), 1000, 3 );
													add_filter( 'woocommerce_cart_subtotal', array($this, 'b2bking_hide_prices_cart'), 1000, 3 );
													add_filter( 'woocommerce_cart_total', array($this, 'b2bking_hide_prices_cart'), 1000, 3 );
												}

												if (apply_filters('b2bking_prevent_checkout_quote', true)){
													// If go to checkout page, redirect to cart
													add_action( 'template_redirect', array($this, 'b2bking_checkout_redirect_to_cart'), 100 );
													// Hide proceed to checkout button
													remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 ); 
													// Hide cart totals entirely
													remove_action( 'woocommerce_cart_collaterals', 'woocommerce_cart_totals', 10 );
													add_action('woocommerce_before_cart_totals', function(){
														ob_start();
													});
													add_action('woocommerce_after_cart_totals', function(){
														$discard = ob_get_clean();
													});

													// prevent regular cart products from being purchased
													add_filter( 'woocommerce_is_purchasable', array($this, 'b2bking_prevent_cart_product_purchasable'), 10, 2);
													add_filter( 'woocommerce_variation_is_purchasable', array($this, 'b2bking_prevent_cart_product_purchasable'), 10, 2);
												}

												// blocks cart
												if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){
													add_action( 'wp_head', array($this, 'b2bking_blocks_cart_hide_prices_quote'));
												}

												

												// show message in cart that other products can't be added to quote while you have an offer in cart
												//add_action( 'woocommerce_before_cart', array($this,'b2bking_cannot_quote_offer_cart_message_products'), 100); // maybe do not show, could overload UI

												// show message on single product page 
												add_action( 'b2bking_product_page_error_message', array($this, 'unavailable_product_display_message_products'), 20 );

												// Hide coupon
												add_filter( 'woocommerce_coupons_enabled', '__return_false' );
											}

											// if have cart product in cart
											if (b2bking()->user_has_p_in_cart('cart') === 'yes'){
												// cannot add quote products to cart
												add_filter( 'woocommerce_is_purchasable', array($this, 'b2bking_prevent_quote_product_purchasable'), 10, 2);
												add_filter( 'woocommerce_variation_is_purchasable', array($this, 'b2bking_prevent_quote_product_purchasable'), 10, 2);

												// show message on single product page 
												add_action( 'b2bking_product_page_error_message', array($this, 'unavailable_product_display_message_products_quote'), 20 );
											}
										});

									}
								}

								if (intval(get_option('b2bking_disable_dynamic_rule_unpurchasable_setting', 0)) === 0){
									if (get_option('b2bking_have_unpurchasable_rules', 'yes') === 'yes'){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_unpurchasable_rules_list', 'yes');
										if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){
											// Dynamic rule Hidden price - disable purchasable
											add_filter( 'woocommerce_is_purchasable', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_unpurchasable_disable_purchasable'), 10, 2);
											add_filter( 'woocommerce_variation_is_purchasable', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_unpurchasable_disable_purchasable'), 10, 2);
										}
									}
								}

								$haveminmaxstep = 'no';

								if (intval(get_option('b2bking_disable_dynamic_rule_minmax_setting', 0)) === 0){
									if (get_option('b2bking_have_minmax_rules', 'yes') === 'yes' or apply_filters('b2bking_auto_activate_minmaxstep_rules_meta', true)){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_minmax_rules_list', 'yes');
										if (($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes') or apply_filters('b2bking_auto_activate_minmaxstep_rules_meta', true)){
											// Dynamic rule Minimum Order

											if (b2bking()->has_blocks_cart() || b2bking()->has_blocks_checkout()){
												add_action( 'woocommerce_check_cart_items', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_minmax_order_amount') );
												
											} else {
												add_action( 'woocommerce_checkout_process', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_minmax_order_amount') );
												add_action( 'woocommerce_before_cart' , array('B2bking_Dynamic_Rules', 'b2bking_dynamic_minmax_order_amount'));
												add_action( 'woocommerce_before_checkout_form' , array('B2bking_Dynamic_Rules', 'b2bking_dynamic_minmax_order_amount'));
											}
										
											// set quantity inputs
											add_filter( 'woocommerce_quantity_input_args', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_minmax_order_amount_quantity'), 100, 2 );
											add_filter( 'woocommerce_available_variation', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_minmax_order_amount_quantity_variation'), 100, 3 );

											$haveminmaxstep = 'yes';
										}
									}
								}

								if (intval(get_option('b2bking_disable_dynamic_rule_requiredmultiple_setting', 0)) === 0){
									if (get_option('b2bking_have_required_multiple_rules', 'yes') === 'yes' or apply_filters('b2bking_auto_activate_minmaxstep_rules_meta', true)){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_required_multiple_rules_list', 'yes');
										if (($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes') or apply_filters('b2bking_auto_activate_minmaxstep_rules_meta', true)){ // have added meta_step, so now activate automatically
											// Dynamic rule Required Multiple
											add_action( 'woocommerce_check_cart_items', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_required_multiple') );

											// add quantity step in product page
											if(apply_filters('b2bking_qty_required_multiple_product_page', true)){
												add_filter( 'woocommerce_quantity_input_args', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_required_multiple_quantity'), 10, 2 );
												add_filter( 'woocommerce_available_variation', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_required_multiple_quantity_variation'), 10, 3 );

												$haveminmaxstep = 'yes';

											}
										}
									}
								}

								if ($haveminmaxstep === 'yes'){
									// Set product quantity added to cart (handling ajax add to cart)
									add_filter( 'woocommerce_add_to_cart_quantity',array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_required_multiple_quantity_number'), 10, 2 );
								}


								if (intval(get_option('b2bking_disable_dynamic_rule_zerotax_setting', 0)) === 0){
									if (get_option('b2bking_have_tax_exemption_rules', 'yes') === 'yes'){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_tax_exemption_rules_list', 'yes');
										if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){
											// Dynamic rule Zero Tax Product
											add_filter( 'woocommerce_product_get_tax_class', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_zero_tax_product'), 10, 2 );
											add_filter( 'woocommerce_product_variation_get_tax_class', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_zero_tax_product'), 10, 2 );
										}
									}
								}

								if (get_option('b2bking_have_renamep_rules', 'yes') === 'yes'){
									// check if the user's ID or group is part of the list.
									$list = get_option('b2bking_have_renamep_rules_list', 'yes');
									if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){

										if ($this->dynamic_rename_purchase_order_method() !== 'no'){
											add_filter( 'woocommerce_available_payment_gateways', function($available_gateways){
												if (! is_checkout() ) { return $available_gateways; }

												$available_gateways = $this->dynamic_rename_purchase_order_method($available_gateways);

												return $available_gateways;
												
											});	
										}
									}
								}
								

								if (intval(get_option('b2bking_disable_dynamic_rule_taxexemption_setting', 0)) === 0){
									if (get_option('b2bking_have_tax_exemption_user_rules', 'yes') === 'yes'){
										// check if the user's ID or group is part of the list.
										$list = get_option('b2bking_have_tax_exemption_user_rules_list', 'yes');
										if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){
											// Dynamic rule Tax Exemption (user)
											add_action( 'init', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_tax_exemption') );

											add_filter( 'option_woocommerce_tax_display_cart', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_tax_exemption_prices_excl_tax_in_shop') );
											add_filter( 'option_woocommerce_tax_display_shop', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_tax_exemption_prices_excl_tax_in_shop') );
											
											add_action( 'woocommerce_cart_totals_before_shipping', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_tax_exemption_fees_display_only'));
											add_action( 'woocommerce_review_order_before_shipping', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_tax_exemption_fees_display_only'));

											// Clear user tax exemption cache when checkout is rendered
											add_action( 'woocommerce_checkout_update_order_review', array($this, 'b2bking_clear_tax_cache_checkout'), 1 );

											// Avalara Avatax integration
											add_filter( 'wc_avatax_is_enabled', array('B2bking_Dynamic_Rules', 'b2bking_avalara_tax_exemption'));
											

										}
									}
								}

								if (get_option('b2bking_have_currency_rules', 'yes') === 'yes'){
									// check if the user's ID or group is part of the list.
									$list = get_option('b2bking_have_currency_rules_list', 'yes');
									if ($this->b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list) === 'yes'){

										add_filter('woocommerce_currency_symbol', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_currency_symbol'), 10, 2);

										add_filter( 'option_woocommerce_currency', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_currency'));
									}
								}
							}
							
							

						
						}
						/* Set Tiered Pricing via Fixed Price Dynamic Rule */
						if (intval(get_option('b2bking_disable_group_tiered_pricing_setting', 0)) === 0){
							
							// raise price percentage integration tiered
							add_filter('b2bking_tiered_pricing_table_price', array($this, 'b2bking_tiered_raise_integration'), 10, 4);

							add_filter('woocommerce_product_get_price', array($this, 'b2bking_tiered_pricing_fixed_price'), 1001, 2 );
							add_filter('woocommerce_product_get_regular_price', array($this, 'b2bking_tiered_pricing_fixed_price'), 1001, 2 );
							// Variations 
							add_filter('woocommerce_product_variation_get_regular_price', array($this, 'b2bking_tiered_pricing_fixed_price'), 1001, 2 );
							add_filter('woocommerce_product_variation_get_price', array($this, 'b2bking_tiered_pricing_fixed_price'), 1001, 2 );
							add_filter( 'woocommerce_variation_prices_price', array($this, 'b2bking_tiered_pricing_fixed_price'), 1001, 2 );
							add_filter( 'woocommerce_variation_prices_regular_price', array($this, 'b2bking_tiered_pricing_fixed_price'), 1001, 2 );

							// fix for iconic attributes plugin: WooCommerce Attribute Swatches by Iconic
							add_filter('iconic_was_cart_item_price', array($this,'iconic_attribute_swatches_price_disable_cart_item_price'), 100, 3);

							// OPTIONS / ADDONS COMPATIBILITY
							if (intval(get_option( 'b2bking_product_options_compatibility_setting', 0 )) === 1){
								// tiered pricing compatibility addons module
								add_filter('b2bking_tiered_price_displayed', array($this, 'b2bking_tiered_pricing_compatibility_addons_options'), 10, 3 );
							}

							// WPML INTEGRATION MULTI CURRENCY TIERED PRICING
							add_filter('b2bking_tiered_price_displayed', array($this, 'b2bking_wpml_multicurrency_tiered_integration'), 100, 3);

							// Show table for tiered prices in product / variation page 
							add_action('woocommerce_after_add_to_cart_button', array($this,'b2bking_show_tiered_pricing_table'));
							add_filter( 'woocommerce_available_variation', array($this,'b2bking_show_tiered_pricing_table_variation'), 10, 3 );

							// Show custom info table in product page
							add_action('woocommerce_after_add_to_cart_button', array($this,'b2bking_show_custom_information_table'));
							// add hook for custom usage by customers
							add_action('b2bking_show_information_table', array($this,'b2bking_show_custom_information_table')); 


							/* Set Individual Product Pricing (via product tab) */
							add_filter('woocommerce_product_get_price', array($this, 'b2bking_individual_pricing_fixed_price'), 999, 2 );
							add_filter('woocommerce_product_get_regular_price', array($this, 'b2bking_individual_pricing_fixed_price'), 999, 2 );
							// Variations 
							add_filter('woocommerce_product_variation_get_regular_price', array($this, 'b2bking_individual_pricing_fixed_price'), 999, 2 );
							add_filter('woocommerce_product_variation_get_price', array($this, 'b2bking_individual_pricing_fixed_price'), 999, 2 );
							add_filter( 'woocommerce_variation_prices_price', array($this, 'b2bking_individual_pricing_fixed_price'), 999, 2 );
							add_filter( 'woocommerce_variation_prices_regular_price', array($this, 'b2bking_individual_pricing_fixed_price'), 999, 2 );
							// Bundle integration
							add_filter( 'woocommerce_bundled_item_price', array($this, 'b2bking_individual_pricing_fixed_price_bundle'), 99999, 4 );
						//	add_filter( 'woosb_get_price', array($this, 'b2bking_individual_pricing_fixed_price_bundle'), 99, 4 );


							// Set sale price as well
							add_filter( 'woocommerce_product_get_sale_price', array($this, 'b2bking_individual_pricing_discount_sale_price'), 9999, 2 );
							add_filter( 'woocommerce_product_variation_get_sale_price', array($this, 'b2bking_individual_pricing_discount_sale_price'), 9999, 2 );
							add_filter( 'woocommerce_variation_prices_price', array($this, 'b2bking_individual_pricing_discount_sale_price'), 9999, 2 );
							add_filter( 'woocommerce_variation_prices_sale_price', array($this, 'b2bking_individual_pricing_discount_sale_price'), 9999, 2 );
							
							// display html
							// Displayed formatted regular price + sale price
							add_filter( 'woocommerce_get_price_html', array($this, 'b2bking_individual_pricing_discount_display_dynamic_price'), 999, 2 );
							// Set sale price in Cart
							add_action( 'woocommerce_before_calculate_totals', array($this, 'b2bking_individual_pricing_discount_display_dynamic_price_in_cart'), 999, 1 );

							// Function to make this work for MiniCart as well
							add_filter('woocommerce_cart_item_price',array($this, 'b2bking_individual_pricing_discount_display_dynamic_price_in_cart_item'),999,3);

							add_filter( 'woocommerce_get_variation_prices_hash', array('B2bking_Dynamic_Rules', 'b2bking_dynamic_rule_discount_sale_price_variation_hash'), 99, 1);

							// deactivated probable performance issues
							//add_filter( 'woocommerce_get_variation_prices_hash', array($this, 'b2bking_woocs_variation_prices_hash'), 99999, 1);
							// variable products woocs integration
							
							if (defined('WOOCS_VERSION')){
								if (b2bking()->is_b2b_user()){
									add_filter( 'woocommerce_get_variation_prices_hash', array($this, 'b2bking_woocs_variation_prices_hash'), 99999, 1);
									add_filter('woocommerce_get_price_html', function($price_html, $product){
										if ($product->is_type('variable')){
											$min_price = -1;
											$max_price = -1;
											$reg_price = -1;

											if (is_a(WC()->customer, 'WC_Customer')){
												$is_exempt = WC()->customer->get_is_vat_exempt(); // new check for woocs professional, not sure if woocs free needs it, or if it may create issues.
											} else {
												$is_exempt = false;
											}

											foreach ($product->get_children() as $child_id){
												$variation = wc_get_product($child_id);
												
												$variationprice = $variation->get_regular_price();
												if ($is_exempt){
													$variationprice = wc_get_price_excluding_tax($variation, array('qty' => 1, 'price' => $variationprice));
												}
												
												if (!empty($variationprice)){
													$reg_price = $variationprice;
												}
												if ($variation->is_on_sale()){
													$variationprice = $variation->get_sale_price();
													if ($is_exempt){
														$variationprice = wc_get_price_excluding_tax($variation, array('qty' => 1, 'price' => $variationprice));
													}
												}
												if ($min_price === -1 || $min_price > $variationprice){
													$min_price = $variationprice;
												}
												if ($max_price === -1 || $max_price < $variationprice){
													$max_price = $variationprice;
												}
											}

											if (floatval($min_price) === floatval(0)){
												$min_price = $max_price;
											}
											if (floatval($max_price) === floatval(0)){
												$max_price = $min_price;
											}
											
											if ($min_price === $max_price){
												$price_html = wc_price( $max_price );
												if ($product->is_on_sale() || ($reg_price > $max_price && $reg_price !== -1) ){

													$price_html = wc_format_sale_price($reg_price, $max_price);
												}
											} else {
												$price_html = b2bking()->format_price_range($min_price, $max_price).$product->get_price_suffix();
											}
											
										}
										
										return $price_html;
									}, 100000, 2);
								}
							}
							
							
							
							// subscriptions free trial integration
							if (class_exists('WC_Subscriptions_Cart')){
								add_action( 'woocommerce_before_calculate_totals', array($this, 'add_calculation_price_filter'), 10 );
								add_action( 'woocommerce_calculate_totals', array($this, 'remove_calculation_price_filter'), 10 );
								add_action( 'woocommerce_after_calculate_totals', array($this, 'remove_calculation_price_filter'), 10 );
							}


						}

						add_action( 'woocommerce_before_mini_cart', function(){
							if (apply_filters('b2bking_calculate_totals_before_mini_cart', true)){
								WC()->cart->calculate_totals();
							}
						}, 999, 0);

						if (intval(get_option('b2bking_disable_shipping_control_setting', 0)) === 0){
							// Disable shipping methods based on group rules
							WC_Cache_Helper::get_transient_version( 'shipping', true );
							add_filter( 'woocommerce_package_rates', array($this, 'b2bking_disable_shipping_methods'), 9999 );
							add_filter( 'woocommerce_package_rates', array($this, 'b2bking_disable_shipping_methods'), 1 );

							// overwrite hide shipping when free to make it work with b2bking
							add_filter('option_woocommerce_shipping_hide_rates_when_free', [$this, 'b2bking_overwrite_hide_shipping_when_free'], 10, 1);
							add_filter('woocommerce_package_rates', [$this, 'b2bking_overwrite_hide_shipping_when_free_higher_priority'], 99999, 2);
						}
						
						// Payment method discounts
						add_filter('woocommerce_cart_calculate_fees', array($this,'b2bking_payment_method_discounts'), 9999, 1);
						add_action('woocommerce_checkout_order_processed', array( $this, 'b2bking_update_order_data' ), 10 );
						add_action('woocommerce_blocks_checkout_order_processed', array( $this, 'b2bking_update_order_data' ), 10 );

						// Enqueue resources
						add_action('wp_enqueue_scripts', array($this, 'enqueue_public_resources'));

					}

					/* Add items to "My Account" */
					// Add custom endpoints
					add_action( 'init', array($this, 'b2bking_custom_endpoints') );

					// make bulkorder shortcode work for all users
					// Add bulk order shortcode
					add_action( 'init', array($this, 'b2bking_bulkorder_shortcode'));
					// Add csv order shortcode
					add_action( 'init', array($this, 'b2bking_csvorder_shortcode'));
					add_action( 'wp', array($this, 'b2bking_handle_file_upload'));
					// csv order show stock error
					add_filter('woocommerce_cart_product_not_enough_stock_message', array($this, 'b2bking_csvorder_not_enough_stock'));
					add_filter('woocommerce_cart_product_not_enough_stock_already_in_cart_message', array($this, 'b2bking_csvorder_not_enough_stock'));

					// Add custom fields to billing
					add_filter('woocommerce_billing_fields', array($this, 'b2bking_custom_woocommerce_billing_fields'), 9999, 1);
					// Add checkout VAT VIES validation + other validations
					add_action('woocommerce_after_checkout_validation', array($this,'b2bking_checkout_vat_vies_validation'), 10, 2);

					add_action('woocommerce_init', array($this, 'b2bking_custom_woocommerce_billing_fields_blocks'));


					// Check if plugin status is B2B OR plugin status is Hybrid and user is B2B user.
					if (get_option( 'b2bking_plugin_status_setting', 'b2b' ) === 'b2b' || (get_option( 'b2bking_plugin_status_setting', 'b2b' ) === 'hybrid' && (get_user_meta( $user_data_current_user_id, 'b2bking_b2buser', true ) === 'yes'))){

						if (intval(get_option('b2bking_disable_registration_setting', 0)) === 0){
							/* Custom Fields and Registration Fields */
							// Display custom registration data in My account details
							add_action('woocommerce_edit_account_form', array($this,'b2bking_display_custom_registration_fields'));
							// Save custom fields after edit
							add_action( 'woocommerce_save_account_details', array($this,'b2bking_save_custom_registration_fields_edit'), 10, 1 );
							// Validate custom fields (especially VAT) on account edit
							add_action( 'woocommerce_save_account_details_errors',array($this,'b2bking_save_custom_registration_fields_validate'), 10, 1 );
							// Validate custom fields (especially VAT) on address edit
							add_action( 'woocommerce_after_save_address_validation',array($this,'b2bking_save_custom_registration_fields_validate'),10,1);
							
							// Add custom fields to order meta
							add_action( 'woocommerce_checkout_update_order_meta',  array($this,'b2bking_add_custom_fields_to_order_meta') );

						}

						/* Add items to "My Account" */
						// Add custom items to My account WooCommerce user menu
						add_filter( 'woocommerce_account_menu_items', array($this, 'b2bking_my_account_custom_items'), 100, 1 );
												// adds "id" query var to WP list. Makes the query recognizable by wp
						add_filter( 'query_vars', array($this, 'b2bking_add_query_vars_filter') );
						if (intval(get_option('b2bking_force_permalinks_setting', 1)) === 0){
							// Add redirects by default to prevent 404 problems
							add_action ('template_redirect', array($this, 'b2bking_redirects_my_account_default'));
						}

						if (intval(get_option('b2bking_force_permalinks_flushing_setting', 1)) === 1){
							add_action( 'init', array($this, 'force_permalinks_rewrite') );
						}
						if (intval(get_option('b2bking_enable_conversations_setting', 1)) === 1){
							/* Conversations */
							// Add content to conversations endpoint
							add_action( 'woocommerce_account_'.get_option('b2bking_conversations_endpoint_setting','conversations').'_endpoint', array($this, 'b2bking_conversations_endpoint_content') );
							// Add content to individual conversation endpoint
							add_action( 'woocommerce_account_'.get_option('b2bking_conversation_endpoint_setting','conversation').'_endpoint', array($this, 'b2bking_conversation_endpoint_content') );
						}

						/* Offers */

						// Credit change price in cart
						if (intval(get_option('b2bking_enable_company_credit_setting', 1)) === 1){
							add_action( 'woocommerce_before_calculate_totals', array($this, 'b2bking_credit_change_price_cart'), 1 );
							add_action( 'woocommerce_before_calculate_totals', array($this, 'b2bking_credit_change_price_cart'), 9999999 );
							add_action( 'woocommerce_after_calculate_totals', array($this, 'b2bking_credit_change_price_cart'), 9999999 );
						}

						// Change product price in the cart for offers AND CREDIT (cannot be conditioned on offers enabled)
						if (intval(get_option('b2bking_enable_offers_setting', 1)) === 1){
							add_action( 'woocommerce_before_calculate_totals', array($this, 'b2bking_offer_change_price_cart') );
							// Add content to offers endpoint
							add_action( 'woocommerce_account_'.get_option('b2bking_offers_endpoint_setting','offers').'_endpoint', array($this, 'b2bking_offers_endpoint_content') );
							// Change product price in the minicart for offers
							add_filter('woocommerce_cart_item_price', array($this, 'b2bking_offer_change_price_minicart'), 10, 3);
							// Add offer item metadata to order (checkout + backend)
							add_action( 'woocommerce_checkout_create_order_line_item', array($this,'b2bking_add_item_metadata_to_order'), 20, 4 );
							// Display offer item metadata in cart
							add_filter('woocommerce_cart_item_name', array($this, 'b2bking_display_metadata_cart'),1,3);
							// Add shortcode
							add_action( 'init', array($this, 'b2bking_offers_shortcode'));

							// if offer has 1 item, set that item to be offer image
							add_filter( 'woocommerce_cart_item_thumbnail', array($this,'filter_offer_image'), 10, 3);

							// new offer system, item name change offers
							add_filter( 'woocommerce_cart_item_name', array($this,'filter_offer_name'), 10, 3);
							add_filter( 'woocommerce_cart_item_price', array($this,'offer_cart_item_price'), 100000, 3);
							add_filter( 'woocommerce_cart_item_subtotal', array($this,'offer_cart_item_price_subtotal'), 100000, 3);
							add_filter( 'woocommerce_cart_item_class', [ $this, 'cart_item_class' ], 10, 2 );
							add_filter( 'woocommerce_mini_cart_item_class', [ $this, 'cart_item_class' ], 10, 2 );
							add_filter( 'woocommerce_order_item_class', [ $this, 'cart_item_class' ], 10, 2 );
							add_filter( 'woocommerce_cart_item_quantity', [ $this, 'cart_item_quantity' ], 10, 3 );
							add_action( 'woocommerce_cart_item_removed', [ $this, 'cart_item_removed' ], 10, 2 );
							add_action('woocommerce_before_calculate_totals', [$this, 'set_specific_items_to_free'], 10, 1);


							
						}

						if (intval(get_option('b2bking_enable_bulk_order_form_setting', 1)) === 1){
							/* Bulk order */
							// Add content to bulk order endpoint
							add_action( 'woocommerce_account_'.get_option('b2bking_bulkorder_endpoint_setting','bulkorder').'_endpoint', array($this, 'b2bking_bulkorder_endpoint_content') );
						}
					
						if (intval(get_option('b2bking_enable_subaccounts_setting', 1)) === 1){
							/* Subaccount */
							// Add content to subaccounts endpoint
							add_action( 'woocommerce_account_'.get_option('b2bking_subaccounts_endpoint_setting','subaccounts').'_endpoint', array($this, 'b2bking_subaccounts_endpoint_content') );
							add_action( 'woocommerce_account_'.get_option('b2bking_subaccount_endpoint_setting','subaccount').'_endpoint', array($this, 'b2bking_subaccount_endpoint_content') );
							// Subaccount: add "Placed by" column in Orders
							add_filter( 'woocommerce_account_orders_columns', array($this, 'b2bking_orders_placed_by_column') );
							// Add data to "Placed by" column
							add_action( 'woocommerce_my_account_my_orders_column_order-placed-by', array($this, 'b2bking_orders_placed_by_column_content')  );
							// Add subaccounts orders to main account order query
							add_filter( 'woocommerce_my_account_my_orders_query', array($this, 'b2bking_add_subaccounts_orders_to_main_query'), 10, 1 );
							add_filter('woocommerce_order_received_verify_known_shoppers','__return_false');
							
							// Add addresses
							add_action( 'woocommerce_after_order_details', array($this, 'b2bking_give_main_account_view_subaccount_orders_permission_address'), 10, 1);

							// Subscriptions
							add_filter('wcs_get_users_subscriptions', array($this, 'b2bking_visible_subscriptions_subaccounts'), 10, 2);

							// Subaccount checkout permission validation
							add_action('woocommerce_after_checkout_validation', array($this,'b2bking_subaccount_checkout_permission_validation'), 10, 2);
							
							add_action( 'woocommerce_before_cart', array($this,'b2bking_subaccount_checkout_permission_validation_mesage'), 10);
							add_action( 'woocommerce_before_checkout_form', array($this,'b2bking_subaccount_checkout_permission_validation_mesage'), 10);
							
						}

						/* Reordering features	*/
						// Add a reorder button in account orders (overview)
						add_filter( 'woocommerce_my_account_my_orders_actions', array($this, 'b2bking_add_reorder_button_overview'), 10, 2 );
						// Create order note mentioning it is a reorder and linking to the initial order
						add_action( 'woocommerce_thankyou', array( $this, 'b2bking_reorder_create_order_note_reference') );
						// Save old order id
						add_action( 'woocommerce_ordered_again', array( $this, 'b2bking_reorder_save_old_order_id' ));
							
						/* General */
						if (intval(get_option('b2bking_enable_purchase_lists_setting', 1)) === 1){
							/* Purchase list */
							// Add content to purchase lists endpoints
							add_action( 'woocommerce_account_'.get_option('b2bking_purchaselists_endpoint_setting','purchase-lists').'_endpoint', array($this, 'b2bking_purchase_lists_endpoint_content') );
							add_action( 'woocommerce_account_'.get_option('b2bking_purchaselist_endpoint_setting','purchase-list').'_endpoint', array($this, 'b2bking_purchase_list_endpoint_content') );
							add_action( 'woocommerce_account_new-list_endpoint', array($this, 'b2bking_purchase_list_new_list_endpoint_content') );
							// Add "Save cart as Purchase List" button
							add_action('wp', function(){
								if ($this->user_has_offer_in_cart() !== 'yes' && b2bking()->user_has_p_in_cart('quote') !== 'yes'){
									// cannot save offer in a purchase list
									add_action( 'woocommerce_cart_actions', array($this, 'b2bking_purchase_list_cart_button'));
									add_action( 'woocommerce_blocks_enqueue_cart_block_scripts_after', array($this, 'b2bking_purchase_list_cart_button') , 100000);

								}
							});
							// Add shortcode
							add_action( 'init', array($this, 'b2bking_purchaselists_shortcode'));
						}

						add_filter("woocommerce_get_query_vars", array($this,'myaccount_query_vars'));
						
						// Change product price in the minicart for credit
						add_filter('woocommerce_cart_item_price', array($this, 'b2bking_credit_change_price_minicart'), 10, 3);

						/* Price and Product Display Settings */
						// Show MOQ Externally
						if (intval(get_option( 'b2bking_show_moq_product_page_setting', 0 )) === 1){
							add_action('woocommerce_after_shop_loop_item_title', array($this,'b2bking_show_moq_externally'));
						}
					}

					// Show both B2B and B2C price to B2B users
					if (intval(get_option( 'b2bking_show_b2c_price_setting', 0 )) === 1){
						add_filter( 'woocommerce_get_price_html', array($this, 'b2bking_show_both_prices'), 99995, 2);
					}

					// Show Tiered Pricing Range
					if (intval(get_option('b2bking_show_tieredp_product_page_setting', 0)) === 1) {
					    
					    // Check if prices should be displayed (not replaced with quotes)
					    $hide_prices_setting = intval(get_option('b2bking_hide_prices_quote_only_setting', 1));
					    
					    // If prices are not hidden (setting != 1) OR the complex conditions for displaying prices are met
					    if ($hide_prices_setting !== 1 || 
					        !(
					            // Not replacing with quotes due to dynamic setting
					            ($this->dynamic_replace_prices_with_quotes() === 'yes' && $hide_prices_setting === 1) 
					            || 
					            // Not replacing with quotes due to guest access restriction
					            (
					                get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote' && 
					                (
					                    !is_user_logged_in() || 
					                    (
					                        intval(get_option('b2bking_multisite_separate_b2bb2c_setting', 0)) === 1 && 
					                        get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'
					                    )
					                )
					            )
					        )
					    ) {
					        // show range instead of price
					        add_filter('woocommerce_get_price_html', array($this, 'b2bking_tiered_pricing_range_display'), 10000, 2);
					        // show current active price under range
					        add_action('woocommerce_before_add_to_cart_form', array($this, 'b2bking_active_price_under_range'));
					        add_action('woocommerce_available_variation', array($this, 'b2bking_active_price_under_range_variation'), 10, 3);
					    }
					}



				
					// Company Order Approval
					if (intval(get_option( 'b2bking_enable_company_approval_setting', 0 )) === 1){
						// add approve/reject company approval button
						add_action( 'woocommerce_order_details_after_order_table', array($this, 'b2bking_approval_order_button'));
					}

					// Apply group rules
					add_action( 'woocommerce_checkout_order_processed', array( $this, 'b2bking_group_rules_apply'), 10, 3 );
					add_action( 'woocommerce_blocks_checkout_order_processed', array( $this, 'b2bking_group_rules_apply'), 10, 3 );

					// Monthly and yearly group rules
					add_action( 'init', [$this, 'monthly_yearly_group_rules']);

					// Cache calculated categories at the end of the execution for improved perofrmance
					add_action('wp_footer', array($this,'cache_calculated_categories'));



				}
			});
		}
	}

	//Apply MONTHLY GROUP Rules (e.g. change b2b group on threshold reached)
	function monthly_yearly_group_rules(){

		// New PRO rules engine: short-circuit legacy periodic logic
		if (get_option('b2bking_early_access_group_rules', 'yes') === 'yes'){
			if (is_user_logged_in() && class_exists('B2BKing_Group_Rules_Pro')){
				$uid = get_current_user_id();
				$uid = b2bking()->get_top_parent_account($uid);
				$changed = B2BKing_Group_Rules_Pro::apply_group_rules_pro_periodic_for_user($uid);
				if ($changed){
					b2bking()->clear_caches_transients();
					b2bking()->b2bking_clear_rules_caches();
				}
			}
			return;
		}

		$group_changed = 'no';

		if (is_user_logged_in()){
			$current_month = date('mY');
			$current_year = date('Y');

			$user_id = get_current_user_id();

			// check if it's already been applied this month
			if (get_user_meta($user_id,'b2bking_monthly_rules_calculated_'.$current_month, true) !== 'yes'){
				
				// Get all monthly group rules 
				// get all group rules
				$group_rules = get_posts([
		    		'post_type' => 'b2bking_grule',
		    	  	'post_status' => 'publish',
		    	  	'numberposts' => -1,
		    	  	'fields'	=> 'ids',
		    	]);

		    	// remove if not enabled here
		    	foreach ($group_rules as $index => $grule_id){
    	       		$status = get_post_meta($grule_id,'b2bking_post_status_enabled', true);
	    	       	if (intval($status) !== 1){
	    	       		unset($group_rules[$index]);
	    	       	}
		    	}

				$monthly_rules = array();
				foreach ($group_rules as $grule_id){
					$type = get_post_meta($grule_id,'b2bking_rule_applies', true);
					if ($type === 'order_value_monthly_higher' || $type === 'order_value_monthly_lower'){
						array_push($monthly_rules, $grule_id);
					}
				}

				$year = date('Y', strtotime(date('Y-m')." -1 month"));
				$month = date('m', strtotime(date('Y-m')." -1 month"));
				$days_in_month = date('t', strtotime(date('Y-m')." -1 month"));

				// get customer's monthly spend
				$args = array(
					'limit' => '-1',
			        'customer_id' => $user_id,
			        'date_created' => $year.'-'.$month.'-01...'.$year.'-'.$month.'-'.$days_in_month,
			        'type' => 'shop_order',
			        'status' => apply_filters('b2bking_group_rules_statuses', array('wc-completed') ),
			    );
			    $orders = wc_get_orders( $args );
			    $monthly_spent = 0;
			    foreach ($orders as $order){
			    	$monthly_spent += $order->get_total();
			    }

			    $monthly_spent = apply_filters('b2bking_group_rules_monthly_spent', $monthly_spent, $user_id);

			    $is_b2b = get_user_meta($user_id,'b2bking_b2buser', true);
			    if ($is_b2b === 'yes'){
			    	$user_group = get_user_meta($user_id,'b2bking_customergroup', true);
			    	// check rules 
			    	foreach ($monthly_rules as $grule_id){
			    		$group1 = explode('_',get_post_meta($grule_id,'b2bking_rule_agents_who', true))[1];
			    		$group2 = explode('_',get_post_meta($grule_id,'b2bking_rule_who', true))[1];
			    		$type = get_post_meta($grule_id,'b2bking_rule_applies', true);
			    		$howmuch = get_post_meta($grule_id,'b2bking_rule_howmuch', true);

			    		// if agent group is group 1, check type agent value and condition, and if pass, promote to group 2
			    		if ($user_group === $group1){
			    			if ($type === 'order_value_monthly_higher'){
			    				if ($monthly_spent > $howmuch){
			    					// promote to group 2
			    					update_user_meta($user_id,'b2bking_customergroup', $group2);
			    					$user_group = $group2;
			    					$group_changed = 'yes';

			    					if (apply_filters('b2bking_use_wp_roles', false)){
			    						$user_obj = new WP_User($user_id);

			    						$groups = get_posts([
			    						  'post_type' => 'b2bking_group',
			    						  'post_status' => 'publish',
			    						  'numberposts' => -1,
			    						  'fields' => 'ids',
			    						]);
			    						$user_obj->remove_role(apply_filters('b2bking_b2c_role_name', 'b2bking_role_b2cuser'));
			    						foreach ($groups as $grouprole){
			    							$user_obj->remove_role('b2bking_role_'.$grouprole);
			    						}

			    						$user_obj->add_role('b2bking_role_'.$group2);

			    						if (apply_filters('b2bking_use_wp_roles_only_b2b', false)){
			    							$user_obj->set_role('b2bking_role_'.$group2);
			    						}
			    					}

			    					break;
			    				}
			    			}
			    			if ($type === 'order_value_monthly_lower'){
			    				if ($monthly_spent < $howmuch){
			    					// promote to group 2
			    					update_user_meta($user_id,'b2bking_customergroup', $group2);
			    					$user_group = $group2;
			    					$group_changed = 'yes';

			    					if (apply_filters('b2bking_use_wp_roles', false)){
			    						$user_obj = new WP_User($user_id);

			    						$groups = get_posts([
			    						  'post_type' => 'b2bking_group',
			    						  'post_status' => 'publish',
			    						  'numberposts' => -1,
			    						  'fields' => 'ids',
			    						]);
			    						$user_obj->remove_role(apply_filters('b2bking_b2c_role_name', 'b2bking_role_b2cuser'));
			    						foreach ($groups as $grouprole){
			    							$user_obj->remove_role('b2bking_role_'.$grouprole);
			    						}

			    						$user_obj->add_role('b2bking_role_'.$group2);

			    						if (apply_filters('b2bking_use_wp_roles_only_b2b', false)){
			    							$user_obj->set_role('b2bking_role_'.$group2);
			    						}
			    					}

			    					break;
			    				}
			    			}
			    		}

			    	}
			    }

				// calculated finish 
				update_user_meta($user_id,'b2bking_monthly_rules_calculated_'.$current_month, 'yes');
			}

			if (get_user_meta($user_id,'b2bking_yearly_rules_calculated_'.$current_year, true) !== 'yes'){
				
				// Get all monthly group rules 
				// get all group rules
				$group_rules = get_posts([
		    		'post_type' => 'b2bking_grule',
		    	  	'post_status' => 'publish',
		    	  	'numberposts' => -1,
		    	  	'fields'	=> 'ids',
		    	]);

		    	// remove if not enabled here
		    	foreach ($group_rules as $index => $grule_id){
    	       		$status = get_post_meta($grule_id,'b2bking_post_status_enabled', true);
	    	       	if (intval($status) !== 1){
	    	       		unset($group_rules[$index]);
	    	       	}
		    	}

				$yearly_rules = array();
				foreach ($group_rules as $grule_id){
					$type = get_post_meta($grule_id,'b2bking_rule_applies', true);
					if ($type === 'order_value_yearly_higher' || $type === 'order_value_yearly_lower'){
						array_push($yearly_rules, $grule_id);
					}
				}

				$year = date('Y', strtotime(date('Y-m')." -1 month"));
				$month = date('m', strtotime(date('Y-m')." -1 month"));
				$days_in_month = date('t', strtotime(date('Y-m')." -1 month"));
				// get customer's monthly spend
				$args = array(
					'limit' => '-1',
			        'customer_id' => $user_id,
			        'date_created' => $year.'-01-01...'.$year.'-12-'.$days_in_month,
			        'type' => 'shop_order',
			        'status' => apply_filters('b2bking_group_rules_statuses', array('wc-completed') ),

			    );
			    $orders = wc_get_orders( $args );
			    $yearly_spent = 0;
			    foreach ($orders as $order){
			    	$yearly_spent += $order->get_total();
			    }

			    $is_b2b = get_user_meta($user_id,'b2bking_b2buser', true);
			    if ($is_b2b === 'yes'){
			    	$user_group = get_user_meta($user_id,'b2bking_customergroup', true);
			    	// check rules 
			    	foreach ($yearly_rules as $grule_id){
			    		$group1 = explode('_',get_post_meta($grule_id,'b2bking_rule_agents_who', true))[1];
			    		$group2 = explode('_',get_post_meta($grule_id,'b2bking_rule_who', true))[1];
			    		$type = get_post_meta($grule_id,'b2bking_rule_applies', true);
			    		$howmuch = get_post_meta($grule_id,'b2bking_rule_howmuch', true);

			    		// if agent group is group 1, check type agent value and condition, and if pass, promote to group 2
			    		if ($user_group === $group1){
			    			if ($type === 'order_value_yearly_higher'){
			    				if ($yearly_spent > $howmuch){
			    					// promote to group 2
			    					update_user_meta($user_id,'b2bking_customergroup', $group2);
			    					$user_group = $group2;
			    					$group_changed = 'yes';

			    					if (apply_filters('b2bking_use_wp_roles', false)){
			    						$user_obj = new WP_User($user_id);

			    						$groups = get_posts([
			    						  'post_type' => 'b2bking_group',
			    						  'post_status' => 'publish',
			    						  'numberposts' => -1,
			    						  'fields' => 'ids',
			    						]);
			    						$user_obj->remove_role(apply_filters('b2bking_b2c_role_name', 'b2bking_role_b2cuser'));
			    						foreach ($groups as $grouprole){
			    							$user_obj->remove_role('b2bking_role_'.$grouprole);
			    						}

			    						$user_obj->add_role('b2bking_role_'.$group2);

			    						if (apply_filters('b2bking_use_wp_roles_only_b2b', false)){
			    							$user_obj->set_role('b2bking_role_'.$group2);
			    						}
			    					}
			    					break;
			    				}
			    			}
			    			if ($type === 'order_value_yearly_lower'){
			    				if ($yearly_spent < $howmuch){
			    					// promote to group 2
			    					update_user_meta($user_id,'b2bking_customergroup', $group2);
			    					$user_group = $group2;
			    					$group_changed = 'yes';

			    					if (apply_filters('b2bking_use_wp_roles', false)){
			    						$user_obj = new WP_User($user_id);

			    						$groups = get_posts([
			    						  'post_type' => 'b2bking_group',
			    						  'post_status' => 'publish',
			    						  'numberposts' => -1,
			    						  'fields' => 'ids',
			    						]);
			    						$user_obj->remove_role(apply_filters('b2bking_b2c_role_name', 'b2bking_role_b2cuser'));
			    						foreach ($groups as $grouprole){
			    							$user_obj->remove_role('b2bking_role_'.$grouprole);
			    						}

			    						$user_obj->add_role('b2bking_role_'.$group2);

			    						if (apply_filters('b2bking_use_wp_roles_only_b2b', false)){
			    							$user_obj->set_role('b2bking_role_'.$group2);
			    						}
			    					}
			    					break;
			    				}
			    			}
			    		}

			    	}
			    }

				// calculated finish 
				update_user_meta($user_id,'b2bking_yearly_rules_calculated_'.$current_year, 'yes');
			}
		}

		if ($group_changed === 'yes'){
			// delete all b2bking transients
			// Must clear transients and rules cache when user group is changed because now new rules may apply.
			b2bking()->clear_caches_transients();
			b2bking()->b2bking_clear_rules_caches();
		}

	}

	function cache_calculated_categories() {
	    $taxonomies = array();
	    $taxonomies_obj = get_taxonomies();
	    foreach ($taxonomies_obj as $taxonomy_name => $details) {
	        $taxonomies[] = $taxonomy_name;
	    }
	    
	    foreach ($taxonomies as $taxonomy) {
	        global ${'b2bking_all_categories'.$taxonomy};
	        
	        // Only proceed if we have an array to work with
	        if (is_array(${'b2bking_all_categories'.$taxonomy})) {
	            // Get the current transient value
	        	global $b2bking_cached_categories_original;
	            
	            // Compare current value with new value
	            if ($b2bking_cached_categories_original !== ${'b2bking_all_categories'.$taxonomy}) {
	                // Only set the transient if the value is different
	                set_transient('b2bking_cached_categories_taxonomies'.$taxonomy, ${'b2bking_all_categories'.$taxonomy}, YEAR_IN_SECONDS);
	            }
	        }
	    }
	}

	function b2bking_checkout_file_upload_ajax(){
		if (!is_user_logged_in()){
			if (is_checkout()){
				?>
				<script>
					jQuery(document).ready(function(){
						jQuery('input[type="file"].b2bking_custom_registration_field').change( function() {
							if ( this.files.length ) {
								const file = this.files[0];
								const formData = new FormData();

								formData.append( 'file', file );
								formData.append( 'security', b2bking_display_settings.security); 

								var fieldid = jQuery(this).attr('id');

								jQuery('#place_order').prop('disabled', true);
								jQuery.ajax({
								   url: wc_checkout_params.ajax_url + '?action=b2bking_checkout_ajax_file_upload',
								   type: 'POST',
								   data: formData,
								   contentType: false,
								   enctype: 'multipart/form-data',
								   processData: false,
								   success: function ( response ) {
								   		let attachmentid = response;
								   		createCookie(fieldid, attachmentid, false);
								   		jQuery('#place_order').prop('disabled', false);

								   }
								});
							}
						});

						function createCookie(name, value, days) {
						    var expires;

						    if (days) {
						        var date = new Date();
						        date.setTime(date.getTime() + (days * 24 * 60 * 60 * parseFloat(b2bking_display_settings.cookie_expiration_days)));
						        expires = "; expires=" + date.toGMTString();
						    } else {
						        expires = "";
						    }
						    document.cookie = encodeURIComponent(name) + "=" + encodeURIComponent(value) + expires + "; path=/";
						}


					});
				</script>
				<?php
			}
		}
	}

	function iconic_attribute_swatches_price_disable_cart_item_price($iconic_price, $cart_item, $cart_item_key){
		if (isset($cart_item['variation_id'])){
			$product = wc_get_product($cart_item['variation_id']);
		} else {
			$product = wc_get_product($cart_item['product_id']);
		}
		if ($product->is_on_sale()){
			$price = $product->get_sale_price();
		} else {
			$price = $product->get_regular_price();
		}
		return $price;
	}

	function b2bking_approval_order_button( $order ) {

		// if is checkout / order received, do not show  button
		if ( is_checkout() && !empty( is_wc_endpoint_url('order-received') ) ) {
		    return;
		}


		// Show payment link if order already approved.
		if ($order){
			$order_id = $order->get_id();
			$approval = $order->get_meta('b2bking_order_approval');


			if ($approval === 'yes'){



				if ($order->get_status()==='pending'){
					$pay_now_url = esc_url( $order->get_checkout_payment_url() );
					if (intval($order->get_total()) == 0){
						esc_html_e('This order has been approved.','b2bking');
					} else {
						esc_html_e('This order has been approved. It is now pending payment.','b2bking');
					}
					echo '<br><br>';

					if (intval($order->get_total()) != 0){
						esc_html_e('Click to pay for the order: ','b2bking');
						echo '<a class="b2bking_pay_now_link" href="'.esc_attr($pay_now_url).'">'.esc_html__('Pay Now','b2bking').'</a>';
						echo '<br><br>';
					}

				} else {
					if ($order->get_status()!=='pcompany'){
						echo '<br>';
						esc_html_e('This order has been approved and paid for.','b2bking');
						echo '<br><br>';
					}
					
				}

			}

		}

		if ( ! $order || ! $order->has_status( apply_filters( 'marketking_valid_statuses_refunds', array( 'wc-pcompany', 'pcompany' ) ) ) || ! is_user_logged_in() ) {
			return;
		}

		
		// if this user is a subaccount, do not show the button
		$currentuserid = get_current_user_id();
    	$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
    	if ($account_type === 'subaccount'){
    		esc_html_e('Your order is pending approval.','b2bking');

    		?>
    		<br><br>
    		<input type="hidden" id="b2bking_order_number" value="<?php echo esc_attr($order->get_id());?>">

    		&nbsp;&nbsp;&nbsp;<a class="button" id="b2bking_reject_order_subaccount"><?php esc_html_e( 'Cancel order', 'b2bking' ); ?></a>

    		<br><br>
    		<?php

    		do_action('b2bking_subaccount_order_pending_approval', $order);

    	} else {
	    	esc_html_e('This order requires your review. You can approve or reject the order below.','b2bking');

			?>
			<br><br>
			<div class="b2bking_order_approve_reject_container">
				<input type="hidden" id="b2bking_pay_now_url" value="<?php echo esc_attr($order->get_checkout_payment_url());?>">
				<input type="hidden" id="b2bking_order_number" value="<?php echo esc_attr($order->get_id());?>">
				<a class="button" id="b2bking_approve_order"><?php echo apply_filters('b2bking_approve_order_text', esc_html__( 'Approve', 'b2bking' )); ?></a>
				&nbsp;&nbsp;&nbsp;<a class="button" id="b2bking_reject_order"><?php esc_html_e( 'Reject', 'b2bking' ); ?></a>
			</div>
			<br><br>
			<?php
    		do_action('b2bking_mainaccount_order_pending_approval', $order);
    	}


    	
		
	}


	function b2bking_csvorder_not_enough_stock($message){
		//wc_add_notice($message);
		return $message;
	}


	function b2bking_group_rules_apply($order_id, $posted_data = array(), $order = array()){

		$update = false;

		$order = wc_get_order($order_id);
		$user_id = $order->get_customer_id();
		// get user's group
    	$user_id = b2bking()->get_top_parent_account($user_id);

    	// set this main user as order meta as well
    	$order->update_meta_data( '_customer_user_main', $user_id );
    	$order->save();

		// PRO rules engine enabled?
		$pro_enabled = (get_option('b2bking_early_access_group_rules', 'yes') === 'yes' && class_exists('B2BKing_Group_Rules_Pro'));
		if ($pro_enabled){
			$update = (bool) B2BKing_Group_Rules_Pro::apply_group_rules_pro_on_order($order);
		} else {

			$currentusergroupidnr = b2bking()->get_user_group($user_id);
			$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );

			if ($is_b2b_user === 'yes'){
				$group_rules_applicable = b2bking()->get_group_rules($currentusergroupidnr);
				// foreach rule, check if the condition is met, and then apply it
				foreach ($group_rules_applicable as $group_rule_id){
					$howmuch = get_post_meta($group_rule_id,'b2bking_rule_howmuch', true);
					$newgroup = get_post_meta($group_rule_id, 'b2bking_rule_who', true);
					$newgroup_id = explode('_', $newgroup)[1];

					$condition = get_post_meta($group_rule_id, 'b2bking_rule_applies', true);

					$user = new WC_Customer($user_id);

					if (apply_filters('b2bking_group_rules_total_spent_incl_tax', true)){
						$total_orders_amount = $user->get_total_spent();
					} else {
						$total_orders_amount = b2bking()->get_customer_total_spent_without_tax($user_id);
					}
					$total_orders_amount = apply_filters('b2bking_total_order_amount_used_group_rules', $total_orders_amount, $user_id);

					if (apply_filters('b2bking_group_rules_count_last_order', false)){
						$total_orders_amount += $order->get_total(); // add current order
					}

					if ($condition === 'order_value_total'){

						// calculate agent order value total
						if ($total_orders_amount >= $howmuch){
							// change group
							b2bking()->update_user_group($user_id, $newgroup_id);
							$update = true;

							if (apply_filters('b2bking_use_wp_roles', false)){
								$user_obj = new WP_User($user_id);

								$groups = get_posts([
								'post_type' => 'b2bking_group',
								'post_status' => 'publish',
								'numberposts' => -1,
								'fields' => 'ids',
								]);
								$user_obj->remove_role(apply_filters('b2bking_b2c_role_name', 'b2bking_role_b2cuser'));
								foreach ($groups as $grouprole){
									$user_obj->remove_role('b2bking_role_'.$grouprole);
								}
								
								$user_obj->add_role('b2bking_role_'.$newgroup_id);

								if (apply_filters('b2bking_use_wp_roles_only_b2b', false)){
									$user_obj->set_role('b2bking_role_'.$newgroup_id);
								}
							}
						}
					}

					do_action('b2bking_apply_group_rule', $group_rule_id, $howmuch, $newgroup_id, $user_id);
					
				}
			}
		}

		do_action('b2bking_finish_apply_group_rules', $order_id, $user_id);

		// offer purchased by user set (applies to both legacy and PRO flows)
		if (intval(get_option( 'b2bking_offer_one_per_user_setting', 0 )) === 1){
			$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
			foreach( $order->get_items() as $item_id => $item ){
			    //Get the product ID
			    $product_id = $item->get_product_id();
				// if not offer, skip
				if (intval($product_id) !== $offer_id){
					continue;
				}

				// item is offer, continue
				$offerid = $item->get_meta('_offer_id', true);
				update_user_meta(get_current_user_id(),'b2bking_purchased_offer_'.$offerid,'yes');
			}
		}

		// delete all b2bking transients
		// Must clear transients and rules cache when user group is changed because now new rules may apply.
		if ($update){
			b2bking()->clear_caches_transients();
			b2bking()->b2bking_clear_rules_caches();
		}
		
	}

	function b2bking_b2b_application_pending(){
		if (apply_filters('b2bking_allow_logged_in_register_b2b', false)){
			$is_b2b = get_user_meta(get_current_user_id(),'b2bking_b2buser', true);

			if ($is_b2b !== 'yes'){
				// if application pending
				if (b2bking()->has_b2b_application_pending(get_current_user_id())){
					// show message
					if (b2bking()->get_user_application_type(get_current_user_id()) === 'agent'){
						?>
						<span class="b2bking-application-pending"><?php esc_html_e('We are currently reviewing your sales agent account application and it is pending.','b2bking'); ?></span><br><br>
						<?php
					} else {

						?>
						<span class="b2bking-application-pending"><?php 

						echo esc_html__('You are logged in as a B2C user.','b2bking').'<br>';

						esc_html_e('We are currently reviewing your B2B account application and it is pending.','b2bking'); 

						?></span><br><br>
						<?php
					}
				}
			}
		}
	}

	public static function b2bking_disable_tiered_price_table_quote_products($disable, $product_id){

		$response = b2bking()->get_applicable_rules('quotes_products', $product_id);
		$haverules = 'no';
		if ($response !== 'norules'){
			$rules = $response[0];
			if (!empty($rules)){
				$haverules = 'yes';
			}
		}

		if ($haverules === 'yes'){
			$disable = true;
		}

		return $disable;
	}

	public function woodmart_b2bking_product_badge($label){
		if (!empty($label)){
			global $product;
			$labelvalue = B2bking_Dynamic_Rules::b2bking_dynamic_rule_discount_display_dynamic_sale_badge('Sale!', 0, $product);
			return array('<span class="onsale product-label">' . $labelvalue . '</span>');
		}
		return $label;
	}



	public static function b2bking_hide_sale_flash_quote_products($flash, $post, $product){

		$product_id = $product->get_id();
		$response = b2bking()->get_applicable_rules('quotes_products', $product_id);
		$haverules = 'no';
		if ($response !== 'norules'){
			$rules = $response[0];
			if (!empty($rules)){
				$haverules = 'yes';
			}
		}

		if ($haverules === 'yes'){
			$flash = false;
		}

		return $flash;
	}

	public static function b2bking_prevent_cart_product_purchasable($purchasable, $product){
		
		$product_id = $product->get_id();
		$response = b2bking()->get_applicable_rules('quotes_products', $product_id);
		$haverules = 'no';
		if ($response !== 'norules'){
			$rules = $response[0];
			if (!empty($rules)){
				$haverules = 'yes';
			}
		}

		if ($haverules === 'no'){

			$purchasable = false;

			if (defined('MARKETKINGPRO_DIR') && defined('MARKETKINGCORE_DIR')){
				if (marketking()->is_pack_product($product_id)){
					$purchasable = true;
				}
			}
		}

		// Check if the product is an offer child
	    if (b2bking()->is_offer_child($product_id)) {
	    	return true; // Always purchasable for offer child products
	    }

		return $purchasable;
	}

	public static function b2bking_prevent_quote_product_purchasable($purchasable, $product){

		$product_id = $product->get_id();

		$response = b2bking()->get_applicable_rules('quotes_products', $product_id);
		$haverules = 'no';
		if ($response !== 'norules'){
			$rules = $response[0];
			if (!empty($rules)){
				$haverules = 'yes';
			}
		}
		if ($haverules === 'yes'){

			$purchasable = false;

			if (defined('MARKETKINGPRO_DIR') && defined('MARKETKINGCORE_DIR')){
				if (marketking()->is_pack_product($product_id)){
					$purchasable = true;
				}
			}
		}

		// Check if the product is an offer child
	    if (b2bking()->is_offer_child($product_id)) {
	    	return true; // Always purchasable for offer child products
	    }

		return $purchasable;
	}

	function b2bking_disable_purchasable_except_offers($purchasable, $product){
		$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
		$credit_id = intval(get_option('b2bking_credit_product_id_setting', 0));
		$offer_products_integrations = $this->get_all_offer_products_integrations();

		$current_product_id = intval($product->get_id());

		// if user is guest, or multisite b2b/b2b separation is enabled and user should be treated as guest
		if ($offer_id !== $current_product_id && $credit_id !== $current_product_id && !in_array($current_product_id, $offer_products_integrations)){
			$purchasable = false;
		}

		if (defined('MARKETKINGPRO_DIR') && defined('MARKETKINGCORE_DIR')){
			if (marketking()->is_pack_product($current_product_id)){
				$purchasable = true;
			}
		}

		// if product exists in cart, as part of an offer, purchasable = true
	    if (b2bking()->is_offer_child($current_product_id)) {
	    	return true; // Always purchasable for offer child products
	    }

		return $purchasable;
	}

	function get_all_offer_products_integrations(){
		// dokan and wcfm integration
		$dokan_offer_products = get_option('b2bking_dokan_hidden_offer_product_ids', 'string');
		$dokan_offer_products_clean = array();
		if ($dokan_offer_products !== 'string' && !empty($dokan_offer_products)){
			$dokan_offer_products = explode(',', $dokan_offer_products);
			$dokan_offer_products_clean = array_unique(array_filter($dokan_offer_products));
		}

		$wcfm_offer_products = get_option('b2bking_wcfm_hidden_offer_product_ids', 'string');
		$wcfm_offer_products_clean = array();
		if ($wcfm_offer_products !== 'string' && !empty($wcfm_offer_products)){
			$wcfm_offer_products = explode(',', $wcfm_offer_products);
			$wcfm_offer_products_clean = array_unique(array_filter($wcfm_offer_products));
		}

		$marketking_offer_products = get_option('b2bking_marketking_hidden_offer_product_ids', 'string');
		$marketking_offer_products_clean = array();
		if ($marketking_offer_products !== 'string' && !empty($marketking_offer_products)){
			$marketking_offer_products = explode(',', $marketking_offer_products);
			$marketking_offer_products_clean = array_unique(array_filter($marketking_offer_products));
		}

		// wpml translations of offer product
		$translation_ids = array();
		$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
		$translated_id_wpml = apply_filters( 'wpml_object_id', $offer_id, 'post', true );
		$translation_ids[] = $translated_id_wpml;
		
		$offer_products_integrations = array_merge($dokan_offer_products_clean, $wcfm_offer_products_clean, $marketking_offer_products_clean, $translation_ids);

		return $offer_products_integrations;
	}

	function user_has_offer_in_cart(){
		$has_offer = 'no';
		$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
		$credit_id = intval(get_option('b2bking_credit_product_id_setting', 0));

		$offer_products_integrations = $this->get_all_offer_products_integrations();
		// dokan and wcfm integration end
		
		if (is_object( WC()->cart )){

			foreach(WC()->cart->get_cart() as $cart_item){
				if ($cart_item['product_id'] === $offer_id || $cart_item['product_id'] === $credit_id){
					$has_offer = 'yes';
				}

				if (in_array($cart_item['product_id'], $offer_products_integrations)){
					$has_offer = 'yes';
				}

				if (defined('MARKETKINGPRO_DIR') && defined('MARKETKINGCORE_DIR')){
					if (marketking()->is_pack_product($cart_item['product_id'])){
						$has_offer = 'yes';
					}
				}
			}
		}

		return $has_offer;
	}

	function b2bking_active_price_under_range(){
		global $post;
		$product = wc_get_product($post->ID);

		$disable_multirun_check_tables = apply_filters('disable_multirun_check_tables', false);

		static $b2bking_has_run4 = false;
		if ($b2bking_has_run4 === false || $disable_multirun_check_tables){

			if (is_object($product) && intval($post->ID) === intval(b2bking()->safe_get_queried_object_id())){

				if (apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product->get_id())){
					return;
				}

				// if hide pricing + quote on this product, return
				if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){
					$product_id = $product->get_id();

					$response = b2bking()->get_applicable_rules('quotes_products', $product_id);
					$haverules = 'no';
					if ($response !== 'norules'){
						$rules = $response[0];
						if (!empty($rules)){
							$haverules = 'yes';
						}
					}

					if ($haverules === 'yes'){
						// yes, have quote
						return;
					}
				}
				

				if( $product->is_type( 'simple' ) ){
					// get if 1) pricing table is enabled and 2) there are tiered prices set up
					$is_enabled = get_post_meta($post->ID, 'b2bking_show_pricing_table', true);
					if (!$product->is_purchasable()){
						$is_enabled = 'no';
					}
					if ($is_enabled !== 'no'){
						// get user's group
						$user_id = get_current_user_id();
				    	$user_id = b2bking()->get_top_parent_account($user_id);

						$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product->get_id());

						$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );

						// GET ORIGINAL PRODUCT PRICE

						if ( $product->is_on_sale() ) {
							$original_user_price = get_post_meta($product->get_id(),'_sale_price',true);
						   	
							if ($is_b2b_user === 'yes'){
								// Search if there is a specific price set for the user's group
								$b2b_price = b2bking()->tofloat(get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
													
								if (!empty($b2b_price)){
									$original_user_price = $b2b_price;
								}
							}

						} else {
							$original_user_price = get_post_meta($product->get_id(),'_regular_price',true);

							if ($is_b2b_user === 'yes'){
								// Search if there is a specific price set for the user's group
								$b2b_price = b2bking()->tofloat(get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true ));
													
								if (!empty($b2b_price)){
									$original_user_price = $b2b_price;
								}
							}
						}
						// adjust price for tax
						$original_user_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $original_user_price ) ); // get sale price

						// ORIGINAL PRODUCT PRICE END

						$price_tiers = get_post_meta($post->ID, 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true);
						$price_tiers = b2bking()->convert_price_tiers($price_tiers, $product);
						$user_price = array();

						// if didn't find anything as a price tier, give regular price tiers
						if (!(!empty($price_tiers) && strlen($price_tiers) > 1 )){
							$price_tiers = get_post_meta($post->ID, 'b2bking_product_pricetiers_group_b2c', true);
							$price_tiers = b2bking()->convert_price_tiers($price_tiers, $product);
							// if user is logged in b2b
							if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) === 'yes'){
								// but first check that there is at least 1 price in the regular tiers that is better than the group price
								$have_better_price = 'no';

								// go through array
								$price_tiers_array = explode(';', $price_tiers);
								$price_tiers_array = array_filter($price_tiers_array);

								$user_group_regular_price = b2bking()->tofloat(get_post_meta($product->get_id(),'b2bking_regular_product_price_group_'.$currentusergroupidnr, true));
								$user_group_sale_price = b2bking()->tofloat(get_post_meta($product->get_id(),'b2bking_sale_product_price_group_'.$currentusergroupidnr, true));
								if (!empty($user_group_sale_price)){
									$user_price = $user_group_sale_price;
								} else {
									$user_price = $user_group_regular_price;
								}
								if (!empty($user_price)){
									// adjust price for tax
									$user_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $user_price ) ); // get sale price

									foreach ($price_tiers_array as $tier_group){
										if (empty($tier_group)) {continue;}

										$tier_price = b2bking()->tofloat(explode(':',$tier_group)[1]);
										$tier_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $tier_price ) ); 
										if (b2bking()->tofloat($tier_price) <= $user_price){
											$have_better_price = 'yes';
											break;
										}
									}
								} else {
									// there is no group price, show b2c table
									$have_better_price = 'yes';
								}

								if ($have_better_price === 'no'){
									$price_tiers = array();
								}
							}

						}

						if (!empty($price_tiers) && strlen($price_tiers) > 1 ){
							$price = $product -> get_price();
							$b2bking_has_run4 = true;


							// adjust price for tax
							$price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $price ) );
							echo '<p class="price b2bking_tiered_active_price">';
							echo apply_filters('b2bking_active_price_under_range', wc_price($price), $product, $price );
							echo '</p>';

							do_action('b2bking_after_tiered_active_price', $price, $product);
						}
					}
					
				}
			}
		}
	}

	function b2bking_not_on_sale_raise_price($on_sale, $product){

		if ($on_sale){
			if ($product->is_type('variable')){
				$prices  = $product->get_variation_prices();
				if ($prices['sale_price'] > $prices['regular_price']){
					$on_sale = false;
				}
			}
		} else {
			// woocs sale badge not showing on variable products fix
			if (get_option('b2bking_have_discount_everywhere_rules', 'yes') === 'yes'){
				if (defined('WOOCS_VERSION')) {
					if ($product->is_type('variable')){
						$children = $product->get_children();
						foreach ($children as $child_id){
							$variation = wc_get_product($child_id);
							$sale_price = $variation->get_sale_price();
							if (!empty($sale_price)){
								$on_sale = true;
								break;
							}
						}
					}
				}
			}
		}

		return $on_sale;
	}

	function b2bking_variable_cache_bust($price, $product){
		$product_id = $product->get_id();
		delete_transient( 'wc_var_prices_' . $product_id );

		return $price;
	}

	function b2bking_negative_discount_variation_price_fix($price, $product){

		$product_id = $product->get_id();
		delete_transient( 'wc_var_prices_' . $product_id );

		$prices = $product->get_variation_prices( true );
		if ( ! empty( $prices['price'] ) ) {
			$min_price     = current( $prices['price'] );
			$max_price     = end( $prices['price'] );
			$min_reg_price = current( $prices['regular_price'] );
			$max_reg_price = end( $prices['regular_price'] );
			if ( $min_price === $max_price && $product->is_on_sale() && $min_reg_price === $max_reg_price) {
				if ($min_price >= $max_reg_price){
					$price = wc_price($min_price);
				}
			}
		}

		return $price;
	}

	function b2bking_allow_negative_discounts($price_html, $product, $sale_price){

		if ($product->get_sale_price() > $product->get_regular_price()){
			$price_html = wc_price($sale_price) . $product->get_price_suffix();
		}

		return apply_filters('b2bking_raise_price_html', $price_html, $product);

	}

	function b2bking_active_price_under_range_variation( $data, $product, $variation ) {

		if (apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product->get_id())){
			return $data;
		}

		if (apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $variation->get_id())){
			return $data;
		}

		ob_start();
		$variation_id = $variation->get_id();
		$product_id = wp_get_post_parent_id($variation_id);

		if (intval($product_id) === intval(b2bking()->safe_get_queried_object_id())){

			// if hide pricing + quote on this product, return
			if (intval(get_option( 'b2bking_hide_prices_quote_only_setting', 1 )) === 1){

				$response = b2bking()->get_applicable_rules('quotes_products', $product_id);
				$haverules = 'no';
				if ($response !== 'norules'){
					$rules = $response[0];
					if (!empty($rules)){
						$haverules = 'yes';
					}
				}

				if ($haverules === 'yes'){
					// yes, have quote
					return;
				}
			}

	    	// get if 1) pricing table is enabled and 2) there are tiered prices set up
	    	$is_enabled = get_post_meta($product_id, 'b2bking_show_pricing_table', true);

	    	if (!$variation->is_purchasable()){
	    		$is_enabled = 'no';
	    	}
	    	if ($is_enabled !== 'no'){
	    		// get user's group
	    		$user_id = get_current_user_id();
	        	$user_id = b2bking()->get_top_parent_account($user_id);


	        	$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $variation->get_id());

	        	$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );

	        	// GET ORIGINAL PRODUCT PRICE

	        	if ( $variation->is_on_sale() ) {
	        		$original_user_price = get_post_meta($variation->get_id(),'_sale_price',true);
	        	   	
	        		if ($is_b2b_user === 'yes'){
	        			// Search if there is a specific price set for the user's group
	        			$b2b_price = b2bking()->tofloat(get_post_meta($variation->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
	        								
	        			if (!empty($b2b_price)){
	        				$original_user_price = $b2b_price;
	        			}
	        		}

	        	} else {
	        		$original_user_price = get_post_meta($variation->get_id(),'_regular_price',true);

	        		if ($is_b2b_user === 'yes'){
	        			// Search if there is a specific price set for the user's group
	        			$b2b_price = b2bking()->tofloat(get_post_meta($variation->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true ));
	        								
	        			if (!empty($b2b_price)){
	        				$original_user_price = $b2b_price;
	        			}
	        		}
	        	}
	        	// adjust price for tax
	        	$original_user_price = b2bking()->b2bking_wc_get_price_to_display( $variation, array( 'price' => $original_user_price ) ); // get sale price

	        	// ORIGINAL PRODUCT PRICE END

	    		$price_tiers = get_post_meta($variation_id, 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true);
	    		$price_tiers = b2bking()->convert_price_tiers($price_tiers, $variation);
	    		$user_price = array();
	    		// if didn't find anything as a price tier, give regular price tiers if it exists
	    		if (!(!empty($price_tiers) && strlen($price_tiers) > 1 )){
	   				$price_tiers = get_post_meta($variation_id, 'b2bking_product_pricetiers_group_b2c', true);
	   				$price_tiers = b2bking()->convert_price_tiers($price_tiers, $variation);

	   				if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) === 'yes'){
						// but first check that there is at least 1 price in the regular tiers that is better than the group price
						$have_better_price = 'no';

						// go through array
						$price_tiers_array = explode(';', $price_tiers);
						$price_tiers_array = array_filter($price_tiers_array);

						
						$user_group_regular_price = b2bking()->tofloat(get_post_meta($variation_id,'b2bking_regular_product_price_group_'.$currentusergroupidnr, true));
						$user_group_sale_price = b2bking()->tofloat(get_post_meta($variation_id,'b2bking_sale_product_price_group_'.$currentusergroupidnr, true));
						if (!empty($user_group_sale_price)){
							$user_price = $user_group_sale_price;
						} else {
							$user_price = $user_group_regular_price;
						}

						if (!empty($user_price)){
							// adjust price for tax
							$user_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $user_price ) ); // get sale price
							foreach ($price_tiers_array as $tier_group){
								if (empty($tier_group)) {continue;}

								$tier_price=explode(':',$tier_group)[1];
								$tier_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $tier_price ) );
								if (b2bking()->tofloat($tier_price) <= $user_price){
									$have_better_price = 'yes';
									break;
								}
							}
						} else {
							// there is no group price, show b2c table
							$have_better_price = 'yes';
						}

						if ($have_better_price === 'no'){
							$price_tiers = array();
						}
					}

	    		}

	    		if (!empty($price_tiers) && strlen($price_tiers) > 1 ){
					// clear cache mostly for variable products
					if (apply_filters('b2bking_clear_wc_products_cache', true)){
						WC_Cache_Helper::get_transient_version( 'product', true );
					}
					$price = $variation -> get_price();
					// adjust price for tax
					$price = b2bking()->b2bking_wc_get_price_to_display( $variation, array( 'price' => $price ) );
					echo '<p class="price b2bking_tiered_active_price">';

					echo apply_filters('b2bking_active_price_under_range', wc_price($price), $product, $price );

					echo '</p>';

					do_action('b2bking_after_tiered_active_price', $price, $product);


				}
			}
		}

	    if (isset($data['availability_html'])){
    		$previous_availability = $data['availability_html'];
    	} else {
    		$previous_availability = '';
    	}
        $data['availability_html'] = ob_get_clean().$previous_availability;
	    return $data;

	}


	// cart subscriptions free trial functions
	public function add_calculation_price_filter() {
		
		WC()->cart->recurring_carts = array();

		// Only hook when cart contains a subscription
		if ( ! WC_Subscriptions_Cart::cart_contains_subscription() ) {
			return;
		}
		
		// Set which price should be used for calculation
		add_filter( 'woocommerce_product_get_price', array('WC_Subscriptions_Cart', 'set_subscription_prices_for_calculation'), 100000, 2 );
		add_filter( 'woocommerce_product_variation_get_price', array('WC_Subscriptions_Cart', 'set_subscription_prices_for_calculation'), 100000, 2 );
	}
	public function remove_calculation_price_filter() {
		remove_filter( 'woocommerce_product_get_price', array('WC_Subscriptions_Cart', 'set_subscription_prices_for_calculation'), 100000 );
		remove_filter( 'woocommerce_product_variation_get_price', array('WC_Subscriptions_Cart', 'set_subscription_prices_for_calculation'), 100000 );
	}

	function b2bking_tiered_pricing_range_display($price, $product){

		$priceoriginal = $price;
		if (!is_a($product,'WC_Product_Variation') && !is_a($product,'WC_Product')){
			return $price;
		}

		if (apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product->get_id())){
			return $price;
		}
		
		$user_id = get_current_user_id();
    	$user_id = b2bking()->get_top_parent_account($user_id);

    	// check transient to see if the current price has been set already via another function
    	//if (get_transient('b2bking_user_'.$user_id.'_product_'.$product->get_id().'_custom_set_price') === $price){

    	if(apply_filters('b2bking_tiered_range_change_custom_set_price', true)){
    		if ((floatval(b2bking()->get_global_data('custom_set_price', $product->get_id(), $user_id)) === floatval($price)) && floatval($price) !== floatval(0)){
    			//return $price;
    			// comparison incorrect - one value ($price) is a string (Created with wc_price), the other is a number
    		}
    	}


		$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product->get_id());

		$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );
			
		// Search price tiers
		$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true );

		// if no tiers AND no group price exists, get B2C tiered pricing
		$grregprice = get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
		$grsaleprice = get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
		$grpriceexists = 'no';
		if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
			$grpriceexists = 'yes';	
		}
		if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
			$grpriceexists = 'yes';	
		}

		if (empty($price_tiers) && $grpriceexists === 'no'){
			$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_b2c', true );
		}

		// apply percentage instead of final prices (optiinally)
		$price_tiers = b2bking()->convert_price_tiers($price_tiers, $product);

		if (!empty($price_tiers) && !$product->is_type('variable')){

			if ( '' !== $product->get_price() ) {
				if ( $product->is_on_sale() ) {
					$price = get_post_meta($product->get_id(),'_sale_price',true);
			    	
					if ($is_b2b_user === 'yes'){
						// Search if there is a specific price set for the user's group
						$b2b_price = b2bking()->tofloat(get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
											
						if (!empty($b2b_price)){
							$price = $b2b_price;
						}
					}

				} else {
					$price = get_post_meta($product->get_id(),'_regular_price',true);

					if ($is_b2b_user === 'yes'){
						// Search if there is a specific price set for the user's group
						$b2b_price = b2bking()->tofloat(get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true ));
											
						if (!empty($b2b_price)){
							$price = $b2b_price;
						} else {
							// if no b2b price, check if there is a tiered price for 1 (user entered tiered price but not b2b price directly)
							$price_tiers_temp = array_filter(explode(';', $price_tiers));
							$price_for_one = '';
							foreach($price_tiers_temp as $tier){
								$tier_values_temp = explode(':', $tier);
								if (isset($tier_values_temp[1])){
									if (intval($tier_values_temp[0]) === 1){
										$price_for_one = $tier_values_temp[1];
										break;
									}
								}
							}
							if (!empty($price_for_one)){
								$price = $price_for_one;
							}
						}
					}
				}
				$price_tiers = array_filter(explode(';', $price_tiers));
				$min_price = b2bking()->tofloat($price);
				$max_price = b2bking()->tofloat($price);

				// first eliminate all quantities larger than the quantity in cart
				foreach($price_tiers as $tier){
					$tier_values = explode(':', $tier);
					if (isset($tier_values[1])){
						if (b2bking()->tofloat($tier_values[1]) < $min_price){
							$min_price = b2bking()->tofloat($tier_values[1]);
						}
					}
				}

				// apply raise price / discount
				$min_price = b2bking()->get_tiered_raise_price_val($min_price, $product->get_id());
				$max_price = b2bking()->get_tiered_raise_price_val($max_price, $product->get_id());

				// if any number remains
				if($min_price !== $max_price){

					// clear cache mostly for variable products
					if (apply_filters('b2bking_clear_wc_products_cache', true)){
						WC_Cache_Helper::get_transient_version( 'product', true );
					}

					// adjust price for tax
					$min_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => b2bking()->get_woocs_price($min_price ) ) );
					$max_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => b2bking()->get_woocs_price($max_price ) ) );
					$style = '';
					if (apply_filters('b2bking_tiered_range_show_min', false)){
						$range = '<div class="b2bking_tiered_range_replaced b2bking_tiered_price_range_replaced_'.esc_attr($product->get_id()).'" style="display:none;">'.b2bking()->format_price_range( $min_price, $max_price ).'</div>'.apply_filters('b2bking_tiered_range_show_min_from',esc_html__('from','b2bking')).' '.wc_price($min_price);
					} else {
						$range = '<div class="b2bking_tiered_range_replaced b2bking_tiered_price_range_replaced_'.esc_attr($product->get_id()).'" '.$style.'>'.b2bking()->format_price_range( $min_price, $max_price ).'</div>'.$product->get_price_suffix();
					}

					$range.='<div class="b2bking_tiered_range_after"></div>';

					$range.='<input type="hidden" class="b2bking_tiered_range_original_price" value="'.$max_price.'">';
					$range.='<input type="hidden" class="b2bking_tiered_range_original_price_display" value="'.strip_tags(wc_price($max_price)).'">';

					$range = apply_filters('b2bking_tiered_range_display_final', $range, $min_price, $max_price, $product);

					if (apply_filters('b2bking_tiered_hide_range', false)){
						return $priceoriginal.'<div class="b2bking_hidden">'.$range.'</div>';
					}

					return $range;

				} else {
					return $priceoriginal.'<div class="b2bking_tiered_range_replaced b2bking_tiered_range_replaced_hidden">'.$priceoriginal.' - '.$priceoriginal.'</div><div class="b2bking_tiered_range_after"></div>';
				}

			} else {
				return $price;
			}

		} else {
			// check if product is variable
			if ($product->is_type('variable')){

				//$range = get_transient('b2bking_tiered_price_range_display_'.$product->get_id().'_'.get_current_user_id());
				$range = b2bking()->get_global_data('b2bking_tiered_price_range_display', $product->get_id(), get_current_user_id());

				if (apply_filters('b2bking_tiered_range_display_cache', true)){
					$range = false;
				}

				if (defined('WOOCS_VERSION')) {
					// if woocs, do not use range transients
					$range = false;
				}

				if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) !== 1){
					$range = false;
				}
				if (!$range){

					// check if any variation has tiered price and if not, return
					$have_tiered_price_in_any_variation = 'no';
					$children = $product->get_children();
					foreach ($children as $variation_id){
						// Search price tiers
						$price_tiers = get_post_meta($variation_id, 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true );


						// if no tiers AND no group price exists, get B2C tiered pricing
						$grregprice = get_post_meta($variation_id, 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
						$grsaleprice = get_post_meta($variation_id, 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
						$grpriceexists = 'no';
						if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
							$grpriceexists = 'yes';	
						}
						if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
							$grpriceexists = 'yes';	
						}

						if (empty($price_tiers) && $grpriceexists === 'no'){
							$price_tiers = get_post_meta($variation_id, 'b2bking_product_pricetiers_group_b2c', true );
						}


						$price_tiers = b2bking()->convert_price_tiers($price_tiers, wc_get_product($variation_id));

						if (!empty($price_tiers)){
							$have_tiered_price_in_any_variation = 'yes';
							break;
						}
					}
					if ($have_tiered_price_in_any_variation === 'no'){
						$range = $price;
						b2bking()->set_global_data('b2bking_tiered_price_range_display', $range, $product->get_id(),get_current_user_id());

						return $price;
					}

					// parse all variations and get min and max price across all. Store it in cache.
					$min_price = 'no';
					$max_price = 'no';
					
					// get all variations, and check price for each.
					foreach ($children as $variation_id){

						$productvariation = wc_get_product($variation_id);
						// get sale/regular price / group price
						if ( '' !== $productvariation->get_price() ) {
							if ( $productvariation->is_on_sale() ) {
								$varprice = get_post_meta($variation_id,'_sale_price',true);
							   	
								if ($is_b2b_user === 'yes'){
									// Search if there is a specific price set for the user's group
									$b2b_price = b2bking()->tofloat(get_post_meta($variation_id, 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
														
									if (!empty($b2b_price)){
										$varprice = $b2b_price;
									}
								}

							} else {
								$varprice = get_post_meta($variation_id,'_regular_price',true);

								if ($is_b2b_user === 'yes'){
									// Search if there is a specific price set for the user's group
									$b2b_price = b2bking()->tofloat(get_post_meta($variation_id, 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true ));
														
									if (!empty($b2b_price)){
										$varprice = $b2b_price;
									}
								}
							}

							// double tax adjustment error
							//$varprice = b2bking()->b2bking_wc_get_price_to_display( $productvariation, array( 'price' => $varprice ) ); 

							// Search price tiers
							$price_tiers = get_post_meta($variation_id, 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true );

							// if no tiers AND no group price exists, get B2C tiered pricing
							$grregprice = get_post_meta($variation_id, 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
							$grsaleprice = get_post_meta($variation_id, 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
							$grpriceexists = 'no';
							if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
								$grpriceexists = 'yes';	
							}
							if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
								$grpriceexists = 'yes';	
							}

							if (empty($price_tiers) && $grpriceexists === 'no'){
								$price_tiers = get_post_meta($variation_id, 'b2bking_product_pricetiers_group_b2c', true );
							}

							$price_tiers = b2bking()->convert_price_tiers($price_tiers, $productvariation);

							if (!empty($price_tiers)){
								

								$price_tiers = array_filter(explode(';', $price_tiers));
								$var_min_price = b2bking()->tofloat($varprice);
								$var_max_price = b2bking()->tofloat($varprice);

								// first eliminate all quantities larger than the quantity in cart
								foreach($price_tiers as $tier){
									$tier_values = explode(':', $tier);
									if (isset($tier_values[1])){
										if (b2bking()->tofloat($tier_values[1]) < $var_min_price){
											$var_min_price = b2bking()->tofloat($tier_values[1]);
										}
									}
								}

								// clear cache mostly for variable products
								if (apply_filters('b2bking_clear_wc_products_cache', true)){
									WC_Cache_Helper::get_transient_version( 'product', true );
								}

								// adjust price for tax
								$var_min_price = b2bking()->b2bking_wc_get_price_to_display( $productvariation, array( 'price' => $var_min_price ) );
								$var_max_price = b2bking()->b2bking_wc_get_price_to_display( $productvariation, array( 'price' => $var_max_price ) );

							} else {

								$var_min_price = b2bking()->b2bking_wc_get_price_to_display( $productvariation, array( 'price' => $varprice ) );
								$var_max_price = b2bking()->b2bking_wc_get_price_to_display( $productvariation, array( 'price' => $varprice ) );
								
							}
						}

						if ($min_price === 'no'){
							$min_price = $var_min_price;
							$max_price = $var_max_price;
						} else {
							if ($var_min_price < $min_price){
								$min_price = $var_min_price;
							}
							if ($var_max_price > $max_price){
								$max_price = $var_max_price;
							}
						}
					}

					if($min_price !== $max_price){						

						if (apply_filters('b2bking_tiered_range_show_min', false)){
							$range = apply_filters('b2bking_tiered_range_show_min_from',esc_html__('from','b2bking')).' '.wc_price($min_price);
						} else {
							$range = '<div class="b2bking_tiered_range_replaced">'.b2bking()->format_price_range( $min_price, $max_price ).'</div>';
						}

					} else {
						$range = $price;
					}

					$range.='<div class="b2bking_tiered_range_after"></div>';


					$range = apply_filters('b2bking_tiered_range_display_final', $range, $min_price, $max_price, $product);

					
					b2bking()->set_global_data('b2bking_tiered_price_range_display', $range, $product->get_id(),get_current_user_id());

				}

				if (apply_filters('b2bking_tiered_hide_range', false)){
					return $price.'<div class="b2bking_hidden">'.$range.'</div>';
				}

				return $range;
			} else {
				return $price;	
			}
		}
	}

	function b2bking_tiered_raise_integration($price_display, $price, $val, $product_id){

		$raise_percentage = b2bking()->get_raise_price_percentage($product_id);
		if ($raise_percentage > 0){
			$price = $price*(100+$raise_percentage)/100;
			$price = apply_filters('b2bking_raise_price_final', $price, $product_id);
			$price_display = wc_price(b2bking()->get_woocs_price($price));
		}

		$disc_percentage = b2bking()->get_discount_everywhere_percentage($product_id);
		$disc_amount = b2bking()->get_discount_everywhere_amount($product_id);
		if ($disc_percentage > 0){
			$price_new = $price*(100-$disc_percentage)/100;
		}

		if ($disc_amount > 0){
			if (isset($price_new)){
				// check which one is larger, amount or percentage
				$price_new2 = $price-$disc_amount;
				if ($price_new2 < $price_new){
					$price_new = $price_new2;
				}
			} else {
				$price_new = $price-$disc_amount;
			}
		}

		if ($disc_amount > 0 || $disc_percentage > 0){
			$price_display = wc_format_sale_price(b2bking()->get_woocs_price($price), b2bking()->get_woocs_price($price_new));
			$price_display = apply_filters('b2bking_tiered_discount_everywhere_final', $price_display, $price, $price_new);
		}
		
		return $price_display;
	}

	function b2bking_tiered_pricing_fixed_price($price, $product){

		if (apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product->get_id())){
			return $price;
		}

		if ($product->get_type() === 'bundle'){
			return $price;
		}

		// compatibility with 'All Products for WooCommerce Subscriptions'
		if (apply_filters('b2bking_use_compatibility_code_wcsatt', true)){
			if (defined('WCS_ATT_VERSION') && class_exists('WCS_ATT_Product')){
				if ( WCS_ATT_Product::is_subscription( $product ) ) {
					return $price;
				}
			}
		}

		// WooCommerce Product Bundles
		if (defined('WC_PB_VERSION')) {
			$price = WC_PB_Product_Prices::filter_get_price($price, $product);
			if ($price === 0) {
				return 0;
			}
		}

		// skip in CRON and such
		if (!is_object( WC()->cart )){
			return $price;
		}
		

		$user_id = get_current_user_id();
    	$user_id = b2bking()->get_top_parent_account($user_id);
    	$user = new WP_User($user_id);
    	$user_name = $user->user_login;

    	// check transient to see if the current price has been set already via another function
    	if ((floatval(b2bking()->get_global_data('custom_set_price', $product->get_id(), $user_id)) === floatval($price)) && floatval($price) !== floatval(0)){
    		return $price;
    	}

    	if (defined('SALESKING_DIR')){
    		if (is_object( WC()->cart )){
    			foreach( WC()->cart->get_cart() as $cart_item ){
    			    $prodid = $cart_item['product_id'];
    			    $varid = $cart_item['variation_id'];
    			    if ($product->get_id() === $prodid || $product->get_id() === $varid){
    			    	if (isset($cart_item['_salesking_set_price'])){
    			    		return $cart_item['_salesking_set_price'];
    			    	}
    			    }
    			}
    		}
    	}

    	// coupon checks, do not apply if this is a free produc tor pdocut added by coupon plugin
    	if (apply_filters('b2bking_check_cart_items', true)){
	    	foreach( WC()->cart->get_cart() as $cart_item ){
				$product_id = $cart_item['product_id'];
				$variation_id = $cart_item['variation_id'];
				if ($product->get_id() === $product_id || $product->get_id() === $variation_id){

					if (isset($cart_item['free_product'])){
						return $price;
					}

					if (isset($cart_item['wd_is_free_gift'])){
						return $price;
					}

					if (isset($cart_item['wdr_free_product'])){
						return $price;
					}

					if (isset($cart_item['free_gift_coupon'])){
						return $price;
					}
					if (isset($cart_item['wc_sc_product_source'])){
						return $price;
					}
					if (isset($cart_item['asnp_wepb_parent_id']) || isset($cart_item['asnp_wepb_items'])){
						return $price;
					}
					if (isset($cart_item['sample_product'])){
						if ($cart_item['sample_product'] === 'yes'){
							return $price;
						}
					}
					// integration with woo chained products
					if (isset($cart_item['chained_item_of'])){
						return $price;
					}

					if (apply_filters('b2bking_disallow_b2b_cart_bundle_pricing', true)){

						if (isset($cart_item['woosb_parent_id']) || isset($cart_item['bundled_by']) || isset($cart_item['b2bking_is_offer_child'])){
							return $price;
						}
					}

					// yith product
					$yith_product = get_option( 'yith_wapo_sold_individually_product_id' );
					if (!empty($yith_product) && $yith_product !== false && $yith_product !== 0){
						if ($product_id == $yith_product || $variation_id == $yith_product){
							return $price;
						}
					}
				}
			}
		}

		// if we have individual meta pricing, do not apply tiered pricing
		$individual_meta_price = get_post_meta($product->get_id(),'b2bking_sale_price_user_'.$user_id, true);
		$individual_meta_regular_price = get_post_meta($product->get_id(),'b2bking_regular_price_user_'.$user_id, true);

		if (empty($individual_meta_price)){
			$individual_meta_price = get_post_meta($product->get_id(),'b2bking_sale_price_user_'.$user_name, true);
		}
		if (empty($individual_meta_regular_price)){
			$individual_meta_regular_price = get_post_meta($product->get_id(),'b2bking_regular_price_user_'.$user_name, true);
		}

		if (!empty($individual_meta_price) || !empty($individual_meta_regular_price)){
			return $price;
		}

		$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product->get_id());

			
		// Search price tiers
		$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true );

		// if no tiers AND no group price exists, get B2C tiered pricing
		$grregprice = get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
		$grsaleprice = get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
		$grpriceexists = 'no';
		if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
			$grpriceexists = 'yes';	
		}
		if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
			$grpriceexists = 'yes';	
		}

		if (empty($price_tiers) && $grpriceexists === 'no'){
			$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_b2c', true );
		}
		$price_tiers = b2bking()->convert_price_tiers($price_tiers, $product);

		if (!empty($price_tiers)){
			// if there are price tiers, check product quantity in cart and set price accordingly

			// find product quantity in cart
			$product_id = $product->get_id();
			$quantity = 0;
			if (is_object( WC()->cart )){
				// particularly in the case of product addons / options, there is the following issue:
				// for customized products with various options, their IDs are the same, just meta data are different
				// by searching the first ID in cart and breaking the foreach, all we're doing is forcing all products to use the qty of the first instance.

				// if there are multiple instances of the item, let's add up all quantities
				$instances = 0;


				// for variable products, sum up variations
				$possible_parent_id = wp_get_post_parent_id($product_id);
				$sum_up_variations = 'no';
				if ($possible_parent_id !== 0){
					$sum_up_variations = get_post_meta( $possible_parent_id, 'b2bking_tiered_sum_up_variations', true );
				}
				
				foreach( WC()->cart->get_cart() as $cart_item ){

				    if ( $product_id === $cart_item['product_id'] || $product_id === $cart_item['variation_id']){
				    	$quantity = apply_filters('b2bking_cart_item_quantity_tiers', $cart_item['quantity'], $cart_item['variation_id'], $cart_item['product_id']);

				    	$instances++;
				    }

				    if ($possible_parent_id !== 0 && $sum_up_variations === 'yes'){
				    	// for variable products, sum up variations if enabled
				    	if ( $possible_parent_id === $cart_item['product_id']){
				    		$quantity = apply_filters('b2bking_cart_item_quantity_tiers', $cart_item['quantity'], $cart_item['variation_id'], $cart_item['product_id']);
				    		$instances++;
				    	}
				    }
				}

				if ($instances > 1){
					$quantity = 0;

					// let's add up all the quantities together
					foreach( WC()->cart->get_cart() as $cart_item ){
					    if ( $product_id === $cart_item['product_id'] || $product_id === $cart_item['variation_id']){
					    	$quantity += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item['quantity'], $product_id);
					    } else {
					    	if ($sum_up_variations === 'yes'){
					    		if ( $possible_parent_id === $cart_item['product_id']){
					    			$quantity += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item['quantity'], $cart_item['variation_id']);
					    		}
					    	}
					    }
					}
				}
			}

			if (apply_filters('b2bking_tiered_pricing_uses_total_cart_qty', false)){
				$quantity = 0;
				foreach( WC()->cart->get_cart() as $cart_item ){
					$quantity += apply_filters('b2bking_tiered_pricing_count_total_qty', $cart_item['quantity'], $cart_item);
				}
			}

		    if ($quantity !== 0){
				$price_tiers = explode(';', $price_tiers);
				$quantities_array = array();
				$prices_array = array();

				// first eliminate all quantities larger than the quantity in cart
				foreach($price_tiers as $tier){
					$tier_values = explode(':', $tier);
					if (count($tier_values) > 1){
						if ($tier_values[0] <= $quantity && !empty($tier_values[0])){
							array_push($quantities_array, $tier_values[0]);

							$prices_array[$tier_values[0]] = b2bking()->tofloat($tier_values[1]);
						}
					}
				}


				// if any number remains
				if(count($quantities_array) !== 0){

					// alternative calculation algorithm START: each additonal item
					if (apply_filters('b2bking_tiered_pricing_use_each_additional', false, $product)){
						$total_price = 0;
						$original_price = $price;
						$pieces_by_quantity = array();
						$prices_by_quantity = array();

						// calculate how many pieces I have of each quantity tier, e.g. 3 pieces in tier 0, 5 pieces in tier 1, etc.
						sort($quantities_array);
						$pieces_by_quantity[0] = $quantities_array[0]-1; // set initial value, e.g. if 3 items is first, then initial is 2
						$prices_by_quantity[0] = $original_price;
						foreach ($quantities_array as $index => $quantity_in_table){
							// if next quantity exists, get value of next quantity
							if (isset($quantities_array[$index+1])){
								$next_quantity = $quantities_array[$index+1];
								$difference = $next_quantity - $quantity_in_table;
							} else {
								// this quantity is the last one
								$next_quantity = $quantity; // qty in cart
								$difference = $next_quantity - $quantity_in_table + 1;
							}

							$pieces_by_quantity[$quantity_in_table] = $difference;
							$prices_by_quantity[$quantity_in_table] = $prices_array[$quantity_in_table];
						}

						foreach ($pieces_by_quantity as $quantityindex => $pieces){
							$total_price += $pieces * $prices_by_quantity[$quantityindex];
						}

						// calculate unit price based on total price
						$unit_price = $total_price / $quantity;
						return $unit_price;
					}
					// alternative calculation algorithm END: each additonal item



					// get the largest number
					$largest = max($quantities_array);
					// clear cache mostly for variable products
					if (apply_filters('b2bking_clear_wc_products_cache', true)){
						WC_Cache_Helper::get_transient_version( 'product', true );
					}
					
					// if regular table exist, but group table does not exist
					// apply tiered pricing only if the user's group price is not already smaller than tier price
					if (empty(get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true ))){

						if (b2bking()->tofloat($price) > b2bking()->tofloat($prices_array[$largest])){


							if (defined('WCCS_VERSION')) {
							    global $WCCS;
							    $prices_array[$largest] = b2bking()->get_woocs_price($prices_array[$largest]);
							}

							// Curcy
							if (defined('WOOMULTI_CURRENCY_F_DIR')) {
								$prices_array[$largest] = b2bking()->get_woocs_price($prices_array[$largest]);
							}

							return apply_filters('b2bking_tiered_price_displayed', $prices_array[$largest], $product, $price);
						} else {
							// return regular price
							return $price;

						}
					} else {

						// before applying the tiered pricing, at first check that the tiered price is smaller than the 'sale price' // otherwise give the sale price
						// if user is not b2c or logged out
						if (is_user_logged_in() && get_user_meta($user_id,'b2bking_b2buser', true) === 'yes'){
							$smallest_standard_price = $grregprice;
							if (!empty($grsaleprice)){
								$smallest_standard_price = $grsaleprice;
							}
							if (!empty($smallest_standard_price)){

								// if smallest standard price is LOWER (better price) than the tiered price, give this instead
								if (b2bking()->tofloat($smallest_standard_price) < b2bking()->tofloat($prices_array[$largest])){

									return $smallest_standard_price;

								}
							}
						}

						if (defined('WCCS_VERSION')) {
						    global $WCCS;
						    $prices_array[$largest] = b2bking()->get_woocs_price($prices_array[$largest]);
						}

						// Curcy
						if (defined('WOOMULTI_CURRENCY_F_DIR')) {
							$prices_array[$largest] = b2bking()->get_woocs_price($prices_array[$largest]);
						}

						return apply_filters('b2bking_tiered_price_displayed', $prices_array[$largest], $product, $price);
					}

				} else {
					return $price;
				}

			} else {
				return $price;
			}

		} else {
			return $price;
		}
	}


	public static function b2bking_show_tiered_pricing_table($prodidshortcode = "", $show_name = 'no'){

		global $post;
		if (isset($post->ID)){
			$post_id = $post->ID;
		} else {
			return;
		}

		if (apply_filters('b2bking_disable_price_table', false, $post_id)){
			return;
		}

		// only for simple products
		$product = wc_get_product($post_id);

		$disable_multirun_check_tables = apply_filters('disable_multirun_check_tables', false);


		$shortcodeusage = false;
		if ($prodidshortcode !== ""){
			$shortcodeusage = true;
			$post_id = $prodidshortcode;
			$product = wc_get_product($prodidshortcode);
		}

		$shortcodeusage = apply_filters('b2bking_shortcodeusage_tiered_table', $shortcodeusage);


		static $b2bking_has_run3 = false;
		if ($b2bking_has_run3 === false || $disable_multirun_check_tables || $shortcodeusage === true){

			if (is_object($product)){

				if (intval($post_id) === intval(b2bking()->safe_get_queried_object_id()) || $shortcodeusage === true || wp_doing_ajax()){

					if( $product->is_type( 'simple' )  || $shortcodeusage === true || apply_filters('b2bking_apply_tiered_price_table', false, $product)){
						// get if 1) pricing table is enabled and 2) there are tiered prices set up
						$is_enabled = get_post_meta($post_id, 'b2bking_show_pricing_table', true);
						if (!$product->is_purchasable() && !apply_filters('b2bking_apply_tiered_price_table', false, $product)){
							$is_enabled = 'no';
						}
						if ($is_enabled !== 'no'){
							// get user's group
							$user_id = get_current_user_id();
					    	$user_id = b2bking()->get_top_parent_account($user_id);
					    	$user = new WP_User($user_id);
					    	$user_name = $user->user_login;

					    	// if we have individual meta pricing, do not apply tiered pricing
					    	$individual_meta_price = get_post_meta($post_id,'b2bking_sale_price_user_'.$user_id, true);
					    	$individual_meta_regular_price = get_post_meta($post_id,'b2bking_regular_price_user_'.$user_id, true);
					    	if (empty($individual_meta_price)){
					    		$individual_meta_price = get_post_meta($post_id,'b2bking_sale_price_user_'.$user_name, true);
					    	}
					    	if (empty($individual_meta_regular_price)){
					    		$individual_meta_regular_price = get_post_meta($post_id,'b2bking_regular_price_user_'.$user_name, true);
					    	}

					    	if (!empty($individual_meta_price) || !empty($individual_meta_regular_price)){
					    		return;
					    	}


					    	$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $post_id);
							$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );

							if ( apply_filters('b2bking_tiered_table_discount_uses_sale_price', $product->is_on_sale() ) ) {
								$original_user_price = get_post_meta($product->get_id(),'_sale_price',true);
							   	
								if ($is_b2b_user === 'yes'){
									// Search if there is a specific price set for the user's group
									$b2b_price = b2bking()->tofloat(get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
														
									if (!empty($b2b_price)){
										$original_user_price = $b2b_price;
									}
								}

							} else {
								$original_user_price = get_post_meta($product->get_id(),'_regular_price',true);

								if ($is_b2b_user === 'yes'){
									// Search if there is a specific price set for the user's group
									$b2b_price = b2bking()->tofloat(get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true ));
														
									if (!empty($b2b_price)){
										$original_user_price = $b2b_price;
									}
								}
							}

							// adjust price for tax
							$original_user_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $original_user_price ) ); // get sale price

							// ORIGINAL PRODUCT PRICE END

							$price_tiers = get_post_meta($post_id, 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true);

							$user_price = array();
							$grpriceexists = 'no';


							// if didn't find anything as a price tier + user does not have group price, give regular price tiers
							// if no tiers AND no group price exists, get B2C tiered pricing
							if ($currentusergroupidnr){
								$grregprice = get_post_meta($post_id, 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
								$grsaleprice = get_post_meta($post_id, 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
								if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
									$grpriceexists = 'yes';	
								}
								if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
									$grpriceexists = 'yes';	
								}
							}


							if (empty($price_tiers) && $grpriceexists === 'no'){
								$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_b2c', true );
							}

							// apply percentage instead of final prices (optiinally)
							$price_tiers = b2bking()->convert_price_tiers($price_tiers, $product);

							/*
							if (!(!empty($price_tiers) && strlen($price_tiers) > 1 )){
								$price_tiers = get_post_meta($post_id, 'b2bking_product_pricetiers_group_b2c', true);
								// if user is logged in b2b
								if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) === 'yes'){
									// but first check that there is at least 1 price in the regular tiers that is better than the group price
									$have_better_price = 'no';

									// go through array
									$price_tiers_array = explode(';', $price_tiers);
									$price_tiers_array = array_filter($price_tiers_array);

									$user_group_regular_price = b2bking()->tofloat(get_post_meta($product->get_id(),'b2bking_regular_product_price_group_'.$currentusergroupidnr, true));
									$user_group_sale_price = b2bking()->tofloat(get_post_meta($product->get_id(),'b2bking_sale_product_price_group_'.$currentusergroupidnr, true));
									if (!empty($user_group_sale_price)){
										$user_price = $user_group_sale_price;
									} else {
										$user_price = $user_group_regular_price;
									}
									if (!empty($user_price)){
										// adjust price for tax
										$user_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $user_price ) ); // get sale price

										foreach ($price_tiers_array as $tier_group){
											$tier_price = b2bking()->tofloat(explode(':',$tier_group)[1]);
											$tier_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $tier_price ) ); 
											if (b2bking()->tofloat($tier_price) <= $user_price){
												$have_better_price = 'yes';
												break;
											}
										}
									} else {
										// there is no group price, show b2c table
										$have_better_price = 'yes';
									}

									if ($have_better_price === 'no'){
										$price_tiers = array();
									}
								}

							}*/

							if (!empty($price_tiers) && strlen($price_tiers) > 1 ){

								// has table
								if ($show_name !== 'no'){
									echo apply_filters('b2bking_product_variations_table_name_html','<p class="b2bking_product_variation_table_title">'.$show_name.'</p>');
								}
								

								$b2bking_has_run3 = true;

								// BETA OPTION
								if (apply_filters('b2bking_show_total_price_tiered_table', false)){
									?>
									<div class="b2bking_tiered_total_price_container">
										<div class="b2bking_tiered_total_price_text"><?php echo apply_filters('b2bking_total_price_tiered_text','Total Price: ');?></div>
										<div class="b2bking_tiered_total_price"></div>
									</div>
									<?php
								}
								?>
								<table class="shop_table b2bking_tiered_price_table <?php if (apply_filters('b2bking_tiered_price_table_horizontal', false)){echo 'b2bking_tiered_price_table_horizontal';} ?> b2bking_shop_table <?php echo 'b2bking_productid_'.esc_attr($post_id);?><?php
								if(intval(get_option( 'b2bking_table_is_clickable_setting', 1 )) === 1){
									echo esc_attr(' b2bking_tiered_clickable');
								}
								?>"><thead>
										<tr>
											<th><?php esc_html_e('Product Quantity','b2bking'); ?></th>
											<?php
											if (intval(get_option( 'b2bking_show_discount_in_table_setting', 0 )) === 1){
												?>
												<th><?php esc_html_e('Discount','b2bking'); ?></th>
												<?php
											}
											?>
											<th><?php echo apply_filters('b2bking_price_per_unit_text',esc_html__('Price per Unit','b2bking'), $product); ?></th>
										</tr>
									</thead>
									<tbody>
										<?php
										$price_tiers_array = explode(';', $price_tiers);
										$price_tiers_array = array_filter($price_tiers_array);

										// need to order this array by the first number (elemnts of form 1:5, 2:5, 6:5)
										$helper_array = array();							
										foreach ($price_tiers_array as $index=> $pair){
											if (empty($pair)) {continue;}
											$pair_array = explode(':', $pair);
											$helper_array[$pair_array[0]] = b2bking()->tofloat($pair_array[1], 4);
										}
										ksort($helper_array);
										$price_tiers_array = array();
										foreach ($helper_array as $index=>$value){
											array_push($price_tiers_array,$index.':'.$value);
										}

										// finished sort
										$number_of_tiers = count($price_tiers_array);
										// only 1 tier
										if ($number_of_tiers === 1){
											$tier_values = explode(':', $price_tiers_array[0]);
											?>
											<tr>
												<td data-range="<?php echo esc_html($tier_values[0]).'+'; ?>"><?php echo esc_html($tier_values[0]).apply_filters('b2bking_tiered_pricing_table_show_direct_qty', '+'); do_action('b2bking_tiered_table_after_quantity', $post_id); ?></td>
												<?php
												// adjust price for tax
												$tier_values[1] = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $tier_values[1] ) ); // get sale price

												if (intval(get_option( 'b2bking_show_discount_in_table_setting', 0 )) === 1){
													?>
													<td><?php
													$now_price = $tier_values[1];

													if ( ! is_numeric($original_user_price) || !($original_user_price > 0)) {
														$original_user_price = 1;
													}

													$discount = ($original_user_price-$now_price)/$original_user_price*100;

													echo apply_filters('b2bking_tiered_round_discount', round($discount).'%', $discount);

													?></td>
													<?php
												}
												?>
												<td><?php 

												echo apply_filters('b2bking_tiered_pricing_table_price', wc_price(b2bking()->get_woocs_price($tier_values[1])), $tier_values[1], $tier_values[0], $post_id); 

												do_action('b2bking_tiered_table_after_price', $post_id, b2bking()->get_woocs_price($tier_values[1]));?>
													
												<input type="hidden" class="b2bking_hidden_tier_value" value="<?php echo b2bking()->get_woocs_price($tier_values[1]);?>">	
												</td>
											</tr>
											<?php
										} else {
											$previous_tier = 'no';
											$previous_value = 'no';

											foreach ($price_tiers_array as $index => $tier){
												if (empty($tier)) {continue;}
												$tier_values = explode(':', $tier);
												if ($previous_tier !== 'no'){

													// adjust price for tax
													$previous_value = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $previous_value ) ); // get sale price


													// check that tier price is better than group price, else don't show tier
													$show_row = 'yes';
													if (!empty($user_price)){
														if ($previous_value > $user_price){
															$show_row = 'no';
														}
													}
													if ($show_row === 'yes'){
														?>
															<tr>
																<td data-range="<?php 

																	if (b2bking()->tofloat($previous_tier) !== b2bking()->tofloat($tier_values[0]-1)){
																		echo esc_html($previous_tier).' - '.esc_html($tier_values[0]-1);
																	} else {
																		echo esc_html($previous_tier);
																	}

																?>"><?php
																if (b2bking()->tofloat($previous_tier) !== b2bking()->tofloat($tier_values[0]-1)){
																	// do not show 1-1
																	if ($previous_tier == $tier_values[0]-1 && $previous_tier == 1){
																		echo 1;
																	} else {
																		// do not show 2-2 3-3 etc
																		if ($previous_tier == $tier_values[0]-1){
																			echo esc_html($previous_tier);
																		} else {
																			echo esc_html($previous_tier).apply_filters('b2bking_tiered_pricing_table_show_direct_qty', ' - '.esc_html($tier_values[0]-1));
																		}
																	}
																} else {
																	echo esc_html(apply_filters('b2bking_tiered_pricing_table_show_direct_qty', $previous_tier));
																}
																do_action('b2bking_tiered_table_after_quantity', $post_id);
																?></td>
																<?php
																if (intval(get_option( 'b2bking_show_discount_in_table_setting', 0 )) === 1){
																	?>
																	<td><?php

																	$now_price = $previous_value;

																	if ( ! is_numeric($original_user_price) || !($original_user_price > 0)) {
																		$original_user_price = 1;
																	}
																	
																	$discount = ($original_user_price-$now_price)/$original_user_price*100;

																	echo apply_filters('b2bking_tiered_round_discount', round($discount).'%', $discount);
																	?></td>
																	<?php
																}
																?>
																<td><?php 

																echo apply_filters('b2bking_tiered_pricing_table_price', wc_price(b2bking()->get_woocs_price($previous_value)), $previous_value, $previous_tier, $post_id); 

																do_action('b2bking_tiered_table_after_price', $post_id, b2bking()->get_woocs_price($previous_value));

																?>
																	
																<input type="hidden" class="b2bking_hidden_tier_value" value="<?php echo b2bking()->get_woocs_price($previous_value);?>">	

																</td>
															</tr>
														<?php
													}
												}
												$previous_tier = $tier_values[0];
												$previous_value = $tier_values[1];

												// if this tier is the last tier
												if (intval($index+1) === intval($number_of_tiers)){

													?>
													<tr>
														<td data-range="<?php echo esc_html($previous_tier).'+'; ?>"><?php echo esc_html($previous_tier).apply_filters('b2bking_tiered_pricing_table_show_direct_qty','+'); do_action('b2bking_tiered_table_after_quantity', $post_id);?></td>
														<?php 
														// adjust price for tax

														$previous_value = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $previous_value ) ); // get sale price

														if (intval(get_option( 'b2bking_show_discount_in_table_setting', 0 )) === 1){
															?>
															<td><?php


															$now_price = $previous_value;

															if ( ! is_numeric($original_user_price) || !($original_user_price > 0)) {
																$original_user_price = 1;
															}	

															$discount = ($original_user_price-$now_price)/$original_user_price*100;

															echo apply_filters('b2bking_tiered_round_discount', round($discount).'%', $discount);
															?></td>
															<?php
														}
														?>
														<td><?php 

														echo apply_filters('b2bking_tiered_pricing_table_price', wc_price(b2bking()->get_woocs_price($previous_value)), $previous_value, $previous_tier, $post_id); 

														do_action('b2bking_tiered_table_after_price', $post_id, b2bking()->get_woocs_price($previous_value));?>
															
														<input type="hidden" class="b2bking_hidden_tier_value" value="<?php echo b2bking()->get_woocs_price($previous_value);?>">	

														</td>

													</tr>
													<?php
												}
											}
										}
										?>
									</tbody>
								</table>
								<?php
								do_action('b2bking_after_tiered_table', $post_id);
							}
						}
					}
				}
			}

		}

	}

	public static function b2bking_show_custom_information_table($prodidshortcode = ""){
		global $post;
		$post_id = $post->ID;
		$product = wc_get_product($post_id);

		$shortcodeusage = false;
		if ($prodidshortcode !== ""){
			$shortcodeusage = true;
			$post_id = $prodidshortcode;
			$product = wc_get_product($prodidshortcode);
		}

		if ($product){
			$disabled_product = apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product->get_id());
			if ($disabled_product === true){
				return;
			}

			static $b2bking_has_run2 = false;
			if ($b2bking_has_run2 === false || $shortcodeusage === true || apply_filters('b2bking_may_show_info_table_multiple', false)){

				if ((is_object($product) && intval($post_id) === intval(b2bking()->safe_get_queried_object_id())) || $shortcodeusage === true || apply_filters('b2bking_may_show_info_table_multiple', false)) {


					// here check that this is indeed a single product page, and that the current product is the main product
					// we do not want to show the table for related products

					if ( is_product() || $shortcodeusage === true){
						// get if 1) info table is enabled and 2) there are rows set up
						$is_enabled = get_post_meta($post_id, 'b2bking_show_information_table', true);
						if ($is_enabled !== 'no' || apply_filters('b2bking_show_information_table_all', false)){
							// get user's group
							$user_id = get_current_user_id();
					    	$user_id = b2bking()->get_top_parent_account($user_id);

							$currentusergroupidnr = b2bking()->get_user_group($user_id);

							$customrows = get_post_meta($post_id, 'b2bking_product_customrows_group_'.$currentusergroupidnr, true);

							// if didn't find anything as a price tier, give regular price tiers
							if (empty($customrows)){
								if (apply_filters('b2bking_information_table_apply_regular_all', true)){
									$customrows = get_post_meta($post_id, 'b2bking_product_customrows_group_b2c', true);
								}
							}

							// now add from dynamic rules
							$rules_tiered = b2bking()->get_applicable_rules('info_table', $product->get_id());

							if (isset($rules_tiered[0])){
								$rules_tiered = $rules_tiered[0];

								if (!empty($rules_tiered)){
									if (is_array($rules_tiered)){

										foreach ($rules_tiered as $index => $rule_id){
											if (get_post_status($rule_id) !== 'publish'){
												unset($rules_tiered[$index]);
											}
										}

										if (!empty($rules_tiered)){

											foreach ($rules_tiered as $applied_rule){
												$extra_table = get_post_meta($applied_rule,'b2bking_product_customrows_group_b2c', true);

												if (empty($customrows)){
													$customrows = $extra_table;
												} else {
													$customrows .= $extra_table;
												}
											}
											
										}

										
									}
									
								}
							}


							if (!empty($customrows) || apply_filters('b2bking_show_information_table_all', false)){
								$b2bking_has_run2 = true;
								?>
								<table class="shop_table b2bking_shop_table b2bking_information_table">
									<thead>
										<tr>
											<th><?php esc_html_e('Information Table','b2bking'); ?></th>
											<th></th>
										</tr>
									</thead>
									<tbody>
										<?php
										$customrows = str_replace('&amp;', '&', $customrows);


										$rows_array = explode(';',$customrows);
										$rows_array = apply_filters('b2bking_information_table_content_rows', $rows_array);
										foreach ($rows_array as $row){
											$row_values = explode (':', $row, 2);
											if (!empty($row_values[0]) && !empty($row_values[1])){
												// display row
												?>
												<tr>
													<td><?php echo wp_kses( $row_values[0], array( 'br' => true, 'strong' => true, 'b' => true, 'a' => array('href' => array(), 'target' => array() ) ) ); ?></td>
													<td><?php echo wp_kses( $row_values[1], array( 'br' => true, 'strong' => true, 'b' => true, 'a' => array('href' => array(), 'target' => array() ) ) ); ?></td>
												</tr>
												<?php
											}
										}
										?>							
									</tbody>
								</table>
								<?php
							}
						}
					}
				}
				
			}
		}
	}


	public static function b2bking_show_tiered_pricing_table_variation( $data, $product, $variation ) {

		ob_start();
		$variation_id = $variation->get_id();
		$product_id = wp_get_post_parent_id($variation_id);

		if (intval($product_id) === intval(b2bking()->safe_get_queried_object_id()) || wp_doing_ajax()){

	    	// get if 1) pricing table is enabled and 2) there are tiered prices set up
	    	$is_enabled = get_post_meta($product_id, 'b2bking_show_pricing_table', true);

	    	if (!$variation->is_purchasable()){
	    		$is_enabled = 'no';
	    	}
	    	if ($is_enabled !== 'no'){
	    		// get user's group
	    		$user_id = get_current_user_id();
	        	$user_id = b2bking()->get_top_parent_account($user_id);
	        	$user = new WP_User($user_id);
	        	$user_name = $user->user_login;

	        	// if we have individual meta pricing, do not apply tiered pricing
	        	$individual_meta_price = get_post_meta($variation_id,'b2bking_sale_price_user_'.$user_id, true);
	        	$individual_meta_regular_price = get_post_meta($variation_id,'b2bking_regular_price_user_'.$user_id, true);
	        	if (empty($individual_meta_price)){
	        		$individual_meta_price = get_post_meta($variation_id,'b2bking_sale_price_user_'.$user_name, true);
	        	}
	        	if (empty($individual_meta_regular_price)){
	        		$individual_meta_regular_price = get_post_meta($variation_id,'b2bking_regular_price_user_'.$user_name, true);
	        	}
	        	if (!empty($individual_meta_price) || !empty($individual_meta_regular_price)){
	        		ob_get_clean();
	        		return $data;
	        	}


	        	$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $variation_id);

	        	// GET ORIGINAL PRODUCT PRICE
	        	$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );
	        	if ( apply_filters('b2bking_tiered_table_discount_uses_sale_price', $variation->is_on_sale() ) ) {
	        		$original_user_price = get_post_meta($variation->get_id(),'_sale_price',true);
	        	   	
	        		if ($is_b2b_user === 'yes'){
	        			// Search if there is a specific price set for the user's group
	        			$b2b_price = b2bking()->tofloat(get_post_meta($variation->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
	        								
	        			if (!empty($b2b_price)){
	        				$original_user_price = $b2b_price;
	        			}
	        		}

	        	} else {
	        		$original_user_price = get_post_meta($variation->get_id(),'_regular_price',true);

	        		if ($is_b2b_user === 'yes'){
	        			// Search if there is a specific price set for the user's group
	        			$b2b_price = b2bking()->tofloat(get_post_meta($variation->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true ));
	        								
	        			if (!empty($b2b_price)){
	        				$original_user_price = $b2b_price;
	        			}
	        		}
	        	}
	        	// adjust price for tax
	        	$original_user_price = b2bking()->b2bking_wc_get_price_to_display( $variation, array( 'price' => $original_user_price ) ); // get sale price

	        	// ORIGINAL PRODUCT PRICE END

	    		$price_tiers = get_post_meta($variation_id, 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true);

	    		$user_price = array();

	    		// if didn't find anything as a price tier + user does not have group price, give regular price tiers
	    		// if no tiers AND no group price exists, get B2C tiered pricing
	    		$grregprice = get_post_meta($variation_id, 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
	    		$grsaleprice = get_post_meta($variation_id, 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
	    		$grpriceexists = 'no';
	    		if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
	    			$grpriceexists = 'yes';	
	    		}
	    		if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
	    			$grpriceexists = 'yes';	
	    		}
	    		if (empty($price_tiers) && $grpriceexists === 'no'){
	    			$price_tiers = get_post_meta($variation_id, 'b2bking_product_pricetiers_group_b2c', true );
	    		}
	    		// apply percentage instead of final prices (optiinally)
	    		$price_tiers = b2bking()->convert_price_tiers($price_tiers, $variation);
	    			    		/*
	    		if (!(!empty($price_tiers) && strlen($price_tiers) > 1 )){
	   				$price_tiers = get_post_meta($variation_id, 'b2bking_product_pricetiers_group_b2c', true);


	   				if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) === 'yes'){
						// but first check that there is at least 1 price in the regular tiers that is better than the group price
						$have_better_price = 'no';

						// go through array
						$price_tiers_array = explode(';', $price_tiers);
						$price_tiers_array = array_filter($price_tiers_array);

						
						$user_group_regular_price = b2bking()->tofloat(get_post_meta($variation_id,'b2bking_regular_product_price_group_'.$currentusergroupidnr, true));
						$user_group_sale_price = b2bking()->tofloat(get_post_meta($variation_id,'b2bking_sale_product_price_group_'.$currentusergroupidnr, true));
						if (!empty($user_group_sale_price)){
							$user_price = $user_group_sale_price;
						} else {
							$user_price = $user_group_regular_price;
						}

						if (!empty($user_price)){
							// adjust price for tax
							$user_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $user_price ) ); // get sale price
							foreach ($price_tiers_array as $tier_group){
								$tier_price=explode(':',$tier_group)[1];
								$tier_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $tier_price ) );
								if (b2bking()->tofloat($tier_price) <= $user_price){
									$have_better_price = 'yes';
									break;
								}
							}
						} else {
							// there is no group price, show b2c table
							$have_better_price = 'yes';
						}

						if ($have_better_price === 'no'){
							$price_tiers = array();
						}
					}

	    		}
	    		*/

	    		$hide_table = apply_filters('b2bking_disable_price_table', false, $variation_id);

	    		if (!empty($price_tiers) && strlen($price_tiers) > 1 && $hide_table === false){

	    			// BETA OPTION
	    			if (apply_filters('b2bking_show_total_price_tiered_table', false)){
	    				?>
	    				<div class="b2bking_tiered_total_price_container">
	    					<div class="b2bking_tiered_total_price_text"><?php echo apply_filters('b2bking_total_price_tiered_text','Total Price: ');?></div>
	    					<div class="b2bking_tiered_total_price"></div>
	    				</div>
	    				<?php
	    			}
	    			
	    			?>
	    			<table class="shop_table b2bking_tiered_price_table <?php if (apply_filters('b2bking_tiered_price_table_horizontal', false)){echo 'b2bking_tiered_price_table_horizontal';} ?> b2bking_shop_table <?php echo 'b2bking_productid_'.esc_attr($variation_id);?><?php

						if(intval(get_option( 'b2bking_table_is_clickable_setting', 1 )) === 1){
							echo esc_attr(' b2bking_tiered_clickable');
						}
					?>"><thead>
	    					<tr>
	    						<th><?php esc_html_e('Product Quantity','b2bking'); ?></th>
	    						<?php
	    						if (intval(get_option( 'b2bking_show_discount_in_table_setting', 0 )) === 1){
	    							?>
	    							<th><?php esc_html_e('Discount','b2bking'); ?></th>
	    							<?php
	    						}
	    						?>
	    						<th><?php echo apply_filters('b2bking_price_per_unit_text',esc_html__('Price per Unit','b2bking'), $variation); ?></th>
	    					</tr>
	    				</thead>
	    				<tbody>
	    					<?php
	    					$price_tiers_array = explode(';', $price_tiers);
	    					$price_tiers_array = array_filter($price_tiers_array);

	    					// need to order this array by the first number (elemnts of form 1:5, 2:5, 6:5)
	    					$helper_array = array();							
	    					foreach ($price_tiers_array as $index=> $pair){
	    						if (empty($pair)) {continue;}
	    						$pair_array = explode(':', $pair);
	    						$helper_array[$pair_array[0]] = b2bking()->tofloat($pair_array[1]);
	    					}
	    					ksort($helper_array);
	    					$price_tiers_array = array();
	    					foreach ($helper_array as $index=>$value){
	    						array_push($price_tiers_array,$index.':'.$value);
	    					}
	    					// finished sort

	    					$number_of_tiers = count($price_tiers_array);
	    					if ($number_of_tiers === 1){
	    						$tier_values = explode(':', $price_tiers_array[0]);
	    						?>
	    						<tr>
	    							<td data-range="<?php echo esc_html($tier_values[0]).'+'; ?>"><?php echo esc_html($tier_values[0]).apply_filters('b2bking_tiered_pricing_table_show_direct_qty','+');
	    								do_action('b2bking_tiered_table_after_quantity', $variation_id); ?></td>

	    							<?php 
	    							// adjust price for tax
	    							$tier_values[1] = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $tier_values[1] ) ); // get sale price

	    							if (intval(get_option( 'b2bking_show_discount_in_table_setting', 0 )) === 1){
	    								?>
	    								<td><?php

	    								$now_price = $tier_values[1];

	    								if ( ! is_numeric($original_user_price) || !($original_user_price > 0)) {
	    									$original_user_price = 1;
	    								}

	    								$discount = ($original_user_price-$now_price)/$original_user_price*100;

	    								echo apply_filters('b2bking_tiered_round_discount', round($discount).'%', $discount);
	    								?></td>
	    								<?php
	    							}
	    							?>
	    							<td><?php 

	    								echo apply_filters('b2bking_tiered_pricing_table_price', wc_price(b2bking()->get_woocs_price($tier_values[1])), $tier_values[1], $tier_values[0], $variation_id); 

	    								do_action('b2bking_tiered_table_after_price', $variation_id, b2bking()->get_woocs_price($tier_values[1])); ?>
	    									
	    								<input type="hidden" class="b2bking_hidden_tier_value" value="<?php echo b2bking()->get_woocs_price($tier_values[1]);?>">	

	    								</td>
	    						</tr>
	    						<?php
	    					} else {
	    						$previous_tier = 'no';
	    						$previous_value = 'no';
	    						foreach ($price_tiers_array as $index => $tier){
	    							if (empty($tier)) {continue;}

	    							$tier_values = explode(':', $tier);
	    							if ($previous_tier !== 'no'){

	    								// adjust price for tax
	    								$previous_value = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $previous_value ) ); // get sale price

	    								// check that tier price is better than group price, else don't show tier
	    								$show_row = 'yes';
	    								if (!empty($user_price)){
	    									if ($previous_value > $user_price){
	    										$show_row = 'no';
	    									}
	    								}
	    								if ($show_row === 'yes'){
	    									?>
		    									<tr>
		    										<td data-range="<?php

		    										if (b2bking()->tofloat($previous_tier) !== b2bking()->tofloat($tier_values[0]-1)){
		    											echo esc_html($previous_tier).' - '.esc_html($tier_values[0]-1);
		    										} else {
		    											echo esc_html($previous_tier);
		    										}

		    										?>"><?php
		    										if (b2bking()->tofloat($previous_tier) !== b2bking()->tofloat($tier_values[0]-1)){

		    											if ($previous_tier == $tier_values[0]-1 && $previous_tier == 1){
		    												echo 1;
		    											} else {
		    												if ($previous_tier == $tier_values[0]-1){
		    													echo esc_html($previous_tier);
		    												} else {
		    													echo esc_html($previous_tier).apply_filters('b2bking_tiered_pricing_table_show_direct_qty',' - '.esc_html($tier_values[0]-1));
		    												}
		    											}

		    										} else {
		    											echo esc_html($previous_tier);
		    										}
		    										do_action('b2bking_tiered_table_after_quantity', $variation_id);
		    										?></td>
		    										<?php
		    										if (intval(get_option( 'b2bking_show_discount_in_table_setting', 0 )) === 1){
		    											?>
		    											<td><?php

		    											$now_price = $previous_value;

		    											if ( ! is_numeric($original_user_price) || !($original_user_price > 0)) {
		    												$original_user_price = 1;
		    											}

		    											$discount = ($original_user_price-$now_price)/$original_user_price*100;

		    											echo apply_filters('b2bking_tiered_round_discount', round($discount).'%', $discount);
		    											?></td>
		    											<?php
		    										} ?>

		    										<td><?php 

		    										echo apply_filters('b2bking_tiered_pricing_table_price', wc_price(b2bking()->get_woocs_price($previous_value)), $previous_value, $previous_tier, $variation_id); 


		    										do_action('b2bking_tiered_table_after_price', $variation_id, b2bking()->get_woocs_price($previous_value));?>
		    											
		    										<input type="hidden" class="b2bking_hidden_tier_value" value="<?php echo b2bking()->get_woocs_price($previous_value);?>">	
	
		    										</td>
		    									</tr>
		    								<?php
		    							}
	    							}
	    							$previous_tier = $tier_values[0];
	    							$previous_value = $tier_values[1];

	    							// if this tier is the last tier
	    							if (intval($index+1) === intval($number_of_tiers)){
	    								?>
	    								<tr>
	    									<td data-range="<?php

	    										echo esc_html($previous_tier).'+';

	    										?>"><?php 

	    										echo esc_html($previous_tier).apply_filters('b2bking_tiered_pricing_table_show_direct_qty','+');
	    										do_action('b2bking_tiered_table_after_quantity', $variation_id);

	    									?></td>

	    									<?php 
	    									// adjust price for tax
	    									$previous_value = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $previous_value ) ); // get sale price

	    									if (intval(get_option( 'b2bking_show_discount_in_table_setting', 0 )) === 1){
	    										?>
	    										<td><?php

	    										$now_price = $previous_value;

	    										if ( ! is_numeric($original_user_price) || !($original_user_price > 0)) {
	    											$original_user_price = 1;
	    										}

	    										$discount = ($original_user_price-$now_price)/$original_user_price*100;

	    										echo apply_filters('b2bking_tiered_round_discount', round($discount).'%', $discount);
	    										?></td>
	    										<?php
	    									}
	    									?>
	    									<td><?php 

	    										echo apply_filters('b2bking_tiered_pricing_table_price', wc_price(b2bking()->get_woocs_price($previous_value)), $previous_value, $previous_tier, $variation_id); 

	    										do_action('b2bking_tiered_table_after_price', $variation_id, b2bking()->get_woocs_price($previous_value)); ?>
	    											
	    										<input type="hidden" class="b2bking_hidden_tier_value" value="<?php echo b2bking()->get_woocs_price($previous_value);?>">	

	    										</td>
	    								</tr>
	    								<?php
	    							}
	    						}
	    					}
	    					?>
	    				</tbody>
	    			</table>
	    			<?php
	    			do_action('b2bking_after_tiered_table', $variation_id);
	    		}
	    	}

	    }

	    if (isset($data['availability_html'])){
    		$previous_availability = $data['availability_html'];
    	} else {
    		$previous_availability = '';
    	}
        $data['availability_html'] = ob_get_clean().$previous_availability;
	    return $data;
	}

	function b2bking_wpml_multicurrency_tiered_integration($tiered_price, $product, $price){
		// WPML Integration
		if (apply_filters('b2bking_apply_wcml_currency', true)){

			$current_currency = apply_filters('wcml_price_currency', NULL );
			if ($current_currency !== NULL){
				$tiered_price = apply_filters( 'wcml_raw_price_amount', $tiered_price, $current_currency );
			}
		}
		return $tiered_price;
	}


	function b2bking_tiered_pricing_compatibility_addons_options($tiered_price, $product, $price){

		// First we need to get the difference between the normal price and the tiered price
		$user_id = get_current_user_id();
		$user_id = b2bking()->get_top_parent_account($user_id);

		$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product->get_id());

		$grregprice = get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
		$grsaleprice = false;

		if (!empty($grsaleprice)){
			if(b2bking()->tofloat($grsaleprice) !== 0){
				$userprice = b2bking()->tofloat($grsaleprice);
			}
		} else {

			if (!empty($grregprice)){
				if(b2bking()->tofloat($grregprice) !== 0){
					$userprice = b2bking()->tofloat($grregprice);	
				}
			} else {

				// sale price
				$userprice = get_post_meta($product->get_id(),'_sale_price', true);

				if (empty($userprice)){
					// reg price
					$userprice = get_post_meta($product->get_id(),'_regular_price', true);
				}
				
			}
		}

		$difference = floatval($userprice) - floatval($tiered_price);

		// now that we have the difference (e.g. -2), we apply it

		$newprice = floatval($price) - floatval($difference);

		return $newprice;

	}

	function b2bking_individual_pricing_fixed_price_bundle($price, $product, $discount = 0, $bundled_item = 0){

		$product_id = $product->get_id();

		// apply group prices
		if (is_user_logged_in()){
			$user_id = get_current_user_id();
	    	$user_id = b2bking()->get_top_parent_account($user_id);
	    	$user = new WP_User($user_id);
	    	$user_name = $user->user_login;

	    	// individual user pricing (meta based / customer pricelists)
	    	$individual_meta_price = get_post_meta($product_id,'b2bking_sale_price_user_'.$user_id, true);
	    	if (empty($individual_meta_price)){
	    		$individual_meta_price = get_post_meta($product_id,'b2bking_sale_price_user_'.$user_name, true);
	    	}
	    	if (empty($individual_meta_price)){
	    		$individual_meta_price = get_post_meta($product_id,'b2bking_regular_price_user_'.$user_id, true);
	    	}
	    	if (empty($individual_meta_price)){
	    		$individual_meta_price = get_post_meta($product_id,'b2bking_regular_price_user_'.$user_name, true);
	    	}

	    	if (!empty($individual_meta_price)){
	    		$individual_meta_price = b2bking()->tofloat($individual_meta_price);

	    		// WCCS
	    		if (defined('WCCS_VERSION')) {
	    			$individual_meta_price = b2bking()->get_woocs_price($individual_meta_price);
	    		}

	    		$price = $individual_meta_price;
	    	}

	    	if (empty($individual_meta_price)){


		    	$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );
		    	$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product_id);
				if ($is_b2b_user === 'yes'){
					// Search if there is a specific price set for the user's group
					$b2b_price = get_post_meta($product_id, 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
					if (empty($b2b_price)){
						$b2b_price = get_post_meta($product_id, 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
					}
					$b2b_price = b2bking()->tofloat($b2b_price);

					if (!empty($b2b_price)){

						// WPML integration
						if (apply_filters('b2bking_apply_wcml_currency', true)){
							$current_currency = apply_filters('wcml_price_currency', NULL );
							if ($current_currency !== NULL){
								$b2b_price = apply_filters( 'wcml_raw_price_amount', $b2b_price, $current_currency );
							}
						}

						// WCCS
						if (defined('WCCS_VERSION')) {
							$b2b_price = b2bking()->get_woocs_price($b2b_price);
						}

						// Curcy
						if (defined('WOOMULTI_CURRENCY_F_DIR')) {
							$b2b_price = b2bking()->get_woocs_price($b2b_price);
						}

						$price = $b2b_price;
					}
				}
			}
		}

		static $running = false;
	    
	    if ($running) {
	        return $price;
	    }
	    
	    $running = true;
	    
	    if ($product->is_on_sale()) {
	    	if (is_cart()){
	        	$price = $product->get_sale_price();
	        }
	    }
	    
	    $running = false;


		return $price;
	}

	function b2bking_individual_pricing_fixed_price($price, $product){


		if (apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product->get_id())){
			return $price;
		}	
		
		if (apply_filters('b2bking_disable_bundle_individual_pricing', true)){
			if ($product->get_type() === 'bundle'){
				return $price;
			}
		}

		if ($product->get_meta('_b2bking_custom_offer_price_set') === 'yes' || $product->get_meta('_b2bking_custom_offer_price_set_bundle') === 'yes') {
	        // If the flag is set, return the current price without modification
	        if ( apply_filters('b2bking_use_compatibility_code_bundles', true)){
	        	return $price;
	        }
	    }
			
		/*
		if (is_cart() or is_checkout()){
			if ( class_exists( 'WC_Subscriptions_Product' ) ){
			    if (WC_Subscriptions_Product::get_trial_length( $product->get_id() ) > 0 ) {
			    	return $price;
			    }
			}
		}*/
		
		// compatibility with 'All Products for WooCommerce Subscriptions'
		if (apply_filters('b2bking_use_compatibility_code_wcsatt', true)){
			if (defined('WCS_ATT_VERSION') && class_exists('WCS_ATT_Product')){
				if ( WCS_ATT_Product::is_subscription( $product ) ) {
					return $price;
				}
			}
		}

		// WooCommerce Product Bundles
		if (defined('WC_PB_VERSION')) {
			$price = WC_PB_Product_Prices::filter_get_price($price, $product);
			if ($price === 0) {
				return 0;
			}
		}

		$custom_price = apply_filters('b2bking_fixed_pricing_custom_price', $price, $product->get_id());
		if ($custom_price !== $price){
			return $custom_price;
		}

		if (!is_object( WC()->cart )){
			if (apply_filters('b2bking_skip_price_changes_api_cron', true)){
				return $price;
			}
		} else {
			if (defined('SALESKING_DIR')){
				foreach( WC()->cart->get_cart() as $cart_item ){
				    $product_id = $cart_item['product_id'];
				    $variation_id = $cart_item['variation_id'];
				    if ($product->get_id() === $product_id || $product->get_id() === $variation_id){
				    	if (isset($cart_item['_salesking_set_price'])){
				    		return $cart_item['_salesking_set_price'];
				    	}
				    }
				}
			}

	    	// coupon checks, do not apply if this is a free produc tor pdocut added by coupon plugin
	    	foreach( WC()->cart->get_cart() as $cart_item_key => $cart_item ){

				$product_id = $cart_item['product_id'];
				$variation_id = $cart_item['variation_id'];
				if ($product->get_id() === $product_id || $product->get_id() === $variation_id){

					if (isset($cart_item['acfw_add_product_discount_type']) && $cart_item['acfw_add_product_discount_type'] === 'override'){
						if(isset($cart_item['acfw_add_product_discount_value']) && floatval($cart_item['acfw_add_product_discount_value']) === floatval(0)){
							return $price;
						}
					}

					if (apply_filters('b2bking_custom_cart_item_ignore_condition', false, $cart_item)){
						return $price;
					}
					
					if (isset($cart_item['free_product'])){
						return $price;
					}

					if (isset($cart_item['wd_is_free_gift'])){
						return $price;
					}

					if (isset($cart_item['wdr_free_product'])){
						return $price;
					}
					
					if (isset($cart_item['free_gift_coupon'])){
						return $price;
					}
					if (isset($cart_item['wc_sc_product_source'])){
						return $price;
					}
					if (isset($cart_item['asnp_wepb_parent_id']) || isset($cart_item['asnp_wepb_items'])){
						return $price;
					}
					if (isset($cart_item['sample_product'])){
						if ($cart_item['sample_product'] === 'yes'){
							return $price;
						}
					}

					// integration with woo chained products
					if (isset($cart_item['chained_item_of'])){
						return $price;
					}

					if (apply_filters('b2bking_disallow_b2b_cart_bundle_pricing', true)){

						if (isset($cart_item['woosb_parent_id'])){
							return $price;
						}
					}
					// yith product
					$yith_product = get_option( 'yith_wapo_sold_individually_product_id' );
					if (!empty($yith_product) && $yith_product !== false && $yith_product !== 0){
						if ($product_id == $yith_product || $variation_id == $yith_product){
							return $price;
						}
					}
				}
			}


			
		}

		// OPTIONS / ADDONS COMPATIBILITY
		if (intval(get_option( 'b2bking_product_options_compatibility_setting', 0 )) === 1){
			// try to get addon value, by calculating price with options - standard price
			$original_price_with_options = floatval($price); 

			$product_id = $product->get_id();
			$standard_price = $regular_price = floatval(get_post_meta($product_id,'_regular_price', true));
			$sale_price = floatval(get_post_meta($product_id,'_sale_price', true));

			/*
			// if current user is b2b and group has a price, get price for his group
			$user_id = get_current_user_id();
			$is_b2b = get_user_meta($user_id,'b2bking_b2buser', true);
			if ($is_b2b === 'yes'){
				$currentusergroupidnr = get_user_meta($user_id,'b2bking_customergroup', true);
				$group_regular = b2bking()->tofloat(get_post_meta($product_id, 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true ));
				if (!empty($group_regular)){
					$standard_price = $regular_price = $group_regular;
					$group_sale = b2bking()->tofloat(get_post_meta($product_id, 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
					$sale_price = $group_sale;
				}
			}*/

			if (!empty($sale_price)){
				$standard_price = $sale_price;
			}
			if (!empty($standard_price)){
				$addon_price = $original_price_with_options-$standard_price;
			} else {
				$addon_price = 0;
			}

			// if addon price is negative at this point, something has gone wrong, so set it to 0 for this calculation

			if ($addon_price > 0){
				if (current_filter() !== 'woocommerce_product_get_regular_price'){
					b2bking()->set_global_data('b2bking_addon_price', $addon_price, $product_id, get_current_user_id());
				}
			} else if ($addon_price < 0){
				// check if we have transient
				//$transient_price = get_transient('b2bking_addon_price_'.$product_id.'_'.get_current_user_id());
				$transient_price = b2bking()->get_global_data('b2bking_addon_price',$product_id,get_current_user_id());
				if ($transient_price){
					$addon_price = $transient_price;
				} else {
					$addon_price = 0;
				}
			}

			// now we have addon price, we add this back at the end to b2bking's calculated price
		}

		
		if (is_user_logged_in()){
			$user_id = get_current_user_id();
	    	$user_id = b2bking()->get_top_parent_account($user_id);
	    	$user = new WP_User($user_id);
	    	$user_name = $user->user_login;

	    	// check transient to see if the current price has been set already via another function
	    //	if (get_transient('b2bking_user_'.$user_id.'_product_'.$product->get_id().'_custom_set_price') === $price){
	    	if ((floatval(b2bking()->get_global_data('custom_set_price', $product->get_id(), $user_id)) === floatval($price)) && floatval($price) !== floatval(0)){
	    		// OPTIONS / ADDONS COMPATIBILITY
	    		if (intval(get_option( 'b2bking_product_options_compatibility_setting', 0 )) === 1){
	    			return (floatval($price) + floatval($addon_price));
	    		}

	    		return $price;
	    	}

	    	// individual user pricing (meta based / customer pricelists)
	    	$individual_meta_price = get_post_meta($product->get_id(),'b2bking_regular_price_user_'.$user_id, true);
	    	if (empty($individual_meta_price)){
	    		$individual_meta_price = get_post_meta($product->get_id(),'b2bking_regular_price_user_'.$user_name, true);
	    	}

	    	if (!empty($individual_meta_price)){
	    		$individual_meta_price = b2bking()->tofloat($individual_meta_price);

	    		// WCCS
	    		if (defined('WCCS_VERSION')) {
	    			$individual_meta_price = b2bking()->get_woocs_price($individual_meta_price);
	    		}
	    		
	    		return $individual_meta_price;
	    	}

	    	$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );
	    	$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product->get_id());
			if ($is_b2b_user === 'yes'){
				// Search if there is a specific price set for the user's group
				$b2b_price = get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );

				// fix for allowing 0 price
				if (trim($b2b_price) === '0'){
					return 0;
				}

				$b2b_price = b2bking()->tofloat($b2b_price);

				if (!empty($b2b_price)){

					// WPML integration
					if (apply_filters('b2bking_apply_wcml_currency', true)){
						$current_currency = apply_filters('wcml_price_currency', NULL );
						if ($current_currency !== NULL){
							$b2b_price = apply_filters( 'wcml_raw_price_amount', $b2b_price, $current_currency );
						}
					}

					// WCCS
					if (defined('WCCS_VERSION')) {
						$b2b_price = b2bking()->get_woocs_price($b2b_price);
					}

					// Curcy
					if (defined('WOOMULTI_CURRENCY_F_DIR')) {
						$b2b_price = b2bking()->get_woocs_price($b2b_price);
					}
					
					// OPTIONS / ADDONS COMPATIBILITY
					if (intval(get_option( 'b2bking_product_options_compatibility_setting', 0 )) === 1){
						if (defined('WCCS_VERSION')) {
							$addon_price = b2bking()->get_woocs_price($addon_price);
						}

						return (floatval($b2b_price) + floatval($addon_price));
					}

					return $b2b_price;
				} else {
					// here is also the possibility that it is empty because it is a variable product. In that case, return a variation price
					// this fix is strictly added for GROUPED products

					if (apply_filters('b2bking_var_products_fix_enable', false)){
						if( $product->is_type('variable') ){
							$children = $product->get_children();
							$min_price = 0;

							// if product has no variation, return price
							if (count($children) === 0){

								return $price;
							}

							foreach ($children as $variation_id){
								// get retail price
								$variation = wc_get_product($variation_id);

								if ($variation){
									$variation_price = get_post_meta($variation_id,'b2bking_regular_product_price_group_'.$currentusergroupidnr, true);
									if (empty($variation_price)){
										$variation_price = get_post_meta($variation_id,'_regular_price', true);	
									}
									if( $variation->is_on_sale() ) {
										$variation_price = get_post_meta($variation_id,'b2bking_sale_product_price_group_'.$currentusergroupidnr, true);
										if (empty($variation_price)){
											$variation_price = get_post_meta($variation_id,'_sale_price', true);	
										}
									}
									if ($min_price === 0){
										$min_price = b2bking()->tofloat($variation_price);
									} else {
										if (b2bking()->tofloat($min_price) > b2bking()->tofloat($variation_price)){
											$min_price = b2bking()->tofloat($variation_price);
										}
									}
									
								}
								
								
							}

							$min_price = b2bking()->b2bking_wc_get_price_to_display( $variation, array( 'price' => $min_price ) );

							// WPML integration
							if (apply_filters('b2bking_apply_wcml_currency', true)){
								$current_currency = apply_filters('wcml_price_currency', NULL );
								if ($current_currency !== NULL){
									$min_price = apply_filters( 'wcml_raw_price_amount', $min_price, $current_currency );
								}
							}

							// WCCS
							if (defined('WCCS_VERSION')) {
								$min_price = b2bking()->get_woocs_price($min_price);
							}

							return $min_price;
						}
					}

					// WCCS
					if (defined('WCCS_VERSION')) {
						$price = b2bking()->get_woocs_price($price);
					}
					

					return $price;
				}
			} else {
				return $price;
			}
		} else {
			return $price;
		}
	}

	function b2bking_individual_pricing_discount_sale_price( $sale_price, $product ){


		if (apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product->get_id())){
			return $sale_price;
		}

		if (apply_filters('b2bking_disable_bundle_individual_pricing', true)){
			if ($product->get_type() === 'bundle'){
				return $sale_price;
			}
		}

		// compatibility with 'All Products for WooCommerce Subscriptions'
		if (apply_filters('b2bking_use_compatibility_code_wcsatt', true)){
			if (defined('WCS_ATT_VERSION') && class_exists('WCS_ATT_Product')){
				if ( WCS_ATT_Product::is_subscription( $product ) ) {
					return $sale_price;
				}
			}
		}		

		if (!is_object( WC()->cart )){
			if (apply_filters('b2bking_skip_price_changes_api_cron', true)){
				return $sale_price;
			}
		} else {
			if (defined('SALESKING_DIR')){
				foreach( WC()->cart->get_cart() as $cart_item ){
				    $product_id = $cart_item['product_id'];
				    $variation_id = $cart_item['variation_id'];
				    if ($product->get_id() === $product_id || $product->get_id() === $variation_id){
				    	if (isset($cart_item['_salesking_set_price'])){
				    		return $sale_price;
				    	}
				    }
				}
			}
		}
				
		if (is_user_logged_in()){
			$user_id = get_current_user_id();
	    	$user_id = b2bking()->get_top_parent_account($user_id);
	    	$user = new WP_User($user_id);
    		$user_name = $user->user_login;

	    	$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );
	    	$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product->get_id());

	    	// individual user pricing (meta based / customer pricelists)
	    	$individual_meta_price = get_post_meta($product->get_id(),'b2bking_sale_price_user_'.$user_id, true);
	    	if (empty($individual_meta_price)){
	    		$individual_meta_price = get_post_meta($product->get_id(),'b2bking_sale_price_user_'.$user_name, true);
	    	}
	    	if (!empty($individual_meta_price)){

	    		$individual_meta_price = b2bking()->tofloat($individual_meta_price);

	    		if (apply_filters('b2bking_apply_wcml_currency', true)){
		    		$current_currency = apply_filters('wcml_price_currency', NULL );
		    		if ($current_currency !== NULL){
		    			$individual_meta_price = apply_filters( 'wcml_raw_price_amount', $individual_meta_price, $current_currency );
		    		}
		    	}

	    		$individual_meta_price = b2bking()->get_woocs_price($individual_meta_price);
	    		return $individual_meta_price;
	    	}


	    	$individual_meta_regular_price = get_post_meta($product->get_id(),'b2bking_regular_price_user_'.$user_id, true);
	    	if (empty($individual_meta_regular_price)){
	    		$individual_meta_regular_price = get_post_meta($product->get_id(),'b2bking_regular_price_user_'.$user_name, true);
	    	}
	    	// if we have a meta regular price but not meta sale price, we must still stop the action, otherwise we mix meta regular with group sale prices, a mess
	    	if (!empty($individual_meta_regular_price)){
	    		return $sale_price;
	    	}

			if ($is_b2b_user === 'yes'){
				// Search if there is a specific price set for the user's group
				$b2b_price = b2bking()->tofloat(get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));

				if (!empty($b2b_price)){

					if (apply_filters('b2bking_apply_wcml_currency', true)){
						$current_currency = apply_filters('wcml_price_currency', NULL );
						if ($current_currency !== NULL){
							$b2b_price = apply_filters( 'wcml_raw_price_amount', $b2b_price, $current_currency );
						}
					}

					$b2b_price = b2bking()->get_woocs_price($b2b_price);

					// First check that there is no tiered price
					$have_tiered_price = 'no';
					// Search price tiers
					$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true );

					// if no tiers AND no group price exists, get B2C tiered pricing
					$grregprice = get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
					$grsaleprice = get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
					$grpriceexists = 'no';
					if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
						$grpriceexists = 'yes';	
					}
					if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
						$grpriceexists = 'yes';	
					}

					if (empty($price_tiers) && $grpriceexists === 'no'){
						$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_b2c', true );
					}


					$price_tiers = b2bking()->convert_price_tiers($price_tiers, $product);

					if (!empty($price_tiers)){
						// if there are price tiers, check product quantity in cart and set price accordingly

						// find product quantity in cart
						$product_id = $product->get_id();
						$quantity = 0;
						if (is_object( WC()->cart )){
						    foreach( WC()->cart->get_cart() as $cart_item ){
						        if ( $product_id === $cart_item['product_id'] || $product_id === $cart_item['variation_id']){
						            $quantity = $cart_item['quantity'];

						            // if "sum up variations" is enabled, make it use the total quantity of the product
						            if (isset($cart_item['variation_id'])){
						            	$possible_parent_id = wp_get_post_parent_id($cart_item['variation_id']);
						            	$sum_up_variations = 'no';
						            	if ($possible_parent_id !== 0){
						            		$sum_up_variations = get_post_meta( $possible_parent_id, 'b2bking_tiered_sum_up_variations', true );
						            	}
						            	if ($sum_up_variations === 'yes' && $possible_parent_id !== 0){
						            		$tempqty = 0;
						            		foreach( WC()->cart->get_cart() as $cart_item2 ){
						            			if ($cart_item2['variation_id'] === $cart_item['variation_id']){
						            				$tempqty += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item2['quantity'], $cart_item2['variation_id']);
						            			} else {
						            				if ($cart_item2['product_id'] === $possible_parent_id){
						            					$tempqty += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item2['quantity'], $cart_item2['variation_id']);
						            				}
						            			}
						            		}

						            		$quantity = $tempqty;
						            	}
						            	// sum up variations end
						            }
						            
						            break;
						        }
						    }
						}

					    if ($quantity !== 0){
							$price_tiers = explode(';', $price_tiers);
							$quantities_array = array();
							$prices_array = array();
							// first eliminate all quantities larger than the quantity in cart
							foreach($price_tiers as $tier){
								$tier_values = explode(':', $tier);
								if (count($tier_values) > 1){
									if ($tier_values[0] <= $quantity && !empty($tier_values[0])){
										array_push($quantities_array, $tier_values[0]);
										$prices_array[$tier_values[0]] = b2bking()->tofloat($tier_values[1]);
									}
								}
							}

							// if any number remains
							if(count($quantities_array) !== 0){
								// get the largest number
								$largest = max($quantities_array);
								// clear cache mostly for variable products
								$have_tiered_price = 'yes';

							}
						}
					} 
					if ($have_tiered_price === 'no'){
						return $b2b_price;
					} else {
						return $sale_price;
					}
				} else {
					// we have reached here = sale price is empty
					// if there is a regular price, but the b2c sale price is smaller, return false instead of b2c sale price
					$b2b_regular_price = b2bking()->tofloat(get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true ));

					
					if (b2bking()->tofloat($sale_price) < b2bking()->tofloat($b2b_regular_price)){
						if ($product->get_type() === 'variation'){
							return $sale_price;
						} else {
							return false;
						}
					} else {
						return $sale_price;
					}
					

				}
			} else {
				return $sale_price;
			}
		} else {
			return $sale_price;
		}
	}

	public function b2bking_woocs_variation_prices_hash( $hash ) {
		// if dynamic rules have changed, clear pricing cache
		WC_Cache_Helper::get_transient_version( 'product', true );
		$hash[] = get_current_user_id().time();
		return $hash;
	}


	function b2bking_individual_pricing_discount_display_dynamic_price( $price_html, $product ) {

		if (apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product->get_id())){
			return $price_html;
		}

		if (apply_filters('b2bking_disable_bundle_individual_pricing', true)){

			if( $product->get_type() === 'bundle'){
				return $price_html;
			}
		}

		if( $product->is_type('variable') && !defined('WOOCS_VERSION')) { // add WOOCS compatibility
			return $price_html;
		}


		if (is_object( WC()->cart )){
			if (defined('SALESKING_DIR')){
				foreach( WC()->cart->get_cart() as $cart_item ){
				    $product_id = $cart_item['product_id'];
				    $variation_id = $cart_item['variation_id'];
				    if ($product->get_id() === $product_id || $product->get_id() === $variation_id){
				    	if (isset($cart_item['_salesking_set_price'])){
				    		return $price_html;
				    	}
				    }
				}
			}
		}

		if (is_user_logged_in()){
			$user_id = get_current_user_id();
	    	$user_id = b2bking()->get_top_parent_account($user_id);
	    	$user = new WP_User($user_id);
	    	$user_name = $user->user_login;

	    	$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );
	    	$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product->get_id());
			if ($is_b2b_user === 'yes'){
				// Search if there is a specific price set for the user's group
				$b2b_price = b2bking()->tofloat(get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));


				$has_individual_meta_price = false;
				// user price has priority over group price, check individual user prices first
				// individual user pricing (meta based / customer pricelists)
				$individual_meta_price = get_post_meta($product->get_id(),'b2bking_sale_price_user_'.$user_id, true);
				if (empty($individual_meta_price)){
					$individual_meta_price = get_post_meta($product->get_id(),'b2bking_sale_price_user_'.$user_name, true);
				}
				if (!empty($individual_meta_price)){
					$individual_meta_price = b2bking()->tofloat($individual_meta_price);

					if (apply_filters('b2bking_apply_wcml_currency', true)){
						$current_currency = apply_filters('wcml_price_currency', NULL );
						if ($current_currency !== NULL){
							$individual_meta_price = apply_filters( 'wcml_raw_price_amount', $individual_meta_price, $current_currency );
						}
					}

					$individual_meta_price = b2bking()->get_woocs_price($individual_meta_price);
					$has_individual_meta_price = true;
				} else {
					// if we have a regular individual price, do not apply B2B / tiered prices
					$individual_meta_regular_price = get_post_meta($product->get_id(),'b2bking_regular_price_user_'.$user_id, true);
					if (empty($individual_meta_regular_price)){
						$individual_meta_regular_price = get_post_meta($product->get_id(),'b2bking_regular_price_user_'.$user_name, true);
					}
					if (!empty($individual_meta_regular_price)){
						$individual_meta_regular_price = b2bking()->tofloat($individual_meta_regular_price);

						return wc_price($individual_meta_regular_price);
					}
				}

				if (!empty($b2b_price) || $has_individual_meta_price){

					// check that there is no tiered price
					// First check that there is no tiered price
					$have_tiered_price = 'no';
					// Search price tiers
					$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true );

					// if no tiers AND no group price exists, get B2C tiered pricing
					$grregprice = get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
					$grsaleprice = get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
					$grpriceexists = 'no';
					if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
						$grpriceexists = 'yes';	
					}
					if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
						$grpriceexists = 'yes';	
					}

					if (empty($price_tiers) && $grpriceexists === 'no'){
						$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_b2c', true );
					}

					$price_tiers = b2bking()->convert_price_tiers($price_tiers, $product);

					if (!empty($price_tiers)){
						// if there are price tiers, check product quantity in cart and set price accordingly

						// find product quantity in cart
						$product_id = $product->get_id();
						$quantity = 0;
						if (is_object( WC()->cart )){
						    foreach( WC()->cart->get_cart() as $cart_item ){
						        if ( $product_id === $cart_item['product_id'] || $product_id === $cart_item['variation_id']){
						            $quantity = $cart_item['quantity'];
						            break;
						        }
						    }
						}

					    if ($quantity !== 0){
							$price_tiers = explode(';', $price_tiers);
							$quantities_array = array();
							$prices_array = array();
							// first eliminate all quantities larger than the quantity in cart
							foreach($price_tiers as $tier){
								$tier_values = explode(':', $tier);
								if (count($tier_values) > 1){
									if ($tier_values[0] <= $quantity && !empty($tier_values[0])){
										array_push($quantities_array, $tier_values[0]);
										$prices_array[$tier_values[0]] = b2bking()->tofloat($tier_values[1]);
									}
								}
							}

							// if any number remains
							if(count($quantities_array) !== 0){
								// get the largest number
								$largest = max($quantities_array);
								// clear cache mostly for variable products
								$have_tiered_price = 'yes';

								// if you have a tiered pricing structure + product is on sale, there's a display issue where a formatted sale price with identical prices shows
								// solve this with a check
								if ($product->is_on_sale()){
									// WCCS
									if (defined('WCCS_VERSION')) {
										$prices_array[$largest] = b2bking()->get_woocs_price($prices_array[$largest]);
									}
									return wc_price($prices_array[$largest]);
								}

							}
						}
					} 
					
					if ($have_tiered_price === 'no' || $has_individual_meta_price){
						if( $product->is_type('variable') && defined('WOOCS_VERSION')) { // add WOOCS compatibility

							global $WOOCS;
							$currrent = $WOOCS->current_currency;
							if ($currrent != $WOOCS->default_currency) {
								$currencies = $WOOCS->get_currencies();
								$rate = $currencies[$currrent]['rate'];

								// apply WOOCS rate to price_html
								$min_price = $product->get_variation_price( 'min' ) / ($rate);
								$max_price = $product->get_variation_price( 'max' ) / ($rate);

								//
								$min_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $min_price ) ); 
								$max_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $max_price ) ); 
								//


								$price_html = b2bking()->format_price_range( $min_price, $max_price );
							}

						} else { 

							if ($product->get_sale_price() < $product->get_regular_price()) {
			    				$price_html = wc_format_sale_price( b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), b2bking()->b2bking_wc_get_price_to_display(  $product, array( 'price' => $product->get_sale_price() ) ) ) . $product->get_price_suffix();
			    			} else {
			    				$price_html = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => min($product->get_regular_price(), $product->get_sale_price())));

			    				if (is_numeric($price_html)){
			    					$price_html = wc_price($price_html);
			    				}

			    			}
						}
					}
		    	}
		    }
		}

		// check that price is not both regular and sale price display error WCCS
		if (defined('WCCS_VERSION')){
			$price1 = $product->get_price();
			if ($price_html === wc_format_sale_price($price1, $price1)){
				return wc_price($price1);
			}
		}

	    return $price_html;
	}

	function b2bking_individual_pricing_discount_display_dynamic_price_in_cart($cart){


		if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
		    return;
		}

		if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ){
		    return;
		}

		// Get current user
    	$user_id = get_current_user_id();
    	$user_id = b2bking()->get_top_parent_account($user_id);
    	$user = new WP_User($user_id);
    	$user_name = $user->user_login;

    	$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );
		if ($is_b2b_user === 'yes'){
			// Iterate through each cart item
			foreach( $cart->get_cart() as $cart_item ) {

				if (isset($cart_item['variation_id']) && intval($cart_item['variation_id']) !== 0){
					$product_id_used = $cart_item['variation_id'];
				} else {
					$product_id_used = $cart_item['product_id'];
				}


				$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product_id_used);


				if (isset($cart_item['sample_product'])){
					if ($cart_item['sample_product'] === 'yes'){
						continue;
					}
				}
				// integration with woo chained products
				if (isset($cart_item['chained_item_of'])){
					continue;
				}
				if (isset($cart_item['wc_sc_product_source'])){
					continue;
				}

				if (apply_filters('b2bking_disallow_b2b_cart_bundle_pricing', true)){

					// integration with woo chained products
					if (isset($cart_item['woosb_parent_id']) || isset($cart_item['bundled_by']) || isset($cart_item['b2bking_is_offer_child'])){
						continue;
					}
				}

				// Search if there is a specific price set for the user's group
				if (isset($cart_item['variation_id']) && intval($cart_item['variation_id']) !== 0){
					$b2b_price = b2bking()->tofloat(get_post_meta($cart_item['variation_id'], 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
					$product_id_set = $cart_item['variation_id'];
				} else {
					$b2b_price = b2bking()->tofloat(get_post_meta($cart_item['product_id'], 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
					$product_id_set = $cart_item['product_id'];
				}

				// yith product
				$yith_product = get_option( 'yith_wapo_sold_individually_product_id' );
				if (!empty($yith_product) && $yith_product !== false && $yith_product !== 0){
					if ($product_id_set == $yith_product){
						continue;
					}
				}

				$disabled_product = apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product_id_set);
				if ($disabled_product === true){
					continue;
				}

				// user price has priority over group price, check individual user prices first
				// individual user pricing (meta based / customer pricelists)
				$individual_meta_price = get_post_meta($product_id_set,'b2bking_sale_price_user_'.$user_id, true);
				if (empty($individual_meta_price)){
					$individual_meta_price = get_post_meta($product_id_set,'b2bking_sale_price_user_'.$user_name, true);
				}

				if (!empty($individual_meta_price)){
					$individual_meta_price = b2bking()->tofloat($individual_meta_price);

					if (apply_filters('b2bking_apply_wcml_currency', true)){
						$current_currency = apply_filters('wcml_price_currency', NULL );
						if ($current_currency !== NULL){
							$individual_meta_price = apply_filters( 'wcml_raw_price_amount', $individual_meta_price, $current_currency );
						}
					}

					$individual_meta_price = b2bking()->get_woocs_price($individual_meta_price);
					$cart_item['data']->set_price( $individual_meta_price );

					b2bking()->set_global_data('custom_set_price', $individual_meta_price, $product_id_set, $user_id);
					continue;
				} else {
					// if we have a regular individual price, do not apply B2B / tiered prices
					$individual_meta_regular_price = get_post_meta($product_id_set,'b2bking_regular_price_user_'.$user_id, true);
					if (empty($individual_meta_regular_price)){
						$individual_meta_regular_price = get_post_meta($product_id_set,'b2bking_regular_price_user_'.$user_name, true);
					}
					if (!empty($individual_meta_regular_price)){
						continue;
					}
				}
				
				if (!empty($b2b_price)){

					if (apply_filters('b2bking_apply_wcml_currency', true)){
						$current_currency = apply_filters('wcml_price_currency', NULL );
						if ($current_currency !== NULL){
							$b2b_price = apply_filters( 'wcml_raw_price_amount', $b2b_price, $current_currency );
						}
					}

					// WCCS
					if (defined('WCCS_VERSION')) {
						$b2b_price = b2bking()->get_woocs_price($b2b_price);
					}

					// First check that there is no tiered price
					$product = wc_get_product($product_id_set);

					$have_tiered_price = 'no';
					// Search price tiers
					$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true );

					// if no tiers AND no group price exists, get B2C tiered pricing
					$grregprice = get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
					$grsaleprice = get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
					$grpriceexists = 'no';
					if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
						$grpriceexists = 'yes';	
					}
					if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
						$grpriceexists = 'yes';	
					}

					if (empty($price_tiers) && $grpriceexists === 'no'){
						$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_b2c', true );
					}
					$price_tiers = b2bking()->convert_price_tiers($price_tiers, $product);

					if (!empty($price_tiers)){
						// if there are price tiers, check product quantity in cart and set price accordingly

						// find product quantity in cart
						$product_id = $product->get_id();
						$quantity = 0;
						if (is_object( WC()->cart )){
						    foreach( WC()->cart->get_cart() as $cart_item ){
						        if ( $product_id === $cart_item['product_id'] || $product_id === $cart_item['variation_id']){
						            $quantity = $cart_item['quantity'];
						            break;
						        }
						    }
						}

						// if "sum up variations" is enabled, make it use the total quantity of the product
						$possible_parent_id = wp_get_post_parent_id($cart_item['variation_id']);
						$sum_up_variations = 'no';
						if ($possible_parent_id !== 0){
							$sum_up_variations = get_post_meta( $possible_parent_id, 'b2bking_tiered_sum_up_variations', true );
						}
						if ($sum_up_variations === 'yes' && $possible_parent_id !== 0){
							$tempqty = 0;
							foreach( WC()->cart->get_cart() as $cart_item2 ){
								if ($cart_item2['variation_id'] === $cart_item['variation_id']){
									$tempqty += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item2['quantity'], $cart_item2['variation_id']);
								} else {
									if ($cart_item2['product_id'] === $possible_parent_id){
										$tempqty += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item2['quantity'], $cart_item2['variation_id']);
									}
								}
							}

							$quantity = $tempqty;
						}
						// sum up variations end

					    if ($quantity !== 0){
							$price_tiers = explode(';', $price_tiers);
							$quantities_array = array();
							$prices_array = array();
							// first eliminate all quantities larger than the quantity in cart
							foreach($price_tiers as $tier){
								$tier_values = explode(':', $tier);
								if (count($tier_values) > 1){
									if ($tier_values[0] <= $quantity && !empty($tier_values[0])){
										array_push($quantities_array, $tier_values[0]);
										$prices_array[$tier_values[0]] = b2bking()->tofloat($tier_values[1]);
									}
								}
							}

							// if any number remains
							if(count($quantities_array) !== 0){
								// get the largest number
								$largest = max($quantities_array);
								// clear cache mostly for variable products
								$have_tiered_price = 'yes';

							}
						}
					} 

					if ($have_tiered_price === 'no'){
						// compatibility with 'All Products for WooCommerce Subscriptions'
						if (apply_filters('b2bking_use_compatibility_code_wcsatt', true)){
							if (defined('WCS_ATT_VERSION') && class_exists('WCS_ATT_Product')){
								if ( WCS_ATT_Product::is_subscription( $cart_item['data'] ) ) {
									continue;
								}
							}
						}

						$cart_item['data']->set_price( $b2b_price );

						b2bking()->set_global_data('custom_set_price', $b2b_price, $product_id_set, $user_id);
					}
		    	}
		    }
	    }

	}

	function b2bking_modify_suffix_vat(){
		if (intval(get_option( 'b2bking_modify_suffix_vat_setting', 0 )) === 1){
			if (apply_filters('b2bking_modify_suffix', true, get_current_user_id())){
				// get if user is b2b
				$vat_exempt = false;

				global $woocommerce;
				$customertest = $woocommerce->customer;

				if (is_a($customertest, 'WC_Customer')){
					$vat_exempt = WC()->customer->is_vat_exempt();
				}

				if ($vat_exempt){
					add_filter( 'woocommerce_get_price_suffix', 'add_price_suffix', 99, 4 );
					  
					function add_price_suffix( $html, $product, $price, $qty ){
					    $html = '<small class="woocommerce-price-suffix"> '.apply_filters('b2bking_price_suffix_ex_vat', esc_html__('ex. VAT', 'b2bking')).'</small>';
					    return $html;
					}
				} else {
					add_filter( 'woocommerce_get_price_suffix', 'add_price_suffixtwo', 99, 4 );
					  
					function add_price_suffixtwo( $html, $product, $price, $qty ){
						// here we account for the situation where rules are set to excl shop incl cart
						if (get_option('woocommerce_tax_display_shop') === 'excl'){
							$html = '<small class="woocommerce-price-suffix"> '.apply_filters('b2bking_price_suffix_ex_vat', esc_html__('ex. VAT', 'b2bking')).'</small>';
						} else {
							$html = '<small class="woocommerce-price-suffix"> '.apply_filters('b2bking_price_suffix_inc_vat', esc_html__('inc. VAT', 'b2bking')).'</small>';
						}
						return $html;
					    
					}
				}
			}
		
		}
	}

	function b2bking_individual_pricing_discount_display_dynamic_price_in_cart_item( $price, $cart_item, $cart_item_key){

		// Get current user
    	$user_id = get_current_user_id();
    	$user_id = b2bking()->get_top_parent_account($user_id);
    	$user = new WP_User($user_id);
    	$user_name = $user->user_login;

    	if (isset($cart_item['sample_product'])){
    		if ($cart_item['sample_product'] === 'yes'){
    			return $price;
    		}
    	}
    	// integration with woo chained products
    	if (isset($cart_item['chained_item_of'])){
    		return $price;
    	}
    	if (isset($cart_item['wc_sc_product_source'])){
    		return $price;
    	}

    	if (apply_filters('b2bking_disallow_b2b_cart_bundle_pricing', true)){

	    	if (isset($cart_item['woosb_parent_id']) || isset($cart_item['bundled_by']) || isset($cart_item['b2bking_is_offer_child'])){
	    		return $price;
	    	}
	    }

    	$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );
		if ($is_b2b_user === 'yes'){

			if (isset($cart_item['variation_id']) && intval($cart_item['variation_id']) !== 0){
				$product_id_used = $cart_item['variation_id'];
			} else {
				$product_id_used = $cart_item['product_id'];
			}
			$currentusergroupidnr = apply_filters('b2bking_b2b_group_for_pricing', b2bking()->get_user_group($user_id), $user_id, $product_id_used);

			if (isset($cart_item['variation_id']) && intval($cart_item['variation_id']) !== 0){
				$b2b_price = b2bking()->tofloat(get_post_meta($cart_item['variation_id'], 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
				$product_id_set = $cart_item['variation_id'];
			} else {
				$b2b_price = b2bking()->tofloat(get_post_meta($cart_item['product_id'], 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true ));
				$product_id_set = $cart_item['product_id'];
			}

			// yith product
			$yith_product = get_option( 'yith_wapo_sold_individually_product_id' );
			if (!empty($yith_product) && $yith_product !== false && $yith_product !== 0){
				if ($product_id_set == $yith_product){
					return $price;
				}
			}

			$disabled_product = apply_filters('b2bking_disable_group_tiered_pricing_product_id', false, $product_id_set);
			if ($disabled_product === true){
				return $price;
			}

			// user price has priority over group price, check individual user prices first
			// individual user pricing (meta based / customer pricelists)
			$individual_meta_price = get_post_meta($product_id_set,'b2bking_sale_price_user_'.$user_id, true);
			if (empty($individual_meta_price)){
				$individual_meta_price = get_post_meta($product_id_set,'b2bking_sale_price_user_'.$user_name, true);
			}
			if (!empty($individual_meta_price)){
				$individual_meta_price = b2bking()->tofloat($individual_meta_price);

				if (apply_filters('b2bking_apply_wcml_currency', true)){
					$current_currency = apply_filters('wcml_price_currency', NULL );
					if ($current_currency !== NULL){
						$individual_meta_price = apply_filters( 'wcml_raw_price_amount', $individual_meta_price, $current_currency );
					}
				}

				$individual_meta_price = b2bking()->get_woocs_price($individual_meta_price);
				return wc_price($individual_meta_price);
			} else {
				// if we have a regular individual price, do not apply B2B / tiered prices
				$individual_meta_regular_price = get_post_meta($product_id_set,'b2bking_regular_price_user_'.$user_id, true);
				if (empty($individual_meta_regular_price)){
					$individual_meta_regular_price = get_post_meta($product_id_set,'b2bking_regular_price_user_'.$user_name, true);
				}
				if (!empty($individual_meta_regular_price)){

					$individual_meta_regular_price = b2bking()->tofloat($individual_meta_regular_price);

					return wc_price($individual_meta_regular_price);
				}
			}

			if (!empty($b2b_price)){

				// First check that there is no tiered price
				$product = wc_get_product($product_id_set);

				// compatibility with 'All Products for WooCommerce Subscriptions'
				if (apply_filters('b2bking_use_compatibility_code_wcsatt', true)){
					if (defined('WCS_ATT_VERSION') && class_exists('WCS_ATT_Product')){
						if ( WCS_ATT_Product::is_subscription( $product ) ) {
							return $price;
						}
					}
				}

				// compatibility with 'All Products for WooCommerce Subscriptions'
				if (apply_filters('b2bking_use_compatibility_code_wcsatt', true)){
					if (defined('WCS_ATT_VERSION') && class_exists('WCS_ATT_Product')){
						if ( WCS_ATT_Product::is_subscription( $cart_item['data'] ) ) {
							return $price;
						}
					}
				}

				$have_tiered_price = 'no';
				// Search price tiers
				$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true );

				// if no tiers AND no group price exists, get B2C tiered pricing
				$grregprice = get_post_meta($product->get_id(), 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
				$grsaleprice = get_post_meta($product->get_id(), 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
				$grpriceexists = 'no';
				if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
					$grpriceexists = 'yes';	
				}
				if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
					$grpriceexists = 'yes';	
				}

				if (empty($price_tiers) && $grpriceexists === 'no'){
					$price_tiers = get_post_meta($product->get_id(), 'b2bking_product_pricetiers_group_b2c', true );
				}
				$price_tiers = b2bking()->convert_price_tiers($price_tiers, $product);

				if (!empty($price_tiers)){
					// if there are price tiers, check product quantity in cart and set price accordingly

					// find product quantity in cart
					$product_id = $product->get_id();
					$quantity = 0;
					if (is_object( WC()->cart )){
					    foreach( WC()->cart->get_cart() as $cart_item ){
					        if ( $product_id === $cart_item['product_id'] || $product_id === $cart_item['variation_id']){
					            $quantity = $cart_item['quantity'];
					            break;
					        }
					    }
					}

					// if "sum up variations" is enabled, make it use the total quantity of the product
					$possible_parent_id = wp_get_post_parent_id($cart_item['variation_id']);
					$sum_up_variations = 'no';
					if ($possible_parent_id !== 0){
						$sum_up_variations = get_post_meta( $possible_parent_id, 'b2bking_tiered_sum_up_variations', true );
					}
					if ($sum_up_variations === 'yes' && $possible_parent_id !== 0){
						$tempqty = 0;
						foreach( WC()->cart->get_cart() as $cart_item2 ){
							if ($cart_item2['variation_id'] === $cart_item['variation_id']){
								$tempqty += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item2['quantity'], $cart_item2['variation_id']);
							} else {
								if ($cart_item2['product_id'] === $possible_parent_id){
									$tempqty += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item2['quantity'], $cart_item2['variation_id']);
								}
							}
						}

						$quantity = $tempqty;
					}
					// sum up variations end

				    if ($quantity !== 0){
						$price_tiers = explode(';', $price_tiers);
						$quantities_array = array();
						$prices_array = array();
						// first eliminate all quantities larger than the quantity in cart
						foreach($price_tiers as $tier){
							$tier_values = explode(':', $tier);
							if (count($tier_values) > 1){
								if ($tier_values[0] <= $quantity && !empty($tier_values[0])){
									array_push($quantities_array, $tier_values[0]);
									$prices_array[$tier_values[0]] = b2bking()->tofloat($tier_values[1]);
								}
							}
						}

						// if any number remains
						if(count($quantities_array) !== 0){
							// get the largest number
							$largest = max($quantities_array);
							// clear cache mostly for variable products
							$have_tiered_price = 'yes';

						}
					}
				} 
				if ($have_tiered_price === 'no'){

					$discount_price = b2bking()->b2bking_wc_get_price_to_display( wc_get_product($product_id_set), array( 'price' => $cart_item['data']->get_sale_price() ) ); // get sale price
					
					if ($discount_price !== NULL && $discount_price !== ''){

						// OPTIONS / ADDONS COMPATIBILITY
						if (intval(get_option( 'b2bking_product_options_compatibility_setting', 0 )) === 1){
							//$addon_price = get_transient('b2bking_addon_price_'.$product_id_set.'_'.get_current_user_id());
							$addon_price = b2bking()->get_global_data('b2bking_addon_price',$product_id_set,get_current_user_id());
							if ($addon_price){
								$discount_price = floatval($discount_price)+floatval($addon_price);
							}
							// now we have addon price, we add this back at the end to b2bking's calculated price
						}

						$price = wc_price($discount_price, 4); 
					}
				}
			} 
		}
		return $price;
	}

	function b2bking_check_user_approval_general(){
		if (is_user_logged_in()){
			$user_id = get_current_user_id();
			$user_status = get_user_meta($user_id, 'b2bking_account_approved', true);
			if($user_status === 'no' && !b2bking()->has_b2b_application_pending($user_id)){
				$is_admin_or_manager = is_user_logged_in() && array_intersect( ['administrator', 'shop_manager'], wp_get_current_user()->roles );

				if (!$is_admin_or_manager){
			    	wp_logout();
			   		wc_add_notice ( esc_html__('Your account is waiting for approval. Until approved, you cannot login.','b2bking'), 'error' );
			   	}
			}
		}
	}

	function b2bking_check_user_approval_on_login ($errors, $username, $password) {

		// First need to get the user object
		if (!empty($username)){
			$user = get_user_by('login', $username);
			if(!$user) {
				$user = get_user_by('email', $username);
				if(!$user) {
					return $errors;
				}
			}
		}

		if (isset($user->ID)){
			$user_status = get_user_meta($user->ID, 'b2bking_account_approved', true);
			if($user_status === 'no' && !b2bking()->has_b2b_application_pending($user->ID)){
				$errors->add('access', esc_html__('Your account is waiting for approval. Until approved, you cannot login.','b2bking'));
			}
		}
	    return $errors;
	}

	// check approval when the user already logged in (eg. ajax or something else)
	function b2bking_check_user_approval_on_login2 ($username, $user) {

		// First need to get the user object
		if (!empty($username)){
			$user = get_user_by('login', $username);
			if(!$user) {
				$user = get_user_by('email', $username);
				if(!$user) {
					return;
				}
			}
		}
		if (isset($user->ID)){
			$user_status = get_user_meta($user->ID, 'b2bking_account_approved', true);
			if($user_status === 'no' && !b2bking()->has_b2b_application_pending($user->ID)){
				$is_admin_or_manager = is_user_logged_in() && array_intersect( ['administrator', 'shop_manager'], wp_get_current_user()->roles );

				if (!$is_admin_or_manager){
					wp_logout();
					wc_add_notice ( esc_html__('Your account is waiting for approval. Until approved, you cannot login.','b2bking'), 'error' );
				}
			}
		}
	}


	// Modify new account email - Add approval needed notice
	function b2bking_modify_new_account_email( $email ) { 

		if ( $email->id === 'customer_new_account' ) {
			$user = get_user_by('email', $email->user_email);
			$approval_needed = get_user_meta($user->ID, 'b2bking_account_approved', true);
			if ($approval_needed === 'no'){
				?>
				<p>
					<?php
					$text = esc_html__('Attention! Your account requires manual approval. Our team will review it as soon as possible. Thank you for understanding.', 'b2bking');
					$text = apply_filters('b2bking_new_account_email_approval_notification', $text );

					echo $text;
					?>
				</p>
				<?php
			}
		}
	}

	function b2bking_save_checkout_entered_billing_fields( $customer_id, $posted ) {

		if (is_user_logged_in()){
			$user_id = $customer_id;
		} else {
			$user_id = 0; 
		}

		// build array of groups visible
		$array_groups_visible = array(
            'relation' => 'OR',
        );

		if (!is_user_logged_in()){
			array_push($array_groups_visible, array(
                'key' => 'b2bking_custom_field_multiple_groups',
                'value' => 'group_loggedout',
                'compare' => 'LIKE'
            ));
		} else {
			// if user is b2c
			if (get_user_meta($user_id,'b2bking_b2buser', true) !== 'yes'){
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_b2c',
	                'compare' => 'LIKE'
	            ));
			} else {
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_'.b2bking()->get_user_group($user_id),
	                'compare' => 'LIKE'
	            ));
        		array_push($array_groups_visible, array(
                    'key' => 'b2bking_custom_field_multiple_groups',
                    'value' => 'group_b2b',
                    'compare' => 'LIKE'
                ));
			}
		}

		// get all enabled custom fields with no default billing connection (first name, last name etc)
		$custom_fields = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
		    	  	    'orderby' => 'menu_order',
		    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_status',
		                        'value' => 1
			                ),
			                array(
			                	'relation' => 'OR',
        		                array(
        	                        'key' => 'b2bking_custom_field_billing_connection',
        	                        'value' => 'none'
        		                ),
        		                array(
        	                        'key' => 'b2bking_custom_field_billing_connection',
        	                        'value' => 'billing_vat'
        		                ),
        		            ),			               
			                array(
		                        'key' => 'b2bking_custom_field_add_to_billing',
		                        'value' => 1
			                ),
			                $array_groups_visible,
		            	)
			    	]);

		foreach ($custom_fields as $custom_field){

			if (isset($posted['b2bking_custom_field_'.$custom_field->ID])) {
		        $data = sanitize_text_field( $posted['b2bking_custom_field_'.$custom_field->ID] );
		        update_user_meta( $customer_id, 'b2bking_custom_field_'.$custom_field->ID, $data);
		    }
	    	if (isset($posted['b2bking_custom_field_'.$custom_field->ID.'bis'])) {
	            $data = sanitize_text_field( $posted['b2bking_custom_field_'.$custom_field->ID.'bis'] );
	            update_user_meta( $customer_id, 'b2bking_custom_field_'.$custom_field->ID, $data);
	        }
		}
	    
	}

	// add custom fields to order meta
	function b2bking_save_billing_details( $order_id ){

		$order = wc_get_order($order_id);

		/* save all regardless, if they exist in POST 
		// build array of groups visible
		$array_groups_visible = array(
            'relation' => 'OR',
        );

		if (!is_user_logged_in()){
			array_push($array_groups_visible, array(
                'key' => 'b2bking_custom_field_multiple_groups',
                'value' => 'group_loggedout',
                'compare' => 'LIKE'
            ));
		} else {
			// if user is b2c
			if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) !== 'yes'){
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_b2c',
	                'compare' => 'LIKE'
	            ));
			} else {
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_'.b2bking()->get_user_group(),
	                'compare' => 'LIKE'
	            ));
	            array_push($array_groups_visible, array(
                    'key' => 'b2bking_custom_field_multiple_groups',
                    'value' => 'group_b2b',
                    'compare' => 'LIKE'
                ));
			}
		}
		*/

		// get all enabled custom fields with no default billing connection (first name, last name etc)
		$custom_fields = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
		    	  	    'orderby' => 'menu_order',
		    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_status',
		                        'value' => 1
			                ),
			                array(
		                        'key' => 'b2bking_custom_field_add_to_billing',
		                        'value' => 1
			                ),
			                //$array_groups_visible
		            	)
			    	]);
		foreach ($custom_fields as $custom_field){
			if (isset($_POST['b2bking_custom_field_'.$custom_field->ID])){
				$order->update_meta_data( 'b2bking_custom_field_'.$custom_field->ID, sanitize_text_field( $_POST['b2bking_custom_field_'.$custom_field->ID] ) );
			}
			if (isset($_POST['b2bking_custom_field_'.$custom_field->ID.'bis'])){
				$order->update_meta_data( 'b2bking_custom_field_'.$custom_field->ID.'bis', sanitize_text_field( $_POST['b2bking_custom_field_'.$custom_field->ID.'bis'] ) );
			}

			$billing_connection = get_post_meta($custom_field->ID, 'b2bking_custom_field_billing_connection', true);
			if (isset($_POST[apply_filters('b2bking_billing_field_name', 'b2bking_custom_field_'.$custom_field->ID, $billing_connection)])){
				$order->update_meta_data( apply_filters('b2bking_billing_field_name', 'b2bking_custom_field_'.$custom_field->ID, $billing_connection), sanitize_text_field( $_POST[apply_filters('b2bking_billing_field_name', 'b2bking_custom_field_'.$custom_field->ID, $billing_connection)] ) );
			}
		}

		$order->save();
	}

	function b2bking_custom_woocommerce_billing_fields_blocks(){

		if ( ! apply_filters('b2bking_blocks_billing_data_apply', false)){ // can cause performance issues on large sites
			return;
		}

		if ( ! apply_filters('b2bking_blocks_billing_data_apply_force', false)){ // can cause performance issues on large sites
			// do not run on my account page, as otherwise leads to double fields.
		    $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
		    
		    if (empty($referer)) {
		        return;
		    }

		    // Get the my account page URL
		    $my_account_url = get_permalink(wc_get_page_id('myaccount'));
		    
		    // Add check for my account URL
		    if (empty($my_account_url)) {
		        return;
		    }
		    
		    $referer_path = parse_url($referer, PHP_URL_PATH);
		    $my_account_path = parse_url($my_account_url, PHP_URL_PATH);
		    
		    // Add checks for parsed paths
		    if (empty($referer_path) || empty($my_account_path)) {
		        return;
		    }
		    
		    $referer_path = rtrim($referer_path, '/');
		    $my_account_path = rtrim($my_account_path, '/');
		    
		    // Final check before strpos
		    if (!empty($my_account_path) && !empty($referer_path)) {
		        if (strpos($referer_path, $my_account_path) === 0) {
		            return; // Exit if we're on any my-account page or subpage
		        }
		    }
		}

		

		$fields['b2bking_js_based_invalid'] = array(
	        'required' => false, 
	        'clear' => false,
	        'type' => 'hidden',
	        'default' => "0",
	    );

		if (is_user_logged_in()){
			$user_id = get_current_user_id();
			if (apply_filters('b2bking_subaccounts_use_same_fields', true)){
				$user_id = b2bking()->get_top_parent_account($user_id);
			}
		} else {
			$user_id = 0; 
		}

		// build array of groups visible
		$array_groups_visible = array(
	        'relation' => 'OR',
	    );

		if (!is_user_logged_in()){
			array_push($array_groups_visible, array(
	            'key' => 'b2bking_custom_field_multiple_groups',
	            'value' => 'group_loggedout',
	            'compare' => 'LIKE'
	        ));
		} else {
			// if user is b2c
			if (get_user_meta($user_id,'b2bking_b2buser', true) !== 'yes'){
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_b2c',
	                'compare' => 'LIKE'
	            ));
			} else {
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_'.b2bking()->get_user_group($user_id),
	                'compare' => 'LIKE'
	            ));
	            array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_b2b',
	                'compare' => 'LIKE'
	            ));
			}
		}

		// Check if custom mapping filter is enabled for cache key
		$custom_mapping_enabled = apply_filters('b2bking_show_custom_mapping_fields_billing', false) ? '1' : '0';
		
		// Build cache key based on user ID
		$cache_key = 'b2bking_blocks_billing_fields_' . $user_id . '_mapping' . $custom_mapping_enabled;
		
		// Try to get cached custom fields
		$custom_fields = get_transient($cache_key);
		
		if (false === $custom_fields) {
			// Cache miss - get all enabled custom fields with no default billing connection (first name, last name etc)
			$custom_fields = get_posts([
	    		'post_type' => 'b2bking_custom_field',
	    	  	'post_status' => 'publish',
	    	  	'numberposts' => -1,
		  	    'orderby' => 'menu_order',
		  	    'order' => 'ASC',
	    	  	'meta_query'=> array(
	    	  		'relation' => 'AND',
	                array(
	                    'key' => 'b2bking_custom_field_status',
	                    'value' => 1
	                ),
	                array(
	                	'relation' => 'OR',
		                array(
	                        'key' => 'b2bking_custom_field_billing_connection',
	                        'value' => 'none'
		                ),
		                array(
	                        'key' => 'b2bking_custom_field_billing_connection',
	                        'value' => 'billing_vat'
		                ),
		            ),			               
	                array(
	                    'key' => 'b2bking_custom_field_add_to_billing',
	                    'value' => 1
	                ),
	                $array_groups_visible,
	        	)
	    	]);

			if ($custom_mapping_enabled === '1'){

				$custom_fields2 = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
				  	    'orderby' => 'menu_order',
				  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
	                        'key' => 'b2bking_custom_field_status',
	                        'value' => 1
			                ),
			                array(
			                	'relation' => 'OR',
			                array(
		                        'key' => 'b2bking_custom_field_billing_connection',
		                        'value' => 'custom_mapping'
			                ),
			            ),			               
			            $array_groups_visible,
	            	)
		    	]);

				$custom_fields = array_merge($custom_fields, $custom_fields2);

			}
			
			// Cache indefinitely
			set_transient($cache_key, $custom_fields, 0);
		}

		$priority = 200;

		foreach ($custom_fields as $custom_field){

			$field_type = get_post_meta ($custom_field->ID, 'b2bking_custom_field_field_type', true);
			$required = intval(get_post_meta ($custom_field->ID, 'b2bking_custom_field_required_billing', true));
			$billing_connection = get_post_meta($custom_field->ID, 'b2bking_custom_field_billing_connection', true);
			// check if this field is VAT
			if ($billing_connection === 'billing_vat'){
				// override type and make it a TEXT type input

				if ($field_type === 'radio' || $field_type === 'checkbox'){
					$field_type = 'select';
				} else {
					$field_type = 'text';

				}

				$required_vat = $required; // remember the actual value of required
				// override required and add it later as a custom validation (reason is that VAT needs to be available only for some countries, and making it required doesn't allow you to conditionally hide/show it)
				if (apply_filters('b2bking_blocks_vat_disable_required', false)){
					$required = 0;
				}

				// check if country applies
				global $woocommerce;
				$customertest = $woocommerce->customer;

				if (is_a($customertest, 'WC_Customer')){
					$billing_country = WC()->customer->get_billing_country();
				} else {
					$billing_country = 'NOTACUSTOMER';
				}
				
				$vat_enabled_countries = get_post_meta($custom_field->ID, 'b2bking_custom_field_VAT_countries', true);
				// set countries in a hidden input
				$fields['b2bking_custom_billing_vat_countries'] = array(
			        'label' => esc_html__('VAT Countries Hidden','b2bking'),
			        'placeholder' => $vat_enabled_countries,
			        'required' => false, 
			        'clear' => false,
			        'type' => 'text',
			        'class' => array('b2bking_vat_countries_hidden'),
			        'default' => $vat_enabled_countries,

			    );
			    // set vat field number in a hidden input
				$fields['b2bking_custom_billing_vat_field_number'] = array(
			        'label' => esc_html__('VAT Field Number','b2bking'),
			        'placeholder' => esc_html__('VAT Field Number','b2bking'),
			        'required' => false, 
			        'clear' => false,
			        'type' => 'text',
			        'class' => array('b2bking_vat_countries_hidden'),
			        'default' => $custom_field->ID,
			    );

				if (!empty($billing_country)){
					if(strpos($vat_enabled_countries, $billing_country) !== false){ // use of !== false is deliberate, strpos has an unusual behaviour
						// vat field applies
						$vat_class='b2bking_vat_visible';
					} else {
						// make the field hidden
						$vat_class='b2bking_vat_hidden';
					}
				} else {
					$vat_class='b2bking_vat_hidden';
				}
			}

			if ($field_type !== 'file'){ // not available to files for the moment
				$field_label = get_post_meta (apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_label', true);
				$field_placeholder = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_placeholder', true);

				$field_value = get_user_meta ($user_id, 'b2bking_custom_field_'.$custom_field->ID, true);

				if ($field_value === NULL){
					$field_value = '';
				}
				if (intval($required) === 1){
					$required = true;
				} else {
					$required = false;
				}

				if ($field_type === 'radio' || $field_type === 'checkbox'){
					$field_type = 'select';
				}

				if ($field_type === 'number' || $field_type === 'email' || $field_type === 'tel'){
					$field_type = 'text';
				}

				$field_array = array(
			        'label' => sanitize_text_field($field_label),
			        'placeholder' => sanitize_text_field($field_placeholder), 
			        'required' => $required, 
			        'clear' => false,
			        'type' => sanitize_text_field($field_type),
			        'default' => $field_value,
			        'priority' => $priority,
			    );


				$editable = intval(get_post_meta($custom_field->ID, 'b2bking_custom_field_editable', true));

				if (is_user_logged_in()) { // editable post-registration
					if ($editable !== 1){
						$field_array['custom_attributes'] = array('readonly'=>'readonly');
					}
				}
				

			    if ($billing_connection === 'billing_vat'){
			    	$field_array['class'] = array($vat_class, 'b2bking_vat_field_container', 'b2bking_vat_field_required_'.$required_vat);

			    	if ($required_vat === 1){
			    		$requiredstring = 'required';
			    	} else {
			    		$requiredstring = '';
			    	}
			    	$field_array['input_class'][] = 'b2bking_custom_field_req_'.$requiredstring;

			    }

			    $options_array = array();
			    if ($field_type === 'select'){
			    	$user_choices = get_post_meta ($custom_field->ID, 'b2bking_custom_field_user_choices', true);
			    	$choices_array = explode (',', $user_choices);
			    	
			    	foreach ($choices_array as $choice){
			    		// check if option is simple or value is specified via option:value
			    		$optionvalue = explode(':', $choice);
			    		if (count($optionvalue) === 2 ){
			    			// value is specified
			    			$options_array[trim($optionvalue[0])] = array('label' => trim($optionvalue[0]), 'value' => trim($optionvalue[1]));
			    		} else {
			    			// simple
			    			$options_array[trim($choice)] = array('label' => trim($choice), 'value' => trim($choice));
			    		}
			    	}
			    }

			    $field_array['options'] = $options_array;

			    $field_arrayname = 'b2bking_custom_field_'.$custom_field->ID;

			    update_user_meta(get_current_user_id(), $field_arrayname, $field_value);

			    $field_arrayname = apply_filters('b2bking_billing_field_name', $field_arrayname, $billing_connection);
			    $fields[$field_arrayname] = $field_array;
			    $priority++;

			    // blocks start
			    $blocks_args = array(
			    		'id'            => 'b2bking/b2bking_custom_field_'.$custom_field->ID,
			    		'label'         => $field_array['label'],
			    		'location'      => 'address',
			    		'required'      => $field_array['required'],
			    		'type' 			=> $field_array['type'],
			    		'attributes'    => array(
			    			'title'        => $field_array['label'],
			    		),
			    	);
			    if (!empty($field_array['options'])){
			    	$blocks_args['options'] = $field_array['options'];
			    }


			    if (isset($field_array['custom_attributes'])){
			    	$blocks_args['attributes']['readOnly']  = $field_array['custom_attributes']['readonly'];
			    }

			    if (function_exists('woocommerce_register_additional_checkout_field')){

			    	$supported_field_types = [ 'text', 'select', 'checkbox' ]; // supported by woocommerce in latest version
			    	if (in_array($blocks_args['type'], $supported_field_types)){
					    woocommerce_register_additional_checkout_field(
					    	$blocks_args
					    );
					}
				}

			    add_filter( 'woocommerce_get_default_value_for_b2bking/b2bking_custom_field_'.$custom_field->ID, function ( $value, $group, $wc_object ) use ($custom_field) {
			    	return 4567;

		    		$user_id = get_current_user_id();
		    		$value = get_user_meta ($user_id, 'b2bking_custom_field_'.$custom_field->ID, true);

		    		if ($value === NULL){
		    			$value = '';
		    		}

		    		return $value;

		    	}, 10, 3);	

		    	add_action('woocommerce_blocks_validate_location_address_fields',
		    		function ( \WP_Error $errors, $fields, $group ) use ($custom_field){

		    			$field_value = $fields['b2bking/b2bking_custom_field_'.$custom_field->ID];
		    			$field_number = $custom_field->ID;

		    			// save field data
		    			update_user_meta(get_current_user_id(), 'b2bking_custom_field_'.$custom_field->ID, $field_value);

		    			// validate VAT
		    			$billing_connection = get_post_meta($custom_field->ID, 'b2bking_custom_field_billing_connection', true);
		    			// check if this field is VAT
		    			if ($billing_connection === 'billing_vat'){
		    				
		    				$vat_number_inputted = $field_value;
		    				$vat_number_inputted = strtoupper(str_replace(array('.', ' '), '', $vat_number_inputted));

		    				if (!empty($vat_number_inputted)){

		    					if (apply_filters('b2bking_set_default_prefix_vat', false) !== false){
		    						$prefix = apply_filters('b2bking_set_default_prefix_vat', false);
		    						// if vat nr does not start with the prefix, add the prefix
		    						if (substr( $vat_number_inputted, 0, 2 ) !== $prefix){
		    							$vat_number_inputted = $prefix.$vat_number_inputted;
		    						}
		    					}	
		    				}
		    				
		    				if (isset($fields['country'])){
		    					$country_inputted = sanitize_text_field($fields['country']);
		    				} else {
		    					$country_inputted = 'none';
		    				}

		    				if ($country_inputted === 'none' || empty($country_inputted)){
		    					// check if it is single country shop
	    					    $countries = WC()->countries->get_allowed_countries();
	    					    
	    					    if (count($countries) === 1) {
	    					        $country_inputted = array_keys($countries)[0]; // Returns country code
	    					    }
		    				}

		    				if (!(empty($vat_number_inputted))){

		    					// check if VIES Validation is enabled in settings
		    					$vat_field_vies_validation_setting = get_post_meta($field_number, 'b2bking_custom_field_VAT_VIES_validation', true);

		    					$countries_list_eu = apply_filters('b2bking_country_list_vies', array('AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'EL', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE'));
		    					if (in_array($country_inputted, $countries_list_eu)){
		    						// proceed only if VIES validation is enabled
		    						if (intval($vat_field_vies_validation_setting) === 1){
		    							$error_details = '';
		    							// check vat
		    							try {
		    								$country_code = substr($vat_number_inputted, 0, 2); // take first 2 chars
		    								$vat_number = substr($vat_number_inputted, 2); // remove first 2 chars

		    								$validation = b2bking()->vies_validation($country_code, $vat_number);

		    								$error_details = 'VAT Validation Issue';

		    								// check country is same as VAT country
		    								if (trim(strtolower($country_inputted)) !== trim(strtolower($country_code))){
		    									// check exception Greece (GR) has EL VAT code
		    									if( (trim(strtolower($country_inputted)) === 'gr') && (trim(strtolower($country_code)) === 'el')){
		    										// if indeed the VAT number is EL and country is GR, do nothing
		    									} else {
		    										$errors->add( 'validation', esc_html__('VAT Number you entered is for a different country than the country you selected', 'b2bking') );
		    									}
		    								}


		    							} catch (Exception $e) {
		    								$error = $e->getMessage();

		    								$error_array = array(
		    								    'INVALID_INPUT'       => esc_html__('CountryCode is invalid or the VAT number is empty.', 'b2bking'),
		    								    'SERVICE_UNAVAILABLE' => esc_html__('VIES VAT Service is unavailable. Try again later.', 'b2bking'),
		    								    'MS_UNAVAILABLE'      => esc_html__('VIES VAT Member State Service is unavailable.', 'b2bking'),
		    								    'TIMEOUT'             => esc_html__('Service timeout. Try again later', 'b2bking'),
		    								    'SERVER_BUSY'         => esc_html__('VAT Server is too busy. Try again later.', 'b2bking'),
		    								    'MS_MAX_CONCURRENT_REQ' => esc_html__('Too many requests. The Europa.eu VIES server cannot process your request right now.', 'b2bking'),
		    								);

		    								if ( array_key_exists( $error , $error_array ) ) {
		    								    $error_details .= $error_array[ $error ];
		    								} else {
		    									$error_details .= $error;
		    								}

		    								// if error is independent of the user (unavailable service, timeout, etc), allow it, but notify the website admin
		    								if (apply_filters('b2bking_allow_vat_timeouts_unavailable_errors', true)){
		    									if ($error !== 'INVALID_INPUT'){ // except the invalid format error
		    										$validation = new stdClass();
		    										$validation -> valid = 1;

		    										// mail the website admin about the issue and that this number needs to be checked
		    										$recipient = get_option( 'admin_email' );
		    										$recipient = apply_filters('b2bking_invalid_vat_number_email', $recipient, 0);

		    									    $message = 'A customer registered / ordered on your shop, but the VIES Validation encountered an issue which is not the fault of the user. The request was accepted, but you should manually check this VAT number and customer.';
		    									    $message .= '<br><br>Error details: '.$error;
		    									    if ( array_key_exists( $error , $error_array ) ) {
		    									        $message .= ' ('.$error_array[ $error ].')';
		    									    }

		    									    $current_user = wp_get_current_user();
		    									    if ($current_user->ID != 0) {
		    									        $user_email = $current_user->user_email;
		    									    } else {
		    									        $user_email = 'Logged out user';
		    									    }

		    									    $message .= '<br><br>The VAT number is: '.$country_code.$vat_number;
		    									    $message .= '<br><br>The email of the user is: '.$user_email;

		    									    do_action( 'b2bking_new_message', $recipient, $message, 'Quoteemail:1', 0 );
		    										
		    									}
		    								}
		    							}

		    							if(isset($validation)){
		    								if (intval($validation->valid) === 1){
		    									// VAT IS VALID
		    									// update vat NR to user meta
		    									$vat_field = get_posts([
		    										    		'post_type' => 'b2bking_custom_field',
		    										    	  	'post_status' => 'publish',
		    										    	  	'fields' => 'ids',
		    										    	  	'numberposts' => -1,
		    										    	  	'meta_query'=> array(
		    										    	  		'relation' => 'AND',
		    										                array(
		    									                        'key' => 'b2bking_custom_field_status',
		    									                        'value' => 1
		    										                ),
		    										                array(
		    									                        'key' => 'b2bking_custom_field_billing_connection',
		    									                        'value' => 'billing_vat'
		    										                ),
		    									            	)
		    										    	]);
		    									if (is_user_logged_in()){
		    										update_user_meta( get_current_user_id(), 'b2bking_custom_field_'.$vat_field[0], $vat_number_inputted);
		    										update_user_meta( get_current_user_id(), 'b2bking_custom_field_'.$vat_field[0].'bis', $vat_number_inputted);
		    										update_user_meta( get_current_user_id(), 'vat_number', $vat_number_inputted);
		    										update_user_meta( get_current_user_id(), 'b2bking_user_vat_status', 'validated_vat');
		    									}
		    								} else {
		    									$errors->add( 'validation', esc_html__('VAT Number is Invalid.', 'b2bking').' '.$error_details );
		    								}
		    							} else {
		    								$errors->add( 'validation', esc_html__('VAT Number is Invalid.', 'b2bking').' '.$error_details );
		    								
		    							}

		    						}
		    					}

		    				}
		    			}		    				
		    		},

		    		10,
		    		3
		    	);		

			}
		}


	}

	// add custom fields to billing
	function b2bking_custom_woocommerce_billing_fields($fields){

		$fields['b2bking_js_based_invalid'] = array(
	        'required' => false, 
	        'clear' => false,
	        'type' => 'hidden',
	        'default' => "0",
	    );

		if (is_user_logged_in()){
			$user_id = get_current_user_id();
			if (apply_filters('b2bking_subaccounts_use_same_fields', true)){
				$user_id = b2bking()->get_top_parent_account($user_id);
			}
		} else {
			$user_id = 0; 
		}

		// build array of groups visible
		$array_groups_visible = array(
            'relation' => 'OR',
        );

		if (!is_user_logged_in()){
			array_push($array_groups_visible, array(
                'key' => 'b2bking_custom_field_multiple_groups',
                'value' => 'group_loggedout',
                'compare' => 'LIKE'
            ));
		} else {
			// if user is b2c
			if (get_user_meta($user_id,'b2bking_b2buser', true) !== 'yes'){
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_b2c',
	                'compare' => 'LIKE'
	            ));
			} else {
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_'.b2bking()->get_user_group($user_id),
	                'compare' => 'LIKE'
	            ));
	            array_push($array_groups_visible, array(
                    'key' => 'b2bking_custom_field_multiple_groups',
                    'value' => 'group_b2b',
                    'compare' => 'LIKE'
                ));
			}
		}

		// get all enabled custom fields with no default billing connection (first name, last name etc)
		$custom_fields = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
		    	  	    'orderby' => 'menu_order',
		    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_status',
		                        'value' => 1
			                ),
			                array(
			                	'relation' => 'OR',
        		                array(
        	                        'key' => 'b2bking_custom_field_billing_connection',
        	                        'value' => 'none'
        		                ),
        		                array(
        	                        'key' => 'b2bking_custom_field_billing_connection',
        	                        'value' => 'billing_vat'
        		                ),
        		            ),			               
			                array(
		                        'key' => 'b2bking_custom_field_add_to_billing',
		                        'value' => 1
			                ),
			                $array_groups_visible,
		            	)
			    	]);

		if (apply_filters('b2bking_show_custom_mapping_fields_billing', false)){

			$custom_fields2 = get_posts([
		    		'post_type' => 'b2bking_custom_field',
		    	  	'post_status' => 'publish',
		    	  	'numberposts' => -1,
	    	  	    'orderby' => 'menu_order',
	    	  	    'order' => 'ASC',
		    	  	'meta_query'=> array(
		    	  		'relation' => 'AND',
		                array(
	                        'key' => 'b2bking_custom_field_status',
	                        'value' => 1
		                ),
		                array(
		                	'relation' => 'OR',
    		                array(
    	                        'key' => 'b2bking_custom_field_billing_connection',
    	                        'value' => 'custom_mapping'
    		                ),
    		            ),			               
		                $array_groups_visible,
	            	)
		    	]);

			$custom_fields = array_merge($custom_fields, $custom_fields2);

		}

		$priority = 200;

		foreach ($custom_fields as $custom_field){

			$field_type = get_post_meta ($custom_field->ID, 'b2bking_custom_field_field_type', true);
			$required = intval(get_post_meta ($custom_field->ID, 'b2bking_custom_field_required_billing', true));
			$billing_connection = get_post_meta($custom_field->ID, 'b2bking_custom_field_billing_connection', true);
			// check if this field is VAT
			if ($billing_connection === 'billing_vat'){
				// override type and make it a TEXT type input

				if ($field_type === 'radio' || $field_type === 'checkbox'){
					$field_type = 'select';
				} else {
					$field_type = 'text';

				}

				$required_vat = $required; // remember the actual value of required
				// override required and add it later as a custom validation (reason is that VAT needs to be available only for some countries, and making it required doesn't allow you to conditionally hide/show it)
				$required = 0;

				// check if country applies
				global $woocommerce;
				$customertest = $woocommerce->customer;

				if (is_a($customertest, 'WC_Customer')){
					$billing_country = WC()->customer->get_billing_country();
				} else {
					$billing_country = 'NOTACUSTOMER';
				}
				
				$vat_enabled_countries = get_post_meta($custom_field->ID, 'b2bking_custom_field_VAT_countries', true);
				// set countries in a hidden input
				$fields['b2bking_custom_billing_vat_countries'] = array(
			        'label' => esc_html__('VAT Countries Hidden','b2bking'),
			        'placeholder' => $vat_enabled_countries,
			        'required' => false, 
			        'clear' => false,
			        'type' => 'text',
			        'class' => array('b2bking_vat_countries_hidden'),
			        'default' => $vat_enabled_countries,

			    );
			    // set vat field number in a hidden input
				$fields['b2bking_custom_billing_vat_field_number'] = array(
			        'label' => esc_html__('VAT Field Number','b2bking'),
			        'placeholder' => esc_html__('VAT Field Number','b2bking'),
			        'required' => false, 
			        'clear' => false,
			        'type' => 'text',
			        'class' => array('b2bking_vat_countries_hidden'),
			        'default' => $custom_field->ID,
			        
			    );

				if (!empty($billing_country)){
					if(strpos($vat_enabled_countries, $billing_country) !== false){ // use of !== false is deliberate, strpos has an unusual behaviour
						// vat field applies
						$vat_class='b2bking_vat_visible';
					} else {
						// make the field hidden
						$vat_class='b2bking_vat_hidden';
					}
				} else {
					$vat_class='b2bking_vat_hidden';
				}
			}

			if ($field_type !== 'file'){ // not available to files for the moment
				$field_label = get_post_meta (apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_label', true);
				$field_placeholder = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_placeholder', true);

				$field_value = get_user_meta ($user_id, 'b2bking_custom_field_'.$custom_field->ID, true);
				if ($field_value === NULL){
					$field_value = '';
				}
				if ($required === 1){
					$required = true;
				} else {
					$required = false;
				}

				if ($field_type === 'radio' || $field_type === 'checkbox'){
					$field_type = 'select';
				}

				$field_array = array(
			        'label' => sanitize_text_field($field_label),
			        'placeholder' => sanitize_text_field($field_placeholder), 
			        'required' => $required, 
			        'clear' => false,
			        'type' => sanitize_text_field($field_type),
			        'default' => $field_value,
			        'priority' => $priority,
			    );

				$editable = intval(get_post_meta($custom_field->ID, 'b2bking_custom_field_editable', true));

				if (is_user_logged_in()) { // editable post-registration
					if ($editable !== 1){
						$field_array['custom_attributes'] = array('readonly'=>'readonly');
					}
				}
				

			    if ($billing_connection === 'billing_vat'){
			    	$field_array['class'] = array($vat_class, 'b2bking_vat_field_container', 'b2bking_vat_field_required_'.$required_vat);

			    	if ($required_vat === 1){
			    		$requiredstring = 'required';
			    	} else {
			    		$requiredstring = '';
			    	}
			    	$field_array['input_class'][] = 'b2bking_custom_field_req_'.$requiredstring;

			    }

			    $options_array = array();
			    if ($field_type === 'select'){
			    	$user_choices = get_post_meta ($custom_field->ID, 'b2bking_custom_field_user_choices', true);
			    	$choices_array = explode (',', $user_choices);
			    	foreach ($choices_array as $choice){
			    		// check if option is simple or value is specified via option:value
			    		$optionvalue = explode(':', $choice);
			    		if (count($optionvalue) === 2 ){
			    			// value is specified
			    			$options_array[trim($optionvalue[0])] = trim($optionvalue[1]);
			    		} else {
			    			// simple
			    			$options_array[trim($choice)] = trim($choice);
			    		}

			    	}
			    }
			    $field_array['options'] = $options_array;

			    $field_arrayname = 'b2bking_custom_field_'.$custom_field->ID;

			    update_user_meta(get_current_user_id(), $field_arrayname, $field_value);

			    $field_arrayname = apply_filters('b2bking_billing_field_name', $field_arrayname, $billing_connection);
			    $fields[$field_arrayname] = $field_array;
			    $priority++;
			}
		}

	    return $fields;
	}


	function b2bking_checkout_vat_vies_validation($fields, $errors) {

		// first add js-based validation in checkout
		if (isset($_POST['b2bking_js_based_invalid'])){
			$val = sanitize_text_field($_POST['b2bking_js_based_invalid']);
			if ($val === 'invalid'){
				$errors->add( 'validation', esc_html__('Please fill all required fields to proceed with your order.', 'b2bking') );
			}
		}


		$vat_number_inputted = '';
		if (isset($_POST['b2bking_custom_billing_vat_field_number'])){
			if (isset($_POST['b2bking_custom_field_'.$_POST['b2bking_custom_billing_vat_field_number']])){
				$vat_number_inputted = sanitize_text_field($_POST['b2bking_custom_field_'.$_POST['b2bking_custom_billing_vat_field_number']]);
				$vat_number_inputted = strtoupper(str_replace(array('.', ' '), '', $vat_number_inputted));
			}
			if (empty($vat_number_inputted)){
				if (isset($_POST['b2bking_custom_field_'.$_POST['b2bking_custom_billing_vat_field_number'].'bis'])){
					$vat_number_inputted = sanitize_text_field($_POST['b2bking_custom_field_'.$_POST['b2bking_custom_billing_vat_field_number'].'bis']);
					$vat_number_inputted = strtoupper(str_replace(array('.', ' '), '', $vat_number_inputted));
				}
			}
		}
		if (empty($vat_number_inputted)){
			if (isset($_POST['b2bking_vat_number_registration_field_number'])){
				$vat_number_inputted = sanitize_text_field($_POST['b2bking_custom_field_'.$_POST['b2bking_vat_number_registration_field_number']]);

			}
		}

		if (!empty($vat_number_inputted)){

			if (apply_filters('b2bking_set_default_prefix_vat', false) !== false){
				$prefix = apply_filters('b2bking_set_default_prefix_vat', false);
				// if vat nr does not start with the prefix, add the prefix
				if (substr( $vat_number_inputted, 0, 2 ) !== $prefix){
					$vat_number_inputted = $prefix.$vat_number_inputted;
				}
			}	
		}
		
		if (isset($_POST['billing_country'])){
			$country_inputted = sanitize_text_field($_POST['billing_country']);
		} else {
			$country_inputted ='none';
		}

		if ($country_inputted === 'none' || empty($country_inputted)){
			// check if it is single country shop
		    $countries = WC()->countries->get_allowed_countries();
		    
		    if (count($countries) === 1) {
		        $country_inputted = array_keys($countries)[0]; // Returns country code
		    }
		}

		if (!(empty($vat_number_inputted))){

			// check if VIES Validation is enabled in settings
			$vat_field_vies_validation_setting = get_post_meta($_POST['b2bking_custom_billing_vat_field_number'], 'b2bking_custom_field_VAT_VIES_validation', true);

			$countries_list_eu = apply_filters('b2bking_country_list_vies', array('AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'EL', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE'));
			if (in_array($country_inputted, $countries_list_eu)){
				// proceed only if VIES validation is enabled
				if (intval($vat_field_vies_validation_setting) === 1){
					$error_details = '';
					// check vat
					try {
						$country_code = substr($vat_number_inputted, 0, 2); // take first 2 chars
						$vat_number = substr($vat_number_inputted, 2); // remove first 2 chars

						$validation = b2bking()->vies_validation($country_code, $vat_number);

						$error_details = 'VAT Validation Issue';

						// check country is same as VAT country
						if (trim(strtolower($country_inputted)) !== trim(strtolower($country_code))){
							// check exception Greece (GR) has EL VAT code
							if( (trim(strtolower($country_inputted)) === 'gr') && (trim(strtolower($country_code)) === 'el')){
								// if indeed the VAT number is EL and country is GR, do nothing
							} else {
								$errors->add( 'validation', esc_html__('VAT Number you entered is for a different country than the country you selected', 'b2bking') );
							}
						}


					} catch (Exception $e) {
						$error = $e->getMessage();

						$error_array = array(
						    'INVALID_INPUT'       => esc_html__('CountryCode is invalid or the VAT number is empty.', 'b2bking'),
						    'SERVICE_UNAVAILABLE' => esc_html__('VIES VAT Service is unavailable. Try again later.', 'b2bking'),
						    'MS_UNAVAILABLE'      => esc_html__('VIES VAT Member State Service is unavailable.', 'b2bking'),
						    'TIMEOUT'             => esc_html__('Service timeout. Try again later', 'b2bking'),
						    'SERVER_BUSY'         => esc_html__('VAT Server is too busy. Try again later.', 'b2bking'),
						    'MS_MAX_CONCURRENT_REQ' => esc_html__('Too many requests. The Europa.eu VIES server cannot process your request right now.', 'b2bking'),
						);

						if ( array_key_exists( $error , $error_array ) ) {
						    $error_details .= $error_array[ $error ];
						} else {
							$error_details .= $error;
						}

						// if error is independent of the user (unavailable service, timeout, etc), allow it, but notify the website admin
						if (apply_filters('b2bking_allow_vat_timeouts_unavailable_errors', true)){
							if ($error !== 'INVALID_INPUT'){ // except the invalid format error
								$validation = new stdClass();
								$validation -> valid = 1;

								// mail the website admin about the issue and that this number needs to be checked
								$recipient = get_option( 'admin_email' );
								$recipient = apply_filters('b2bking_invalid_vat_number_email', $recipient, 0);

							    $message = 'A customer registered / ordered on your shop, but the VIES Validation encountered an issue which is not the fault of the user. The request was accepted, but you should manually check this VAT number and customer.';
							    $message .= '<br><br>Error details: '.$error;
							    if ( array_key_exists( $error , $error_array ) ) {
							        $message .= ' ('.$error_array[ $error ].')';
							    }

							    $current_user = wp_get_current_user();
							    if ($current_user->ID != 0) {
							        $user_email = $current_user->user_email;
							    } else {
							        $user_email = 'Logged out user';
							    }

							    $message .= '<br><br>The VAT number is: '.$country_code.$vat_number;
							    $message .= '<br><br>The email of the user is: '.$user_email;

							    do_action( 'b2bking_new_message', $recipient, $message, 'Quoteemail:1', 0 );
								
							}
						}
					}

					if(isset($validation)){
						if (intval($validation->valid) === 1){
							// VAT IS VALID
							// update vat NR to user meta
							$vat_field = get_posts([
								    		'post_type' => 'b2bking_custom_field',
								    	  	'post_status' => 'publish',
								    	  	'fields' => 'ids',
								    	  	'numberposts' => -1,
								    	  	'meta_query'=> array(
								    	  		'relation' => 'AND',
								                array(
							                        'key' => 'b2bking_custom_field_status',
							                        'value' => 1
								                ),
								                array(
							                        'key' => 'b2bking_custom_field_billing_connection',
							                        'value' => 'billing_vat'
								                ),
							            	)
								    	]);
							if (is_user_logged_in()){
								update_user_meta( get_current_user_id(), 'b2bking_custom_field_'.$vat_field[0], $vat_number_inputted);
								update_user_meta( get_current_user_id(), 'b2bking_custom_field_'.$vat_field[0].'bis', $vat_number_inputted);
								update_user_meta( get_current_user_id(), 'vat_number', $vat_number_inputted);
								update_user_meta( get_current_user_id(), 'b2bking_user_vat_status', 'validated_vat');
							}
						} else {
							$errors->add( 'validation', esc_html__('VAT Number is Invalid.', 'b2bking').' '.$error_details );
						}
					} else {
						$errors->add( 'validation', esc_html__('VAT Number is Invalid.', 'b2bking').' '.$error_details );
						
					}

				}
			}

		}

	}


	function b2bking_subaccount_checkout_permission_validation($data, $errors){
		$user_id = get_current_user_id();
		// check if subaccount
		$account_type = get_user_meta($user_id, 'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			// if it's subaccount check, if subaccount has permission to checkout
			$permission_checkout = filter_var(get_user_meta($user_id, 'b2bking_account_permission_buy', true),FILTER_VALIDATE_BOOLEAN);
			if ($permission_checkout === false){
				$errors->add( 'validation', esc_html__('Your account does not have permission to checkout', 'b2bking') );

			}
		}
	}

	public static function b2bking_cannot_quote_offer_cart_message() {
		wc_print_notice( esc_html__('While you have an offer / pack in cart, you cannot add products to quote', 'b2bking'), 'notice' );
	}

	public static function b2bking_cannot_quote_offer_cart_message_products() {
		wc_print_notice( esc_html__('While you are working on a quote request, you cannot add regular products to cart', 'b2bking'), 'notice' );
	}

	function b2bking_subaccount_checkout_permission_validation_mesage() {
		$user_id = get_current_user_id();
		// check if subaccount
		$account_type = get_user_meta($user_id, 'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			// if it's subaccount check, if subaccount has permission to checkout
			$permission_checkout = filter_var(get_user_meta($user_id, 'b2bking_account_permission_buy', true),FILTER_VALIDATE_BOOLEAN);
			if ($permission_checkout === false){
				wc_print_notice( esc_html__('Your account does not have permission to checkout', 'b2bking'), 'error' );
			}
		}
	}

	// add custom fields to order meta
	public static function b2bking_add_custom_fields_to_order_meta( $order_id, $rest_request = false ) {

		if (is_a($order_id, 'WC_Order')) {
			$order = $order_id;
		} else {
			$order = wc_get_order($order_id);
		}

		// get and save meta data from billing postmeta
		if (is_object($order)){ // wc order object
			$order_meta = $order->get_meta_data();

			// Loop through each meta data item
			foreach ($order_meta as $meta_item) {
			    // Get the key from the meta data object
			    $meta_key = $meta_item->get_data()['key'];
			    $meta_value = $meta_item->get_data()['value'];
			    
			    // Check if the key contains 'b2bking'
			    if (strpos($meta_key, 'b2bking') !== false) {
			        // Extract the part after the last slash
			        $key_parts = explode('/', $meta_key);
			        $simplified_key = end($key_parts);
			        
			        // Save as new order meta with the simplified key
			        $order->update_meta_data($simplified_key, $meta_value);
			    }
			}

			// Save the order to persist the meta data changes
			$order->save();
		}

		// build array of groups visible
		$array_groups_visible = array(
            'relation' => 'OR',
        );

		if (!is_user_logged_in()){
			array_push($array_groups_visible, array(
                'key' => 'b2bking_custom_field_multiple_groups',
                'value' => 'group_loggedout',
                'compare' => 'LIKE'
            ));
		} else {
			// if user is b2c
			if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) !== 'yes'){
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_b2c',
	                'compare' => 'LIKE'
	            ));
			} else {
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_'.b2bking()->get_user_group(),
	                'compare' => 'LIKE'
	            ));
	            array_push($array_groups_visible, array(
                    'key' => 'b2bking_custom_field_multiple_groups',
                    'value' => 'group_b2b',
                    'compare' => 'LIKE'
                ));
			}
		}
				
		// get all enabled custom fields with no default billing connection (first name, last name etc)
		$custom_fields = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
		    	  	    'orderby' => 'menu_order',
		    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_status',
		                        'value' => 1
			                ),
			                array(
		                        'key' => 'b2bking_custom_field_billing_connection',
		                        'value' => 'none'
			                ),
			                array(
		                        'key' => 'b2bking_custom_field_add_to_billing',
		                        'value' => 1
			                ),
			                $array_groups_visible
		            	)
			    	]);

		foreach ($custom_fields as $custom_field){
			if ( ! empty( $_POST['b2bking_custom_field_'.$custom_field->ID] ) ) {
				$field_label = get_post_meta ($custom_field->ID, 'b2bking_custom_field_field_label', true);
			    $order->update_meta_data( sanitize_text_field( $field_label ), sanitize_text_field( $_POST['b2bking_custom_field_'.$custom_field->ID] ) );
			}
		}

		// save custom mappings
		if (apply_filters('b2bking_show_custom_mapping_fields_billing', false)){

			$user_id = $order->get_customer_id();

			// build array of groups visible
			$array_groups_visible = array(
	            'relation' => 'OR',
	        );

			if (!is_user_logged_in()){
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_loggedout',
	                'compare' => 'LIKE'
	            ));
			} else {
				// if user is b2c
				if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) !== 'yes'){
					array_push($array_groups_visible, array(
		                'key' => 'b2bking_custom_field_multiple_groups',
		                'value' => 'group_b2c',
		                'compare' => 'LIKE'
		            ));
				} else {
					array_push($array_groups_visible, array(
		                'key' => 'b2bking_custom_field_multiple_groups',
		                'value' => 'group_'.b2bking()->get_user_group(),
		                'compare' => 'LIKE'
		            ));
		            array_push($array_groups_visible, array(
	                    'key' => 'b2bking_custom_field_multiple_groups',
	                    'value' => 'group_b2b',
	                    'compare' => 'LIKE'
	                ));
				}
			}

			// get all enabled custom fields with no default billing connection (first name, last name etc)
			$custom_fields = get_posts([
				    		'post_type' => 'b2bking_custom_field',
				    	  	'post_status' => 'publish',
				    	  	'numberposts' => -1,
			    	  	    'orderby' => 'menu_order',
			    	  	    'order' => 'ASC',
				    	  	'meta_query'=> array(
				    	  		'relation' => 'AND',
				                array(
			                        'key' => 'b2bking_custom_field_status',
			                        'value' => 1
				                ),
				                array(
				                	'relation' => 'OR',
	            	                array(
	                                    'key' => 'b2bking_custom_field_billing_connection',
	                                    'value' => 'custom_mapping',
	            	                ),
	        		            ),			               
				                $array_groups_visible,
			            	)
				    	]);

			foreach ($custom_fields as $field){
				// get field and check if set
				$field_value = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_custom_field_'.$field->ID)); 
				$billing_connection = get_post_meta($field->ID,'b2bking_custom_field_billing_connection', true);

				if ($field_value !== NULL){
					update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID, $field_value);
					if ($billing_connection === 'custom_mapping'){
						update_user_meta ($user_id, sanitize_text_field(get_post_meta($field->ID, 'b2bking_custom_field_mapping', true)), $field_value);
					}
				}
			}
		}


		$order->save();
	}

	// Custom Registration Fields
	function b2bking_custom_registration_fields(){

		if (get_option( 'marketking_vendor_registration_setting', 'myaccount' ) === 'separate'){
			$page = apply_filters( 'wpml_object_id', get_option('marketking_vendor_registration_page_setting', 12345), 'page' , true);
		} else {
			$page = 12345;
		}

		// if page is not marketking become a vendor
		global $post;
		if (isset($post->ID)){
			$post_id = $post->ID;
		} else {
			$post_id = 0;
		}

		if ($post_id !== intval($page)){
			if (!is_checkout() || (is_checkout() && apply_filters('b2bking_allow_registration_fields_checkout', false)) ){ // check against some errors in checkout
				global $woocommerce;    
				global $b2bking_is_b2b_registration;
				global $b2bking_is_b2b_registration_shortcode_role_id;

				if ($b2bking_is_b2b_registration_shortcode_role_id === NULL || $b2bking_is_b2b_registration_shortcode_role_id === ''){
					$b2bking_is_b2b_registration_shortcode_role_id = 'none';
				}

				// if Registration Roles dropdown is enabled (enabled by default), show custom registration roles and fields
				$registration_role_setting = intval(get_option( 'b2bking_registration_roles_dropdown_setting', 1 ));
				if ($registration_role_setting === 1 || $b2bking_is_b2b_registration === 'yes'){

					// get roles
					$custom_roles = get_posts([
					    		'post_type' => 'b2bking_custom_role',
					    	  	'post_status' => 'publish',
					    	  	'numberposts' => -1,
				    	  	    'orderby' => 'menu_order',
				    	  	    'order' => 'ASC',
					    	  	'meta_query'=> array(
					    	  		'relation' => 'AND',
					                array(
				                        'key' => 'b2bking_custom_role_status',
				                        'value' => 1
					                ),
				            	)
					    	]);

					if (!empty($custom_roles)){
						?>
						<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide b2bking_registration_roles_dropdown_section <?php if ($b2bking_is_b2b_registration_shortcode_role_id !== 'none' || count($custom_roles) === 1){ echo 'b2bking_registration_roles_dropdown_section_hidden'; } ?>">
							<?php
							do_action('b2bking_before_user_type_dropdown');
							?>
							<label for="b2bking_registration_roles_dropdown">
								<?php esc_html_e('User Type','b2bking'); ?>&nbsp;<span class="required">*</span>
							</label>
							<select id="b2bking_registration_roles_dropdown" name="b2bking_registration_roles_dropdown" required>
								<?php
								foreach ($custom_roles as $role){

									$non_selectable = get_post_meta($role->ID,'b2bking_non_selectable',true);

									$rolevalue = 'role_'.esc_attr($role->ID);
									if (intval($non_selectable) === 1){
										$rolevalue = ''; // force to choose
									}
									echo '<option value="'.$rolevalue.'" '.selected($role->ID,$b2bking_is_b2b_registration_shortcode_role_id,false).'>'.esc_html(get_the_title(apply_filters( 'wpml_object_id', $role->ID, 'post', true ))).'</option>';
								}
								?>
							</select>
						</p>
						<?php
					}

					

					do_action('b2bking_after_registration_dropdown');
				}

				$custom_fields = array();
				// if dropdown enabled, retrieve all enabled fields. Else, show only "All Roles" fields
				if ($registration_role_setting === 1 || $b2bking_is_b2b_registration === 'yes'){
					$custom_fields = get_posts([
					    		'post_type' => 'b2bking_custom_field',
					    	  	'post_status' => 'publish',
					    	  	'numberposts' => -1,
				    	  	    'orderby' => 'menu_order',
				    	  	    'order' => 'ASC',
					    	  	'meta_query'=> array(
					    	  		'relation' => 'AND',
					                array(
				                        'key' => 'b2bking_custom_field_status',
				                        'value' => 1
					                ),
				            	)
					    	]);
				}

				// show all retrieved fields
				foreach ($custom_fields as $custom_field){
					$billing_exclusive = intval(get_post_meta($custom_field->ID, 'b2bking_custom_field_billing_exclusive', true));
					if ($billing_exclusive !== 1){
						$field_type = get_post_meta($custom_field->ID, 'b2bking_custom_field_field_type', true);
						$field_label = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_label', true);
						$field_placeholder = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_placeholder', true);
						$required = get_post_meta($custom_field->ID, 'b2bking_custom_field_required', true);
						$billing_connection = get_post_meta($custom_field->ID, 'b2bking_custom_field_billing_connection', true);
						// role identifier
						$role = get_post_meta($custom_field->ID, 'b2bking_custom_field_registration_role', true);
						if ($role !== 'multipleroles'){
							$role_class = 'b2bking_custom_registration_'.esc_attr($role);
						} else {
							$field_roles = get_post_meta($custom_field->ID, 'b2bking_custom_field_multiple_roles', true);
							$roles_array = explode(',',$field_roles);
							$role_class = '';
							foreach($roles_array as $role){
								$role_class.='b2bking_custom_registration_'.esc_attr($role).' ';
							}
						}
						// if error, get previous value and show it in the fields, for user friendliness
						$previous_value = '';
						if (isset($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID)])){
							$previous_value = sanitize_text_field($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID)]);
						} else {
							// check if data exists in billing connection
							$data = get_user_meta(get_current_user_id(),$billing_connection, true);
							if (!empty($data)){
								$previous_value = $data;
							}
						}

						if (intval($required) === 1){
							$required = 'required';
						} else {
							$required = '';
						}

						$vat_container = '';
						if ($billing_connection === 'billing_vat'){
							$vat_container = 'b2bking_vat_number_registration_field_container';
						}

						$class = '';
						// purely aesthethical fix, add a class to the P in countries, in order to remove the margin bottom
						if ($billing_connection === 'billing_countrystate' || $billing_connection === 'billing_country' || $billing_connection === 'billing_state'){
							$class = 'b2bking_country_or_state';
						}
						
						echo '<div class="'.esc_attr($vat_container).' b2bking_custom_registration_container b2bking_custom_registration_container_field_'.$custom_field->ID.' '.esc_attr($role_class).'">';
						echo '<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide '.$class.'">';

						$labelfor = 'b2bking_field_'.esc_attr($custom_field->ID);
						if ($billing_connection === 'billing_vat'){
							$labelfor = 'b2bking_vat_number_registration_field';
						}
						if ($billing_connection === 'billing_country') {
							$labelfor = 'b2bking_custom_field_'.esc_attr($custom_field->ID);
							
						}
						if ($billing_connection === 'billing_countrystate') {
							$labelfor = 'b2bking_custom_field_'.esc_attr($custom_field->ID);
						}
						echo '<label for="'.esc_attr($labelfor).'">'.wp_kses( $field_label, array( 'li' => true, 'ul' => true, 'br' => true, 'strong' => true, 'b' => true, 'a' => array('href' => array(), 'target' => array() ) ) ).'&nbsp;';
							if ($required === 'required'){ 
								echo '<span class="required">*</span>'; 
							}
							echo '</label>';

						// if billing connection is country, replace field with countries dropdown
						if ($billing_connection !== 'billing_countrystate' && $billing_connection !== 'billing_country' && $billing_connection !== 'billing_vat'){

							if ($field_type === 'text'){
								echo '<input type="text" id="b2bking_field_'.esc_attr($custom_field->ID).'" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
							} else if ($field_type === 'textarea'){
								echo '<textarea id="b2bking_field_'.esc_attr($custom_field->ID).'" class="b2bking_custom_registration_field b2bking_custom_registration_field_textarea b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>'.esc_html($previous_value).'</textarea>';
							} else if ($field_type === 'number'){
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="number" step="0.00001" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
							} else if ($field_type === 'email'){
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="email" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
							} else if ($field_type === 'date'){
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="date" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
							} else if ($field_type === 'time'){
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="time" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
							} else if ($field_type === 'tel'){
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="tel" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
							} else if ($field_type === 'file'){
								if (!apply_filters('b2bking_allow_file_upload_multiple', false)){
									$multiple = '';
									$multiplename = '';
								} else {
									$multiple = 'multiple';
									$multiplename = '[]';
								}
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="file" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).$multiplename.'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).' '.$multiple.'>'.'<br /><span class="b2bking_supported_types">'.esc_html__('Supported file types:','b2bking').' '.apply_filters('b2bking_allowed_file_types_text', 'jpg, jpeg, png, txt, pdf, doc, docx').'</span>';
								do_action('b2bking_after_supported_types', $custom_field->ID);

							} else if ($field_type === 'select'){
								$select_options = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_user_choices', true);
								$select_options = explode(',', $select_options);

								echo '<select id="b2bking_field_'.esc_attr($custom_field->ID).'" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
									foreach ($select_options as $option){
										// check if option is simple or value is specified via option:value
										$optionvalue = explode(':', $option);
										if (count($optionvalue) === 2 ){
											// value is specified
											echo '<option value="'.esc_attr(trim($optionvalue[0])).'" '.selected(trim($optionvalue[0]), $previous_value, false).'>'.esc_html(trim($optionvalue[1])).'</option>';
										} else {
											// simple
											echo '<option value="'.esc_attr(trim($option)).'" '.selected($option, $previous_value, false).'>'.esc_html(trim($option)).'</option>';
										}
									}
								echo '</select>';
							} else if ($field_type === 'checkbox'){

								$select_options = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_user_choices', true);
								$select_options = explode(',', $select_options);
								$i = 1;

								// if required and only 1 option (might be like an "I accept privacy policy" box), set required
								if ($required === 'required' && count($select_options) === 1){
									$uniquerequired = 'required';
								} else {
									$uniquerequired = '';
								}
								foreach ($select_options as $option){
									
									$previous_value = '';
									if (isset($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i])){
										$previous_value = sanitize_text_field($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i]);
									}
									echo '<p class="form-row">';
									echo '<label class="woocommerce-form__label woocommerce-form__label-for-checkbox">';
									echo '<input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox b2bking_custom_registration_field b2bking_checkbox_registration_field b2bking_custom_field_req_'.esc_attr($uniquerequired).'" value="1" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i.'" '.checked(1, $previous_value, false).' '.esc_attr($uniquerequired).'>';
									echo '<span>'.trim(wp_kses( $option, array( 'a'     => array(
								        'href' => array(), 'target' => array()
								    ) ) )).'</span></label></p>';

									$i++;
								}
							} else if ($field_type === 'radio'){

								$select_options = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_user_choices', true);
								$select_options = explode(',', $select_options);
								$i = 1;

								// if required and only 1 option (might be like an "I accept privacy policy" box), set required
								if ($required === 'required'){
									$uniquerequired = 'required';
								} else {
									$uniquerequired = '';
								}
								foreach ($select_options as $option){
									
									$previous_value = '';
									if (isset($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i])){
										$previous_value = sanitize_text_field($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i]);
									}
									echo '<p class="form-row">';
									echo '<label class="woocommerce-form__label woocommerce-form__label-for-checkbox">';
									echo '<input type="radio" class="woocommerce-form__input woocommerce-form__input-checkbox b2bking_custom_registration_field b2bking_checkbox_registration_field b2bking_custom_field_req_'.esc_attr($uniquerequired).'" value="'.esc_attr(trim($option)).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'">';
									echo '<span>'.trim(wp_kses( $option, array( 'a'     => array(
								        'href' => array(), 'target' => array()
								    ) ) )).'</span></label></p>';

									$i++;
								}
							}

							do_action('b2bking_after_custom_field', $custom_field->ID);


						} else if ($billing_connection === 'billing_country') {
							woocommerce_form_field( 'b2bking_custom_field_'.esc_attr($custom_field->ID), array( 'default' => $previous_value, 'type' => 'country', 'class' => array( 'b2bking_country_field_selector', 'b2bking_custom_registration_field', 'b2bking_custom_field_req_'.esc_attr($required), 'b2bking_country_field_req_'.esc_attr($required))));
							echo '<input type="hidden" id="b2bking_country_registration_field_number" name="b2bking_country_registration_field_number" value="'.esc_attr($custom_field->ID).'">';
						} else if ($billing_connection === 'billing_countrystate') {
							if (isset($_POST['billing_state'])){
								$post_billing_state = sanitize_text_field($_POST['billing_state']);
							} else {
								$post_billing_state = '';
							}

							// if there's only one country, force state options
							if (get_option('woocommerce_allowed_countries') === 'specific'){
								$countries = get_option('woocommerce_specific_allowed_countries');
								if (is_array($countries)){
									if (count($countries) === 1){
										$_POST[ 'billing_country' ] = $countries[0];
									}
								}
							}

							woocommerce_form_field( 'b2bking_custom_field_'.esc_attr($custom_field->ID), array( 'default' => $previous_value, 'type' => 'country', 'class' => array( 'b2bking_country_field_selector', 'b2bking_custom_registration_field', 'b2bking_custom_field_req_'.esc_attr($required), 'b2bking_country_field_req_'.esc_attr($required))));
							woocommerce_form_field( 'billing_state', array( 'placeholder' => esc_attr__('State / County', 'b2bking'), 'default' => $post_billing_state, 'type' => 'state', 'class' => array( 'b2bking_custom_registration_field', apply_filters('b2bking_registration_state_required', 'b2bking_custom_field_req_'.esc_attr($required)))));
							echo '<input type="hidden" id="b2bking_country_registration_field_number" name="b2bking_country_registration_field_number" value="'.esc_attr($custom_field->ID).'">';
						} else if ($billing_connection === 'billing_vat'){
							echo '<input type="text" id="b2bking_vat_number_registration_field" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
							$vat_enabled_countries = get_post_meta($custom_field->ID, 'b2bking_custom_field_VAT_countries', true);
							if (empty($vat_enabled_countries)){
								// select all countries + update the field backend
								$countries_object = new WC_Countries;
								$countries_list = $countries_object -> get_countries();
								$indexes_array = array();
								foreach ($countries_list as $index => $country){
									$indexes_array[] = $index;
								}
								$vat_enabled_countries = implode(',', $indexes_array);
								update_post_meta($custom_field->ID, 'b2bking_custom_field_VAT_countries', $vat_enabled_countries);
							}
							echo '<input type="hidden" id="b2bking_vat_number_registration_field_countries" value="'.esc_attr($vat_enabled_countries).'">';
							echo '<input type="hidden" id="b2bking_vat_number_registration_field_number" name="b2bking_vat_number_registration_field_number" value="'.esc_attr($custom_field->ID).'">';
						}
						echo '</p></div>';
					}

					$user_id = get_current_user_id();
					$is_b2b = get_user_meta($user_id,'b2bking_b2buser', true);
					do_action('b2bking_after_field_registration_page', $custom_field->ID, $user_id, $is_b2b);

					
				}
			}
		}
	}

	function b2bking_custom_registration_fields_checkout(){

		global $woocommerce;    
		global $b2bking_is_b2b_registration;
		global $b2bking_is_b2b_registration_shortcode_role_id;

		if ($b2bking_is_b2b_registration_shortcode_role_id === NULL || $b2bking_is_b2b_registration_shortcode_role_id === ''){
			$b2bking_is_b2b_registration_shortcode_role_id = 'none';
		}

		// if Registration Roles dropdown is enabled (enabled by default), show custom registration roles and fields
		$registration_role_setting = intval(get_option( 'b2bking_registration_roles_dropdown_setting', 1 ));
		if ($registration_role_setting === 1 || $b2bking_is_b2b_registration === 'yes'){

			// get roles
			$custom_roles = get_posts([
			    		'post_type' => 'b2bking_custom_role',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
		    	  	    'orderby' => 'menu_order',
		    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_role_status',
		                        'value' => 1
			                ),
		            	)
			    	]);

			?>
			<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide b2bking_registration_roles_dropdown_section <?php if ($b2bking_is_b2b_registration_shortcode_role_id !== 'none'){ echo 'b2bking_registration_roles_dropdown_section_hidden'; } ?>">
				<label for="b2bking_registration_roles_dropdown">
					<?php esc_html_e('User Type','b2bking'); ?>&nbsp;<span class="required">*</span>
				</label>
				<select id="b2bking_registration_roles_dropdown" name="b2bking_registration_roles_dropdown">
					<?php
					foreach ($custom_roles as $role){

						$non_selectable = get_post_meta($role->ID,'b2bking_non_selectable',true);

						$rolevalue = 'role_'.esc_attr($role->ID);
						if (intval($non_selectable) === 1){
							$rolevalue = ''; // force to choose
						}
						echo '<option value="'.$rolevalue.'" '.selected($role->ID,$b2bking_is_b2b_registration_shortcode_role_id,false).'>'.esc_html(get_the_title(apply_filters( 'wpml_object_id', $role->ID, 'post', true ))).'</option>';
					}
					?>
				</select>
			</p>
			<?php
		}

		echo '<div id="b2bking_checkout_registration_main_container_fields">';

		$custom_fields = array();
		// if dropdown enabled, retrieve all enabled fields. Else, show only "All Roles" fields
		if ($registration_role_setting === 1 || $b2bking_is_b2b_registration === 'yes'){
			$custom_fields = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
		    	  	    'orderby' => 'menu_order',
		    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_status',
		                        'value' => 1
			                ),
			                array(
			                	'relation' => 'OR',
        		                array(
        	                        'key' => 'b2bking_custom_field_billing_connection',
        	                        'value' => 'none'
        		                ),
        		                array(
        	                        'key' => 'b2bking_custom_field_billing_connection',
        	                        'value' => 'billing_vat'
        		                ),
        		            ),			               
		            	)
			    	]);
		}

		$custom_fields = apply_filters('b2bking_fields_available_checkout_registration', $custom_fields);

		// show all retrieved fields
		 	foreach ($custom_fields as $custom_field){
			$billing_exclusive = intval(get_post_meta($custom_field->ID, 'b2bking_custom_field_billing_exclusive', true));
			if ($billing_exclusive !== 1){
				$field_type = get_post_meta($custom_field->ID, 'b2bking_custom_field_field_type', true);
				$field_label = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_label', true);
				$field_placeholder = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_placeholder', true);
				$required = get_post_meta($custom_field->ID, 'b2bking_custom_field_required', true);
				$billing_connection = get_post_meta($custom_field->ID, 'b2bking_custom_field_billing_connection', true);
				// role identifier
				$role = get_post_meta($custom_field->ID, 'b2bking_custom_field_registration_role', true);
				if ($role !== 'multipleroles'){
					$role_class = 'b2bking_custom_registration_'.esc_attr($role);
				} else {
					$field_roles = get_post_meta($custom_field->ID, 'b2bking_custom_field_multiple_roles', true);
					$roles_array = explode(',',$field_roles);
					$role_class = '';
					foreach($roles_array as $role){
						$role_class.='b2bking_custom_registration_'.esc_attr($role).' ';
					}
				}
				// if error, get previous value and show it in the fields, for user friendliness
				$previous_value = '';
				if (isset($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID)])){
					$previous_value = sanitize_text_field($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID)]);
				}

				if (intval($required) === 1){
					$required = 'required';
				} else {
					$required = '';
				}

				$vat_container = '';
				if ($billing_connection === 'billing_vat'){
					$vat_container = 'b2bking_vat_number_registration_field_container';
				}

				$class = '';
				// purely aesthethical fix, add a class to the P in countries, in order to remove the margin bottom
				if ($billing_connection === 'billing_countrystate' || $billing_connection === 'billing_country' || $billing_connection === 'billing_state'){
					$class = 'b2bking_country_or_state';
				}
				
				echo '<div class="'.esc_attr($vat_container).' b2bking_custom_registration_container '.esc_attr($role_class).'">';
				echo '<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide '.$class.'">';

				$labelfor = 'b2bking_field_'.esc_attr($custom_field->ID);
				if ($billing_connection === 'billing_vat'){
					$labelfor = 'b2bking_vat_number_registration_field';
				}
				if ($billing_connection === 'billing_country') {
					$labelfor = 'b2bking_custom_field_'.esc_attr($custom_field->ID);
					
				}
				if ($billing_connection === 'billing_countrystate') {
					$labelfor = 'b2bking_custom_field_'.esc_attr($custom_field->ID);
				}

				echo '<label for="'.esc_attr($labelfor).'">'.trim(wp_kses( $field_label, array( 'a'     => array(
				        'href' => array(), 'target' => array()
				    ) ) )).'&nbsp;';
					if ($required === 'required'){ 
						echo '<span class="required">*</span>'; 
					}
					echo '</label>';

				// if billing connection is country, replace field with countries dropdown
				if ($billing_connection !== 'billing_countrystate' && $billing_connection !== 'billing_country' && $billing_connection !== 'billing_vat'){

					if ($field_type === 'text'){
						echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="text" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
					} else if ($field_type === 'textarea'){
						echo '<textarea id="b2bking_field_'.esc_attr($custom_field->ID).'" class="b2bking_custom_registration_field b2bking_custom_registration_field_textarea b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>'.esc_html($previous_value).'</textarea>';
					} else if ($field_type === 'number'){
						echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="number" step="0.00001" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
					} else if ($field_type === 'email'){
						echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="email" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
					} else if ($field_type === 'date'){
						echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="date" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
					} else if ($field_type === 'time'){
						echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="time" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
					} else if ($field_type === 'tel'){
						echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="tel" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
					} else if ($field_type === 'file'){

						$allowed_file_types = apply_filters('b2bking_allowed_file_types', array( "image/jpeg", "image/jpg", "image/png", "text/plain", "application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/octet-stream" ));

						echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="file" accept="'.implode(',',$allowed_file_types).'" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>'.'<br /><span class="b2bking_supported_types">'.esc_html__('Supported file types:','b2bking').' '.apply_filters('b2bking_allowed_file_types_text', 'jpg, jpeg, png, txt, pdf, doc, docx').'</span>';
						do_action('b2bking_after_supported_types', $custom_field->ID);


					} else if ($field_type === 'select'){
						$select_options = get_post_meta($custom_field->ID, 'b2bking_custom_field_user_choices', true);
						$select_options = explode(',', $select_options);

						echo '<select id="b2bking_field_'.esc_attr($custom_field->ID).'" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).'>';
							foreach ($select_options as $option){

								// check if option is simple or value is specified via option:value
								$optionvalue = explode(':', $option);
								if (count($optionvalue) === 2 ){
									// value is specified
									echo '<option value="'.esc_attr(trim($optionvalue[0])).'" '.selected(trim($optionvalue[0]), $previous_value, false).'>'.esc_html(trim($optionvalue[1])).'</option>';
								} else {
									// simple
									echo '<option value="'.esc_attr(trim($option)).'" '.selected($option, $previous_value, false).'>'.esc_html(trim($option)).'</option>';
								}

							}
						echo '</select>';
					} else if ($field_type === 'checkbox'){

						$select_options = get_post_meta($custom_field->ID, 'b2bking_custom_field_user_choices', true);
						$select_options = explode(',', $select_options);
						$i = 1;
						foreach ($select_options as $option){
							
							$previous_value = '';
							if (isset($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i])){
								$previous_value = sanitize_text_field($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i]);
							}
							echo '<p class="form-row">';
							echo '<label class="woocommerce-form__label woocommerce-form__label-for-checkbox">';
							echo '<input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox b2bking_custom_registration_field b2bking_checkbox_registration_field" value="1" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i.'" '.checked(1, $previous_value, false).'>';
							echo '<span>'.trim(wp_kses( $option, array( 'a'     => array(
							        'href' => array(), 'target' => array()
							    ) ) )).'</span></label></p>';

							$i++;
						}

					} else if ($field_type === 'radio'){

						$select_options = get_post_meta($custom_field->ID, 'b2bking_custom_field_user_choices', true);
						$select_options = explode(',', $select_options);
						$i = 1;
						foreach ($select_options as $option){
							
							$previous_value = '';
							if (isset($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i])){
								$previous_value = sanitize_text_field($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i]);
							}
							echo '<p class="form-row">';
							echo '<label class="woocommerce-form__label woocommerce-form__label-for-checkbox">';
							echo '<input type="radio" class="woocommerce-form__input woocommerce-form__input-checkbox b2bking_custom_registration_field b2bking_checkbox_registration_field" value="'.esc_attr(trim($option)).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'">';
							echo '<span>'.trim(esc_html($option)).'</span></label></p>';

							$i++;
						}

					}

					do_action('b2bking_after_custom_field', $custom_field->ID);


				} else if ($billing_connection === 'billing_country') {
					woocommerce_form_field( 'b2bking_custom_field_'.esc_attr($custom_field->ID), array( 'type' => 'country', 'class' => array( 'b2bking_country_field_selector', 'b2bking_custom_registration_field', 'b2bking_custom_field_req_'.esc_attr($required), 'b2bking_country_field_req_'.esc_attr($required))));
					echo '<input type="hidden" id="b2bking_country_registration_field_number" name="b2bking_country_registration_field_number" value="'.esc_attr($custom_field->ID).'">';
				} else if ($billing_connection === 'billing_countrystate') {
					woocommerce_form_field( 'b2bking_custom_field_'.esc_attr($custom_field->ID), array( 'type' => 'country', 'class' => array( 'b2bking_country_field_selector', 'b2bking_custom_registration_field', 'b2bking_custom_field_req_'.esc_attr($required), 'b2bking_country_field_req_'.esc_attr($required))));
					woocommerce_form_field( 'billing_state', array( 'type' => 'state', 'class' => array( 'b2bking_custom_registration_field', 'b2bking_custom_field_req_'.esc_attr($required))));
					echo '<input type="hidden" id="b2bking_country_registration_field_number" name="b2bking_country_registration_field_number" value="'.esc_attr($custom_field->ID).'">';
				} else if ($billing_connection === 'billing_vat'){
					$disabled = '';
					if (isset($_COOKIE['b2bking_validated_vat_number'])){
						$previous_value = sanitize_text_field($_COOKIE['b2bking_validated_vat_number']);
						$disabled = 'readonly="readonly"';		
					}

					echo '<input type="text" id="b2bking_vat_number_registration_field" class="b2bking_custom_registration_field b2bking_custom_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" '.esc_attr($required).' '.esc_attr($disabled).'>';
					$vat_enabled_countries = get_post_meta($custom_field->ID, 'b2bking_custom_field_VAT_countries', true);
					if (empty($vat_enabled_countries)){
						// select all countries + update the field backend
						$countries_object = new WC_Countries;
						$countries_list = $countries_object -> get_countries();
						$indexes_array = array();
						foreach ($countries_list as $index => $country){
							$indexes_array[] = $index;
						}
						$vat_enabled_countries = implode(',', $indexes_array);
						update_post_meta($custom_field->ID, 'b2bking_custom_field_VAT_countries', $vat_enabled_countries);
					}
					
					echo '<input type="hidden" id="b2bking_vat_number_registration_field_countries" value="'.esc_attr($vat_enabled_countries).'">';
					echo '<input type="hidden" id="b2bking_vat_number_registration_field_number" name="b2bking_vat_number_registration_field_number" value="'.esc_attr($custom_field->ID).'">';

					// since we are at checkout, show VALIDATE VAT NR button
					if (intval(get_option('b2bking_validate_vat_button_checkout_setting', 0)) === 1){
						global $b2bking_has_shown_validate_vat;
						if ($b2bking_has_shown_validate_vat !== 'yes'){
							$textvat = esc_html__('Validate VAT','b2bking');
							$disabled = '';
							if (isset($_COOKIE['b2bking_validated_vat_number'])){
								$textvat = esc_html__('VAT Validated Successfully', 'b2bking');
								$disabled = 'disabled';
							}
							echo '<button type="button" id="b2bking_checkout_registration_validate_vat_button" '.esc_attr($disabled).'>'.esc_html($textvat).'</button>';
							$b2bking_has_shown_validate_vat = 'yes';
						}
					}
				}
				echo '</p></div>';
			}
		}
		echo '</div>';
	}

	function b2bking_validate_vat_registration_disabled(){

		// if registration at checkout is disabled and validate button is enabled and there is a VAT field in billing

		if (intval(get_option('b2bking_validate_vat_button_checkout_setting', 0)) === 1){

			// check that there is a VAT field there
			// build array of groups visible
			$array_groups_visible = array(
	            'relation' => 'OR',
	        );

			if (!is_user_logged_in()){
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_loggedout',
	                'compare' => 'LIKE'
	            ));
			} else {
				// if user is b2c
				if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) !== 'yes'){
					array_push($array_groups_visible, array(
		                'key' => 'b2bking_custom_field_multiple_groups',
		                'value' => 'group_b2c',
		                'compare' => 'LIKE'
		            ));
				} else {
					array_push($array_groups_visible, array(
		                'key' => 'b2bking_custom_field_multiple_groups',
		                'value' => 'group_'.b2bking()->get_user_group(),
		                'compare' => 'LIKE'
		            ));
            		array_push($array_groups_visible, array(
                        'key' => 'b2bking_custom_field_multiple_groups',
                        'value' => 'group_b2b',
                        'compare' => 'LIKE'
                    ));
				}
			}
			$vat_fields = get_posts([
				    		'post_type' => 'b2bking_custom_field',
				    	  	'post_status' => 'publish',
				    	  	'numberposts' => -1,
			    	  	    'orderby' => 'menu_order',
			    	  	    'order' => 'ASC',
				    	  	'meta_query'=> array(
				    	  		'relation' => 'AND',
				                array(
			                        'key' => 'b2bking_custom_field_status',
			                        'value' => 1
				                ),
            	                array(
                                    'key' => 'b2bking_custom_field_billing_connection',
                                    'value' => 'billing_vat'
            	                ),			               
				                array(
			                        'key' => 'b2bking_custom_field_add_to_billing',
			                        'value' => 1
				                ),
				                $array_groups_visible,
			            	)
				    	]);
				if (!empty($vat_fields)){
					global $b2bking_has_shown_validate_vat;
					if ($b2bking_has_shown_validate_vat !== 'yes'){
						$textvat = esc_html__('Validate VAT','b2bking');
						$disabled = '';
						if (isset($_COOKIE['b2bking_validated_vat_number'])){
							$textvat = esc_html__('VAT Validated Successfully', 'b2bking');
							$disabled = 'disabled';
						}
						echo '<button type="button" id="b2bking_checkout_registration_validate_vat_button" '.esc_attr($disabled).'>'.esc_html($textvat).'</button>';
						$b2bking_has_shown_validate_vat = 'yes';

					}
				}
			}
		
	}

	// Save Custom Registration Fields
	function b2bking_save_custom_registration_fields($user_id){

		$pending_application = get_user_meta($user_id,'b2bking_b2b_application_pending', true);

		if (get_user_meta($user_id, 'b2bking_registration_data_saved', true) === 'yes' && $pending_application !== 'yes'){
			// function has already run
			return;
		} else {
			update_user_meta($user_id,'b2bking_registration_data_saved', 'yes');
		}

		// not relevant if this is a dokan seller
		if (isset($_POST['role'])){
			if (sanitize_text_field($_POST['role']) === 'seller'){
				return;
			}
		}

		$custom_fields_string = '';

		// get all enabled custom fields
		$custom_fields = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
	  	    	  	    'orderby' => 'menu_order',
	  	    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_status',
		                        'value' => 1
			                ),

		            	)
			    	]);
		// loop through fields
		foreach ($custom_fields as $field){

			// if field is checkbox, check checkbox options and save them
			$field_type = get_post_meta($field->ID, 'b2bking_custom_field_field_type', true);

			if ($field_type === 'checkbox'){

				// add field to fields string
				$custom_fields_string .= $field->ID.',';

				$select_options = get_post_meta($field->ID, 'b2bking_custom_field_user_choices', true);
				$select_options = explode(',', $select_options);
				$i = 1;
				foreach ($select_options as $option){

					// get field and check if set
					$field_value = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_custom_field_'.$field->ID.'_option_'.$i)); 
					if (intval($field_value) === 1){
						update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID.'_option_'.$i, $option);
						// if have a selected value, give a value of 1 to the field, so we know to display it in the backend
						update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID, 1);
					}
					$i++;
				}
			}

			// get field and check if set
			$field_value = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_custom_field_'.$field->ID)); 
			if ($field_value !== NULL && $field_type !== 'checkbox'){
				update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID, $field_value);

				// Also set related field data as user meta.
				// Relevant fields: field type, label and user_choices

				// add field to fields string
				$custom_fields_string .= $field->ID.',';

				$field_type = get_post_meta($field->ID, 'b2bking_custom_field_field_type', true);
				$field_label = get_post_meta($field->ID, 'b2bking_custom_field_field_label', true);
				if ($field_type === 'file' ){

					if (!apply_filters('b2bking_allow_file_upload_multiple', false)){

						if ( ! empty( $_FILES['b2bking_custom_field_'.$field->ID]['name'] ) ){

						// has already been checked for errors (type/size) in b2bking_custom_registration_fields_check_errors function
					        require_once( ABSPATH . 'wp-admin/includes/image.php' );
							require_once( ABSPATH . 'wp-admin/includes/file.php' );
							require_once( ABSPATH . 'wp-admin/includes/media.php' );

					        // Upload the file
					        $attachment_id = media_handle_upload( 'b2bking_custom_field_'.$field->ID, 0 );
					        // Set attachment author as the user who uploaded it
					        $attachment_post = array(
					            'ID'          => $attachment_id,
					            'post_author' => $user_id
					        );
					        wp_update_post( $attachment_post );   

					        // set attachment id as user meta
					        update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID, $attachment_id );
					    } else {
				    		// check cookie
				    		if (isset($_COOKIE['b2bking_field_'.$field->ID])){
				    			$attachment_id = sanitize_text_field($_COOKIE['b2bking_field_'.$field->ID]);
				    			update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID, $attachment_id );
				    		}
					    }
					} else {
						// multiple file upload

						if ( ! empty( $_FILES['b2bking_custom_field_'.$field->ID])){

					        require_once( ABSPATH . 'wp-admin/includes/image.php' );
							require_once( ABSPATH . 'wp-admin/includes/file.php' );
							require_once( ABSPATH . 'wp-admin/includes/media.php' );

							$i = 0;

							$savefiles = $_FILES;

							while (isset($_FILES['b2bking_custom_field_'.$field->ID]['name'][$i])){
								// Upload the file

								$file = array( 
				                    'name' => $_FILES['b2bking_custom_field_'.$field->ID]['name'][$i],
				                    'type' => $_FILES['b2bking_custom_field_'.$field->ID]['type'][$i], 
				                    'tmp_name' => $_FILES['b2bking_custom_field_'.$field->ID]['tmp_name'][$i], 
				                    'error' => $_FILES['b2bking_custom_field_'.$field->ID]['error'][$i],
				                    'size' => $_FILES['b2bking_custom_field_'.$field->ID]['size'][$i]
				                ); 

								$_FILES = array("upload_file" => $file);
								$attachment_id = media_handle_upload("upload_file", 0);

								// Set attachment author as the user who uploaded it
								$attachment_post = array(
								    'ID'          => $attachment_id,
								    'post_author' => $user_id
								);
								wp_update_post( $attachment_post );   

								// set attachment id as user meta
								update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID.$i, $attachment_id );
								update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID, $attachment_id );
								$i++;
								$_FILES = $savefiles;

							}
							
						}

					}
				}

				// if field has billing connection, update billing user meta
				$billing_connection = get_post_meta($field->ID, 'b2bking_custom_field_billing_connection', true);
				if ($billing_connection !== 'none'){
					// special situation for countrystate combined field
					if($billing_connection === 'billing_countrystate'){
						if (!empty($field_value)){
							update_user_meta ($user_id, 'billing_country', $field_value);
						}
						
						// get state as well 
						$state_value = sanitize_text_field(filter_input(INPUT_POST, 'billing_state')); 
						if (!empty($state_value)){
							update_user_meta ($user_id, 'billing_state', $state_value);
						}
						
					} else {
						if (!empty($field_value)){
							// field value name is identical to billing user meta field name
							if ($billing_connection !== 'custom_mapping'){
								update_user_meta ($user_id, $billing_connection, $field_value);
							} else {
								update_user_meta ($user_id, sanitize_text_field(get_post_meta($field->ID, 'b2bking_custom_field_mapping', true)), $field_value);
							}
							// if field is first name or last name, add it to account details (Sync)
							if ($billing_connection === 'billing_first_name'){
								update_user_meta( $user_id, 'first_name', $field_value );
							} else if ($billing_connection === 'billing_last_name'){
								update_user_meta( $user_id, 'last_name', $field_value );
							}

							if ($billing_connection === 'billing_vat'){
								update_user_meta( $user_id, 'vat_number', $field_value );
							}
						}
					}
				}
			}
		}

		// set string of custom field ids as meta
		if ($custom_fields_string !== ''){
			update_user_meta( $user_id, 'b2bking_custom_fields_string', $custom_fields_string);
		}

		// if user role dropdown enabled, also set user registration role as meta
		if (isset($_POST['b2bking_registration_roles_dropdown'])){
			$user_role = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_registration_roles_dropdown'));
			if ($user_role !== NULL){
				update_user_meta( $user_id, 'b2bking_registration_role', $user_role);
			}
		}

		// if VIES VAT Validation is Enabled AND VAT field is not empty, set vies-validated vat meta
		if (isset($_POST['b2bking_vat_number_registration_field_number'])){
			$vat_number_inputted = sanitize_text_field($_POST['b2bking_custom_field_'.$_POST['b2bking_vat_number_registration_field_number']]);
			$vat_number_inputted = strtoupper(str_replace(array('.', ' '), '', $vat_number_inputted));
			if (!(empty($vat_number_inputted))){
				// check if VIES Validation is enabled in settings
				$vat_field_vies_validation_setting = get_post_meta($_POST['b2bking_vat_number_registration_field_number'], 'b2bking_custom_field_VAT_VIES_validation', true);
				// proceed only if VIES validation is enabled
				if (intval($vat_field_vies_validation_setting) === 1){
					update_user_meta($user_id, 'b2bking_user_vat_status', 'validated_vat');
				}

				// if cookie, set validate vat also
				if (isset($_COOKIE['b2bking_validated_vat_status'])){
					update_user_meta($user_id, 'b2bking_user_vat_status', sanitize_text_field($_COOKIE['b2bking_validated_vat_status']));
				}

				update_user_meta($user_id, 'vat_number', $vat_number_inputted);

			}
		}

		// if settings require approval on all users OR chosen user role requires approval
		if (intval(get_option('b2bking_approval_required_all_users_setting', 0)) === 1){
			update_user_meta( $user_id, 'b2bking_account_approved', 'no');

			$user_role = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_registration_roles_dropdown'));
			$user_role_id = explode('_', $user_role);
			if (count($user_role_id) > 1){
				$user_role_id = $user_role_id[1];
			} else {
				$user_role_id = 0;
			}
			$user_role_approval = get_post_meta($user_role_id, 'b2bking_custom_role_approval', true);
			$user_role_automatic_customer_group = get_post_meta($user_role_id, 'b2bking_custom_role_automatic_approval_group', true);

			if ($user_role_approval === 'manual'){
				update_user_meta( $user_id, 'b2bking_account_approved', 'no');
				// check if there is a setting to automatically send the user to a particular customer group
				if ($user_role_automatic_customer_group !== 'none' && $user_role_automatic_customer_group !== NULL && $user_role_automatic_customer_group !== ''){
					update_user_meta($user_id,'b2bking_default_approval_manual', $user_role_automatic_customer_group);
				}

				// if sales agent, save info as meta
				if (substr($user_role_automatic_customer_group, 0, 6) === 'salesk'){
					update_user_meta($user_id,'registration_role_agent', 'yes');
				}

			}

		} else if (isset($_POST['b2bking_registration_roles_dropdown'])){
			$user_role = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_registration_roles_dropdown'));
			$user_role_id = explode('_', $user_role);
			if (count($user_role_id) > 1){
				$user_role_id = $user_role_id[1];
			} else {
				$user_role_id = 0;
			}
			$user_role_approval = get_post_meta($user_role_id, 'b2bking_custom_role_approval', true);
			$user_role_automatic_customer_group = get_post_meta($user_role_id, 'b2bking_custom_role_automatic_approval_group', true);

			if ($user_role_approval === 'manual'){
				update_user_meta( $user_id, 'b2bking_account_approved', 'no');
				// check if there is a setting to automatically send the user to a particular customer group
				if ($user_role_automatic_customer_group !== 'none' && $user_role_automatic_customer_group !== NULL && $user_role_automatic_customer_group !== ''){
					update_user_meta($user_id,'b2bking_default_approval_manual', $user_role_automatic_customer_group);
				}

				// if sales agent, save info as meta
				if (substr($user_role_automatic_customer_group, 0, 6) === 'salesk'){
					update_user_meta($user_id,'registration_role_agent', 'yes');
				}

			} else if ($user_role_approval === 'automatic'){
				// check if there is a setting to automatically send the user to a particular customer group
				if ($user_role_automatic_customer_group !== 'none' && $user_role_automatic_customer_group !== NULL && $user_role_automatic_customer_group !== '' && substr($user_role_automatic_customer_group, 0, 6) !== 'salesk'){
					$group_id = explode('_',$user_role_automatic_customer_group)[1];
					b2bking()->update_user_group($user_id, sanitize_text_field($group_id));


					if (apply_filters('b2bking_use_wp_roles', false)){
						$user_obj = new WP_User($user_id);
						$user_obj->add_role('b2bking_role_'.$group_id);

						if (apply_filters('b2bking_use_wp_roles_only_b2b', false)){
							$user_obj->set_role('b2bking_role_'.$group_id);
						}
					}
				}

				// if salesking agent
				if (substr($user_role_automatic_customer_group, 0, 6) === 'salesk'){
					$group_id = explode('_',$user_role_automatic_customer_group)[1];
					update_user_meta( $user_id, 'salesking_group', sanitize_text_field($group_id));
					update_user_meta( $user_id, 'salesking_user_choice', 'agent');
					update_user_meta( $user_id, 'salesking_assigned_agent', 'none');
					do_action('b2bking_after_register_salesking_agent', $user_id);
				}
			}
		}

		// if customer is being approved automatically, and group is other than none, set customer as B2B
		$user_role = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_registration_roles_dropdown'));

		$user_role_id = 0;
		if (!empty($user_role)){
			$user_role_id = explode('_', $user_role);
			if (count($user_role_id) > 1){
				$user_role_id = $user_role_id[1];
			}
		}
		
		$user_role_approval = get_post_meta($user_role_id, 'b2bking_custom_role_approval', true);
		$user_role_automatic_customer_group = get_post_meta($user_role_id, 'b2bking_custom_role_automatic_approval_group', true);

		// if not sales agent

		if (!b2bking()->is_rest_api_request()){ // do not apply in API requests

			if (substr($user_role_automatic_customer_group, 0, 6) !== 'salesk'){
				if ($user_role_approval === 'automatic'){
					if ($user_role_automatic_customer_group !== 'none' && metadata_exists('post', $user_role_id, 'b2bking_custom_role_automatic_approval_group')){
						update_user_meta($user_id, 'b2bking_b2buser', 'yes');
					} else {
						// user must be b2c, add b2c role
						if (apply_filters('b2bking_use_wp_roles', false)){
							$user_obj = new WP_User($user_id);
							$user_obj->add_role(apply_filters('b2bking_b2c_role_name', 'b2bking_role_b2cuser'));

							if (apply_filters('b2bking_use_wp_roles_only_b2b', false)){
								$user_obj->set_role(apply_filters('b2bking_b2c_role_name', 'b2bking_role_b2cuser'));
							}
						}
						update_user_meta($user_id, 'b2bking_b2buser', 'no');
						b2bking()->update_user_group($user_id, 'no');

					}
				}

				$user_is_b2b = get_user_meta($user_id,'b2bking_b2buser', true);

				if (!isset($_POST['b2bking_registration_roles_dropdown']) && $user_is_b2b !== 'yes'){
					// must be a default b2c registration, add b2c role
					if (apply_filters('b2bking_use_wp_roles', false)){
						$user_obj = new WP_User($user_id);
						$user_obj->add_role(apply_filters('b2bking_b2c_role_name', 'b2bking_role_b2cuser'));

						if (apply_filters('b2bking_use_wp_roles_only_b2b', false)){
							$user_obj->set_role(apply_filters('b2bking_b2c_role_name', 'b2bking_role_b2cuser'));
						}
					}
					update_user_meta($user_id, 'b2bking_b2buser', 'no');
					b2bking()->update_user_group($user_id, 'no');

				}
			}

		}

		do_action('b2bking_after_register_user_save_fields', $user_id);

	}
	// If user approval is manual, stop automatic login on registration
	function b2bking_check_user_approval_on_registration($redirection_url) {
		$user_id = get_current_user_id();
		$user_approval = get_user_meta($user_id, 'b2bking_account_approved', true);
		$redir_change = 'no';

		if ($user_approval === 'no'){

			// for separate b2b reg
		    $separate_page = get_option( 'b2bking_registration_separate_my_account_page_setting', 'disabled' );
		    if ($separate_page !== 'disabled'){
		    	$redirection_url = get_permalink( $separate_page );
		    	$redir_change = 'yes';
		    }

		    if (apply_filters('b2bking_allow_logged_in_register_b2b', false)){

		    	update_user_meta($user_id,'b2bking_b2b_application_pending','yes');

		    	if (b2bking()->get_user_application_type($user_id) === 'agent'){
		    		
		    		wc_add_notice( esc_html__('Your account has been succesfully created. We are now reviewing your application to become a sales agent. Please wait to be approved.', 'b2bking'), 'success' );	

		    	} else {
			    	wc_add_notice( esc_html__('Your account has been succesfully created. We are now reviewing your application to become a B2B user. Please wait to be approved.', 'b2bking'), 'success' );	
		    	}

		    } else {
		    	wp_logout();

		    	do_action( 'woocommerce_set_cart_cookies',  true );

		    	wc_add_notice( apply_filters('b2bking_registration_manual_approval_message', esc_html__('Thank you for registering. Your account requires manual approval. Please wait to be approved.', 'b2bking'), 'success' ));	
		    }
		
		}
	
		if ($redir_change === 'no'){

			$my_account_link = get_permalink( wc_get_page_id( 'myaccount' ) );

			$redirection_url = add_query_arg( 'redir', 1, $my_account_link );
		}


		if ($user_approval === 'no'){
			$redirection_url = apply_filters('b2bking_manual_approval_redirect_registration', $redirection_url, $user_id);
		}

		return $redirection_url;
	}

	function b2bking_check_user_approval_on_registration_checkout($order_id) {
		$user_id = get_current_user_id();
		$user_approval = get_user_meta($user_id, 'b2bking_account_approved', true);

		if ($user_approval === 'no'){
			wp_logout();

			do_action( 'woocommerce_set_cart_cookies',  true );

			wc_add_notice( apply_filters('b2bking_registration_manual_approval_message', esc_html__('Thank you for registering. Your account requires manual approval. Please wait to be approvedddd.', 'b2bking'), 'success' ));			

		}
	}

	// Check registration for errors (especially file upload errors) also VAT error
	function b2bking_custom_registration_fields_check_errors( $errors, $username, $email ) {
		// get all enabled file upload custom fields
		$file_upload_fields = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_field_type',
		                        'value' => 'file'
			                ),
		            	)
			    	]);

		foreach($file_upload_fields as $file_upload_field){
			// get field and check if set
			$field_value = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_custom_field_'.$file_upload_field->ID)); 
			if ($field_value !== NULL){

				// Allowed file types
				$allowed_file_types = apply_filters('b2bking_allowed_file_types', array( "image/jpeg", "image/jpg", "image/png", "text/plain", "application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/octet-stream" ));
				$allowed_file_types_text = apply_filters('b2bking_allowed_file_types_text', 'jpg, jpeg, png, txt, pdf, doc, docx');
				// Allowed file size -> 5MB
				$allowed_file_size = apply_filters('b2bking_allowed_file_types_size', 5000000);
				$upload_errors = '';
				// Check if has a file 
				if (!apply_filters('b2bking_allow_file_upload_multiple', false)){
					if ( ! empty( $_FILES['b2bking_custom_field_'.$file_upload_field->ID]['name'] ) ) {
					    // Check file type
					    if ( ! in_array( $_FILES['b2bking_custom_field_'.$file_upload_field->ID]['type'], $allowed_file_types ) ) {
					        $upload_errors .= esc_html__('Invalid file type','b2bking').': ' . 
					                          $_FILES['b2bking_custom_field_'.$file_upload_field->ID]['type'] . 
					                          '. '.esc_html__('Supported file types','b2bking').': '.$allowed_file_types_text;
					    }
					    // Check file size
					    if ( $_FILES['b2bking_custom_field_'.$file_upload_field->ID]['size'] > $allowed_file_size ) {
					        $upload_errors .= '<p>'.esc_html__('File is too large. Max. upload file size is','b2bking').' 5MB</p>';
					    }
					    // If errors, show errors
					    if (! empty( $upload_errors ) ) {
					    	$errors->add( 'username_error', esc_html($upload_errors) );
					    }
					}
				} else {
					if ( ! empty( $_FILES['b2bking_custom_field_'.$file_upload_field->ID]) ) {
						$i = 0;
						while (isset($_FILES['b2bking_custom_field_'.$file_upload_field->ID]['name'][$i])){
							// Check file type
							if ( ! in_array( $_FILES['b2bking_custom_field_'.$file_upload_field->ID]['type'][$i], $allowed_file_types ) ) {
								if (!empty($_FILES['b2bking_custom_field_'.$file_upload_field->ID]['type'][$i])){
							    	$upload_errors .= esc_html__('One of the files uploaded does not match the allowed file types','b2bking');
							    }
							}
							// Check file size
							if ( $_FILES['b2bking_custom_field_'.$file_upload_field->ID]['size'][$i] > $allowed_file_size ) {
							    $upload_errors .= '<p>'.esc_html__('One of the files uploaded is too large. Max. upload file size is','b2bking').' 5MB</p>';
							}

							$i++;

						}
					}

					// If errors, show errors
					if (! empty( $upload_errors ) ) {
						$errors->add( 'username_error', esc_html($upload_errors) );
					}
				}
				
			}
		}
		if (isset($_POST['b2bking_vat_number_registration_field_number'])){
			$vat_number_inputted = sanitize_text_field($_POST['b2bking_custom_field_'.$_POST['b2bking_vat_number_registration_field_number']]);

			if (!empty($vat_number_inputted)){

				if (apply_filters('b2bking_set_default_prefix_vat', false) !== false){
					$prefix = apply_filters('b2bking_set_default_prefix_vat', false);
					// if vat nr does not start with the prefix, add the prefix
					if (substr( $vat_number_inputted, 0, 2 ) !== $prefix){
						$vat_number_inputted = $prefix.$vat_number_inputted;
					}
				}	
			}
		} else {
			$vat_number_inputted = '';
		}

		if (isset($_POST['b2bking_country_registration_field_number'])){
			$country_inputted = sanitize_text_field($_POST['b2bking_custom_field_'.$_POST['b2bking_country_registration_field_number']]);
		} else {
			$country_inputted = '';
		}

		if ($country_inputted === 'none' || empty($country_inputted)){
			// check if it is single country shop
		    $countries = WC()->countries->get_allowed_countries();
		    
		    if (count($countries) === 1) {
		        $country_inputted = array_keys($countries)[0]; // Returns country code
		    }
		}

		if (!(empty($vat_number_inputted))){

			// check if VIES Validation is enabled in settings
			$vat_field_vies_validation_setting = get_post_meta($_POST['b2bking_vat_number_registration_field_number'], 'b2bking_custom_field_VAT_VIES_validation', true);

			$countries_list_eu = apply_filters('b2bking_country_list_vies', array('AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'EL', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE'));
			if (in_array($country_inputted, $countries_list_eu)){
				// proceed only if VIES validation is enabled
				if (intval($vat_field_vies_validation_setting) === 1){
					$error_details = '';
					$validation = new stdClass();
					$validation -> valid = 1;
					// check vat
					try {

						$country_code = substr($vat_number_inputted, 0, 2); // take first 2 chars
						$vat_number = substr($vat_number_inputted, 2); // remove first 2 chars

						$validation = b2bking()->vies_validation($country_code, $vat_number);

						$error_details = '';

						// check country is same as VAT country
						if (trim(strtolower($country_inputted)) !== trim(strtolower($country_code))){
							// check exception Greece (GR) has EL VAT code
							if( (trim(strtolower($country_inputted)) === 'gr') && (trim(strtolower($country_code)) === 'el')){
								// if indeed the VAT number is EL and country is GR, do nothing
							} else {
								$errors->add( 'username_error', esc_html__('VAT Number you entered is for a different country than the country you selected', 'b2bking'));
							}
						}


					} catch (Exception $e) {
						$error = $e->getMessage();

						$error_array = array(
						    'INVALID_INPUT'       => esc_html__('CountryCode is invalid or the VAT number is empty.', 'b2bking'),
						    'SERVICE_UNAVAILABLE' => esc_html__('VIES VAT Service is unavailable. Try again later.', 'b2bking'),
						    'MS_UNAVAILABLE'      => esc_html__('VIES VAT Member State Service is unavailable.', 'b2bking'),
						    'TIMEOUT'             => esc_html__('Service timeout. Try again later', 'b2bking'),
						    'SERVER_BUSY'         => esc_html__('VAT Server is too busy. Try again later.', 'b2bking'),
						    'MS_MAX_CONCURRENT_REQ' => esc_html__('Too many requests. The Europa.eu VIES server cannot process your request right now.', 'b2bking'),
						);

						if ( array_key_exists( $error , $error_array ) ) {
						    $error_details .= $error_array[ $error ];
						} else {
							$error_details .= $error;
						}

						$validation->valid=0;

						// if error is independent of the user (unavailable service, timeout, etc), allow it, but notify the website admin
						if (apply_filters('b2bking_allow_vat_timeouts_unavailable_errors', true)){
							if ($error !== 'INVALID_INPUT'){ // except the invalid format error
								$validation = new stdClass();
								$validation -> valid = 1;

								// mail the website admin about the issue and that this number needs to be checked
								$recipient = get_option( 'admin_email' );
								$recipient = apply_filters('b2bking_invalid_vat_number_email', $recipient, 0);

							    $message = 'A customer registered or ordered on your shop, but the VIES validation encountered an issue which is not the user\'s fault. The request was accepted, but you should manually check this VAT number and customer.';
							    $message .= '<br><br>Error details: '.$error;
							    if ( array_key_exists( $error , $error_array ) ) {
							        $message .= ' ('.$error_array[ $error ].')';
							    }

							    $current_user = wp_get_current_user();
							    if ($current_user->ID != 0) {
							        $user_email = $current_user->user_email;
							    } else {
							        $user_email = 'Logged out user';
							    }

							    $message .= '<br><br>The VAT number is: '.$country_code.$vat_number;
							    $message .= '<br><br>The email of the user is: '.$user_email;

							    do_action( 'b2bking_new_message', $recipient, $message, 'Quoteemail:1', 0 );
								
							}
						}
					}

					if(intval($validation->valid) === 1){
						// VAT IS VALID
					} else {
						$errors->add( 'username_error', esc_html__('VAT Number is Invalid.', 'b2bking').' '.esc_html($error_details) );
					}

				}
			}

		}

		// Check normal fields to add some extra checks
		if (isset($_POST['b2bking_registration_roles_dropdown'])){
			$role_selected = sanitize_text_field($_POST['b2bking_registration_roles_dropdown']);
			// get fields that are enabled, and required for this role
			$custom_fields = get_posts([
	    		'post_type' => 'b2bking_custom_field',
	    	  	'post_status' => 'publish',
	    	  	'numberposts' => -1,
    	  	    'orderby' => 'menu_order',
    	  	    'order' => 'ASC',
    	  	    'fields' => 'ids',
	    	  	'meta_query'=> array(
	    	  		'relation' => 'AND',
	                array(
                        'key' => 'b2bking_custom_field_status',
                        'value' => 1
	                ),
	                array(
                        'key' => 'b2bking_custom_field_required',
                        'value' => 1
	                ),
            	)
	    	]);

	    	// remove VAT fields (because those have extra country based validation)
	    	foreach ($custom_fields as $index => $field_id){
	    		$billing_connection = get_post_meta($field_id,'b2bking_custom_field_billing_connection', true);
	    		if ($billing_connection === 'billing_vat'){
	    			unset($custom_fields[$index]);
	    		}
	    	}
	    	// remove none fields which are set as billing-exclusive
	    	foreach ($custom_fields as $index => $field_id){
	    		$billing_connection = get_post_meta($field_id,'b2bking_custom_field_billing_connection', true);
	    		if ($billing_connection === 'none'){
		    		$billing_exclusive = intval(get_post_meta($field_id, 'b2bking_custom_field_billing_exclusive', true));
		    		if ($billing_exclusive === 1){
		    			unset($custom_fields[$index]);
		    		}
		    	}
	    	}
	    	// remove file, select, checkbox, radio fields
	    	foreach ($custom_fields as $index => $field_id){
	    		$field_type = get_post_meta($field_id,'b2bking_custom_field_field_type', true);

				if ($field_type === 'file' || $field_type === 'checkbox' || $field_type === 'radio' || $field_type === 'select'){
		    		unset($custom_fields[$index]);
		    	}
		    }

		    // remove fields which do not belong to the role selected
        	foreach ($custom_fields as $index => $field_id){
        		$role_applies = false;
        		$field_role = get_post_meta($field_id,'b2bking_custom_field_registration_role', true); // e.g role_123
        		if ($field_role === 'allroles'){
        			$role_applies = true;
        		}
        		if ($field_role === $role_selected){
        			$role_applies = true;
        		}
        		if ($field_role === 'multipleroles'){
        			$field_roles = get_post_meta($field_id, 'b2bking_custom_field_multiple_roles', true);
        			$field_roles = explode(',', $field_roles);
        			if (in_array($role_selected, $field_roles)){
        				$role_applies = true;
        			}
        		}

        		if ($role_applies === false){
        			unset($custom_fields[$index]);
        		}
    	    }

    	    // now finally check that fields are not empty
    	    foreach ($custom_fields as $field_id){
    	    	$value = trim(sanitize_text_field($_POST['b2bking_custom_field_'.$field_id]));
    	    	if (empty($value) && isset($_POST['b2bking_custom_field_'.$field_id])){
    	    		$label = get_post_meta(apply_filters( 'wpml_object_id', $field_id, 'post', true ), 'b2bking_custom_field_field_label', true);
    	    		$errors->add( 'b2bking_error_'.$field_id, $label.' '.esc_html__('is a required field.', 'b2bking') );
    	    	}
    	    }

		}



		return $errors;
	}
	

	function b2bking_display_custom_registration_fields(){

		$user_id = get_current_user_id();
		if (apply_filters('b2bking_subaccounts_use_same_fields', true)){
			$user_id = b2bking()->get_top_parent_account($user_id);
		}

		// build array of groups visible
		$array_groups_visible = array(
            'relation' => 'OR',
        );

		if (!is_user_logged_in()){
			array_push($array_groups_visible, array(
                'key' => 'b2bking_custom_field_multiple_groups',
                'value' => 'group_loggedout',
                'compare' => 'LIKE'
            ));
		} else {
			// if user is b2c
			if (get_user_meta($user_id,'b2bking_b2buser', true) !== 'yes'){
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_b2c',
	                'compare' => 'LIKE'
	            ));
			} else {
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_'.b2bking()->get_user_group($user_id),
	                'compare' => 'LIKE'
	            ));
	            array_push($array_groups_visible, array(
                    'key' => 'b2bking_custom_field_multiple_groups',
                    'value' => 'group_b2b',
                    'compare' => 'LIKE'
                ));
			}
		}

		// Get all enabled editable fields
		$custom_fields = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
		    	  	    'orderby' => 'menu_order',
		    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_status',
		                        'value' => 1
			                ),
			                array(
		                        'key' => 'b2bking_custom_field_editable',
		                        'value' => 1
			                ),
			                // show in My Account only fields with no billing connection OR VAT (billing connection fields are already shown by default by WooCommerce)
			                array(
    			    	  		'relation' => 'OR',
    			                array(
    		                        'key' => 'b2bking_custom_field_billing_connection',
    		                        'value' => 'none'
    			                ),
    			                array(
    		                        'key' => 'b2bking_custom_field_billing_connection',
    		                        'value' => 'billing_vat'
    			                ),
			                ),
			                $array_groups_visible
		            	)
			    	]);

		$custom_fields_mapping = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
		    	  	    'orderby' => 'menu_order',
		    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_status',
		                        'value' => 1
			                ),
			                array(
		                        'key' => 'b2bking_custom_field_editable',
		                        'value' => 1
			                ),
			                // show in My Account only fields with no billing connection OR VAT (billing connection fields are already shown by default by WooCommerce)
			                array(
                                'key' => 'b2bking_custom_field_billing_connection',
                                'value' => 'custom_mapping'
        	                ),
		            	)
			    	]);

		$custom_fields = apply_filters('b2bking_available_custom_fields_my_account', array_merge($custom_fields, $custom_fields_mapping));

		// loop through fields
		foreach ($custom_fields as $field){

			$customval = apply_filters('b2bking_customval_field_myaccount', '', $field->ID);

			$field_type = get_post_meta($field->ID, 'b2bking_custom_field_field_type', true);

			if ($field_type !== 'file' && $field_type !== 'checkbox' && $field_type !== 'radio'){
				// get field data
				$field_label = get_post_meta(apply_filters( 'wpml_object_id', $field->ID, 'post', true ), 'b2bking_custom_field_field_label', true);


				$field_user_choices = get_post_meta($field->ID, 'b2bking_custom_field_user_choices', true);
				// get value (from registration
				$field_value = get_user_meta($user_id, 'b2bking_custom_field_'.$field->ID, true);
				if ($field_value === null){
					$field_value = '';
				}

				// display label
				echo '<label for="b2bking_custom_field_'.esc_attr($field->ID).'">'.esc_html($field_label).'</label>';

				// display field
				if ($field_type === 'text'){
					echo '<input type="text" class="b2bking_custom_registration_field" name="b2bking_custom_field_'.esc_attr($field->ID).'" id="b2bking_custom_field_'.esc_attr($field->ID).'" value="'.esc_attr($field_value).'" '.$customval.'><br /><br />';
				} else if ($field_type === 'number'){
					echo '<input type="number" step="0.00001" class="b2bking_custom_registration_field" name="b2bking_custom_field_'.esc_attr($field->ID).'" id="b2bking_custom_field_'.esc_attr($field->ID).'" value="'.esc_attr($field_value).'"><br /><br />';
				} else if ($field_type === 'email'){
					echo '<input type="email" class="b2bking_custom_registration_field" name="b2bking_custom_field_'.esc_attr($field->ID).'" id="b2bking_custom_field_'.esc_attr($field->ID).'" value="'.esc_attr($field_value).'"><br /><br />';
				} else if ($field_type === 'date'){
					echo '<input type="date" class="b2bking_custom_registration_field" name="b2bking_custom_field_'.esc_attr($field->ID).'" id="b2bking_custom_field_'.esc_attr($field->ID).'" value="'.esc_attr($field_value).'"><br /><br />';
				} else if ($field_type === 'time'){
					echo '<input type="time" class="b2bking_custom_registration_field" name="b2bking_custom_field_'.esc_attr($field->ID).'" id="b2bking_custom_field_'.esc_attr($field->ID).'" value="'.esc_attr($field_value).'"><br /><br />';
				} else if ($field_type === 'tel'){
					echo '<input type="tel" class="b2bking_custom_registration_field" name="b2bking_custom_field_'.esc_attr($field->ID).'" id="b2bking_custom_field_'.esc_attr($field->ID).'" value="'.esc_attr($field_value).'"><br /><br />';
				} else if ($field_type === 'textarea'){
					echo '<textarea class="b2bking_custom_registration_field" name="b2bking_custom_field_'.esc_attr($field->ID).'" id="b2bking_custom_field_'.esc_attr($field->ID).'">'.esc_html($field_value).'</textarea><br /><br />';
				} else if ($field_type === 'select'){
					$user_options = explode(',', $field_user_choices);
					echo '<select class="b2bking_custom_registration_field" name="b2bking_custom_field_'.esc_attr($field->ID).'" id="b2bking_custom_field_'.esc_attr($field->ID).'">';
					foreach ($user_options as $option){
						if ($option !== NULL && $option !== ''){
							// check if option is simple or value is specified via option:value
							$optionvalue = explode(':', $option);
							if (count($optionvalue) === 2 ){
								// value is specified
								echo '<option value="'.esc_attr(trim($optionvalue[0])).'" '.selected(trim($optionvalue[0]), $field_value, false).'>'.esc_html(trim($optionvalue[1])).'</option>';
							} else {
								// simple
								echo '<option value="'.esc_attr(trim($option)).'" '.selected(trim($option),trim($field_value),false).'>'.esc_html(trim($option)).'</option>';
							}
						}
					}
					echo '</select>
					<br /><br />';
				}
			}
		}
	}

	function offer_cart_item_price($price, $cart_item, $cart_item_key){

		if (intval(get_option( 'b2bking_offer_use_products_setting', 1 )) === 1){
			if (isset($cart_item['b2bking_is_offer_child'])){
				if ($cart_item['b2bking_is_offer_child'] === 'yes'){
					// set name to parent offer
					$item_price = $cart_item['b2bking_offer_child_price'];
					return wc_price($item_price);
				}
			}
		}

		return $price;
	}
	function offer_cart_item_price_subtotal($subtotal, $cart_item, $cart_item_key){

		if (intval(get_option( 'b2bking_offer_use_products_setting', 1 )) === 1){
			if (isset($cart_item['b2bking_is_offer_child'])){
				$offer_id = $cart_item['b2bking_offer_id'];
				if ($cart_item['b2bking_is_offer_child'] === 'yes'){
					$offer_qty = 0;
					foreach ( WC()->cart->get_cart() as $cart_item_key2 => $cart_item2 ) {
						if (isset($cart_item2['b2bking_parent_offer'])){
							if ($cart_item2['b2bking_offer_id'] == $offer_id){
								$offer_qty = $cart_item2['quantity'];
							}
						}
					}

					// set name to parent offer
					$item_subtotal = $cart_item['b2bking_offer_child_price'] * $cart_item['b2bking_offer_child_qty'] * $offer_qty;
					return wc_price($item_subtotal);
				}
			}
		}

		return $subtotal;
	}
	function filter_offer_name($name, $cart_item, $cart_item_key){

		if (intval(get_option( 'b2bking_offer_use_products_setting', 1 )) === 1){
			if (isset($cart_item['b2bking_is_offer_child'])){
				if ($cart_item['b2bking_is_offer_child'] === 'yes'){
					// set name to parent offer
					$offer_id = $cart_item['b2bking_offer_id'];
					$offer_name = get_the_title(apply_filters( 'wpml_object_id', $offer_id, 'post' , true));
					$name = $offer_name . ' → ' . $name;
				}
			}
		}

		return $name;
	}
	function cart_item_class( $class, $cart_item ) {
		if ( isset( $cart_item['b2bking_is_offer_child'] ) ) {
			$class .= ' b2bking-cart-item-child';
		}

		return $class;
	}

	function set_specific_items_to_free($cart) {
	    if (is_admin() && !defined('DOING_AJAX')) {
	    	return;
	    }

	    // Remove orphaned offer children whose parent offer is no longer in the cart
	    $active_parent_offer_ids = [];
	    foreach ($cart->get_cart() as $cart_item) {
	        if (isset($cart_item['b2bking_parent_offer'])) {
	            $active_parent_offer_ids[] = $cart_item['b2bking_offer_id'];
	        }
	    }
	    $keys_to_remove = [];
	    foreach ($cart->get_cart() as $key => $cart_item) {
	        if (isset($cart_item['b2bking_is_offer_child']) && !in_array($cart_item['b2bking_offer_id'], $active_parent_offer_ids)) {
	            $keys_to_remove[] = $key;
	        }
	    }
	    foreach ($keys_to_remove as $key) {
	        $cart->remove_cart_item($key);
	    }

	    // set to free
	    foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
	        // Check if the cart item has the 'b2bking_offer_id' set
	        if (isset($cart_item['b2bking_is_offer_child'])) {
	            // Set the price to 0 to make the item free
	            $cart_item['data']->set_price(0);
	       	 	$cart_item['data']->update_meta_data('_b2bking_custom_offer_price_set', 'yes');
            } else {
                // Ensure the flag is removed if condition is not met
                $cart_item['data']->delete_meta_data('_b2bking_custom_offer_price_set');
            }


            if (isset($cart_item['bundled_by'])) {
            	$cart_item['data']->update_meta_data('_b2bking_custom_offer_price_set_bundle', 'yes');
            } else {
            	$cart_item['data']->delete_meta_data('_b2bking_custom_offer_price_set_bundle');
            }

	    }
	}

	function cart_item_quantity( $quantity, $cart_item_key, $cart_item = array() ) {
		// add qty as text - not input
		if ( isset( $cart_item['b2bking_is_offer_child'] ) ) {
			$offer_id = $cart_item['b2bking_offer_id'];

			$offer_qty = 0;
			foreach ( WC()->cart->get_cart() as $cart_item_key2 => $cart_item2 ) {
				if (isset($cart_item2['b2bking_parent_offer'])){
					if ($cart_item2['b2bking_offer_id'] == $offer_id){
						$offer_qty = $cart_item2['quantity'];
					}
				}
			}

			$new_child_quantity = $cart_item['b2bking_offer_child_qty'] * $offer_qty;

			WC()->cart->set_quantity($cart_item_key, round($new_child_quantity)); // Update the child item quantity

			return $new_child_quantity;
		}

		return $quantity;
	}

	function cart_item_removed( $cart_item_key, $cart ) {

		if ( isset( $cart->removed_cart_contents[ $cart_item_key ]['b2bking_offer_name'] ) ) {
			$offer_removed = $cart->removed_cart_contents[ $cart_item_key ]['b2bking_offer_id'];

			foreach ( $cart->get_cart() as $cart_item_key2 => $cart_item ) {
			   // Check if the cart item has the specific b2bking_offer_id meta data
			   if ( isset($cart_item['b2bking_offer_id']) && $cart_item['b2bking_offer_id'] == $offer_removed ) {
			       // Remove the item from the cart
			       $cart->remove_cart_item($cart_item_key2);
			   }
			}
		}
	}


	function filter_offer_image($image, $cart_item, $cart_item_key){


		if (isset($cart_item['b2bking_offer_id'])){

			// first, set the standard offer img, if not empty
			$settings_offer_image = get_option('b2bking_offers_image_setting','');
			if (!empty($settings_offer_image)){
				$image = wp_get_attachment_image(attachment_url_to_postid($settings_offer_image));
			}

			$offer_id = $cart_item['b2bking_offer_id'];

			$offer_details = get_post_meta(apply_filters( 'wpml_object_id', $offer_id, 'post' , true), 'b2bking_offer_details', true);
			$products = explode ('|', $offer_details);

			$countprod = 0;
			$prodimg = $image;

			foreach($products as $product){
				$details = explode(';',$product);

				// if item is in the form product_id, change title
				$isproductid = explode('_', $details[0]); 
				if ($isproductid[0] === 'product'){
					// it is a product+id, get product title
					$newproduct = wc_get_product($isproductid[1]);
					if ($newproduct){
						$countprod++;
						$prodimg = $newproduct->get_image();
					}
				}
			}

			if ($countprod === 1){
				if (apply_filters('b2bking_individual_image_offer', true)){
					if (!empty($prodimg)){
						$image = $prodimg;
					}
				}
			}

		}
		
		return $image;
	}

	function b2bking_user_is_in_list($user_data_current_user_id, $user_data_current_user_b2b, $user_data_current_user_group, $list){
		// checks based on user id, b2b status and group, if it's part of an applicable rules list
		$is_in_list = 'no';
		$list_array = explode(',',$list);
		if (intval($user_data_current_user_id) !== 0){
			if (in_array('all_registered', $list_array)){
				return 'yes';
			}
			if ($user_data_current_user_b2b === 'yes'){
				// user is b2b
				if (in_array('everyone_registered_b2b', $list_array)){
					return 'yes';
				}
				if (in_array('group_'.$user_data_current_user_group, $list_array)){
					return 'yes';
				}
			} else {
				// user is b2c
				if (in_array('everyone_registered_b2c', $list_array)){
					return 'yes';
				}
			}
			if (in_array('user_'.$user_data_current_user_id, $list_array)){
				return 'yes';
			}

		} else if (intval($user_data_current_user_id) === 0){
			if (in_array('user_0', $list_array)){
				return 'yes';
			}
		}

		return $is_in_list;
	}

	// Save custom registration fields after edit
	function b2bking_save_custom_registration_fields_edit(){
		
		$user_id = get_current_user_id();
		if (apply_filters('b2bking_subaccounts_use_same_fields', true)){
			$user_id = b2bking()->get_top_parent_account($user_id);
		}


	    $user = get_user_by('id', $user_id) -> user_login;

		// Get all enabled editable fields
		$custom_fields = get_posts([
			    		'post_type' => 'b2bking_custom_field',
			    	  	'post_status' => 'publish',
			    	  	'numberposts' => -1,
		    	  	    'orderby' => 'menu_order',
		    	  	    'order' => 'ASC',
			    	  	'meta_query'=> array(
			    	  		'relation' => 'AND',
			                array(
		                        'key' => 'b2bking_custom_field_status',
		                        'value' => 1
			                ),
			                array(
		                        'key' => 'b2bking_custom_field_editable',
		                        'value' => 1
			                ),

		            	)
			    	]);

		// loop through fields
		foreach ($custom_fields as $field){
			// get field and check if set
			$field_value = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_custom_field_'.$field->ID)); 
			$billing_connection = get_post_meta($field->ID,'b2bking_custom_field_billing_connection', true);

			if ($field_value !== NULL){
				

				if ($billing_connection === 'billing_vat'){
					if (!empty($field_value)){
						update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID, $field_value);
						update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID.'bis', $field_value);
						update_user_meta( $user_id, 'vat_number', $field_value);
					}
				} else {
					update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID, $field_value);
					if ($billing_connection === 'custom_mapping'){
						update_user_meta ($user_id, sanitize_text_field(get_post_meta($field->ID, 'b2bking_custom_field_mapping', true)), $field_value);
					}
				}
			}
		}
	}


	function b2bking_save_custom_registration_fields_validate( $errors ){

		$user_id = get_current_user_id();
		if (apply_filters('b2bking_subaccounts_use_same_fields', true)){
			$user_id = b2bking()->get_top_parent_account($user_id);
		}

		/* If there is vat, validate VAT */
		// Get VAT field
		$vat_fields = get_posts([
    		'post_type' => 'b2bking_custom_field',
    	  	'post_status' => 'publish',
    	  	'numberposts' => -1,
	  	    'orderby' => 'menu_order',
	  	    'order' => 'ASC',
    	  	'meta_query'=> array(
    	  		'relation' => 'AND',
                array(
                    'key' => 'b2bking_custom_field_status',
                    'value' => 1
                ),
                array(
                    'key' => 'b2bking_custom_field_editable',
                    'value' => 1
                ),
                array(
                    'key' => 'b2bking_custom_field_billing_connection',
                    'value' => 'billing_vat'
                ),
        	)
    	]);

		foreach ($vat_fields as $vat_field) { // should be only one

		    if ( isset( $_POST['b2bking_custom_field_'.$vat_field->ID] ) ) {

		    	if (!empty($_POST['b2bking_custom_field_'.$vat_field->ID])){

		    		// if VIES Validation is enabled perform new VIES Validation 
		    		$vat_field_vies_validation_setting = get_post_meta($vat_field->ID, 'b2bking_custom_field_VAT_VIES_validation', true);
		    		if (intval($vat_field_vies_validation_setting) === 1){

		    			// check vat
		    			$vat_number_inputted = sanitize_text_field($_POST['b2bking_custom_field_'.$vat_field->ID]);
		    			$vat_number_inputted = strtoupper(str_replace(array('.', ' '), '', $vat_number_inputted));

		    			if (!empty($vat_number_inputted)){

			    			if (apply_filters('b2bking_set_default_prefix_vat', false) !== false){
			    				$prefix = apply_filters('b2bking_set_default_prefix_vat', false);
			    				// if vat nr does not start with the prefix, add the prefix
			    				if (substr( $vat_number_inputted, 0, 2 ) !== $prefix){
			    					$vat_number_inputted = $prefix.$vat_number_inputted;
			    				}
			    			}	

			    		}
			    		$countries_list_eu = apply_filters('b2bking_country_list_vies', array('AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'EL', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE'));
		    			

		    			if (in_array(substr($vat_number_inputted, 0, 2), $countries_list_eu)){

		    				$error_details = '';
			    			try {
			    				$country_code = substr($vat_number_inputted, 0, 2); // take first 2 chars
			    				$vat_number = substr($vat_number_inputted, 2); // remove first 2 chars

			    				$validation = b2bking()->vies_validation($country_code, $vat_number);

			    				$error_details = '';

			    			} catch (Exception $e) {
			    				$error = $e->getMessage();

			    				$error_array = array(
			    				    'INVALID_INPUT'       => esc_html__('CountryCode is invalid or the VAT number is empty.', 'b2bking'),
			    				    'SERVICE_UNAVAILABLE' => esc_html__('VIES VAT Service is unavailable. Try again later.', 'b2bking'),
			    				    'MS_UNAVAILABLE'      => esc_html__('VIES VAT Member State Service is unavailable.', 'b2bking'),
			    				    'TIMEOUT'             => esc_html__('Service timeout. Try again later', 'b2bking'),
			    				    'SERVER_BUSY'         => esc_html__('VAT Server is too busy. Try again later.', 'b2bking'),
			    				    'MS_MAX_CONCURRENT_REQ' => esc_html__('Too many requests. The Europa.eu VIES server cannot process your request right now.', 'b2bking'),
			    				);

			    				if ( array_key_exists( $error , $error_array ) ) {
			    				    $error_details .= $error_array[ $error ];
			    				} else {
									$error_details .= $error;
								}

								// if error is independent of the user (unavailable service, timeout, etc), allow it, but notify the website admin
								if (apply_filters('b2bking_allow_vat_timeouts_unavailable_errors', true)){
									if ($error !== 'INVALID_INPUT'){ // except the invalid format error
										$validation = new stdClass();
										$validation -> valid = 1;

										// mail the website admin about the issue and that this number needs to be checked
										$recipient = get_option( 'admin_email' );
										$recipient = apply_filters('b2bking_invalid_vat_number_email', $recipient, 0);

									    $message = 'A customer registered / ordered on your shop, but the VIES Validation encountered an issue which is not the fault of the user. The request was accepted, but you should manually check this VAT number and customer.';
									    $message .= '<br><br>Error details: '.$error;
									    if ( array_key_exists( $error , $error_array ) ) {
									        $message .= ' ('.$error_array[ $error ].')';
									    }

									    $current_user = wp_get_current_user();
									    if ($current_user->ID != 0) {
									        $user_email = $current_user->user_email;
									    } else {
									        $user_email = 'Logged out user';
									    }

									    $message .= '<br><br>The VAT number is: '.$country_code.$vat_number;
									    $message .= '<br><br>The email of the user is: '.$user_email;

									    do_action( 'b2bking_new_message', $recipient, $message, 'Quoteemail:1', 0 );
										
									}
								}
			    			}

			    			if(isset($validation)){
			    				if (intval($validation->valid) === 1){
			    					// VAT IS VALID
			    					update_user_meta( $user_id, 'b2bking_user_vat_status', 'validated_vat');
			    				} else {
			    					wc_add_notice( esc_html__( 'VAT number is invalid. ', 'b2bking' ).$error_details, 'error' );
			    				}
			    			} else {
			    				wc_add_notice( esc_html__( 'VAT number is invalid. ', 'b2bking' ).$error_details, 'error' );
			    			}
			    		} else {
			    			// should not have valid vat status unless VIES checked
			    			update_user_meta( $user_id, 'b2bking_user_vat_status', 'invalid');
			    		}

		    		} else {
		    			// should not have valid vat status unless VIES checked
		    			update_user_meta( $user_id, 'b2bking_user_vat_status', 'invalid');
		    		}
		    	}
		
		    }

		}



		if (apply_filters('b2bking_show_custom_mapping_fields_billing', false)){

			if (is_user_logged_in()){
				$user_id = get_current_user_id();
				$user_id = b2bking()->get_top_parent_account($user_id);
			} else {
				$user_id = 0; 
			}

			// build array of groups visible
			$array_groups_visible = array(
	            'relation' => 'OR',
	        );

			if (!is_user_logged_in()){
				array_push($array_groups_visible, array(
	                'key' => 'b2bking_custom_field_multiple_groups',
	                'value' => 'group_loggedout',
	                'compare' => 'LIKE'
	            ));
			} else {
				// if user is b2c
				if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) !== 'yes'){
					array_push($array_groups_visible, array(
		                'key' => 'b2bking_custom_field_multiple_groups',
		                'value' => 'group_b2c',
		                'compare' => 'LIKE'
		            ));
				} else {
					array_push($array_groups_visible, array(
		                'key' => 'b2bking_custom_field_multiple_groups',
		                'value' => 'group_'.b2bking()->get_user_group(),
		                'compare' => 'LIKE'
		            ));
		            array_push($array_groups_visible, array(
	                    'key' => 'b2bking_custom_field_multiple_groups',
	                    'value' => 'group_b2b',
	                    'compare' => 'LIKE'
	                ));
				}
			}

			// get all enabled custom fields with no default billing connection (first name, last name etc)
			$custom_fields = get_posts([
				    		'post_type' => 'b2bking_custom_field',
				    	  	'post_status' => 'publish',
				    	  	'numberposts' => -1,
			    	  	    'orderby' => 'menu_order',
			    	  	    'order' => 'ASC',
				    	  	'meta_query'=> array(
				    	  		'relation' => 'AND',
				                array(
			                        'key' => 'b2bking_custom_field_status',
			                        'value' => 1
				                ),
				                array(
				                	'relation' => 'OR',
	            	                array(
	                                    'key' => 'b2bking_custom_field_billing_connection',
	                                    'value' => 'custom_mapping',
	            	                ),
	        		            ),			               
				                $array_groups_visible,
			            	)
				    	]);

			foreach ($custom_fields as $field){
				// get field and check if set
				$field_value = sanitize_text_field(filter_input(INPUT_POST, 'b2bking_custom_field_'.$field->ID)); 
				$billing_connection = get_post_meta($field->ID,'b2bking_custom_field_billing_connection', true);

				$customval = apply_filters('b2bking_customval_field_myaccount', '', $field->ID);
				if ($customval !== 'readonly'){
					if ($field_value !== NULL){
						update_user_meta( $user_id, 'b2bking_custom_field_'.$field->ID, $field_value);
						if ($billing_connection === 'custom_mapping'){
							update_user_meta ($user_id, sanitize_text_field(get_post_meta($field->ID, 'b2bking_custom_field_mapping', true)), $field_value);
						}
					}
				}

				
			}
		}
	} 


	// Allow file upload in registration for WooCommerce
	function b2bking_custom_registration_fields_allow_file_upload() {
	   	echo 'enctype="multipart/form-data"';
	}

	function b2bking_overwrite_hide_shipping_when_free($val){

		if ($val === 'yes'){
			// overwrite with B2BKing function
			global $b2bking_check_package_rates;

			// not b2bking checking the setting
			if ($b2bking_check_package_rates !== 'yes'){
				$val = 'no';
			}
		}

	    return $val;

	}

	function b2bking_overwrite_hide_shipping_when_free_higher_priority($rates, $package){
		global $b2bking_check_package_rates;
		$b2bking_check_package_rates = 'yes';
		$hide_shipping_when_free = get_option('woocommerce_shipping_hide_rates_when_free','no');

		if ($hide_shipping_when_free === 'yes'){
			// overwrite without custom function that does the same thing just with higher priority
			// Define arrays to hold our Free Shipping and Local Pickup methods, if found.
			$free_shipping = [];
			$local_pickup  = [];

			// Go through each rate received.
			foreach ( $rates as $rate_id => $rate ) {
				// If either method is found, add them to their respective array.
				if ( 'free_shipping' === $rate->method_id ) {
					$free_shipping[ $rate_id ] = $rate;
					continue;
				}
				if ( 'pickup_location' === $rate->method_id || 'local_pickup' === $rate->method_id ) {
					$local_pickup[ $rate_id ] = $rate;
				}
			}

			// If the free_shipping array contains a method, then merge the local_pickup into it, and overwrite the rates array.
			if ( ! empty( $free_shipping ) ) {
				$rates = array_merge( $free_shipping, $local_pickup );
			}

			return $rates;
		}


		$b2bking_check_package_rates = 'no';
		return $rates;
	}

	// Disable shipping methods based on user settings (group)
	function b2bking_disable_shipping_methods( $rates ){

		if (apply_filters('b2bking_use_zone_shipping_control', true)){
			$user_id = get_current_user_id();
			$user_id = b2bking()->get_top_parent_account($user_id);

			$available = array();
			// if user is guest, disable shipping methods by guest group options
			if (intval($user_id) === 0){

				// For each shipping method, check if it's available. Add it to available options
				foreach ( $rates as $rate_id => $rate ) {
					$user_access = get_option('b2bking_logged_out_users_shipping_method_'.$rate->method_id.$rate->instance_id, 1);

					// UPS EXCEPTION
					if ($rate->method_id === 'wf_shipping_ups'){
						$user_access = get_option('b2bking_logged_out_users_shipping_method_'.$rate->method_id.'0', 1);
					}
					if (intval($user_access) === 1){
						$available[ $rate_id ] = $rate;
					}
				}

			// else if user is B2C, disable by B2C group options
			} else if (get_user_meta($user_id, 'b2bking_b2buser', true ) !== 'yes'){

				// if user override activated, check user access, else check group access
				$user_override = get_user_meta($user_id, 'b2bking_user_shipping_payment_methods_override', true);
				if ($user_override === 'manual'){
					// follow user rules

					// For each shipping method, check if it's available to the current user. Add it to available options
					foreach ( $rates as $rate_id => $rate ) {
						$user_access = get_user_meta($user_id, 'b2bking_user_shipping_method_'.$rate->method_id.$rate->instance_id, true);

						// enabled if metadata empty
						if (!metadata_exists('user', $user_id, 'b2bking_user_shipping_method_'.$rate->method_id.$rate->instance_id)){
							if (apply_filters('b2bking_payment_shipping_methods_enabled_default', true)){
								$user_access = 1;
							}
						}
						// UPS EXCEPTION
						if ($rate->method_id === 'wf_shipping_ups'){
							$user_access = get_user_meta($user_id,'b2bking_user_shipping_method_'.$rate->method_id.'0', true);
						}
						if (intval($user_access) === 1){
							$available[ $rate_id ] = $rate;
						}
					}

				} else {
					// For each shipping method, check if it's available. Add it to available options
					foreach ( $rates as $rate_id => $rate ) {
						$user_access = get_option('b2bking_b2c_users_shipping_method_'.$rate->method_id.$rate->instance_id, 1);

						
						// UPS EXCEPTION
						if ($rate->method_id === 'wf_shipping_ups'){
							$user_access = get_option('b2bking_b2c_users_shipping_method_'.$rate->method_id.'0', 1);
						}
						if (intval($user_access) === 1){
							$available[ $rate_id ] = $rate;
						}
					}
				}

				

			// else it means user is B2B so follow B2B rules
			} else {

				// if user override activated, check user access, else check group access
				$user_override = get_user_meta($user_id, 'b2bking_user_shipping_payment_methods_override', true);
				if ($user_override === 'manual'){
					// follow user rules

					// For each shipping method, check if it's available to the current user. Add it to available options
					foreach ( $rates as $rate_id => $rate ) {
						$user_access = get_user_meta($user_id, 'b2bking_user_shipping_method_'.$rate->method_id.$rate->instance_id, true);

						// enabled if metadata empty
						if (!metadata_exists('user', $user_id, 'b2bking_user_shipping_method_'.$rate->method_id.$rate->instance_id)){
							if (apply_filters('b2bking_payment_shipping_methods_enabled_default', true)){
								$user_access = 1;
							}
						}

						// UPS EXCEPTION
						if ($rate->method_id === 'wf_shipping_ups'){
							$user_access = get_user_meta($user_id,'b2bking_user_shipping_method_'.$rate->method_id.'0', true);
						}
						if (intval($user_access) === 1){
							$available[ $rate_id ] = $rate;
						}
					}

				} else {
					// follow group rules
					$currentusergroupidnr = b2bking()->get_user_group($user_id);

					// For each shipping method, check if it's available to the current user's group. Add it to available options
					foreach ( $rates as $rate_id => $rate ) {
						$group_access = get_post_meta($currentusergroupidnr, 'b2bking_group_shipping_method_'.$rate->method_id.$rate->instance_id, true);

						// enabled if metadata empty
						if (!metadata_exists('post', $currentusergroupidnr, 'b2bking_group_shipping_method_'.$rate->method_id.$rate->instance_id)){
							if (apply_filters('b2bking_payment_shipping_methods_enabled_default', true)){
								$group_access = 1;
							}
						}
						// UPS EXCEPTION
						if ($rate->method_id === 'wf_shipping_ups'){
							$group_access = get_post_meta($currentusergroupidnr, 'b2bking_group_shipping_method_'.$rate->method_id.'0', true);
						}
						if (intval($group_access) === 1){
							$available[ $rate_id ] = $rate;
						}
					}
				}
			}
			
		} else {

			// Older shipping mechanisms here, non-zone, for cases where needed

			$user_id = get_current_user_id();
			$user_id = b2bking()->get_top_parent_account($user_id);

			$available = array();
			// if user is guest, disable shipping methods by guest group options
			if (intval($user_id) === 0){

				// For each shipping method, check if it's available. Add it to available options
				foreach ( $rates as $rate_id => $rate ) {
					$user_access = get_option('b2bking_logged_out_users_shipping_method_'.$rate->method_id, 1);
					if (intval($user_access) === 1){
						$available[ $rate_id ] = $rate;
					}
				}

			// else if user is B2C, disable by B2C group options
			} else if (get_user_meta($user_id, 'b2bking_b2buser', true ) !== 'yes'){

				// For each shipping method, check if it's available. Add it to available options
				foreach ( $rates as $rate_id => $rate ) {
					$user_access = get_option('b2bking_b2c_users_shipping_method_'.$rate->method_id, 1);
					if (intval($user_access) === 1){
						$available[ $rate_id ] = $rate;
					}
				}

			// else it means user is B2B so follow B2B rules
			} else {

				// if user override activated, check user access, else check group access
				$user_override = get_user_meta($user_id, 'b2bking_user_shipping_payment_methods_override', true);
				if ($user_override === 'manual'){
					// follow user rules

					// For each shipping method, check if it's available to the current user. Add it to available options
					foreach ( $rates as $rate_id => $rate ) {
						$user_access = get_user_meta($user_id, 'b2bking_user_shipping_method_'.$rate->method_id, true);
						// enabled if metadata empty
						if (!metadata_exists('user', $user_id, 'b2bking_user_shipping_method_'.$rate->method_id)){
							if (apply_filters('b2bking_payment_shipping_methods_enabled_default', true)){
								$user_access = 1;
							}
						}
						if (intval($user_access) === 1){
							$available[ $rate_id ] = $rate;
						}
					}

				} else {
					// follow group rules
					$currentusergroupidnr = b2bking()->get_user_group($user_id);

					// For each shipping method, check if it's available to the current user's group. Add it to available options
					foreach ( $rates as $rate_id => $rate ) {
						$group_access = get_post_meta($currentusergroupidnr, 'b2bking_group_shipping_method_'.$rate->method_id, true);
						// enabled if metadata empty
						if (!metadata_exists('post', $currentusergroupidnr, 'b2bking_group_shipping_method_'.$rate->method_id)){
							if (apply_filters('b2bking_payment_shipping_methods_enabled_default', true)){
								$group_access = 1;
							}
						}
						if (intval($group_access) === 1){
							$available[ $rate_id ] = $rate;
						}
					}
				}
			}
		}

		// apply shipping method restriction dynamic rules

		// Get all dynamic rules that apply to the user or user's group
		$smpr_user_ids = get_option('b2bking_have_smpr_rules_list_ids', '');
		if (!empty($smpr_user_ids)){
			$smpr_user_ids = explode(',',$smpr_user_ids);
		} else {
			$smpr_user_ids = array();
		}
			
		$smpr_rules = b2bking()->get_global_data('b2bking_smpr_user_',false, get_current_user_id());

		if (!$smpr_rules){

			if (empty($smpr_user_ids)){
				$smpr_user_ids = array(98765432123456789);
			}

			$smpr_rules = get_posts([
				'post_type' => 'b2bking_rule',
				'post_status' => 'publish',
	    		'post__in' => $smpr_user_ids,
	    		'fields'        => 'ids', // Only get post IDs
	    	  	'numberposts' => -1
	    	]);

			$smpr_rules = b2bking()->filter_check_rules_apply_current_user($smpr_rules);

			b2bking()->set_global_data('b2bking_smpr_user', $smpr_rules, false, get_current_user_id());

		}
		
    	// if there are smpr rules
    	if (is_object( WC()->cart )){
	    	if (!empty($smpr_rules)){
	    		foreach ($available as $rate_id => $rate){

	    			// for each rule, check minimum, and find lowest minimum
	    			foreach ($smpr_rules as $rule){
	    				// check if rule applies to gateway
	    				$rule_shippingmethod = get_post_meta($rule, 'b2bking_rule_shippingmethod', true);

	    				// Add support for partial matches, e.g. virtual methods like Fedex plugin
	    				$partial_match = false;
	    				$rate_id_start = explode(':', $rate_id)[0];
	    				$rule_rate_id_start = explode(':', $rule_shippingmethod)[0];
	    				if ($rate_id_start === $rule_rate_id_start){
		    				if ($rate_id_start === 'ph_fedex_shipping_zone'){
		    					$partial_match = true;
		    				}
		    			}

	    				if ($rate_id === $rule_shippingmethod || $partial_match){
	    					// gateway applies, check further

    						// check the products in the applies to list, and see if any of them are in cart, products, categories, or total
    						$rule_applies = get_post_meta($rule, 'b2bking_rule_applies', true);
    						if ($rule_applies === 'cart_total'){
								unset($available[$rate_id]);
							} else if ($rule_applies === 'excluding_multiple_options'){
								// check that any product in cart is not in exclusion list
								$multiple_options = get_post_meta($rule, 'b2bking_rule_applies_multiple_options', true);
								$multiple_options_array = explode(',', $multiple_options);

								$has_non_excluded_product = false;

								if (is_object( WC()->cart )){
									foreach(WC()->cart->get_cart() as $cart_item){
										if (isset($cart_item['b2bking_is_offer_child'])){
											continue;
										}

										$current_product_id = $cart_item['product_id'];
										$variation_parent_id = 0;
										if (isset($cart_item['variation_id']) && intval($cart_item['variation_id']) !== 0){
											$current_product_id = $cart_item['variation_id'];
											$variation_parent_id = wp_get_post_parent_id($current_product_id);
										}

										$product_is_excluded = 'no';

										// check if product is in exclusion list
										if (in_array('product_'.$current_product_id, $multiple_options_array) || in_array('product_'.$variation_parent_id, $multiple_options_array)){
											$product_is_excluded = 'yes';
										} else {
											// try categories
											$taxonomies = b2bking()->get_taxonomies();
											foreach ($taxonomies as $tax_nickname => $tax_name){
												$current_product_categories = b2bking()->get_all_product_categories_taxonomies( $current_product_id, $tax_name );
												$parent_product_categories = b2bking()->get_all_product_categories_taxonomies( $variation_parent_id, $tax_name );
												$current_product_categories = array_merge($current_product_categories, $parent_product_categories);

												$current_product_belongsto_array = array_map(function($value) use ($tax_nickname) { return $tax_nickname.'_'.$value; }, $current_product_categories);

												foreach ($current_product_belongsto_array as $item_category){
													if (in_array($item_category, $multiple_options_array)){
														$product_is_excluded = 'yes';
														break 2;
													}
												}
											}
										}

										// check if product has any variations that are excluded
										// If current product is a variation, check parent's children; otherwise check current product's children
										$product_to_check_children = ($variation_parent_id !== 0) ? $variation_parent_id : $current_product_id;
										$productobjj = wc_get_product($product_to_check_children);
										if ($productobjj){
											$children_ids = $productobjj->get_children();
											foreach ($children_ids as $child_id){
												if (in_array('product_'.$child_id, $multiple_options_array)){
													$product_is_excluded = 'yes';
													break;
												}
											}
										}

										if ($product_is_excluded === 'no'){
											// product is not excluded, therefore rule applies
											$has_non_excluded_product = true;
											break;
										}
									}
								}

								if ($has_non_excluded_product){
									unset($available[$rate_id]);
								}
							} else {
								$explode = explode('_', $rule_applies);
								if ($explode[0] === 'product'){
									if (b2bking()->has_id_in_cart($explode[1])){
										unset($available[$rate_id]);
									}
								}

								if ($explode[0] === 'category'){
									if (b2bking()->has_id_in_cart($explode[1], 'category')){
										unset($available[$rate_id]);
									}
								}

								if ($explode[0] === 'multiple'){
									$original_multiple = get_post_meta( $rule, 'b2bking_rule_applies_multiple_options', true);

									$original_multiple = explode(',', $original_multiple);
									foreach ($original_multiple as $multiple_element){
										$multiple_element = trim($multiple_element);
										if (!empty($multiple_element)){
											$appliestemp = explode('_',$multiple_element);
											if ($appliestemp[0] === 'product'){
												if (b2bking()->has_id_in_cart($appliestemp[1])){
													unset($available[$rate_id]);
												}
											}

											if ($appliestemp[0] === 'category'){
												if (b2bking()->has_id_in_cart($appliestemp[1],'category')){
													unset($available[$rate_id]);
												}
											}
										}
									}

								}
							}

	    				}
	    			} 
	    		}
	    	}
	    }

		return $available;

	}


	function validate_vat_button_blocks_checkout() {

		if (!is_checkout()){
			//return;
		}

		if (intval(get_option('b2bking_validate_vat_button_checkout_setting', 0)) === 1){
			global $b2bking_has_shown_validate_vat;
			if ($b2bking_has_shown_validate_vat !== 'yes'){

				$textvat = esc_html__('Validate VAT','b2bking');
				$disabled = '';
				if (isset($_COOKIE['b2bking_validated_vat_number'])){
					$textvat = esc_html__('VAT Validated Successfully', 'b2bking');
					$disabled = 'disabled';
				}

				?>
				<script type="text/javascript">
					document.addEventListener('DOMContentLoaded', function() {
				        
				        function addContentAfterBillingCheckbox() {
				            // Target the specific "use address for billing" element
				            var billingCheckbox = document.querySelector('.wc-block-checkout__use-address-for-billing');
				            
				            if (billingCheckbox && !document.getElementById('custom-message-after-billing')) {
				                var customDiv = document.createElement('div');
				                customDiv.id = 'custom-message-after-billing';
				                customDiv.innerHTML = '<button type="button" id="b2bking_checkout_registration_validate_vat_button" <?php echo $disabled; ?>><?php echo esc_html($textvat); ?></button>';
				                
				                // Insert right after the billing checkbox element
				                billingCheckbox.parentNode.insertBefore(customDiv, billingCheckbox.nextSibling);
				            }
				        }
				        
				        // Try to add content immediately
				        addContentAfterBillingCheckbox();
				        
				        // Also try after delays for dynamic content
				        setTimeout(addContentAfterBillingCheckbox, 1000);
				        setTimeout(addContentAfterBillingCheckbox, 3000);
				        
				        // Watch for changes in the checkout area
				        var checkoutForm = document.querySelector('form.wc-block-checkout__form');
				        if (checkoutForm) {
				            var observer = new MutationObserver(function(mutations) {
				                mutations.forEach(function(mutation) {
				                    if (mutation.type === 'childList') {
				                        addContentAfterBillingCheckbox();
				                    }
				                });
				            });
				            
				            observer.observe(checkoutForm, {
				                childList: true,
				                subtree: true
				            });
				        }
				    });
				</script>
				<?php

				$custom_fields = get_posts([
				    		'post_type' => 'b2bking_custom_field',
				    	  	'post_status' => 'publish',
				    	  	'numberposts' => -1,
			    	  	    'orderby' => 'menu_order',
			    	  	    'order' => 'ASC',
				    	  	'meta_query'=> array(
				    	  		'relation' => 'AND',
				                array(
			                        'key' => 'b2bking_custom_field_status',
			                        'value' => 1
				                ),
				                array(
				                	'relation' => 'OR',
	        		                array(
	        	                        'key' => 'b2bking_custom_field_billing_connection',
	        	                        'value' => 'none'
	        		                ),
	        		                array(
	        	                        'key' => 'b2bking_custom_field_billing_connection',
	        	                        'value' => 'billing_vat'
	        		                ),
	        		            ),			               
			            	)
				    	]);
				if (!empty($custom_fields)){
					echo '<input type="hidden" id="b2bking_vat_number_registration_field_number" name="b2bking_vat_number_registration_field_number" value="'.esc_attr($custom_fields[0]->ID).'">';
				}


				$b2bking_has_shown_validate_vat = 'yes';
			}
		}
	    
	}

	function b2bking_update_order_data( $order_id ) {

		$order = wc_get_order($order_id);
		$payment_method_title     = $order->get_payment_method_title();
		$new_payment_method_title = preg_replace( '/<small>.*<\/small>/', '', $payment_method_title );

		// save excl tax value for future emails
		$tax_display_cart = get_option('woocommerce_tax_display_cart');
		$order->update_meta_data( 'b2bking_tax_display_cart', $tax_display_cart ); // val = incl or excl

		// Save the new payment method title.
		$order->set_payment_method_title($new_payment_method_title);

		// add b2b marker if b2b order
		$customer_id = $order->get_customer_id();
		$is_b2b = get_user_meta($customer_id,'b2bking_b2buser', true);
		if ($is_b2b === 'yes'){
			$order->update_meta_data( 'b2bking_is_b2b_order', 'yes' );
			// set group ID
			$order->update_meta_data( 'b2bking_b2b_group', get_user_meta($customer_id,'b2bking_customergroup', true) );
		} else {
			$order->update_meta_data( 'b2bking_is_b2b_order', 'no' );
		}

		// vat number custom order meta
		$vat_fields = get_posts([
    		'post_type' => 'b2bking_custom_field',
    	  	'post_status' => 'publish',
    	  	'numberposts' => -1,
	  	    'orderby' => 'menu_order',
	  	    'order' => 'ASC',
	  	    'fields' => 'ids',
    	  	'meta_query'=> array(
    	  		'relation' => 'AND',
                array(
                    'key' => 'b2bking_custom_field_status',
                    'value' => 1
                ),
                array(
                	'relation' => 'OR',
	                array(
                        'key' => 'b2bking_custom_field_billing_connection',
                        'value' => 'billing_vat'
	                ),
	            )
        	)
    	]);
		foreach ($vat_fields as $custom_field){
			$val = $order->get_meta('b2bking_custom_field_'.$custom_field);
			if (!empty($val)){
				$order->update_meta_data('vat_number', $val);
			}
		}

		$order->update_meta_data( 'b2bking_main_account_user_id', b2bking()->find_first_parent_account($customer_id));

		$order->save();
	}


	function b2bking_payment_method_discounts(WC_Cart $cart ){

		if (is_checkout() || true){

			$user_id = get_current_user_id();
			$user_id = b2bking()->get_top_parent_account($user_id);
			$currentusergroupidnr = b2bking()->get_user_group($user_id);

			$array_who_multiple = array(
		                'relation' => 'OR',
		                array(
		                    'key' => 'b2bking_rule_who_multiple_options',
		                    'value' => 'group_'.$currentusergroupidnr,
		                	'compare' => 'LIKE'
		                ),
		                array(
		                    'key' => 'b2bking_rule_who_multiple_options',
		                    'value' => 'user_'.$user_id,
		                    'compare' => 'LIKE'
		                ),
		            );

			if ($user_id !== 0){
				array_push($array_who_multiple, array(
		            'key' => 'b2bking_rule_who_multiple_options',
		            'value' => 'all_registered',
		            'compare' => 'LIKE'
		        ));

				// add rules that apply to all registered b2b/b2c users
				$user_is_b2b = get_user_meta($user_id, 'b2bking_b2buser', true);
				if ($user_is_b2b === 'yes'){
					array_push($array_who_multiple, array(
		                'key' => 'b2bking_rule_who_multiple_options',
		                'value' => 'everyone_registered_b2b',
		                'compare' => 'LIKE'
		            ));
				} else if ($user_is_b2b === 'no'){
					array_push($array_who_multiple, array(
		                'key' => 'b2bking_rule_who_multiple_options',
		                'value' => 'everyone_registered_b2c',
		                'compare' => 'LIKE'
		            ));
				}
			}

			$array_who = array(
		        'relation' => 'OR',
		        array(
		            'key' => 'b2bking_rule_who',
		            'value' => 'group_'.$currentusergroupidnr
		        ),
		        array(
		            'key' => 'b2bking_rule_who',
		            'value' => 'user_'.$user_id
		        ),
		        array(
		            'relation' => 'AND',
		            array(
		                'key' => 'b2bking_rule_who',
		                'value' => 'multiple_options'
		            ),
		            $array_who_multiple
		        ),
		    );
			// if user is registered, also select rules that apply to all registered users
			if ($user_id !== 0){
				array_push($array_who, array(
		                        'key' => 'b2bking_rule_who',
		                        'value' => 'all_registered'
		                    ));

				// add rules that apply to all registered b2b/b2c users
				$user_is_b2b = get_user_meta($user_id, 'b2bking_b2buser', true);
				if ($user_is_b2b === 'yes'){
					array_push($array_who, array(
		                        'key' => 'b2bking_rule_who',
		                        'value' => 'everyone_registered_b2b'
		                    ));
				} else if ($user_is_b2b === 'no'){
					array_push($array_who, array(
		                        'key' => 'b2bking_rule_who',
		                        'value' => 'everyone_registered_b2c'
		                    ));
				}
			}

			// Get all dynamic rules that apply to the user or user's group
			$pmd_user_ids = get_option('b2bking_have_pmd_rules_list_ids', '');
			if (!empty($pmd_user_ids)){
				$pmd_user_ids = explode(',',$pmd_user_ids);
			} else {
				$pmd_user_ids = array();
			}
				
			//$pmd_rules = get_transient('b2bking_pmd_user_'.get_current_user_id());
			$pmd_rules = b2bking()->get_global_data('b2bking_pmd_user',false, get_current_user_id());

			if (!$pmd_rules){

				if (empty($pmd_user_ids)){
					$pmd_user_ids = array(98765432123456789);
				}

				if (apply_filters('b2bking_use_simple_query_system', false)){
					$pmd_rules = get_posts([
						'post_type' => 'b2bking_rule',
						'post_status' => 'publish',
			    		'post__in' => $pmd_user_ids,
			    		'fields'        => 'ids', // Only get post IDs
			    	  	'numberposts' => -1
			    	]);
					
					$pmd_rules = b2bking()->filter_check_rules_apply_current_user($pmd_rules);

				} else {
					$pmd_rules = get_posts([
						'post_type' => 'b2bking_rule',
						'post_status' => 'publish',
			    		'post__in' => $pmd_user_ids,
			    		'fields'        => 'ids', // Only get post IDs
			    	  	'numberposts' => -1,
			    	  	'meta_query'=> array(
			                $array_who,
			            )
			    	]);
				}

				
				b2bking()->set_global_data('b2bking_pmd_user', $pmd_rules, false, get_current_user_id());

			}

			// if there are pmd rules
			$pmd_rules = apply_filters('b2bking_pmd_rules_before_apply', $pmd_rules);
			
			if (!empty($pmd_rules)){
				// get current method selected for payments
				$gateway_id = WC()->session->get('chosen_payment_method');
				$maximum = 'no';
				$percentamount_used = '';
				// if there is a maximum, find the biggest one
				foreach ($pmd_rules as $rule){
					// check if rule applies to gateway
					$rule_paymentmethod = get_post_meta($rule, 'b2bking_rule_paymentmethod', true);
					if ($gateway_id === $rule_paymentmethod || apply_filters('b2bking_rule_paymentmethod_applies', false, $gateway_id, $rule_paymentmethod)){
						// gateway applies, check further
						// largest maximum has to be given. E.g. regular users 10%, VIP 50%
						$percentamount = get_post_meta($rule, 'b2bking_rule_paymentmethod_percentamount', true);
						$discountsurcharge = get_post_meta($rule, 'b2bking_rule_paymentmethod_discountsurcharge', true);

						$maximumrule = get_post_meta($rule, 'b2bking_rule_howmuch', true);
						if ($discountsurcharge === 'surcharge'){
							$maximumrule = -1 * abs($maximumrule);
						}

						if ($percentamount === 'percentage'){
							$cart_total = apply_filters('b2bking_payment_method_discount_total', WC()->cart->get_subtotal());
							$maximumrule = $cart_total*$maximumrule/100;
						}

						if ($maximum === 'no'){
							$maximum = $maximumrule;

							$percentamount_used = get_post_meta($rule, 'b2bking_rule_howmuch', true);
							if ($discountsurcharge === 'surcharge'){
								$percentamount_used = -1 * abs($percentamount_used);
							}

						} else if (floatval($maximumrule) > floatval($maximum)){
							$maximum = $maximumrule;
							
							$percentamount_used = get_post_meta($rule, 'b2bking_rule_howmuch', true);
							if ($discountsurcharge === 'surcharge'){
								$percentamount_used = -1 * abs($percentamount_used);
							}
						}
					}
				} 

				if ($maximum !== 'no'){
					if (is_object( WC()->cart )){
						// find method title
						$method_title = esc_html__('Payment method', 'b2bking');
						$payment_methods = WC()->payment_gateways->payment_gateways();
						foreach ($payment_methods as $payment_method){
							if ($payment_method->id === $gateway_id){
								if (isset($payment_method->title) && !empty($payment_method->title)){
									$method_title = esc_html($payment_method->title); 
								} else {
									$method_title = $payment_method->get_title();
								}
							}
						}
						$method_title = strip_tags($method_title);

						$text_after = esc_html__('discount', 'b2bking');
						if (floatval($maximum) < 0){
							$text_after = esc_html__('surcharge','b2bking');
						}
						$text_after = apply_filters('b2bking_text_payment_method_discount', $text_after, $percentamount_used);
						
						// add surcharge / discount suffix if it doesn't already exist
						if (strpos($method_title, $text_after) === false) {
							$text_final = apply_filters('b2bking_text_payment_method_discount_final', $method_title.' '.$text_after);
						} else {
							$text_final = apply_filters('b2bking_text_payment_method_discount_final', $method_title);
						}
						
						$cart->add_fee( $text_final, -$maximum, apply_filters('b2bking_paymentmethod_fee_taxable', false, $method_title));
					}
				}

			} else {
				// do nothing since there are no applicable rules
			}

		}



	}


	function unavailable_product_display_message() {
	    global $product;

	    if(! $product->is_purchasable() ){
	        echo '<p style="color:#e00000;">' . esc_html__("While there is an offer in cart, you cannot add other products. To add this product to cart, first remove the existing offer.",'b2bking') . '</p>';
	    }
	}

	public static function unavailable_product_display_message_products() {
	    global $product;

	    $product_id = $product->get_id();
	    $response = b2bking()->get_applicable_rules('quotes_products', $product_id);

	    $haverules = 'no';
	    if ($response !== 'norules'){
	    	$rules = $response[0];
	    	if (!empty($rules)){
	    		$haverules = 'yes';
	    	}
	    }

	    if ($haverules === 'no'){
	        echo '<p style="color:#e00000;">' . esc_html__("You cannot add this product to cart while you are working on a quote request. Please empty the basket first.",'b2bking') . '</p>';
	    }
	}

	public static function unavailable_product_display_message_products_quote() {
	    global $product;

	    $product_id = $product->get_id();
	    $response = b2bking()->get_applicable_rules('quotes_products', $product_id);

	    $haverules = 'no';
	    if ($response !== 'norules'){
	    	$rules = $response[0];
	    	if (!empty($rules)){
	    		$haverules = 'yes';
	    	}
	    }

	    if ($haverules === 'yes'){
	        echo '<p style="color:#e00000;">' . esc_html__("This product cannot be purchased directly. To request a quote for this product, please empty your cart first.",'b2bking') . '</p>';
	    }
	}

	// Change product price in cart for offers
	function b2bking_offer_change_price_cart( $_cart ){
		// loop through the cart_contents
	    foreach ( $_cart->cart_contents as $cart_item_key => $value ) {
	    	// if product is offer
	    	if (array_key_exists("b2bking_numberofproducts",$value)){
	    		// check that all items are in stock, otherwise, remove product from cart
	    		if (isset($value['b2bking_products_stock'])){
	    			$productsstock = explode(';',$value['b2bking_products_stock']);
	    			foreach ($productsstock as $prodstock){
	    				if (!empty($prodstock)){
		    				$prodidqty = explode(':', $prodstock);
		    				$prodid = $prodidqty[0];
		    				$prodqty = $prodidqty[1];

		    				$prod_temp = wc_get_product($prodid);

		    				if ($prod_temp){
		            			$stockqty = $prod_temp->get_stock_quantity();
					    		if ( ! $prod_temp->get_manage_stock() ){
					    			$stockqty = 999999999;
					    		} else {
		    						// if backorders, same 
		    						if ('yes' === $prod_temp->get_backorders() || 'notify' === $prod_temp->get_backorders()){
		    							$stockqty = 999999999;
		    						}
		    					}

		    					if ($prodqty > $stockqty){
		    						// remove offer from cart
		    						WC()->cart->remove_cart_item( $cart_item_key );
		    						wc_add_notice(esc_html__('An offer was removed from your cart because one if its products is no longer in stock.','b2bking'), 'error');
		    					}
		    				}
	            			

	    					
	    				}
	    				
	    			}
	    		}

		    	if ($value['b2bking_numberofproducts'] !== NULL){
			    	$bundleprice = 0;
			    	$numberofproducts = $value['b2bking_numberofproducts'];	    	
			    	for ($i=1;$i<=$numberofproducts;$i++){
			    		$bundleprice += intval($value['b2bking_product_'.$i.'_quantity'])*floatval($value['b2bking_product_'.$i.'_price']);
			    	}       
		            $value['data']->set_price($bundleprice);
	        	}
        	}
        }
	}

	function b2bking_credit_change_price_cart( $_cart ){
		// loop through the cart_contents
	    foreach ( $_cart->cart_contents as $cart_item_key => $value ) {
	    	
        	// if product is credit
        	if (array_key_exists("b2bking_credit_amount",$value)){
        		$value['data']->set_price($value['b2bking_credit_amount']);
        	}
        }
	}



	// Change product price in minicart for offers
	function b2bking_offer_change_price_minicart( $price, $cart_item, $cart_item_key ){
		// if not offer, skip
		$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
		if (intval($cart_item['product_id']) !== $offer_id){ 
			return $price;
		}

    	// if product is offer
    	if (array_key_exists("b2bking_numberofproducts",$cart_item)){
	    	if ($cart_item['b2bking_numberofproducts'] !== NULL){
		    	$bundleprice = 0;
		    	$numberofproducts = $cart_item['b2bking_numberofproducts'];	    	
		    	for ($i=1;$i<=$numberofproducts;$i++){
		    		$bundleprice += intval($cart_item['b2bking_product_'.$i.'_quantity'])*floatval($cart_item['b2bking_product_'.$i.'_price']);
		    	}

		    	// adjust bundle price for tax
		    	// get offer product
		    	$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
		    	$offer_product = wc_get_product($offer_id);

		    	if (get_option('woocommerce_calc_taxes', 'no') === 'yes'){
		    		if( wc_prices_include_tax() && ('incl' !== get_option( 'woocommerce_tax_display_shop') || WC()->customer->is_vat_exempt())) {
		    			// if prices are entered including tax, but display is without tax, remove tax 
		    			// get tax rate for the offer product
		    			$tax_rates = WC_Tax::get_base_tax_rates( $offer_product->get_tax_class( 'unfiltered' ) ); 
		    			$taxes = WC_Tax::calc_tax( $bundleprice, $tax_rates, true ); 
		    			$bundleprice = WC_Tax::round( $bundleprice - array_sum( $taxes ) ); 

		    		} else if ( !wc_prices_include_tax() && ('incl' === get_option( 'woocommerce_tax_display_shop') && !WC()->customer->is_vat_exempt())){
		    			// if prices are entered excluding tax, but display is with tax, add tax
		    			$tax_rates = WC_Tax::get_rates( $offer_product->get_tax_class() );
		    			$taxes     = WC_Tax::calc_tax( $bundleprice, $tax_rates, false );
		    			$bundleprice = WC_Tax::round( $bundleprice + array_sum( $taxes ) );
		    		} else {
		    			// no adjustment
		    		}
		    	}
		    	

	            return wc_price($bundleprice);
        	}
    	}
	}

	// Change product price in minicart for credit
	function b2bking_credit_change_price_minicart( $price, $cart_item, $cart_item_key ){
		// if not offer, skip
		$credit_id = intval(get_option('b2bking_credit_product_id_setting', 0));
		if (intval($cart_item['product_id']) !== $credit_id ){ 
			return $price;
		}

    	// if product is offer
    	if (array_key_exists("b2bking_credit_amount",$cart_item)){
	        return wc_price($cart_item['b2bking_credit_amount']);
    	}
	}

	function b2bking_hide_offer_post($query) {
		$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
		$credit_id = intval(get_option('b2bking_credit_product_id_setting', 0));
		$mkcredit_id = intval(get_option('marketking_credit_product_id_setting', 0));

		$current_exclude = $query->query_vars['post__not_in'];
		if (is_array($current_exclude)){
			$query->query_vars['post__not_in'] = array_merge(array($offer_id, $credit_id, $mkcredit_id), $current_exclude); 
		} else {
        	$query->query_vars['post__not_in'] = array($offer_id, $credit_id, $mkcredit_id);
    	}
	}	

	// Add item metadata to order
	function b2bking_add_item_metadata_to_order( $item, $cart_item_key, $values, $order ) {

		if (isset($values['b2bking_is_offer_child'])){
			$item->update_meta_data( '_b2bking_is_offer_child', 'yes');
		}

		if (isset($values['b2bking_offer_name'])){

			$offerid = $values['b2bking_offer_id'];

			if (isset($values['b2bking_products_stock'])){
				 $item->update_meta_data( '_b2bkingstockinfo', esc_html($values['b2bking_products_stock']) );
			}
			    
		    $item->update_meta_data( esc_html__('Offer name','b2bking'), esc_html($values['b2bking_offer_name']) );
		    // add products to details string
		    $details = '';
		    for ($i=1; $i<=intval($values['b2bking_numberofproducts']); $i++){

		    	if (isset($values['b2bking_product_'.$i.'stock'])){

		    	}

		    	$unit_price_display = $values['b2bking_product_'.$i.'_price'];
		    	// adjust for tax
		    	// get offer product
		    	$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
		    	$offer_product = wc_get_product($offer_id);
		    	if (get_option('woocommerce_calc_taxes', 'no') === 'yes'){

			    	if( wc_prices_include_tax() && ('incl' !== get_option( 'woocommerce_tax_display_shop') || WC()->customer->is_vat_exempt())) {
			    		// if prices are entered including tax, but display is without tax, remove tax 
			    		// get tax rate for the offer product
			    		$tax_rates = WC_Tax::get_base_tax_rates( $offer_product->get_tax_class( 'unfiltered' ) ); 
			    		$taxes = WC_Tax::calc_tax( $unit_price_display, $tax_rates, true ); 
			    		$unit_price_display = WC_Tax::round( $unit_price_display - array_sum( $taxes ) ); 

			    	} else if ( !wc_prices_include_tax() && ('incl' === get_option( 'woocommerce_tax_display_shop') && !WC()->customer->is_vat_exempt())){
			    		// if prices are entered excluding tax, but display is with tax, add tax
			    		$tax_rates = WC_Tax::get_rates( $offer_product->get_tax_class() );
			    		$taxes     = WC_Tax::calc_tax( $unit_price_display, $tax_rates, false );
			    		$unit_price_display = WC_Tax::round( $unit_price_display + array_sum( $taxes ) );
			    	} else {
			    		// no adjustment
			    	}
			    }


		    	$details .= $values['b2bking_product_'.$i.'_name'].' - '.esc_html__('Qty','b2bking').': '.$values['b2bking_product_'.$i.'_quantity'].' - '.esc_html__('Unit Price','b2bking').': '.round($unit_price_display, apply_filters('b2bking_rounding_precision', wc_get_price_decimals()) ).' <br />';
		    }

		    $item->update_meta_data( esc_html__('Details','b2bking'), $details);
		    $item->update_meta_data( '_offer_id', $offerid);
	    }
	}

	function b2bking_display_metadata_cart($product_name, $values, $cart_item_key ) {

		if (intval(get_option( 'b2bking_offer_use_products_setting', 1 )) === 1){
			global ${'b2bking_has_run_cartoffername_'.$cart_item_key};
			if (${'b2bking_has_run_cartoffername_'.$cart_item_key} !== true){
				${'b2bking_has_run_cartoffername_'.$cart_item_key} = false;
			}
			// User is guest, or multisite option is enabled and user should be treated as guest
			if (${'b2bking_has_run_cartoffername_'.$cart_item_key} === false){

				// If product is an offer
				if (!empty($values['b2bking_numberofproducts'])){
					return $product_name.'<br />'.$values['b2bking_offer_name'];
				}
			}
		}

		global ${'b2bking_has_run_cartoffername_'.$cart_item_key};
		if (${'b2bking_has_run_cartoffername_'.$cart_item_key} !== true){
			${'b2bking_has_run_cartoffername_'.$cart_item_key} = false;
		}
		// User is guest, or multisite option is enabled and user should be treated as guest
		if (${'b2bking_has_run_cartoffername_'.$cart_item_key} === false){

			// If product is an offer
			if (!empty($values['b2bking_numberofproducts'])){
				$details = '';
				for ($i=1; $i<=intval($values['b2bking_numberofproducts']); $i++){
					// adjust unit price for tax
					$unit_price_display = $values['b2bking_product_'.$i.'_price'];
					// get offer product
					$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
					$offer_product = wc_get_product($offer_id);
					if (get_option('woocommerce_calc_taxes', 'no') === 'yes'){

						if( wc_prices_include_tax() && ('incl' !== get_option( 'woocommerce_tax_display_shop') || WC()->customer->is_vat_exempt())) {
							// if prices are entered including tax, but display is without tax, remove tax 
							// get tax rate for the offer product
							$tax_rates = WC_Tax::get_base_tax_rates( $offer_product->get_tax_class( 'unfiltered' ) ); 
							$taxes = WC_Tax::calc_tax( $unit_price_display, $tax_rates, true ); 
							$unit_price_display = WC_Tax::round( $unit_price_display - array_sum( $taxes ) ); 

						} else if ( !wc_prices_include_tax() && ('incl' === get_option( 'woocommerce_tax_display_shop') && !WC()->customer->is_vat_exempt())){
							// if prices are entered excluding tax, but display is with tax, add tax
							$tax_rates = WC_Tax::get_rates( $offer_product->get_tax_class() );
							$taxes     = WC_Tax::calc_tax( $unit_price_display, $tax_rates, false );
							$unit_price_display = WC_Tax::round( $unit_price_display + array_sum( $taxes ) );
						} else {
							// no adjustment
						}
					}

					$details .= $values['b2bking_product_'.$i.'_name'].' - '.esc_html__('Qty','b2bking').': '.$values['b2bking_product_'.$i.'_quantity'].' - '.esc_html__('Unit Price','b2bking').': '.round($unit_price_display, apply_filters('b2bking_rounding_precision', wc_get_price_decimals()) ).' <br />';
				}

				${'b2bking_has_run_cartoffername_'.$cart_item_key} = true;
				return $product_name.'<br />'.$values['b2bking_offer_name'].'<br /><strong>'.esc_html__('Details','b2bking').':</strong><br />'.$details;
			} else {

				${'b2bking_has_run_cartoffername_'.$cart_item_key} = true;
				return $product_name;
			}
		}

		return $product_name;


	}


	// Add custom items to My account WooCommerce user menu
	function b2bking_my_account_custom_items( $items ) {
		// Get current user
		$user_id = get_current_user_id();
		$account_type = get_user_meta($user_id,'b2bking_account_type', true);

    	$user_id = b2bking()->get_top_parent_account($user_id);

    	if (!is_array($items)){
    		$items = array();
    	}

    	$i = 2;
		
		// Add conversations
		if (intval(get_option('b2bking_enable_conversations_setting', 1)) === 1){
	    	$items = array_slice($items, 0, $i, true) +
	    	    array(get_option('b2bking_conversations_endpoint_setting','conversations') => apply_filters('b2bking_conversations_my_account_title_sidebar', esc_html__( 'Conversations', 'b2bking' ))) + 
	    	    array_slice($items, $i, count($items)-$i, true);

    	    $i++;
    	}

    	// Add offers
    	if (intval(get_option('b2bking_enable_offers_setting', 1)) === 1){
	    	$items = array_slice($items, 0, $i, true) +
	    	    array(get_option('b2bking_offers_endpoint_setting','offers') => apply_filters('b2bking_offers_my_account_title_sidebar',esc_html__( 'Offers', 'b2bking' ))) + 
	    	    array_slice($items, $i, count($items)-$i, true);
    	    $i++;
	    }

    	//if (get_transient('b2bking_replace_prices_quote_user_'.$user_id) !== 'yes'){

		    // Add purchase lists
		    if (intval(get_option('b2bking_enable_purchase_lists_setting', 1)) === 1){
			    $items = array_slice($items, 0, $i, true) +
			        array(get_option('b2bking_purchaselists_endpoint_setting','purchase-lists') => apply_filters('b2bking_purchaselists_my_account_title_sidebar', esc_html__( 'Purchase lists', 'b2bking' ))) + 
			        array_slice($items, $i, count($items)-$i, true);
			    $i++;
			}	  	    

	    	// Add bulk order
	    	if (intval(get_option('b2bking_enable_bulk_order_form_setting', 1)) === 1){
		    	$items = array_slice($items, 0, $i, true) +
		    	    array(get_option('b2bking_bulkorder_endpoint_setting','bulkorder') => apply_filters('b2bking_bulkorder_my_account_title_sidebar', esc_html__( 'Bulk order', 'b2bking' ))) + 
		    	    array_slice($items, $i, count($items)-$i, true);
		    	$i++;	    
		    }

		//}

    	// Add subaccounts
    	if (intval(get_option('b2bking_enable_subaccounts_setting', 1)) === 1){
    		// only show if current account is not itself a subaccount
    		if ($account_type !== 'subaccount' or apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
		    	$items = array_slice($items, 0, $i, true) +
		    	    array(get_option('b2bking_subaccounts_endpoint_setting','subaccounts') => apply_filters('b2bking_subaccounts_my_account_title_sidebar', esc_html__( 'Subaccounts', 'b2bking' ))) + 
		    	    array_slice($items, $i, count($items)-$i, true);	
		    	$i++;
		    }
    	}

	    return apply_filters('b2bking_my_account_menu_items', $items);

	}

	// Add custom endpoints
	function b2bking_custom_endpoints() {
		
		// Add conversations endpoints
		if (intval(get_option('b2bking_enable_conversations_setting', 1)) === 1){
			add_rewrite_endpoint( get_option('b2bking_conversations_endpoint_setting','conversations'), EP_ROOT | EP_PAGES | EP_PERMALINK );
			add_rewrite_endpoint( get_option('b2bking_conversation_endpoint_setting','conversation'), EP_ROOT | EP_PAGES | EP_PERMALINK );
		}
		// Add offers endpoint
		if (intval(get_option('b2bking_enable_offers_setting', 1)) === 1){
			add_rewrite_endpoint( get_option('b2bking_offers_endpoint_setting','offers'), EP_ROOT | EP_PAGES | EP_PERMALINK );
		}
		// Bulk order form endpoint
		if (intval(get_option('b2bking_enable_bulk_order_form_setting', 1)) === 1){
			add_rewrite_endpoint( get_option('b2bking_bulkorder_endpoint_setting','bulkorder'), EP_ROOT | EP_PAGES | EP_PERMALINK );
		}
		// Subaccounts 
		if (intval(get_option('b2bking_enable_subaccounts_setting', 1)) === 1){
			// only show if current account is not itself a subaccount
			$account_type = get_user_meta(get_current_user_id(),'b2bking_account_type', true);
			if ($account_type !== 'subaccount'){
				add_rewrite_endpoint( get_option('b2bking_subaccounts_endpoint_setting','subaccounts'), EP_ROOT | EP_PAGES | EP_PERMALINK );
				add_rewrite_endpoint( get_option('b2bking_subaccount_endpoint_setting','subaccount'), EP_ROOT | EP_PAGES | EP_PERMALINK );
			}
		}
		// Purchase Lists
		if (intval(get_option('b2bking_enable_purchase_lists_setting', 1)) === 1){
			add_rewrite_endpoint( get_option('b2bking_purchaselists_endpoint_setting','purchase-lists'), EP_ROOT | EP_PAGES | EP_PERMALINK );
			add_rewrite_endpoint( get_option('b2bking_purchaselist_endpoint_setting','purchase-list'), EP_ROOT | EP_PAGES | EP_PERMALINK );
			add_rewrite_endpoint( 'new-list', EP_ROOT | EP_PAGES | EP_PERMALINK );
		}

		do_action('b2bking_extend_endpoints');


	}

	

	function b2bking_add_query_vars_filter( $vars ) {
	  $vars[] = "id";
	  return $vars;
	}

	function b2bking_redirects_my_account_default(){

		if (isset($_SERVER['HTTPS']) &&
		        ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === 1) ||
		        isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
		        $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
		        $protocol = 'https://';
		        }
		        else {
		        $protocol = 'http://';
		    }

	    $currenturl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
	    $currenturl_relative = wp_make_link_relative(remove_query_arg('id',$currenturl));
	    $idqueryvar = get_query_var('id');

	    $bulkorderurl = wp_make_link_relative(wc_get_endpoint_url(get_option('b2bking_bulkorder_endpoint_setting','bulkorder')));
	    $bulkorderurlbuilt = wp_make_link_relative(get_permalink( get_option('woocommerce_myaccount_page_id') )).get_option('b2bking_bulkorder_endpoint_setting','bulkorder').'/';

	    $conversationsurl = wp_make_link_relative(wc_get_endpoint_url(get_option('b2bking_conversations_endpoint_setting','conversations')));
	    $conversationsurlbuilt = wp_make_link_relative(get_permalink( get_option('woocommerce_myaccount_page_id') )).get_option('b2bking_conversations_endpoint_setting','conversations').'/';

	    $conversationurl = apply_filters('b2bking_conversation_url', wp_make_link_relative(wc_get_endpoint_url(get_option('b2bking_conversation_endpoint_setting','conversation'))));
	    $conversationurlbuilt = wp_make_link_relative(get_permalink( get_option('woocommerce_myaccount_page_id') )).get_option('b2bking_conversation_endpoint_setting','conversation').'/';

	    $offersurl = wp_make_link_relative(wc_get_endpoint_url(get_option('b2bking_offers_endpoint_setting','offers')));
	    $offersurlbuilt = wp_make_link_relative(get_permalink( get_option('woocommerce_myaccount_page_id') )).get_option('b2bking_offers_endpoint_setting','offers').'/';

	    $subaccountsurl = wp_make_link_relative(wc_get_endpoint_url(get_option('b2bking_subaccounts_endpoint_setting','subaccounts')));
	    $subaccountsurlbuilt = wp_make_link_relative(get_permalink( get_option('woocommerce_myaccount_page_id') )).get_option('b2bking_subaccounts_endpoint_setting','subaccounts').'/';

	    $subaccounturl = wp_make_link_relative(wc_get_endpoint_url(get_option('b2bking_subaccount_endpoint_setting','subaccount')));
	    $subaccounturlbuilt = wp_make_link_relative(get_permalink( get_option('woocommerce_myaccount_page_id') )).get_option('b2bking_subaccount_endpoint_setting','subaccount').'/';

	    $purchaselistssurl = wp_make_link_relative(wc_get_endpoint_url(get_option('b2bking_purchaselists_endpoint_setting','purchase-lists')));
	    $purchaselistssurlbuilt = wp_make_link_relative(get_permalink( get_option('woocommerce_myaccount_page_id') )).get_option('b2bking_purchaselists_endpoint_setting','purchase-lists').'/';

	    $purchaselistssurlnew = wp_make_link_relative(wc_get_endpoint_url('new-list'));
	    $purchaselistssurlbuiltnew = wp_make_link_relative(get_permalink( get_option('woocommerce_myaccount_page_id') )).'new-list'.'/';

	    $purchaselisturl = wp_make_link_relative(wc_get_endpoint_url(get_option('b2bking_purchaselist_endpoint_setting','purchase-list')));
	    $purchaselisturlbuilt = wp_make_link_relative(get_permalink( get_option('woocommerce_myaccount_page_id') )).get_option('b2bking_purchaselist_endpoint_setting','purchase-list').'/';

	    $setredirect = 'no';
	    switch ($currenturl_relative) {

	    	case $bulkorderurl:
	    	case $bulkorderurlbuilt:
	    	    $urlto = get_permalink( get_option('woocommerce_myaccount_page_id') ).'?'.get_option('b2bking_bulkorder_endpoint_setting','bulkorder');
	    	    $setredirect = 'yes';
	    	    break;

	    	case $conversationsurl:
	    	case $conversationsurlbuilt:
	    	    $urlto = get_permalink( get_option('woocommerce_myaccount_page_id') ).'?'.get_option('b2bking_conversations_endpoint_setting','conversations');
	    	    $setredirect = 'yes';
	    	    break;

	    	case $purchaselistssurl:
	    	case $purchaselistssurlbuilt:
	    	    $urlto = get_permalink( get_option('woocommerce_myaccount_page_id') ).'?'.get_option('b2bking_purchaselists_endpoint_setting','purchase-lists');
	    	    $setredirect = 'yes';
	    	    break;

	    	case $purchaselistssurlnew:
	    	case $purchaselistssurlbuiltnew:
	    	    $urlto = get_permalink( get_option('woocommerce_myaccount_page_id') ).'?'.'new-list';
	    	    $setredirect = 'yes';
	    	    break;

	    	case $offersurl:
	    	case $offersurlbuilt:
	    	    $urlto = get_permalink( get_option('woocommerce_myaccount_page_id') ).'?'.get_option('b2bking_offers_endpoint_setting','offers');
	    	    $setredirect = 'yes';
	    	    break;

	    	case $subaccountsurl:
	    	case $subaccountsurlbuilt:
	    	    $urlto = get_permalink( get_option('woocommerce_myaccount_page_id') ).'?'.get_option('b2bking_subaccounts_endpoint_setting','subaccounts');
	    	    $setredirect = 'yes';
	    	    break;

	    	case $subaccounturl:
	    	case $subaccounturlbuilt:
	    	  	$urlto = get_permalink( get_option('woocommerce_myaccount_page_id') ).'?'.get_option('b2bking_subaccount_endpoint_setting','subaccount').'&id='.$idqueryvar;
	    	  	$setredirect = 'yes';
	    	    break;

	    	case $purchaselisturl:
	    	case $purchaselisturlbuilt:
	    	  	$urlto = get_permalink( get_option('woocommerce_myaccount_page_id') ).'?'.get_option('b2bking_purchaselist_endpoint_setting','purchase-list').'&id='.$idqueryvar;
	    	  	$setredirect = 'yes';
	    	    break;

	    	case $conversationurl:
	    	case $conversationurlbuilt:
	    	  	$urlto = get_permalink( get_option('woocommerce_myaccount_page_id') ).'?'.get_option('b2bking_conversation_endpoint_setting','conversation').'&id='.$idqueryvar;
	    	  	$setredirect = 'yes';
	    	    break;

	        default:
	            return;
	    }

	    if ($setredirect === 'yes'){
	        exit( wp_redirect( $urlto ) );
	    }
		
	}


	// Conversations endpoint content
	function b2bking_conversations_endpoint_content() {

		// Get user login
		$currentuser = wp_get_current_user();
		$currentuserlogin = $currentuser -> user_login;

		$account_type = get_user_meta($currentuser->ID, 'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			// Check if user has permission to view all account conversations
			$permission_view_account_conversations = filter_var(get_user_meta($currentuser->ID, 'b2bking_account_permission_view_conversations', true), FILTER_VALIDATE_BOOLEAN); 
			if ($permission_view_account_conversations === true){
				// for all intents and purposes set current user as the subaccount parent
				$parent_user_id = get_user_meta($currentuser->ID, 'b2bking_account_parent', true);
				$currentuser = get_user_by('id', $parent_user_id);
				$currentuserlogin = $currentuser -> user_login;
			}
		}

		
		$accounts_login_array = array($currentuserlogin);

		// Add subaccounts to accounts array
		$subaccounts_list = get_user_meta($currentuser->ID, 'b2bking_subaccounts_list', true);
		$subaccounts_list = explode(',', $subaccounts_list);
		$subaccounts_list = array_filter($subaccounts_list);
		foreach ($subaccounts_list as $subaccount_id){
			$accounts_login_array[$subaccount_id] = get_user_by('id', $subaccount_id) -> user_login;
		}


	    // Define custom query parameters
	    $custom_query_args = array( 'post_type' => 'b2bking_conversation', // only conversations
			'posts_per_page' => 8,
	        'meta_query'=> array(	// only the specific user's conversations
	        	'relation' => 'OR',
	            array(
	                'key' => 'b2bking_conversation_user',
	                'value' => $accounts_login_array, 
	                'compare' => 'IN'
	            )
        ));

        $endpointsurl = get_option('b2bking_conversations_endpoint_setting','conversations');
        $pagestr = get_query_var($endpointsurl);
        $pagearr = explode('/', $pagestr);
        if (isset($pagearr[1])){
        	$pagenr = intval($pagearr[1]);
        }

	    $custom_query_args['paged'] = isset($pagenr) ? $pagenr : 1;
	    global $paged;
	    $paged = $custom_query_args['paged'];

	    // Instantiate custom query
	    $custom_query = new WP_Query( $custom_query_args );

	    // Pagination fix
	    $temp_query = NULL;
	    $wp_query   = NULL;
	    $wp_query   = $custom_query;

	    // Get Conversation Endpoint URL
	    $endpointurl = wc_get_endpoint_url(get_option('b2bking_conversation_endpoint_setting','conversation'));

		?>
		<div id="b2bking_myaccount_conversations_container">
			<div id="b2bking_myaccount_conversations_container_top">
				<div id="b2bking_myaccount_conversations_title">
					<?php echo apply_filters('b2bking_conversations_title_my_account', esc_html__('Conversations','b2bking')); ?>
				</div>
				<button type="button" id="b2bking_myaccount_make_inquiry_button">
					<svg class="b2bking_myaccount_new_conversation_button_icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 20 20">
					  <path fill="#fff" d="M18 0H2a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V2a2 2 0 00-2-2zM4 7h12v2H4V7zm8 5H4v-2h8v2zm4-6H4V4h12"/>
					</svg>
					<?php echo apply_filters('b2bking_conversations_new_title_my_account', esc_html__('New Conversation','b2bking')); ?>
				</button>
			</div>

			<!-- New conversation hidden panel-->
			<div class="b2bking_myaccount_new_conversation_container">
	            <div class="b2bking_myaccount_new_conversation_top">
	            	<div class="b2bking_myaccount_new_conversation_top_item b2bking_myaccount_new_conversation_new"><?php echo apply_filters('b2bking_conversations_new_title_my_account_new', esc_html__('New Conversation','b2bking')); ?></div>
	            	<div class="b2bking_myaccount_new_conversation_top_item b2bking_myaccount_new_conversation_close"><?php esc_html_e('Close X','b2bking'); ?></div>
	            </div>
	            <div class="b2bking_myaccount_new_conversation_content">
	            	<?php do_action('b2bking_start_new_conversation'); ?>
	            	<div class="b2bking_myaccount_new_conversation_content_element">
	            		<div class="b2bking_myaccount_new_conversation_content_element_text"><?php esc_html_e('Type','b2bking'); ?></div>
	            		<select id="b2bking_myaccount_conversation_type">
	            			<?php
	            				ob_start();
	            				?>
		            			<option value="inquiry"><?php esc_html_e('Inquiry','b2bking'); ?></option>
		            			<option value="message"><?php esc_html_e('Message','b2bking'); ?></option>
		            			<option value="quote"><?php esc_html_e('Quote Request','b2bking'); ?></option>
		            			<?php
		            			$content = ob_get_clean();
		            			$content = apply_filters('b2bking_filter_message_types_dropdown', $content);
		            			echo $content;
		            		?>
	            		</select>
	            	</div>
	            	<div class="b2bking_myaccount_new_conversation_content_element">
	            		<div class="b2bking_myaccount_new_conversation_content_element_text"><?php esc_html_e('Title','b2bking'); ?></div>
	            		<input type="text" id="b2bking_myaccount_title_conversation_start" placeholder="<?php esc_attr_e('Enter the title here...','b2bking') ?>">
	            	</div>
	            	<div class="b2bking_myaccount_new_conversation_content_element">
	            		<div class="b2bking_myaccount_new_conversation_content_element_text"><?php esc_html_e('Message','b2bking'); ?></div>
	            		<textarea id="b2bking_myaccount_textarea_conversation_start" placeholder="<?php esc_attr_e('Enter your message here...','b2bking') ?>"></textarea>
	            	</div>
	            	<?php do_action('b2bking_new_conversation_my_account_after_message'); ?>
                    <div class="b2bking_myaccount_start_conversation_bottom">
                    	<button id="b2bking_myaccount_send_inquiry_button" class="b2bking_myaccount_start_conversation_button" type="button">
                    		<svg class="b2bking_myaccount_start_conversation_button_icon" xmlns="http://www.w3.org/2000/svg" width="21" height="21" fill="none" viewBox="0 0 21 21">
                		  	<path fill="#fff" d="M5.243 12.454h9.21v4.612c0 .359-.122.66-.368.906-.246.245-.567.377-.964.396H5.243L1.955 21v-2.632h-.651a1.19 1.19 0 01-.907-.396A1.414 1.414 0 010 17.066V8.52c0-.358.132-.67.397-.934.264-.264.567-.387.907-.368h3.939v5.236zM19.696.002c.378 0 .69.123.936.368.245.245.368.566.368.962V9.85c0 .359-.123.66-.368.906a1.37 1.37 0 01-.936.396h-.652v2.632l-3.287-2.632H6.575v-9.82c0-.377.123-.698.368-.962.246-.264.558-.387.936-.368h11.817z"/>
                			</svg>
                    		<?php esc_html_e('Start Conversation','b2bking'); ?>
                    	</button>
                    </div>
	            </div>
	        </div>


			<?php
			// Display each conversation
			// Output custom query loop
			if ( $custom_query->have_posts() ) {
			    while ( $custom_query->have_posts() ) {
			        $custom_query->the_post();
			        global $post;

			        $conversation_title = $post->post_title;
			        $conversation_type = get_post_meta($post->ID, 'b2bking_conversation_type', true);
			        $username = get_post_meta($post->ID, 'b2bking_conversation_user', true);

			        $nr_messages = get_post_meta ($post->ID, 'b2bking_conversation_messages_number', true);
			        $last_reply_time = intval(get_post_meta ($post->ID, 'b2bking_conversation_message_'.$nr_messages.'_time', true));

			        // build time string
				    // if today
				    if((time()-$last_reply_time) < 86400){
				    	// show time
				    	$conversation_last_reply = date_i18n( get_option('time_format'), $last_reply_time+(get_option('gmt_offset')*3600) );
				    } else if ((time()-$last_reply_time) < 172800){
				    // if yesterday
				    	$conversation_last_reply = esc_html__('Yesterday at ','b2bking').date_i18n( get_option('time_format'), $last_reply_time+(get_option('gmt_offset')*3600) );
				    } else {
				    // date
				    	$conversation_last_reply = date_i18n( get_option('date_format'), $last_reply_time+(get_option('gmt_offset')*3600) ); 
				    }

			        ?>
        			<div class="b2bking_myaccount_individual_conversation_container">
                        <div class="b2bking_myaccount_individual_conversation_top">
                        	<div class="b2bking_myaccount_individual_conversation_top_item"><?php esc_html_e('Title','b2bking'); ?></div>
                        	<div class="b2bking_myaccount_individual_conversation_top_item"><?php esc_html_e('Type','b2bking'); ?></div>
                        	<div class="b2bking_myaccount_individual_conversation_top_item"><?php esc_html_e('User','b2bking'); ?></div>
                        	<?php do_action('b2bking_myaccount_conversations_items_title', $post->ID); ?>
                        	<div class="b2bking_myaccount_individual_conversation_top_item"><?php esc_html_e('Last Reply','b2bking'); ?></div>
                        </div>
                        <div class="b2bking_myaccount_individual_conversation_content">
                        	<div class="b2bking_myaccount_individual_conversation_content_item"><?php echo esc_html($conversation_title); ?></div>
                        	<div class="b2bking_myaccount_individual_conversation_content_item"><?php
                        	switch ($conversation_type) {
                        	  case "inquiry":
                        	    esc_html_e('inquiry','b2bking');
                        	    break;
                        	  case "message":
                        	    esc_html_e('message','b2bking');
                        	    break;
                        	  case "quote":
                        	    esc_html_e('quote','b2bking');
                        	    break;
                        	}
                        	?></div>
                        	<div class="b2bking_myaccount_individual_conversation_content_item"><?php 

                        	echo esc_html(apply_filters('b2bking_display_message_author', $username));

                        	?></div>
                        	<?php do_action('b2bking_myaccount_conversations_items_content', $post->ID); ?>
                        	<div class="b2bking_myaccount_individual_conversation_content_item"><?php echo esc_html($conversation_last_reply); ?></div>
                        </div>
                        <div class="b2bking_myaccount_individual_conversation_bottom">
                        	<a href="<?php echo esc_url(add_query_arg('id',$post->ID,$endpointurl)); ?>">
	                        	<button class="b2bking_myaccount_view_conversation_button" type="button">
	                        		<svg class="b2bking_myaccount_view_conversation_button_icon" xmlns="http://www.w3.org/2000/svg" width="21" height="21" fill="none" viewBox="0 0 21 21">
	                        		  <path fill="#fff" d="M5.243 12.454h9.21v4.612c0 .359-.122.66-.368.906-.246.245-.567.377-.964.396H5.243L1.955 21v-2.632h-.651a1.19 1.19 0 01-.907-.396A1.414 1.414 0 010 17.066V8.52c0-.358.132-.67.397-.934.264-.264.567-.387.907-.368h3.939v5.236zM19.696.002c.378 0 .69.123.936.368.245.245.368.566.368.962V9.85c0 .359-.123.66-.368.906a1.37 1.37 0 01-.936.396h-.652v2.632l-3.287-2.632H6.575v-9.82c0-.377.123-.698.368-.962.246-.264.558-.387.936-.368h11.817z"/>
	                        		</svg>
	                        		<?php esc_html_e('View Conversation','b2bking'); ?>
	                        	</button>
	                        </a>
                        </div>
        	        </div>

			        <?php

			    }
			} else {
				wc_print_notice(esc_html__('No conversations exist.', 'b2bking'), 'notice');
			}

			?>

		</div>

		<?php
		
	    // Reset postdata
	    wp_reset_postdata();
	    ?>
	   	<div class="b2bking_myaccount_conversations_pagination_container">
		    <div class="b2bking_myaccount_conversations_pagination_button b2bking_newer_conversations_button">
		    	<?php previous_posts_link( esc_html__('← Newer conversations','b2bking') ); ?>
		    </div>
		    <div class="b2bking_myaccount_conversations_pagination_button b2bking_older_conversations_button">
		    	<?php next_posts_link( esc_html__('Older conversations →','b2bking'), $custom_query->max_num_pages ); ?>
		    </div>
		</div>
	    <?php

	    // Reset main query object
	    $wp_query = NULL;
	    $wp_query = $temp_query;

	}


	// Individual conversation endpoint
	function b2bking_conversation_endpoint_content() {

		$conversation_id = sanitize_text_field( $_GET['id'] );
		$conversation_title = get_the_title($conversation_id);
		$conversation_type = get_post_meta($conversation_id, 'b2bking_conversation_type',true);
        $starting_time = intval(get_post_meta ($conversation_id, 'b2bking_conversation_message_1_time', true));

        if ($conversation_type === 'inquiry'){
        	$conversation_type = esc_html__('inquiry','b2bking');
        } else if ($conversation_type === 'message'){
        	$conversation_type = esc_html__('message','b2bking');
        } else if ($conversation_type === 'quote'){
        	$conversation_type = esc_html__('quote','b2bking');
        }


        // build time string
	    // if today
	    if((time()-$starting_time) < 86400){
	    	// show time
	    	$conversation_started_time = date_i18n( get_option('time_format'), $starting_time+(get_option('gmt_offset')*3600));
	    } else if ((time()-$starting_time) < 172800){
	    // if yesterday
	    	$conversation_started_time = esc_html__('Yesterday at ','b2bking').date_i18n( get_option('time_format'), $starting_time+(get_option('gmt_offset')*3600) );
	    } else {
	    // date
	    	$conversation_started_time = date_i18n( get_option('date_format'), $starting_time+(get_option('gmt_offset')*3600) ); 
	    }

		// Get Conversations Endpoint URL
		$endpointurl = wc_get_endpoint_url(get_option('b2bking_conversations_endpoint_setting','conversations'));

		?>
		<div id="b2bking_myaccount_conversation_endpoint_container">
			<div id="b2bking_myaccount_conversation_endpoint_container_top">
				<div id="b2bking_myaccount_conversation_endpoint_title">
					<?php echo esc_html($conversation_title); ?>
				</div>
				<a href="<?php echo esc_url($endpointurl); ?>">
					<button type="button">
						<?php esc_html_e('←  Go Back','b2bking'); ?>
					</button>
				</a>
			</div>
			<div id="b2bking_myaccount_conversation_endpoint_container_top_header">
				<div class="b2bking_myaccount_conversation_endpoint_container_top_header_item"><?php esc_html_e('Type:','b2bking'); ?> <span class="b2bking_myaccount_conversation_endpoint_top_header_text_bold"><?php echo esc_html($conversation_type); ?></span></div>
				<div class="b2bking_myaccount_conversation_endpoint_container_top_header_item"><?php esc_html_e('Date Started:','b2bking'); ?> <span class="b2bking_myaccount_conversation_endpoint_top_header_text_bold"><?php echo esc_html($conversation_started_time); ?></span></div>
			</div>
		<?php
		
		// Check user permission against Conversation user meta
		$user = get_post_meta ($conversation_id, 'b2bking_conversation_user', true);
		// build array of current login + subaccount logins
		$current_user = wp_get_current_user();
		$subaccounts_list = get_user_meta($current_user->ID, 'b2bking_subaccounts_list', true);
		$subaccounts_list = explode (',',$subaccounts_list);
		$subaccounts_list = array_filter($subaccounts_list);
		$logins_array = array($current_user->user_login);
		foreach($subaccounts_list as $subaccount_id){
			$username = get_user_by('id', $subaccount_id)->user_login;
			$logins_array[$subaccount_id] = $username;
		}

		// if current user is a subaccount, give access to parent + subaccounts, IF it has permission to see all account conversations
		$account_type = get_user_meta($current_user->ID, 'b2bking_account_type', true);
		if($account_type === 'subaccount'){
			$permission_view_conversations = filter_var(get_user_meta($current_user->ID, 'b2bking_account_permission_view_conversations', true), FILTER_VALIDATE_BOOLEAN); 
			if ($permission_view_conversations === true){
				// give access to parent
				$parent_id = get_user_meta($current_user->ID, 'b2bking_account_parent', true);
				$parent_user = get_user_by('id', $parent_id);
				$logins_array[$parent_id] = $parent_user->user_login;
				// give access to parent subaccounts
				$parent_subaccounts_list = get_user_meta($parent_id, 'b2bking_subaccounts_list', true);
				$parent_subaccounts_list = explode (',',$parent_subaccounts_list);
				$parent_subaccounts_list = array_filter($parent_subaccounts_list);
				foreach($parent_subaccounts_list as $subaccount_id){
					$username = get_user_by('id', $subaccount_id)->user_login;
					$logins_array[$subaccount_id] = $username;
				}
			}
		}

		// if conversation user is part of the logins array (user + subaccounts), give permission
		if (in_array($user, $logins_array)){
			// Display conversation

			// get number of messages
			$nr_messages = get_post_meta ($conversation_id, 'b2bking_conversation_messages_number', true);
			?>
			<div id="b2bking_conversation_messages_container">
				<?php	
				// loop through and display messages
				for ($i = 1; $i <= $nr_messages; $i++) {
				    // get message details
				    $message = get_post_meta ($conversation_id, 'b2bking_conversation_message_'.$i, true);
				    $author = get_post_meta ($conversation_id, 'b2bking_conversation_message_'.$i.'_author', true);
				    $time = get_post_meta ($conversation_id, 'b2bking_conversation_message_'.$i.'_time', true);
				    // check if message author is self, parent, or subaccounts
				    $current_user_id = get_current_user_id();
				    $subaccounts_list = get_user_meta($current_user_id,'b2bking_subaccounts_list', true);
				    $subaccounts_list = explode(',', $subaccounts_list);
				    $subaccounts_list = array_filter($subaccounts_list);
				    array_push($subaccounts_list, $current_user_id);

					// add parent account+all subaccounts lists
				    $account_type = get_user_meta($current_user_id, 'b2bking_account_type', true);
				    if ($account_type === 'subaccount'){
						$parent_account = get_user_meta($current_user_id, 'b2bking_account_parent', true);
			    		$parent_subaccounts_list = explode(',', get_user_meta($parent_account, 'b2bking_subaccounts_list', true));
			    		$parent_subaccounts_list = array_filter($parent_subaccounts_list); // filter blank, null, etc.
			    		array_push($parent_subaccounts_list, $parent_account); // add parent itself to form complete parent accounts list

			    		$subaccounts_list = array_merge($subaccounts_list, $parent_subaccounts_list);
				    }



				    foreach ($subaccounts_list as $user){
				    	$subaccounts_list[$user] = get_user_by('id', $user)->user_login;
				    }
				    if (in_array($author, $subaccounts_list)){
				    	$self = ' b2bking_conversation_message_self';
				    } else {
				    	$self = '';
				    }
				    // build time string
					    // if today
					    if((time()-$time) < 86400){
					    	// show time
					    	$timestring = date_i18n( get_option('time_format'), $time+(get_option('gmt_offset')*3600) );
					    } else if ((time()-$time) < 172800){
					    // if yesterday
					    	$timestring = esc_html__('Yesterday at ','b2bking').date_i18n( get_option('time_format'), $time+(get_option('gmt_offset')*3600) );
					    } else {
					    // date
					    	$timestring = date_i18n( get_option('date_format'), $time+(get_option('gmt_offset')*3600) ); 
					    }
				    ?>
			    <div class="b2bking_conversation_message <?php echo esc_attr($self); ?>">
			    	<?php 
			    	// remove multiple new lines / spaces
			    	$message = preg_replace('/(\r\n|\r|\n)+/', "\n", $message);
			    	echo apply_filters('b2bking_content_message', nl2br(b2bking()->make_clickable($message)), $message); 
					do_action('b2bking_conversation_message_before_time', $conversation_id);

			    	?>
			    	<div class="b2bking_conversation_message_time">

			    		<?php echo esc_html(apply_filters('b2bking_display_message_author', $author)).' - '; ?>
			    		<?php echo esc_html($timestring); ?>
			    	</div>
			    </div>
				    <?php
				}
				?>
			</div>
			<textarea name="b2bking_conversation_user_new_message" id="b2bking_conversation_user_new_message"></textarea><br />
			<input type="hidden" id="b2bking_conversation_id" value="<?php echo esc_attr($conversation_id); ?>">

			<?php
			do_action('b2bking_conversation_before_send_message_button');

			?>
			<div class="b2bking_myaccount_conversation_endpoint_bottom">
		    	<button id="b2bking_conversation_message_submit" class="b2bking_myaccount_conversation_endpoint_button" type="button">
		    		<svg class="b2bking_myaccount_conversation_endpoint_button_icon" xmlns="http://www.w3.org/2000/svg" width="21" height="21" fill="none" viewBox="0 0 21 21">
				  	<path fill="#fff" d="M5.243 12.454h9.21v4.612c0 .359-.122.66-.368.906-.246.245-.567.377-.964.396H5.243L1.955 21v-2.632h-.651a1.19 1.19 0 01-.907-.396A1.414 1.414 0 010 17.066V8.52c0-.358.132-.67.397-.934.264-.264.567-.387.907-.368h3.939v5.236zM19.696.002c.378 0 .69.123.936.368.245.245.368.566.368.962V9.85c0 .359-.123.66-.368.906a1.37 1.37 0 01-.936.396h-.652v2.632l-3.287-2.632H6.575v-9.82c0-.377.123-.698.368-.962.246-.264.558-.387.936-.368h11.817z"/>
					</svg>
		    		<?php esc_html_e('Send Message','b2bking'); ?>
		    	</button>
			</div>
			<?php
		} else {
			esc_html_e('Conversation does not exist!','b2bking'); // or user does not have permission
		}
		echo '</div>';

	}
	
	function b2bking_offers_endpoint_content() {
		// Title
		?>
		<div id="b2bking_myaccount_offers_container">
		<div id="b2bking_myaccount_offers_title"><?php echo esc_html__('Available Offers','b2bking'); ?></div>
		
		<?php 
		echo do_shortcode('[b2bking_offers]');
	}

	// Quick / Bulk Order Form Endpoint Content
	function b2bking_bulkorder_endpoint_content(){
		do_action('b2bking_my_account_order_form_start');
		?>
		<div id="b2bking_myaccount_bulkorder_container">
			<div id="b2bking_myaccount_bulkorder_title">
				<?php echo apply_filters('b2bking_my_account_bulkorder_title', esc_html__('Quick / Bulk Order Form','b2bking')); ?>
			</div>
		<?php echo do_shortcode(apply_filters('b2bking_my_account_bulkorder_shortcode','[b2bking_bulkorder]')); 
		do_action('b2bking_my_account_order_form_end');

		?>
		</div>

		<?php
	}

	function b2bking_purchase_list_new_list_endpoint_content(){
		?>
		<div id="b2bking_myaccount_bulkorder_container">
			<div id="b2bking_myaccount_bulkorder_title">
				<?php echo apply_filters('b2bking_my_account_bulkorder_title', esc_html__('New Purchase List','b2bking')); ?>
			</div>
		<?php echo do_shortcode('[b2bking_bulkorder theme=classic]'); 
		do_action('b2bking_new_list_page_end');
		?>
		</div>

		<?php
	}

	// Enable the B2B registration shortcode
	function b2bking_quote_form_shortcode(){

		add_shortcode('b2bking_quote_form', array($this, 'b2bking_quote_form_shortcode_content'));
	}

	function b2bking_quote_form_shortcode_content( $atts ){

		ob_start();

		$atts = shortcode_atts(
	        array(
	            'type' => 'button', // 2 types, "button", and "form" (preclicked)
	        ), 
	    $atts);

	    $button_or_form = $atts['type'];

		if (is_product()){
			global $product;
			$prodid = $product->get_id();

			add_filter('b2bking_request_custom_quote_text', function($val){
				return esc_html__('Request quote', 'b2bking');
			}, 10, 1);

			echo $this->b2bking_add_request_quote_button('productpage', $prodid, $button_or_form);
		
		} else {
			$this->b2bking_add_request_quote_button('shortcode', '', $button_or_form);
		}

		return ob_get_clean();
	}

	// Enable the B2B registration shortcode
	function b2bking_b2b_registration_shortcode(){

		add_shortcode('b2bking_b2b_registration', array($this, 'b2bking_b2b_registration_shortcode_content'));
	}
	function b2bking_b2b_registration_shortcode_content( $atts ){

		// prevent errors in rest api
		if (!function_exists('wc_print_notices')){
			return;
		}

		wp_enqueue_script( 'selectWoo' );
		wp_enqueue_style( 'select2' );
		wp_enqueue_script( 'wc-country-select' );
		wp_enqueue_script( 'wc-password-strength-meter' );

		add_filter( 'woocommerce_is_account_page', '__return_true' );

		$atts = shortcode_atts(
	        array(
	            'registration_role_id' => 'none',
	        ), 
	    $atts);

    	global $b2bking_is_b2b_registration_shortcode_role_id;
	    $b2bking_is_b2b_registration_shortcode_role_id = $atts['registration_role_id'];

		global $b2bking_is_b2b_registration;
		$b2bking_is_b2b_registration = 'yes';
		ob_start();

		// if user is logged in, show message instead of shortcode
		if ( is_user_logged_in() ) {

			if (apply_filters('b2bking_allow_logged_in_register_b2b', false)){

				if (b2bking()->has_b2b_application_pending(get_current_user_id())){
					// wait to be approved
					echo '<span class="b2bking_already_logged_in_message">';
					esc_html_e('You have applied for a B2B account. We are currently reviewing your application.','b2bking');
					echo '</span>';
				} else {
					// register

					if (!b2bking()->is_b2b_user()){

						?>
						<form action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" method="POST" class="woocommerce-form woocommerce-form-register register">


							<?php

							B2bking_Public::b2bking_custom_registration_fields();
							?>

							<p class="woocommerce-form-row form-row">
								<button type="submit" class="woocommerce-Button woocommerce-button button woocommerce-form-register__submit" name="register" value="<?php esc_attr_e( 'Send application', 'b2bking' ); ?>"><?php esc_html_e( 'Send application', 'b2bking' ); ?></button>
							</p>

							<input type="hidden" name="action" value="b2bking_become_b2b_loggedin">

						</form>
						<?php
					} else {
						echo '<span class="b2bking_already_logged_in_message">';
						esc_html_e('Your user account is already a B2B account.','b2bking');
						echo '</span>';
					}
					
				}

			} else {
				echo '<span class="b2bking_already_logged_in_message">';
				$text = esc_html__('You are already logged in. To apply for a Business account, please logout first. ','b2bking');
				echo apply_filters('b2bking_you_are_logged_in_text', $text);
				echo '<a href="'.esc_url(wp_logout_url(get_permalink())).'">'.esc_html__('Click here to log out','b2bking').'</a></span>';

			}
		} else {
			wc_print_notices();

			if (apply_filters('b2bking_b2b_registration_redirect_to_my_account', true)){
				// redirect to my account
				add_action('woocommerce_login_form_start', function(){
					echo '<input type="hidden" name="redirect" value="'.esc_attr(apply_filters('b2bking_redirect_after_login_permalink', wc_get_page_permalink( 'myaccount' ))).'">';
				}, 100);
			}
			
			echo do_shortcode('[woocommerce_my_account]');
					
		}

		$output = ob_get_clean();
		return $output;
	}

	// Enable the B2B registration shortcode
	function b2bking_b2b_registration_separate_shortcode(){
		add_shortcode('b2bking_b2b_registration_separate', array($this, 'b2bking_b2b_registration_separate_shortcode_content'));
	}
	function b2bking_b2b_registration_separate_shortcode_content( $atts ){

		// prevent errors in rest api
		if (!function_exists('wc_print_notices')){
			return;
		}

		wp_enqueue_script( 'selectWoo' );
		wp_enqueue_style( 'select2' );
		wp_enqueue_script( 'wc-country-select' );
		wp_enqueue_script( 'wc-password-strength-meter' );

		add_filter( 'woocommerce_is_account_page', '__return_true' );

		$atts = shortcode_atts(
	        array(
	            'registration_role_id' => 'none',
	        ), 
	    $atts);

    	global $b2bking_is_b2b_registration_shortcode_role_id;
	    $b2bking_is_b2b_registration_shortcode_role_id = $atts['registration_role_id'];

		global $b2bking_is_b2b_registration;
		$b2bking_is_b2b_registration = 'yes';

		global $b2bking_is_b2b_registration_separate;
		$b2bking_is_b2b_registration_separate = 'yes';

		ob_start();

		if (!is_user_logged_in()){
			wc_print_notices(); 
		}
		echo do_shortcode('[woocommerce_my_account]');

		$output = ob_get_clean();
		return $output;
	}



	function b2bking_separate_page_registration_b2b ( $value ){

		// avoid conflicts
		$separate_page = get_option( 'b2bking_registration_separate_my_account_page_setting', 'disabled' );
		if ($separate_page === 'disabled'){
			return $value;
		}


	    $user_id = get_current_user_id();
	    $user_is_b2b = get_user_meta($user_id, 'b2bking_b2buser',true);

	    // if current page is salesking agent dashboard, return b2c value (for affiliate links for example)
    	if (intval(b2bking()->safe_get_queried_object_id()) === intval(apply_filters( 'wpml_object_id', get_option( 'salesking_agents_page_setting', 'disabled' ), 'post' , true) )){
    		return $value;
    	}


	    // getting lost password link to work correctly
	    if (!is_user_logged_in()){
	    	$separate_page = get_option( 'b2bking_registration_separate_my_account_page_setting', 'disabled' );
	    	if ($separate_page !== 'disabled'){
	    		// if page is the b2b account page
	    		if (intval(b2bking()->safe_get_queried_object_id()) === intval($separate_page)){
	    			update_option('b2bking_logged_out_separate_delay', apply_filters('b2bking_separate_lostpassword_delay', 60));
	    			$user_is_b2b = 'yes';
	    		} else {
	    			$current_delay = intval(get_option('b2bking_logged_out_separate_delay'));
	    			if ($current_delay > 0){
	    				$user_is_b2b = 'yes';
	    				$current_delay--;
	    				update_option('b2bking_logged_out_separate_delay', $current_delay);
	    			}
	    		}

	    		
	    	}
	    }

	    if ($user_is_b2b === 'yes'){
	        // check if have setting separate my acc page for b2b users
	        $separate_page = get_option( 'b2bking_registration_separate_my_account_page_setting', 'disabled' );
	        if ($separate_page !== 'disabled'){
	        	return $separate_page;
	        } else {
	        	return $value;
	        }
	    } else {
	        return $value;
	    }
	}

	// B2BKing Content Shortcode
	function b2bking_content_shortcode(){
		add_shortcode('b2bking_content', array($this, 'b2bking_content_shortcode_content'));
	}
	function b2bking_content_shortcode_content($atts = array(), $content = null){

		$atts = shortcode_atts(
	        array(
	            'show_to' => 'none',
	        ), 
	    $atts);
	    if ($atts['show_to'] === 'none'){
	    	return '';
	    } else {
	    	$groups_array=explode(',',$atts['show_to']);
	    	// check if current user has access
	    	$current_user_id = get_current_user_id();

	    	$current_user_id = b2bking()->get_top_parent_account($current_user_id);

	    	$current_user_group = b2bking()->get_user_group($current_user_id);

	    	$user_is_b2b = get_user_meta($current_user_id,'b2bking_b2buser',true);
	    	if ($user_is_b2b !== 'yes'){
	    		if (is_user_logged_in()){
	    			$current_user_group = 'b2c';
	    		} else {
	    			$current_user_group = 'loggedout';
	    		}
	    	}

	    	if (in_array($current_user_group,$groups_array)){
	    		// allow stacking shortcodes if a piece of content is a shortcode itself
	    		if (shortcode_exists(substr($content, 1, -1))){
	    			return do_shortcode($content);
	    		} else {
	    			// maybe shortcode with parameter, try with a space
	    			$shortcodewithspace = explode(' ', substr($content, 1, -1));
    				if (shortcode_exists($shortcodewithspace[0])){
    					return do_shortcode($content);
    				}
	    		}
	    		return $content;
	    	} else {
	    		// check if user is b2b in general
	    		if ($user_is_b2b === 'yes' && in_array('b2b', $groups_array)){
	    			if (shortcode_exists(substr($content, 1, -1))){
	    				return do_shortcode($content);
	    			} else {
		    			// maybe shortcode with parameter, try with a space
		    			$shortcodewithspace = explode(' ', substr($content, 1, -1));
	    				if (shortcode_exists($shortcodewithspace[0])){
	    					return do_shortcode($content);
	    				}
		    		}
	    			return $content;
	    		} else{
	    			// check user's specific username
	    			$user_login = wp_get_current_user()->user_login;
	    			if (in_array($user_login,$groups_array)){
	    				if (shortcode_exists(substr($content, 1, -1))){
	    					return do_shortcode($content);
	    				} else {
			    			// maybe shortcode with parameter, try with a space
			    			$shortcodewithspace = explode(' ', substr($content, 1, -1));
		    				if (shortcode_exists($shortcodewithspace[0])){
		    					return do_shortcode($content);
		    				}
			    		}
	    				return $content;
	    			} else {
	    				// check specific purchase, user has purchased
	    				// if there are purchased conditions
	    				foreach ($groups_array as $option){
	    					$optionexplode = explode('bought', $option);
	    					if (isset($optionexplode[1])){
	    						$boughtid = $optionexplode[1];
	    						if ( wc_customer_bought_product( '', get_current_user_id(), $boughtid ) ) {
	    							return $content;
	    						}
	    					}
	    				}

	    				return '';
	    			}
	    		}
	    	}
	    }

	}

	function b2bking_always_redirect_to_shop(){
		if ( get_option('b2bking_plugin_status_setting', 'disabled') !== 'disabled' ){
			if (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'hide_website'){
				if (!is_user_logged_in()) {
					if ( (!is_shop() || apply_filters('b2bking_redirect_shop_hide_site', false)) && !is_account_page() && apply_filters('b2bking_guest_shop_redirect_conditional', true)) {

						wp_redirect( 
						    add_query_arg( 
						        apply_filters('b2bking_redirect_to_path', 'redirect_to'), 
						        urlencode( $_SERVER['REQUEST_URI'] ), 
						        apply_filters('b2bking_guest_shop_redirect_link', get_permalink(wc_get_page_id('shop')))
						    )
						); 

						exit();
					}

				}
			}
		}
		return;
	}


	// Enable the B2B registration shortcode
	function b2bking_b2b_registration_only_shortcode(){
		add_shortcode('b2bking_b2b_registration_only', array($this, 'b2bking_b2b_registration_only_shortcode_content'));
	}
	function b2bking_b2b_registration_only_shortcode_content( $atts ){

		// prevent errors in rest api
		if (!function_exists('wc_print_notices')){
			return;
		}

		wp_enqueue_script( 'selectWoo' );
		wp_enqueue_style( 'select2' );
		wp_enqueue_script( 'wc-country-select' );
		wp_enqueue_script( 'wc-password-strength-meter' );

		add_filter( 'woocommerce_is_account_page', '__return_true' );
		$atts = shortcode_atts(
	        array(
	            'registration_role_id' => 'none',
	        ), 
	    $atts);

    	global $b2bking_is_b2b_registration_shortcode_role_id;
	    $b2bking_is_b2b_registration_shortcode_role_id = $atts['registration_role_id'];

		global $b2bking_is_b2b_registration;
		$b2bking_is_b2b_registration = 'yes';
		ob_start();

		// if user is logged in, show message instead of shortcode
		if ( is_user_logged_in() ) {

			if (apply_filters('b2bking_allow_logged_in_register_b2b', false)){

				if (b2bking()->has_b2b_application_pending(get_current_user_id())){
					// wait to be approved
					echo '<span class="b2bking_already_logged_in_message">';
					esc_html_e('You have applied for a B2B account. We are currently reviewing your application.','b2bking');
					echo '</span>';
				} else {
					// register

					if (!b2bking()->is_b2b_user()){
						?>
						<form action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" method="POST" class="woocommerce-form woocommerce-form-register register">


							<?php

							B2bking_Public::b2bking_custom_registration_fields();
							?>

							<p class="woocommerce-form-row form-row">
								<button type="submit" class="woocommerce-Button woocommerce-button button woocommerce-form-register__submit" name="register" value="<?php esc_attr_e( 'Send application', 'b2bking' ); ?>"><?php esc_html_e( 'Send application', 'b2bking' ); ?></button>
							</p>

							<input type="hidden" name="redirectto" value="<?php echo add_query_arg('b2b_applied', '1', home_url($_SERVER['REQUEST_URI'])); ?>">


							<input type="hidden" name="action" value="b2bking_become_b2b_loggedin">

						</form>
						<?php

					} else {
						echo '<span class="b2bking_already_logged_in_message">';
						if (isset($_GET['b2b_applied']) && $_GET['b2b_applied'] === '1'){
							esc_html_e('Thank you for your submission. Your B2B account has been approved. You may now browse our products and place orders. ', 'b2bking');
							echo '<a href="' . esc_url(wc_get_page_permalink('shop')) . '">' . esc_html__('Visit Shop', 'b2bking') . '</a>';
						} else {
							esc_html_e('Your user account is already a B2B account.','b2bking');
						}
						echo '</span>';
					}
					
				}

			} else {
				echo '<span class="b2bking_already_logged_in_message">';
				esc_html_e('You are already logged in. To apply for a Business account, please logout first. ','b2bking');
				echo '<a href="'.esc_url(wp_logout_url(get_permalink())).'">'.esc_html__('Click here to log out','b2bking').'</a></span>';
			}


			
		} else {
			$message = apply_filters( 'woocommerce_my_account_message', '' );
			if ( ! empty( $message ) ) {
				wc_add_notice( $message );
			}
			wc_print_notices();

			?>
			<h2 class="b2bking_b2bregistration_only_register_header">
			<?php echo apply_filters('b2bking_b2bregistration_only_register_header',esc_html__( 'Register', 'b2bking' )); ?></h2>
			<div class="woocommerce">
				<form method="post" class="woocommerce-form woocommerce-form-register register" <?php do_action( 'woocommerce_register_form_tag' ); ?> >

					<?php do_action( 'woocommerce_register_form_start' ); ?>

					<?php if ( 'no' === get_option( 'woocommerce_registration_generate_username' ) ) { ?>

						<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
							<label for="reg_username"><?php esc_html_e( 'Username', 'b2bking' ); ?>&nbsp;<span class="required">*</span></label>
							<input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="username" id="reg_username" autocomplete="username" value="<?php echo ( ! empty( $_POST['username'] ) ) ? esc_attr( wp_unslash( $_POST['username'] ) ) : ''; ?>" />
						</p>

					<?php } ?>

					<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
						<label for="reg_email"><?php esc_html_e( 'Email address', 'b2bking' ); ?>&nbsp;<span class="required">*</span></label>
						<input type="email" class="woocommerce-Input woocommerce-Input--text input-text" name="email" id="reg_email" autocomplete="email" value="<?php echo ( ! empty( $_POST['email'] ) ) ? esc_attr( wp_unslash( $_POST['email'] ) ) : ''; ?>" />
					</p>

					<?php if ( 'no' === get_option( 'woocommerce_registration_generate_password' ) ) { ?>

						<p class="woocommerce-form-row woocommerce-form-row--wide form-row form-row-wide">
							<label for="reg_password"><?php esc_html_e( 'Password', 'b2bking' ); ?>&nbsp;<span class="required">*</span></label>
							<input type="password" class="woocommerce-Input woocommerce-Input--text input-text" name="password" id="reg_password" autocomplete="new-password" />
						</p>

					<?php } else { ?>

						<p><?php esc_html_e( 'A link to set a new password will be sent to your email address.', 'b2bking' ); ?></p>

					<?php } ?>

					<?php do_action( 'woocommerce_register_form' ); ?>

					<p class="woocommerce-form-row form-row">
						<?php wp_nonce_field( 'woocommerce-register', 'woocommerce-register-nonce' ); ?>
						<button type="submit" class="woocommerce-Button woocommerce-button button woocommerce-form-register__submit" name="register" value="<?php esc_attr_e( 'Register', 'b2bking' ); ?>"><?php esc_html_e( 'Register', 'b2bking' ); ?></button>
					</p>

					<?php do_action( 'woocommerce_register_form_end' ); ?>

				</form>
			</div>
			<?php
		}

		$output = ob_get_clean();
		return $output;
	}

	function b2bking_handle_file_upload(){
		// Stop immediately if form is not submitted
		if ( ! isset( $_POST['b2bking_submit_csvorder'] ) ) {
			return;
		}

		$error = 'no';

		// Throws a message if no file is selected
		if ( ! $_FILES['b2bking_csvorder']['name'] ) {
			wc_add_notice( esc_html__( 'Please choose a file', 'b2bking' ), 'error' );
			$error = 'yes';
		}

		// Check for valid file extension
		$allowed_extensions = array( 'csv');
		$tmp = explode('.', $_FILES['b2bking_csvorder']['name']);
		if( ! in_array(end($tmp), $allowed_extensions)){
			wc_add_notice( sprintf(  esc_html__( 'Invalid file extension, only allowed: %s', 'b2bking' ), implode( ', ', $allowed_extensions ) ), 'error' );
			$error = 'yes';
		}

		$file_size = $_FILES['b2bking_csvorder']['size'];
		$allowed_file_size = 5512000; // Here we are setting the file size limit to 5.5MB

		// Check for file size limit
		if ( $file_size >= $allowed_file_size ) {
			wc_add_notice( sprintf( esc_html__( 'File size limit exceeded, file size should be smaller than %d KB', 'b2bking' ), $allowed_file_size / 1000 ), 'error' );
			$error = 'yes';

		}

		if ( $error !== 'no') {
			wc_add_notice( esc_html__( 'Sorry, there was an error with your file upload.', 'b2bking' ), 'error' );
		} else {

			// process upload to add to cart
			$csv = array_map(function($v) {
			    return str_getcsv($v, ',', '"', '\\');
			}, file($_FILES['b2bking_csvorder']['tmp_name'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
			
    	    $failed_skus = array();
    	    $ids_added = array();

    	    $linenumber = 0;
			foreach ($csv as $line){

				$lineelementsarray = explode(';',$line[0]);

				if (isset($lineelementsarray[1])){
		    		$sku = $lineelementsarray[apply_filters('b2bking_csv_sku_column_index', 0)];
		    		$qty = $lineelementsarray[apply_filters('b2bking_csv_qty_column_index', 1)];
		    	} else {
		    		$sku = $line[apply_filters('b2bking_csv_sku_column_index', 0)];
		    		$qty = $line[apply_filters('b2bking_csv_qty_column_index', 1)];
		    	}

		    	if (intval($qty) === 0){
		    		continue;
		    	}

	    		$id = wc_get_product_id_by_sku($sku);

	    		$id = apply_filters('b2bking_find_product_id_csvorder', $id, $sku);

	    		$possible_parent_id = wp_get_post_parent_id($id);

	    		if ($id !== 0 && !empty($id)){

	    			$qty = apply_filters('b2bking_quickorder_qty_added', $qty, $id);

	    			if ($possible_parent_id !== 0){
	    				$added = WC()->cart->add_to_cart( $possible_parent_id, intval($qty), $id);
	    			} else {
	    				$added = WC()->cart->add_to_cart( $id, intval($qty));
	    			}

					if ($added) {
						array_push($ids_added, $id);
					} else {
						array_push($failed_skus, $sku);
					}
	    		} else {
	    			if ($linenumber !== 0){
	    				array_push($failed_skus, $sku);
	    			}
	    		}

	    		$linenumber++;
			}

			$ids_added = array_filter(array_unique($ids_added));
			$successful_skus = count($ids_added);

			$success_message = esc_html__( 'Upload successful', 'b2bking' );
			if ($successful_skus !== 0){

				if ($successful_skus === 1){
					$success_message.= ': '.$successful_skus.' '.esc_html__('product was added to the cart','b2bking');
				} else {
					$success_message.= ': '.$successful_skus.' '.esc_html__('products were added to the cart','b2bking');
				}
			}

			wc_add_notice( $success_message, 'success' );


			if (!empty($failed_skus)){
				$skus_string = '';
				foreach ($failed_skus as $sku){
					$skus_string .= $sku.', ';
				}
				$skus_string = substr($skus_string, 0, -2);
				wc_add_notice( esc_html__( 'We could not match any products with the following SKUs: ', 'b2bking' ).$skus_string, 'error' );
			}
		}

	}

	function myaccount_query_vars ($vars) {

		$endpoints = [get_option('b2bking_conversations_endpoint_setting','conversation'), get_option('b2bking_conversations_endpoint_setting','conversations'), get_option('b2bking_offers_endpoint_setting','offers'), get_option('b2bking_bulkorder_endpoint_setting','bulkorder'), get_option('b2bking_subaccount_endpoint_setting','subaccount'), get_option('b2bking_subaccounts_endpoint_setting','subaccounts'), get_option('b2bking_purchaselist_endpoint_setting','purchase-list'), get_option('b2bking_purchaselists_endpoint_setting','purchase-lists')];

		if (intval(get_option('b2bking_enable_company_credit_setting', 1)) === 1 && defined('b2bkingcredit_DIR')){
			$endpoints[] = get_option('b2bking_credit_endpoint_setting', 'company-credit');
		}

	    foreach ($endpoints as $e) {
	        $vars[$e] = $e;
	    }

	    return $vars;
	}

	// Enables csv order shortcode
	function b2bking_csvorder_shortcode(){
		add_shortcode('b2bking_csvorder', array($this, 'b2bking_csvorder_shortcode_content'));
	}
	function b2bking_csvorder_shortcode_content(){
		ob_start();
		if (!current_user_can( apply_filters('b2bking_backend_capability_needed', 'manage_woocommerce') )){
			wc_print_notices();
		}
		?>
		<form method="post" enctype="multipart/form-data">
			<label for="b2bking_csvorder"><?php esc_html_e('Upload .csv files with SKU on first column and quantity on second column.','b2bking');?></label>
			<p class="form-row form-row-wide">
		        <span class="woocommerce-input-wrapper">
		            <input type="file" name="b2bking_csvorder" id="b2bking_csvorder" class="input-text" accept=".csv">
		        </span>
		    </p>
		    <button type="submit" class="button" name="b2bking_submit_csvorder"><?php echo apply_filters('b2bking_csvorder_add_text', esc_html__('Add to Cart','b2bking')); ?></button>
		</form>

		<?php
		$content = ob_get_contents();
		ob_end_clean();
		return $content;
	}

	/*
	function b2bking_product_information_shortcode(){
		add_shortcode('b2bking_product_information_table', array($this, 'b2bking_show_custom_information_table_shortcode_content'));
		add_shortcode('b2bking_tiered_pricing_table', array($this, 'b2bking_tiered_pricing_table_shortcode_content'));
	}

	function b2bking_show_custom_information_table_shortcode_content($atts){
		$atts = shortcode_atts(
	        array(
	            'id' => "",
	        ), 
	    $atts);

	    $prodid = $atts['id'];

	    ob_start();
	    $this->b2bking_show_custom_information_table($prodid);
	    $content = ob_get_clean();
	    return $content;
	}

	function b2bking_tiered_pricing_table_shortcode_content($atts){
		$atts = shortcode_atts(
	        array(
	            'id' => "",
	            'allvariations' => "no",
	            'firstvariation' => "no",
	        ), 
	    $atts);

	    $prodid = $atts['id'];
	    $allvariations = $atts['allvariations'];
	    $firstvariation = $atts['firstvariation'];

	    ob_start();

	    if ($allvariations === 'yes'){
	    	global $post;
	    	$prodid = $post->ID;
	    	$product = wc_get_product($prodid);
	    	if ($product){
	    		if ($product->is_type('variable')){
	    			$children = $product->get_children();
	    			foreach ($children as $child){
	    				$child_prod = wc_get_product($child);
	    				$name = $child_prod->get_formatted_name();
	    				echo apply_filters('b2bking_product_variations_table_name_html','<p class="b2bking_product_variation_table_title">'.$name.'</p>');
	    				$this->b2bking_show_tiered_pricing_table($child);
	    				echo '<br>';
	    			}
	    		}
	    	}
	    	
	    } else if ($firstvariation === 'yes'){
	    	global $post;
	    	$prodid = $post->ID;
	    	$product = wc_get_product($prodid);
	    	if ($product){
	    		if ($product->is_type('variable')){
	    			$children = $product->get_children();
	    			$first_child = $children[0];
    				$this->b2bking_show_tiered_pricing_table($first_child);
	    		}
	    	}
	    	
	    } else {
	    	$this->b2bking_show_tiered_pricing_table($prodid);
	    }

	    $content = ob_get_clean();
	    return $content;
	}

	*/


	function b2bking_offers_shortcode(){
		add_shortcode('b2bking_offers', array($this, 'b2bking_offers_shortcode_content'));
	}

	function b2bking_offers_shortcode_content($atts){

		// load styles
		if (B2BKING_FILE_RELEASE === 'DEV'){
			wp_enqueue_style('b2bking_sub_offers_conv', plugins_url('../includes/assets/css/style-sub-offers-conv.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);
		} else {
			wp_enqueue_style('b2bking_sub_offers_conv', plugins_url('../includes/assets/css/style-sub-offers-conv.min.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);
		}

		// in case of individual offer
		$atts = shortcode_atts(
	        array(
	            'id' => 'none',
	        ), 
	    $atts);

	    $shortcode_offer_id = sanitize_text_field($atts['id']);

		wp_enqueue_script('pdfmake', plugins_url('../includes/assets/lib/pdfmake/pdfmake.min.js', __FILE__), $deps = array(), $ver = false, $in_footer =true);
		wp_enqueue_script('vfsfonts', plugins_url('../includes/assets/lib/pdfmake/vfs_fonts.js', __FILE__), $deps = array(), $ver = false, $in_footer =true);

		ob_start();

		// Get user login and user group
		$user_id = get_current_user_id();
		$original_user_id = $user_id;

		$account_type = get_user_meta($user_id,'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			// Check if user has permission to view all account offers
			$permission_view_account_offers = filter_var(get_user_meta($user_id, 'b2bking_account_permission_view_offers', true), FILTER_VALIDATE_BOOLEAN); 
			if ($permission_view_account_offers === true){
				// for all intents and purposes set current user as the subaccount parent
				$parent_user_id = get_user_meta($user_id, 'b2bking_account_parent', true);
				$user_id = $parent_user_id;

			}
		}

		if (is_user_logged_in()){
			$user = get_user_by('id', $user_id) -> user_login;
			$email = get_user_by('id', $user_id) -> user_email;

			$currentusergroupidnr = b2bking()->get_user_group($user_id);

			$subaccount_direct_visibility = '';		
			if ($user_id !== $original_user_id){
				$original_user_login = get_user_by('id', $original_user_id) -> user_login;
				$subaccount_direct_visibility = array(
				    'key' => 'b2bking_user_'.$original_user_login, 
				    'value' => '1',
				);
			}	

			// Define custom query parameters
		    $custom_query_args = array( 'post_type' => 'b2bking_offer',
	            	  'post_status' => 'publish',
	            	  'posts_per_page' => 6,
	            	  'suppress_filters' => true,
	            	  'meta_query'=> 
	  			    	  	array(
	  			                'relation' => 'AND',
	  			                array(
	  			                    'key' => 'b2bking_post_status_enabled',
	  			                    'value' => '1',
	  			                ),
	  	                	  	array(
	  	                            'relation' => 'OR',
	  	                            array(
	  	                                'key' => 'b2bking_group_'.$currentusergroupidnr,
	  	                                'value' => '1',
	  	                            ),
	  	                            array(
	  	                                'key' => 'b2bking_user_'.$user, 
	  	                                'value' => '1',
	  	                            ),
	  	                            array(
	  	                                'key' => 'b2bking_user_'.$email, 
	  	                                'value' => '1',
	  	                            ), $subaccount_direct_visibility
	  	                        ),
	  			            )
	                   );

		    	  	
		    

		    $custom_query_args = apply_filters('b2bking_offers_args', $custom_query_args);

            $endpointsurl = get_option('b2bking_offers_endpoint_setting','offers');
            $pagestr = get_query_var($endpointsurl);
            $pagearr = explode('/', $pagestr);
            if (isset($pagearr[1])){
            	$pagenr = intval($pagearr[1]);
            }

    	    $custom_query_args['paged'] = isset($pagenr) ? $pagenr : 1;
    	    global $paged;
    	    $paged = $custom_query_args['paged'];


		    // Instantiate custom query
		    $custom_query = new WP_Query( $custom_query_args );

		    // Pagination fix
		    $temp_query = NULL;
		    $wp_query   = NULL;
		    $wp_query   = $custom_query;

		    ?>
		    <img id="b2bking_img_logo" class="b2bking_hidden_img" src="<?php echo get_option('b2bking_offers_logo_setting','');?>">
		    <?php

		    // Output custom query loop
		    if ( $custom_query->have_posts() ) {
		        while ( $custom_query->have_posts() ) {
		            $custom_query->the_post();
		            global $post;
		            $offer_price = 0;

		            if ($shortcode_offer_id !== 'none'){

		            	if (intval(apply_filters( 'wpml_object_id', $post->ID, 'post' , true)) === intval($shortcode_offer_id)){
		            		// this offer is the offer in the shortcode, proceed to display it
		            	} else {
		            		// this is not the offer, skip it
		            		continue;
		            	}
		            }

		            // offer only once. If current user or its parent has already purchased offer, do not allow, skip
		            if (intval(get_option( 'b2bking_offer_one_per_user_setting', 0 )) === 1){
		            	$currentuser = get_current_user_id();
		            	// $user_id can be this user or parent

		            	$already_purchased = 'no';
		            	if (get_user_meta($user_id,'b2bking_purchased_offer_'.$post->ID, true) === 'yes'){
		            		$already_purchased = 'yes';
		            	}
		            	if (get_user_meta($currentuser,'b2bking_purchased_offer_'.$post->ID, true) === 'yes'){
		            		$already_purchased = 'yes';
		            	}

		            	if ($already_purchased === 'yes'){
		            		continue;
		            	}
		            }
		            if (apply_filters('b2bking_offer_skip', false, $post->ID, get_current_user_id())){
		            	continue;
		            }


		            // In stock or on backorder items.
		            // For all items in the offer, if one of the items is A) managed stock and B) not on backorder and C) quantities not enough, then replace "add to cart" and "pdf" buttons with "not in stock" grayed out msg
		            $offerinstock = 'yes';
		            $insufficientstock = array();
		            if (apply_filters('b2bking_offers_items_use_stock', true)){
		            	$details = get_post_meta(apply_filters( 'wpml_object_id', $post->ID, 'post' , true),'b2bking_offer_details', true);
		            	$offer_products = explode('|',$details);
		            	// thumbnails for PDF
		            	// show image thumbnails for PDFs
		            	$offerprods = $details;
		            	$offerprods = array_filter(array_unique(explode('|', $offerprods)));
		            	$thumbnails = array();
		            	foreach ($offerprods as $offerprod){

		            		$prodd = explode(';', $offerprod)[0];
		            		$qty = intval(explode(';', $offerprod)[1]);
		            		$prodid = explode('_', $prodd);

		            		if (isset($prodid[1])){
		            			$prodid = $prodid[1];
		            			$prod_temp = wc_get_product($prodid);
		            			
		            			if ($prod_temp){

			            			$stockqty = $prod_temp->get_stock_quantity();
						    		if ( ! $prod_temp->get_manage_stock() ){
						    			$stockqty = 999999999;
						    		} else {
			    						// if backorders, same 
			    						if ('yes' === $prod_temp->get_backorders() || 'notify' === $prod_temp->get_backorders()){
			    							$stockqty = 999999999;
			    						}
			    					}

			    					if ($qty > $stockqty){
			    						// do not allow
			    						$offerinstock = 'no';
			    						array_push($insufficientstock, $prodid);
			    					}
			    				}
		            		}
		            	}
		            }


		            ?>
		            <div class="b2bking_myaccount_individual_offer_container">
		            	<svg class="b2bking_myaccount_individual_offer_top_icon" xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" viewBox="0 0 20 20">
		            	  <path fill="#EDEDED" d="M19.41 9.58l-9-9C10.05.22 9.55 0 9 0H2C.9 0 0 .9 0 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM3.5 5C2.67 5 2 4.33 2 3.5S2.67 2 3.5 2 5 2.67 5 3.5 4.33 5 3.5 5z"/>
		            	</svg>
		            	<div class="b2bking_myaccount_individual_offer_top">
		            		<?php 

		            			if (apply_filters('b2bking_individual_offer_top_display_default', true)){
		            				echo esc_html(substr(get_the_title(apply_filters( 'wpml_object_id', $post->ID, 'post' , true)),0,40));
		            				if (strlen(get_the_title(apply_filters( 'wpml_object_id', $post->ID, 'post' , true))) > 40){
		            					echo '...';
		            				} 
		            			} else {
		            				do_action('b2bking_individual_offer_top_display_changed');
		            			}
		            			
		            		?>
		            			
		            	</div>
		            	<div class="b2bking_myaccount_individual_offer_header_line">
		            		<div class="b2bking_myaccount_individual_offer_header_line_item"><?php esc_html_e('Item','b2bking'); ?></div>
		            		<div class="b2bking_myaccount_individual_offer_header_line_item"><?php esc_html_e('Quantity','b2bking'); ?></div>
		            		<div class="b2bking_myaccount_individual_offer_header_line_item"><?php esc_html_e('Unit Price','b2bking'); ?></div>
		            		<div class="b2bking_myaccount_individual_offer_header_line_item"><?php esc_html_e('Subtotal','b2bking'); ?></div>
		            	</div>
		            	<?php 

		            	$details = get_post_meta(apply_filters( 'wpml_object_id', $post->ID, 'post' , true),'b2bking_offer_details', true);
		            	$offer_products = explode('|',$details);


		            	// thumbnails for PDF
		            	// show image thumbnails for PDFs
		            	$offerprods = $details;
		            	$offerprods = array_filter(array_unique(explode('|', $offerprods)));
		            	$thumbnails = array();
		            	foreach ($offerprods as $offerprod){

		            		$offerprod = explode(';', $offerprod)[0];
		            		$prodid = explode('_', $offerprod);

		            		if (isset($prodid[1])){
		            			$prodid = $prodid[1];

		            			$product_image = wp_get_attachment_image_src( get_post_thumbnail_id( $prodid ) );

		            			if ( false === $product_image ) {

		            				// try to find parent image
		            				$possible_parent_id = wp_get_post_parent_id($prodid);
		            				if ($possible_parent_id !== 0){
		            					$product_image = wp_get_attachment_image_src( get_post_thumbnail_id( $possible_parent_id ) );
		            					if ( false === $product_image ) {
		            						$product_image = 'no';
		            						array_push($thumbnails, $product_image);
		            					} else {
		            						array_push($thumbnails, $product_image[0]);
		            					}
		            				} else {
		            					$product_image = 'no';
		            					array_push($thumbnails, $product_image);
		            				}
		            			} else {
		            				array_push($thumbnails, $product_image[0]);
		            			}
		            		} else {
								array_push($thumbnails, 'no');
							}		            		
		            		
		            	}
		            	$thumbnailstext = '';
		            	$nr = 0;
		            	foreach ($thumbnails as $thumbnailsrc){
		            		$thumbnailstext .= $thumbnailsrc.'|';
		            		if ($thumbnailsrc !== 'no'){
		            			?>
		            			<img id="b2bking_img_logo<?php echo $nr.apply_filters( 'wpml_object_id', $post->ID, 'post' , true);?>" class="b2bking_hidden_img" src="<?php echo esc_attr($thumbnailsrc);?>">
		            			<?php
		            			$nr++;
		            		}
		            	}
		            	$thumbnailstext = substr($thumbnailstext, 0, -1);
		            	?>
		            	<input type="hidden" id="b2bking_offer_id" value="<?php echo esc_attr(apply_filters( 'wpml_object_id', $post->ID, 'post' , true));?>">
		            	<input type="hidden" class="b2bking_offers_thumbnails_str" value="<?php echo esc_attr($thumbnailstext);?>">
		            	<?php
		            	// thumbnails for PDF END



		            	foreach ($offer_products as $product){
		            		$product_details = explode(';', $product);
		            		// if item is in the form product_id, change title
		            		$isproductid = explode('_', $product_details[0]); 
		            		if ($isproductid[0] === 'product'){
		            			// it is a product+id, get product title
		            			$newproduct = wc_get_product($isproductid[1]);

		            			if (is_a($newproduct,'WC_Product_Variation') || is_a($newproduct,'WC_Product')){
			            			$product_details[0] = $newproduct->get_name();
			            		}

		            			//if product is a variation with 3 or more attributes, need to change display because get_name doesnt 
		            			// show items correctly
		            			if (is_a($newproduct,'WC_Product_Variation')){
		            				$attributes = $newproduct->get_variation_attributes();
		            				$number_of_attributes = count($attributes);
		            				if ($number_of_attributes > 2){
		            					$product_details[0].=' - ';
		            					foreach ($attributes as $attribute){
		            						$product_details[0].=$attribute.', ';
		            					}
		            					$product_details[0] = substr($product_details[0], 0, -2);
		            				}
		            			}

		            			$product_details[0] = apply_filters('b2bking_offer_name_display_frontend', $product_details[0], $newproduct);

		            		}
		            		?>
		            		<div class="b2bking_myaccount_individual_offer_element_line">
		            			<div class="b2bking_myaccount_individual_offer_element_line_item <?php 

		            			if (isset($isproductid[1])){
		            				if (in_array($isproductid[1], $insufficientstock)){
		            					echo 'b2bking_offer_insufficient_stock_item';
		            				}
		            			}
		            			

		            			?>"><div class="b2bking_myaccount_individual_offer_element_line_item_name"><?php echo esc_html(strip_tags($product_details[0])); ?>
		            			<?php
		            			// Check if this product needs configuration and add dropdowns inline
		            			if ($isproductid[0] === 'product'){
		            				$productobj = wc_get_product($isproductid[1]);
		            				if (is_a($productobj,'WC_Product_Variation')){
		            					foreach ($productobj->get_variation_attributes() as $name => $value){
		            						if (empty($value) && $value !== 0 && $value !== '0') {
		            							wc_dropdown_variation_attribute_options(array(
		            								'attribute' => str_replace('attribute_', '', $name),
		            								'product'   => wc_get_product($productobj->get_parent_id()),
		            								'class'		=> 'variation_'.$isproductid[1].' b2bking_offer_select',
		            								'required'	=> true,
		            								'show_option_none' => esc_html__('Choose ','b2bking').wc_attribute_label(str_replace('attribute_', '', $name)),
		            								'id'		=> str_replace('attribute_', '', $name).'_'.$isproductid[1],
		            								'name'		=> $name.'_'.$isproductid[1]
		            							));
		            						}
		            					}
		            				}
		            			}
		            			?>
		            			</div>
		            				<?php 
		            				// if image is enabled in settings, and product is product_id
		            				if ($isproductid[0] === 'product' && intval(get_option('b2bking_offers_product_image_setting', 0)) === 1){
		            					// show image
				            			if (is_a($newproduct,'WC_Product_Variation') || is_a($newproduct,'WC_Product')){
						            		$link = $newproduct->get_permalink();
			            					?>
			            					<a href="<?php echo esc_attr($link);?>"><img class="b2bking_offer_image" src="<?php echo wp_get_attachment_url( $newproduct->get_image_id() ); ?>"></a>
		            					<?php
		            					}
		            				}
		            				?>
		            			</div>
		            			<div class="b2bking_myaccount_individual_offer_element_line_item"><?php echo esc_html($product_details[1]); ?></div>
		            			<div class="b2bking_myaccount_individual_offer_element_line_item"><?php

		            			if (!isset($newproduct)){
		            				$newproduct = '';
		            			}

		            			do_action('b2bking_offer_frontend_before_unit_price', $newproduct);
		            			// adjust Unit price for tax 
		            			$unit_price_display = $product_details[2];
		            			// get offer product
		            			$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
		            			$offer_product = wc_get_product($offer_id);

		            			if (is_a($offer_product,'WC_Product')){
			            			if (is_a(WC()->customer, 'WC_Customer')){
			            				if (get_option('woocommerce_calc_taxes', 'no') === 'yes'){

					            			if( wc_prices_include_tax() && ('incl' !== get_option( 'woocommerce_tax_display_shop') || WC()->customer->is_vat_exempt())) {
					            				// if prices are entered including tax, but display is without tax, remove tax 
					            				// get tax rate for the offer product
					            				$tax_rates = WC_Tax::get_base_tax_rates( $offer_product->get_tax_class( 'unfiltered' ) ); 
					            				$taxes = WC_Tax::calc_tax( $unit_price_display, $tax_rates, true ); 
					            				$unit_price_display = WC_Tax::round( $unit_price_display - array_sum( $taxes ) ); 

					            			} else if ( !wc_prices_include_tax() && ('incl' === get_option( 'woocommerce_tax_display_shop') && !WC()->customer->is_vat_exempt())){
					            				// if prices are entered excluding tax, but display is with tax, add tax
					            				$tax_rates = WC_Tax::get_rates( $offer_product->get_tax_class() );
					            				$taxes     = WC_Tax::calc_tax( $unit_price_display, $tax_rates, false );
					            				$unit_price_display = WC_Tax::round( $unit_price_display + array_sum( $taxes ) );
					            			} else {
					            				// no adjustment
					            			}
					            		}
				            		}
		            			}
		            			
		            			echo wc_price(b2bking()->get_woocs_price($unit_price_display)); 

		            			do_action('b2bking_offer_frontend_after_unit_price', $newproduct, $product_details[2]);


		            			?></div>
		            			<div class="b2bking_myaccount_individual_offer_element_line_item"><?php 

		            			if (isset($isproductid[1])){
		            				if (!in_array($isproductid[1], $insufficientstock)){
		            					echo wc_price(b2bking()->get_woocs_price($product_details[1]*$unit_price_display)); 
		            				} else {
		            					esc_html_e('Insufficient stock','b2bking');
		            				}
		            			} else {
		            				echo wc_price(b2bking()->get_woocs_price($product_details[1]*$unit_price_display)); 
		            			}

		            			do_action('b2bking_offer_frontend_after_subtotal', $newproduct, $product_details[2], $product_details[1]);

		            			

		            			?></div>

		            		</div>
		            		<?php
		            		$offer_price+=$product_details[1]*$product_details[2];
		            	}


		            	/*
		            	* Adjust for tax with 3 possibilities:
		            	* Option 1: Need to remove tax
		            	* Option 2: Need to add tax
		            	* Option 3: No adjustment
		            	*/ 

		            	// First calculate tax
		            	// get offer product
		            	$offer_id = intval(get_option('b2bking_offer_product_id_setting', 0));
		            	$offer_product = wc_get_product($offer_id);

		            	if (is_a($offer_product,'WC_Product')){
			            	if (is_a(WC()->customer, 'WC_Customer')){
			            		if (get_option('woocommerce_calc_taxes', 'no') === 'yes'){

					            	if( wc_prices_include_tax() && ('incl' !== get_option( 'woocommerce_tax_display_shop') || WC()->customer->is_vat_exempt())) {
					            		// if prices are entered including tax, but display is without tax, remove tax 
					            		// get tax rate for the offer product
					            		$tax_rates = WC_Tax::get_base_tax_rates( $offer_product->get_tax_class( 'unfiltered' ) ); 
					            		$taxes = WC_Tax::calc_tax( $offer_price, $tax_rates, true ); 
					            		$offer_price = WC_Tax::round( $offer_price - array_sum( $taxes ) ); 

					            	} else if ( !wc_prices_include_tax() && ('incl' === get_option( 'woocommerce_tax_display_shop') && !WC()->customer->is_vat_exempt())){
					            		// if prices are entered excluding tax, but display is with tax, add tax
					            		$tax_rates = WC_Tax::get_rates( $offer_product->get_tax_class() );
					            		$taxes     = WC_Tax::calc_tax( $offer_price, $tax_rates, false );
					            		$offer_price = WC_Tax::round( $offer_price + array_sum( $taxes ) );
					            	} else {
					            		// no adjustment
					            	}
					            }
				            }
				        }
		            	

		            	?>
		            	<?php
		            	do_action('b2bking_before_offer_add_to_cart_public', $post->ID);
		            	// check if there is any custom text in the offer. Display it
		            	$postidnr = apply_filters( 'wpml_object_id', $post->ID, 'post', true );
		            	$custom_text = get_post_meta($postidnr, 'b2bking_offer_customtext_textarea', true);
		            	if (!empty($custom_text) && $custom_text !== NULL){
		            	?>
			            	<div class="b2bking_myaccount_individual_offer_custom_text"><?php echo esc_textarea($custom_text); ?>
			            	</div>
			            <?php } ?>
		            	<div class="b2bking_myaccount_individual_offer_bottom_line">
		            		<div class="b2bking_myaccount_individual_offer_bottom_line_add">
		            			<?php
		            			if ($offerinstock === 'yes'){
		            				?>
			            			<button class="b2bking_myaccount_individual_offer_bottom_line_button b2bking_offer_add" value="<?php echo esc_attr($post->ID); ?>" type="button" <?php do_action('b2bking_offer_add_button'); ?>>
			            				<svg class="b2bking_myaccount_individual_offer_bottom_line_button_icon" xmlns="http://www.w3.org/2000/svg" width="21" height="19" fill="none" viewBox="0 0 21 19">
			            				  <path fill="#fff" d="M18.401 11.875H7.714l.238 1.188h9.786c.562 0 .978.53.854 1.087l-.202.901a2.082 2.082 0 011.152 1.87c0 1.159-.93 2.096-2.072 2.079-1.087-.016-1.981-.914-2.01-2.02a2.091 2.091 0 01.612-1.543H8.428c.379.378.614.903.614 1.485 0 1.18-.967 2.131-2.14 2.076-1.04-.05-1.886-.905-1.94-1.964a2.085 2.085 0 011.022-1.914L3.423 2.375H.875A.883.883 0 010 1.485V.89C0 .399.392 0 .875 0h3.738c.416 0 .774.298.857.712l.334 1.663h14.32c.562 0 .978.53.854 1.088l-1.724 7.719a.878.878 0 01-.853.693zm-3.526-5.64h-1.75V4.75a.589.589 0 00-.583-.594h-.584a.589.589 0 00-.583.594v1.484h-1.75a.589.589 0 00-.583.594v.594c0 .328.26.594.583.594h1.75V9.5c0 .328.261.594.583.594h.584a.589.589 0 00.583-.594V8.016h1.75a.589.589 0 00.583-.594v-.594a.589.589 0 00-.583-.594z"/>
			            				</svg>
			            			<?php echo apply_filters('b2bking_offer_add_to_cart_button', esc_html__('Add to Cart','b2bking')); ?></button>
			            			<?php do_action('b2bking_after_offer_add_to_cart_button', $post->ID); ?>
			            			<button class="b2bking_myaccount_individual_offer_bottom_line_button b2bking_offer_download" value="<?php echo esc_attr($post->ID); ?>" type="button">
			            				<svg class="b2bking_myaccount_individual_offer_bottom_line_button_icon" xmlns="http://www.w3.org/2000/svg" width="21" height="19" fill="none" viewBox="0 0 23 23">
										  <path fill="#fff" d="M9.778 4.889h7.333v2.444H9.778V4.89zm0 4.889h7.333v2.444H9.778V9.778zm0 4.889h7.333v2.444H9.778v-2.444zm-4.89-9.778h2.445v2.444H4.89V4.89zm0 4.889h2.445v2.444H4.89V9.778zm0 4.889h2.445v2.444H4.89v-2.444zM20.9 0H1.1C.489 0 0 .489 0 1.1v19.8c0 .489.489 1.1 1.1 1.1h19.8c.489 0 1.1-.611 1.1-1.1V1.1c0-.611-.611-1.1-1.1-1.1zm-1.344 19.556H2.444V2.444h17.112v17.112z"></path>
										</svg>
			            				
			            			<?php esc_html_e('↓ PDF','b2bking'); ?></button>
		            				<?php
		            			} else {
		            				esc_html_e('Products are not in stock.','b2bking');
		            			}
		            			?>
		            			
		            		</div>
		            		<div class="b2bking_myaccount_individual_offer_bottom_line_total">
		            			<?php esc_html_e('Total: ','b2bking'); ?><strong><?php echo wc_price(b2bking()->get_woocs_price($offer_price));?><?php do_action('b2bking_offer_frontend_after_total', $offer_price); ?></strong>
		            		</div>
		            	</div>
		            </div>

		            <?php

		        }
		    } else {
		    	if ($shortcode_offer_id === 'none'){
		    		wc_print_notice(esc_html__('No offers available yet.', 'b2bking'), 'notice');
		    	}
		    }
		    // Reset postdata
		    wp_reset_postdata();


		    // show pagination if not individual offer
		    if ($shortcode_offer_id === 'none'){
			    // Custom query loop pagination
			    ?>
			    <div class="b2bking_myaccount_offers_pagination_container">
				    <div class="b2bking_myaccount_conversations_pagination_button b2bking_newer_offers_button">
				    	<?php previous_posts_link( esc_html__('←   Newer offers','b2bking') ); ?>
				    </div>
				    <div class="b2bking_myaccount_conversations_pagination_button b2bking_older_offers_button">
				    	<?php next_posts_link( esc_html__('Older offers   →','b2bking'), $custom_query->max_num_pages ); ?>
				    </div>
				</div>
				<?php
			}

		    // Reset main query object
		    $wp_query = NULL;
		    $wp_query = $temp_query;
			
			echo '</div>';
		}

	    

		$content = ob_get_contents();
		ob_end_clean();
		return $content;
	}

	function b2bking_purchaselists_shortcode(){
		add_shortcode('b2bking_purchaselists', array($this, 'b2bking_purchaselists_shortcode_content'));

	}
	function b2bking_purchaselists_shortcode_content(){
		ob_start();

		if (isset($_GET['id'])){
			$purchase_list_id = sanitize_text_field( $_GET['id'] );
		} else {
			$purchase_list_id = '';
		}
		if (!empty($purchase_list_id)){
			$this->b2bking_purchase_list_endpoint_content();
		} else {

			$bulk_order_endpoint_url = wc_get_account_endpoint_url(get_option('b2bking_bulkorder_endpoint_setting','bulkorder'));
			
			do_action('b2bking_before_purchase_lists_content');
			?>

			<div class="b2bking_purchase_list_top_container">
				<div class="b2bking_purchase_lists_top_title">
					<?php echo apply_filters('b2bking_my_account_purchaselists_title', esc_html__('Purchase lists', 'b2bking')); ?>
				</div>
				<?php

				// if bulk order form is disabled, remove the "new list" button
				// if order form theme is indigo or cream , disable also
				$theme = get_option( 'b2bking_order_form_theme_setting', 'classic' );
				if (intval(get_option('b2bking_enable_bulk_order_form_setting', 1)) === 1 && $theme === 'classic'){ 
					// continue
				} else {

					$bulk_order_endpoint_url = wc_get_endpoint_url('new-list');

				}

				?>
				<a href="<?php echo esc_attr($bulk_order_endpoint_url); ?>" class="b2bking_purchase_list_new_link">
					<button type="button" id="b2bking_purchase_list_new_button">
						<svg class="b2bking_purchase_list_new_button_icon" xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none" viewBox="0 0 22 22">
						  <path fill="#fff" d="M9.778 4.889h7.333v2.444H9.778V4.89zm0 4.889h7.333v2.444H9.778V9.778zm0 4.889h7.333v2.444H9.778v-2.444zm-4.89-9.778h2.445v2.444H4.89V4.89zm0 4.889h2.445v2.444H4.89V9.778zm0 4.889h2.445v2.444H4.89v-2.444zM20.9 0H1.1C.489 0 0 .489 0 1.1v19.8c0 .489.489 1.1 1.1 1.1h19.8c.489 0 1.1-.611 1.1-1.1V1.1c0-.611-.611-1.1-1.1-1.1zm-1.344 19.556H2.444V2.444h17.112v17.112z"></path>
						</svg>
						<?php esc_html_e('New List','b2bking'); ?>
					</button>
				</a>


			</div>
			<?php

			do_action('b2bking_before_purchase_lists_table');


			?>
			<table id="b2bking_purchase_lists_table">
			        <thead>
			            <tr>
			                <th><?php esc_html_e('List name','b2bking'); ?></th>
			                <th><?php esc_html_e('Number of items','b2bking'); ?></th>
			                <th><?php esc_html_e('User','b2bking'); ?></th>
			                <th><?php esc_html_e('Actions','b2bking'); ?></th>

			            </tr>
			        </thead>
			        <tbody>
			        	<?php
			        	// get all lists of the user and his subaccounts
			        	$current_user = get_current_user_id();
			        	$subaccounts_list = explode(',', get_user_meta($current_user, 'b2bking_subaccounts_list', true));
			        	$subaccounts_list = array_filter($subaccounts_list); // filter blank, null, etc.
			        	// add current user to subaccounts to form a complete accounts list
			        	array_push($subaccounts_list, $current_user);

			        	// if multiple levels, add all subaccounts orders to main query
			        	if (apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
			        		$subaccounts_list = array_filter(array_unique($this->get_all_subaccounts($current_user, array($current_user))));
			        	}

			        	// if current account is subaccount AND has permission to view all account purchase lists, add parent account+all subaccounts lists
			        	$account_type = get_user_meta($current_user, 'b2bking_account_type', true);
			        	if ($account_type === 'subaccount'){
			        		$permission_view_all_lists = filter_var(get_user_meta($current_user, 'b2bking_account_permission_view_lists', true),FILTER_VALIDATE_BOOLEAN);
			        		if ($permission_view_all_lists === true){
			        			// has permission
			        			$parent_account = get_user_meta($current_user, 'b2bking_account_parent', true);
			        			$parent_subaccounts_list = explode(',', get_user_meta($parent_account, 'b2bking_subaccounts_list', true));
			        			$parent_subaccounts_list = array_filter($parent_subaccounts_list); // filter blank, null, etc.
			        			array_push($parent_subaccounts_list, $parent_account); // add parent itself to form complete parent accounts list

			        			$subaccounts_list = array_merge($subaccounts_list, $parent_subaccounts_list);

			        			// check if parent has a parent
			        			if (apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
			        				$parent_account_type = get_user_meta($parent_account, 'b2bking_account_type', true);
			        				if ($parent_account_type === 'subaccount'){
			        					$parent_parent_account = get_user_meta($parent_account, 'b2bking_account_parent', true);

			        					$parent_parent_subaccounts_list = explode(',', get_user_meta($parent_parent_account, 'b2bking_subaccounts_list', true));
			        					$parent_parent_subaccounts_list = array_filter($parent_parent_subaccounts_list); // filter blank, null, etc.
			        					array_push($parent_parent_subaccounts_list, $parent_parent_account); // add parent itself to form complete parent accounts list

			        					$subaccounts_list = array_merge($subaccounts_list, $parent_parent_subaccounts_list);
			        				}
			        			}
			        		}
			        	}


			        	$purchase_lists = get_posts([
				    		'post_type' => 'b2bking_list',
				    	  	'post_status' => 'publish',
				    	  	'numberposts' => -1,
				    	  	'author__in' => $subaccounts_list,
				    	]);

				    	$endpointurl = apply_filters('b2bking_purchaselist_endpoint_url_link', wc_get_endpoint_url(get_option('b2bking_purchaselist_endpoint_setting','purchase-list')));

				    	if (!is_account_page()){
				    		$endpointurl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
				    	}

				    	foreach ($purchase_lists as $list){
				    		$list_details = get_post_meta($list->ID, 'b2bking_purchase_list_details', true);
				    		$list_items_array = explode('|', $list_details);
				    		$list_items_array = array_filter($list_items_array);
				    		$items_number = count($list_items_array);
				    		$list_author_id = get_post_field( 'post_author', $list->ID );
				    		$list_author_username = get_user_by('id', $list_author_id)->user_login;
				    		?>
				    		<tr>
				    		    <td><?php echo esc_html($list->post_title); ?></td>
				    		    <td>
				    		    	<?php 
				    		    	echo esc_html($items_number); 
				    		    	if ($items_number === 1){
				    		    		esc_html_e(' item', 'b2bking'); 	
				    		    	} else {
				    		    		esc_html_e(' items', 'b2bking'); 
									}
				    		    	?>
				    		    	
				    		    </td>
				    		    <td><?php echo esc_html($list_author_username); ?></td>
				    		    <td>
				    		    	<a class="b2bking_purchase_list_button_href" href="<?php echo esc_url(add_query_arg('id',$list->ID, $endpointurl)); ?>">
				    		    		<button type="button" class="b2bking_purchase_lists_view_list"><img class="b2bking_list_download" src="<?php echo plugins_url('../includes/assets/images/view2.svg', __FILE__); ?>"><?php esc_html_e('View','b2bking'); ?></button>
				    		    	</a>
				    		    	<a class="b2bking_download_list_button b2bking_purchase_list_button_href id_<?php echo esc_attr($list->ID);?>" href="#">
				    		    		<button type="button" class="b2bking_purchase_lists_view_list"><img class="b2bking_list_download" src="<?php echo plugins_url('../includes/assets/images/download1.svg', __FILE__); ?>"><?php esc_html_e('Download','b2bking'); ?></button>
				    		    	</a>
				    		    </td>
				    		</tr>

				    		<?php
				    	}		        	

			        	?>
			        			           
			        </tbody>
			        <tfoot>
			            <tr>
			                <th><?php esc_html_e('List name','b2bking'); ?></th>
			                <th><?php esc_html_e('Number of items','b2bking'); ?></th>
			                <th><?php esc_html_e('User','b2bking'); ?></th>
			                <th><?php esc_html_e('Actions','b2bking'); ?></th>
			            </tr>
			        </tfoot>
		   	 </table>
		    <?php
		}
		$content = ob_get_contents();
		ob_end_clean();
		return $content;
	}

	// Enables bulk order shortcode
	function b2bking_bulkorder_shortcode(){
		add_shortcode('b2bking_bulkorder', array($this, 'b2bking_bulkorder_shortcode_content'));
		add_shortcode('b2bking_variations_table', array($this, 'b2bking_variations_table_shortcode_content'));
	}

	function b2bking_variations_table_shortcode_content( $atts ){
		ob_start();

		$atts = shortcode_atts(
	        array(
	            'product_id' => '',
	            'width' => 'adaptive',
	            'style' => '',
	            'hidecolumns' => '',
	        ), 
	    $atts);

		$hidecolumns = $atts['hidecolumns'];
		$width = $atts['width'];
		$style = $atts['style'];
	    $product_id = $atts['product_id'];
	    if (empty($product_id)){
	    	global $post;
	    	if (isset($post->ID)){
	    		$product_id = $post->ID;
	    	} else {
	    		global $product;
	    		if (is_a($product,'WC_Product_Variation') || is_a($product,'WC_Product')){
	    			$product_id = $product->get_id();
	    		}
	    	}
	    }

	    if (!empty($product_id)){
	    	$sanitized_product_id = sanitize_text_field($product_id);
	    	$sanitized_style = sanitize_text_field($style);
	    	$sanitized_hidecolumns = sanitize_text_field($hidecolumns);
	    	$sanitized_width = sanitize_text_field($width);
	    	echo do_shortcode(apply_filters('b2bking_bulk_variations_table_shortcode', '[b2bking_bulkorder theme=cream variationstable=yes product_list="'.$sanitized_product_id.'" multiselect="yes" style="'.$sanitized_style.'" hidecolumns="'.$sanitized_hidecolumns.'" width="'.$sanitized_width.'"]'));
	    	?>
	    	<style type="text/css">
	    		.b2bking_bulkorder_form_container_content_line_cream_view_options, .b2bking_bulkorder_cream_header_container{
	    			display:none !important;
	    		}
	    		.b2bking_bulkorder_form_container_content_line_cream_hidden {
	    			display: flex !important;
	    		}
	    		.b2bking_bulkorder_container_final{
	    			clear:both;
	    		}
	    	</style>
	    	<?php
	    }

		return ob_get_clean();
	}

	// Bulk order shortcode content
	function b2bking_bulkorder_shortcode_content( $atts ){

		wp_enqueue_style('b2bking_fonts_dmsans', plugins_url('../includes/assets/css/fonts-dmsans.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);

		if (B2BKING_FILE_RELEASE === 'DEV'){
			wp_enqueue_style('b2bking_bulkorder', plugins_url('../includes/assets/css/style-bulkorder.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);
		} else {
			wp_enqueue_style('b2bking_bulkorder', plugins_url('../includes/assets/css/style-bulkorder.min.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);
		}

		$atts = shortcode_atts(
	        array(
	            'theme' => get_option( 'b2bking_order_form_theme_setting', 'classic' ),
	            'category' => 'all',
	            'tag' => 'all',
	            'sku' => 'no',
	            'multiselect' => get_option( 'b2bking_order_form_cream_multiselect_setting', 0 ),
	            'stock' => 'no',
	            'sortby' => get_option( 'b2bking_order_form_sortby_setting', 'atoz' ),
	            'exclude' => '',
	            'product_list' => '',
	            'attributes' => 'no',
	            'instock' => 'instock',
	            'width' => 'adaptive',
	            'hidecolumns' => '',
	            'style' => '',
	            'variationstable' => 'no',
	            'attributestext' => apply_filters('b2bking_orderform_attributes_text', esc_html__('Attributes','b2bking')),
	        ), 
	    $atts);

	    $theme = sanitize_text_field($atts['theme']);
	    $multiselect = sanitize_text_field($atts['multiselect']);
	    if ($multiselect !== 'yes' && $multiselect !== 'no'){
		    if (intval($multiselect) === 0){
		    	$multiselect = 'no';
		    } else if (intval($multiselect) === 1){
		    	$multiselect = 'yes';
		    }
		}

	    $is_variations_table = sanitize_text_field($atts['variationstable']);
	    $attributes = sanitize_text_field($atts['attributes']);
	    $width = sanitize_text_field($atts['width']);
	    $hidecolumns = sanitize_text_field($atts['hidecolumns']);
	    $style = sanitize_text_field($atts['style']);
	    if (empty($hidecolumns)){
	    	$hidecolumns = array();
	    } else {
	    	$hidecolumns = explode(',', $hidecolumns);
	    	$hidecolumns = array_map('trim', $hidecolumns);
	    	$hidecolumns = array_map('sanitize_text_field', $hidecolumns);
	    }

	    $attributestext = sanitize_text_field($atts['attributestext']);
	    $showsku = sanitize_text_field($atts['sku']);
	    $showstock = sanitize_text_field($atts['stock']);
	    $category = sanitize_text_field($atts['category']);
	    if ($category === 'all'){
	    	$category = 0;
	    }
	    $tag = sanitize_text_field($atts['tag']);
	    if ($tag === 'all'){
	    	$tag = 0;
	    }
	    $exclude = sanitize_text_field($atts['exclude']);
	    $product_list = sanitize_text_field($atts['product_list']);
	    $sortby = sanitize_text_field($atts['sortby']);
	    $instock = sanitize_text_field($atts['instock']);

	    if (apply_filters('b2bking_bulkorder_instock_filter', false)){
	    	if (apply_filters('b2bking_bulkorder_instock_filter_default_all', true)){
		    	$instock = 'all';
		    }
	    }

		ob_start();

		if ($this->user_has_offer_in_cart() === 'yes'){
			if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'))){
				wc_print_notice( esc_html__('While you have an offer / pack in cart, you cannot add products to quote', 'b2bking'), 'error' );
			}
		}

		?>
		<div class="b2bking_bulkorder_container_final <?php if ($is_variations_table === 'yes'){ echo 'variations_table'; } ?>">
			<input type="hidden" class="b2bking_bulkorder_exclude" value="<?php echo esc_attr($exclude);?>">
			<input type="hidden" class="b2bking_bulkorder_product_list" value="<?php echo esc_attr($product_list);?>">
			<input type="hidden" class="b2bking_bulkorder_category" value="<?php echo esc_attr($category);?>">
			<input type="hidden" class="b2bking_bulkorder_tag" value="<?php echo esc_attr($tag);?>">
			<input type="hidden" class="b2bking_bulkorder_attributes" value="<?php echo esc_attr($attributes);?>">
			<input type="hidden" class="b2bking_bulkorder_sortby" value="<?php echo esc_attr($sortby);?>">
			<input type="hidden" class="b2bking_bulkorder_instock" value="<?php echo esc_attr($instock);?>">
			<?php

			if ($theme === 'classic'){
				?>
				<div class="b2bking_bulkorder_form_container">
					<div class="b2bking_bulkorder_form_container_top">
						<?php esc_html_e('Bulk Order Form', 'b2bking'); ?>
					</div>
					<div class="b2bking_bulkorder_form_container_content">
						<div class="b2bking_bulkorder_form_container_content_header">
							<?php do_action('b2bking_bulkorder_column_header_start'); ?>

							<div class="b2bking_bulkorder_form_container_content_header_product">
								<?php
								if (intval(get_option( 'b2bking_search_by_sku_setting', 1 )) === 1){
									esc_html_e('Search by', 'b2bking');
									ob_start();
								?>
									<select id="b2bking_bulkorder_searchby_select">
										<option value="productname"><?php esc_html_e('Product Name', 'b2bking'); ?></option>
										<option value="sku"><?php 

										echo apply_filters('b2bking_sku_search_display', esc_html__('SKU', 'b2bking')); 

										?></option>
									</select>
								<?php 
								$content = ob_get_clean();
								echo apply_filters('b2bking_classic_form_searchby_display', $content);
								} else {
									esc_html_e('Product name', 'b2bking');
								}
								?>
		            		</div>
		            		<div class="b2bking_bulkorder_form_container_content_header_qty">
		            			<?php esc_html_e('Qty', 'b2bking'); ?>
		            		</div>
		            		<?php do_action('b2bking_bulkorder_column_header_mid'); ?>
		            		<div class="b2bking_bulkorder_form_container_content_header_subtotal">
		            			<?php esc_html_e('Subtotal', 'b2bking'); ?>
		            		</div>

		            		<?php do_action('b2bking_bulkorder_column_header_end'); ?>

						</div>

		            	<?php
		            	// show 5 lines of bulk order form
		            	$lines = apply_filters('b2bking_bulkorder_lines_default', 5);
		            	for ($i = 1; $i <= $lines; $i++){
		            		?>
		            		<div class="b2bking_bulkorder_form_container_content_line"><input type="text" class="b2bking_bulkorder_form_container_content_line_product" <?php 

		            		if ($i === 1){
		            			echo 'placeholder="'.esc_attr__('Search for a product...','b2bking').'"';
		            		}

		            		?>><input type="number" min="0" class="b2bking_bulkorder_form_container_content_line_qty b2bking_bulkorder_form_container_content_line_qty_classic" step="1"><?php do_action('b2bking_bulkorder_column_header_mid_content'); ?><div class="b2bking_bulkorder_form_container_content_line_subtotal"><?php 

		            		if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'))){
		            			esc_html_e('Quote','b2bking');
		            		} else {
		            			if (intval(get_option( 'b2bking_show_accounting_subtotals_setting', 0 )) === 1){
		            				echo wc_price(0);
		            			} else {
		            				echo get_woocommerce_currency_symbol().'0'; 
		            			}
		            		}

		            		?></div><?php do_action('b2bking_bulkorder_column_header_end_content'); ?><div class="b2bking_bulkorder_form_container_content_line_livesearch"></div></div>
		            		<?php
		            	}
		            	?>

		            	<!-- new line button -->
		            	<div class="b2bking_bulkorder_form_container_newline_container">
		            		<button class="b2bking_bulkorder_form_container_newline_button">
		            			<svg class="b2bking_bulkorder_form_container_newline_button_icon" xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none" viewBox="0 0 22 22">
		            			  <path fill="#fff" d="M11 1.375c-5.315 0-9.625 4.31-9.625 9.625s4.31 9.625 9.625 9.625 9.625-4.31 9.625-9.625S16.315 1.375 11 1.375zm4.125 10.14a.172.172 0 01-.172.172h-3.265v3.266a.172.172 0 01-.172.172h-1.032a.172.172 0 01-.171-.172v-3.265H7.046a.172.172 0 01-.172-.172v-1.032c0-.094.077-.171.172-.171h3.266V7.046c0-.095.077-.172.171-.172h1.032c.094 0 .171.077.171.172v3.266h3.266c.095 0 .172.077.172.171v1.032z"/>
		            			</svg>
		            			<?php esc_html_e('new line','b2bking'); ?>
		            		</button>
		            	</div>

		            	<div class="b2bking_bulkorder_form_newline_template" style="display:none"><div class="b2bking_bulkorder_form_container_content_line"><input type="text" class="b2bking_bulkorder_form_container_content_line_product"><input type="number" min="0" step="1" class="b2bking_bulkorder_form_container_content_line_qty b2bking_bulkorder_form_container_content_line_qty_classic"><?php do_action('b2bking_bulkorder_column_header_mid_newline_content'); ?><div class="b2bking_bulkorder_form_container_content_line_subtotal">pricetext</div><div class="b2bking_bulkorder_form_container_content_line_livesearch"></div></div></div>

		            	<!-- add to cart button -->
		            	<div class="b2bking_bulkorder_form_container_bottom">
		            		<!-- initialize hidden loader to get it to load instantly -->
		            		<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/loader.svg', __FILE__); ?>">
		            		<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/no_products.svg', __FILE__); ?>">
		            		<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/close.svg', __FILE__); ?>">
		            		<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/filter.svg', __FILE__); ?>">

		            		<div class="b2bking_bulkorder_form_container_bottom_add">
		            			<button class="b2bking_bulkorder_form_container_bottom_add_button" type="button">
		            				<svg class="b2bking_bulkorder_form_container_bottom_add_button_icon" xmlns="http://www.w3.org/2000/svg" width="21" height="19" fill="none" viewBox="0 0 21 19">
		            				  <path fill="#fff" d="M18.401 11.875H7.714l.238 1.188h9.786c.562 0 .978.53.854 1.087l-.202.901a2.082 2.082 0 011.152 1.87c0 1.159-.93 2.096-2.072 2.079-1.087-.016-1.981-.914-2.01-2.02a2.091 2.091 0 01.612-1.543H8.428c.379.378.614.903.614 1.485 0 1.18-.967 2.131-2.14 2.076-1.04-.05-1.886-.905-1.94-1.964a2.085 2.085 0 011.022-1.914L3.423 2.375H.875A.883.883 0 010 1.485V.89C0 .399.392 0 .875 0h3.738c.416 0 .774.298.857.712l.334 1.663h14.32c.562 0 .978.53.854 1.088l-1.724 7.719a.878.878 0 01-.853.693zm-3.526-5.64h-1.75V4.75a.589.589 0 00-.583-.594h-.584a.589.589 0 00-.583.594v1.484h-1.75a.589.589 0 00-.583.594v.594c0 .328.26.594.583.594h1.75V9.5c0 .328.261.594.583.594h.584a.589.589 0 00.583-.594V8.016h1.75a.589.589 0 00.583-.594v-.594a.589.589 0 00-.583-.594z"/>
		            				</svg>
		            			<?php 

		            			if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'))){
		            				esc_html_e('Add to Quote','b2bking'); 
		            			} else {
		            				esc_html_e('Add to Cart','b2bking'); 	
		            			}
		            			

		            			?>
		            			</button>
		            			<?php if (intval(get_option('b2bking_enable_purchase_lists_setting', 1)) === 1){ ?>
			            			<button class="b2bking_bulkorder_form_container_bottom_save_button" type="button">
			            				<svg class="b2bking_bulkorder_form_container_bottom_save_button_icon" xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none" viewBox="0 0 22 22">
			            				  <path fill="#fff" d="M9.778 4.889h7.333v2.444H9.778V4.89zm0 4.889h7.333v2.444H9.778V9.778zm0 4.889h7.333v2.444H9.778v-2.444zm-4.89-9.778h2.445v2.444H4.89V4.89zm0 4.889h2.445v2.444H4.89V9.778zm0 4.889h2.445v2.444H4.89v-2.444zM20.9 0H1.1C.489 0 0 .489 0 1.1v19.8c0 .489.489 1.1 1.1 1.1h19.8c.489 0 1.1-.611 1.1-1.1V1.1c0-.611-.611-1.1-1.1-1.1zm-1.344 19.556H2.444V2.444h17.112v17.112z"/>
			            				</svg>
			            			<?php esc_html_e('Save list','b2bking'); ?>
			            			</button>
		            			<?php } ?>

		            		</div>
		            		<div class="b2bking_bulkorder_form_container_bottom_total">
		            			<?php
		            			if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'))){

		            			} else {
		            				?>
		            					<?php esc_html_e('Total: ','b2bking'); ?><strong><?php echo wc_price(0);?></strong>
		            				<?php	
		            			}?>
		            			
		            		</div>
		            	</div>


		            </div>
				</div>
				<?php
			}

			if ($theme === 'indigo'){


				?>
				<div class="b2bking_bulkorder_form_container b2bking_bulkorder_form_container_indigo">

					<div class="b2bking_bulkorder_form_container_content_header_top">
						<input type="text" id="b2bking_bulkorder_search_text_indigoid" class="b2bking_bulkorder_search_text_indigo" placeholder="<?php esc_html_e('Search products...','b2bking');?>">
					</div>


					<div class="b2bking_bulkorder_form_container_top b2bking_bulkorder_form_container_top_indigo">
						<?php do_action('b2bking_bulkorder_column_header_start'); ?>

						<div class="b2bking_bulkorder_form_container_content_header_product b2bking_bulkorder_form_container_content_header_product_indigo">
							<?php esc_html_e('Product', 'b2bking'); ?>
	            		</div>
	            		<div class="b2bking_bulkorder_form_container_content_header_qty b2bking_bulkorder_form_container_content_header_qty_indigo">
	            			<?php esc_html_e('Qty', 'b2bking'); ?>
	            		</div>
	            		<?php do_action('b2bking_bulkorder_column_header_mid'); ?>
	            		<div class="b2bking_bulkorder_form_container_content_header_subtotal b2bking_bulkorder_form_container_content_header_subtotal_indigo">
	            			<?php esc_html_e('Subtotal', 'b2bking'); ?>
	            		</div>
	            		<div class="b2bking_bulkorder_form_container_content_header_subtotal b2bking_bulkorder_form_container_content_header_cart_indigo">
	            			<?php esc_html_e('Cart', 'b2bking'); ?>
	            		</div>
	            		<?php do_action('b2bking_bulkorder_column_header_end'); ?>
					</div>


					<div class="b2bking_bulkorder_form_container_content b2bking_bulkorder_form_container_content_indigo">

		            	<input type="hidden" id="b2bking_indigo_order_form" value="1">
		            	<!-- initialize hidden loader to get it to load instantly -->
		            	<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/loader.svg', __FILE__); ?>">
		            	<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/no_products.svg', __FILE__); ?>">
		            	<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/close.svg', __FILE__); ?>">
		            	<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/filter.svg', __FILE__); ?>">


		            </div>
				</div>
				<?php
			}

			if ($theme === 'cream'){

				$hidecolumns = apply_filters('b2bking_cream_hidecolumns_cream', $hidecolumns);

				if ($style === 'nameqty'){ // 2 columns, name, qty
					$hidecolumns[] = 'subtotal';
					$hidecolumns[] = 'cart';
					// $hidecolumns[] = 'multiselect';
					$hidecolumns = apply_filters('b2bking_cream_hidecolumns_nameqty', $hidecolumns);
					?>
					<style>
						.b2bking_bulkorder_indigo_product_container, .b2bking_cream_input_group, .b2bking_bulkorder_form_container_content_header_product.b2bking_bulkorder_form_container_content_header_product_indigo.b2bking_bulkorder_form_container_content_header_product_cream, .b2bking_bulkorder_form_container_content_header_qty.b2bking_bulkorder_form_container_content_header_qty_indigo.b2bking_bulkorder_form_container_content_header_qty_cream, .b2bking_bulkorder_indigo_product_container.b2bking_bulkorder_cream_product_container{
							width:50% !important;
						}
						.b2bking_bulkorder_form_container_top.b2bking_bulkorder_form_container_top_indigo.b2bking_bulkorder_form_container_top_cream {
						    padding-right: 0px;
						}
						.b2bking_bulkorder_form_container_content_header_qty.b2bking_bulkorder_form_container_content_header_qty_indigo.b2bking_bulkorder_form_container_content_header_qty_cream{
							margin-right: 5% !important;
						}
						#b2bking_cream_add_selected.active {
						    background: #000;
						}
						#b2bking_cream_add_selected.active:hover {
						    background: #3d3d3d !important;
						}
						.b2bking_bulkorder_form_container {
						    min-width: 300px;
						    max-width: 550px;
						}
						.b2bking_bulkorder_form_container_content_line_indigo.b2bking_bulkorder_form_container_content_line_cream {
						    min-height: 66px !important;
						}
						
					</style>
					<?php
				}

				if (in_array('image', $hidecolumns)){
					?>
					<style>
						img.b2bking_bulkorder_indigo_image.b2bking_bulkorder_cream_image {
						    display: none !important;
						}
					</style>
					<?php
				}

				if (in_array('subtotal', $hidecolumns)){
					?>
					<style>
						.b2bking_bulkorder_form_container_content_header_subtotal_cream, .b2bking_bulkorder_form_container_content_line_subtotal{
							display: none !important;
						}
					</style>
					<?php
				}
				if (in_array('cart', $hidecolumns)){
					?>
					<style>
						.b2bking_bulkorder_form_container_content_header_cart_cream, .b2bking_bulkorder_cream_add, .b2bking_bulkorder_form_container_content_line_cart_cream, .b2bking_bulkorder_form_container_content_header_subtotal.b2bking_bulkorder_form_container_content_header_cart_indigo.b2bking_bulkorder_form_container_content_header_cart_cream{
							display: none !important;
						}
					</style>
					<?php
				}
				if (in_array('multiselect', $hidecolumns)){
					?>
					<style>
						.b2bking_bulkorder_form_container_content_multiselect_cream{
							display: none !important;
						}
					</style>
					<?php
				}


				?>
				<div class="b2bking_bulkorder_form_container <?php echo 'multiselect_'.esc_attr($multiselect).' '; ?><?php echo esc_attr($width); ?> b2bking_bulkorder_form_container_indigo b2bking_bulkorder_form_container_cream b2bking_orderform_<?php echo get_option( 'b2bking_order_form_creme_cart_button_setting', 'cart' );?>_container <?php 
					if ($showsku === 'yes' || $showstock === 'yes'){
						echo 'b2bking_has_extra_column';
					}

					?>">

					<div class="b2bking_bulkorder_cream_header_container">
						<div class="b2bking_bulkorder_form_container_content_header_top b2bking_bulkorder_form_container_content_header_top_cream b2bking_orderform_filters">
							<span class="b2bking_bulkorder_search_text_cream"><?php esc_html_e('Filters','b2bking');?></span>
							<div id="b2bking_bulkorder_cream_filter_icon">
								<img src="<?php echo plugins_url('../includes/assets/images/filter.svg', __FILE__); ?>">
							</div>
						</div>
						<?php
						if ($attributes !== 'no'){
							?>
							<div class="b2bking_bulkorder_form_container_content_header_top b2bking_bulkorder_form_container_content_header_top_cream b2bking_orderform_attributes">
								<span class="b2bking_bulkorder_search_text_cream"><?php echo esc_html($attributestext); ?></span>
								<div id="b2bking_bulkorder_cream_filter_icon_attributes">
									<img src="<?php echo plugins_url('../includes/assets/images/attributes.svg', __FILE__); ?>">
								</div>
							</div>
							<?php
						}

						// prepopulate based on query args
						$search = '';
						if (apply_filters('b2bking_prepopulate_bulkorder_search', true)){
							if (isset($_GET['search'])){
								$search = sanitize_text_field($_GET['search']);
							} else if (isset($_GET['b2bkingsearch'])){
								$search = sanitize_text_field($_GET['b2bkingsearch']);
							}
						}

						?>

						<div class="b2bking_bulkorder_form_container_content_header_top b2bking_bulkorder_form_container_content_header_top_cream">
							<input type="text" id="b2bking_bulkorder_search_text_indigoid" class="b2bking_bulkorder_search_text_indigo b2bking_bulkorder_search_text_cream" placeholder="<?php esc_html_e('Search products...','b2bking');?>" value="<?php echo $search; ?>">
							<div class="b2bking_bulkorder_cream_search_icon b2bking_bulkorder_cream_search_icon_show b2bking_bulkorder_cream_search_icon_search">
								<img src="<?php echo plugins_url('../includes/assets/images/search.svg', __FILE__); ?>">
							</div>
							<div class="b2bking_bulkorder_cream_search_icon b2bking_bulkorder_cream_search_icon_hide b2bking_bulkorder_cream_search_icon_clear">
								<img src="<?php echo plugins_url('../includes/assets/images/clear.svg', __FILE__); ?>">
							</div>
						</div>

						<?php

						if (is_object( WC()->cart )){
							$cartcount = WC()->cart->get_cart_contents_count();
							$cartsubtotal = WC()->cart->get_cart_subtotal();
						} else {
							$cartcount = 0;
							$cartsubtotal = 0;
						}

						?>

						<div class="b2bking_bulkorder_form_container_content_header_top b2bking_bulkorder_form_container_content_header_top_cream b2bking_orderform_<?php echo get_option( 'b2bking_order_form_creme_cart_button_setting', 'cart' );?> b2bking_orderform_<?php if ($cartcount == 0) {echo get_option( 'b2bking_order_form_creme_cart_button_setting', 'cart' ).'_inactive'; } ?>">
							<div id="b2bking_bulkorder_cream_cart_icon">
								<img src="<?php echo plugins_url('../includes/assets/images/cart.svg', __FILE__); ?>">
							</div>
							<div id="b2bking_bulkorder_cream_filter_cart_text">
								<?php 


									if (get_option( 'b2bking_order_form_creme_cart_button_setting', 'cart' ) === 'cart'){
										echo '<span class="b2bking_cream_cart_button_price">'.$cartsubtotal.' </span><span class="b2bking_cream_cart_button_items"><span class="b2bking_cream_cart_button_items_qty">'.$cartcount.'</span>'.' '.esc_html__('items','b2bking').'</span>';
									}

									if (get_option( 'b2bking_order_form_creme_cart_button_setting', 'cart' ) === 'carticon'){
										echo $cartcount; 
									}

									if (get_option( 'b2bking_order_form_creme_cart_button_setting', 'cart' ) === 'checkout'){
										esc_html_e('Checkout','b2bking');
									}

								?>
							</div>
						</div>
					</div>

					<div class="b2bking_bulkorder_form_cream_main_container b2bking_filters_closed">
						<div class="b2bking_bulkorder_form_container_cream_filters b2bking_filters_closed">
							<div class="b2bking_bulkorder_form_container_cream_filters_content_first">
								<div class="b2bking_bulkorder_filter_header b2bking_bulkorder_filter_header_sortby <?php 
								$skipsort = apply_filters('b2bking_bulkorder_skip_sort', false);
								if ($skipsort){
									echo 'b2bking_bulkorder_filters_list_sortby_hidden';
								}
								?>"><?php esc_html_e('Sort By','b2bking');?></div>
								<ul class="b2bking_bulkorder_filters_list_sortby <?php 
								if ($skipsort){
									echo 'b2bking_bulkorder_filters_list_sortby_hidden';
								}
								?>">
									<?php
									$available_sort_options = apply_filters('b2bking_bulkorder_sorting_options', array('automatic','bestselling', 'latest', 'atoz','ztoa'));

									if (in_array('automatic', $available_sort_options)){
										?>
										<li value="automatic" <?php if ($sortby === 'automatic'){ echo 'style="text-decoration:underline;"';} ?>><?php esc_html_e('Automatic','b2bking');?></li>
										<?php
									}

									if (in_array('bestselling', $available_sort_options)){
										?>
										<li value="bestselling" <?php if ($sortby === 'bestselling'){ echo 'style="text-decoration:underline;"';} ?>><?php esc_html_e('Best Selling','b2bking');?></li>
										<?php
									}

									if (in_array('latest', $available_sort_options)){
										?>
										<li value="latest" <?php if ($sortby === 'latest'){ echo 'style="text-decoration:underline;"';} ?>><?php esc_html_e('Latest','b2bking');?></li>
										<?php
									}

									if (in_array('atoz', $available_sort_options)){
										?>
										<li value="atoz" <?php if ($sortby === 'atoz'){ echo 'style="text-decoration:underline;"';} ?>><?php esc_html_e('Alphabetically, A->Z','b2bking');?></li>
										<?php
									}

									if (in_array('ztoa', $available_sort_options)){
										?>
										<li value="ztoa" <?php if ($sortby === 'ztoa'){ echo 'style="text-decoration:underline;"';} ?>><?php esc_html_e('Alphabetically, Z->A','b2bking');?></li>
										<?php
									}
									?>
								</ul>
								<div class="b2bking_categories_header_separator <?php 
								if ($skipsort){
									echo 'b2bking_bulkorder_filters_list_sortby_hidden';
								}
								?>"></div>
								<?php
								if (apply_filters('b2bking_bulkorder_instock_filter', false)){
									?>
									<div class="b2bking_bulkorder_filter_header b2bking_bulkorder_filter_instock"><?php esc_html_e('In Stock','b2bking');?></div>
									<ul class="b2bking_bulkorder_filters_list_instock">
										<?php
										if (apply_filters('b2bking_bulkorder_instock_filter_default_all', true)){
											?>
											<li value="all" style="text-decoration:underline;"><?php esc_html_e('View All', 'b2bking'); ?></li>
											<?php
										}
										?>
										<li value="instock" <?php if (!apply_filters('b2bking_bulkorder_instock_filter_default_all', true)){echo 'style="text-decoration:underline;"'; } ?>><?php esc_html_e('In Stock', 'b2bking'); ?></li>
										<?php if (apply_filters('b2bking_bulkorder_instock_filter_show_onbackorder', false)): ?>
										<li value="onbackorder"><?php esc_html_e('On Backorder', 'b2bking'); ?></li>
										<?php endif; ?>
										<li value="outofstock"><?php esc_html_e('Out of Stock', 'b2bking'); ?></li>
									</ul>
									<div class="b2bking_categories_header_separator"></div>
									<?php
								}
								?>
								<div class="b2bking_bulkorder_filter_header b2bking_bulkorder_filter_header_categories <?php if ($category !== 0){

									if (!apply_filters('b2bking_bulkorder_category_shortcode_show_subcategories', false)){
										echo 'b2bking_categories_orderform_hidden';
									}

								} ?>"><?php echo apply_filters('b2bking_creamform_taxonomy_filter_name', esc_html__('Categories','b2bking'));?></div>
								<ul class="b2bking_bulkorder_filters_list <?php if ($category !== 0){

									if (!apply_filters('b2bking_bulkorder_category_shortcode_show_subcategories', false)){
										echo 'b2bking_categories_orderform_hidden';
									}
								} ?>">
									<?php

									if (!apply_filters('b2bking_bulkorder_category_shortcode_show_subcategories', false)){
										?>
										<li value="0"  <?php if (intval($category) === 0){ echo 'style="text-decoration:underline;"';} ?>><?php esc_html_e('All Products','b2bking');?></li>
										<?php
									}

								$exclude_ids = explode(',', $exclude);
								$exclude_ids_categories = array();
								foreach($exclude_ids as $exclude_option){
									$exclude = explode('_',$exclude_option);
									if ($exclude[0] === 'category'){
										$cat_id = $exclude[1];
										array_push($exclude_ids_categories, $cat_id);
									}
								}

								if (!function_exists('buildCategoryHierarchy')) {
								    function buildCategoryHierarchy($categories) {
								        $items = [];
								        foreach ($categories as $category) {
								            $items[$category->term_id] = $category;
								            $items[$category->term_id]->children = [];
								        }

								        $tree = [];
								        foreach ($items as $item) {
								            if ($item->category_parent == 0) {
								                $tree[$item->term_id] = &$items[$item->term_id];
								            } else {
								            	if (isset($items[$item->category_parent]->children)){
								            		$items[$item->category_parent]->children[$item->term_id] = &$items[$item->term_id];
								            	}
								            }
								        }

								        return $tree;
								    }
								}

								if (!function_exists('flattenCategoryHierarchy')) {
								    function flattenCategoryHierarchy($tree, &$result = []) {
								        foreach ($tree as $item) {
								            $result[] = $item;
								            if (!empty($item->children)) {
								                flattenCategoryHierarchy($item->children, $result);
								            }
								        }
								        return $result;
								    }
								}

								// Retrieve categories
								$categories = get_categories(array('hide_empty' => apply_filters('b2bking_orderform_hide_empty_categories', false), 'taxonomy' => apply_filters('b2bking_creamform_taxonomy_filter', 'product_cat')));

								// hide categories if visibility is enabled and the category is explicitly hidden for the current user group / username
								if (intval(get_option('b2bking_disable_visibility_setting', 0)) === 0){
									if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){

									    $currentuserid = get_current_user_id();
								    	$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
								    	if ($account_type === 'subaccount'){
								    		// for all intents and purposes set current user as the subaccount parent
								    		$parent_user_id = get_user_meta($currentuserid, 'b2bking_account_parent', true);
								    		$currentuserid = $parent_user_id;
								    	}
										$currentusergroupidnr = b2bking()->get_user_group($currentuserid);

										// if user is B2C, set to B2C
										if (get_user_meta($currentuserid,'b2bking_b2buser', true) !== 'yes'){
											$currentusergroupidnr = 'b2c';
										}
										if (!is_user_logged_in()){
											$currentusergroupidnr = 0;
										}

										$currentuser = wp_get_current_user();
								        // if user is guest, set to 0
								        if ($currentuser === false){
								        	$currentuserlogin = 0;
								        } else {
								        	$currentuserlogin = $currentuser -> user_login;
								        }


										foreach ($categories as $index => $term){
											$has_enabled = false;
											
											$group_meta = get_term_meta( $term->term_id, 'b2bking_group_'.$currentusergroupidnr, true );
											if (intval($group_meta) === 1){
												$has_enabled = true;
											// else check user
											} else {
												$userlistcommas = get_term_meta( $term->term_id, 'b2bking_category_users_textarea', true );
												$userarray = explode(',', $userlistcommas);
												$visible = 'no';
												foreach ($userarray as $user){
													if (trim($user) === $currentuserlogin){
														$has_enabled = true;
														break;
													}
												}
											}

											if (!$has_enabled){
												unset($categories[$index]);
											}
										}
										
									}
								}

								// Build hierarchy and flatten it back into a list
								$tree = buildCategoryHierarchy($categories);
								$sortedCategories = flattenCategoryHierarchy($tree);
								$categories = $sortedCategories;
								// Use $sortedCategories for sorted list of categories

								foreach ($categories as $cat) {
								    // Check if we're filtering for a specific category and its subcategories
								    $show_category = true;
								    
								    if ($category !== 0 && apply_filters('b2bking_bulkorder_category_shortcode_show_subcategories', false)) {
								        // Only show the selected category and its subcategories
								        $is_selected_category = (intval($cat->term_id) === intval($category));
								        $is_subcategory = false;
								        
								        // Check if this is a subcategory of the selected category
								        $parent_id = $cat->category_parent;
								        while ($parent_id != 0) {
								            if (intval($parent_id) === intval($category)) {
								                $is_subcategory = true;
								                break;
								            }
								            $parent_term = get_term($parent_id);
								            $parent_id = $parent_term->parent;
								        }
								        
								        // Only show if it's the selected category or its subcategory
								        $show_category = $is_selected_category || $is_subcategory;
								    }
								    
								    // Proceed only if we should show this category
								    if ($show_category) {
								        // remove excluded categories 
								        if (!in_array($cat->term_id, $exclude_ids_categories)) {
								            if (apply_filters('b2bking_bulkorder_category_hierarchical', true)) {
								                // allow setting a limit on number of categories children shown
								                $parents = 0;
								                $parentcat = $cat->category_parent;
								                while ($parentcat != 0) {
								                    $parents++;
								                    $newparent = get_term($parentcat);
								                    $parentcat = $newparent->parent;
								                }
								                $levels_limit = apply_filters('b2bking_bulkorder_categories_hierarchy_levels_limit', 2);
								                if ($parents > $levels_limit) {
								                    continue;
								                }
								            }
								            ?>
								            <li value="<?php echo esc_attr($cat->term_id); ?>" <?php if (intval($category) === intval($cat->term_id)){ echo 'style="text-decoration:underline;"';} ?>>
								                <?php
								                // show category hierarchy or not
								                if (apply_filters('b2bking_bulkorder_category_hierarchical', true)) {
								                    while ($parents > 0) {
								                        echo '—';
								                        $parents--;
								                    }
								                }
								                echo esc_html($cat->name);
								                ?>
								            </li>
								            <?php
								        }
								    }
								}
								
								?>
								</ul>
							</div>
							<div class="b2bking_bulkorder_form_container_cream_filters_content_second">
								<?php
								if ($attributes !== 'no'){
									$attributes_slugs = explode(',', $attributes);
									$attributes_slugs = array_map('trim', $attributes_slugs);

									foreach ($attributes_slugs as $slug){
										if (!empty($slug)){
											$attribute_taxonomy   = 'pa_' . $slug; 

											?>
											<div class="b2bking_bulkorder_filter_header <?php echo esc_attr($attribute_taxonomy); ?>"><?php echo wc_attribute_label( $attribute_taxonomy ); ?></div>
												<ul class="b2bking_bulkorder_filters_list_attributes <?php echo esc_attr($attribute_taxonomy); ?>">
													<input type="hidden" class="b2bking_attribute_value b2bking_attribute_value_<?php echo esc_attr($slug);?>" value="0">
													<?php

													$terms = get_terms( array(
													    'taxonomy'   => $attribute_taxonomy,
													    'hide_empty' => false,
													) );
													?>

													<li value="0" <?php echo 'style="text-decoration:underline;"'; ?>><?php esc_html_e('View All','b2bking');?></li>

													<?php

													foreach ( $terms as $term ) {
														?>
														<li value="<?php echo esc_attr($term->term_id); ?>"><?php echo '— '.esc_html($term->name);?></li>
														<?php
													}
													
													?>
												</ul>
												<div class="b2bking_categories_header_separator"></div>
											<?php
										}
										
									}
									
								}
								?>
							</div>
							
						</div>
						<div class="b2bking_bulkorder_form_cream_main_container_content b2bking_filters_closed">
							<div class="b2bking_bulkorder_before_top_cream"></div>
							<div class="b2bking_bulkorder_form_container_top b2bking_bulkorder_form_container_top_indigo b2bking_bulkorder_form_container_top_cream">
								<?php do_action('b2bking_bulkorder_column_header_start'); ?>

								<div class="b2bking_bulkorder_form_container_content_header_product b2bking_bulkorder_form_container_content_header_product_indigo b2bking_bulkorder_form_container_content_header_product_cream">
									<?php esc_html_e('Product', 'b2bking'); ?>
			            		</div>
			            		<?php
			            		if ($showsku === 'yes'){
			            			?>
									<div class="b2bking_bulkorder_form_container_content_header_cream_sku">
										<?php esc_html_e('SKU', 'b2bking'); ?>
				            		</div>
				            		<input type="hidden" class="b2bking_order_form_show_sku" value="yes">
				            		<?php
			            		}
			            		if ($showstock === 'yes'){
			            			?>
									<div class="b2bking_bulkorder_form_container_content_header_cream_stock">
										<?php esc_html_e('In Stock', 'b2bking'); ?>
				            		</div>
				            		<input type="hidden" class="b2bking_order_form_show_stock" value="yes">
				            		<?php
			            		}

			            		do_action('b2bking_bulkorder_cream_custom_heading');
			            		?>
			            		<div class="b2bking_bulkorder_form_container_content_header_qty b2bking_bulkorder_form_container_content_header_qty_indigo b2bking_bulkorder_form_container_content_header_qty_cream">
			            			<?php esc_html_e('Qty', 'b2bking'); ?>
			            		</div>
			            		<?php do_action('b2bking_bulkorder_column_header_mid'); ?>
			            		<div class="b2bking_bulkorder_form_container_content_header_subtotal b2bking_bulkorder_form_container_content_header_subtotal_indigo b2bking_bulkorder_form_container_content_header_subtotal_cream">
			            			<?php esc_html_e('Subtotal', 'b2bking'); ?>
			            		</div>
			            		<div class="b2bking_bulkorder_form_container_content_header_subtotal b2bking_bulkorder_form_container_content_header_cart_indigo b2bking_bulkorder_form_container_content_header_cart_cream">
			            			<?php 

			            			if (apply_filters('b2bking_cream_hide_individual_addtocart', false)){
			            				esc_html_e('Select', 'b2bking'); 
			            			} else {
			            				esc_html_e('Cart', 'b2bking'); 
			            			}

			            			?>
			            		</div>
			            		<?php
			            			if ($multiselect === 'yes'){
			            				?>
			            				<div class="b2bking_bulkorder_form_container_content_header_multiselect_cream <?php if (apply_filters('b2bking_cream_hide_individual_addtocart', false)){ echo 'b2bking_hidden_img'; }?>">
			            					<!-- <input type="checkbox" class="b2bking_cream_select_checkbox_all"> -->
			            				</div>
			            				<?php
			            			}
			            		?>
			            		<?php do_action('b2bking_bulkorder_column_header_end'); ?>
							</div>
							<div class="b2bking_bulkorder_form_container_content b2bking_bulkorder_form_container_content_indigo b2bking_bulkorder_form_container_content_cream">

				            	<input type="hidden" id="b2bking_indigo_order_form" class="b2bking_cream_order_form" value="1">
				            	<!-- initialize hidden loader to get it to load instantly -->
				            	<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/loader.svg', __FILE__); ?>">
				            	<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/no_products.svg', __FILE__); ?>">
				            	<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/close.svg', __FILE__); ?>">
				            	<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/filter.svg', __FILE__); ?>">


				            </div>
				        </div>
			        </div>
				</div>
				<?php
			}
		?>
		</div>
		<?php

		$content = ob_get_clean();
		return apply_filters('b2bking_bulkorder_content', $content);
	}

	// Subaccounts Endpoint Content
	function b2bking_subaccounts_endpoint_content(){
		$account_type = get_user_meta(get_current_user_id(), 'b2bking_account_type', true);
		?>
		<div class="b2bking_subaccounts_container">
			<div class="b2bking_subaccounts_container_top">
				<div class="b2bking_subaccounts_container_top_title">
					<?php esc_html_e('Subaccounts','b2bking'); ?>
				</div>
				<?php
				// only available if current account is not itself a subaccount
				if ($account_type !== 'subaccount' or apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
					if (apply_filters('b2bking_allow_subaccount_creation_editing', true)){
						?>
						<button class="b2bking_subaccounts_container_top_button" type="button">
							<svg class="b2bking_subaccounts_container_top_button_icon" xmlns="http://www.w3.org/2000/svg" width="34" height="34" fill="none" viewBox="0 0 34 34">
							  <path fill="#fff" d="M6.375 12.115c0 2.827 2.132 4.959 4.958 4.959 2.827 0 4.959-2.132 4.959-4.959 0-2.826-2.132-4.958-4.959-4.958-2.826 0-4.958 2.132-4.958 4.958zm20.542-.782h-2.834v4.25h-4.25v2.834h4.25v4.25h2.834v-4.25h4.25v-2.834h-4.25v-4.25zM5.667 26.917h14.166V25.5a7.091 7.091 0 00-7.083-7.083H9.917A7.091 7.091 0 002.833 25.5v1.417h2.834z"/>
							</svg>
							<?php esc_html_e('New subaccount','b2bking'); ?>
						</button>
						<?php
					}
				}
				?>
			</div>

			<!-- Hidden New Subaccount Container -->
			<?php
			// only available if current account is not itself a subaccount
			if ($account_type !== 'subaccount' or apply_filters('b2bking_allow_multiple_subaccount_levels', false)){

				if (apply_filters('b2bking_allow_subaccount_creation_editing', true)){
					?>
					<div class="b2bking_subaccounts_new_account_container">
						<div class="b2bking_subaccounts_new_account_container_top">
							<div class="b2bking_subaccounts_new_account_container_top_title">
								<?php esc_html_e('New Subaccount', 'b2bking'); ?>
							</div>
							<div class="b2bking_subaccounts_new_account_container_top_close">
								<?php esc_html_e('Close X', 'b2bking'); ?>
							</div>
						</div>
						<div class="b2bking_subaccounts_new_account_container_content">
							<div class="b2bking_subaccounts_new_account_container_content_large_title">
								<svg class="b2bking_subaccounts_new_account_container_content_large_title_icon" xmlns="http://www.w3.org/2000/svg" width="35" height="25" fill="none" viewBox="0 0 35 25">
								  <path fill="#4E4E4E" d="M22.75 10.5H35V14H22.75v-3.5zm1.75 7H35V21H24.5v-3.5zM21 3.5h14V7H21V3.5zm-17.5 21H21v-1.75c0-4.825-3.925-8.75-8.75-8.75h-3.5C3.925 14 0 17.925 0 22.75v1.75h3.5zm7-12.25c3.491 0 6.125-2.634 6.125-6.125S13.991 0 10.5 0 4.375 2.634 4.375 6.125 7.009 12.25 10.5 12.25z"/>
								</svg>
								<span class="b2bking_span_title_text_subaccount"><?php esc_html_e('Login Details', 'b2bking'); ?></span>
							</div>
							<?php

							if (apply_filters('b2bking_disable_username_subaccounts', 1) === 0 || apply_filters('b2bking_show_username_subaccounts', false)){
								?>
								<div class="b2bking_subaccounts_new_account_container_content_element">
									<div class="b2bking_subaccounts_new_account_container_content_element_label">
										<?php esc_html_e('Username','b2bking'); ?>
									</div>
									<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_username" placeholder="<?php esc_attr_e('Enter the subaccount username here...','b2bking'); ?>" >
								</div>
								<?php
							}


							?>
							<div class="b2bking_subaccounts_new_account_container_content_element">
								<div class="b2bking_subaccounts_new_account_container_content_element_label">
									<?php esc_html_e('Email Address','b2bking'); ?>
								</div>
								<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_email_address" placeholder="<?php esc_attr_e('Enter the subaccount email here...','b2bking'); ?>">
							</div>
							<div class="b2bking_subaccounts_new_account_container_content_element b2bking_subaccount_horizontal_line" <?php
							if (apply_filters('b2bking_subaccounts_set_own_password', false)){
								echo ' style="display:none" ';
							}
							?>>
								<div class="b2bking_subaccounts_new_account_container_content_element_label">
									<?php esc_html_e('Password','b2bking'); ?>
								</div>
								<input type="password" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_password" placeholder="<?php esc_attr_e('Enter the subaccount password here...','b2bking'); ?>" <?php 

								if (apply_filters('b2bking_subaccounts_set_own_password', false)){
									echo ' value="account123456" <!-- not actually used, subaccount will set own password -->';
								}
							?>>
							</div>

							<?php
							// custom fields
							do_action('b2bking_custom_new_subaccount_fields');

							$custom_field_names = apply_filters('b2bking_custom_new_subaccount_field_names', array());
							$custom_fields_string = '';
							foreach ($custom_field_names as $name){
								$custom_fields_string .= $name.';';
							}

							// remove last semicolon
							$custom_fields_string = substr($custom_fields_string, 0, -1);

							?>
							<input type="hidden" id="b2bking_custom_new_subaccount_fields" value="<?php echo esc_attr($custom_fields_string); ?>">

							<div class="b2bking_subaccounts_new_account_container_content_large_title b2bking_subaccount_top_margin">
								<svg class="b2bking_subaccounts_new_account_container_content_large_title_icon" xmlns="http://www.w3.org/2000/svg" width="35" height="29" fill="none" viewBox="0 0 35 29">
								  <path fill="#4E4E4E" d="M12.25 14.063c3.867 0 7-3.148 7-7.031 0-3.884-3.133-7.032-7-7.032-3.866 0-7 3.148-7 7.032 0 3.883 3.134 7.031 7 7.031zm4.9 1.758h-.913a9.494 9.494 0 01-3.986.879 9.512 9.512 0 01-3.987-.88H7.35C3.292 15.82 0 19.129 0 23.205v2.285a2.632 2.632 0 002.625 2.637H17.66a2.648 2.648 0 01-.142-1.17l.372-3.346.066-.61.432-.433 4.227-4.247c-1.34-1.521-3.281-2.5-5.463-2.5zm2.478 7.982l-.372 3.35a.873.873 0 00.963.968l3.33-.374 7.542-7.575-3.921-3.94-7.542 7.57zm14.99-9.031l-2.072-2.082a1.306 1.306 0 00-1.849 0l-2.067 2.076-.224.225 3.927 3.94 2.285-2.297a1.327 1.327 0 000-1.862z"/>
								</svg>
								<span class="b2bking_span_title_text_subaccount"><?php esc_html_e('Personal Details', 'b2bking'); ?></span>
							</div>
							<div class="b2bking_subaccounts_new_account_container_content_element">
								<div class="b2bking_subaccounts_new_account_container_content_element_label">
									<?php esc_html_e('First Name','b2bking'); ?>
								</div>
								<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_name" placeholder="<?php esc_attr_e('Enter the account holder\'s first name here...','b2bking'); ?>">
							</div>
							<div class="b2bking_subaccounts_new_account_container_content_element">
								<div class="b2bking_subaccounts_new_account_container_content_element_label">
									<?php esc_html_e('Last Name','b2bking'); ?>
								</div>
								<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_last_name" placeholder="<?php esc_attr_e('Enter the account holder\'s last name here...','b2bking'); ?>">
							</div>
							<div class="b2bking_subaccounts_new_account_container_content_element">
								<div class="b2bking_subaccounts_new_account_container_content_element_label">
									<?php esc_html_e('Job Title','b2bking'); ?>
								</div>
								<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_job_title" placeholder="<?php esc_attr_e('Enter the account holder\'s title here...','b2bking'); ?>">
							</div>
							<div class="b2bking_subaccounts_new_account_container_content_element b2bking_subaccount_horizontal_line">
								<div class="b2bking_subaccounts_new_account_container_content_element_label">
									<?php esc_html_e('Phone Number','b2bking'); ?>
								</div>
								<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_phone_number" placeholder="<?php esc_attr_e('Enter the account holder\'s phone here...','b2bking'); ?>">
							</div>
							<div class="b2bking_subaccounts_new_account_container_content_large_title b2bking_subaccount_top_margin">
								<svg class="b2bking_subaccounts_new_account_container_content_large_title_icon" xmlns="http://www.w3.org/2000/svg" width="35" height="24" fill="none" viewBox="0 0 35 24">
								  <path fill="#575757" d="M16.042 8.75v2.917h-1.459v2.916h-2.916v-2.916H8.502a4.36 4.36 0 01-4.127 2.916 4.375 4.375 0 110-8.75A4.36 4.36 0 018.502 8.75h7.54zm-11.667 0a1.458 1.458 0 100 2.917 1.458 1.458 0 000-2.917zm18.958 5.833c3.894 0 11.667 1.955 11.667 5.834v2.916H11.667v-2.916c0-3.88 7.773-5.834 11.666-5.834zm0-2.916a5.833 5.833 0 110-11.667 5.833 5.833 0 010 11.667z"/>
								</svg>
								<span class="b2bking_span_title_text_subaccount"><?php esc_html_e('Permissions', 'b2bking'); ?></span>
							</div>
							<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
								<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
									<?php esc_html_e('Place an Order','b2bking'); ?>
								</div>
								<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_buy">
							</div>
							<?php
							if (intval(get_option( 'b2bking_enable_company_approval_setting', 0 )) === 1){
								?>
								<div class="b2bking_subaccounts_new_account_container_content_element_checkbox b2bking_checkbox_child b2bking_checkbox_permission_approval">
									<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
										<?php esc_html_e('Orders require approval (the user can place pending orders, and you will need to approve them)','b2bking'); ?>
									</div>
									<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_buy_approval">
								</div>
								<?php
							}
							?>
							<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
								<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
									<?php esc_html_e('View all account orders','b2bking'); ?>
								</div>
								<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_orders">
							</div>
							<?php
							if (class_exists('WC_Subscriptions')){
								?>
								<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
									<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
										<?php esc_html_e('View all account subscriptions','b2bking'); ?>
									</div>
									<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_subscriptions" >
								</div>
								<?php
							}

							?>
							<?php if (intval(get_option('b2bking_enable_offers_setting', 1)) === 1){ ?>
								<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
									<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
										<?php esc_html_e('View all account offers','b2bking'); ?>
									</div>
									<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_offers">
								</div>
							<?php } ?>
							<?php if (intval(get_option('b2bking_enable_conversations_setting', 1)) === 1){ ?>
								<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
									<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
										<?php esc_html_e('View all account conversations','b2bking'); ?>
									</div>
									<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_conversations">
								</div>
							<?php } ?>
							<?php if (intval(get_option('b2bking_enable_purchase_lists_setting', 1)) === 1){ ?>
								<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
									<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
										<?php esc_html_e('View all account purchase lists','b2bking'); ?>
									</div>
									<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_lists">
								</div>
							<?php } ?>
							<div class="b2bking_subaccounts_new_account_container_content_bottom">
								<div class="b2bking_subaccounts_new_account_container_content_bottom_validation_errors">
								</div>
								<button class="b2bking_subaccounts_new_account_container_content_bottom_button" type="button">
									<svg class="b2bking_subaccounts_new_account_container_content_bottom_button_icon" xmlns="http://www.w3.org/2000/svg" width="30" height="20" fill="none" viewBox="0 0 30 20">
									  <path fill="#fff" d="M4.375 5.115c0 2.827 2.132 4.959 4.958 4.959 2.827 0 4.959-2.132 4.959-4.959 0-2.826-2.132-4.958-4.959-4.958-2.826 0-4.958 2.132-4.958 4.958zm20.542-.782h-2.834v4.25h-4.25v2.834h4.25v4.25h2.834v-4.25h4.25V8.583h-4.25v-4.25zM3.667 19.917h14.166V18.5a7.091 7.091 0 00-7.083-7.083H7.917A7.091 7.091 0 00.833 18.5v1.417h2.834z"/>
									</svg>
									<?php esc_html_e('Create Subaccount', 'b2bking'); ?>
								</button>
							</div>
						</div>
					</div>
					<?php
				}
			}

			// Get all subaccounts and display them;
			$user_id = get_current_user_id();
			$user_subaccounts_list = get_user_meta($user_id, 'b2bking_subaccounts_list', true);
			$subaccounts_array = explode(',', $user_subaccounts_list);
			$subaccounts_array = array_filter($subaccounts_array); // removing blank, null, false, 0 (zero) values
			$subaccounts_array = array_reverse($subaccounts_array); // show newest first 

			if(empty($subaccounts_array)){
				wc_print_notice(esc_html__('No subaccounts exist.', 'b2bking'), 'notice');
			}

			$subaccounts_array = apply_filters('b2bking_subaccounts_before_display', $subaccounts_array);

			foreach($subaccounts_array as $subaccount){
				// display subaccount
				$user = get_user_by('ID', $subaccount);

				// if user does not exist, delete the user and continue to the next foreach item
				if ($user === false){
					$user_subaccounts_list = str_replace(','.$subaccount,'',$user_subaccounts_list);
					update_user_meta($user_id, 'b2bking_subaccounts_list', sanitize_text_field($user_subaccounts_list));
					continue;
				}

				// verify that the user indeed belongs to current parent
				$parent_of_subaccount = get_user_meta($subaccount, 'b2bking_account_parent', true);
				if (intval($parent_of_subaccount) !== intval($user_id)){
					$user_subaccounts_list = str_replace(','.$subaccount,'',$user_subaccounts_list);
					update_user_meta($user_id, 'b2bking_subaccounts_list', sanitize_text_field($user_subaccounts_list));
					continue;
				}

				$username = $user->user_login;
				$name = get_user_meta($subaccount, 'first_name', true);
				$last_name = get_user_meta($subaccount, 'last_name', true);
				$job_title = get_user_meta($subaccount, 'b2bking_account_job_title', true);
				$phone = get_user_meta($subaccount, 'b2bking_account_phone', true);
				$email = $user->user_email;
				// Get Subaccount Endpoint URL
		   		$endpointurl = wc_get_endpoint_url(get_option('b2bking_subaccount_endpoint_setting','subaccount'));
				?>
				<div class="b2bking_subaccounts_account_container">
					<div class="b2bking_subaccounts_account_top">
						<svg class="b2bking_subaccounts_account_top_icon" xmlns="http://www.w3.org/2000/svg" width="26" height="26" fill="none" viewBox="0 0 26 26">
						  <path fill="#fff" d="M8.125 7.042A4.881 4.881 0 0013 11.917a4.88 4.88 0 004.875-4.875A4.88 4.88 0 0013 2.167a4.881 4.881 0 00-4.875 4.875zM21.667 22.75h1.083v-1.083c0-4.18-3.403-7.584-7.583-7.584h-4.334c-4.181 0-7.583 3.403-7.583 7.584v1.083h18.417z"/>
						</svg>
						<?php echo esc_html($username); ?>
					</div>
					<div class="b2bking_subaccounts_account_line">
						<div class="b2bking_subaccounts_account_name_title">
							<div class="b2bking_subaccounts_account_name">
								<?php 
								do_action('b2bking_before_subaccount_name', $subaccount);
								echo esc_html($name).' ';
								echo esc_html($last_name); 
								?>
							</div>
							<div class="b2bking_subaccounts_account_title">
								<?php 
								do_action('b2bking_before_subaccount_job', $subaccount);
								echo esc_html($job_title); 
								?>
							</div>
						</div>
						<div>
							<?php
							if (apply_filters('b2bking_allow_subaccount_login', true, $subaccount)){
								?>
								<button class="b2bking_subaccounts_account_button b2bking_subaccounts_account_button_login" type="button" value="<?php echo esc_html($subaccount);?>">
									<svg class="b2bking_subaccounts_account_button_icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24">
									  <path fill="#fff" d="M12 21v-2h7V5h-7V3h7c.55 0 1.021.196 1.413.588.392.392.588.863.587 1.412v14c0 .55-.196 1.021-.588 1.413A1.922 1.922 0 0 1 19 21h-7Zm-2-4-1.375-1.45 2.55-2.55H3v-2h8.175l-2.55-2.55L10 7l5 5-5 5Z"/>
									</svg>
									<?php esc_html_e('Log in','b2bking'); ?>
								</button>
								<?php
							}
							do_action('b2bking_before_subaccount_edit_button', $subaccount);
							?>
							<?php
							if (apply_filters('b2bking_allow_subaccount_creation_editing', true)){
								if (apply_filters('b2bking_allow_subaccount_edit', true, $subaccount)){
									?>
									<a href="<?php echo esc_url(add_query_arg('id',$subaccount,$endpointurl)); ?>">
										<button class="b2bking_subaccounts_account_button" type="button">
											<svg class="b2bking_subaccounts_account_button_icon" xmlns="http://www.w3.org/2000/svg" width="24" height="23" fill="none" viewBox="0 0 24 23">
											  <path fill="#fff" d="M20.016 11.236a5.529 5.529 0 01-2.79 1.432 5.672 5.672 0 01-3.15-.294l-6.492 7.498a3.129 3.129 0 01-4.296 0c-1.188-1.139-1.188-2.979 0-4.105l7.824-6.233c-.816-1.898-.42-4.152 1.188-5.693 1.536-1.472 3.744-1.863 5.664-1.219l-3.468 3.324 3.384 3.242 3.432-3.3a5.048 5.048 0 01-1.296 5.348zM4.572 18.64c.48.449 1.248.449 1.716 0 .48-.46.48-1.195 0-1.644a1.24 1.24 0 00-1.716 0c-.225.22-.351.515-.351.822 0 .308.126.603.351.823z"/>
											</svg>
											<?php esc_html_e('Edit account','b2bking'); ?>
										</button>
									</a>
									<?php
								}
							}
							do_action('b2bking_after_subaccount_edit_button', $subaccount);
							?>
						</div>
					</div>
					<div class="b2bking_subaccounts_account_line">
						<div class="b2bking_subaccounts_account_phone_email">
							<div class="b2bking_subaccounts_account_phone_email_text">
								<?php echo esc_html($phone); ?>
							</div>
							<div class="b2bking_subaccounts_account_phone_email_text">
								<?php echo esc_html($email); ?>
							</div>
							<?php do_action('b2bking_subaccount_tab_bottom', $user); ?>

						</div>
						<?php do_action('b2bking_subaccount_tab_right', $user); ?>

					</div>
				</div>
			<?php	
			}
			?>
			</div>	
		<?php
	}

    function b2bking_switched_to(){
    	// check if switch cookie is set
    	if (isset($_COOKIE['b2bking_switch_cookie'])){
    		$switch_to = sanitize_text_field($_COOKIE['b2bking_switch_cookie']);	
    	} else {
    		$switch_to = '';
    	}
    	
    	$current_id = get_current_user_id();

    	if (!empty($switch_to) && is_user_logged_in()){
    		// show bar
			$udata = get_userdata( get_current_user_id() );
			$name = $udata->first_name.' '.$udata->last_name;

			// get agent details
			$agent = explode('_',$switch_to);
			$customer_id = intval($agent[0]);
			$agent_id = intval($agent[1]);
			$agent_registration = $agent[2];
			// check real registration in database
			$udataagent = get_userdata( $agent_id );
            $registered_date = $udataagent->user_registered;

            // if current logged in user is the one in the cookie + agent cookie checks out
            if ($current_id === $customer_id && $agent_registration === $registered_date){

    		?>
    		<div id="b2bking_agent_switched_bar">
    			<div class="b2bking_bar_element">
					<?php 

					esc_html_e('You are logged in as ','b2bking');
					echo apply_filters('b2bking_logged_in_as_text', '<strong>'.esc_html($name).' ('.$udata->user_login.')'.'</strong>', $customer_id);

					?>  
				</div> 	
				<div class="b2bking_bar_element">
					<button id="b2bking_return_agent" value="<?php echo esc_attr($agent_id);?>"><em class="b2bking_ni b2bking_ni-swap"></em>&nbsp;&nbsp;&nbsp;<span><?php esc_html_e('Switch to Main Account', 'b2bking'); ?></span></button>
					<input type="hidden" id="b2bking_return_agent_registered" value="<?php echo esc_attr($agent_registration);?>">
				</div>		
    		</div>

    		<style>
    		body {
    		  padding-top: 50px;
    		}

    		</style>
  			<?php
  			}
    	}
    }

    function b2bking_bulk_variations_table(){
    	global $post;
    	$product_id = $post->ID;

    	$is_enabled = apply_filters('b2bking_show_variations_table', get_post_meta($product_id, 'b2bking_show_variations_table', true), $product_id);
    	$location = apply_filters('b2bking_variations_table_location', get_post_meta($product_id, 'b2bking_variations_table_location', true), $product_id);
    	if (empty($location)){
    		$location = 'below';
    	}

    	if ($is_enabled === 'yes' && $location === 'below'){
	    	echo do_shortcode(apply_filters('b2bking_bulk_variations_table_shortcode','[b2bking_bulkorder theme=cream product_list="'.$product_id.'" multiselect="yes"]'));
	    	?>
	    	<style type="text/css">
	    		.b2bking_bulkorder_form_container_content_line_cream_view_options, .b2bking_bulkorder_cream_header_container{
	    			display:none !important;
	    		}
	    		.b2bking_bulkorder_form_container_content_line_cream_hidden {
	    			display: flex !important;
	    		}
	    		.b2bking_bulkorder_container_final{
	    			clear:both;
	    		}
	    	</style>
	    	<?php
	    }
    }

    function b2bking_bulk_variations_table_replace_before(){
    	global $post;
    	$product_id = $post->ID;

    	$is_enabled = apply_filters('b2bking_show_variations_table', get_post_meta($product_id, 'b2bking_show_variations_table', true), $product_id);
    	$location = apply_filters('b2bking_variations_table_location', get_post_meta($product_id, 'b2bking_variations_table_location', true), $product_id);
    	if (empty($location)){
    		$location = 'below';
    	}

    	$attributes_nr = b2bking()->get_selectable_attributes_count($product_id);
    	
    	if ($is_enabled === 'yes' && $location === 'replace'){
    		if ($attributes_nr === 1){
    			if ( ! b2bking()->has_tiered_price_table($product_id)){
    				ob_start();
    			}
    		}
    		
	    }
    }
    function b2bking_bulk_variations_table_replace_after(){
    	global $post;
    	$product_id = $post->ID;

    	$is_enabled = apply_filters('b2bking_show_variations_table', get_post_meta($product_id, 'b2bking_show_variations_table', true), $product_id);
    	$location = apply_filters('b2bking_variations_table_location', get_post_meta($product_id, 'b2bking_variations_table_location', true), $product_id);
    	if (empty($location)){
    		$location = 'below';
    	}

    	$attributes_nr = b2bking()->get_selectable_attributes_count($product_id);
    	
    	if ($is_enabled === 'yes' && $location === 'replace'){
    		// in all cases, hide add to cart button as we don't need it
    		?>
    		<style type="text/css">
    			.woocommerce-variation-add-to-cart.variations_button > *:not(.b2bking_information_table){
    				display: none !important;
    			}
    			.b2bking_bulkorder_cream_product_container select{
    				display:none;
    			}
    		</style>
    		<script>
    			jQuery(document).ready(function(){
    				jQuery('.b2bking_information_table').detach().insertAfter('.b2bking_bulkorder_form_cream_main_container');
    			});
    		</script>
    		<?php
    		if ($attributes_nr === 1){
	    		if ( ! b2bking()->has_tiered_price_table($product_id)){ // show form to be able to see table
			   		$discard = ob_get_clean();
			   	}
		   		echo do_shortcode('[b2bking_variations_table width="nonadaptive" style="nameqty"]');
		   	}

		   	if ($attributes_nr > 1){
		   		echo do_shortcode('[b2bking_variations_table width="nonadaptive" style="nameqty"]');
		   	}

	    }
    }

	// Individual subaccount endpoint content
	function b2bking_subaccount_endpoint_content(){
		// get subaccount
		$subaccount_id = sanitize_text_field( $_GET['id'] );
		// check if current user has permission to access this subaccount
		$current_user = get_current_user_id();
		$current_user_subaccounts = get_user_meta($current_user, 'b2bking_subaccounts_list', true);
		$current_user_subaccounts = array_filter(explode(',',$current_user_subaccounts));
		if (in_array ( $subaccount_id, $current_user_subaccounts)){
			// has permission
			// get subaccount meta
			$name = get_user_meta($subaccount_id, 'first_name', true);
			$last_name = get_user_meta($subaccount_id, 'last_name', true);

			if (empty($name)){
				$name = get_user_meta($subaccount_id,'b2bking_account_name', true);
			}

			$job_title = get_user_meta($subaccount_id, 'b2bking_account_job_title', true);
			$phone = get_user_meta($subaccount_id, 'b2bking_account_phone', true);
			$permission_buy = filter_var(get_user_meta($subaccount_id, 'b2bking_account_permission_buy', true), FILTER_VALIDATE_BOOLEAN); 
			$permission_buy_approval = filter_var(get_user_meta($subaccount_id, 'b2bking_account_permission_buy_approval', true), FILTER_VALIDATE_BOOLEAN); 
			$permission_view_orders = filter_var(get_user_meta($subaccount_id, 'b2bking_account_permission_view_orders', true), FILTER_VALIDATE_BOOLEAN);
			$permission_view_subscriptions = filter_var(get_user_meta($subaccount_id, 'b2bking_account_permission_view_subscriptions', true), FILTER_VALIDATE_BOOLEAN);
			$permission_view_offers = filter_var(get_user_meta($subaccount_id, 'b2bking_account_permission_view_offers', true), FILTER_VALIDATE_BOOLEAN); 
			$permission_view_conversations = filter_var(get_user_meta($subaccount_id, 'b2bking_account_permission_view_conversations', true), FILTER_VALIDATE_BOOLEAN); 
			$permission_view_lists = filter_var(get_user_meta($subaccount_id, 'b2bking_account_permission_view_lists', true), FILTER_VALIDATE_BOOLEAN);   
			?>

			<div class="b2bking_subaccounts_edit_account_container">
				<div class="b2bking_subaccounts_new_account_container_top">
					<div class="b2bking_subaccounts_new_account_container_top_title">
						<?php esc_html_e('Edit Subaccount', 'b2bking'); ?>
					</div>
					<div class="b2bking_subaccounts_edit_account_container_top_close">
						<?php esc_html_e('Close X', 'b2bking'); ?>
					</div>
				</div>
				<div class="b2bking_subaccounts_new_account_container_content">
					<div class="b2bking_subaccounts_new_account_container_content_large_title b2bking_subaccount_top_margin">
						<svg class="b2bking_subaccounts_new_account_container_content_large_title_icon" xmlns="http://www.w3.org/2000/svg" width="35" height="29" fill="none" viewBox="0 0 35 29">
						  <path fill="#4E4E4E" d="M12.25 14.063c3.867 0 7-3.148 7-7.031 0-3.884-3.133-7.032-7-7.032-3.866 0-7 3.148-7 7.032 0 3.883 3.134 7.031 7 7.031zm4.9 1.758h-.913a9.494 9.494 0 01-3.986.879 9.512 9.512 0 01-3.987-.88H7.35C3.292 15.82 0 19.129 0 23.205v2.285a2.632 2.632 0 002.625 2.637H17.66a2.648 2.648 0 01-.142-1.17l.372-3.346.066-.61.432-.433 4.227-4.247c-1.34-1.521-3.281-2.5-5.463-2.5zm2.478 7.982l-.372 3.35a.873.873 0 00.963.968l3.33-.374 7.542-7.575-3.921-3.94-7.542 7.57zm14.99-9.031l-2.072-2.082a1.306 1.306 0 00-1.849 0l-2.067 2.076-.224.225 3.927 3.94 2.285-2.297a1.327 1.327 0 000-1.862z"/>
						</svg>
						<?php esc_html_e('Personal Details', 'b2bking'); ?>
					</div>
					<div class="b2bking_subaccounts_new_account_container_content_element">
						<div class="b2bking_subaccounts_new_account_container_content_element_label">
							<?php esc_html_e('First Name','b2bking'); ?>
						</div>
						<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_name" placeholder="<?php esc_attr_e('Enter the account holder\'s first name here...','b2bking'); ?>" value="<?php echo esc_attr($name);?>">
					</div>
					<div class="b2bking_subaccounts_new_account_container_content_element">
						<div class="b2bking_subaccounts_new_account_container_content_element_label">
							<?php esc_html_e('Last Name','b2bking'); ?>
						</div>
						<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_last_name" placeholder="<?php esc_attr_e('Enter the account holder\'s last name here...','b2bking'); ?>" value="<?php echo esc_attr($last_name);?>">
					</div>
					<div class="b2bking_subaccounts_new_account_container_content_element">
						<div class="b2bking_subaccounts_new_account_container_content_element_label">
							<?php esc_html_e('Job Title','b2bking'); ?>
						</div>
						<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_job_title" placeholder="<?php esc_attr_e('Enter the account holder\'s title here...','b2bking'); ?>" value="<?php echo esc_attr($job_title);?>">
					</div>
					<div class="b2bking_subaccounts_new_account_container_content_element b2bking_subaccount_horizontal_line">
						<div class="b2bking_subaccounts_new_account_container_content_element_label">
							<?php esc_html_e('Phone Number','b2bking'); ?>
						</div>
						<input type="text" class="b2bking_subaccounts_new_account_container_content_element_text" name="b2bking_subaccounts_new_account_phone_number" placeholder="<?php esc_attr_e('Enter the account holder\'s phone here...','b2bking'); ?>" value="<?php echo esc_attr($phone);?>">
					</div>
					<?php

					// custom fields
					do_action('b2bking_custom_new_subaccount_fields', $subaccount_id);

					$custom_field_names = apply_filters('b2bking_custom_new_subaccount_field_names', array());
					$custom_fields_string = '';
					foreach ($custom_field_names as $name){
						$custom_fields_string .= $name.';';
					}

					// remove last semicolon
					$custom_fields_string = substr($custom_fields_string, 0, -1);

					?>
					<input type="hidden" id="b2bking_custom_new_subaccount_fields" value="<?php echo esc_attr($custom_fields_string); ?>">

					
					<div class="b2bking_subaccounts_new_account_container_content_large_title b2bking_subaccount_top_margin">
						<svg class="b2bking_subaccounts_new_account_container_content_large_title_icon" xmlns="http://www.w3.org/2000/svg" width="35" height="24" fill="none" viewBox="0 0 35 24">
						  <path fill="#575757" d="M16.042 8.75v2.917h-1.459v2.916h-2.916v-2.916H8.502a4.36 4.36 0 01-4.127 2.916 4.375 4.375 0 110-8.75A4.36 4.36 0 018.502 8.75h7.54zm-11.667 0a1.458 1.458 0 100 2.917 1.458 1.458 0 000-2.917zm18.958 5.833c3.894 0 11.667 1.955 11.667 5.834v2.916H11.667v-2.916c0-3.88 7.773-5.834 11.666-5.834zm0-2.916a5.833 5.833 0 110-11.667 5.833 5.833 0 010 11.667z"/>
						</svg>
						<?php esc_html_e('Permissions', 'b2bking'); ?>
					</div>
					<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
						<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
							<?php esc_html_e('Checkout (place order)','b2bking'); ?>
						</div>
						<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_buy" <?php checked(true, $permission_buy, true); ?>>
					</div>
					<?php
					if (intval(get_option( 'b2bking_enable_company_approval_setting', 0 )) === 1){
						?>
						<div class="b2bking_subaccounts_new_account_container_content_element_checkbox b2bking_checkbox_child b2bking_checkbox_permission_approval">
							<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
								<?php esc_html_e('Orders require approval (the user can place pending orders, and you will need to approve them)','b2bking'); ?>
							</div>
							<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_buy_approval" <?php checked(true, $permission_buy_approval, true); ?>>
						</div>
						<?php
					}
					?>
					<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
						<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
							<?php esc_html_e('View all account orders','b2bking'); ?>
						</div>
						<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_orders" <?php checked(true, $permission_view_orders, true); ?>>
					</div>

					<?php
					if (class_exists('WC_Subscriptions')){
						?>
						<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
							<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
								<?php esc_html_e('View all account subscriptions','b2bking'); ?>
							</div>
							<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_subscriptions" <?php checked(true, $permission_view_subscriptions, true); ?>>
						</div>
						<?php
					}

					?>

					<?php if (intval(get_option('b2bking_enable_offers_setting', 1)) === 1){ ?>
						<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
							<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
								<?php esc_html_e('View all account offers','b2bking'); ?>
							</div>
							<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_offers" <?php checked(true, $permission_view_offers, true); ?>>
						</div>
					<?php } ?>
					<?php if (intval(get_option('b2bking_enable_conversations_setting', 1)) === 1){ ?>
						<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
							<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
								<?php esc_html_e('View all account conversations','b2bking'); ?>
							</div>
							<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_conversations" <?php checked(true, $permission_view_conversations, true); ?>>
						</div>
					<?php } ?>
					<?php if (intval(get_option('b2bking_enable_purchase_lists_setting', 1)) === 1){ ?>
						<div class="b2bking_subaccounts_new_account_container_content_element_checkbox">
							<div class="b2bking_subaccounts_new_account_container_content_element_checkbox_name">
								<?php esc_html_e('View all account purchase lists','b2bking'); ?>
							</div>
							<input type="checkbox" value="1" class="b2bking_subaccounts_new_account_container_content_element_checkbox_input" name="b2bking_subaccounts_new_account_container_content_element_checkbox_view_lists" <?php checked(true, $permission_view_lists, true); ?>>
						</div>
					<?php } ?>

					<?php

					do_action('b2bking_custom_subaccount_after_permissions', $subaccount_id);


					if (apply_filters('b2bking_allow_subaccount_creation_editing', true)){
						?>
						<div class="b2bking_subaccounts_new_account_container_content_bottom">
							<button class="b2bking_subaccounts_edit_account_container_content_bottom_button_delete" type="button" value="<?php echo esc_attr($subaccount_id); ?>">
								<svg class="b2bking_subaccounts_new_account_container_content_bottom_button_icon" xmlns="http://www.w3.org/2000/svg" width="32" height="33" fill="none" viewBox="0 0 32 33">
								  <path fill="#fff" d="M11 16.572c2.743 0 4.813-2.07 4.813-4.813S13.742 6.946 11 6.946s-4.813 2.07-4.813 4.813 2.07 4.813 4.813 4.813zm1.375 1.303h-2.75A6.883 6.883 0 002.75 24.75v1.375h16.5V24.75a6.883 6.883 0 00-6.875-6.875zm15.528-6.472l-3.153 3.153-3.153-3.153-1.944 1.944 3.151 3.152-3.152 3.152 1.944 1.945 3.153-3.153 3.154 3.154 1.944-1.944-3.153-3.153 3.153-3.153-1.944-1.944z"/>
								</svg>
								<?php esc_html_e('Delete subaccount', 'b2bking'); ?>
							</button>
							<button class="b2bking_subaccounts_edit_account_container_content_bottom_button" type="button" value="<?php echo esc_attr($subaccount_id); ?>">
								<svg class="b2bking_subaccounts_new_account_container_content_bottom_button_icon" xmlns="http://www.w3.org/2000/svg" width="29" height="21" fill="none" viewBox="0 0 29 21">
								  <path fill="#fff" d="M8.626 10.063c2.868 0 5.032-2.163 5.032-5.031S11.494 0 8.626 0 3.594 2.164 3.594 5.032s2.164 5.031 5.032 5.031zm1.437 1.363H7.188C3.225 11.426 0 14.651 0 18.614v1.438h17.252v-1.438c0-3.963-3.225-7.188-7.189-7.188zM26.3 4.658l-6.182 6.17-1.857-1.857-2.033 2.033 3.89 3.887 8.212-8.197-2.03-2.036z"/>
								</svg>
								<?php esc_html_e('Update subaccount', 'b2bking'); ?>
							</button>
						</div>
						<?php
					}
					?>
				</div>
			</div>


			<?php

		} else {
			// no permission
			esc_html_e('Subaccount does not exist!','b2bking');
		}

	}

	function b2bking_purchase_lists_endpoint_content(){

		echo do_shortcode('[b2bking_purchaselists]');

	}

	// Content of individual purchase list in my account (based on bulk order form content)
	function b2bking_purchase_list_endpoint_content(){

		if (function_exists('wp_suspend_cache_addition')){
			wp_suspend_cache_addition(true);
		}

		// bulkorder styling
		if (B2BKING_FILE_RELEASE === 'DEV'){
			wp_enqueue_style('b2bking_bulkorder', plugins_url('../includes/assets/css/style-bulkorder.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);
		} else {
			wp_enqueue_style('b2bking_bulkorder', plugins_url('../includes/assets/css/style-bulkorder.min.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);
		}


		// get list name
		$purchase_list_id = sanitize_text_field( $_GET['id'] );
		$list_author_id = get_post_field( 'post_author', $purchase_list_id );

		// check permissions
		$current_user = get_current_user_id();
		$subaccounts_list = explode(',', get_user_meta($current_user, 'b2bking_subaccounts_list', true));
		$subaccounts_list = array_filter($subaccounts_list); // filter blank, null, etc.
		array_push($subaccounts_list, $current_user);

		// if multiple levels, add all subaccounts orders to main query
		if (apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
			$subaccounts_list = array_filter(array_unique($this->get_all_subaccounts($current_user, array($current_user))));
		}

		// if current account is subaccount AND has permission to view all account purchase lists, add parent account + all subaccounts 
		$account_type = get_user_meta($current_user, 'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			$permission_view_all_lists = filter_var(get_user_meta($current_user, 'b2bking_account_permission_view_lists', true),FILTER_VALIDATE_BOOLEAN);
			if ($permission_view_all_lists === true){

				// has permission, add all account orders (parent+parent subaccount list orders)
				$parent_account = get_user_meta($current_user, 'b2bking_account_parent', true);
				$parent_subaccounts_list = explode(',', get_user_meta($parent_account, 'b2bking_subaccounts_list', true));
				$parent_subaccounts_list = array_filter($parent_subaccounts_list); // filter blank, null, etc.
				array_push($parent_subaccounts_list, $parent_account); // add parent itself to form complete parent accounts list

				$subaccounts_list = array_merge($subaccounts_list, $parent_subaccounts_list);

				// check if parent has a parent
				if (apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
					$parent_account_type = get_user_meta($parent_account, 'b2bking_account_type', true);
					if ($parent_account_type === 'subaccount'){
						$parent_parent_account = get_user_meta($parent_account, 'b2bking_account_parent', true);

						$parent_parent_subaccounts_list = explode(',', get_user_meta($parent_parent_account, 'b2bking_subaccounts_list', true));
						$parent_parent_subaccounts_list = array_filter($parent_parent_subaccounts_list); // filter blank, null, etc.
						array_push($parent_parent_subaccounts_list, $parent_parent_account); // add parent itself to form complete parent accounts list

						$subaccounts_list = array_merge($subaccounts_list, $parent_parent_subaccounts_list);
					}
				}
			}
		}

		// Get current user's data: group, id, login, etc
	    $currentuserid = get_current_user_id();
    	$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
    	if ($account_type === 'subaccount'){
    		// for all intents and purposes set current user as the subaccount parent
    		$parent_user_id = get_user_meta($currentuserid, 'b2bking_account_parent', true);
    		$currentuserid = $parent_user_id;
    	}
		$currentusergroupidnr = b2bking()->get_user_group($currentuserid);

		// if user is B2C, set to B2C
		if (get_user_meta($currentuserid,'b2bking_b2buser', true) !== 'yes'){
			$currentusergroupidnr = 'b2c';
		}

		if (in_array($list_author_id, $subaccounts_list )){
			// has permission to view purchase list
			$list_title = get_the_title($purchase_list_id);
			$list_details = get_post_meta($purchase_list_id, 'b2bking_purchase_list_details', true);
			$list_items = explode('|', $list_details);
			$list_items = array_filter($list_items);
			$products_list_comma = '';
			foreach ($list_items as $list_item){
				$item = explode(':', $list_item);
				$product_id = $item[0];
				$products_list_comma .= $product_id.',';
			}
			// remove last comma
			$products_list_comma = substr($products_list_comma, 0, -1);

			ob_start();
			?>
			<div class="b2bking_bulkorder_form_container">
				<div class="b2bking_bulkorder_form_container_top">
					<?php echo esc_html($list_title); ?>
				</div>
				<div class="b2bking_bulkorder_form_container_content">
					<div class="b2bking_bulkorder_form_container_content_header">
						<?php do_action('b2bking_bulkorder_column_header_start'); ?>

						<div class="b2bking_bulkorder_form_container_content_header_product">
							<?php 
							if (apply_filters('b2bking_skusearch_disabled_list', true)){
								esc_html_e('Product', 'b2bking'); 
							} else {
								if (intval(get_option( 'b2bking_search_by_sku_setting', 1 )) === 1){
									esc_html_e('Search by', 'b2bking');
									ob_start();
									?>
									<select id="b2bking_bulkorder_searchby_select">
										<option value="productname"><?php esc_html_e('Product Name', 'b2bking'); ?></option>
										<option value="sku"><?php 

										echo apply_filters('b2bking_sku_search_display', esc_html__('SKU', 'b2bking')); 
										?></option>
									</select>
									<?php 
									$content = ob_get_clean();
									echo apply_filters('b2bking_classic_form_searchby_display', $content);
								} else {
									esc_html_e('Product name', 'b2bking');
								}
							}
							?>
	            		</div>
	            		<div class="b2bking_bulkorder_form_container_content_header_qty">
	            			<?php esc_html_e('Qty', 'b2bking'); ?>
	            		</div>
	            		<?php do_action('b2bking_bulkorder_column_header_mid'); ?>

	            		<div class="b2bking_bulkorder_form_container_content_header_subtotal">
	            			<?php esc_html_e('Subtotal', 'b2bking'); ?>
	            		</div>
	            		<?php do_action('b2bking_bulkorder_column_header_end'); ?>

					</div>

					<?php 
						$i = 0;
						$total = 0;
						$cleanup_needed = false;
						$valid_list_items = array();

						$pricesstring = '';

						foreach ($list_items as $list_item){
							$item = explode(':', $list_item);
							$product_id = $item[0];
							$product_qty = apply_filters('b2bking_purchase_list_start_quantity', $item[1]);
							$productobj = wc_get_product($product_id);

							// Check if product is valid and not trashed - if not, mark for cleanup and skip
							if (!is_a($productobj,'WC_Product_Variation') && !is_a($productobj,'WC_Product')){
								$cleanup_needed = true;
								continue; // Skip this deleted product
							}

							// Also skip products that are in the trash
							if ($productobj->get_status() === 'trash') {
								$cleanup_needed = true;
								continue;
							}

							// Add valid product to cleaned list
							$valid_list_items[] = $list_item;


							// for locked lists, add attribute data as well
							$variation_data = get_post_meta($purchase_list_id, 'variation_data', true);
							if (isset($variation_data[$i])){
								if (!empty($variation_data[$i])){
									$attribute_data = $variation_data[$i];
									$attribute_array = array();
									foreach ($attribute_data as $attribute_name => $value){
										$attribute_name = explode('attribute_', $attribute_name)[1];
										$attribute_array[$attribute_name] = $value;
									}

									$productobj->set_attributes( 
									    $attribute_array
									);
								}
							}
							

							$i++;

							$product_title = strip_tags($productobj->get_formatted_name());
							//if product is a variation with 3 or more attributes, need to change display because get_name doesnt 
							// show items correctly
							if (is_a($productobj,'WC_Product_Variation')){
								$attributes = $productobj->get_variation_attributes();
								$number_of_attributes = count($attributes);
								if ($number_of_attributes > 2){
									$product_title = $productobj->get_name();
									$product_title.=' - ';
									foreach ($attributes as $attribute){
										$product_title.=$attribute.', ';
									}
									$product_title = substr($product_title, 0, -2);
								}
							}

							$product_title = apply_filters('b2bking_product_title_bulk_order', $product_title, $product_id);

							if( $productobj->is_on_sale() ) {
							    $product_price = $productobj -> get_sale_price();
							} else {
								$product_price = $productobj -> get_price();
								$sale_price = $productobj -> get_sale_price();
								if ($sale_price > $product_price){
									// we have a raise price rule
									$product_price = $sale_price;
								}
							}

							$product_price = round(floatval(b2bking()->b2bking_wc_get_price_to_display( $productobj, array( 'price' => $product_price))),2);
							$product_stock = $productobj->get_stock_quantity();

							
							$pricetiers = get_post_meta($product_id,'b2bking_product_pricetiers_group_'.$currentusergroupidnr, true);
							// if no tiers AND no group price exists, get B2C tiered pricing
							$grregprice = get_post_meta($product_id, 'b2bking_regular_product_price_group_'.$currentusergroupidnr, true );
							$grsaleprice = get_post_meta($product_id, 'b2bking_sale_product_price_group_'.$currentusergroupidnr, true );
							$grpriceexists = 'no';
							if (!empty($grregprice) && b2bking()->tofloat($grregprice) !== 0){
								$grpriceexists = 'yes';	
							}
							if (!empty($grsaleprice) && b2bking()->tofloat($grsaleprice) !== 0){
								$grpriceexists = 'yes';	
							}

							if (empty($pricetiers) && $grpriceexists === 'no'){
								$pricetiers = get_post_meta($product_id, 'b2bking_product_pricetiers_group_b2c', true );
							}


							$pricetiers = b2bking()->convert_price_tiers($pricetiers, $productobj);

							if (empty($pricetiers)){
								$pricetiers = 0;
							} else {
								// adjust product price based on price tiers
								// find product quantity in cart
								$quantitycart = 0;
								if (is_object( WC()->cart )){
								    foreach( WC()->cart->get_cart() as $cart_item ){
								        if ( $product_id === $cart_item['product_id'] || $product_id === $cart_item['variation_id']){
								            $quantitycart = $cart_item['quantity'];
								            break;
								        }
								    }
								}

								// add list qty
								$quantitycart += $product_qty;

							    if ($quantitycart !== 0){
									$price_tiers = explode(';', $pricetiers);
									$quantities_array = array();
									$prices_array = array();
									// first eliminate all quantities larger than the quantity in cart
									foreach($price_tiers as $tier){
										$tier_values = explode(':', $tier);
										if ($tier_values[0] <= $quantitycart && !empty($tier_values[0])){
											array_push($quantities_array, $tier_values[0]);
											$prices_array[$tier_values[0]] = b2bking()->tofloat($tier_values[1]);
										}
									}

									// if any number remains
									if(count($quantities_array) !== 0){
										// get the largest number
										$largest = max($quantities_array);

										// if regular table exist, but group table does not exist
										// apply tiered pricing only if the user's group price is not already smaller than tier price
										$product_price =  $prices_array[$largest];


									}

								}
							}

							$pricesstring .= $product_id.'-'.$product_price.'-'.$pricetiers.'-'.$product_stock.'|';
							
							$subtotal = $product_qty * $product_price;
							$total += $subtotal;

							if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'))){
								$subtotal = esc_html__('Quote','b2bking');
							} else {
								if (intval(get_option( 'b2bking_show_accounting_subtotals_setting', 0 )) === 1){
									$subtotal = strip_tags(wc_price($subtotal));
								} else {
									$subtotal = get_woocommerce_currency_symbol().$subtotal;
								}
							}

							?>
							<div class="b2bking_bulkorder_form_container_content_line">
								<input type="text" data-url="<?php echo esc_url($productobj->get_permalink());?>" class="b2bking_bulkorder_form_container_content_line_product b2bking_bulkorder_form_container_content_line_product_url b2bking_selected_product_id_<?php echo esc_attr($product_id); ?>" placeholder="<?php esc_attr_e('Search for a product...','b2bking'); ?>" value="<?php echo esc_attr($product_title); ?>" readonly>
								<?php
								$locked_list = apply_filters('b2bking_locked_list', get_post_meta($purchase_list_id, 'locked_list', true));
								if ($locked_list !== 'yes'){
									?><button class="b2bking_bulkorder_clear"><?php esc_html_e('Clear X','b2bking'); ?></button><?php
								}?><input type="number" min="0" class="b2bking_bulkorder_form_container_content_line_qty" step="1" value="<?php echo esc_attr($product_qty); ?>"><?php do_action('b2bking_bulkorder_column_header_mid_content', esc_attr($product_id), esc_attr($product_qty)); ?><div class="b2bking_bulkorder_form_container_content_line_subtotal"><?php echo esc_html($subtotal); 

									do_action('b2bking_list_frontend_after_subtotal');

							?></div><?php do_action('b2bking_bulkorder_column_header_end_content'); ?><div class="b2bking_bulkorder_form_container_content_line_livesearch"></div></div>
							<?php
						

							unset($productobj);
						}

						// Clean up deleted products from the list if needed
						if ($cleanup_needed && !empty($valid_list_items)) {
							$cleaned_list_details = implode('|', $valid_list_items);
							update_post_meta($purchase_list_id, 'b2bking_purchase_list_details', $cleaned_list_details);
						}

					?>
					<input type="hidden" id="b2bking_initial_prices" value="<?php echo esc_attr($pricesstring);?>">
					<?php
					if (apply_filters('b2bking_purchase_list_loading_activated', true)){ // calls an ajax function on each item to get its details, can affect performance
						?>
						<input type="hidden" id="b2bking_purchase_list_page" value="1">
						<?php
					}
					?>

	            	<!-- new line button -->
	            	<?php
		            	$locked_list = apply_filters('b2bking_locked_list', get_post_meta($purchase_list_id, 'locked_list', true));
		            	if ($locked_list !== 'yes'){
		            		?>
			            	<div class="b2bking_bulkorder_form_container_newline_container">
			            		<button class="b2bking_bulkorder_form_container_newline_button">
			            			<svg class="b2bking_bulkorder_form_container_newline_button_icon" xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none" viewBox="0 0 22 22">
			            			  <path fill="#fff" d="M11 1.375c-5.315 0-9.625 4.31-9.625 9.625s4.31 9.625 9.625 9.625 9.625-4.31 9.625-9.625S16.315 1.375 11 1.375zm4.125 10.14a.172.172 0 01-.172.172h-3.265v3.266a.172.172 0 01-.172.172h-1.032a.172.172 0 01-.171-.172v-3.265H7.046a.172.172 0 01-.172-.172v-1.032c0-.094.077-.171.172-.171h3.266V7.046c0-.095.077-.172.171-.172h1.032c.094 0 .171.077.171.172v3.266h3.266c.095 0 .172.077.172.171v1.032z"/>
			            			</svg>
			            			<?php esc_html_e('new line', 'b2bking'); ?>
			            		</button>
			            	</div>
			            	<?php
			            }
			            ?>
	            	<div class="b2bking_bulkorder_form_newline_template" style="display:none">
	            	    <div class="b2bking_bulkorder_form_container_content_line">
	            	      <input type="text" class="b2bking_bulkorder_form_container_content_line_product">
	            	      <input type="number" min="0" step="1" class="b2bking_bulkorder_form_container_content_line_qty">
	            	      <?php do_action('b2bking_bulkorder_column_header_mid_newline_content'); ?>
	            	      <div class="b2bking_bulkorder_form_container_content_line_subtotal">pricetext</div>
	            	      <div class="b2bking_bulkorder_form_container_content_line_livesearch"></div>
	            	    </div>
	            	  </div>

	            	<!-- add to cart button -->
	            	<div class="b2bking_bulkorder_form_container_bottom">
	            		<div class="b2bking_bulkorder_form_container_bottom_add">
	            			<button class="b2bking_bulkorder_form_container_bottom_add_button" type="button" value="<?php echo esc_attr($purchase_list_id); ?>">
	            				<svg class="b2bking_bulkorder_form_container_bottom_add_button_icon" xmlns="http://www.w3.org/2000/svg" width="21" height="19" fill="none" viewBox="0 0 21 19">
	            				  <path fill="#fff" d="M18.401 11.875H7.714l.238 1.188h9.786c.562 0 .978.53.854 1.087l-.202.901a2.082 2.082 0 011.152 1.87c0 1.159-.93 2.096-2.072 2.079-1.087-.016-1.981-.914-2.01-2.02a2.091 2.091 0 01.612-1.543H8.428c.379.378.614.903.614 1.485 0 1.18-.967 2.131-2.14 2.076-1.04-.05-1.886-.905-1.94-1.964a2.085 2.085 0 011.022-1.914L3.423 2.375H.875A.883.883 0 010 1.485V.89C0 .399.392 0 .875 0h3.738c.416 0 .774.298.857.712l.334 1.663h14.32c.562 0 .978.53.854 1.088l-1.724 7.719a.878.878 0 01-.853.693zm-3.526-5.64h-1.75V4.75a.589.589 0 00-.583-.594h-.584a.589.589 0 00-.583.594v1.484h-1.75a.589.589 0 00-.583.594v.594c0 .328.26.594.583.594h1.75V9.5c0 .328.261.594.583.594h.584a.589.589 0 00.583-.594V8.016h1.75a.589.589 0 00.583-.594v-.594a.589.589 0 00-.583-.594z"/>
	            				</svg>
	            			<?php 

	            			if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'))){
	            				esc_html_e('Add to Quote','b2bking'); 
	            			} else {
	            				esc_html_e('Add to Cart','b2bking'); 
	            			}
	            			
	            			?>
	            			</button>

	            			<?php

	            			$locked_list = apply_filters('b2bking_locked_list', get_post_meta($purchase_list_id, 'locked_list', true));
	            			if ($locked_list !== 'yes'){
	            				?>
	            				<button class="b2bking_bulkorder_form_container_bottom_update_button" type="button" value="<?php echo esc_attr($purchase_list_id); ?>">
	            					<svg class="b2bking_bulkorder_form_container_bottom_update_button_icon" xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none" viewBox="0 0 22 22">
	            					  <path fill="#fff" d="M9.778 4.889h7.333v2.444H9.778V4.89zm0 4.889h7.333v2.444H9.778V9.778zm0 4.889h7.333v2.444H9.778v-2.444zm-4.89-9.778h2.445v2.444H4.89V4.89zm0 4.889h2.445v2.444H4.89V9.778zm0 4.889h2.445v2.444H4.89v-2.444zM20.9 0H1.1C.489 0 0 .489 0 1.1v19.8c0 .489.489 1.1 1.1 1.1h19.8c.489 0 1.1-.611 1.1-1.1V1.1c0-.611-.611-1.1-1.1-1.1zm-1.344 19.556H2.444V2.444h17.112v17.112z"/>
	            					</svg>
	            				<?php esc_html_e('Update list','b2bking'); ?>
	            				</button>
	            				<?php
	            			} else {
	            				echo '&nbsp;&nbsp;';
	            			}
	            			?>
	            			
	            			<button class="b2bking_bulkorder_form_container_bottom_delete_button" type="button" value="<?php echo esc_attr($purchase_list_id); ?>">
	            				<svg class="b2bking_bulkorder_form_container_bottom_delete_button_icon" xmlns="http://www.w3.org/2000/svg" width="29" height="29" fill="none" viewBox="0 0 29 29">
	            				  <path fill="#fff" d="M17.4 5.8h4.35c.87 0 1.45.58 1.45 1.45V8.7H4.35V7.25c0-.87.725-1.45 1.45-1.45h4.35c.29-1.595 1.885-2.9 3.625-2.9S17.11 4.205 17.4 5.8zm-5.8 0h4.35c-.29-.87-1.305-1.45-2.175-1.45-.87 0-1.885.58-2.175 1.45zm-5.8 4.35h15.95l-1.305 14.645c0 .725-.725 1.305-1.45 1.305H8.555c-.725 0-1.305-.58-1.45-1.305L5.8 10.15z"/>
	            				</svg>
	            			<?php esc_html_e('Trash','b2bking'); ?>
	            			</button>
	            			<?php do_action('b2bking_bulkorder_form_after_actions', esc_attr($purchase_list_id)); ?>


	            		</div>
	            		<div class="b2bking_bulkorder_form_container_bottom_total">
            			<?php
            			if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'))){

            			} else {
            				?>
            					<?php esc_html_e('Total: ','b2bking'); ?><strong><?php echo wc_price(0);?></strong>
            				<?php	
            			}?>
            			
            		</div>
	            	</div>


	            </div>
			</div>
			<?php

			$list = ob_get_clean();

			// snippet to use different theme in purchase lists
			$purchase_lists_theme = apply_filters('b2bking_purchase_list_display_theme', 'classic'); // can be set to cream or indigo
			if ($purchase_lists_theme !== 'classic'){
				add_filter('b2bking_purchase_list_display', function($list, $purchase_list_id, $products_list_comma, $list_title){
					ob_start();
					echo '<input type="hidden" id="purchase_list_id" name="purchase_list_id" value="'.$purchase_list_id.'">';
					echo apply_filters('b2bking_purchase_list_title_theme', '<h3>'.esc_html($list_title).'</h3>');
					$purchase_lists_theme = apply_filters('b2bking_purchase_list_display_theme', 'classic'); // can be set to cream or indigo

					if ($purchase_lists_theme === 'cream'){
						// set products with "any" to display the parent variable product, not the individual variation
						// Convert comma-separated string to array
					    $product_ids = array_filter(array_map('trim', explode(',', $products_list_comma)));
					    
					    // Array to store normalized IDs
					    $normalized_ids = array();
					    
					    foreach ($product_ids as $product_id) {
					        // Get product object
					        $product = wc_get_product($product_id);
					        
					        if (!$product) {
					            continue; // Skip if product doesn't exist
					        }
					        
					        // Check if it's a variation
					        if ($product->is_type('variation')) {
					            // Get the parent/variable product ID
					            $parent_id = $product->get_parent_id();
					            if ($parent_id) {
					                $normalized_ids[] = $parent_id;
					            }
					        } else {
					            // If it's not a variation, keep the original ID
					            $normalized_ids[] = $product_id;
					        }

					        unset($product);
					    }
					    
					    // Remove duplicates (in case multiple variations of same product were in list)
					    $products_list_comma = implode(',',array_unique($normalized_ids));
					}

					$multiselect = apply_filters('b2bking_purchase_list_multiselect_cream','no');
					if ($multiselect === true){ $multiselect = 'yes'; }

					$shortcode = apply_filters('b2bking_purchase_list_shortcode','[b2bking_bulkorder width="nonadaptive" multiselect="'.$multiselect.'" theme='.$purchase_lists_theme.' product_list="'.$products_list_comma.'"]');


					echo do_shortcode($shortcode);

					?>
					<div class="b2bking_theme_list_buttons">
						<button class="b2bking_bulkorder_form_container_bottom_add_button" type="button" value="<?php echo esc_attr($purchase_list_id); ?>">
							<svg class="b2bking_bulkorder_form_container_bottom_add_button_icon" xmlns="http://www.w3.org/2000/svg" width="21" height="19" fill="none" viewBox="0 0 21 19">
							  <path fill="#fff" d="M18.401 11.875H7.714l.238 1.188h9.786c.562 0 .978.53.854 1.087l-.202.901a2.082 2.082 0 011.152 1.87c0 1.159-.93 2.096-2.072 2.079-1.087-.016-1.981-.914-2.01-2.02a2.091 2.091 0 01.612-1.543H8.428c.379.378.614.903.614 1.485 0 1.18-.967 2.131-2.14 2.076-1.04-.05-1.886-.905-1.94-1.964a2.085 2.085 0 011.022-1.914L3.423 2.375H.875A.883.883 0 010 1.485V.89C0 .399.392 0 .875 0h3.738c.416 0 .774.298.857.712l.334 1.663h14.32c.562 0 .978.53.854 1.088l-1.724 7.719a.878.878 0 01-.853.693zm-3.526-5.64h-1.75V4.75a.589.589 0 00-.583-.594h-.584a.589.589 0 00-.583.594v1.484h-1.75a.589.589 0 00-.583.594v.594c0 .328.26.594.583.594h1.75V9.5c0 .328.261.594.583.594h.584a.589.589 0 00.583-.594V8.016h1.75a.589.589 0 00.583-.594v-.594a.589.589 0 00-.583-.594z"/>
							</svg>
						<?php 

						if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes'))){
							esc_html_e('Add to Quote','b2bking'); 
						} else {
							esc_html_e('Add to Cart','b2bking'); 
						}
						
						?>
						</button>

						<?php
						$locked_list = apply_filters('b2bking_locked_list', get_post_meta($purchase_list_id, 'locked_list', true));
						if ($locked_list !== 'yes'){
							?>
							<button class="b2bking_bulkorder_form_container_bottom_update_button" type="button" value="<?php echo esc_attr($purchase_list_id); ?>">
								<svg class="b2bking_bulkorder_form_container_bottom_update_button_icon" xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="none" viewBox="0 0 22 22">
								  <path fill="#fff" d="M9.778 4.889h7.333v2.444H9.778V4.89zm0 4.889h7.333v2.444H9.778V9.778zm0 4.889h7.333v2.444H9.778v-2.444zm-4.89-9.778h2.445v2.444H4.89V4.89zm0 4.889h2.445v2.444H4.89V9.778zm0 4.889h2.445v2.444H4.89v-2.444zM20.9 0H1.1C.489 0 0 .489 0 1.1v19.8c0 .489.489 1.1 1.1 1.1h19.8c.489 0 1.1-.611 1.1-1.1V1.1c0-.611-.611-1.1-1.1-1.1zm-1.344 19.556H2.444V2.444h17.112v17.112z"/>
								</svg>
							<?php esc_html_e('Update list','b2bking'); ?>
							</button>
							<?php
						} else {
							echo '&nbsp;&nbsp;';
						}
						?>

						<button class="b2bking_bulkorder_form_container_bottom_delete_button b2bking_list_button_delete_theme" type="button" value="<?php echo esc_attr($purchase_list_id); ?>">
							<svg class="b2bking_bulkorder_form_container_bottom_delete_button_icon" xmlns="http://www.w3.org/2000/svg" width="29" height="29" fill="none" viewBox="0 0 29 29">
							  <path fill="#fff" d="M17.4 5.8h4.35c.87 0 1.45.58 1.45 1.45V8.7H4.35V7.25c0-.87.725-1.45 1.45-1.45h4.35c.29-1.595 1.885-2.9 3.625-2.9S17.11 4.205 17.4 5.8zm-5.8 0h4.35c-.29-.87-1.305-1.45-2.175-1.45-.87 0-1.885.58-2.175 1.45zm-5.8 4.35h15.95l-1.305 14.645c0 .725-.725 1.305-1.45 1.305H8.555c-.725 0-1.305-.58-1.45-1.305L5.8 10.15z"/>
							</svg>
						<?php esc_html_e('Delete List','b2bking'); ?>
						</button>
					</div>
					<?php
					if ($purchase_lists_theme === 'cream'){
						?>
						<style type="text/css">
							.b2bking_theme_list_buttons .b2bking_bulkorder_form_container_bottom_add_button{
								background: #323232;
							}
							.b2bking_theme_list_buttons .b2bking_bulkorder_form_container_bottom_add_button:hover{
								background: #000;
							}
						</style>
						<?php
					}

					return ob_get_clean();
				}, 10, 4);
			}

			echo apply_filters('b2bking_purchase_list_display', $list, $purchase_list_id, $products_list_comma, $list_title);
		} else {
			esc_html_e('Purchase list does not exist!', 'b2bking');
		}

	}

	// Add "Save as Purchase List" button to cart
	function b2bking_purchase_list_cart_button(){
		// should never appear to a guest user + check setting
		if (is_user_logged_in() && (intval(get_option('b2bking_enable_purchase_lists_setting', 1)) === 1)){
			// should not appear if user has a dynamic rule replace prices with quote
			$user_id = get_current_user_id();
	    	$user_id = b2bking()->get_top_parent_account($user_id);
	    	if (get_transient('b2bking_replace_prices_quote_user_'.$user_id) !== 'yes'){
			?>
				<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/loader.svg', __FILE__); ?>">

				<button type="button" class="b2bking_add_cart_to_purchase_list_button button">
					<?php echo apply_filters('b2bking_save_as_purchase_list_text', esc_html__( 'Save as purchase list', 'b2bking' )); ?>
				</button>
			<?php
			}
		}
	}

	// Add "Placed by" column to orders
	function b2bking_orders_placed_by_column( $columns ) {

	    $new_columns = array();
	    foreach ( $columns as $key => $name ) {
	        $new_columns[ $key ] = $name;
	        // add ship-to after order status column
	        if ( 'order-number' === $key ) {
	            $new_columns['order-placed-by'] = esc_html__( 'Placed by', 'b2bking' );
	        }
	    }
	    return $new_columns;
	}

	// Add content to the "Placed by" column
	function b2bking_orders_placed_by_column_content( $order ) {
	    $customer_id = $order->get_customer_id();
	    $username = get_user_by('id', $customer_id)->user_login;
	    echo apply_filters('b2bking_orders_placed_by_content', esc_html($username), $order);
	}

	function b2bking_visible_subscriptions_subaccounts($subscriptions, $current_user){

		// parent account subscriptions
		$account_type = get_user_meta($current_user, 'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			$permission_view_all_orders = filter_var(get_user_meta($current_user, 'b2bking_account_permission_view_subscriptions', true),FILTER_VALIDATE_BOOLEAN);
			if ($permission_view_all_orders === true || apply_filters('b2bking_view_subscriptions_all', false)){

				// has permission, add all account orders (parent+parent subaccount list orders)
				$parent_account = get_user_meta($current_user, 'b2bking_account_parent', true);
				$parent_subaccounts_list = explode(',', get_user_meta($parent_account, 'b2bking_subaccounts_list', true));
				$parent_subaccounts_list = array_filter($parent_subaccounts_list); // filter blank, null, etc.
				array_push($parent_subaccounts_list, $parent_account); // add parent itself to form complete parent accounts list

				foreach ($parent_subaccounts_list as $parent_id){
					$subscription_ids = WCS_Customer_Store::instance()->get_users_subscription_ids( $parent_id );

					foreach ( $subscription_ids as $subscription_id ) {
						$subscription = wcs_get_subscription( $subscription_id );

						if ( $subscription ) {
							$subscriptions[ $subscription_id ] = $subscription;
						}
					}
				}

			}
		}

		// also add all subaccounts subscriptions
		$subaccounts_list = explode(',', get_user_meta($current_user, 'b2bking_subaccounts_list', true));
		$subaccounts_list = array_filter($subaccounts_list); // filter blank, null, etc.
		foreach ($subaccounts_list as $subaccount_id){
			$subscription_ids = WCS_Customer_Store::instance()->get_users_subscription_ids( $subaccount_id );

			foreach ( $subscription_ids as $subscription_id ) {
				$subscription = wcs_get_subscription( $subscription_id );

				if ( $subscription ) {
					$subscriptions[ $subscription_id ] = $subscription;
				}
			}
		}

		return $subscriptions;
	}

	// Show user subaccount orders as well
	function b2bking_add_subaccounts_orders_to_main_query( $q ) {

		if (is_null($q)){
			return;
		}

		// Set customer orders to Current User + Subaccounts
		$current_user = get_current_user_id();
		$subaccounts_list = explode(',', get_user_meta($current_user, 'b2bking_subaccounts_list', true));
		$subaccounts_list = array_filter($subaccounts_list); // filter blank, null, etc.
		// add current user to subaccounts to form a complete accounts list
		array_push($subaccounts_list, $current_user);

		// if multiple levels, add all subaccounts orders to main query
		if (apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
			$subaccounts_list = array_filter(array_unique($this->get_all_subaccounts($current_user, array($current_user))));
		}

		// if current account is subaccount AND has permission to view all account orders, add parent account+all subaccounts orders
		$account_type = get_user_meta($current_user, 'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			$permission_view_all_orders = filter_var(get_user_meta($current_user, 'b2bking_account_permission_view_orders', true),FILTER_VALIDATE_BOOLEAN);
			if ($permission_view_all_orders === true){

				// has permission, add all account orders (parent+parent subaccount list orders)
				$parent_account = get_user_meta($current_user, 'b2bking_account_parent', true);
				$parent_subaccounts_list = explode(',', get_user_meta($parent_account, 'b2bking_subaccounts_list', true));
				$parent_subaccounts_list = array_filter($parent_subaccounts_list); // filter blank, null, etc.
				array_push($parent_subaccounts_list, $parent_account); // add parent itself to form complete parent accounts list

				$subaccounts_list = array_merge($subaccounts_list, $parent_subaccounts_list);

				// check if parent has a parent
				if (apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
					$parent_account_type = get_user_meta($parent_account, 'b2bking_account_type', true);
					if ($parent_account_type === 'subaccount'){
						$parent_parent_account = get_user_meta($parent_account, 'b2bking_account_parent', true);

						$parent_parent_subaccounts_list = explode(',', get_user_meta($parent_parent_account, 'b2bking_subaccounts_list', true));
						$parent_parent_subaccounts_list = array_filter($parent_parent_subaccounts_list); // filter blank, null, etc.
						array_push($parent_parent_subaccounts_list, $parent_parent_account); // add parent itself to form complete parent accounts list

						$subaccounts_list = array_merge($subaccounts_list, $parent_parent_subaccounts_list);
					}
				}
			}
		}
		
		if (apply_filters('b2bking_show_subaccount_orders_user', true, $current_user)){
			$q['customer'] = $subaccounts_list; 
		}

	    return $q;
	}

	function get_all_subaccounts($user_id, $final_list = array()){

		$list_meta = get_user_meta($user_id, 'b2bking_subaccounts_list', true);

		if (!empty($list_meta)){

			$sublist = array_filter(explode(',', $list_meta));

			foreach ($sublist as $subaccount_id){
				$final_list = array_merge($final_list, $this->get_all_subaccounts($subaccount_id, $sublist));
			}

		}

		return $final_list;

	}

	// Give user permission to access subaccount orders
	function b2bking_give_main_account_view_subaccount_orders_permission_address( $order ) {
	
    	// build list of current user and subaccounts
    	$current_user = get_current_user_id();
    	$subaccounts_list = explode(',', get_user_meta($current_user, 'b2bking_subaccounts_list', true));
    	$subaccounts_list = array_filter($subaccounts_list); // filter blank, null, etc.
    	array_push($subaccounts_list, $current_user);

    	// if multiple levels, add all subaccounts orders to main query
    	if (apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
    		$subaccounts_list = array_filter(array_unique($this->get_all_subaccounts($current_user, array($current_user))));
    	}

    	// if current account is subaccount AND has permission to view all account orders, add parent account + all subaccounts orders
    	$account_type = get_user_meta($current_user, 'b2bking_account_type', true);
    	if ($account_type === 'subaccount'){
    		$permission_view_all_orders = filter_var(get_user_meta($current_user, 'b2bking_account_permission_view_orders', true),FILTER_VALIDATE_BOOLEAN);
    		if ($permission_view_all_orders === true){

    			// has permission, add all account orders (parent+parent subaccount list orders)
    			$parent_account = get_user_meta($current_user, 'b2bking_account_parent', true);
    			$parent_subaccounts_list = explode(',', get_user_meta($parent_account, 'b2bking_subaccounts_list', true));
    			$parent_subaccounts_list = array_filter($parent_subaccounts_list); // filter blank, null, etc.
    			array_push($parent_subaccounts_list, $parent_account); // add parent itself to form complete parent accounts list

    			$subaccounts_list = array_merge($subaccounts_list, $parent_subaccounts_list);

    			// check if parent has a parent
    			if (apply_filters('b2bking_allow_multiple_subaccount_levels', false)){
    				$parent_account_type = get_user_meta($parent_account, 'b2bking_account_type', true);
    				if ($parent_account_type === 'subaccount'){
    					$parent_parent_account = get_user_meta($parent_account, 'b2bking_account_parent', true);

    					$parent_parent_subaccounts_list = explode(',', get_user_meta($parent_parent_account, 'b2bking_subaccounts_list', true));
    					$parent_parent_subaccounts_list = array_filter($parent_parent_subaccounts_list); // filter blank, null, etc.
    					array_push($parent_parent_subaccounts_list, $parent_parent_account); // add parent itself to form complete parent accounts list

    					$subaccounts_list = array_merge($subaccounts_list, $parent_parent_subaccounts_list);
    				}
    			}
    		}
    	}

    	// check if the current order is part of the list but not this user's order
    	$order_placed_by = $order->get_customer_id();
    	if (in_array($order_placed_by, $subaccounts_list) && $order->get_user_id() !== get_current_user_id()){
    		// give permission
    		wc_get_template( 'order/order-details-customer.php', array( 'order' => $order ) );
    	}
 
	}


	// If multisite, restrict B2C access to my account on main B2B site
	function b2bking_multisite_logout_user_myaccount(){
		if (is_user_logged_in() && (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser',true ) !== 'yes')){
			if (is_account_page()){

				$is_admin_or_manager = is_user_logged_in() && array_intersect( ['administrator', 'shop_manager'], wp_get_current_user()->roles );

				if (!$is_admin_or_manager){
					wp_logout();
				}
			}
		}
	}

	function b2bking_separate_myaccount_redirect(){
		$separate_page = get_option( 'b2bking_registration_separate_my_account_page_setting', 'disabled' );

		if (is_user_logged_in() && $separate_page !== 'disabled'){
			$is_b2b = get_user_meta(get_current_user_id(), 'b2bking_b2buser',true );

			if ($is_b2b === 'yes'){

				$redirection_url = get_permalink( $separate_page );
				// if user is b2b, and this is the b2c my account, redirecto the b2b my account
				if (is_account_page() && intval(b2bking()->safe_get_queried_object_id()) !== intval($separate_page)){
					wp_redirect($redirection_url); // redirect home. 
				}
			} else {
				global $wpdb;
				$option = 'woocommerce_myaccount_page_id';
				$default_my_account = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option ) );
				$redirection_url = get_permalink($default_my_account->option_value);

				// b2c user, if this is b2b my account redirect to b2c
				if (intval(b2bking()->safe_get_queried_object_id()) === intval($separate_page)){
					wp_redirect($redirection_url); // redirect home. 
				}
			}
			
		}
	}

	function b2bking_hide_prices_guest_users_bundle_components(){
		?>
		<style>
			.bundled_item_unavailable, .bundle_unavailable{
				display: none;
			}
		</style>
		<?php
	}

	// Hide prices to guest users
	function b2bking_hide_prices_guest_users( $price, $product ) {
		// if user is guest, OR multisite B2B/B2C separation is enabled and user should be treated as guest
		if (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes')){
			$pricetext = get_option('b2bking_hide_prices_guests_text_setting', esc_html__('Log in to view prices','b2bking'));

			// define icons
			$icons = b2bking()->get_icons();
			foreach ($icons as $icon_name => $svg){
				if (!empty($svg)){
					// replace icons
					$pricetext = str_replace('['.$icon_name.']', $svg, $pricetext);
				}
			}
			
			$pricetext = apply_filters('b2bking_hide_price_product_text', $pricetext, $product, $price);
			return $pricetext;
		} else {
			return $price;
		}
	}

	function bricks_logged_out_hide_prices($value, $tag, $post_id, $filters, $context){

		if (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes')){

			$pricetext = get_option('b2bking_hide_prices_guests_text_setting', esc_html__('Log in to view prices','b2bking'));

			if (in_array($tag, array('woo_product_regular_price', 'woo_product_sale_price', 'woo_product_price'))){
				$value = $pricetext;
			}
		}

		return $value;
	}

	function b2bking_quote_product_stock_status($val, $product){

		$product_id = $product->get_id();
		$response = b2bking()->get_applicable_rules('quotes_products', $product_id);
		$haverules = 'no';
		if ($response !== 'norules'){
			$rules = $response[0];
			if (!empty($rules)){
				$haverules = 'yes';
			}
		}

		if ($haverules === 'yes'){
			$val = 'instock';
		}

		return $val;
	}


	public static function b2bking_replace_add_to_cart_text_products($text, $product) {

		$product_id = $product->get_id();		

		$response = b2bking()->get_applicable_rules('quotes_products', $product_id);
		$haverules = 'no';
		if ($response !== 'norules'){
			$rules = $response[0];
			if (!empty($rules)){
				$haverules = 'yes';
			}
		}

		if ($haverules === 'yes'){
			// yes, have quote
			if (b2bking()->user_has_p_in_cart('cart') === 'yes'){
	            $text = esc_html__('Read more', 'b2bking');

	        } else {
	            $text = esc_html__('Add to Quote Request', 'b2bking');

	        }
		}

		return $text;
	}

	function b2bking_cart_to_quote_text($translated_text, $original_text, $domain) {
	    if ($domain === 'woocommerce') {
	        if ($original_text === 'View cart') {
	            return __('View quote', 'b2bking');
	        }
	    }
	    return $translated_text;
	}

	function b2bking_modify_add_to_cart_message($message, $products, $show_qty) {
	    // Get translated version of 'quote'
	    $translated_quote = esc_html__('quote', 'b2bking');
	    $translated_quote_capital = ucfirst($translated_quote);
	    
	    // Replace "cart" with "quote" only when it's not part of a URL
	    // Look behind for either start of string or non-URL character
	    // Look ahead for either end of string or non-URL character
	    $message = preg_replace('/(?<![\/\w])([Cc])art(?![\/\w])/', 
	        '$1' === 'C' ? $translated_quote_capital : $translated_quote, 
	        $message
	    );
	    
	    return $message;
	}

	function b2bking_blocks_cart_hide_prices_quote(){
		if (b2bking()->has_blocks_cart() && is_cart()){
			?>
			<style>
				.wc-block-formatted-money-amount, .wp-block-woocommerce-cart-totals-block, .wc-block-cart-items__header-total, .wc-block-cart-item__prices, .wc-block-cart-item__total, .wc-block-components-sale-badge {
				    display: none !important;
				}
				.wc-block-components-main{
					width: 100% !important;
				}
			</style>
			<script>
				jQuery(document).ready(function(){
					jQuery('.wc-block-formatted-money-amount, .wp-block-woocommerce-cart-totals-block, .wc-block-cart-items__header-total, .wc-block-cart-item__prices, .wc-block-cart-item__total, .wc-block-components-sale-badge').remove();
					setTimeout(function(){
						jQuery('.wc-block-formatted-money-amount, .wp-block-woocommerce-cart-totals-block, .wc-block-cart-items__header-total').remove();
					}, 750);
				});
			</script>
			<?php
		}
		
	}

	public static function b2bking_hide_prices_request_quote_products( $price, $product ) {

		$product_id = $product->get_id();

		$response = b2bking()->get_applicable_rules('quotes_products', $product_id);
		$haverules = 'no';
		if ($response !== 'norules'){
			$rules = $response[0];
			if (!empty($rules)){
				$haverules = 'yes';
			}
		}

		if ($haverules === 'yes'){
			// yes, have quote
			$price = '';
		}

		return $price;
	}

	function b2bking_hide_prices_request_quote( $price, $product ) {
		return '';
	}


	function b2bking_disable_purchasable_guest_users($purchasable){
		// if user is guest, or multisite b2b/b2b separation is enabled and user should be treated as guest
		if (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes')){
			return false;
		} else {
			return $purchasable;
		}
	}

	function b2bking_replace_add_to_cart_text() {
		return esc_html__('Add to Quote Request', 'b2bking');
	}

	public static function b2bking_hide_prices_cart( $price ) {

		return apply_filters('b2bking_hidden_price_cart_quote', esc_html__('Quote','b2bking'), $price);
	}

	public static function b2bking_checkout_redirect_to_cart(){
		// only for checkout
	    if ( ! is_checkout() ) return; 

	    if (is_wc_endpoint_url( 'order-received' )) return;

	    wp_redirect( get_permalink( wc_get_page_id( 'cart' ) ) ); // redirect to cart.
	    
	    exit();
	}

	function b2bking_hide_proceed_checkout_blocks(){
		?>
		<style>
			.wp-block-woocommerce-proceed-to-checkout-block, .wc-block-cart__submit-button{
				display:none !important;
			}
		</style>
		<?php
	}

	/* Hide Website completely to guest users */
	function b2bking_hide_products( $q ) {

		if (is_null($q)){
			return;
		}

		// User is guest, or multisite option is enabled and user should be treated as guest
		if (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes')){	

			if (is_array($q)){
	
				$q['where'] .= ' AND p.ID IN ( 98989898321123 )';
				
				return $q;
			}

		    $tax_query = (array) $q->get( 'tax_query' );
		    $tax_query[] = array(
		           'taxonomy' => 'product_cat',
		           'field' => 'slug',
		           'terms' => array( 'j2kh87ds5gjsfd3dfsZn21bd89d' ), // don't show any products
		           'operator' => 'IN'
		    );

		    $q->set( 'tax_query', $tax_query );
		}
	}

	function bricks_postin( $query_vars, $settings, $element_id ) {

		$is_products_query = false;
		if (isset($query_vars['product_cat'])){
			$is_products_query = true;
		}
		if (isset($query_vars['post_type'])){
			if ($query_vars['post_type'] === 'product'){
				$is_products_query = true;
			}
			if (is_array($query_vars['post_type'])){
				if (in_array('product', $query_vars['post_type'])){
					$is_products_query = true;
				}
			}
		}

		if (!$is_products_query){
			return $query_vars; // only modify product queries
		}


		$query_vars['post__in'] = isset($query_vars['post__in']) && is_array($query_vars['post__in']) ? $query_vars['post__in'] : array();


		if (!b2bking()->use_wpml_cache()){
			$allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility');
		} else {
			$allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility'.ICL_LANGUAGE_NAME_EN);
		}

		$allTheIDs = apply_filters('b2bking_ids_post_in_visibility', $allTheIDs);

		$currentval = $query_vars['post__in'];
		if (!empty($currentval) && $allTheIDs !== false){
			$allTheIDs = array_intersect($allTheIDs, $currentval);
		}

		if ($allTheIDs){
		    if(!empty($allTheIDs)){
		    	$query_vars['post__in'] = array_merge($query_vars['post__in'], $allTheIDs);
		    }
		}	

	    return $query_vars;
	}

	function bricks_postin_loggedout( $query_vars, $settings, $element_id ) {

		$is_products_query = false;
		if (isset($query_vars['product_cat'])){
			$is_products_query = true;
		}
		if (isset($query_vars['post_type'])){
			if ($query_vars['post_type'] === 'product'){
				$is_products_query = true;
			}
			if (is_array($query_vars['post_type'])){
				if (in_array('product', $query_vars['post_type'])){
					$is_products_query = true;
				}
			}
		}

		if (!$is_products_query){
			return $query_vars; // only modify product queries
		}

		if (!is_user_logged_in()){
			if (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'hide_website'){
				$query_vars['post__in'] = array('invalid');
			}
		}

	    return $query_vars;
	}

	function b2bking_hide_products_shortcode( $query_args ) {
		// User is guest, or multisite option is enabled and user should be treated as guest
		if (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes')){		
		    $query_args['post__in'] = array('j2kh87ds5gjsfd3dfsZn21bd89d');
		}
		return $query_args;
	}

	function b2bking_show_login() {

		static $b2bking_has_run = false;
		// User is guest, or multisite option is enabled and user should be treated as guest
		if ($b2bking_has_run === false || apply_filters('b2bking_force_show_login', false)){
			if (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes')){	
				remove_action( 'woocommerce_no_products_found', 'wc_no_products_found', 10 );

				do_action('b2bking_before_hide_shop_products_login');

				$message = esc_html( get_option('b2bking_hide_b2b_site_text_setting', esc_html__('Please login to access the B2B Portal.','b2bking')));

				// define icons
				$icons = b2bking()->get_icons();
				foreach ($icons as $icon_name => $svg){
					if (!empty($svg)){
						// replace icons
						$message = str_replace('['.$icon_name.']', $svg, $message);
					}
				}

				echo '<p class="woocommerce-info">' . $message .'</p>';

				echo do_shortcode( '[woocommerce_my_account]' );

				do_action('b2bking_after_hide_shop_products_login');

				$b2bking_has_run = true;
			}
		}
		
	} 

	function b2bking_product_redirection_to_account() {
		// User is guest, or multisite option is enabled and user should be treated as guest
		if (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes')){	
		    if ( ! is_product() ) return; // Only for single product pages.
		    
		    // Get the redirect URL and check if it's still the my account page
		    $redirect_url = apply_filters('b2bking_forbidden_access_redirection_url', get_permalink( wc_get_page_id( 'myaccount' ) ));
		    $myaccount_url = get_permalink( wc_get_page_id( 'myaccount' ) );
		    
		    // Prevent infinite loop if already on my account page and redirect URL is still my account
		    if ( is_account_page() && $redirect_url === $myaccount_url ) return;
		    
		    	wp_redirect( 
		    	    add_query_arg( 
		    	        apply_filters('b2bking_redirect_to_path', 'redirect_to'), 
		    	        urlencode( $_SERVER['REQUEST_URI'] ), 
		    	        $redirect_url
		    	    )
		    	); 
		    exit();
		}

	}	

	function b2bking_member_only_site() {
	    if ( !is_user_logged_in() && (get_current_user_id() === 0)) {
	    	if (apply_filters('b2bking_auth_redirect', true)){
	    		auth_redirect();
	    	}
	    }
	}

	function hide_invisible_pages_menu_2( $items, $menu, $args ) {

	 	foreach ($items as $index => $item){

	 		$page_id = get_post_meta( $item->ID, '_menu_item_object_id', true );

	 		$post_type = get_post_type($page_id);

	 		// remove invisible products / new 
	 		if (isset($item->object) && $item->object === 'product'){
		 		if ($post_type === 'product'){
		 			if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){

					    $currentuserid = get_current_user_id();
				    	$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
				    	if ($account_type === 'subaccount'){
				    		// for all intents and purposes set current user as the subaccount parent
				    		$parent_user_id = get_user_meta($currentuserid, 'b2bking_account_parent', true);
				    		$currentuserid = $parent_user_id;
				    	}

		    			if (!b2bking()->use_wpml_cache()){
							$allTheIDs = get_transient('b2bking_user_'.$currentuserid.'_ajax_visibility');
						} else {
							$allTheIDs = get_transient('b2bking_user_'.$currentuserid.'_ajax_visibility'.ICL_LANGUAGE_NAME_EN);
						}

						$allTheIDs = apply_filters('b2bking_ids_post_in_visibility', $allTheIDs);
						if (is_array($allTheIDs)){
							if (!in_array($page_id, $allTheIDs)){
								unset($items[$index]);
							}
						}

		 			}
				}
			}

			if (isset($item->object) && $item->object === 'page'){
				$access = true;
				if (is_user_logged_in()){
					if (b2bking()->is_b2b_user()){
						$group = b2bking()->get_user_group();

						// b2b
						$permission = get_post_meta($page_id, 'b2bking_group_'.$group, true);
						if ($permission === 0 || $permission === '0'){
							$access = false;
						}
					} else {
						// b2c
						$permission = get_post_meta($page_id, 'b2bking_group_b2c', true);
						if ($permission === 0 || $permission === '0'){
							$access = false;
						}
					}

				} else {
					// if user is explicity forbidden, then deny permission
					// logged out users
					$permission = get_post_meta($page_id, 'b2bking_group_0', true);
					if ($permission === 0 || $permission === '0'){
						$access = false;
					}
				}

				if (!$access){
					unset($items[$index]);
				}
			} else {
				continue;
			}

	 		
	 	}
		return $items;
	}

	// hide pages in menus
	function hide_invisible_pages_menu( $args ) {


		if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

			// build list of invisible pages

			$list = '';

			$pages = get_posts([
				'post_type' => 'page',
				'post_status' => 'publish',
				'numberposts' => -1,
				'fields'	 => 'ids'
			]);

			foreach ($pages as $page_id){
				if (is_user_logged_in()){
					if (b2bking()->is_b2b_user()){
						$group = b2bking()->get_user_group();

						// b2b
						$permission = get_post_meta($page_id, 'b2bking_group_'.$group, true);
						if ($permission === 0 || $permission === '0'){
							$list.=$page_id.',';
						}
					} else {
						// b2c
						$permission = get_post_meta($page_id, 'b2bking_group_b2c', true);
						if ($permission === 0 || $permission === '0'){
							$list.=$page_id.',';
						}
					}

				} else {
					// if user is explicity forbidden, then deny permission
					// logged out users
					$permission = get_post_meta($page_id, 'b2bking_group_0', true);
					if ($permission === 0 || $permission === '0'){
						$list.=$page_id.',';
					}
				}
			}

			if (!isset($args['exclude'])){
				$args['exclude'] = $list; // comma separated IDs
			} else {
				$args['exclude'] .= $list; // comma separated IDs
			}
		}
	

	  return $args;
	}

	function b2bking_invisible_page_redirection_to_account() {
		if ( is_preview() ){
			return;
		}

		if (defined('ELEMENTOR_VERSION')){

			if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
				return;
			}
			if ( \Elementor\Plugin::$instance->preview->is_preview_mode() ) {
				return;
			}
		}
		// start with pages here
		if (is_page() || is_shop() || is_home()){
			if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){
				$has_access = true;

				$page_id = get_the_ID();

				if (is_page($page_id) || is_shop() || is_home()){

					if (is_shop()){
						$page_id = wc_get_page_id('shop');
					}

					if (is_home()){ // blog page true for is_home()
						$page_id = b2bking()->safe_get_queried_object_id();
					}

					if (is_user_logged_in()){
						if (b2bking()->is_b2b_user()){
							$group = b2bking()->get_user_group();

							// b2b
							$permission = get_post_meta($page_id, 'b2bking_group_'.$group, true);
							if ($permission === 0 || $permission === '0'){
								$has_access = false;
							}
						} else {
							// b2c
							$permission = get_post_meta($page_id, 'b2bking_group_b2c', true);
							if ($permission === 0 || $permission === '0'){
								$has_access = false;
							}
						}

					} else {
						// if user is explicity forbidden, then deny permission
						// logged out users
						$permission = get_post_meta($page_id, 'b2bking_group_0', true);

						if ($permission === 0 || $permission === '0'){
							$has_access = false;
						}
					}
				}

				if ( ! $has_access ){

					// if current user is SK agent AND page to be accessed is agent dashboard page, auto-enabe
					if (apply_filters('b2bking_agent_can_always_view_dashboard_page', true)){
						if ( is_user_logged_in() ) {
						    // check if user is sales agent
						    $is_sales_agent = get_user_meta(get_current_user_id(),'salesking_group', true);
						    if ($is_sales_agent === 'none' || empty($is_sales_agent)){
							    // not agent
						    } else {
						        // User is logged in, and a sales agent -> Show dashboard
						    	// check if current page is agent dashboard page
						    	global $post;
						    	if (isset($post->ID)){
						    		if ( intval($post->ID) === intval(apply_filters( 'wpml_object_id', get_option( 'salesking_agents_page_setting', 'disabled' ), 'post' , true) ) ){
						    			$has_access = true;
						    		}
						    	}
						    }
						}
					}

				}

				
			    if ( ! $has_access ){

			    	// Get the redirect URL and check if it's still the my account page
			    	$redirect_url = apply_filters('b2bking_forbidden_access_redirection_url', get_permalink( wc_get_page_id( 'myaccount' ) ));
			    	$myaccount_url = get_permalink( wc_get_page_id( 'myaccount' ) );
			    	
			    	// Prevent infinite loop if already on my account page and redirect URL is still my account
			    	if ( ! ( is_account_page() && $redirect_url === $myaccount_url ) ){
					   wp_redirect( 
					       add_query_arg( 
					           apply_filters('b2bking_redirect_to_path', 'redirect_to'), 
					           urlencode( $_SERVER['REQUEST_URI'] ), 
					           $redirect_url
					       )
					   ); 
					   exit();
					}
			    } else {
			    	return;
			    }
			}
		}
	}

	function b2bking_login_redirect_to( $redirect ) {
	    if ( isset( $_GET[apply_filters('b2bking_redirect_to_path', 'redirect_to')] ) && ! empty( $_GET[apply_filters('b2bking_redirect_to_path', 'redirect_to')] ) ) {
	        $redirect_to = urldecode( $_GET[apply_filters('b2bking_redirect_to_path', 'redirect_to')] );
	        // Ensure the redirect URL is on the same domain for security
	        if ( wp_http_validate_url( home_url( $redirect_to ) ) ) {
	            return home_url( $redirect_to );
	        }
	    }
	    return $redirect;
	}

	// if user accesses product that he doesn't have access to, redirect to my account
	function b2bking_invisible_product_redirection_to_account() {

		if ( is_preview() ){
			return;
		}

		// for products here
	    if ( ! is_product() ){
	    	return; // Only for single product pages.
	    }
	    
		$has_access = true;
		if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){

			if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

				$user_is_b2b = get_user_meta( get_current_user_id(), 'b2bking_b2buser', true );

				// if user logged in and is b2b
				if (is_user_logged_in() && ($user_is_b2b === 'yes')){
					// Get current user's data: group, id, login, etc
				    $currentuserid = get_current_user_id();
			    	$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
			    	if ($account_type === 'subaccount'){
			    		// for all intents and purposes set current user as the subaccount parent
			    		$parent_user_id = get_user_meta($currentuserid, 'b2bking_account_parent', true);
			    		$currentuserid = $parent_user_id;
			    	}
			        $currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = b2bking()->get_user_group($currentuserid);
				// if user is b2c
				} else if (is_user_logged_in() && ($user_is_b2b !== 'yes')){
					$currentuserid = get_current_user_id();
			    	$currentuserid = b2bking()->get_top_parent_account($currentuserid);
			        $currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = 'b2c';
				} else {
					$currentuserlogin = 0;
					$currentusergroupidnr = 0;
				}
				
				/*
				* 
				*	There are 2 separate queries that need to be made:
				* 	1. Query of all Categories visible to the USER AND all Categories visible to the USER'S GROUP 
				*	2. Query of all Products set to Manual visibility mode, visible to the user or the user's group 
				*
				*/

				// Build Visible Categories for the 1st Query
				$visiblecategories = array();
				$hiddencategories = array();

				// Get all categories
				$terms = get_terms( array( 
				    'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
				    'fields' => 'ids',
				    'hide_empty' => false
				) );
				foreach ($terms as $term){

					/* 
					* If category is visible to GROUP OR category is visible to USER
					* Push category into visible categories array
					*/

					// first check group
					$group_meta = get_term_meta( $term, 'b2bking_group_'.$currentusergroupidnr, true );
					if (intval($group_meta) === 1){
						array_push($visiblecategories, $term);
					// else check user
					} else {
						$userlistcommas = get_term_meta( $term, 'b2bking_category_users_textarea', true );
						$userarray = explode(',', $userlistcommas);
						$visible = 'no';
						foreach ($userarray as $user){
							if (trim($user) === $currentuserlogin){
								array_push($visiblecategories, $term);
								$visible = 'yes';
								break;
							}
						}
						if ($visible === 'no'){
							array_push($hiddencategories, $term);
						}
					}
				}

				$product_category_visibility_array = array(
				           'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
				           'field' => 'term_id',
				           'terms' => $visiblecategories, 
				           'operator' => 'IN',
		          		   'include_children' => (!apply_filters('b2bking_category_visibility_direct_categories_only', false))
				);

				// if user has enabled "hidden has priority", override setting
				if (intval(get_option( 'b2bking_hidden_has_priority_setting', 0 )) === 1){
					$product_category_visibility_array = array(
					           'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
					           'field' => 'term_id',
					           'terms' => $hiddencategories, 
					           'operator' => 'NOT IN',
		          			   'include_children' => (!apply_filters('b2bking_category_visibility_direct_categories_only', false))
					);
				}

				/* Get all items that do not have manual visibility set up */
				// get all products ids
				if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){
					if (!b2bking()->use_wpml_cache()){
						$items_not_manual_visibility_array = get_transient('b2bking_not_manual_visibility_array');
					} else {
						$items_not_manual_visibility_array = get_transient('b2bking_not_manual_visibility_array'.ICL_LANGUAGE_NAME_EN);
					}
				} else {
					$items_not_manual_visibility_array = false;
				}
				
				if (!$items_not_manual_visibility_array){
					$all_prods = new WP_Query(array(
				        'posts_per_page' => -1,
				        'post_type' => 'product',
				        'fields' => 'ids'));
					$all_prod_ids = !empty($all_prods->posts) && is_object($all_prods->posts[0]) ? wp_list_pluck($all_prods->posts, 'ID') : $all_prods->posts; // Extract IDs if objects returned

					// get all products with manual visibility ids
					$all_prods_manual = new WP_Query(array(
				        'posts_per_page' => -1,
				        'post_type' => 'product',
				        'fields' => 'ids',
	    		        'meta_query'=> array(
	                            'relation' => 'AND',
	                            array(
	                                'key' => 'b2bking_product_visibility_override',
	                                'value' => 'manual',
	                            )
	                        )));
					$all_prod_manual_ids = !empty($all_prods_manual->posts) && is_object($all_prods_manual->posts[0]) ? wp_list_pluck($all_prods_manual->posts, 'ID') : $all_prods_manual->posts; // Extract IDs if objects returned
					// get the difference
					$items_not_manual_visibility_array = array_diff($all_prod_ids,$all_prod_manual_ids);
					set_transient('b2bking_not_manual_visibility_array', $items_not_manual_visibility_array, 30 * DAY_IN_SECONDS);
				}

				if (empty($items_not_manual_visibility_array)){
					$items_not_manual_visibility_array = array('invalid');
				}

				// Build first query
			    $queryAparams = array(
			        'posts_per_page' => -1,
			        'post_type' => 'product',
			        'fields' => 'ids',
			        'tax_query' => array(
			        	$product_category_visibility_array
			        ),
					'post__in' => $items_not_manual_visibility_array,
				);

			    // Build 2nd query: all manual visibility products with USER OR USER GROUP visibility
			    $queryBparams = array(
			        'posts_per_page' => -1,
			        'post_type' => 'product',
			        'fields' => 'ids',
			        'meta_query'=> array(
	                        'relation' => 'AND',
	                        array(
	                            'relation' => 'OR',
	                            array(
	                                'key' => 'b2bking_group_'.$currentusergroupidnr,
	                                'value' => '1'
	                            ),
	                            array(
	                                'key' => 'b2bking_user_'.$currentuserlogin,
	                                'value' => '1'
	                            )
	                        ),
	                        array(
	                            'key' => 'b2bking_product_visibility_override',
	                            'value' => 'manual',
	                        )
	                    ));


			    // if caching is enabled
			    if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){

			    	// WPML CACHE INTEGRATION
			    	if (!b2bking()->use_wpml_cache()){

				    	$allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility');
				    	$allTheIDs = b2bking()->check_visibility_cache_integrity($allTheIDs);

				    	// cache query results
				    	if (!$allTheIDs){
				    		$queryA = new WP_Query($queryAparams);
				    		$queryB = new WP_Query($queryBparams);
				    	 	// Merge the 2 queries in an IDs array
				    		$allTheIDs = array_merge($queryA->posts,$queryB->posts);
				    		b2bking()->update_visibility_integrity_log($allTheIDs);
				    		set_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility', $allTheIDs, YEAR_IN_SECONDS);
				    	}

				    } else {

				        // cache query results
				    	$allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility'.ICL_LANGUAGE_NAME_EN);
				    	$allTheIDs = b2bking()->check_visibility_cache_integrity($allTheIDs);
				    	// cache query results
				    	if (!$allTheIDs){
				    	    $queryA = new WP_Query($queryAparams);
				    	    $queryB = new WP_Query($queryBparams);
				    	    // Merge the 2 queries in an IDs array
				    	    $allTheIDs = array_merge($queryA->posts,$queryB->posts);
				    	    b2bking()->update_visibility_integrity_log($allTheIDs);
				    	    set_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility'.ICL_LANGUAGE_NAME_EN, $allTheIDs, YEAR_IN_SECONDS);
				    	}

				    }

			    } else {

		    	 	$queryA = new WP_Query($queryAparams);
			    	$queryB = new WP_Query($queryBparams);
			     	// Merge the 2 queries in an IDs array
			    	$allTheIDs = array_merge($queryA->posts,$queryB->posts);

			    }

			    if (in_array(get_the_ID(), $allTheIDs)){
			    	$has_access = true;
			    } else {
			    	$has_access = false;
			    }
			}
		}
		
	    if ( ! $has_access ){
	    	// Get the redirect URL and check if it's still the my account page
	    	$redirect_url = apply_filters('b2bking_forbidden_access_redirection_url', get_permalink( wc_get_page_id( 'myaccount' ) ));
	    	$myaccount_url = get_permalink( wc_get_page_id( 'myaccount' ) );
	    	
	    	// Prevent infinite loop if already on my account page and redirect URL is still my account
	    	if ( ! ( is_account_page() && $redirect_url === $myaccount_url ) ){
			   wp_redirect( 
			       add_query_arg( 
			           apply_filters('b2bking_redirect_to_path', 'redirect_to'), 
			           urlencode( $_SERVER['REQUEST_URI'] ), 
			           $redirect_url
			       )
			   ); 
			   exit();
			}

	    } else {
	    	return;
	    }
	}

	function b2bking_init_set_excluded_categories(){

		$currentuserid = get_current_user_id();
		$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			// for all intents and purposes set current user as the subaccount parent
			$parent_user_id = get_user_meta($currentuserid, 'b2bking_account_parent', true);
			$currentuserid = intval($parent_user_id);
		}

		if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){

			if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

				$user_is_b2b = get_user_meta( $currentuserid, 'b2bking_b2buser', true );

				// if user logged in and is b2b
				if (is_user_logged_in() && ($user_is_b2b === 'yes')){
					// Get current user's data: group, id, login, etc
			    	
			        $currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = b2bking()->get_user_group($currentuserid);
				// if user is b2c
				} else if (is_user_logged_in() && ($user_is_b2b !== 'yes')){
					$currentuserlogin = 'b2c';
					$currentusergroupidnr = 'b2c';
				} else {
					$currentuserlogin = 0;
					$currentusergroupidnr = 0;
				}

				// Build Visible Categories 
				$visiblecategories = array();
				$hiddencategories = array();

				$terms = get_terms( array( 
				    'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
				    'fields' => 'ids',
				    'hide_empty' => false
				) );

				foreach ($terms as $term){

					/* 
					* If category is visible to GROUP OR category is visible to USER
					* Push category into visible categories array
					*/

					// first check group
					$group_meta = get_term_meta( $term, 'b2bking_group_'.$currentusergroupidnr, true );
					if (intval($group_meta) === 1){
						array_push($visiblecategories, $term);
					// else check user
					} else {
						$userlistcommas = get_term_meta( $term, 'b2bking_category_users_textarea', true );
						$userarray = explode(',', $userlistcommas);
						$visible = 'no';
						foreach ($userarray as $user){
							if (trim($user) === $currentuserlogin){
								array_push($visiblecategories, $term);
								$visible = 'yes';
								break;
							}
						}
						if ($visible === 'no'){
							array_push($hiddencategories, $term);
						}
					}
				}
				if (!b2bking()->use_wpml_cache()){
					if (!get_transient('b2bking_user_exclude_categories_id_'.$currentuserid)){
						set_transient('b2bking_user_exclude_categories_id_'.$currentuserid, $hiddencategories, YEAR_IN_SECONDS);
					}
				} else {
					if (!get_transient('b2bking_user_exclude_categories_id_'.$currentuserid.ICL_LANGUAGE_NAME_EN)){
						set_transient('b2bking_user_exclude_categories_id_'.$currentuserid.ICL_LANGUAGE_NAME_EN, $hiddencategories, YEAR_IN_SECONDS);
					}
				}
			} else{
				if (!b2bking()->use_wpml_cache()){
					delete_transient('b2bking_user_exclude_categories_id_'.$currentuserid);
				} else {
					delete_transient('b2bking_user_exclude_categories_id_'.$currentuserid.ICL_LANGUAGE_NAME_EN);
				}
			}
		} else {
			if (!b2bking()->use_wpml_cache()){
				delete_transient('b2bking_user_exclude_categories_id_'.$currentuserid);
			} else {
				delete_transient('b2bking_user_exclude_categories_id_'.$currentuserid.ICL_LANGUAGE_NAME_EN);
			}
		}
	}

	function b2bking_categories_restrict( $args, $taxonomies ) {

		if (apply_filters('b2bking_categories_restrict_filter_abort', false)){
	        return $args;
	    }

		$user_id = get_current_user_id();
		$account_type = get_user_meta($user_id,'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			// for all intents and purposes set current user as the subaccount parent
			$parent_user_id = get_user_meta($user_id, 'b2bking_account_parent', true);
			$user_id = intval($parent_user_id);
		}

		
		if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){

			if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

				if (isset($taxonomies[0])){
					if ( is_admin() && 'category' !== $taxonomies[0] ){
					    return $args;
					}
				}

				if (apply_filters('b2bking_completely_category_restrict', true)){
					if (!b2bking()->use_wpml_cache()){
						if (get_transient('b2bking_user_exclude_categories_id_'.$user_id)){
							$args['exclude'] = get_transient('b2bking_user_exclude_categories_id_'.$user_id); // Array of cat ids to exclude
						}
					} else {
						if (get_transient('b2bking_user_exclude_categories_id_'.$user_id.ICL_LANGUAGE_NAME_EN)){
							$args['exclude'] = get_transient('b2bking_user_exclude_categories_id_'.$user_id.ICL_LANGUAGE_NAME_EN); // Array of cat ids to exclude
						}
					}
				}
				
				return $args;
			}
		}
		return $args;
	}
	public static function b2bking_show_both_prices($price, $product){

		$product_id = $product->get_id();

		if (apply_filters('b2bking_show_both_prices_user', true, get_current_user_id()) && apply_filters('b2bking_show_both_prices_product', true, $product_id)){
			if (!get_transient('b2bking_display_price_both'.$product_id.'_'.get_current_user_id()) || apply_filters('b2bking_display_both_cache_disable', true)){

				$retail_text = get_option('b2bking_retail_price_text_setting', esc_html__('Retail price','b2bking')).': ';
				$retail_text = apply_filters('b2bking_retail_price_text', $retail_text);
				$wholesale_text = get_option('b2bking_wholesale_price_text_setting', esc_html__('Wholesale price','b2bking')).': ';
				$wholesale_text = apply_filters('b2bking_wholesale_price_text', $wholesale_text);

				// define icons
				$icons = b2bking()->get_icons();
				foreach ($icons as $icon_name => $svg){
					if (!empty($svg)){
						// replace icons
						$wholesale_text = str_replace('['.$icon_name.']', $svg, $wholesale_text);
						$retail_text = str_replace('['.$icon_name.']', $svg, $retail_text);
					}
				}

				$is_b2b_user = get_user_meta(get_current_user_id(),'b2bking_b2buser', true);
				if ($is_b2b_user === 'yes'){
					
					$wholesale_price = $price;
					
					// variable product
					if( $product->is_type('variable') ){
						$children = $product->get_children();
						$min_price = 0;
						$max_price = 0;
						foreach ($children as $variation_id){
							// get retail price
							$variation = wc_get_product($variation_id);
							$variation_price = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($variation_id,'_regular_price', true)));
							$variation_price_temp = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($variation_id,'_sale_price', true)));

							if (empty(get_post_meta($variation_id,'_regular_price', true)) && empty(get_post_meta($variation_id,'_sale_price', true))){
								continue; // variation has no retail price set, skip pricing
							}

							if (!empty($variation_price_temp) && apply_filters('b2bking_use_retail_sale_price', true)){
								// there is indeed a sale price
								$variation_price = $variation_price_temp;
							}

							if ($max_price === 0){
								$min_price = $max_price = $variation_price;
							} else {
								if ($variation_price < $min_price){
									$min_price = $variation_price;
								}
								if ($variation_price > $max_price){
									$max_price = $variation_price;
								}
							}
						}

						// apply tax
						if (apply_filters('b2bking_both_prices_retail_adjust_tax', false)){ // recent change, previously true
							$min_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $min_price ) );
							$max_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $max_price ) );
						}


						if (apply_filters('b2bking_both_prices_retail_force_add_tax', false)){
							$min_price = wc_get_price_including_tax($product,array('qty'   => 1,'price' => $min_price));
							$max_price = wc_get_price_including_tax($product,array('qty'   => 1,'price' => $max_price));
						}

						// if min and max prices are different, show range, else show the price
						if ($min_price !== $max_price){
							$retail_price = b2bking()->format_price_range( $min_price, $max_price );
						} else {
							$retail_price = wc_price($min_price);
							if ($min_price === 0){
								$retail_price = ''; // do not show
							}
						}

					} else {
						
						// Simple product
						// get retail price
						$retail_price = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($product_id,'_regular_price', true)));

						$retail_sale_price = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($product_id,'_sale_price', true)));

						if (!empty($retail_price) && floatval($retail_price) !== 0){
							if (!empty($retail_sale_price) && apply_filters('b2bking_use_retail_sale_price', true)){
								// if there is a sale price
								if (apply_filters('b2bking_both_prices_retail_adjust_tax', false)){// recent change, previously true

									$retail_price = wc_format_sale_price(b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $retail_price ) ), b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $retail_sale_price ) ));

								} else {
									if (apply_filters('b2bking_both_prices_retail_force_add_tax', false)){
										$retail_price = wc_get_price_including_tax($product,array('qty' => 1,'price' => $retail_price));
										$retail_sale_price = wc_get_price_including_tax($product,array('qty'=> 1,'price' => $retail_sale_price));
									}

									$retail_price = wc_format_sale_price($retail_price, $retail_sale_price );

								}
							} else {
								if (apply_filters('b2bking_both_prices_retail_adjust_tax', false)){// recent change, previously true
									$retail_price = wc_price(b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $retail_price )));

								} else {

									if (apply_filters('b2bking_both_prices_retail_force_add_tax', false)){
										$retail_price = wc_get_price_including_tax($product,array('qty'=> 1,'price' => $retail_price));
									}

									$retail_price = wc_price($retail_price);
								}
							}
						}
					
					}

					$abort_terms = array('/ month', '/ year');
					$abort = 'no';
					foreach ($abort_terms as $term){
						if (strpos($wholesale_price, $term) !== false) {
							$abort = 'yes';
						}
						if (strpos($retail_price, $term) !== false) {
							$abort = 'yes';
						}
					}

					$show_retail_suffix = false;
					if (intval(get_option( 'b2bking_modify_suffix_vat_setting', 0 )) === 1){
						if (apply_filters('b2bking_modify_suffix', true, get_current_user_id())){
							$show_retail_suffix = true;
						}
					}

					$exvat = get_option('b2bking_ex_vat_text_setting', esc_html__('ex. VAT','b2bking'));
					$incvat = get_option('b2bking_inc_vat_text_setting', esc_html__('inc. VAT','b2bking'));


					$retail_price_without_suffix = $retail_price;

					$retail_price_with_suffix_1 = $retail_price.'<small class="woocommerce-price-suffix"> '.esc_html($exvat).'</small>';
					$retail_price_with_suffix_2 = $retail_price.'<small class="woocommerce-price-suffix"> '.esc_html($incvat).'</small>';

					$retail_price_with_suffix_1_striptags = trim(strip_tags($retail_price_with_suffix_1));
					$retail_price_with_suffix_2_striptags = trim(strip_tags($retail_price_with_suffix_2));

					if (apply_filters('b2bking_show_both_retail_price_show_suffix', $show_retail_suffix)){
						if (apply_filters('b2bking_both_prices_retail_adjust_tax', false)){
							if (!empty($retail_price)){
								$retail_price .= '<small class="woocommerce-price-suffix"> '.esc_html($exvat).'</small>';
							}
						} else {
							if (!empty($retail_price)){
								$retail_price .= '<small class="woocommerce-price-suffix"> '.esc_html($incvat).'</small>';
							}
						}
					}

					if (
						($wholesale_price !== $retail_price_without_suffix && 
						$wholesale_price !== $retail_price_with_suffix_2 && 
						$wholesale_price !== $retail_price_with_suffix_1 && 
						trim(strip_tags($wholesale_price)) !== $retail_price_with_suffix_1_striptags && 
						trim(strip_tags($wholesale_price)) !== $retail_price_with_suffix_2_striptags && 
						$wholesale_price !== $retail_price && 
						$retail_price !== 0 && 
						$retail_price !== floatval(0) && 
						$retail_price_without_suffix !== 0 && 
						$retail_price !== wc_price(0) && 
						$retail_price_without_suffix !== wc_price(0) &&
						$retail_price !== ''  &&
						$retail_price_without_suffix !== '' &&
						$wholesale_price !== '' &&
						$abort === 'no' &&
						!b2bking()->price_difference_may_be_rounding_error($wholesale_price, $retail_price)
						)|| (apply_filters('b2bking_always_show_both_prices', false))){
						if ( ! b2bking()->price_is_already_formatted($wholesale_price)){
							$wholesale_price = wc_price($wholesale_price);
						}

						$wholesale_price = apply_filters('b2bking_filter_wholesale_price', $wholesale_price, $product_id);
						$price = '<span class="b2bking_both_prices_text b2bking_retail_price_text">'.$retail_text .'</span><span class="b2bking_both_prices_price b2bking_retail_price_price">'. $retail_price . '<br></span><span class="b2bking_both_prices_text b2bking_b2b_price_text">'.$wholesale_text.'</span><span class="b2bking_both_prices_price b2bking_b2b_price_price b2bking_b2b_price_id_'.esc_attr($product_id).'">'.$wholesale_price.'</span>';

						$price = apply_filters('b2bking_filter_wholesale_price_final', $price, $retail_text, $retail_price, $wholesale_text, $wholesale_price, $product_id);

					}
							
				} else {
					if (apply_filters('b2bking_show_both_prices_all', false)){
						$retail_price = $price;

						// get random group
						$group_id = apply_filters('b2bking_show_both_prices_all_group_id', get_posts( array( 'post_type' => 'b2bking_group','post_status'=>'publish','numberposts' => -1,'fields' => 'ids') )[0] );

						// variable product
						if( $product->is_type('variable') ){
							$children = $product->get_children();
							$min_price = 0;
							$max_price = 0;
							foreach ($children as $variation_id){
								// get retail price
								$variation = wc_get_product($variation_id);
								$variation_price = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($variation_id,'_regular_price', true)));
								$variation_price_temp = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($variation_id,'_sale_price', true)));

								$variation_price_group = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($variation_id,'b2bking_regular_product_price_group_'.$group_id, true)));
								$wholesale_sale_price_group = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($variation_id,'b2bking_sale_product_price_group_'.$group_id, true)));
								if (!empty($wholesale_price_group)){ $variation_price = $wholesale_price_group; }
								if (!empty($wholesale_sale_price_group)){ $variation_price_temp = $wholesale_sale_price_group; }

								if (!empty($variation_price_temp) && apply_filters('b2bking_use_wholesale_sale_price', true)){
									// there is indeed a sale price
									$variation_price = $variation_price_temp;
								}

								if ($max_price === 0){
									$min_price = $max_price = $variation_price;
								} else {
									if ($variation_price < $min_price){
										$min_price = $variation_price;
									}
									if ($variation_price > $max_price){
										$max_price = $variation_price;
									}
								}
							}

							// apply tax
							if (apply_filters('b2bking_both_prices_wholesale_adjust_tax', false)){ // recent change, previously true
								$min_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $min_price ) );
								$max_price = b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $max_price ) );
							}

							if (apply_filters('b2bking_both_prices_wholesale_force_add_tax', false)){
								$min_price = wc_get_price_including_tax($product,array('qty'   => 1,'price' => $min_price));
								$max_price = wc_get_price_including_tax($product,array('qty'   => 1,'price' => $max_price));
							}

							// if min and max prices are different, show range, else show the price
							if ($min_price !== $max_price){
								$wholesale_price = b2bking()->format_price_range( $min_price, $max_price );
							} else {
								$wholesale_price = wc_price($min_price);
								if ($min_price === 0){
									$wholesale_price = ''; // do not show
								}
							}

						} else {
							
							// Simple product
							// get retail price
							$wholesale_price = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($product_id,'_regular_price', true)));
							$wholesale_sale_price = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($product_id,'_sale_price', true)));
							$wholesale_price_group = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($product_id,'b2bking_regular_product_price_group_'.$group_id, true)));
							$wholesale_sale_price_group = b2bking()->get_woocs_price(b2bking()->tofloat(get_post_meta($product_id,'b2bking_sale_product_price_group_'.$group_id, true)));
							if (!empty($wholesale_price_group)){ $wholesale_price = $wholesale_price_group; }
							if (!empty($wholesale_sale_price_group)){ $wholesale_sale_price = $wholesale_sale_price_group; }


							if (!empty($wholesale_price) && floatval($wholesale_price) !== 0){
								if (!empty($wholesale_sale_price) && apply_filters('b2bking_use_wholesale_sale_price', true)){
									// if there is a sale price
									if (apply_filters('b2bking_both_prices_wholesale_adjust_tax', false)){// recent change, previously true

										$wholesale_price = wc_format_sale_price(b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $wholesale_price ) ), b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $wholesale_sale_price ) ));

									} else {
										if (apply_filters('b2bking_both_prices_wholesale_force_add_tax', false)){
											$wholesale_price = wc_get_price_including_tax($product,array('qty' => 1,'price' => $wholesale_price));
											$wholesale_sale_price = wc_get_price_including_tax($product,array('qty'=> 1,'price' => $wholesale_sale_price));
										}

										$wholesale_price = wc_format_sale_price($wholesale_price, $wholesale_sale_price );

									}
								} else {
									if (apply_filters('b2bking_both_prices_wholesale_adjust_tax', false)){// recent change, previously true
										$wholesale_price = wc_price(b2bking()->b2bking_wc_get_price_to_display( $product, array( 'price' => $wholesale_price )));

									} else {

										if (apply_filters('b2bking_both_prices_wholesale_force_add_tax', false)){
											$wholesale_price = wc_get_price_including_tax($product,array('qty'=> 1,'price' => $wholesale_price));
										}

										$wholesale_price = wc_price($wholesale_price);
									}
								}
							}
						
						}

						$abort_terms = array('/ month', '/ year');
						$abort = 'no';
						foreach ($abort_terms as $term){
							if (strpos($wholesale_price, $term) !== false) {
								$abort = 'yes';
							}
							if (strpos($retail_price, $term) !== false) {
								$abort = 'yes';
							}
						}

						$show_wholesale_suffix = false;
						if (intval(get_option( 'b2bking_modify_suffix_vat_setting', 0 )) === 1){
							if (apply_filters('b2bking_modify_suffix', true, get_current_user_id())){
								$show_wholesale_suffix = true;
							}
						}

						$wholesale_price_without_suffix = $wholesale_price;

						if (apply_filters('b2bking_show_both_wholesale_price_show_suffix', $show_wholesale_suffix)){
							if (apply_filters('b2bking_both_prices_wholesale_adjust_tax', false)){
								$exvat = get_option('b2bking_ex_vat_text_setting', esc_html__('ex. VAT','b2bking'));
								if (!empty($wholesale_price)){
									$wholesale_price .= '<small class="woocommerce-price-suffix"> '.esc_html($exvat).'</small>';
								}
							} else {
								$incvat = get_option('b2bking_inc_vat_text_setting', esc_html__('inc. VAT','b2bking'));
								if (!empty($wholesale_price)){
									$wholesale_price .= '<small class="woocommerce-price-suffix"> '.esc_html($incvat).'</small>';
								}
							}
						}

						if (($retail_price !== $wholesale_price_without_suffix && $wholesale_price !== $retail_price && $retail_price !== 0 && $wholesale_price_without_suffix !== 0 && $retail_price !== wc_price(0) && $retail_price !== floatval(0) && $wholesale_price_without_suffix !== wc_price(0) && $retail_price !== ''  && $wholesale_price_without_suffix !== '' && $wholesale_price !== '' && $abort === 'no' && !b2bking()->price_difference_may_be_rounding_error($wholesale_price, $retail_price)) || (apply_filters('b2bking_always_show_both_prices', false))){
							if ( ! b2bking()->price_is_already_formatted($wholesale_price)){
								$wholesale_price = wc_price($wholesale_price);
							}

							$wholesale_price = apply_filters('b2bking_filter_wholesale_price', $wholesale_price, $product_id);
							$price = '<span class="b2bking_both_prices_text b2bking_retail_price_text">'.$retail_text .'</span><span class="b2bking_both_prices_price b2bking_retail_price_price">'. $retail_price . '<br></span><span class="b2bking_both_prices_text b2bking_b2b_price_text">'.$wholesale_text.'</span><span class="b2bking_both_prices_price b2bking_b2b_price_price b2bking_b2b_price_id_'.esc_attr($product_id).'">'.$wholesale_price.'</span>';

							$price = apply_filters('b2bking_filter_wholesale_price_final', $price, $retail_text, $retail_price, $wholesale_text, $wholesale_price, $product_id);

							

						}

					}
				}
				set_transient('b2bking_display_price_both'.$product_id.'_'.get_current_user_id(), $price);
			} else {
				$price = get_transient('b2bking_display_price_both'.$product_id.'_'.get_current_user_id());
			}
		}

		return $price;
	}


	function b2bking_show_moq_externally(){
			global $post;
			$user_id = get_current_user_id();
			$product_id = $post->ID;

			//$dynamic_minmax_rules = get_transient('b2bking_minmax_'.get_current_user_id());
			$dynamic_minmax_rules = b2bking()->get_global_data('b2bking_minmax',false,get_current_user_id());

			if (!$dynamic_minmax_rules){

				$user_id = b2bking()->get_top_parent_account($user_id);

				$currentusergroupidnr = b2bking()->get_user_group($user_id);
				if (!$currentusergroupidnr || empty($currentusergroupidnr)){
					$currentusergroupidnr = 'invalid';
				}

				$rules_ids_elements = get_option('b2bking_have_minmax_rules_list_ids_elements', array());

				$user_rules = array();
				if (isset($rules_ids_elements['user_'.$user_id])){
					$user_rules = $rules_ids_elements['user_'.$user_id];
				}

				$group_rules = array();
				if (isset($rules_ids_elements['group_'.$currentusergroupidnr])){
					$group_rules = $rules_ids_elements['group_'.$currentusergroupidnr];
				}

				$user_applicable_rules = array_merge($user_rules, $group_rules);
				if (is_user_logged_in()){

					if (isset($rules_ids_elements['all_registered'])){
						// add everyone_registered rules
						$user_applicable_rules = array_merge($user_applicable_rules, $rules_ids_elements['all_registered']);
					}

					// if is user b2b add b2b rules
					if (get_user_meta($user_id,'b2bking_b2buser', true) === 'yes'){
						if (isset($rules_ids_elements['everyone_registered_b2b'])){
							$user_applicable_rules = array_merge($user_applicable_rules, $rules_ids_elements['everyone_registered_b2b']);
						}
					} else {
						// add b2c rules
						if (isset($rules_ids_elements['everyone_registered_b2c'])){
							$user_applicable_rules = array_merge($user_applicable_rules, $rules_ids_elements['everyone_registered_b2c']);
						}
					}
				}

				b2bking()->set_global_data('b2bking_minmax', $user_applicable_rules, false, get_current_user_id());
				$dynamic_minmax_rules = b2bking()->get_global_data('b2bking_minmax',false,get_current_user_id());

			}

			$smallest_minimum = 'none';
			$largest_maximum = 'none';

			foreach($dynamic_minmax_rules as $dynamic_minmax_rule){
				// get rule details
				$minimum_maximum = get_post_meta($dynamic_minmax_rule, 'b2bking_rule_what', true);
				$quantity_value = get_post_meta($dynamic_minmax_rule, 'b2bking_rule_quantity_value', true);
				$howmuch = floatval(get_post_meta($dynamic_minmax_rule, 'b2bking_rule_howmuch', true));
				$applies = get_post_meta($dynamic_minmax_rule, 'b2bking_rule_applies', true);
				if ($applies === 'cart_total'){


				} else {
					// rule is category or product rule or multiple select rule
					$applies = explode('_',$applies);
					if ($applies[0] === 'category'){

						
					}  else if ($applies[0] === 'product'){
						// rule is product rule
						if(intval($applies[1]) === intval($product_id)){
							if ($quantity_value === 'quantity'){
								if ($minimum_maximum === 'minimum_order'){
									if ($smallest_minimum === 'none'){
										$smallest_minimum = $howmuch;
									} else if ($smallest_minimum > $howmuch) {
										$smallest_minimum = $howmuch;
									}
								} else if ($minimum_maximum === 'maximum_order'){
									if ($largest_maximum === 'none'){
										$largest_maximum = $howmuch;
									} else if ($largest_maximum < $howmuch) {
										$largest_maximum = $howmuch;
									}
								}
							}
						}

					// multiple select rule
					} else if ($applies[0] === 'multiple'){
						$rule_multiple_options = get_post_meta($dynamic_minmax_rule, 'b2bking_rule_applies_multiple_options', true);
						$rule_multiple_options_array = explode(',',$rule_multiple_options);
						// foreach element, category or product
						foreach($rule_multiple_options_array as $rule_element){
							$rule_element_array = explode('_',$rule_element);
							// if is category
							if ($rule_element_array[0] === 'category'){



							// if is product
							} else if ($rule_element_array[0] === 'product'){

								if(intval($rule_element_array[1]) === $product_id){
									if ($quantity_value === 'quantity'){
										if ($minimum_maximum === 'minimum_order'){
											if ($smallest_minimum === 'none'){
												$smallest_minimum = $howmuch;
											} else if ($smallest_minimum > $howmuch) {
												$smallest_minimum = $howmuch;
											}
										} else if ($minimum_maximum === 'maximum_order'){
											if ($largest_maximum === 'none'){
												$largest_maximum = $howmuch;
											} else if ($largest_maximum < $howmuch) {
												$largest_maximum = $howmuch;
											}
										}
									}
								}
							} 
						}
					}
				}
			}

			$meta_min = b2bking()->get_product_meta_min($product_id);

			if ($meta_min !== false){
				if (is_numeric($smallest_minimum)){
					$smallest_minimum = min($smallest_minimum, $meta_min);
				} else {
					$smallest_minimum = $meta_min;
				}
			}

			if ($smallest_minimum !== 'none'){

				$text = '<span class="b2bking_moq_text">'.esc_html__('Minimum Order Quantity: ', 'b2bking').$smallest_minimum.'</span>';
				$text = apply_filters('b2bking_external_moq_text', $text, $smallest_minimum );
				echo $text;

			}
			
		}

	// Filter category count
	function b2bking_category_count_filter( $terms, $taxonomy ) {
		// if caching is enabled
		if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){

			if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){

				if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

					if (get_option('woocommerce_shop_page_display') === 'subcategories' || get_option('woocommerce_category_archive_display') === 'subcategories'){

					    $currentuserid = get_current_user_id();
				    	$currentuserid = b2bking()->get_top_parent_account($currentuserid);

						// WPML INTEGRATION

						if (!b2bking()->use_wpml_cache()){

						    // cache query results
							if (get_transient('b2bking_user_'.$currentuserid.'_ajax_visibility')){
						   		$allTheIDs = get_transient('b2bking_user_'.$currentuserid.'_ajax_visibility');
						   	
							   	if ( in_array( 'product_cat', $taxonomy ) ) {
							   	    foreach ( $terms as $i => $term ) {
							   	        if ( is_a( $term, 'WP_Term' ) ) {
							   	        	// calculate how many IDs there are in this category
						   	        		$products_in_category = new WP_Query(array(
						   	        	        'posts_per_page' => -1,
						   	        	        'fields' => 'ids',
						   	        	        'post_type' => 'product',
						   	        	        'tax_query' => array(
					   	        	                array(
					   	        	                    'taxonomy'  => 'product_cat',
					   	        	                    'field'     => 'id', 
					   	        	                    'terms'     => $term->term_id,
					   	        	                )
					   	        	            ),
						   	        	        'post__in' => $allTheIDs,
						   	        	    ));

						   	        		$number = count($products_in_category->posts);
							   	        	
							   	            $terms[$i]->count = $number;
							   	        }
							   	    }
							   	}
						   	}
						} else {
							// cache query results
							if (get_transient('b2bking_user_'.$currentuserid.'_ajax_visibility'.ICL_LANGUAGE_NAME_EN)){
						   		$allTheIDs = get_transient('b2bking_user_'.$currentuserid.'_ajax_visibility'.ICL_LANGUAGE_NAME_EN);
						   	
							   	if ( in_array( 'product_cat', $taxonomy ) ) {
							   	    foreach ( $terms as $i => $term ) {
							   	        if ( is_a( $term, 'WP_Term' ) ) {
							   	        	// calculate how many IDs there are in this category
						   	        		$products_in_category = new WP_Query(array(
						   	        	        'posts_per_page' => -1,
						   	        	        'fields' => 'ids',
						   	        	        'post_type' => 'product',
						   	        	        'tax_query' => array(
					   	        	                array(
					   	        	                    'taxonomy'  => 'product_cat',
					   	        	                    'field'     => 'id', 
					   	        	                    'terms'     => $term->term_id,
					   	        	                )
					   	        	            ),
						   	        	        'post__in' => $allTheIDs,
						   	        	    ));

						   	        		$number = count($products_in_category->posts);
							   	        	
							   	            $terms[$i]->count = $number;
							   	        }
							   	    }
							   	}
						   	}
						}
					}
				}
			}
		}
	    
	    return $terms;
	}


	function b2bking_visibility_wordpress_posts($q ){

		if (is_null($q)){
			return;
		}

		// this helps get / set the current user, otherwise the user gets 0
		if (!b2bking()->is_rest_api_request()){
			$determined_user_id = apply_filters( 'determine_current_user', false );

			$current_user_id = get_current_user_id();
			if (empty($current_user_id) || $current_user_id == 0){
				wp_set_current_user( $determined_user_id );
			}
		}

		if ($q->is_search()) { 

			if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){

				if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

					if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){

						$currentuserid = get_current_user_id();
						
		    			$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
		    			if ($account_type === 'subaccount'){
		    				// for all intents and purposes set current user as the subaccount parent
		    				$parent_user_id = get_user_meta($currentuserid, 'b2bking_account_parent', true);
		    				$currentuserid = $parent_user_id;
		    			}

		    			if (!b2bking()->use_wpml_cache()){
							$allTheIDs = get_transient('b2bking_user_'.$currentuserid.'_ajax_visibility');
						} else {
							$allTheIDs = get_transient('b2bking_user_'.$currentuserid.'_ajax_visibility'.ICL_LANGUAGE_NAME_EN);
						}


						$allTheIDs = apply_filters('b2bking_ids_post_in_visibility', $allTheIDs);

						$currentval = $q->query_vars['post__in'];
						if (!empty($currentval) && $allTheIDs !== false){
							$allTheIDs = array_intersect($allTheIDs, $currentval);
						}
							
						if ($allTheIDs){
						    if(!empty($allTheIDs)){

						    	if (apply_filters('b2bking_enable_visibility_posts', true)){
			    			    	// set a negative value, of hidden products, so that other posts like articles can show

			    			    	$all_products_ids = get_transient('b2bking_all_products_ids');
			    			    	if ( ! $all_products_ids){
		    			    		    $all_products_ids_args = array(
		    			    		        'posts_per_page' => -1,
		    			    		        'post_type' => 'product',
		    			    		        'fields' => 'ids',
		    			    			);
		    			    			$all_products_ids = get_posts($all_products_ids_args);
		    			    			set_transient('b2bking_all_products_ids', $all_products_ids, 30 * DAY_IN_SECONDS);
			    			    	}
			    		    	    
			    		    	    $negative_allTheIDs = array_diff($all_products_ids, $allTheIDs);
			    			    	$q->set('post__not_in',$negative_allTheIDs);
						    	}
						    	
							}
						}

					}

				}
			}
		}


	}


	// If user is logged in, set up product/category/user/user group visibility rules
	function b2bking_product_categories_visibility_rules( $q ){

		if (is_null($q)){
			return;
		}

		if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){

			if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

				$user_is_b2b = get_user_meta( get_current_user_id(), 'b2bking_b2buser', true );

				// if user logged in and is b2b
				if (is_user_logged_in() && ($user_is_b2b === 'yes')){
					// Get current user's data: group, id, login, etc
				    $currentuserid = get_current_user_id();
			    	$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
			    	if ($account_type === 'subaccount'){
			    		// for all intents and purposes set current user as the subaccount parent
			    		$parent_user_id = get_user_meta($currentuserid, 'b2bking_account_parent', true);
			    		$currentuserid = $parent_user_id;
			    	}	    	

			        $currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = b2bking()->get_user_group($currentuserid);
				// if user is b2c
				} else if (is_user_logged_in() && ($user_is_b2b !== 'yes')){
				    $currentuserid = get_current_user_id();
			    	$currentuserid = b2bking()->get_top_parent_account($currentuserid);
			        $currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = 'b2c';
				} else {
					$currentuserlogin = 0;
					$currentusergroupidnr = 0;
				}

				// if salesking agent, get visibility of sales agent
    	    	if ($this->check_user_is_agent_with_access()){
    				$agent_id = $this->get_current_agent_id();
    				$currentuserid = $agent_id;
    				$currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = b2bking()->get_user_group($currentuserid);
    			}

				/*
				* 
				*	There are 2 separate queries that need to be made:
				* 	1. Query of all Categories visible to the USER AND all Categories visible to the USER'S GROUP 
				*	2. Query of all Products set to Manual visibility mode, visible to the user or the user's group 
				*
				*/

				// Build Visible Categories for the 1st Query
				$visiblecategories = array();
				$hiddencategories = array();

				$terms = get_terms( array( 
				    'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
				    'fields' => 'ids',
				    'hide_empty' => false
				) );

				foreach ($terms as $term){

					/* 
					* If category is visible to GROUP OR category is visible to USER
					* Push category into visible categories array
					*/

					// first check group
					$group_meta = get_term_meta( $term, 'b2bking_group_'.$currentusergroupidnr, true );
					if (intval($group_meta) === 1){
						array_push($visiblecategories, $term);
					// else check user
					} else {
						$userlistcommas = get_term_meta( $term, 'b2bking_category_users_textarea', true );
						$userarray = explode(',', $userlistcommas);
						$visible = 'no';
						foreach ($userarray as $user){
							if (trim($user) === $currentuserlogin){
								array_push($visiblecategories, $term);
								$visible = 'yes';
								break;
							}
						}
						if ($visible === 'no'){
							array_push($hiddencategories, $term);
						}
					}
				}


				$product_category_visibility_array = array(
				           'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
				           'field' => 'term_id',
				           'terms' => $visiblecategories, 
				           'operator' => 'IN',
		           		   'include_children' => (!apply_filters('b2bking_category_visibility_direct_categories_only', false))
				);

				// if user has enabled "hidden has priority", override setting
				if (intval(get_option( 'b2bking_hidden_has_priority_setting', 0 )) === 1){
					$product_category_visibility_array = array(
					           'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
					           'field' => 'term_id',
					           'terms' => $hiddencategories, 
					           'operator' => 'NOT IN',
		          			   'include_children' => (!apply_filters('b2bking_category_visibility_direct_categories_only', false))
					);
				}

				/* Get all items that do not have manual visibility set up */
				// get all products ids
				if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){
					if (!b2bking()->use_wpml_cache()){
						$items_not_manual_visibility_array = get_transient('b2bking_not_manual_visibility_array');
					} else {
						$items_not_manual_visibility_array = get_transient('b2bking_not_manual_visibility_array'.ICL_LANGUAGE_NAME_EN);
					}
				} else {
					$items_not_manual_visibility_array = false;
				}
				
				if (!$items_not_manual_visibility_array){
					$all_prods = new WP_Query(array(
				        'posts_per_page' => -1,
				        'post_type' => 'product',
				        'fields' => 'ids'));
					$all_prod_ids = !empty($all_prods->posts) && is_object($all_prods->posts[0]) ? wp_list_pluck($all_prods->posts, 'ID') : $all_prods->posts; // Extract IDs if objects returned

					// get all products with manual visibility ids
					$all_prods_manual = new WP_Query(array(
				        'posts_per_page' => -1,
				        'post_type' => 'product',
				        'fields' => 'ids',
	    		        'meta_query'=> array(
	                            'relation' => 'AND',
	                            array(
	                                'key' => 'b2bking_product_visibility_override',
	                                'value' => 'manual',
	                            )
	                        )));
					$all_prod_manual_ids = !empty($all_prods_manual->posts) && is_object($all_prods_manual->posts[0]) ? wp_list_pluck($all_prods_manual->posts, 'ID') : $all_prods_manual->posts; // Extract IDs if objects returned
					// get the difference
					$items_not_manual_visibility_array = array_diff($all_prod_ids,$all_prod_manual_ids);
					set_transient('b2bking_not_manual_visibility_array', $items_not_manual_visibility_array, 30 * DAY_IN_SECONDS);
				}

				if (empty($items_not_manual_visibility_array)){
					$items_not_manual_visibility_array = array('invalid');
				}
				

				// Build first query
			    $queryAparams = array(
			        'posts_per_page' => -1,
			        'post_type' => 'product',
			        'fields' => 'ids',
			        'tax_query' => array(
			        	$product_category_visibility_array
			        ),
				    'post__in' => $items_not_manual_visibility_array,
				);

			    // Build 2nd query: all manual visibility products with USER OR USER GROUP visibility
			    $queryBparams = array(
			        'posts_per_page' => -1,
			        'post_type' => 'product',
			        'fields' => 'ids',
			        'meta_query'=> array(
	                        'relation' => 'AND',
	                        array(
	                            'relation' => 'OR',
	                            array(
	                                'key' => 'b2bking_group_'.$currentusergroupidnr,
	                                'value' => '1'
	                            ),
	                            array(
	                                'key' => 'b2bking_user_'.$currentuserlogin,
	                                'value' => '1'
	                            )
	                        ),
	                        array(
	                            'key' => 'b2bking_product_visibility_override',
	                            'value' => 'manual',
	                        )
	                    ));


			    // if caching is enabled
			    if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){

			    	// WPML CACHE INTEGRATION
			    	if (!b2bking()->use_wpml_cache()){
			    	    // Get cache and check integrity
			    	    $allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility');
			    	    $allTheIDs = b2bking()->check_visibility_cache_integrity($allTheIDs);
			    	    // cache query results
			    	    if (!$allTheIDs){
			    	        $queryA = new WP_Query($queryAparams);
			    	        $queryB = new WP_Query($queryBparams);
			    	        // Merge the 2 queries in an IDs array
			    	        $allTheIDs = array_merge($queryA->posts,$queryB->posts);
			    	        b2bking()->update_visibility_integrity_log($allTheIDs);
			    	        set_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility', $allTheIDs, YEAR_IN_SECONDS);
			    	    }
			    	} else {
			    	    // Get cache and check integrity
			    	    $allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility'.ICL_LANGUAGE_NAME_EN);
			    	    $allTheIDs = b2bking()->check_visibility_cache_integrity($allTheIDs);
			    	    // cache query results
			    	    if (!$allTheIDs){
			    	        $queryA = new WP_Query($queryAparams);
			    	        $queryB = new WP_Query($queryBparams);
			    	        // Merge the 2 queries in an IDs array
			    	        $allTheIDs = array_merge($queryA->posts,$queryB->posts);
			    	        b2bking()->update_visibility_integrity_log($allTheIDs);
			    	        set_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility'.ICL_LANGUAGE_NAME_EN, $allTheIDs, YEAR_IN_SECONDS);
			    	    }
			    	}

				} else {
				 	$queryA = new WP_Query($queryAparams);
				 	$queryB = new WP_Query($queryBparams);
					 // Merge the 2 queries in an IDs array
					$allTheIDs = array_merge($queryA->posts,$queryB->posts);
				}

				$allTheIDs = apply_filters('b2bking_ids_post_in_visibility', $allTheIDs);
			

				if (is_array($q)){
				    if (!empty($allTheIDs)) {
					    if (isset($q['where'])) {
					        $q['where'] .= ' AND p.ID IN (' . implode(',', $allTheIDs) . ')';
					    } else {
					        $q['where'] = 'p.ID IN (' . implode(',', $allTheIDs) . ')';
					    }
					} else {
					    // If the array is empty, WooCommerce shows all products. To fix this, we pass an invalid IDs array in that case.
					    if (isset($q['where'])) {
					        $q['where'] .= ' AND p.ID IN (98989898321123)';
					    } else {
					        $q['where'] = 'p.ID IN (98989898321123)';
					    }
					}
					
					return $q;
				} else {
				    if(!empty($allTheIDs)){

				    	if (isset($q->query_vars)){
				    		if (isset($q->query_vars['post__in'])){
				    			$existing = $q->query_vars['post__in'];
				    			if (!empty($existing)){
				    				$intersection = array_intersect($existing, $allTheIDs);
				    				$allTheIDs = $intersection;

				    				if (empty($intersection)){
										$q->set('post__in',array('invalidid'));
									}
				    			}
				    		}
				    	}
				    	
				    	$q->set('post__in',$allTheIDs);
					} else {
						// If the array is empty, WooCommerce shows all products. To fix this, we pass an invalid IDs array in that case.
						$q->set('post__in',array('invalidid'));
					}	
				}
			    
			}
		}
	}

	function b2bking_product_categories_visibility_rules_productfilter($visible, $product_id){
		if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){

			if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

				$user_is_b2b = get_user_meta( get_current_user_id(), 'b2bking_b2buser', true );

				// if user logged in and is b2b
				if (is_user_logged_in() && ($user_is_b2b === 'yes')){
					// Get current user's data: group, id, login, etc
				    $currentuserid = get_current_user_id();
			    	$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
			    	if ($account_type === 'subaccount'){
			    		// for all intents and purposes set current user as the subaccount parent
			    		$parent_user_id = get_user_meta($currentuserid, 'b2bking_account_parent', true);
			    		$currentuserid = $parent_user_id;
			    	}

			        $currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = b2bking()->get_user_group($currentuserid);
				// if user is b2c
				} else if (is_user_logged_in() && ($user_is_b2b !== 'yes')){
				    $currentuserid = get_current_user_id();
			    	$currentuserid = b2bking()->get_top_parent_account($currentuserid);
			        $currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = 'b2c';
				} else {
					$currentuserlogin = 0;
					$currentusergroupidnr = 0;
				}

				// if salesking agent, get visibility of sales agent
    	    	if ($this->check_user_is_agent_with_access()){
    				$agent_id = $this->get_current_agent_id();
    				$currentuserid = $agent_id;
    				$currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = b2bking()->get_user_group($currentuserid);
    			}

				/*
				* 
				*	There are 2 separate queries that need to be made:
				* 	1. Query of all Categories visible to the USER AND all Categories visible to the USER'S GROUP 
				*	2. Query of all Products set to Manual visibility mode, visible to the user or the user's group 
				*
				*/

				// Build Visible Categories for the 1st Query
				$visiblecategories = array();
				$hiddencategories = array();

				$terms = get_terms( array( 
				    'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
				    'fields' => 'ids',
				    'hide_empty' => false
				) );

				foreach ($terms as $term){

					/* 
					* If category is visible to GROUP OR category is visible to USER
					* Push category into visible categories array
					*/

					// first check group
					$group_meta = get_term_meta( $term, 'b2bking_group_'.$currentusergroupidnr, true );
					if (intval($group_meta) === 1){
						array_push($visiblecategories, $term);
					// else check user
					} else {
						$userlistcommas = get_term_meta( $term, 'b2bking_category_users_textarea', true );
						$userarray = explode(',', $userlistcommas);
						$visible_local = 'no';
						foreach ($userarray as $user){
							if (trim($user) === $currentuserlogin){
								array_push($visiblecategories, $term);
								$visible_local = 'yes';
								break;
							}
						}
						if ($visible_local === 'no'){
							array_push($hiddencategories, $term);
						}
					}
				}


				$product_category_visibility_array = array(
				           'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
				           'field' => 'term_id',
				           'terms' => $visiblecategories, 
				           'operator' => 'IN',
		           		   'include_children' => (!apply_filters('b2bking_category_visibility_direct_categories_only', false))
				);

				// if user has enabled "hidden has priority", override setting
				if (intval(get_option( 'b2bking_hidden_has_priority_setting', 0 )) === 1){
					$product_category_visibility_array = array(
					           'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
					           'field' => 'term_id',
					           'terms' => $hiddencategories, 
					           'operator' => 'NOT IN',
		           			   'include_children' => (!apply_filters('b2bking_category_visibility_direct_categories_only', false))
					);
				}

				/* Get all items that do not have manual visibility set up */
				// get all products ids
				if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){
					if (!b2bking()->use_wpml_cache()){
						$items_not_manual_visibility_array = get_transient('b2bking_not_manual_visibility_array');
					} else {
						$items_not_manual_visibility_array = get_transient('b2bking_not_manual_visibility_array'.ICL_LANGUAGE_NAME_EN);
					}
				} else {
					$items_not_manual_visibility_array = false;
				}
				
				if (!$items_not_manual_visibility_array){
					$all_prods = new WP_Query(array(
				        'posts_per_page' => -1,
				        'post_type' => 'product',
				        'fields' => 'ids'));
					$all_prod_ids = !empty($all_prods->posts) && is_object($all_prods->posts[0]) ? wp_list_pluck($all_prods->posts, 'ID') : $all_prods->posts; // Extract IDs if objects returned

					// get all products with manual visibility ids
					$all_prods_manual = new WP_Query(array(
				        'posts_per_page' => -1,
				        'post_type' => 'product',
				        'fields' => 'ids',
	    		        'meta_query'=> array(
	                            'relation' => 'AND',
	                            array(
	                                'key' => 'b2bking_product_visibility_override',
	                                'value' => 'manual',
	                            )
	                        )));
					$all_prod_manual_ids = !empty($all_prods_manual->posts) && is_object($all_prods_manual->posts[0]) ? wp_list_pluck($all_prods_manual->posts, 'ID') : $all_prods_manual->posts; // Extract IDs if objects returned
					// get the difference
					$items_not_manual_visibility_array = array_diff($all_prod_ids,$all_prod_manual_ids);
					set_transient('b2bking_not_manual_visibility_array', $items_not_manual_visibility_array, 30 * DAY_IN_SECONDS);
				}

				if (empty($items_not_manual_visibility_array)){
					$items_not_manual_visibility_array = array('invalid');
				}

				// Build first query
			    $queryAparams = array(
			        'posts_per_page' => -1,
			        'post_type' => 'product',
			        'fields' => 'ids',
			        'tax_query' => array(
			        	$product_category_visibility_array
			        ),
				    'post__in' => $items_not_manual_visibility_array,
				);

			    // Build 2nd query: all manual visibility products with USER OR USER GROUP visibility
			    $queryBparams = array(
			        'posts_per_page' => -1,
			        'post_type' => 'product',
			        'fields' => 'ids',
			        'meta_query'=> array(
	                        'relation' => 'AND',
	                        array(
	                            'relation' => 'OR',
	                            array(
	                                'key' => 'b2bking_group_'.$currentusergroupidnr,
	                                'value' => '1'
	                            ),
	                            array(
	                                'key' => 'b2bking_user_'.$currentuserlogin,
	                                'value' => '1'
	                            )
	                        ),
	                        array(
	                            'key' => 'b2bking_product_visibility_override',
	                            'value' => 'manual',
	                        )
	                    ));


			    // if caching is enabled
			    if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){

			    	// WPML INTEGRATION for CACHE
			    	if (!b2bking()->use_wpml_cache()){
			    	    // Get cache and check integrity
			    	    $allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility');
			    	    $allTheIDs = b2bking()->check_visibility_cache_integrity($allTheIDs);
			    	    // cache query results
			    	    if (!$allTheIDs){
			    	        $queryA = new WP_Query($queryAparams);
			    	        $queryB = new WP_Query($queryBparams);
			    	        // Merge the 2 queries in an IDs array
			    	        $allTheIDs = array_merge($queryA->posts,$queryB->posts);
			    	        b2bking()->update_visibility_integrity_log($allTheIDs);
			    	        set_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility', $allTheIDs, YEAR_IN_SECONDS);
			    	    }
			    	} else {
			    	    // Get cache and check integrity
			    	    $allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility'.ICL_LANGUAGE_NAME_EN);
			    	    $allTheIDs = b2bking()->check_visibility_cache_integrity($allTheIDs);
			    	    // cache query results
			    	    if (!$allTheIDs){
			    	        $queryA = new WP_Query($queryAparams);
			    	        $queryB = new WP_Query($queryBparams);
			    	        // Merge the 2 queries in an IDs array
			    	        $allTheIDs = array_merge($queryA->posts,$queryB->posts);
			    	        b2bking()->update_visibility_integrity_log($allTheIDs);
			    	        set_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility'.ICL_LANGUAGE_NAME_EN, $allTheIDs, YEAR_IN_SECONDS);
			    	    }
			    	}

				} else {
				 	$queryA = new WP_Query($queryAparams);
				 	$queryB = new WP_Query($queryBparams);
					 // Merge the 2 queries in an IDs array
					$allTheIDs = array_merge($queryA->posts,$queryB->posts);
				}

				$allTheIDs = apply_filters('b2bking_ids_post_in_visibility', $allTheIDs);


			    if(!empty($allTheIDs)){
			    	$post_parent_id = wp_get_post_parent_id($product_id);
			    	if (in_array($product_id, $allTheIDs) || in_array($post_parent_id, $allTheIDs)){
			    		// do nothing
			    	} else {
			    		$visible = false;
			    	}
				} else {
					$visible = false;
				}	
			    
			}
		}
		return $visible;
	}


	// copied from above 
	function b2bking_product_categories_visibility_rules_shortcode( $query_args ){

		if (isset($query_args['post_type'])){
			// if not product, then return 
			if ($query_args['post_type'] !== 'product' && $query_args['post_type'] !== array('product')){
				return $query_args;
			}
		}

		if (intval(get_option( 'b2bking_all_products_visible_all_users_setting', 1 )) !== 1){

			if ( get_option( 'b2bking_plugin_status_setting', 'b2b' ) !== 'disabled' ){

				$user_is_b2b = get_user_meta( get_current_user_id(), 'b2bking_b2buser', true );

				// if user logged in and is b2b
				if (is_user_logged_in() && ($user_is_b2b === 'yes')){
					// Get current user's data: group, id, login, etc
				    $currentuserid = get_current_user_id();
			    	$account_type = get_user_meta($currentuserid,'b2bking_account_type', true);
			    	if ($account_type === 'subaccount'){
			    		// for all intents and purposes set current user as the subaccount parent
			    		$parent_user_id = get_user_meta($currentuserid, 'b2bking_account_parent', true);
			    		$currentuserid = $parent_user_id;
			    	}

			        $currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = b2bking()->get_user_group($currentuserid);
				// if user is b2c
				} else if (is_user_logged_in() && ($user_is_b2b !== 'yes')){
				    $currentuserid = get_current_user_id();
			    	$currentuserid = b2bking()->get_top_parent_account($currentuserid);
			        $currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = 'b2c';
				} else {
					$currentuserlogin = 0;
					$currentusergroupidnr = 0;
				}

				// if salesking agent, get visibility of sales agent
    	    	if ($this->check_user_is_agent_with_access()){
    				$agent_id = $this->get_current_agent_id();
    				$currentuserid = $agent_id;
    				$currentuser = get_user_by('id', $currentuserid);
					$currentuserlogin = $currentuser -> user_login;
					$currentusergroupidnr = b2bking()->get_user_group($currentuserid);
    			}

				/*
				* 
				*	There are 2 separate queries that need to be made:
				* 	1. Query of all Categories visible to the USER AND all Categories visible to the USER'S GROUP 
				*	2. Query of all Products set to Manual visibility mode, visible to the user or the user's group 
				*
				*/

				// Build Visible Categories for the 1st Query
				$visiblecategories = array();
				$hiddencategories = array();

				$terms = get_terms( array( 
				    'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
				    'fields' => 'ids',
				    'hide_empty' => false
				) );

				foreach ($terms as $term){

					/* 
					* If category is visible to GROUP OR category is visible to USER
					* Push category into visible categories array
					*/

					// first check group
					$group_meta = get_term_meta( $term, 'b2bking_group_'.$currentusergroupidnr, true );
					if (intval($group_meta) === 1){
						array_push($visiblecategories, $term);
					// else check user
					} else {
						$userlistcommas = get_term_meta( $term, 'b2bking_category_users_textarea', true );
						$userarray = explode(',', $userlistcommas);
						$visible = 'no';
						foreach ($userarray as $user){
							if (trim($user) === $currentuserlogin){
								array_push($visiblecategories, $term);
								$visible = 'yes';
								break;
							}
						}
						if ($visible === 'no'){
							array_push($hiddencategories, $term);
						}
					}
				}


				$product_category_visibility_array = array(
				           'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
				           'field' => 'term_id',
				           'terms' => $visiblecategories, 
				           'operator' => 'IN',
				           'include_children' => (!apply_filters('b2bking_category_visibility_direct_categories_only', false))
				);

				// if user has enabled "hidden has priority", override setting
				if (intval(get_option( 'b2bking_hidden_has_priority_setting', 0 )) === 1){
					$product_category_visibility_array = array(
					           'taxonomy' => apply_filters('b2bking_visibility_taxonomy','product_cat'),
					           'field' => 'term_id',
					           'terms' => $hiddencategories, 
					           'operator' => 'NOT IN',
					           'include_children' => (!apply_filters('b2bking_category_visibility_direct_categories_only', false))
					);
				}

				/* Get all items that do not have manual visibility set up */
				// get all products ids
				if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){
					if (!b2bking()->use_wpml_cache()){
						$items_not_manual_visibility_array = get_transient('b2bking_not_manual_visibility_array');
					} else {
						$items_not_manual_visibility_array = get_transient('b2bking_not_manual_visibility_array'.ICL_LANGUAGE_NAME_EN);
					}
				} else {
					$items_not_manual_visibility_array = false;
				}
				
				if (!$items_not_manual_visibility_array){
					$all_prods = new WP_Query(array(
				        'posts_per_page' => -1,
				        'post_type' => 'product',
				        'fields' => 'ids'));
					$all_prod_ids = !empty($all_prods->posts) && is_object($all_prods->posts[0]) ? wp_list_pluck($all_prods->posts, 'ID') : $all_prods->posts; // Extract IDs if objects returned

					// get all products with manual visibility ids
					$all_prods_manual = new WP_Query(array(
				        'posts_per_page' => -1,
				        'post_type' => 'product',
				        'fields' => 'ids',
	    		        'meta_query'=> array(
	                            'relation' => 'AND',
	                            array(
	                                'key' => 'b2bking_product_visibility_override',
	                                'value' => 'manual',
	                            )
	                        )));
					$all_prod_manual_ids = !empty($all_prods_manual->posts) && is_object($all_prods_manual->posts[0]) ? wp_list_pluck($all_prods_manual->posts, 'ID') : $all_prods_manual->posts; // Extract IDs if objects returned
					// get the difference
					$items_not_manual_visibility_array = array_diff($all_prod_ids,$all_prod_manual_ids);
					set_transient('b2bking_not_manual_visibility_array', $items_not_manual_visibility_array, 30 * DAY_IN_SECONDS);
				}

				if (empty($items_not_manual_visibility_array)){
					$items_not_manual_visibility_array = array('invalid');
				}

				// Build first query
			    $queryAparams = array(
			        'posts_per_page' => -1,
			        'post_type' => 'product',
			        'fields' => 'ids',
			        'tax_query' => array(
			        	$product_category_visibility_array
			        ),
				    'post__in' => $items_not_manual_visibility_array,
				);

			    // Build 2nd query: all manual visibility products with USER OR USER GROUP visibility
			    $queryBparams = array(
			        'posts_per_page' => -1,
			        'post_type' => 'product',
			        'fields' => 'ids',
			        'meta_query'=> array(
	                        'relation' => 'AND',
	                        array(
	                            'relation' => 'OR',
	                            array(
	                                'key' => 'b2bking_group_'.$currentusergroupidnr,
	                                'value' => '1'
	                            ),
	                            array(
	                                'key' => 'b2bking_user_'.$currentuserlogin,
	                                'value' => '1'
	                            )
	                        ),
	                        array(
	                            'key' => 'b2bking_product_visibility_override',
	                            'value' => 'manual',
	                        )
	                    ));


			    // if caching is enabled
			    if (intval(get_option( 'b2bking_product_visibility_cache_setting', 1 )) === 1){

			    	// WPML CACHE INTEGRATION
			    	if (!b2bking()->use_wpml_cache()){
			    	    // Get cache and check integrity
			    	    $allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility');
			    	    $allTheIDs = b2bking()->check_visibility_cache_integrity($allTheIDs);
			    	    // cache query results
			    	    if (!$allTheIDs){
			    	        $queryA = new WP_Query($queryAparams);
			    	        $queryB = new WP_Query($queryBparams);
			    	        // Merge the 2 queries in an IDs array
			    	        $allTheIDs = array_merge($queryA->posts,$queryB->posts);
			    	        b2bking()->update_visibility_integrity_log($allTheIDs);
			    	        set_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility', $allTheIDs, YEAR_IN_SECONDS);
			    	    }
			    	} else {
			    	    // Get cache and check integrity
			    	    $allTheIDs = get_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility'.ICL_LANGUAGE_NAME_EN);
			    	    $allTheIDs = b2bking()->check_visibility_cache_integrity($allTheIDs);
			    	    // cache query results
			    	    if (!$allTheIDs){
			    	        $queryA = new WP_Query($queryAparams);
			    	        $queryB = new WP_Query($queryBparams);
			    	        // Merge the 2 queries in an IDs array
			    	        $allTheIDs = array_merge($queryA->posts,$queryB->posts);
			    	        b2bking()->update_visibility_integrity_log($allTheIDs);
			    	        set_transient('b2bking_user_'.get_current_user_id().'_ajax_visibility'.ICL_LANGUAGE_NAME_EN, $allTheIDs, YEAR_IN_SECONDS);
			    	    }
			    	}
				} else {
				 	$queryA = new WP_Query($queryAparams);
				 	$queryB = new WP_Query($queryBparams);
					 // Merge the 2 queries in an IDs array
					$allTheIDs = array_merge($queryA->posts,$queryB->posts);
				}

			    if(!empty($allTheIDs)){
			    	// check if it is already set to something
			    	// in the widget it can be set to products that are on sale
			    	if (empty($query_args['post__in'])){
			    		$query_args['post__in'] = $allTheIDs;
			    	} else {

			    		// for WPML, to one of the sides being intersected (post_in existing because it's lighter, add all filters to lang)
			    		$existing = $query_args['post__in'];
			    		foreach ($existing as $existing_item){
			    			array_push($existing, apply_filters( 'wpml_object_id', $existing_item, 'post' , true));
			    		}
			    		

			    		// intersect array
			    		$intersection = array_intersect($existing, $allTheIDs);
			    		$query_args['post__in'] = $intersection;

			    		if (empty($intersection)){
							$query_args['post__in'] = array('invalidid');
						}
			    	}
				} else {
					// If the array is empty, WooCommerce shows all products. To fix this, we pass an invalid IDs array in that case.
			    	$query_args['post__in'] = array('invalidid');
				}
				return $query_args;
			}
		}
	}

	/* Functions that handle Reordering	*/
	// Add reorder button in account orders (overview)
	function b2bking_add_reorder_button_overview( $actions, $order ) {

		if ( ! $order || ! is_user_logged_in() ) {
			return $actions;
		}

		// check if order is completed
		if ( $order->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_order_again', array( 'completed' ) ) ) ) { 
			$actions['order-again'] = array(
			'url'  => wp_nonce_url( add_query_arg( 'order_again', $order->get_id() ) , 'woocommerce-order_again' ),
			'name' => esc_html__( 'Order again', 'b2bking' )
			);
		}
		return $actions;

	}

	function b2bking_reorder_save_old_order_id( $order_id ) {
		WC()->session->set( 'b2bking_reorder_from_orderid', $order_id );
	}

	function b2bking_reorder_create_order_note_reference( $order_id ) {
		$reorder_id = WC()->session->get( 'b2bking_reorder_from_orderid');
		$order = wc_get_order($order_id);
		if ($reorder_id != '' ) {
            $order->update_meta_data('_reorder_from_id', $reorder_id);
            $order->save();

            $url = get_edit_post_link( $reorder_id );
            $note = esc_html__('This is a reorder of order ','b2bking').'<a href="'.esc_url($url).'">'.esc_html($reorder_id).'</a>'.esc_html__('. Please note, however, that customers may have changed the items/quantity ordered — Note by B2BKing.','b2bking');
            $order->add_order_note( apply_filters( 'b2bking_reorder_order_note', $note, $reorder_id, $order_id ) );
		}
		WC()->session->set( 'b2bking_reorder_from_orderid' , null );
	}

	function b2bking_subaccount_order_note( $order_id ) {
        $order = wc_get_order( $order_id );
        $customer_id = $order->get_customer_id();
        $account_type = get_user_meta($customer_id, 'b2bking_account_type', true);
        if ($account_type === 'subaccount'){
        	$parent_id = intval(get_user_meta($customer_id,'b2bking_account_parent', true));
        	$parent_user = new WP_User($parent_id);
        	$parent_login = $parent_user->user_login;

	        $note = esc_html__('This is an order placed by a subaccount of the user ','b2bking').'<a href="'.esc_attr(get_edit_user_link($parent_id)).'">'.esc_html($parent_login).'</a>';
	        $order->add_order_note( $note);

    
        	// check if requires approval
        	if ($order->get_payment_method() === 'b2bking-approval-gateway'){
		     	$permission_approval = filter_var(get_user_meta($customer_id, 'b2bking_account_permission_buy_approval', true),FILTER_VALIDATE_BOOLEAN);
		     	$permission_approval = apply_filters('b2bking_subaccount_needs_approval', $permission_approval, $customer_id);

		     	if ($permission_approval === true){
		     		$order->update_meta_data('b2bking_order_approval_gateway', 'yes');

		     		if (floatval($order->get_total()) == 0){
						$order->update_status( apply_filters( 'b2bking_company_approval_order_status', 'wc-pcompany', $order ), esc_html__( 'Pending company approval.', 'b2bking' ) );

						// Fire message to parent account
						$parent_user_id = get_user_meta($customer_id,'b2bking_account_parent', true);
						$parent_user = new WP_User($parent_user_id);
						$currentuser = wp_get_current_user();
						$currentname = $currentuser->first_name.' '.$currentuser->last_name;
						$message = apply_filters('b2bking_approval_message_parent', 'One of your subaccounts, '.$currentname.', has placed an order that is now pending your review. Click <a href="'.esc_url( wc_get_account_endpoint_url( 'orders' ) ).'">here</a> to view orders.', $currentname);
						//do_action( 'b2bking_new_message', $parent_user->user_email, $message, 'Quoteemail:1', 0 );

		 			}
		 			$order->save();	
		     	}
        	}
        	
    	}
	}

	function b2bking_quote_button_product_page(){
		if (is_product()){
			if (apply_filters('b2bking_quote_button_product_page', false)){ // set to false
				global $product;
				$prodid = $product->get_id();

				add_filter('b2bking_request_custom_quote_text', function($val){
					return esc_html__('Request quote', 'b2bking');
				}, 10, 1);

				echo $this->b2bking_add_request_quote_button('productpage', $prodid);


			}
		}
	}

	function b2bking_purchaselists_productpage_button(){
		if (is_product() && is_user_logged_in()){
			global $product;
			$product_id = $product->get_id();

			$purchase_lists = get_posts([
				'post_type'   => 'b2bking_list',
				'post_status' => 'publish',
				'numberposts' => -1,
				'author'      => get_current_user_id(),
			]);

			echo '<div class="b2bking_purchaselist_productpage_wrap">';
			echo '<select class="b2bking_purchaselist_productpage_select" data-product-id="' . esc_attr($product_id) . '">';
			echo '<option value="create">' . esc_html__('Create a list...', 'b2bking') . '</option>';
			foreach ($purchase_lists as $list) {
				echo '<option value="' . esc_attr($list->ID) . '">' . esc_html($list->post_title) . '</option>';
			}
			echo '</select>';
			echo '<button type="button" class="b2bking_purchaselist_productpage_add_button button">' . esc_html__('Add to list', 'b2bking') . '</button>';
			echo '</div>';
		}
	}

	function b2bking_add_request_quote_button_cart_block($block_content, $block) {
	    if ($block['blockName'] === 'woocommerce/cart') {

	    	ob_start();

	    	if (is_object( WC()->cart )){
		    	if (!empty(WC()->cart->get_cart())){
		    		$this->b2bking_add_request_quote_button();
		    	}
		    }

	    	$custom_content = ob_get_clean();

	        $block_content .= $custom_content;

	    }
	    return $block_content;
	}

	// Add "Request a Quote" button
	function b2bking_add_request_quote_button($location = 'standard', $product_id = '', $button_or_form = 'button'){

		if ($button_or_form === 'form'){

			// pre-click the button automatically
			?>
			<script>
				jQuery(document).ready(function(){
					setTimeout(function(){
						jQuery('#b2bking_request_custom_quote_button').click();

						setTimeout(function(){
							jQuery('.b2bking_send_custom_quote_button').addClass('b2bking_shortcode_send');

						}, 5);

					}, 5);
				});
			</script>
			<?php
		}

		?>
		<img class="b2bking_loader_hidden" src="<?php echo plugins_url('../includes/assets/images/loader.svg', __FILE__); ?>">

		<div id="b2bking_before_quote_request_button"></div>
		<?php

		// If Conversations are enabled in settings
		if (intval(get_option('b2bking_enable_conversations_setting', 1)) === 1){
			if ((get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes')) ){
				// continue
			} else {
				$quote_button_setting = get_option('b2bking_quote_button_cart_setting', 'enableb2b');

				// check if current user has quotes only. In that case, must auto enable button
				if ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes')) ){
					$quote_button_setting = 'enableall';
				}

				// must also auto-enable button if there's a quote on specific products only item in cart
				if (b2bking()->user_has_p_in_cart('quote') === 'yes'){
					$quote_button_setting = 'enableall';

				}



				if ($quote_button_setting === 'disabled'){
					return;
				} else if ($quote_button_setting === 'enableb2b'){
					// return if user is not b2b
					if (get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes'){
						return;
					}
				} else if ($quote_button_setting === 'enableb2c'){
					// return if user is b2b
					if (get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) === 'yes'){
						return;
					}
				} else if ($quote_button_setting === 'enableall'){
					// continue
				}
			}
			?>
			<div class="b2bking_before_quote_request_form">
				<?php do_action('b2bking_before_quote_request_form'); ?>
			</div>
			<?php

			// If user is a guest and this is a Quote Request initiated by a guest, add "Name" and "Email address" (or if B2C in hybrid mode)
			if (!is_user_logged_in() || (get_user_meta(get_current_user_id(), 'b2bking_b2buser', true) !== 'yes' && get_option( 'b2bking_plugin_status_setting', 'b2b' ) === 'hybrid')){
				?>
				<span class="b2bking_request_custom_quote_text_label"><?php esc_html_e('Your name (*):','b2bking'); ?></span>
				<input type="text" id="b2bking_request_custom_quote_name" name="b2bking_request_custom_quote_name">
				<span class="b2bking_request_custom_quote_text_label"><?php esc_html_e('Your email address (*):','b2bking'); ?></span>
				<input type="email" id="b2bking_request_custom_quote_email" name="b2bking_request_custom_quote_email">
				<?php
			}
			?>
			<?php

			// CUSTOM QUOTE FIELDS HERE
			$custom_fields = get_posts([
	    		'post_type' => 'b2bking_quote_field',
	    	  	'post_status' => 'publish',
	    	  	'numberposts' => -1,
    	  	    'orderby' => 'menu_order',
    	  	    'order' => 'ASC',
	    	  	'meta_query'=> array(
	    	  		'relation' => 'AND',
	                array(
                        'key' => 'b2bking_custom_field_status',
                        'value' => 1
	                ),
            	)
	    	]);


			// Get current user
			$user_id = get_current_user_id();

	    	$user_id = b2bking()->get_top_parent_account($user_id);

			$currentusergroupidnr = b2bking()->get_user_group($user_id);
			$is_b2b = get_user_meta( $user_id, 'b2bking_b2buser', true );
			if (empty($currentusergroupidnr)){
				$currentusergroupidnr = 'nothave'; // necessary to avoid issues for guests
			}
			$text_ids = array();
			$checkbox_ids = array();
			$file_ids = array();
			$required_ids = array();


		 	foreach ($custom_fields as $custom_field){
					$field_type = get_post_meta($custom_field->ID, 'b2bking_custom_field_field_type', true);
					$field_label = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_label', true);
					$field_placeholder = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_field_placeholder', true);
					$required = get_post_meta($custom_field->ID, 'b2bking_custom_field_required', true);
					// role identifier
					$role = get_post_meta($custom_field->ID, 'b2bking_custom_field_registration_role', true);

					$show = 'no';
					if ($role === 'allroles'){
						$show = 'yes';
					} else if ($role === 'loggedout'){
						if (!is_user_logged_in()){
							$show = 'yes';
						}
					} else if ($role === 'b2c'){
						if (is_user_logged_in() && $is_b2b !== 'yes'){
							$show = 'yes';
						}
					} else if ($role === 'multipleroles'){
						$field_roles = get_post_meta($custom_field->ID, 'b2bking_custom_field_multiple_roles', true);
						$roles_array = explode(',',$field_roles);
						if (in_array('loggedout', $roles_array)){
							if (!is_user_logged_in()){
								$show = 'yes';
							}
						}
						if (in_array('b2c', $roles_array)){
							if (is_user_logged_in() && $is_b2b !== 'yes'){
								$show = 'yes';
							}
						}
						if (in_array('role_'.$currentusergroupidnr, $roles_array)){
							$show = 'yes';
						}
					} else {
						if ($role === 'role_'.$currentusergroupidnr){
							$show = 'yes';
						}
					}

					// hide or show quote field based on visibility

					if ($show === 'yes'){

						// if error, get previous value and show it in the fields, for user friendliness
						$previous_value = '';
						if (isset($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID)])){
							$previous_value = sanitize_text_field($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID)]);
						}

						if (intval($required) === 1 && $field_type !== 'checkbox'){
							array_push($required_ids, $custom_field->ID);
							$required = 'required';
						} else {
							$required = '';
						}
					

						$class = '';

						
						
						?>
						<div class="b2bking_custom_quote_field_container">
						<span class="b2bking_request_custom_quote_text_label"><?php echo esc_html($field_label);
						if ($required === 'required'){ 
							echo ' (*)';
						}
						echo ':';						

						 ?></span>
						<?php

							if ($field_type === 'text'){
								array_push($text_ids, $custom_field->ID);
								echo '<input type="text" id="b2bking_field_'.esc_attr($custom_field->ID).'" class="b2bking_custom_quote_field b2bking_quote_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" >';
							} else if ($field_type === 'textarea'){
								array_push($text_ids, $custom_field->ID);
								echo '<textarea id="b2bking_field_'.esc_attr($custom_field->ID).'" class="b2bking_custom_quote_field b2bking_custom_registration_field_textarea b2bking_quote_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" placeholder="'.esc_attr($field_placeholder).'" >'.esc_html($previous_value).'</textarea>';
							} else if ($field_type === 'number'){
								array_push($text_ids, $custom_field->ID);
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="number" step="0.00001" class="b2bking_custom_quote_field b2bking_quote_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" >';
							} else if ($field_type === 'email'){
								array_push($text_ids, $custom_field->ID);
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="email" class="b2bking_custom_quote_field b2bking_quote_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" >';
							} else if ($field_type === 'date'){
								array_push($text_ids, $custom_field->ID);
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="date" class="b2bking_custom_quote_field b2bking_quote_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" >';
							} else if ($field_type === 'time'){
								array_push($text_ids, $custom_field->ID);
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="time" class="b2bking_custom_quote_field b2bking_quote_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" >';
							} else if ($field_type === 'tel'){
								array_push($text_ids, $custom_field->ID);
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="tel" class="b2bking_custom_quote_field b2bking_quote_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" value="'.esc_attr($previous_value).'" placeholder="'.esc_attr($field_placeholder).'" >';
							} else if ($field_type === 'file'){
								array_push($file_ids, $custom_field->ID);
								echo '<input id="b2bking_field_'.esc_attr($custom_field->ID).'" type="file" class="b2bking_custom_quote_field b2bking_quote_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" placeholder="'.esc_attr($field_placeholder).'" >'.'<span class="b2bking_supported_types">'.esc_html__('Supported file types: ','b2bking').apply_filters('b2bking_allowed_file_types_text', 'jpg, jpeg, png, txt, pdf, doc, docx').'</span>';
								do_action('b2bking_after_supported_types', $custom_field->ID);


							} else if ($field_type === 'select'){
								array_push($text_ids, $custom_field->ID);
								$select_options = get_post_meta(apply_filters( 'wpml_object_id', $custom_field->ID, 'post', true ), 'b2bking_custom_field_user_choices', true);
								$select_options = explode(',', $select_options);

								echo '<select id="b2bking_field_'.esc_attr($custom_field->ID).'" class="b2bking_custom_quote_field b2bking_quote_field_req_'.esc_attr($required).'" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'" placeholder="'.esc_attr($field_placeholder).'" >';
									foreach ($select_options as $option){
										// check if option is simple or value is specified via option:value
										$optionvalue = explode(':', $option);
										if (count($optionvalue) === 2 ){
											// value is specified
											echo '<option value="'.esc_attr(trim($optionvalue[0])).'" '.selected(trim($optionvalue[0]), $previous_value, false).'>'.esc_html(trim($optionvalue[1])).'</option>';
										} else {
											// simple
											echo '<option value="'.esc_attr(trim($option)).'" '.selected($option, $previous_value, false).'>'.esc_html(trim($option)).'</option>';
										}
									}
								echo '</select>';
							} else if ($field_type === 'checkbox'){	
								array_push($checkbox_ids, $custom_field->ID);

								$select_options = get_post_meta($custom_field->ID, 'b2bking_custom_field_user_choices', true);
								$select_options = explode(',', $select_options);
								$i = 1;

								// if required and only 1 option (might be like an "I accept privacy policy" box), set required
								if ($required === 'required' && count($select_options) === 1){
									$uniquerequired = 'required';
								} else {
									$uniquerequired = '';
								}
								echo '<br>';
								foreach ($select_options as $option){
									
									$previous_value = '';
									if (isset($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i])){
										$previous_value = sanitize_text_field($_POST['b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i]);
									}
									echo '<p class="form-row">';
									echo '<label class="woocommerce-form__label woocommerce-form__label-for-checkbox">';
									echo '<input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox b2bking_custom_quote_field b2bking_checkbox_registration_field b2bking_quote_field_req_'.esc_attr($uniquerequired).'" value="1" name="b2bking_custom_field_'.esc_attr($custom_field->ID).'_option_'.$i.'" '.checked(1, $previous_value, false).' '.esc_attr($uniquerequired).'>';
									echo '<span>'.trim(wp_kses( $option, array( 'a'     => array(
								        'href' => array(), 'target' => array()
								    ) ) )).'</span></label></p>';

									$i++;
								}

							}

							do_action('b2bking_after_custom_field', $custom_field->ID);

							
						echo '</div>';

					}

					
				}
			?>
			<span id="b2bking_request_custom_quote_textarea_abovetext"><?php esc_html_e('Your message:','b2bking'); ?></span>
			<textarea id="b2bking_request_custom_quote_textarea"></textarea>
			<button type="button" id="b2bking_request_custom_quote_button" class="button <?php 

				if ($location === 'shortcode'){ echo 'b2bking_button_quote_shortcode'; }
				if ($location === 'productpage'){ echo 'b2bking_button_quote_productpage'; }

			?>" <?php if (!empty($product_id)) { echo 'value="'.esc_html($product_id).'"';} ?>>
				<?php echo apply_filters('b2bking_request_custom_quote_text', esc_html__('Request custom quote','b2bking')); ?>
			</button>

			<?php

			$textidstring = '';
			foreach ($text_ids as $textid){
				$textidstring.=$textid.',';
			}

			$checkboxidstring = '';
			foreach ($checkbox_ids as $textid){
				$checkboxidstring.=$textid.',';
			}

			$fileidstring = '';
			foreach ($file_ids as $textid){
				$fileidstring.=$textid.',';
			}

			$requiredidsstring = '';
			foreach ($required_ids as $textid){
				$requiredidsstring.=$textid.',';
			}
			$fileidstring = substr($fileidstring, 0, -1);
			$checkboxidstring = substr($checkboxidstring, 0, -1);
			$textidstring = substr($textidstring, 0, -1);
			$requiredidsstring = substr($requiredidsstring, 0, -1);


			echo '<input type="hidden" id="b2bking_quote_text_ids" value="'.esc_attr($textidstring).'">';
			echo '<input type="hidden" id="b2bking_quote_checkbox_ids" value="'.esc_attr($checkboxidstring).'">';
			echo '<input type="hidden" id="b2bking_quote_file_ids" value="'.esc_attr($fileidstring).'">';
			echo '<input type="hidden" id="b2bking_quote_required_ids" value="'.esc_attr($requiredidsstring).'">';

			?>
		<?php
		}
	}

    function check_user_is_agent_with_access(){
    	// check if switch cookie is set
    	if (isset($_COOKIE['salesking_switch_cookie'])){
	    	$switch_to = sanitize_text_field($_COOKIE['salesking_switch_cookie']);
	    	$current_id = get_current_user_id();

	    	if (!empty($switch_to) && is_user_logged_in()){
	    		// show bar
				$udata = get_userdata( get_current_user_id() );
				$name = $udata->first_name.' '.$udata->last_name;

				// get agent details
				$agent = explode('_',$switch_to);
				$customer_id = intval($agent[0]);
				$agent_id = intval($agent[1]);
				$agent_registration = $agent[2];
				// check real registration in database
				$udataagent = get_userdata( $agent_id );
	            $registered_date = $udataagent->user_registered;

	            // if current logged in user is the one in the cookie + agent cookie checks out
	            if ($current_id === $customer_id && $agent_registration === $registered_date){
	            	return apply_filters('b2bking_enable_salesking_visibility', true);
	            }
	        }
	    }
        return false;
    }

    function get_current_agent_id(){
    	if (isset($_COOKIE['salesking_switch_cookie'])){
	    	$switch_to = sanitize_text_field($_COOKIE['salesking_switch_cookie']);
	    	if (!empty($switch_to)){
	    		$agent = explode('_',$switch_to);
	    		$agent_id = intval($agent[1]);
	    		return $agent_id;
	    	}
	    }
	    return false;
    }

	// clear user tax cache when checkout is rendered
	function b2bking_clear_tax_cache_checkout(){
		delete_option('_transient_b2bking_tax_exemption_user_'.get_current_user_id());
	}

	/* 
	* Replaces price with quote requests (dynamic rule)
	* returns 'yes' or 'no' string
	*/
	function dynamic_replace_prices_with_quotes(){

		if (apply_filters('b2bking_disable_quotes_for_agents_shopping', true)){
			if ($this->check_user_is_agent_with_access()){
				return 'no';
			}
		}

		// Get current user
		$user_id = get_current_user_id();

    	$user_id = b2bking()->get_top_parent_account($user_id);

		$currentusergroupidnr = b2bking()->get_user_group($user_id);
		if (empty($currentusergroupidnr)){
			$currentusergroupidnr = 'nothave'; // necessary to avoid issues for guests
		}

		$replace_prices_quote = get_transient('b2bking_replace_prices_quote_user_'.$user_id);

		if (!$replace_prices_quote){


			$array_who_multiple = array(
		                'relation' => 'OR',
		                array(
		                    'key' => 'b2bking_rule_who_multiple_options',
		                    'value' => 'group_'.$currentusergroupidnr,
		                	'compare' => 'LIKE'
		                ),
		                array(
		                    'key' => 'b2bking_rule_who_multiple_options',
		                    'value' => 'user_'.$user_id,
		                    'compare' => 'LIKE'
		                ),
		            );

			if ($user_id !== 0){
				array_push($array_who_multiple, array(
	                'key' => 'b2bking_rule_who_multiple_options',
	                'value' => 'all_registered',
	                'compare' => 'LIKE'
	            ));

				// add rules that apply to all registered b2b/b2c users
				$user_is_b2b = get_user_meta($user_id, 'b2bking_b2buser', true);
				if ($user_is_b2b === 'yes'){
					array_push($array_who_multiple, array(
	                    'key' => 'b2bking_rule_who_multiple_options',
	                    'value' => 'everyone_registered_b2b',
	                    'compare' => 'LIKE'
	                ));
				} else if ($user_is_b2b === 'no'){
					array_push($array_who_multiple, array(
	                    'key' => 'b2bking_rule_who_multiple_options',
	                    'value' => 'everyone_registered_b2c',
	                    'compare' => 'LIKE'
	                ));
				}
			}

			$array_who = array(
	            'relation' => 'OR',
	            array(
	                'key' => 'b2bking_rule_who',
	                'value' => 'group_'.$currentusergroupidnr
	            ),
	            array(
	                'key' => 'b2bking_rule_who',
	                'value' => 'user_'.$user_id
	            ),
	            array(
	                'relation' => 'AND',
	                array(
	                    'key' => 'b2bking_rule_who',
	                    'value' => 'multiple_options'
	                ),
	                $array_who_multiple
	            ),
	        );
			// if user is registered, also select rules that apply to all registered users
			if ($user_id !== 0){
				array_push($array_who, array(
		                        'key' => 'b2bking_rule_who',
		                        'value' => 'all_registered'
		                    ));

				// add rules that apply to all registered b2b/b2c users
				$user_is_b2b = get_user_meta($user_id, 'b2bking_b2buser', true);
				if ($user_is_b2b === 'yes'){
					array_push($array_who, array(
		                        'key' => 'b2bking_rule_who',
		                        'value' => 'everyone_registered_b2b'
		                    ));
				} else if ($user_is_b2b === 'no'){
					array_push($array_who, array(
		                        'key' => 'b2bking_rule_who',
		                        'value' => 'everyone_registered_b2c'
		                    ));
				}
			}

			if (apply_filters('b2bking_use_simple_query_system', false)){
				$quote_request_rules = get_posts([
		    		'post_type' => 'b2bking_rule',
		    	  	'post_status' => 'publish',
		    	  	'fields'        => 'ids', // Only get post IDs
		    	  	'numberposts' => -1,
		    	  	'meta_query'=> array(
		                array(
		                    'key' => 'b2bking_rule_what',
		                    'value' => 'replace_prices_quote'
		                ),
		            )
		    	]);
				
				$quote_request_rules = b2bking()->filter_check_rules_apply_current_user($quote_request_rules);
				$quote_request_rules = b2bking()->filter_check_rules_apply_meta_value($quote_request_rules, 'b2bking_rule_what', 'replace_prices_quote');


			} else {
				$quote_request_rules = get_posts([
		    		'post_type' => 'b2bking_rule',
		    	  	'post_status' => 'publish',
		    	  	'fields'        => 'ids', // Only get post IDs
		    	  	'numberposts' => -1,
		    	  	'meta_query'=> array(
		                'relation' => 'AND',
		                array(
		                    'key' => 'b2bking_rule_what',
		                    'value' => 'replace_prices_quote'
		                ),
		                $array_who,
		            )
		    	]);
			}
			

	    	if (empty($quote_request_rules)){
	    		$replace_prices_quote = 'no';
	    	} else {
	    		$replace_prices_quote = 'yes';
	    	}

	    	set_transient('b2bking_replace_prices_quote_user_'.$user_id, $replace_prices_quote);

		}

		return $replace_prices_quote;

	}

	function dynamic_rename_purchase_order_method($available_gateways = array()){

		// Get current user
		$user_id = get_current_user_id();

    	$user_id = b2bking()->get_top_parent_account($user_id);

		$currentusergroupidnr = b2bking()->get_user_group($user_id);
		if (empty($currentusergroupidnr)){
			$currentusergroupidnr = 'nothave'; // necessary to avoid issues for guests
		}

		$array_who_multiple = array(
	                'relation' => 'OR',
	                array(
	                    'key' => 'b2bking_rule_who_multiple_options',
	                    'value' => 'group_'.$currentusergroupidnr,
	                	'compare' => 'LIKE'
	                ),
	                array(
	                    'key' => 'b2bking_rule_who_multiple_options',
	                    'value' => 'user_'.$user_id,
	                    'compare' => 'LIKE'
	                ),
	            );

		if ($user_id !== 0){
			array_push($array_who_multiple, array(
                'key' => 'b2bking_rule_who_multiple_options',
                'value' => 'all_registered',
                'compare' => 'LIKE'
            ));

			// add rules that apply to all registered b2b/b2c users
			$user_is_b2b = get_user_meta($user_id, 'b2bking_b2buser', true);
			if ($user_is_b2b === 'yes'){
				array_push($array_who_multiple, array(
                    'key' => 'b2bking_rule_who_multiple_options',
                    'value' => 'everyone_registered_b2b',
                    'compare' => 'LIKE'
                ));
			} else if ($user_is_b2b === 'no'){
				array_push($array_who_multiple, array(
                    'key' => 'b2bking_rule_who_multiple_options',
                    'value' => 'everyone_registered_b2c',
                    'compare' => 'LIKE'
                ));
			}
		}

		$array_who = array(
            'relation' => 'OR',
            array(
                'key' => 'b2bking_rule_who',
                'value' => 'group_'.$currentusergroupidnr
            ),
            array(
                'key' => 'b2bking_rule_who',
                'value' => 'user_'.$user_id
            ),
            array(
                'relation' => 'AND',
                array(
                    'key' => 'b2bking_rule_who',
                    'value' => 'multiple_options'
                ),
                $array_who_multiple
            ),
        );
		// if user is registered, also select rules that apply to all registered users
		if ($user_id !== 0){
			array_push($array_who, array(
	                        'key' => 'b2bking_rule_who',
	                        'value' => 'all_registered'
	                    ));

			// add rules that apply to all registered b2b/b2c users
			$user_is_b2b = get_user_meta($user_id, 'b2bking_b2buser', true);
			if ($user_is_b2b === 'yes'){
				array_push($array_who, array(
	                        'key' => 'b2bking_rule_who',
	                        'value' => 'everyone_registered_b2b'
	                    ));
			} else if ($user_is_b2b === 'no'){
				array_push($array_who, array(
	                        'key' => 'b2bking_rule_who',
	                        'value' => 'everyone_registered_b2c'
	                    ));
			}
		}

		if (apply_filters('b2bking_use_simple_query_system', false)){
			$quote_request_rules = get_posts([
	    		'post_type' => 'b2bking_rule',
	    	  	'post_status' => 'publish',
	    	  	'fields'        => 'ids', // Only get post IDs
	    	  	'numberposts' => -1
	    	]);
			
			$quote_request_rules = b2bking()->filter_check_rules_apply_current_user($quote_request_rules);
			$quote_request_rules = b2bking()->filter_check_rules_apply_meta_value($quote_request_rules, 'b2bking_rule_what', 'rename_purchase_order');

		} else {
			$quote_request_rules = get_posts([
	    		'post_type' => 'b2bking_rule',
	    	  	'post_status' => 'publish',
	    	  	'fields'        => 'ids', // Only get post IDs
	    	  	'numberposts' => -1,
	    	  	'meta_query'=> array(
	                'relation' => 'AND',
	                array(
	                    'key' => 'b2bking_rule_what',
	                    'value' => 'rename_purchase_order'
	                ),
	                $array_who,
	            )
	    	]);
		}

		if (empty($quote_request_rules)){
			return 'no';
		} else {

			foreach ($quote_request_rules as $rule_id){
				$gateway_name = get_post_meta($rule_id,'b2bking_rule_taxname', true);
				$selected_method = get_post_meta($rule_id,'b2bking_rule_paymentmethod', true);
				if (isset($available_gateways[$selected_method])){
					$available_gateways[$selected_method]->title = $gateway_name;
				}
			}

			return $available_gateways;
		}

	}

	// check coupon validity based on role
	function b2bking_filter_woocommerce_coupon_is_valid( $is_valid, $coupon, $discount ) {

		$coupon_id = wc_get_coupon_id_by_code($coupon->get_code());
	    // Get meta
	    $b2bking_customer_user_role = get_post_meta($coupon_id, 'b2bking_customer_user_role', true);

	    // if there is a restriction
	    if( ! empty( $b2bking_customer_user_role ) ) {

	        // Convert string to array
	        $allowed_roles_array = explode(',', $b2bking_customer_user_role);
	        $allowed_roles_array = array_map('trim', $allowed_roles_array);
	        $allowed_roles_array = array_map('strtolower', $allowed_roles_array);
	        // Get current user role
	        $user = new WP_User( get_current_user_id() );
	        $roles = ( array ) $user->roles;

	        $user_is_allowed = 'no';
	        // check if there is any allowed role that the user has
	        foreach ($roles as $user_role){
	        	if (in_array($user_role, $allowed_roles_array)){
	        		$user_is_allowed = 'yes';
	        		break;
	        	}
	        }

	        if ($user_is_allowed === 'no'){
		        // enable "loggedout", "b2c", "b2b"

		        // logged out
		        if (!is_user_logged_in()){
		        	if (in_array('loggedout', $allowed_roles_array) || in_array('guest', $allowed_roles_array)){
		        		$user_is_allowed = 'yes';
		        	}
		        } else {
			        // user is b2c
			        if (get_user_meta(get_current_user_id(),'b2bking_b2buser', true) !== 'yes'){
			        	if (in_array('b2c', $allowed_roles_array)){
			        		$user_is_allowed = 'yes';
			        	}
			        } else {
			        // user is b2b
			        	if (in_array('b2b', $allowed_roles_array)){
			        		$user_is_allowed = 'yes';
			        	}
			        }
			    }
		    }

		    // check user groups
		    if ($user_is_allowed === 'no'){
    			// get user's group
    			$user_id = get_current_user_id();
    	    	$account_type = get_user_meta($user_id,'b2bking_account_type', true);
    	    	if ($account_type === 'subaccount'){
    	    		// for all intents and purposes set current user as the subaccount parent
    	    		$parent_user_id = get_user_meta($user_id, 'b2bking_account_parent', true);
    	    		$user_id = $parent_user_id;
    	    	}

    			$currentusergroupidnr = b2bking()->get_user_group($user_id);
    			$is_b2b_user = get_user_meta( $user_id, 'b2bking_b2buser', true );

    			if ($is_b2b_user === 'yes'){
    				if (in_array('b2bking_group_'.$currentusergroupidnr, $allowed_roles_array)){
		        		$user_is_allowed = 'yes';
		        	}
    				if (in_array('b2bking_role_'.$currentusergroupidnr, $allowed_roles_array)){
		        		$user_is_allowed = 'yes';
		        	}
    			}
		    }


	        if ($user_is_allowed === 'no'){
	        	$is_valid = false; 
	        }

	    }

	    return $is_valid;
	}

	// Add user classes to body
	function b2bking_body_classes($classes) {

		//b2bking version
		$classes[] = 'b2bking_pro_version_'.B2BKING_VERSION;
		// if user is B2B
		$user_id = get_current_user_id();

		// subaccount
		$account_type = get_user_meta($user_id, 'b2bking_account_type', true);
		if ($account_type === 'subaccount'){
			$classes[] = 'b2bking_subaccount';
		}

		$user_id = b2bking()->get_top_parent_account($user_id);

		$is_b2b = get_user_meta($user_id,'b2bking_b2buser', true);

		if ($is_b2b === 'yes'){
			$classes[] = 'b2bking_b2b_user';
			// add group
			$group = b2bking()->get_user_group($user_id);
			$classes[] = 'b2bking_b2b_group_'.$group;
		} else {
			if (is_user_logged_in()){
				$classes[] = 'b2bking_b2c_user';
			} else {
				$classes[] = 'b2bking_logged_out';
			}
		}

		// my account endpoints
		$is_b2bking_account_page = 'no';
		foreach ([get_option('b2bking_conversations_endpoint_setting','conversation'), get_option('b2bking_conversations_endpoint_setting','conversations'), get_option('b2bking_offers_endpoint_setting','offers'), get_option('b2bking_bulkorder_endpoint_setting','bulkorder'), get_option('b2bking_subaccount_endpoint_setting','subaccount'), get_option('b2bking_subaccounts_endpoint_setting','subaccounts'), get_option('b2bking_purchaselist_endpoint_setting','purchase-list'), get_option('b2bking_purchaselists_endpoint_setting','purchase-lists')] as $e) {
		    if (is_wc_endpoint_url($e)){
		    	$is_b2bking_account_page = 'yes';
		    	$classes[] = 'b2bking_'.$e;
		    }
		}

		if ($is_b2bking_account_page === 'yes'){
		    $classes[] = 'b2bking_account_page';
		}	

	    return $classes;
	}

	function b2bking_user_cookies() {
	    $user_id = get_current_user_id();
	    $account_type = get_user_meta($user_id,'b2bking_account_type', true);
	    if ($account_type === 'subaccount'){
	    	// for all intents and purposes set current user as the subaccount parent
	    	$parent_user_id = get_user_meta($user_id, 'b2bking_account_parent', true);
	    	$user_id = $parent_user_id;
	    }

	    $is_b2b = get_user_meta($user_id,'b2bking_b2buser', true);

	    if(!headers_sent()){

		    if ($is_b2b === 'yes'){
		    	setcookie('b2bking_user_type', 'b2b', time()+3600, '/');

		    } else {
		    	if (is_user_logged_in()){
		    		setcookie('b2bking_user_type', 'b2c', time()+3600, '/');
		    	} else {
		    		setcookie('b2bking_user_type', 'logged_out', time()+3600, '/');
		    	}
		    }

		}

	}

	function b2bking_custom_color() {
		$color = get_option( 'b2bking_color_setting', '#3AB1E4' );
		$colorhover = get_option( 'b2bking_colorhover_setting', '#0088c2' );

		$purchase_lists_header = get_option( 'b2bking_purchase_lists_color_header_setting', '#353042' );
		$purchase_lists_action = get_option( 'b2bking_purchase_lists_color_action_buttons_setting', '#b1b1b1' );
		$purchase_lists_new = get_option( 'b2bking_purchase_lists_color_new_list_setting', '#353042' );
		?>

		<style type="text/css">
			.b2bking_myaccount_individual_offer_bottom_line_add button.b2bking_myaccount_individual_offer_bottom_line_button, #b2bking_myaccount_conversations_container_top button, button.b2bking_myaccount_start_conversation_button, .b2bking_myaccount_conversation_endpoint_button, button.b2bking_bulkorder_form_container_bottom_add_button, button.b2bking_subaccounts_container_top_button, button.b2bking_subaccounts_new_account_container_content_bottom_button, button.b2bking_subaccounts_edit_account_container_content_bottom_button, button#b2bking_purchase_list_new_button, button.b2bking_purchase_lists_view_list, button#b2bking_reimburse_amount_button, button#b2bking_redeem_amount_button, #b2bking_return_agent{
				background: <?php echo esc_html( $color ); ?>;
			}

			.b2bking_has_color{
				background: <?php echo esc_html( $color ); ?>!important;
				background-color: <?php echo esc_html( $color ); ?>!important;
			}
			table.b2bking_tiered_price_table tbody td.b2bking_has_color{
				background: <?php echo esc_html( $color ); ?>!important;
				background-color: <?php echo esc_html( $color ); ?>!important;
			}

			.b2bking_myaccount_individual_offer_bottom_line_add button:hover.b2bking_myaccount_individual_offer_bottom_line_button, #b2bking_myaccount_conversations_container_top button:hover, button:hover.b2bking_myaccount_start_conversation_button, .b2bking_myaccount_conversation_endpoint_button, button:hover.b2bking_bulkorder_form_container_bottom_add_button, button:hover.b2bking_subaccounts_container_top_button, button:hover.b2bking_subaccounts_new_account_container_content_bottom_button, button:hover.b2bking_subaccounts_edit_account_container_content_bottom_button, button:hover#b2bking_purchase_list_new_button, button:hover.b2bking_purchase_lists_view_list, .b2bking_myaccount_conversation_endpoint_button:hover, button#b2bking_reimburse_amount_button:hover, #b2bking_return_agent:hover{
				background: <?php echo esc_html( $colorhover ); ?>;
			}

			table#b2bking_purchase_lists_table thead tr th {
			    background: <?php echo esc_html( $purchase_lists_header ); ?>;
			    color: white;
			}
			.b2bking_purchase_lists_view_list {
			    background: <?php echo esc_html( $purchase_lists_action ); ?> !important;
			}
			#b2bking_purchase_list_new_button {
			    background: <?php echo esc_html( $purchase_lists_new ); ?> !important;
			}
			.b2bking_purchase_lists_view_list:hover, #b2bking_purchase_list_new_button:hover{
				filter: brightness(85%);
				filter: contrast(135%);
			}
			
		</style>

		<?php

		if (is_rtl()){
			// bulk order form RTL
			?>
			<style>
				.b2bking_cream_input_group button.b2bking_cream_input_minus_button.b2bking_cream_input_button {
				    margin-left: 0 !important;
				    margin-right: 4.3% !important;
				    border-right: 1px solid rgba(0, 0, 0, 0.2) !important;
				    border-left: 0px !important;
				    border-radius: 0px 4px 4px 0px !important;
				}
				.b2bking_cream_input_group button.b2bking_cream_input_plus_button.b2bking_cream_input_button {
				    margin-right: 0 !important;
				    margin-left: 4.3% !important;
				    border-left: 1px solid rgba(0, 0, 0, 0.2) !important;
				    border-right: 0px !important;
				    border-radius: 4px 0px 0px 4px !important;
				}
				.b2bking_cream_product_nr_icon {
				    right: 10px !important;
				    left: auto !important;
				}
				img.b2bking_bulkorder_indigo_image.b2bking_bulkorder_cream_image {
				    margin-right: auto !important;
				    margin-left: 19px !important;
				}
				.b2bking_bulkorder_form_container_content_header_cart_indigo {
				    padding-right: 5% !important;
				    padding-left: initial !important;
				}
				.b2bking_bulkorder_form_container_content_line_cart_indigo.b2bking_bulkorder_form_container_content_line_cart_cream {
				    right: 3.25% !important;
				    left: auto !important;
				}
				.b2bking_bulkorder_filter_header {
				    padding-right: 0px !important;
				}
			</style>
			<?php
		}
	}

	function force_permalinks_rewrite() {
	    // Trigger post types and endpoints functions
	    require_once ( B2BKING_DIR . 'admin/class-b2bking-admin.php' );
	    $adminobj = new B2bking_Admin;

	    $this->b2bking_custom_endpoints();
	    
	    if (apply_filters('b2bking_flush_permalinks', true)){
	    	// Flush rewrite rules
	    	flush_rewrite_rules();
	    }
	    
	}

	function enqueue_public_resources(){

		$user_data_current_user_id = get_current_user_id();

		$user_data_current_user_id = b2bking()->get_top_parent_account($user_data_current_user_id);

		// scripts and styles already registered by default
		wp_enqueue_script('jquery'); 

		wp_enqueue_script( 'jquery-ui' );
		wp_enqueue_script( 'jquery-ui-datepicker' );
		wp_enqueue_style( 'jquery-ui' );
		wp_enqueue_style( 'jquery-ui-datepicker' );


		if ( class_exists( 'WC_Frontend_Scripts' ) ) {
			$frontend_scripts = new \WC_Frontend_Scripts();
			$frontend_scripts::load_scripts();
		}

		// the following 3 scripts enable WooCommerce Country and State selectors
		if (intval(get_option( 'b2bking_disable_registration_scripts_setting', 0 )) === 0){
			if (apply_filters('b2bking_enable_registration_scripts_frontend', true)){
				if (apply_filters('b2bking_enable_country_scripts_frontend', true)){

					wp_enqueue_script( 'selectWoo' );
					wp_enqueue_style( 'select2' );
					wp_enqueue_script( 'wc-country-select' );

				}
				// activate password strength for my account custom pages
				wp_enqueue_script( 'wc-password-strength-meter' );
			}
		}

		// Checkout Blocks
		/*
		if (is_checkout()) {
	        wp_enqueue_script(
	            'b2bking-checkout-fields-blocks',
	            plugins_url('../includes/blocks/fields.js', __FILE__), // Adjust the path if you're using a plugin
	            array('wc-blocks-checkout',
                'wc-blocks-registry',
                'wc-settings',
                'wp-element',
                'wp-html-entities',
                'wp-i18n'),
	            $ver = B2BKING_VERSION, 
	            $in_footer =true
	        );
	    }
	    */

		if (B2BKING_FILE_RELEASE === 'DEV'){
			wp_enqueue_script('b2bking_public_script', plugins_url('assets/js/public.js', __FILE__), $deps = array(), $ver = B2BKING_VERSION, $in_footer =true);
			wp_enqueue_style('b2bking_main_style', plugins_url('../includes/assets/css/style.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);

			if (is_account_page() || b2bking()->is_marketplace_dashboard()){
				wp_enqueue_style('b2bking_sub_offers_conv', plugins_url('../includes/assets/css/style-sub-offers-conv.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);
			}

		} else {
			wp_enqueue_script('b2bking_public_script', plugins_url('assets/js/public.min.js', __FILE__), $deps = array(), $ver = B2BKING_VERSION, $in_footer =true);
			wp_enqueue_style('b2bking_main_style', plugins_url('../includes/assets/css/style.min.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);

			if (is_account_page() || b2bking()->is_marketplace_dashboard()){
				wp_enqueue_style('b2bking_sub_offers_conv', plugins_url('../includes/assets/css/style-sub-offers-conv.min.css', __FILE__), $deps = array(), $ver = B2BKING_VERSION);

			}
		}

		// only load for B2B users
		if (get_option( 'b2bking_plugin_status_setting', 'b2b' ) === 'b2b' || (get_option( 'b2bking_plugin_status_setting', 'b2b' ) === 'hybrid' && (get_user_meta( $user_data_current_user_id, 'b2bking_b2buser', true ) === 'yes'))){

			if (is_user_logged_in()){
				if (apply_filters('b2bking_load_datatables', true)){
					wp_enqueue_script('dataTables', plugins_url('../includes/assets/lib/dataTables/jquery.dataTables.min.js', __FILE__), $deps = array(), $ver = false, $in_footer =true);
					wp_enqueue_style( 'dataTables', plugins_url('../includes/assets/lib/dataTables/jquery.dataTables.min.css', __FILE__));
				}
			}			
		}


		// if offers shortcode is used
    
		// Get number of allowed countries and pass it to registration public.js 
		$countries = new WC_Countries;
		$countries_allowed = $countries->get_allowed_countries();
		$number_of_countries = count($countries_allowed);

		$add_cart_quantity_tiered_table = apply_filters('b2bking_add_cart_quantity_tiered_table', 1);
		// if table is clickable, do not add existing cart qty, to prevent confusion
		if(intval(get_option( 'b2bking_table_is_clickable_setting', 1 )) === 1){
			$add_cart_quantity_tiered_table = 0;
		}

		$enable_registration_fields_checkout = 1;
		if (is_checkout() && !apply_filters('b2bking_enable_registration_fields_checkout', true)){
			$enable_registration_fields_checkout = 0;
		}

		global $post;

		// Send display settings to JS
    	$data_to_be_passed = array(
    		'security'  => wp_create_nonce( 'b2bking_security_nonce' ),
    		'ajaxurl' => admin_url( 'admin-ajax.php' ),
    		'carturl' => wc_get_cart_url(),
    		'checkouturl' => wc_get_checkout_url(),
    		'currency_symbol' => get_woocommerce_currency_symbol(),
    		'conversationurl' => wc_get_account_endpoint_url(get_option('b2bking_conversation_endpoint_setting','conversation')), // conversation endpoint URL, for start conversation redirect
    		'subaccountsurl' => apply_filters('b2bking_subaccounts_endpoint_url_js', wc_get_account_endpoint_url(get_option('b2bking_subaccounts_endpoint_setting','subaccounts'))),
    		'purchaselistsurl' => wc_get_account_endpoint_url(get_option('b2bking_purchaselists_endpoint_setting','purchase-lists')),
    		'newSubaccountUsernameError' => esc_html__('Username must be between 8 and 30 characters, and cannot contain special characters. ','b2bking'),
    		'newSubaccountEmailError' => esc_html__('Email is invalid. ','b2bking'),
    		'newSubaccountPasswordError' => esc_html__('Password must have at least 8 characters, at least 1 letter and 1 number. ','b2bking'),
    		'newSubaccountAccountError' => esc_html__('Account creation error.','b2bking'),
    		'newSubaccountMaximumSubaccountsError' => esc_html__('You have reached the maximum number of subaccounts. ','b2bking'),
    		'are_you_sure_delete' => esc_html__('Are you sure you want to delete this subaccount?', 'b2bking'),
    		'are_you_sure_delete_list' => esc_html__('Are you sure you want to delete this purchase list?','b2bking'),
    		'no_products_found' => esc_html__('No products found...','b2bking'),
    		'no_products_found_img' => plugins_url('../includes/assets/images/no_products.svg', __FILE__),
    		'filters_close' => plugins_url('../includes/assets/images/close.svg', __FILE__),
    		'attributes' => plugins_url('../includes/assets/images/attributes.svg', __FILE__),
    		'filters' => plugins_url('../includes/assets/images/filter.svg', __FILE__),
    		'save_list_name' => esc_html__('Name for the new purchase list:', 'b2bking'),
    		'list_saved' => esc_html__('The list has been saved', 'b2bking'),
    		'add_to_list' => esc_html__('Add to list', 'b2bking'),
    		'product_added_to_list' => esc_html__('Added to list!', 'b2bking'),
    		'list_empty' => esc_html__('The list is empty', 'b2bking'),
    		'quote_request_success' => esc_html__('Your quote request has been received. We will get back to you as soon as possible.', 'b2bking'),
    		'custom_quote_request' => esc_html__('Custom Quote Request', 'b2bking'),
    		'max_items_stock' => esc_html__('There are only %s items in stock', 'b2bking'),
    		'send_quote_request' => apply_filters('b2bking_send_request_custom_quote_text', esc_html__('Send custom quote request', 'b2bking')),
    		'clearx' => esc_html__('Clear X', 'b2bking'),
    		'number_of_countries' => $number_of_countries,
    		'datatables_folder' => plugins_url('../includes/assets/lib/dataTables/i18n/', __FILE__),
    		'loaderurl' => plugins_url('../includes/assets/images/loader.svg', __FILE__),
    		'loadertransparenturl' => plugins_url('../includes/assets/images/loadertransparent.svg', __FILE__),
    		'purchase_lists_language_option' => get_option('b2bking_purchase_lists_language_setting','english'),
    		'accountingsubtotals' => get_option( 'b2bking_show_accounting_subtotals_setting', 0 ),
    		'bulkorderformimages'	=> intval(get_option( 'b2bking_show_images_bulk_order_form_setting', 1 )),
    		'validating' => esc_html__('Validating...', 'b2bking'),
    		'vatinvalid' => esc_html__('Invalid VAT. Click to try again', 'b2bking'),
    		'vatinvalidcountry' => esc_html__('VAT number doesn\'t match country. Try again.', 'b2bking'),
    		'vatvalid' => esc_html__('VAT Validated Successfully', 'b2bking'),
    		'validatevat' => esc_html__('Validate VAT', 'b2bking'),
    		'differentdeliverycountrysetting' => intval(get_option( 'b2bking_vat_exemption_different_country_setting', 0 )),
    		'myaccountloggedin' => (is_account_page() && is_user_logged_in()),
    		'colorsetting' => get_option( 'b2bking_color_setting', '#3AB1E4' ),
    		'ischeckout' => is_checkout(),
    		'quote_request_empty_fields' => esc_html__('Please fill all required fields to submit the quote request', 'b2bking'),
    		'quote_request_invalid_email' => esc_html__('The email address you entered is invalid', 'b2bking'),
    		'is_required' => esc_html__('is required', 'b2bking'),
    		'must_select_country' =>  esc_html__('You must select a country', 'b2bking'),
    		'disable_checkout_required_validation' => apply_filters('b2bking_disable_checkout_required_validation', 0),
    		'is_enabled_color_tiered' => get_option( 'b2bking_color_price_range_setting', 1 ),
    		'is_enabled_discount_table' => get_option( 'b2bking_show_discount_in_table_setting', 0 ),
    		'validate_vat_checkout' => get_option('b2bking_validate_vat_button_checkout_setting', 0),
    		'offer_details' => esc_html__('Offer details', 'b2bking'),
    		'offers_endpoint_link' => apply_filters('b2bking_offers_link', get_permalink( get_option('woocommerce_myaccount_page_id') ).get_option('b2bking_offers_endpoint_setting','offers')),
    		'offer_go_to'	=> esc_html__('-> Go to Offers', 'b2bking'),
    		'offer_custom_text' => esc_html__('Additional info', 'b2bking'),
    		'item_name' => esc_html__('Item', 'b2bking'),
    		'item_quantity' => esc_html__('Quantity', 'b2bking'),
    		'unit_price' => esc_html__('Unit price', 'b2bking'),
    		'item_subtotal' => esc_html__('Subtotal', 'b2bking'),
    		'offer_total' => esc_html__('Total', 'b2bking'),
    		'approve_order_confirm' => esc_html__('Are you sure you want to approve this order? The order will be pending payment.', 'b2bking'),
    		'reject_order_confirm' => esc_html__('Are you sure you want to reject this order? The order will be cancelled.', 'b2bking'),
    		'cancel_order_confirm' => esc_html__('Are you sure you want to cancel this order?', 'b2bking'),
    		'reject_order_email' => esc_html__('(Optional) Enter a rejection reason to be shown to the subaccount who placed the order.', 'b2bking'),
    		'offers_logo' => get_option('b2bking_offers_logo_setting',''),
    		'offers_images_setting' => get_option('b2bking_offers_product_image_setting', 0),
    		'quotes_enabled'	=> ($this->dynamic_replace_prices_with_quotes() === 'yes' || (get_option('b2bking_guest_access_restriction_setting', 'hide_prices') === 'replace_prices_quote') && (!is_user_logged_in() || (intval(get_option( 'b2bking_multisite_separate_b2bb2c_setting', 0 )) === 1 && get_user_meta($user_data_current_user_id, 'b2bking_b2buser', true) !== 'yes'))),
    		'quote_text'	=> esc_html__('Quote','b2bking'),
    		'add_indigo'	=> esc_html__('Add','b2bking'),
    		'add_more_indigo'	=> esc_html__('Add more','b2bking'),
    		'add_to_cart'	=> esc_html__('Add to cart','b2bking'),
    		'sending_please_wait'	=> esc_html__('Sending, please wait...','b2bking'),
    		'left_in_stock'	=> esc_html__('left in stock','b2bking'),
    		'already_in_cart' => esc_html__('Already in cart','b2bking'),
    		'left_in_stock_low_left'	=> esc_html__('Only ','b2bking'),
    		'left_in_stock_low_right'	=> esc_html__(' in stock!','b2bking'),
    		'price0' => wc_price(0),
    		'disable_username_subaccounts' => apply_filters('b2bking_disable_username_subaccounts', 1),
    		'cookie_expiration_days' => apply_filters('b2bking_validated_vat_cookie_expiration_days',1000),
    		'pdf_download_lang' => apply_filters('b2bking_pdf_downloads_language', 'english'),
    		'pdf_download_font' => apply_filters('b2bking_pdf_downloads_font', 'standard'),
    		'add_cart_quantity_tiered_table' => $add_cart_quantity_tiered_table,
    		'enable_payment_method_change_refresh' => apply_filters('enable_payment_method_change_refresh', 1),
    		'lists_zero_qty' =>  apply_filters('b2bking_purchase_lists_allow_zero_qty', 0),
    		'table_is_clickable' => intval(get_option( 'b2bking_table_is_clickable_setting', 1 )),
    		'approve_order_redirect_payment' => apply_filters('b2bking_approve_order_redirect_payment', 0),
    		'cream_form_cart_button' => get_option( 'b2bking_order_form_creme_cart_button_setting', 'cart' ),
    		'cream_multiselect_total' => apply_filters('b2bking_cream_multiselect_total', 'number'),
    		'bulkorder_is_product' => is_product() ? 'yes' : 'no',
    		'bulkorder_is_product_replace' => isset($post->ID) ? get_post_meta($post->ID, 'b2bking_variations_table_location', true) : 0,
    		'b2bking_orderform_skip_stock_search' => apply_filters('b2bking_order_form_skip_stock_search', 0),
    		'custom_content_center_1' => apply_filters('b2bking_custom_content_offer_pdf_center_1', ''),
    		'custom_content_center_2' => apply_filters('b2bking_custom_content_offer_pdf_center_2', ''),
    		'custom_content_left_1' => apply_filters('b2bking_custom_content_offer_pdf_left_1', ''),
    		'custom_content_left_2' => apply_filters('b2bking_custom_content_offer_pdf_left_2', ''),
    		'custom_content_after_logo_center_1' => apply_filters('b2bking_custom_content_after_logo_offer_pdf_center_1', ''),
    		'custom_content_after_logo_center_2' => apply_filters('b2bking_custom_content_after_logo_offer_pdf_center_2', ''),
    		'custom_content_after_logo_left_1' => apply_filters('b2bking_custom_content_after_logo_offer_pdf_left_1', ''),
    		'custom_content_after_logo_left_2' => apply_filters('b2bking_custom_content_after_logo_offer_pdf_left_2', ''),
    		'mention_offer_requester' => apply_filters('b2bking_mention_offer_requester', ''),
    		'loading_products_text' => esc_html__('Loading products...','b2bking'),
    		'enable_registration_fields_checkout' => $enable_registration_fields_checkout,
    		'offerlogowidth' => apply_filters('b2bking_offer_logo_width', 150),
    		'offerlogotopmargin' => apply_filters('b2bking_offer_logo_top_margin', 0),
    		'productid' => isset($post->ID) ? intval($post->ID) : 0,
    		'shopurl' => apply_filters('b2bkingking_login_subaccount_link',get_permalink( wc_get_page_id( 'shop' ) )),
    		'quote_without_message' => apply_filters('b2bking_quote_without_messaging', 0),
    		'offer_file_name' => apply_filters('b2bking_offer_file_name', 'offer'),
    		'redirect_cart_add_cart_classic_form' => apply_filters('b2bking_redirect_cart_add_cart_classic_form', 1),
    		'added_cart' => esc_html__('Add more products','b2bking'),
    		'force_step_1' => apply_filters('b2bking_force_step_1', 1),
    		'tiered_active_price_overwrite_range' => apply_filters('b2bking_tiered_active_price_overwrite_range', 0),
    		'quote_request_url_redirect' => apply_filters('b2bking_quote_request_url_redirect', ''),
    		'quote_request_success_message' => apply_filters('b2bking_quote_request_success_message', '1'),
    		'have_payment_method_rules' => apply_filters('b2bking_have_pmd_rules_publicjs', get_option('b2bking_have_pmd_rules', 'no')),
    		'tiered_table_use_lowest_quantity' => apply_filters('b2bking_tiered_table_use_lowest_quantity', 0),
    		'woo_price_decimals' => wc_get_price_decimals(),
    		'offers_rtl' => apply_filters('b2bking_offer_use_rtl', 0),
    		'bulkorder_first_search' => apply_filters('b2bking_bulkorder_initial_search', true) ? 1 : 0,
    		'added_cart_event' => apply_filters('b2bking_trigger_added_cart_event', false) ? 1 : 0, // changes because too many default issues
    		'form_enforce_qty' => apply_filters('b2bking_forms_enforce_qty', false) ? 1: 0,
    		'credit_text_translat1' => esc_html__('Available credit: ','b2bking'),
    		'credit_text_translat2' => esc_html__('Insufficient credit - your available credit is: ','b2bking'),
    		'credit_text_translat3' => esc_html__('You can ','b2bking'),
    		'credit_text_translat4' => esc_html__('redeem credits','b2bking'),
    		'credit_text_translat5' => esc_html__(' as a coupon.','b2bking'),
		);

		// order pay params
		global $wp;
		if ( isset($wp->query_vars['order-pay']) && absint($wp->query_vars['order-pay']) > 0 ) {
		    $order_id = absint($wp->query_vars['order-pay']); // The order ID
		    $payment_method = get_post_meta( $order_id, '_payment_method', true );
		    $order = wc_get_order( $order_id );
		    if ( $order ) {
		    	if ( $order->meta_exists( '_payment_method' ) ) {
		    		$payment_method = $order->get_meta( '_payment_method' );
		    	} else {
		    		$payment_method = $order->get_payment_method();
		    	}
		    }
		} else {
			$order_id = 0;
			$payment_method = 0;
		}
		$data_to_be_passed['orderid'] = $order_id;
		$data_to_be_passed['paymentmethod'] = $payment_method;




		$totalqty = 0;
		if (apply_filters('b2bking_tiered_pricing_uses_total_cart_qty', false)){
			foreach( WC()->cart->get_cart() as $cart_item ){
			    $totalqty += apply_filters('b2bking_tiered_pricing_count_total_qty', $cart_item['quantity'], $cart_item);
			}
		}

		// expose cart to frontend, for tiered pricing hover script
		$hoverarray = array();
		if (is_object( WC()->cart )){
		    foreach( WC()->cart->get_cart() as $cart_item ){
		    	if (isset($cart_item['variation_id']) && intval($cart_item['variation_id']) !== 0){
		    		$hoverarray[$cart_item['variation_id']] = $cart_item['quantity'];


		    		// if "sum up variations" is enabled, make the script get the total quantity of the product
		    		$possible_parent_id = wp_get_post_parent_id($cart_item['variation_id']);
		    		$sum_up_variations = 'no';
		    		if ($possible_parent_id !== 0){
		    			$sum_up_variations = get_post_meta( $possible_parent_id, 'b2bking_tiered_sum_up_variations', true );
		    		}
		    		if ($sum_up_variations === 'yes' && $possible_parent_id !== 0){
		    			$tempqty = 0;
		    			foreach( WC()->cart->get_cart() as $cart_item2 ){
		    				if ($cart_item2['variation_id'] === $cart_item['variation_id']){
		    					$tempqty += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item2['quantity'], $cart_item2['variation_id']);
		    				} else {
		    					if ($cart_item2['product_id'] === $possible_parent_id){
		    						$tempqty += apply_filters('b2bking_cart_item_quantity_tiers', $cart_item2['quantity'], $cart_item2['variation_id']);
		    					}
		    				}
		    			}

		    			$hoverarray[$cart_item['variation_id']] = $tempqty;

		    			// also get all other children (other variations and set qty as well)
		    			$product = wc_get_product($possible_parent_id);
		    			if ($product){
		    				$children = $product->get_children();
		    				foreach ($children as $child_id){
		    					$hoverarray[$child_id] = $tempqty;
		    				}
		    			}
		    		}
		    		// sum up variations end


		    	} else {
		    		$hoverarray[$cart_item['product_id']] = $cart_item['quantity'];
		    	}
		    }
		}
		$data_to_be_passed['cart_quantities'] = $hoverarray;
		$data_to_be_passed['cart_quantities_cartqty'] = $totalqty;


		// set purchase lists language for WPML
	 	if (defined('ICL_LANGUAGE_NAME_EN')){
	 		$data_to_be_passed['purchase_lists_language_option'] = ICL_LANGUAGE_NAME_EN;
	 	}

	 	$data_to_be_passed = apply_filters('b2bking_frontend_data', $data_to_be_passed);

		wp_localize_script( 'b2bking_public_script', 'b2bking_display_settings', $data_to_be_passed );
		
		
    }
    	
}

