Abilash Erikson
Abilash Erikson

Reputation: 351

Add as separate cart items for a product with custom data in Woocommerce

Hi currently i have a custom form on each product on frontend . Here customer can insert custom width and height as per this price will change

For this i write the following code, and it's working

add_filter( 'woocommerce_add_cart_item', 'add_custom_cart_item_data', 10, 2 );
function add_custom_cart_item_data( $cart_item_data, $cart_item_key ) {

    if( isset( $_POST['new-width'] ) )
        $cart_item_data['new-width'] = $_POST['new-width'];
    if(isset( $_POST['new-height'] ) )
       $cart_item_data['new-height'] = $_POST['new-height'];

    return $cart_item_data;
}


add_action( 'woocommerce_before_calculate_totals', 'set_custom_cart_item_price', 10, 1 );
function set_custom_cart_item_price( $wc_cart ) {

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

    foreach ( $wc_cart->get_cart() as $cart_item ){
        if( ! empty($cart_item['new-width']) && ! empty($cart_item['new-height']) ){
            $new_value=$cart_item['new-width']*$cart_item['new-height'];
            $cart_item['data']->set_price($new_value);
            }
    } 
}

Now the problem i face is

Customer added the product1 to the cart with width=30 and height=30. so the total price is 30*30=90 [based on $cart_item['new-width']*$cart_item['new-height'] ] and customer add the same product1 with width=40 and height=40 . as per my formula the price will become 40*40=160 . and total price in checkout should be 160+90=250 But what i get is 90+90=180

in checkout page what i need is

(1)product-1(width=30, height=30)  90
(2)product-1(width=40, height=40)  160
total 250

But currently it showing

(1)product-1(width=30, height=30)  90  qty(2)

total 180

Please help

Upvotes: 2

Views: 1142

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 254373

Updated (October 2018)

First you should better use woocommerce_add_cart_item_data hook instead, this way to get different items:

add_filter( 'woocommerce_add_cart_item_data', 'save_custom_fields_data_to_cart', 10, 2 );
function save_custom_fields_data_to_cart( $cart_item_data, $product_id ) {
    $data = array();

    // Set the custom data in the cart item
    if( isset( $_POST['new-height'] ) && ! empty( $_POST['new-height'] ) 
    && isset( $_POST['new-height'] ) && ! empty( $_POST['new-height'] ) )
    {
        // Save the new calculated price as cart item custom data
        $cart_item_data[custom_data]['price']  = $_POST['new-width'] * $_POST['new-height'];

        // Save 'new-width' and 'new-height' as cart item custom data (if needed)
        $cart_item_data[custom_data]['width']  = $_POST['new-width'];
        $cart_item_data[custom_data]['height'] = $_POST['new-height'];

        // Every add to cart action is set as a unique line item
        $cart_item_data[custom_data]['unique_key'] = md5( microtime().rand() );
    }
    return $cart_item_data;
}

Then with some little changes:

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

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

    foreach ( $cart->get_cart() as $cart_item ){
        if( isset( $cart_item['custom_data']['price'] ) && ! empty( $cart_item['custom_data']['price'] ) ){
            $cart_item['data']->set_price( $cart_item['custom_data']['price'] );
        }
    }
}

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

tested and works

Note: 30 x 30 is not 90 but it is 900 and 40 x 40 is not 160 but it is 1600

Upvotes: 2

Related Questions