Показывать цены за месяц в подписках Woocommerce - PullRequest
1 голос
/ 06 марта 2019

У меня есть три продукта подписки: раз в год, раз в полгода и раз в месяц. По умолчанию цены указаны за год, за каждые 6 месяцев и за месяц на странице моего магазина.

На основе " Изменение цены товара с помощью хука в коде ответа WooCommerce 3 " , я пытаюсь отобразить все цены за месяц, поэтому изменить отображение цены на основе срок подписки:

// Utility function to change the prices with a multiplier (number)
function get_price_multiplier($var_product) {
    switch($var_product) {
        case 111:
            // Annual
            return 12;
            break;
        case 222:
            // Semiannual
            return 6;
            break;
        case 333:
            // Month
            return 1;
            break;          
        default:
            return 1;
            break;
    }
}

add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
function custom_price( $price, $product ) {
    $var_product = $product->get_id();
    return $price / get_price_multiplier($var_product);
}

Это сработало, но когда товар добавлен в корзину, цена - это не обычная цена, а измененная цена из функции выше.

На основе " Установить программную цену продажи товара и цены на товары в корзине в Woocommerce 3 " код ответа, я смог исправить это:

add_action( 'woocommerce_before_calculate_totals', 'set_cart_item_sale_price', 20, 1 );
function set_cart_item_sale_price( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

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

    // Iterate through each cart item
    foreach( $cart->get_cart() as $cart_item ) {
        $regular_price = $cart_item['data']->get_regular_price();
        $variation_id = $cart_item['variation_id'];
        $cart_item['data']->set_price( $regular_price * get_price_multiplier($variation_id) );
    }
}

Это сбрасывает цену корзины, и кажется, что она работает, хотя одна из цен снижается на копейку.

Это все запутанно и склонно к проблемам или это надежный способ добиться того, что я хочу: показать цену за подписку на странице магазина?

1 Ответ

1 голос
/ 06 марта 2019

Вы делаете это правильно ... Есть 2 способа (последний самый лучший):

Примечание: Расчет и изменение цены не нужны, если множитель равен 1.

1) Первый вариант: Улучшенная версия кода, очень похожая на вашу.

Вот мой прокомментированный код:

// Utility function that increase conditionally the variation price with a multiplier (int)
function get_variation_calculated_price( $variation_id, $price, $multiplier = true ) {
    switch( $variation_id ) {
        case 111: // Annual
            $rate = 12;
            break;

        case 222: // Semi-annual
            $rate = 6;
            break;

        default: // Month (and others)
            $rate = 1;
            break;
    }
    // Return calculated price (or false when multiplier is 1, as calculation is not needed)
    return $rate !== 1 ? ( $multiplier ? $price * $rate : $price / $rate ) : false;
}


// Change variations calculated prices
add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
function custom_price( $price, $variation ) {
    if( $new_price = get_variation_calculated_price( $variation->get_id(), $price, false ) )
        return $new_price;

    return $price;
}

// Customizing cart item prices
add_action( 'woocommerce_before_calculate_totals', 'set_cart_item_sale_price', 20, 1 );
function set_cart_item_sale_price( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    // Required since Woocommerce version 3.2 for cart items properties changes
    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    // Loop  through cart items
    foreach( $cart->get_cart() as $cart_item ) {
        // Only for variations
        if( $cart_item['variation_id'] > 0 ) {
            if( $new_price = get_variation_calculated_price( $cart_item['variation_id'], $cart_item['data']->get_price() ) ) {
                $cart_item['data']->set_price( $new_price );
            }
        }
    }
}

Код помещается в файл function.php вашей активной дочерней темы (или активной темы). Проверено и работает.


2) Второй вариант: гораздо точнее и легче, ограничивая цену товара, избегая изменения цены на корзину, кассу и бэкэнд.

Примечание: Вам нужно будет избегать отображения перекрестных продаж товаров на странице корзины (так как цены не будут изменены, как на странице магазина).

Таким образом, код будет более легким, компактным и эффективным:

// Utility function that increase conditionally the variation price with a multiplier (int)
function get_variation_calculated_price( $variation_id, $price ) {
    switch( $variation_id ) {
        case 111: // Annual
            $rate = 12;
            break;

        case 939: // Semi-annual
            $rate = 6;
            break;

        default: // Month (and others)
            $rate = 1;
            break;
    }
    // Return calculated price (or false when multiplier is 1, as calculation is not needed)
    return $rate !== 1 ? $price / $rate : false;
}


// Change variations calculated prices
add_filter('woocommerce_product_variation_get_price', 'custom_price', 99, 2 );
function custom_price( $price, $variation ) {
    // Not in cart, checkout and admin
    if( is_cart() || is_checkout() || is_admin() ) 
        return $price;

    if( $new_price = get_variation_calculated_price( $variation->get_id(), $price ) )
        return $new_price;

    return $price;
}

Код помещается в файл function.php вашей активной дочерней темы (или активной темы). Проверено и работает.

...