Обновление 3
Плагин и ваш код устарели, с некоторыми ошибками и ошибками. В приведенном ниже коде я использую другой способ с ajax и WC_Session
.
Поведение «Ставка налога» для введенных продуктов, включая налоги.
Чтобы сделать любой код, который манипулирует налоговыми ставками, эффективными, цены на товары должны быть введены без учета налогов. Если нет, требуется дополнительный код, чтобы захватить цену товара без учета налогов в качестве данных пользовательской корзины, чтобы сделать налог с нулевой ставкой эффективным.
Я добавил пользовательскую функцию, частично скопированную из кода плагина, которая добавляет поле выбора извлечения billing_timologio
, чтобы сделать код тестируемым.
Также кнопка добавления в корзину ajax заменяется кнопкой, связанной с отдельными страницами продуктов для определенных категорий продуктов, поскольку мы добавляем цену продукта без учета налогов в качестве данных пользовательской корзины.
Код (только для Woocommerce версии 3.3 +):
// Your product categories settings
function get_my_terms(){
return array( 'clothing' );
return array( 222, 228, 231 );
}
// Change add to cart ajax button to a button linked to single product pages for specific product categories
add_filter( 'woocommerce_loop_add_to_cart_link', 'conditionally_replace_add_to_cart', 10, 2 );
function conditionally_replace_add_to_cart( $html, $product ) {
if ( has_term( get_my_terms(), 'product_cat', $product_id ) && $product->is_type('simple') ) {
// Set HERE your button link
$link = get_permalink($product_id);
$text = __("Read More", "woocommerce");
$html = '<a href="' . $link . '" class="button alt add_to_cart_button">' . $text . '</a>';
}
return $html;
}
// Adding a custom checkout select field
add_filter( 'woocommerce_billing_fields', 'custom_billing_fields', 20, 1 );
function custom_billing_fields($billing_fields) {
$billing_fields['billing_timologio'] = array(
'type' => 'select',
'label' => __('INVOICE'),
'placeholder' => _x('INVOICE', 'placeholder'),
'required' => false,
'class' => array('form-row-wide'),
'clear' => true,
'options' => array(
'N' => __('No'),
'Y' => __('Yes'),
),
'value' => '',
);
return $billing_fields;
}
// The jQuery Ajax script
add_action( 'wp_footer', 'custom_checkout_script' );
function custom_checkout_script() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
// Removing WC_Session "
if( WC()->session->__isset('billing_timologio') ){
WC()->session->__unset('billing_timologio');
}
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
// On load reset value to 'N'
$('#billing_timologio_field select').val('N');
// On change (Ajax)
$('#billing_timologio_field select').change( function () {
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'get_ajax_billing_timologio',
'b_timologio': $(this).val() == 'Y' ? 1 : 0,
},
success: function (result) {
$('body').trigger('update_checkout');
}
});
});
});
</script>
<?php
endif;
}
// The Wordpress Ajax receiver
add_action( 'wp_ajax_get_ajax_billing_timologio', 'get_ajax_billing_timologio' );
add_action( 'wp_ajax_nopriv_get_ajax_billing_timologio', 'get_ajax_billing_timologio' );
function get_ajax_billing_timologio() {
if ( $_POST['b_timologio'] == '1' ){
WC()->session->set('billing_timologio', '1');
} else {
WC()->session->set('billing_timologio', '0');
}
die();
}
// Save the product price excluding tax as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_price_excl_vat_as_custom_cart_item_data', 20, 3);
function add_price_excl_vat_as_custom_cart_item_data( $cart_item_data, $product_id, $variation_id ) {
if ( ! wc_prices_include_tax() )
return $cart_item_data;
$_product_id = $variation_id > 0 ? $variation_id : $product_id;
$product = wc_get_product($_product_id); // The WC_Product Object
// Save the price excluding tax as custom cart item data
if( has_term( get_my_terms(), 'product_cat', $product_id ) ) {
$cart_item_data['price_excl_tax'] = wc_get_price_excluding_tax( $product, array( 'price' => $product->get_price() ) );
}
return $cart_item_data;
}
// Changing conditionally specific items tax rate
add_action( 'woocommerce_before_calculate_totals', 'zero_tax_items_based_on_invoice_choice', 30, 1 );
function zero_tax_items_based_on_invoice_choice( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item ) {
// Check for product categories and enabled "billing_timologio" field
if( has_term( get_my_terms(), 'product_cat', $cart_item['product_id'] ) && WC()->session->get('billing_timologio') ){
// Set the item tax rate to "Zero rate"
$cart_item['data']->set_tax_class('Zero Rate');
// Set price excluding taxes
if( isset($cart_item['price_excl_tax']) ){
$cart_item['data']->set_price($cart_item['price_excl_tax']);
}
}
}
}
Код помещается в файл function.php вашей активной дочерней темы (или активной темы). Проверено и работает.
На полученных заказах, страницах просмотра заказа и (администратора) редактирования, налог будет установлен на «Нулевую ставку» для определенных позиций, когда клиент выбрал «Да» для «СЧЕТА-ВЫПЛАТЫ» ( ΤΙΜΟΛΟΓΙΟ).
Цена соответствующего продукта, оставшаяся для определенных категорий продуктов будет иметь на этот раз правильную цену без учета налогов …
Оригинальный ответ.
Мне кажется, что есть 2 ошибки:
- Первый -
$product->id
, который должен быть заменен на $product->get_id()
- Во-вторых, вам нужно поставить внутреннюю функцию снаружи
Также код может быть упрощен.
Без каких-либо гарантий, поскольку ваш код не может быть протестирован на самом деле, попробуйте это вместо:
add_action( 'woocommerce_checkout_update_order_review', 'tfwc_taxexempt_checkout_based_invoice_choice' );
function tfwc_taxexempt_checkout_based_invoice_choice( $post_data ) {
WC()->customer->set_is_vat_exempt( false );
parse_str($post_data);
if ( $billing_timologio == 'Y' )
add_filter( 'woocommerce_product_get_tax_class', 'wc_diff_rate_for_user', 1, 2 );
}
}
function wc_diff_rate_for_user( $tax_class, $product ) {
// Checking for specific product categories
if( has_term( array(228,231,222), 'product_cat', $product->get_id() ) ) {
return 'Zero Rate';
}
return $tax_class;
}
Надеюсь, это сработает.