Задать вопрос
@Mircek

Как вывести общую сумму скидок в Woocommerce?

Всем привет. Очень рассчитываю на помощь зала, потому как сама уже голову сломала, пытаясь решить простую задачу. В интернет-магазине на Woocommerce есть гибкая система различных скидок:

1. Периодически появляющиеся скидки на отдельные товары;
2. Скидка 10% за заказ на общую сумму корзины 5000-7000 рублей;
3. Скидка 15% за заказ на общую сумму корзины более 7000 рублей;
4. Время от времени анонсируются купоны на дополнительную скидку к заказу.

Задача следующая: необходимо на страницах «Cart» и «Checkout» вывести общую сумму всех скидок, которыми воспользовался покупатель. Пример:

Cart Subtotal: $1000
Coupon: -$50
10% discount for 3 items in Cart: -$100
Order Total: $850
Saved: $150

На просторах интернета был найден следующий код:

function wc_discount_total_30() {
    global $woocommerce;
    $discount_total = 0;
    foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values) {
        $_product = $values['data'];
        if ( $_product->is_on_sale() ) {
            $regular_price = $_product->get_regular_price();
            $sale_price = $_product->get_sale_price();
            $discount = ($regular_price - $sale_price) * $values['quantity'];
            $discount_total += $discount;
        }
    }
    if ( $discount_total > 0 ) {
        echo '<tr class="cart-discount">
        <th>'. __( 'Saved', 'tsavedis' ) .'</th>
        <td data-title=" '. __( 'Saved', 'tsavedis' ) .' ">'
        . wc_price( $discount_total + $woocommerce->cart->discount_cart ) .'</td>
        </tr>';
    }
}

// Hook our values to the Basket and Checkout pages
add_action( 'woocommerce_cart_totals_after_order_total', 'wc_discount_total_30', 99);
add_action( 'woocommerce_review_order_after_order_total', 'wc_discount_total_30', 99);


С этим кодом две проблемы:

1. Он выводит сумму скидок на индивидуальные товары и скидку по купону, но не плюсует сюда скидку за большую сумму заказа. Скидку за большую сумму заказа получаю следующим кодом:

function woo_discount_total(WC_Cart $cart) {

 	$woo_current_price = $cart->subtotal; // Текущая итоговая сумма
	
	if($woo_current_price >= 5000 && $woo_current_price <= 7000) {
	
		$discount = $cart->subtotal * 0.10; // это 10%
		$cart->add_fee("Скидка в 10% за заказ на сумму от 5 000 до 7 000 рублей ", -$discount);
		
	} elseif($woo_current_price > 7000) {
	
		$discount = $cart->subtotal * 0.15; // это 15%
		$cart->add_fee("Скидка в 15% за заказ на сумму более 7 000 рублей ", -$discount);
	
	}

}

add_action("woocommerce_cart_calculate_fees" , "woo_discount_total");


2. Код выводит строку «Saved» только если в корзине есть хотя бы один товар с индивидуальной скидкой на него. Если удалить этот товар из корзины, оставив только товары без скидок, то этот код не выводит строку «Saved» вообще. Получилось обойти это, убрав условие:

if ( $discount_total > 0 )

Строка теперь выводится в любом случае — вне зависимости от того, есть ли хотя бы один товар со скидкой в корзине или нет.

Из двух проблем осталась только одна — как приплюсовать ещё вывод скидки за большую сумму заказа. Вообще самым простым и логичным способом решения задачи вижу вычесть сумму «Order Total» из «Cart Subtotal», и получить таким образом сумму всех применённых к заказу скидок, но хоть убейте, не могу найти информацию как это сделать. Может у кого есть идеи?
  • Вопрос задан
  • 2135 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Mircek Автор вопроса
UPD: проблему решила сама. Оставляю решение — вдруг у кого-то будет та же задача. В коде заменила

. wc_price( $discount_total + $woocommerce->cart->discount_cart ) .

на
. wc_price( $woocommerce->cart->subtotal - $woocommerce->cart->total + $woocommerce->cart->shipping_total + $discount_total ) .
.

Что делает новая строка:
$woocommerce->cart->subtotal - $woocommerce->cart->total — вычитаем из суммы всех товаров итоговую сумму заказа после применения всех скидок
+ $woocommerce->cart->shipping_total — добавляем стоимость доставки (если этого не сделать, то стоимость доставки вычтется из суммы сэкономленных денег)
+ $discount_total — добавляем сумму индивидуальных скидок на товары (если какой-то товар обычно стоит 1000 руб., но сейчас он на распродаже и стоит 800 руб., то эти 200 рублей тоже нужно учесть как сэкономленные).

И добавляем условие выводить строку «Вы сэкономили: N руб.» только в том случае, если «сумма товаров + доставка» больше, чем «сумма заказа с учётом всех скидок + доставка» или если в заказе есть товар(ы) с индивидуальной скидкой.

if ( $woocommerce->cart->subtotal + $woocommerce->cart->shipping_total > $woocommerce->cart->total + $woocommerce->cart->shipping_total || $discount_total > 0 )


Весь готовый код выглядит так (вставлять в functions.php дочерней темы):

function wc_discount_total_30() {
 
    global $woocommerce;
      
    $discount_total = 0;
      
    foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values) {
          
   $_product = $values['data'];
  
        if ( $_product->is_on_sale() ) {
        $regular_price = $_product->get_regular_price();
        $sale_price = $_product->get_sale_price();
        $discount = ($regular_price - $sale_price) * $values['quantity'];
        $discount_total += $discount;
        }
  
    }    
            
if ( $woocommerce->cart->subtotal + $woocommerce->cart->shipping_total > $woocommerce->cart->total + $woocommerce->cart->shipping_total || $discount_total > 0 ) {
	    
    echo '<tr class="cart-discount">
    <th>'. __( 'Вы сэкономили:', 'woocommerce' ) .'</th>
    <td data-title=" '. __( 'Saved', 'woocommerce' ) .' ">' 
    . wc_price( $woocommerce->cart->subtotal - $woocommerce->cart->total + $woocommerce->cart->shipping_total + $discount_total ) .'</td>
    </tr>';
}    
 
}
 
// Hook our values to the Basket and Checkout pages
 
add_action( 'woocommerce_cart_totals_after_order_total', 'wc_discount_total_30', 99);
add_action( 'woocommerce_review_order_after_order_total', 'wc_discount_total_30', 99);


Решение может быть не самое изысканное, но рабочее (проверено).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы