На просторах интернета я нашел код который меняет цену товара на фиксированную без каких-либо условий.
И вышло что-то на подобии этого:
// Adding a wholesale price for items
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 20, 1);
function add_custom_price( $cart ) {
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Avoiding hook repetition (when using price calculations for example)
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Get order subtotal
$order_subtotal = WC()->cart->get_cart_subtotal();
if ( $order_subtotal >= 2000 ) {
foreach ( $cart->get_cart() as $item ) {
// Значение set_price нужно будет заменить на id кастомной цены, если всё заработает
$item['data']->set_price( 150.6 );
}
}
}
Тут для проверки роботоспосоности я просто изменяю цену товаров к корзине на фиксированную.
Но при сохранении functions.php с этим кодом, сайт выдаёт ошибку при попытке добвления товара к корзину. Это происходит если я сравниваю подытог корзины с нужной мне суммой (при условии 1 == 1 всё работает). Также я не уверен что правильно получаю значение
$order_subtotal
.
Даже при условии что код заработает как должет, будет ли присваиваться определённому товару конкретно его кастомная цена.
UPD:
Я начал проверять значение
$order_subtotal
через
echo
, но мне постоянно выдавало что оно равно 0 (нуль или ноль?). Не понимая что присходит я немного впал в отчаянне. Но. НО. После я заметил что в
add_action
написано
woocommerce_before_calculate_totals
. Хахахах. Всё было так просто. Там написано before. Это BEFORE. Т.е до подсчёта суммы. Лёгкими нажатиями своими пальчиками я заменил этот никчёмный "before" на нужный мне "after". И боги, оно заработало. Я начал видеть правильный мне подытог корзины.
После я понял что если получать нужное мне значение через использывание
get_cart_subtotal()
, то я получаю сумму в виде строки со знаком валюты, а если использывать
get_subtotal()
мы получаем уже тип float, который можно использывать для конструкции if.
Сейчас код имеет такой вид:
// Adding a wholesale price for items
add_action( 'woocommerce_after_calculate_totals', 'add_custom_price', 20, 1);
function add_custom_price( $cart ) {
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Avoiding hook repetition (when using price calculations for example)
if ( did_action( 'woocommerce_after_calculate_totals' ) >= 2 )
return;
if ( WC()->cart->get_subtotal() >= 2000 ) {
foreach ( $cart->get_cart() as $item ) {
$item['data']->set_price( 150.6 );
}
}
}
P.S Пока редактировал текст заметил что когда подытог становится больше чем нужно (т.е условие выполняется) и товар преобретает нужную цену, конечый итог считает по старой цене. Буду думать дальше
P.S 2 Я понял почему так происходит. Я задаю условие при котором цена товара задаётся уже после подсчёта суммы корзины и поэтому он считает по стандартному прайсу.
UPS 2
Дыыыы. Оно работает так как надо. Так как хотел того именно я.
Код:
// Adding a wholesale price for items
add_action( 'woocommerce_after_calculate_totals', 'add_custom_price', 20, 1);
function add_custom_price( $cart ) {
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Avoiding hook repetition (when using price calculations for example)
if ( did_action( 'woocommerce_after_calculate_totals' ) >= 2 )
return;
// Adding a custom price for items
if ( WC()->cart->get_subtotal() >= 2000 ) {
foreach ( $cart->get_cart() as $item ) {
$item['data']->set_price( 150.6 );
}
}
// Recount cart total
WC()->cart->calculate_totals();
// Wrong minimum amount protection
if ( WC()->cart->get_subtotal() < 2000 ) {
foreach ( $cart->get_cart() as $item ) {
$regular_price = $item['data']->get_regular_price();
$item['data']->set_price( $regular_price );
}
}
// Recount cart total
WC()->cart->calculate_totals();
}
А теперь по порядку. Во первых я не знал как пересчитать итоговую стоимость корзины с изменёнными ценами. у мена была идея которой я придерживался. Уже и не хочу думать как я бы это сделал, потому что уже голова болит от этого. Но суть именно в том как я начал это делать. Я добавил переменную
$ca = WC()->cart->calculate_totals()
. В попытках проверить не виснит ли сайт от такой логики при перезагрузки я не увидил сообщение о том что "Возникла ошибка. Поробуйте в другой раз." (Это уже очень радовало). Я решил попробывать изменить количесто товара. И именно тут я заметил что корзина пересчитывает итогувую сумму по новой, заданной мной, цене. ОоОООООООО. Я перекрестился и сказал чпасибо себе за то что я такой классный. После я оставил только
WC()->cart->calculate_totals()
, что также работало исправно.
Понимая что смена цены работает только в одну сторону, я добавил вторую конструкцию if только с обратным условием. Фиксированную цену заменил на
$regular_price = $item['data']->get_regular_price()
и также добавил перерасчет суммы корзины после.
Это моя лична маленькая победа над которой я очень горжусь, ведь до этого момента я не имел дело с php от слова вообще. Осталось только добавить оптовую цену, указать её в моём мальком коде и всё. На этом мои мучения закончены.