Update variation product price - not visible in product page - Woocommerce - php

i have made custom import products which are variable type. Then i have make a file that has to update the variation product price. I am using the update_post_meta method. The values are appearing in the edit product page in the field of each variation, but it's not seems to update the price in the front page of the product.
I have to make a update product (by clicking the update button) in admin panel to work with the new prices.
I have tried using $product->variable_product_sync(); but it didn't seemed to work. Any ideas?
Sample of my code:
foreach ($variations as $variationProduct) {
$variationProductId = $variationProduct["variation_id"];
$productPrice = number_format($productPrice, 2, '.', '');
update_post_meta( $variationProductId, '_regular_price', $productPrice);
}
Any help or solution on this?

Solved!! Finally i found it through the woocommerce api. If you are using woocommerce 2.7 or newer you can use the following line:
$product->save();

Please use the following script to update the variation prices. Click here get the full code.
https://www.pearlbells.co.uk/bulk-update-product-variation-price-woocommerce/
function getExistingProducts($updatedPrices,$skuArray) {
$loop = new WP_Query(array('post_type' => array('product', 'product_variation'), 'posts_per_page' => -1));
while ($loop->have_posts()) : $loop->the_post();
$id = get_the_ID();
$product = wc_get_product( $id );
$sku = get_post_meta($id, '_sku', true);
if( in_array( $sku, $skuArray ) ) {
$attributes = $product->get_attributes();
$attributes['medium-quantity-price']['value'] = $updatedPrices[$sku][4];
$attributes['low-quantity-price']['value'] = $updatedPrices[$sku][3];
$attributes['v-low-quantity-price']['value'] = $updatedPrices[$sku][2];
update_post_meta( $id,'_product_attributes',$attributes);
echo ' Update Sku : '.$sku.' '.PHP_EOL;
}
endwhile;
}

Related

Add products to order after payment (WooCommerce/Wordpress)

