I'm working with a custom product where customers can type their custom text that will be added to cart.
Depending on the size of the text, a different price will be set, the logic is done and I can see the new price in the product object.
It seems that I can change the product object with the new price but I get status 500 back from admin-ajax.php when I do $woocommerce->setup_product_data($product_id).
I have found several topics but none of them seems to work in my case.
I'm not able to update the cart with the new price.
Here is my ajax function in functions.php:
// Adjust new price
function applyNewPrice() {
global $woocommerce;
// From JS
$product_id = (int) $_POST['id'];
// From JS
$price = (float) $_POST['price'];
$product_data = get_post($product_id);
// Code returning status 500 here...
$product = $woocommerce->setup_product_data($product_data);
$product->set_price($price);
update_post_meta($product_id,'_price',$price);
update_post_meta($product_id,'_regular_price',$price);
$woocommerce->clear_product_transients( $product_id );
}
add_action('wp_ajax_applyNewPrice', 'applyNewPrice');
add_action('wp_ajax_nopriv_applyNewPrice', 'applyNewPrice');
The function you are trying to call does not exist. This is the function you need.
$product = wc_setup_product_data( $product_id );
No sure where you are coming up with those functions. I could not find this function either?
$woocommerce->clear_product_transients( $product_id );
Related
I have written this to extract the product variation prices
global $product;
if ( $product->is_type('variable') ) {
function get_product_variation_price($variation_id) {
global $woocommerce;
$product = new WC_Product_Variation($variation_id);
return $product->get_price_html();
}
$product_variations = $product->get_available_variations();
$arr_variations_id = array();
foreach ($product_variations as $variation) {
$product_variation_id = $variation['variation_id'];
$product_price = get_product_variation_price($product_variation_id);
}
$amount = get_product_variation_price($product_variation_id);
} else {
$amount = str_replace(".", ",", $product->get_price());
}
What I am trying to achieve is that if the product is a variable product, the amount variable changes to what currently selected variants set price is, however, this will always get me the first variants price. How can I achieve that?
I don't see any reason to create a plugin for showing variation prices because this is the default from woocommerce. Can you share why are you creating this plugin? Does the default function not work on your site? If you are only looking to change decimals for prices, you can change these settings from currency options.
I created a custom product type for WooCommerce. With this product type it is possible to connect an other product that is exist by ID.
WooCommerce reduce the stock quantity automatically if an order is placed and the payment is successful.
For example I added a product with ID 4082 to the cart with a quantity from 3.
After place this order WooCommerce updated the stock from product 4082 with -3.
Ok back to my custom product type. As I said it is possible to connect another product by ID.
For example I connect product 4082 with product ID 10988.
If a customer add product 4082 to the cart and placed the order I want reduce the stock quantity from product ID 10988 and not from 4082.
<?php
add_action('woocommerce_checkout_order_processed', 'stocktest');
function stocktest($order_id){
$order = wc_get_order( $order_id );
$order_item = $order->get_items();
foreach( $order_item as $product ) {
//for the topic I programmed the IDs hardcoded
if($product->ID == '4082'){
wc_update_product_stock( 10998, $product['qty'], 'decrease', '' );
}
}
}
?>
I tried the code above and the stock from ID 10998 is correctly decreased but also the stock from ID 4082 is decreased.
Do I use the wrong hook? And how can I make the function correctly?
Hope somebody can help me with this.
Thanks a lot
Does wc_update_product_stock( 4082, $product['qty'], 'increase', '' ); not work?
That way, the stock should be adjusted for the 4082 product.
Also, there might be a potential issue with your snippet. The $product variable refers to the product object of 4082 product, not the 10998 product.
Maybe try something like this?
<?php
add_action('woocommerce_checkout_order_processed', 'stocktest');
function stocktest($order_id){
$order = wc_get_order( $order_id );
$order_item = $order->get_items();
foreach( $order_item as $product ) {
//for the topic I programmed the IDs hardcoded
if($product->ID == '4082'){
$connected_qty = get_post_meta( 10988, '_stock', true );
wc_update_product_stock( 10998, $connected_qty, 'decrease', '' );
wc_update_product_stock( 4082, $product['qty'], 'increase', '' );
}
}
}
?>
Instead of using the custom field query, you could use the WC_Product class:
$connected_product = wc_get_product(10998);
$connected_qty = $connected_product->get_stock_quantity();
I did some research on your question. WooCommerce called a lot of functions to update the stock af order / payment. If an order is placed the items become an status reduce_stock yes or no.
If is yes go further and update the stock of this item. After this WooCommerce created the e-mails and ordernotes.
All this functions worked together please be careful with changing the code in the file wc-stock-functions.php
If you want change and try something do this for example on a local testserver.
This are some functions in the file
<?php
wc_maybe_reduce_stock_levels();
wc_maybe_increase_stock_levels();
wc_reduce_stock_levels();
wc_trigger_stock_change_notifications();
?>
How can I update a product by product_id in my functions file?
I tried using the below code but to no success:
$_pf = new WC_Product_Factory();
$product_id = wc_get_product_id_by_sku( $sku );
$_product = $_pf->get_product($product_id);
$_product->set_price('225');
Since WooCommerce 3, new WC_Product_Factory() with get_product() method is deprecated and replaced simply by the function wc_get_product().
To update price, you have to update the price and the regular price (or the price and the sale price)...
Also the save() method is necessary to grab the data at the end.
So to get the WC_Product Object from an existing product SKU and to use on it any available method, do the following:
$new_price = '225'; // New price
$_product_id = wc_get_product_id_by_sku( $sku );
if ( $_product_id > 0 ) {
// Get an instance of the WC_Product Object
$_product = wc_get_product( $_product_id );
$_product->set_regular_price($new_price); // Set the regular price
$_product->set_price($new_price); // Set the price
$_product->save(); // Save to database and sync
} else {
// Display an error (invalid Sku
printf('Invalid sku "%s"… Can not update price.', $sku);
}
Tested and works.
I am trying to change the price of the product based on location.
For this i am using wc fields factory to create number of fields for locations and updating the price and based on IP i am finding the city(location) and i am fetching the custom field value.
Using
function return_custom_price($price, $product) {
global $post, $blog_id;
$price = get_post_meta($post->ID, '_regular_price');
$post_id = $post->ID;
$price = ($price[0]*2.5);
return $price;
}
add_filter('woocommerce_get_price', 'return_custom_price', 10, 2);
Its working fine, but when i go to view Cart there it showing product price as 0
like this:
Please help me out in this.
Thanks.
Update:
The product meta data '_regular_price' is not a custom field but the product regular price, that you can get directly using WC_Product methods and magic properties directly on the $product object.
If you look to your function you have 2 arguments: $price (the product price) and the $product (the product object)… So you don't need to use any global variables as you got already $product object, that you can use.
Here is the updated code:
add_filter('woocommerce_get_price', 'product_custom_price', 10, 2);
function product_custom_price($price, $product) {
$custom_price = $product->get_regular_price();
return $custom_price * 2.5;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
Please see the cart screenshots:
1) The cart without using this code (before):
2) The cart using this the code (after):
As you can see, this code works perfectly and display the regular prices in cart items.
The OP is using this code with a custom field:
add_filter('woocommerce_get_price', 'product_custom_price', 10, 2);
function product_custom_price($price, $product) {
$custom_price = get_post_meta($product->id, 'custom_key', true);
return $custom_price;
}
I have a problem with adding action to 'save_post_product' hook.
I want to send stock data to my external API when product is changed(updated) in woocommerce admin.
The problem is that the stock values i get from simple product after the action is called are one 'iteration' old. By that i mean that the stock data i get seem to be the data before update. so if i call the update product 2 times, first time i get old data, second time i get the new ones.
add_action('save_post_product', array($this, 'product_changed'), 99, 3);
function product_changed($post_id, $post, $update)
{
if ('product' != $post->post_type || $update != true) {
return;
}
$_pf = new WC_Product_Factory();
$product = $_pf->get_product($post_id);
$items = array();
if ($product->product_type == 'simple') {
$product->get_total_stock();
$inStock = $product->is_in_stock();
$qty = $product->get_stock_quantity();
$managing = $product->managing_stock();
$items[$product->id] = [
...
];
} elseif ($product->product_type == 'variable') {
$variations = $product->get_available_variations();
/*For variations it works properly*/
}
}
$itemsJson = json_encode($items);
$this->sendData($itemsJson, '/products-changed/');
}
TLDR (example):
Lets say that product is set to manage stock, stock quantity 500 and is in stock.
Now i change the product not to manage stock, and set that it is out of stock.
I hit update.
Everything runs and wordpress gets to my code. When i get the values i still get
$product->is_in_stock(); //true
$product->get_stock_quantity(); //500
$product->managing_stock(); //yes
Now, when i hit the update again, everything runs the second time, but now i get the correct values.
$product->is_in_stock(); //false
$product->get_stock_quantity(); //0
$product->managing_stock(); //no
I assume that the product stock update runs after 'save_post_product' hook however, i was not able to find any other hook that might solve my problem.
NOTE: It works well with variations in the first 'iteration'. I think it has to do something with the $product->get_available_variations() code.
Seems like hooking the action to wp_insert_post hook did the trick :
add_action('wp_insert_post', array($this, 'product_changed'), 99, 3);
save_post is triggered BEFORE the update. So you would have to use the $_POST, $_GET or the global $post_data, as specified in https://codex.wordpress.org/Plugin_API/Action_Reference/save_post
You already resolved this by using wp_insert_post, so that's okay. Just a clarification for any one seeing this