Albert
Albert

Reputation: 45

Change price from a product variantion if corresponding product variantion is in WooCommerce cart

I have a series of products that have a variant 'A' and a variant 'B'.

I would need to make sure that when the variant 'A' of a product is present in the cart the variant 'B' of the same product is discounted by 15%.

The variant to be discounted is always 'B' because 'A' would already be discounted.

I tried with this code but it only works for one product and I have several products, plus this code has a poblem, if I first enter the product 'B' and then the product 'A' the price of product 'B' is not recalculated.

function woo_in_cart( $disc_product_id ) {
    global $woocommerce;


    if ( ! isset( $disc_product_id ) ) {
    return false;
     }


foreach ( $woocommerce->cart->get_cart() as $cart_myitem ) {
    if ( $cart_myitem['variation_id'] === $disc_product_id ) {
        return true;
    } else {
        return false;
         }
    }
    }
add_action( 'woocommerce_before_calculate_totals', 'webroom_change_price_of_product' );

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

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

    $target_product_id = 3161; // PRODUCT ID TO DISCOUNT

    if(woo_in_cart(3162)!=0) {
         foreach ( $cart->get_cart() as $cart_item ) {
             if ( ($disc_product_id-1) == $cart_item['variation_id'] ){
                 // Set your price
                 $price =round($cart_item['data']->price*((100-15) / 100), 2);
        
                 $cart_item['data']->set_price( $price ); 
        
             }
    
        }
    }
}

Any help will be appreciated!

Upvotes: 1

Views: 309

Answers (1)

7uc1f3r
7uc1f3r

Reputation: 29624

The first piece of code will ensure that an extra checkbox appears for each variant.

  • The intention is that this is used with variable products that only contain 2 variants (A & B variant)
  • That the checkbox is checked for 1 of the 2 variants, which will stand for the 'A variant'
// Add checkbox
function action_woocommerce_variation_options( $loop, $variation_data, $variation ) {
    // Checkbox checked (ticked)
    $checked = get_post_meta( $variation->ID, '_mycheckbox', true ) == 'yes' ? 'checked' : '';

    // Output
    ?>
    <label class="tips" data-tip="<?php esc_attr_e( 'This is my data tip', 'woocommerce' ); ?>">
        <?php esc_html_e( 'This my checkbox:', 'woocommerce' ); ?>
        <input type="checkbox" class="checkbox variable_checkbox" name="variable_mycheckbox[<?php echo esc_attr( $loop ); ?>]"<?php echo $checked; ?>/>
    </label>
    <?php
}
add_action( 'woocommerce_variation_options', 'action_woocommerce_variation_options', 10, 3 );

// Save checkbox
function action_woocommerce_admin_process_variation_object( $variation, $i ) {
     // Isset, yes or no
    $value = isset( $_POST['variable_mycheckbox'][$i] ) ? 'yes' : 'no';
    
    // Update
    $variation->update_meta_data( '_mycheckbox', $value );
}
add_action( 'woocommerce_admin_process_variation_object', 'action_woocommerce_admin_process_variation_object', 10, 2 );

checkbox variation options



The 2nd piece of code will check if the checkbox is on for 1 of the 2 variants (The A variant)

  • If this is the case for the 'A variant', and the 'B variant' is in the shopping cart. Then a discount of 15% will be granted on the 'B variant'
// Used to calculate totals
function action_woocommerce_before_calculate_totals( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

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

    // Discount in percent
    $discount = 15;

    // Iterating though each cart items
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
        // Only for variations
        if ( $cart_item['data']->get_type() == 'variation' ) {
            // Get the value of the checkbox
            $checked = $cart_item['data']->get_meta( '_mycheckbox' );
            
            // Variant is checked
            if ( $checked == 'yes' ) {              
                // Get all variations ID of a variable product
                // Main function for returning products
                $variation = wc_get_product( $cart_item['product_id'] );
                
                // Get product child ids (Array)
                $child_ids = $variation->get_children();
                
                // Normally there are 2 childsIDs, we will remove the current one so that the other variantionID is known
                $other_variantion_id = array_diff( $child_ids, array( $cart_item['variation_id'] ) );
                
                // Convert to integer
                $other_variantion_id = (int) reset( $other_variantion_id );
                
                // Call function - other product ID in cart? yes, then get that cart item
                $other_cart_item = product_id_in_cart_get_cart_item( $other_variantion_id );
                
                // Finds whether a variable is an array
                if ( is_array( $other_cart_item ) ) {                   
                    // Calculate new price
                    $new_price = round( $other_cart_item['data']->get_price() * ( ( 100 - $discount ) / 100 ), 2 );
                    
                    // Set price
                    $other_cart_item['data']->set_price( $new_price );
                }
            }
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );

// Product ID in cart? return cart_item
function product_id_in_cart_get_cart_item( $product_id ) {  
    // Iterating though each cart items
    foreach( WC()->cart->get_cart() as $cart_item ) {
        // Compare
        if ( $product_id == $cart_item['data']->get_id() ) {
            // In cart
            return $cart_item;
        }
    }
    
    return false;
}

Upvotes: 1

Related Questions