Search code examples
phpwoocommercehook-woocommercecart

Sync custom product price by product category on cart items in Woocommerce


i have to arrange product price based on category . So every product in category A have price 5 , and in category B product price is 10 and in category c product price is 15 .

After this arrangement , when product is adding to cart , then i have to multiply product price by our margin . Currently our margin is 2.5.

So we write following codes in fucntions.php

add_filter('woocommerce_product_get_price', 'product_price_new', 10, 2);
 function product_price_new($price, $product) {
     if(!is_cart()){
     if(has_term( 'accessories', 'product_cat' ,$product->id)){  $price=5; }
     if(has_term( 'hoodies', 'product_cat' ,$product->id)){ $price=10; }
     if(has_term( 'tshirts', 'product_cat' ,$product->id)){ $price=15;}

     }
     return $price;
 }

add_filter( 'woocommerce_add_cart_item_data', 'margin_price', 30, 3 );
function margin_price( $cart_item_data, $product_id, $variation_id ) {
    $the_id = $variation_id > 0 ? $variation_id : $product_id;
    $product = wc_get_product( $the_id );
    $product_price = (float) $product->get_price(); 
    $cart_item_data['calculated-price'] = $product_price*2.5;
    return $cart_item_data;
}


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

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item ){
        if( ! empty( $cart_item['calculated-price'] ) ){
            // Set the calculated item price (if there is one)
            $cart_item['data']->set_price( $cart_item['calculated-price'] );

        }
    }
}

Please see what happen .

For example if we are trying to add product in category hoodies , so price will be , 10 *2.5=25

(1) in cart page product pric is showing 25 , and this is correct . [mywebsite.com/cart]

(2) In checkout page product price is showing 10, so the total is coming as 10 . This is wrong it should be 25 .

(3) In the minicart that showing near the menu , it showing 1*10 and subtotal is 10 , but it NEED to show 1 *25 and subtotal = 25

enter image description here

Please help to solve this issue . What i missed ?

i tried all this code in default woocommerce storfront theme . https://woocommerce.com/storefront/


Solution

  • Only for simple products, you can try the following instead:

    // Utility function
    function get_special_product_category_prices( $price, $product_id ) {
        // HERE your prices by product category
        $prices_by_cat = array( 5 => 'accessories', 10 => 'hoodies', 15 => 't-shirts' );
        foreach( $prices_by_cat as $key_price => $term ){
            if( has_term( $term, 'product_cat', $product_id ) )
                return $key_price;
        }
        return $price;
    }
    
    // Alter product displayed prices (for simple products only)
    add_filter( 'woocommerce_get_price_html', 'alter_displayed_price_html', 20, 2 );
    function alter_displayed_price_html( $price, $product ) {
    
        if( $product->is_type('simple') ){
            $raw_price = get_special_product_category_prices( $product->get_price(), $product->get_id() );
    
            if( $raw_price > 0 )
                $price = wc_price( wc_get_price_to_display( $product, array( 'price' => $raw_price ) ) );
        }
        return $price;
    }
    
    add_filter( 'woocommerce_add_cart_item_data', 'add_calculated_margin_price', 30, 3 );
    function add_calculated_margin_price( $cart_item_data, $product_id, $variation_id ) {
        $the_id = $variation_id > 0 ? $variation_id : $product_id;
        $product = wc_get_product( $the_id );
    
        $product_price = (float) get_special_product_category_prices( $product->get_price(), $product_id );
    
        $cart_item_data['calculated-price'] = $product_price * 2.5;
        return $cart_item_data;
    }
    
    add_action( 'woocommerce_before_calculate_totals', 'set_caculated_price', 20, 1 );
    function set_caculated_price( $cart ) {
        if ( is_admin() && ! defined( 'DOING_AJAX' ) )
            return;
    
        if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
            return;
    
        // Loop through cart items
        foreach ( $cart->get_cart() as $cart_item ){
            if( ! empty( $cart_item['calculated-price'] ) ){
                // Set the calculated item price (if there is one)
                $cart_item['data']->set_price( $cart_item['calculated-price'] );
            }
        }
    }
    

    Code goes in function.php file of your active child theme (or theme). It should work.