I am using WooCommerce with WPML plugin. I want to implement a feature on checkout when a customer under certain conditions can have an upgrade of his product but keeping the old product price.
The products are variable with many variable attributes. So, more specifically, what I want is if a customer has selected a specific product variation with x price on checkout (under a certain condition) I could change his cart item with another product's variation but keep the x price.
What I tried first is to change only the name of the product using woocommerce_order_item_name
hook but the change doesn't follow on the order. This is important because some order data are then sent to an API.
Afterwards I used "Changing WooCommerce cart item names" answer code, which worked perfectly for my purpose until I installed WPML. For some reason the WC_Cart
method set_name()
doesn't work with WPML. I opened a support thread but they still can't find a solution.
Can anyone suggest any other solution?
Update
I have tried an approach where I remove the product item on cart and then I add the one I need. After I use set_price() to change the price of the newly added item. The removal/addition seems to be working but the price is not changed on one language and it is not applied on both languages after placing order. This is the code I use:
function berrytaxiplon_change_product_name( $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_key => $cart_item ) {
// Get an instance of the WC_Product object
$product = $cart_item['data'];
// Get the product name (Added Woocommerce 3+ compatibility)
$product_id = method_exists( $product, 'get_parent_id' ) ? $product->get_parent_id() : $product->post->post_parent;
if ( ICL_LANGUAGE_CODE == 'en') {
if (isset($cart_item['s-member-level']) && $cart_item['s-member-level'] == 3 && $product_id == 12) {
$new_product = wc_get_product( 82 );
$atrributes = $product->get_attributes('view');
foreach ($atrributes as $atrribute_key => $atrribute_value) {
$new_attributes['attribute_' . $atrribute_key] = strtolower($atrribute_value);
}
$new_variation_id = find_matching_product_variation_id(82, $new_attributes);
$cart->remove_cart_item( $cart_item_key );
$cart->add_to_cart( 82, 1, $new_variation_id, $new_attributes, $cart_item );
foreach ( WC()->cart->get_cart() as $new_item ) {
$new_item['data']->set_price( $cart_item['s-fare'] );
}
}
} else {
if (isset($cart_item['s-member-level']) && $cart_item['s-member-level'] == 3 && $product_id == 282) {
$new_product = wc_get_product( 303 );
$atrributes = $product->get_attributes('view');
foreach ($atrributes as $atrribute_key => $atrribute_value) {
$new_attributes['attribute_' . $atrribute_key] = strtolower($atrribute_value);
}
$new_variation_id = find_matching_product_variation_id(303, $new_attributes);
$cart->remove_cart_item( $cart_item_key );
$cart->add_to_cart( 303, 1, $new_variation_id, $new_attributes, $cart_item );
foreach ( WC()->cart->get_cart() as $new_item ) {
$new_item['data']->set_price( $cart_item['s-fare']);
}
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'berrytaxiplon_change_product_name', 10, 1 );
Any idea why the set_price() method is not applied?
Update 2
WPMl uses 'woocommerce_before_calculate_totals' and overrides the action added on functions.php
WPML support provided a solution using 3 filters: