Home > Software engineering >  Issue with changing WooCommerce cart item prices based on product meta
Issue with changing WooCommerce cart item prices based on product meta

Time:04-29

When the product subtotal is more than 3000, it has to be another price.

I added it as a meta field to products. On Stack Overflow, a long time ago someone advised me the filter for a special price called woocommerce_cart_item_name

I modified it a little for my purpose:

function kia_add_subtitle_to_cart_product( $title, $cart_item ){
    $threshold = 3000; // Change price if > 3000
    $_product = $cart_item['data'];
    $meta     = $_product->get_meta( '_opt_price_var');
    $price = $_product->get_regular_price();
    $subtotal = $cart_item['quantity'] * $price;
    if (  $subtotal > $threshold && ( $meta )) {            
        $_product->set_price( $meta );       
    }
    echo $title;
}

add_filter( 'woocommerce_cart_item_name', 'kia_add_subtitle_to_cart_product', 10, 2 );

The special price is showing only in the cart form, but not in cart totals and not in the checkout, in totals and in checkout the price is still regular, the main calculator doesn't take it from this filter.

How can I fix it? How to include it in the main calculator too?

I tried different hooks that can be responsive for the calculator - both add_action and add_filter, with and without 10, 2 - it isn't it.

add_action('woocommerce_before_shipping_calculator', 'kia_add_subtitle_to_cart_product',10,2);

add_action('woocommerce_before_cart_totals', 'kia_add_subtitle_to_cart_product', 10, 2 );

CodePudding user response:

The woocommerce_cart_item_name hook is being misused in your code attempt. A filter hook should always return something compared to the use of echo.

You should use the woocommerce_before_calculate_totals hook instead

So you get:

function action_woocommerce_before_calculate_totals( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;
    
    // Change price if > 3000
    $threshold = 3000;

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item ) {
        // Get regular price
        $price = $cart_item['data']->get_regular_price();

        // Subtotal = Get quantity * price
        $subtotal = $cart_item['quantity'] * $price;

        // Greater than  
        if ( $subtotal > $threshold ) {
            // Get meta
            $meta = $cart_item['data']->get_meta( '_opt_price_var', true );

            // NOT empty
            if ( ! empty ( $meta ) ) {
                // Set new price
                $cart_item['data']->set_price( $meta );
            }
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );

CodePudding user response:

add_filter('woocommerce_calculated_total', 'custom_calculated_total', 10, 2);

function custom_calculated_total($total, $cart_object) {

        if (is_admin() && !defined('DOING_AJAX'))
            return;

        if (!WC()->cart->is_empty()):
            foreach ($cart_object->cart_contents as $key => $cart_item) {
                $meta = $cart_item['data']->get_meta('_opt_price_var');

                if ($total >= 3000 && ( $meta )) {

                    $total = $meta;
                }
            }
        endif;
        return $total;
}
  • Related