Вопрос или проблема
Мы продаем комбинацию нескольких продуктов как один продукт, эти продукты нельзя добавлять отдельно в WordPress, поэтому мы используем обычный тип продукта для комбинации.
Эти продукты имеют отдельные налоговые классы (части по 9% и 21%), поэтому я создал плагин для сохранения двух налоговых значений как мета-значений.
Когда я размещаю заказ, я сохраняю настраиваемое мета-поле с элементом заказа со средним налогом, рассчитанным (например, 15%).
В функции calculate_taxes я могу получить это мета-значение и использовать его для расчета правильного налога, но когда я это делаю, я перезаписываю основной файл, и я не хочу этого из-за обновлений.
Как мне переопределить функцию calculate_taxes?
Я также пытался использовать фильтр woocommerce_find_rates, но не знаю, могу ли я получить элемент заказа внутри этого фильтра, иначе я могу использовать этот фильтр.
ИЗМЕНЕНИЕ:
Код, который я использую для добавления настраиваемого налога в woocommerce/includes/class-wc-order-item.php
<?php
public function calculate_taxes( $calculate_tax_for = array() ) {
if ( ! isset( $calculate_tax_for['country'], $calculate_tax_for['state'], $calculate_tax_for['postcode'], $calculate_tax_for['city'] ) ) {
return false;
}
if ( '0' !== $this->get_tax_class() && 'taxable' === $this->get_tax_status() && wc_tax_enabled() ) {
$calculate_tax_for['tax_class'] = $this->get_tax_class();
$tax_rates = WC_Tax::find_rates( $calculate_tax_for );
/* ЧАСТЬ НАСТРОЙКИ */
foreach ($tax_rates as $k => $t) {
if (!empty($this->get_meta('_line_tax_rate'))) $t['rate'] = $this->get_meta('_line_tax_rate');
$tax_rates[$k] = $t;
}
/* КОНЕЦ ЧАСТИ НАСТРОЙКИ */
$taxes = WC_Tax::calc_tax( $this->get_total(), $tax_rates, false );
if ( method_exists( $this, 'get_subtotal' ) ) {
$subtotal_taxes = WC_Tax::calc_tax( $this->get_subtotal(), $tax_rates, false );
$this->set_taxes(
array(
'total' => $taxes,
'subtotal' => $subtotal_taxes,
)
);
} else {
$this->set_taxes( array( 'total' => $taxes ) );
}
} else {
$this->set_taxes( false );
}
do_action( 'woocommerce_order_item_after_calculate_taxes', $this, $calculate_tax_for );
return true;
}
вы можете перезаписать вывод, используя фильтр woocommerce_find_rates
Ответ или решение
Для изменения ставки налога в WooCommerce программно без изменения исходных файлов, вы можете воспользоваться хуками и фильтрами, которые предоставляет WooCommerce. В вашем случае, вы уже на правильном пути, пробуя использовать фильтр woocommerce_find_rates
.
Подход с использованием фильтра woocommerce_find_rates
Фильтр woocommerce_find_rates
позволяет вам модифицировать ставки налога, получаемые при расчете налогов для заказов. Таким образом, вы можете использовать этот фильтр для добавления вашей логики обработки налога на основе пользовательских метаполей.
Вот пример кода, который показывает, как можно использовать фильтр woocommerce_find_rates
для изменения ставки налога на основе значения метаполя:
add_filter('woocommerce_find_rates', 'custom_find_tax_rates', 10, 2);
function custom_find_tax_rates($rates, $args) {
// Получаем ID продукта или заказа, если это необходимо.
// Предположим, что вы передали ID продукта в args.
$product_id = isset($args['product_id']) ? $args['product_id'] : null;
if ($product_id) {
// Получаем ваше пользовательское мета значение
$line_tax_rate = get_post_meta($product_id, '_line_tax_rate', true);
// Если метаполе существует и не пустое, переопределяем ставку налога
if (!empty($line_tax_rate)) {
foreach ($rates as $key => $rate) {
// Применяем вашу пользовательскую налоговую ставку
$rates[$key]['rate'] = $line_tax_rate;
}
}
}
return $rates;
}
Примечания к коду:
- Убедитесь, что
_line_tax_rate
– это правильно установленное метаполе для продукта или заказа. Если используете другой ключ, замените его в коде на ваш. - Вы можете получить
$product_id
через массив$args
. Например, если вы работаете с элементом заказа, вы можете передать ID продукта вwoocommerce_order_item_after_calculate_taxes
для возможности получения его в фильтре. - Этот код необходимо поместить в файл вашего плагина или в файл
functions.php
вашей темы.
Дополнительный совет:
Если у вас есть сложные расчеты налогов, которые необходимо произвести, вы также можете создать собственный метод для расчетов и использовать его в нужных местах, а не переписывать классы WooCommerce.
Заключение
Использование фильтров, таких как woocommerce_find_rates
, является надёжным и безопасным способом изменения логики расчета налогов в WooCommerce, без изменения ядра плагина. Это позволит вам сохранить совместимость с будущими обновлениями WooCommerce и обеспечит более стабильную работу вашего сайта.