I am creating a 'Build Your Own' page. After selecting 4 products from the options, 1 main product gets added to the basket with 4 of the selected products being added as meta_data under that main product.
You can see below the main product with 4 selected products (IDs).
After paying for this item, I need to add each selected product to the order, so that they are within the order on the backend. I'm having to do it like this, because I need the stock of the selected product to go down, eventually pulling into a stock management system we use (veeqo)
Any help is appreciated. The code below allows me get the some meta_data for woocommerce_thankyou but I am not sure if it will work then...
add_action('woocommerce_thankyou', 'BuildYourOwn', 10, 1);
function BuildYourOwn( $order_id ) {
if ( !$order_id ){
return;
}
$firstTime = get_post_meta( $order_id, '_thankyou_action_done', true );
// Allow code execution only once
if( !$firstTime ) {
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
$exItems = '';
// Loop through order items
foreach ( $order->get_items() as $item_id => $item ) {
//print_r($item);
// Get the product object
$product = $item->get_product();
// Get the product sku
$product_sku = $product->get_sku();
// Get the product name
$product_id = $product->get_name();
$extras = $item->get_formatted_meta_data('_', true);
$exItems.=$product_sku;
if(!empty($extras)){
$exItems.=$product_sku.' -';
foreach($extras as $extra){
$exItems.= ' ['.$extra->key.' : '. preg_replace("/[^A-Za-z0-9?#,.&%!\s]/","",$extra->value).'] ';
}
}
$exItems.="\n";
}
var_dump($exItems);
Maybe I worded the question wrong - But I figured it out:
I used the code below to get the meta_data which I then looped through and got individual item id and added it to the basket this way.
// Get the product meta data
$extras = $item->get_formatted_meta_data('_', true);
if ($product_id == 60023){
if(!empty($extras)){
$args = array(
'subtotal' => 0,
'total' => 0,
);
foreach($extras as $extra){
$mini_name = $extra->value;
$mini = get_page_by_title( $mini_name, OBJECT, 'product' );
$mini_id = $mini->ID;
$order->add_product( wc_get_product($mini_id), 1, $args); // Add Minis
}
}
}
The only slight issue is woocommerce_thankyou hook not firing if paypal users don't come back to the site after paying.

Update all WooCommerce products if "sale_price" is greater than "price"

I am trying to update wp_postmeta table for all products sale price.
I'm struggling with how to work this, due to both fields being meta_key / meta_value pairs in this wp_postmeta table.
How can I write a query that will update all '_sale_price' = 0 WHERE '_sale_price' > '_price'?
A different approach with a custom function that should do the same job. You will have to use this function just one time, and then remove it after the job is done (at first site load, the process will depend on number of products you have).
Here is the code:
function update_products_sale_price(){
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish'
);
// getting all products
$products = get_posts( $args );
// Going through all products
foreach ( $products as $key => $value ) {
// the product ID
$product_id = $value->ID;
// Getting the product sale price
$sale_price = get_post_meta($product_id, '_sale_price', true);
// if product sale price is not defined we give to the variable a 0 value
if (empty($sale_price))
$sale_price = 0;
// Getting the product sale price
$price = get_post_meta($product_id, '_price', true);
// udate sale_price to 0 if sale price is bigger than price
if ($sale_price > $price)
update_post_meta($product_id, '_sale_price', '0');
}
}
// Here the function we will do the job.
update_products_sale_price();
You can also embed the code function in a hook…
This code goes on function.php file of your active child theme or theme
This code is tested and fully functional
References:
WordPress Code Reference - Function get_post_meta()
WordPress Code Reference - Function update_post_meta()

WooCommerce Variable Product notice Issue - please choose product options

I'm building an e-commerce site. I'm having some trouble with WooCommerce Variable Product.
The "Add to Cart" button works fine with simple products, but does not work with variable products. It gives a "Please choose product options…" notice.
I looked everywhere and tried several suggestions online, none of them work. So I looked into WooCommerce source file: class-wc-form-handler.php.
In the function add_to_cart_handler_variable:
function add_to_cart_handler_variable( $product_id ) {
$adding_to_cart = wc_get_product( $product_id );
$variation_id = empty( $_REQUEST['variation_id'] ) ? '' : absint( $_REQUEST['variation_id'] );
$quantity = empty( $_REQUEST['quantity'] ) ? 1 : wc_stock_amount( $_REQUEST['quantity'] );
$missing_attributes = array();
$variations = array();
$attributes = $adding_to_cart->get_attributes();
$variation = wc_get_product( $variation_id );
...
if ( $missing_attributes ) {
wc_add_notice( sprintf( _n( '%s is a required field', '%s are required fields', sizeof( $missing_attributes ), 'woocommerce' ), wc_format_list_of_items( $missing_attributes ) ), 'error' );
} elseif ( empty( $variation_id ) ) {
wc_add_notice( __( 'Please choose product options…', 'woocommerce' ), 'error' );
} else {
// Add to cart validation
$passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations );
if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ) !== false ) {
wc_add_to_cart_message( $product_id );
return true;
}
}
return false;
}
The error is caught in the elseif clause.
So I tried to echo out $variation_id, $variations, and $variation. None of them has anything in it because when I echo $variation_id: it doesn't output anything.
How can the error be resolved?
On shop page you can't use add-to-cart button for variable products, because you need first to go on single product page to chose the options for this variable product before adding it to cart.
On variable product pages, normally you have some displayed options to chose for a variable product, before using "add to cart" button. If you don't do it, you get the error message… So at this point:
The options are not displayed in the product page (Bad settings in your backend product page, a bug with your theme or some additional plugin):
Check your product backend settings
Try to switch to default wordpress theme (to see if this issue is still there)
Try to disable most of all plugins.
the options are displayed: So chose your options first for this product, then add to cart
If this issue is related to your theme, contact the author of your theme and open a support thread or ticket…
OUPUTTING PRODUCT VARIATIONS FOR A PRODUCT ID:
To get product variations programmatically for a variable product ID:
$product = wc_get_product( $product_id );
$product_variations = $product->get_available_variations();
echo var_dump($product_variations); // Displaying the array
Then to get the first variation ID:
$product = wc_get_product( $product_id );
$product_variations = $product->get_available_variations();
$variation_product_id = $product_variations [0]['variation_id'];
echo $variation_product_id; // Displaying the variation ID
Or to get an array of all variations ID of this product ID:
$product = wc_get_product( $product_id );
$product_variations = $product->get_available_variations();
$arr_variations_id = array();
foreach ($product_variations as $variation) {
$product_variation_id = $variation['variation_id'];
array_push( $arr_variations_id, $product_variation_id );
}
echo var_dump($arr_variations_id); // Displaying the array of variations ID
A reference : Change "Add to Cart" button to "Go to Product" in the Shop Page
Just in case anyone else is building a custom theme and encounters this issue with variations not adding to the cart as expected - you may need to check your theme is loading the /woocommerce/assets/js/frontend/add-to-cart-variation.min.js script - add the following to wherever you enqueue your scripts to manually add it:
wp_enqueue_script('wc-add-to-cart-variation');
This solved the issue for me.
While we all have variation swatches in common the error (bizarre as this sounds) lays with the theme being incompatible. To test simply switch to 2020 theme and the ordering should work. I would recommend then making 2020 suite your needs and stop using the theme where the developers take days off when woocommerce updates are rolled out! Disabling the swatches wont help as the code is already there. Good luck.
I was facing the same issue.....delete your variation swatches plugin and the problem will be solved
Had the same issue....deactivated the autoptimize plugin and the problem was solved.
Also,to know which plugin to disable, you can simply load the page or the website, inspect element or developers mode, then check the console to see the source of the error which you can then relate to the relevant plugin and then disable from your wp dashboard.
I use wishlist plugin and when I tried to add variable product to cart I have got: 'The selected product isn't a variation of Product name, please choose product options by visiting Product name.'
The problem was that my product haven't default variation. So user added to wishlist product without selected variation. So when after user tries to add this product to cart error appears.
Here is FIX: just set default variation to all cariation products!
(Manually or via code). So user COULD NOT add product with EMPTY variation. Variation will be selected by default or user changes variation by himself.
So now in wishlist we have variation selected and all works as it should. It will work on all pages, archives, wishlists etc. Good luck! ;)
you’ll need to modify the functions.php file. Simply go to wp-content/yourtheme/functions.php on your child theme. Here, we’ll show you the full code and then we’ll explain its main parts. So the full PHP script to create WooCommerce default product attributes programmatically is the following:
add_action('woocommerce_before_single_product_summary', 'quadlayers_product_default_attributes');
function quadlayers_product_default_attributes() {
global $product;
if (!count($default_attributes = get_post_meta($product->get_id(), '_default_attributes'))) {
$new_defaults = array();
$product_attributes = $product->get_attributes();
if (count($product_attributes)) {
foreach ($product_attributes as $key => $attributes) {
$values = explode(',', $product->get_attribute($key));
if (isset($values[0]) && !isset($default_attributes[$key])) {
$new_defaults[$key] = sanitize_key($values[0]);
}
}
update_post_meta($product->get_id(), '_default_attributes', $new_defaults);
}
}
}

Bulk Updating Woocommerce Variation Prices

I'm trying to update woocommerce variation prices with a php/mysql script outside of wordpress.
I have a script that updates the _price and _regular_price value of one product_variation of a product in wp_postmeta table.
If I have more than one variation the correct price of the variation is displayed on the webpage - but the the price / price range coming from woocommerce`s price.php is not updated.
However, if I have only this one variation, the price in the table is updated, but not at all on the rendered webpage.
I also tried to edit the prices of the product itself. But: I still get the old price on the rendered webpage.
Basically I now have the same new price in these fields:
in product-variation -> postmeta: _price, _regular_price
and in product -> postmeta: _price, _regular_price, _min_variation_price, _max_variation_price, _min_variation_regular_price, _max_variation_regular_price
I couldn't find any other fields with a price - I'm stuck...
Did I miss anything? Is there any other table/field to be updated?
Thanks for your help!
-EDIT-
Maybe this helps: Apparently when having only one Variation my price is rendered with echo $product->get_price_html(); instead of echo $value['price_html'];. So where is the price used in $product->get_price_html(); stored?
OK after some digging around and thanks to #helgatheviking who pointed me in the right direction I tried this:
included wp-load.php in script
called WC_Product_Variable::sync( $post_id );
-> unfortunately this didn't work for me. I just put it here because I think this is the right approach - hopefully it helps someone else.
What actually helped me was including this in my functions.php:
// Display Price For Variable Product With Same Variations Prices
add_filter('woocommerce_available_variation', function ($value, $object = null, $variation = null) {
if ($value['price_html'] == '') {
$value['price_html'] = '<span class="price">' . $variation->get_price_html() . '</span>';
}
return $value;
}, 10, 3);
// Hook into price html
add_filter( 'woocommerce_get_price_html', 'wpa83367_price_html', 100, 2 );
function wpa83367_price_html( $price, $product ){
WC_Product_Variable::sync( $product->id );
$myPrice = $product->min_variation_price;
$priceFormat = str_replace(utf8_encode('.'), ",", $myPrice);
return '<span class="amount">from ' . $priceFormat . ' €</span>';
}
Please use the following script to bulk update the product variations.
Click here for full code. https://www.pearlbells.co.uk/bulk-update-product-variation-price-woocommerce/
function getExistingProducts($updatedPrices,$skuArray) {
$loop = new WP_Query(array('post_type' => array('product', 'product_variation'), 'posts_per_page' => -1));
while ($loop->have_posts()) : $loop->the_post();
$id = get_the_ID();
$product = wc_get_product( $id );
$sku = get_post_meta($id, '_sku', true);
if( in_array( $sku, $skuArray ) ) {
$attributes = $product->get_attributes();
$attributes['medium-quantity-price']['value'] = $updatedPrices[$sku][4];
$attributes['low-quantity-price']['value'] = $updatedPrices[$sku][3];
$attributes['v-low-quantity-price']['value'] = $updatedPrices[$sku][2];
update_post_meta( $id,'_product_attributes',$attributes);
echo ' Update Sku : '.$sku.' '.PHP_EOL;
}
endwhile;
}

Override product prices in custom query

I know this is not a woocommerce related websites, I tried the official forum, but no reply in 3 days. I spent a day or more with this, so I hope you can help.
I created a custom wp_query for the products. These products has a custom field (custom_price). I would like to override the prices in the query with the values of the custom fields.
I saw questions here about this, but I'm very new in php/wordpress. I really appreciate your help.
My query:
<?php woocommerce_product_loop_start(); ?>
<?php
if(is_front_page()){
$args = array(
'post_type' => 'product',
'posts_per_page' => 6,
'meta_key' => '_featured',
'meta_value' => 'yes'
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
wc_get_template_part( 'content', 'product' );
}
}
wp_reset_query();
}
?>
<?php woocommerce_product_loop_end(); ?>
If you just want to change the price that is displayed, then you can implement the filters woocommerce_price_html, woocommerce_sale_price_html, woocommerce_cart_item_price_html. This will result in the displayed price being whatever you would like, however the actual price in the cart used for calculating tax, shipping, totals, etc will be based on the "real" price.
// the HTML that is displayed on the product pages
function my_price_html( $html, $_product ) {
// if this is a variation we want the variation ID probably?
$id = isset($_product->variation_id) ? $_product->variation_id : $_product->id;
$custom_price = get_post_meta( $id, 'custom_price', true );
$custom_price_html = "<b>$custom_price</b>"; // just an example of HTML
return $custom_price_html;
}
add_filter( 'woocommerce_price_html', 'my_price_html', 10, 2 );
add_filter( 'woocommerce_sale_price_html', 'my_price_html', 10, 2 );
// the HTML that is displayed on the cart
function my_cart_item_price_html( $html, $cart_item, $cart_item_key ) {
$id = $cart_item['data']->id;
$custom_price = get_post_meta( $id, 'custom_price', true );
$custom_price_html = "<b>$custom_price</b>"; // just an example of HTML
return $custom_price_html;
}
add_filter( 'woocommerce_cart_item_price_html', 'my_cart_item_price_html', 10, 3 );
You will need to implement other filters/actions if you want to actually affect the item price, the above just affects the display. A better option might be to implement an action for save_post or update_post_meta that updates the WooCommerce product price when the custom field value changes (assuming you are using the codex to update this value).

Categories