Need help with variation and stock
-
Hello.
I sell lesson, people can be sponsored by the government for each lesson, so it change the price. I gives me my first variation (as price change from lesson to lesson). No stock change here.
Each lesson has a set of date and limited quantity seats (stock), so I made a second variation “dates”, but this variation do not change price.
Seems simple but impossible to achieve!
Do you have an idea?
Have a nice day.Here is two lesson exemple:
Lesson 1:
Sponsored-> Yes (30$)/ No (250$)
Dates-> 24th June (3 in stock)/ 5th July (12 in stock)Lesson 2:
Sponsored-> Yes (10$)/ No (425$)
Dates-> 10th June (1 in stock)/ 15th July (12 in stock)If I buy the Lesson 2 , non-sponsored, 15th july, I want the system to remove 1 from the “15th July” variation and charge me 425$…
-
Hi there,
You just have to set the stock amount on the dates, so when someone buys it your stock will update.
First you have to create your attributes, just go into Products > Attributes. Make sure to create the Dates e Sponsored attributes and set all terms.
Then, go into your product and set it as “Variable Product”. Check Dates as “Used for variations”.
Now go into Variations and select “Create variations from all attributes”. Then just check them as “Manage stock?” and set stock amount.
You could look here for more information: https://docs.woocommerce.com/document/variable-product/
As you said that you want to change the price as well, so could just check both (Dates and Sponsored) as “Used for variations”. And then set the changes they must get.
Like that: https://i.imgur.com/K0Vr1UX.png
Ok thanks. I did this but it’s weird, stock do not decrease in Date when buying… I buy a sponsored for the 10th of June for exemple, but the “10th of june” stock do not decrease after… I have no hook or other think that would interfere for now…
Hi @dantahoua, which is your order status?
Note that adding an order manually has no effect on stock/inventory. You need really try buy your product.
Let’s make sure you followed the right steps:
1. Create your attributes, just go into Products > Attributes. Make sure to create the Dates and Sponsored attributes, and set all terms.
2. Go into your product and set it as “Variable Product”. Check Dates and Sponsored as “Used for variations”.
3. Go into Variations and select “Create variations from all attributes”.
4. Set this way, and then “expand” them.
5. Then just check them as “Manage stock?” and set stock amount to your Dates, set the prices changes to Sponsored as well.
Thanks Felipe. I did this, put the variations on “any”, set up stock for “dates”, price for “sponsored”… I even tested one think, I set up the stock on “0” for one of the two “dates”, but I’m still able to order it!
When I order something in stock, the stock do not decrease after ordering.
I made those test:
-Create a “simple” product and order it. Stock is decreasing as expected.
-Removing my theme and using the default theme with my “variable product. Stock is not decreasing for the variation I ordered…Note that the “dates” attribute is created per product as it change from product to product. The “sponsored” attribute is created in Products->Attributes as it the same two option for all my lessons…
Edit: Finally I saw that attribute created per product are also created in Product->Attributes…
I didn’t check the manage stock at product level for the variable product as we want it to be managed per “dates” variation…
Weird, should work, still not working… Are you sure woocommerce is able to mange Stock this way?
Second edit: I made a test with a product with just “dates” variation. And it works as it should (stock decrease, even show in the product page). It’s when I made “cross” variations that is it not working…
Someone kindly help me also on StackOverflow. Here is the code which work as Woocommerce do not allow to make “cross variation” stock/price management…
If it could help someone else! ??add_action('woocommerce_thankyou', 'sync_variations_stock'); //woocommerce_thankyou //woocommerce_order_status_changed //woocommerce_payment_complete //woocommerce_order_status_processing //woocommerce_order_status_completed function sync_variations_stock($order_id) { $order = wc_get_order( $order_id ); foreach( $order->get_items() as $item ){ $product_id = $item->get_product_id(); $product_variation_id = $item->get_variation_id(); if (!$product_variation_id) return; // if the item isn't a variation $date_variation = get_post_meta( $product_variation_id, 'attribute_pa_dates', true); $sponsored_variation = get_post_meta( $product_variation_id, 'attribute_pa_admissible-emploi-quebec', true); $new_stock = (int) get_post_meta( $product_variation_id, '_stock', true); if ( ! $date_variation && ! $sponsored_variation ) return; //if the variation doesn't have date and color attributes $args = array( 'post_parent' => $product_id, 'post_type' => 'product_variation', 'posts_per_page' => -1, 'meta_query' => array( array( 'key' => 'attribute_pa_dates', 'value' => $date_variation, 'compare' => '=' ), array( 'key' => 'attribute_pa_admissible-emploi-quebec', 'value' => $sponsored_variation, 'compare' => '!=' ) ), ); $other_date_variations = get_posts($args); if( is_array($other_date_variations) && !empty($other_date_variations) ){ foreach ($other_date_variations as $date_variation) { // do your stock updating proccess here. (updateStockVariation() as you write in your code) $variation_id = $date_variation->ID; $date_variation_stock = (int) get_post_meta( $variation_id, '_stock', true); if ($date_variation_stock > 0) { //to prevent backorders //$date_variation_stock = $date_variation_stock - 1; $date_variation_stock = $new_stock; update_post_meta($variation_id, '_stock', $date_variation_stock); // if the variation is now out-of-stock, set it as so if ($date_variation_stock === 0) { update_post_meta($variation_id, '_stock_status', 'outofstock'); wp_set_post_terms( $variation_id, 'outofstock', 'product_visibility', true ); } } } } } }
-
This reply was modified 5 years, 9 months ago by
dantahoua.
I’ve updated the code on StackOverflow, but still you need to make it work with refunds and order edits. However after reading the info here, I think there may be better approaches than using variations for this.
You can insert variations only based on the dates and use some third-party plugins (e.g. Extra Product Options for WooCommerce or WooCommerce Extra Product Options) to add a product option (maybe a checkbox) for Sponsorship selection, which changes the price.@yashar, I already checked all plugin for this… Sadly all plugin just add or subtract an amount (or a %) from the price of the product and it’s always the same amount for all product. In my case, the price variation is different from product to product… So the custom way was the only solution there… ??
Here is the updated code:
function sync_variations_stock($order_id) { if (is_admin()) return; // make sure it's a user order and we aren't on admin dashboard $order = wc_get_order( $order_id ); foreach( $order->get_items() as $item ) { if ($item->get_type() !== 'line_item') continue; //if $item is not a product or variation $order_variation_count = $item->get_quantity(); $order_product_id = $item->get_product_id(); $order_variation_id = $item->get_variation_id(); if ( ! $order_variation_id ) continue; // if the item isn't a variation $order_variation = wc_get_product($order_variation_id); $order_variation_attribs = $order_variation->get_variation_attributes(); if ( isset($order_variation_attribs['attribute_pa_dates']) ) { $current_date_attrib = $order_variation_attribs['attribute_pa_dates']; //Get the stock of the current variation for updating others. $new_stock = $order_variation->get_stock_quantity(); } else { continue; // stop if the variation in the order doesn't have 'pa_dates' attrib } $product = wc_get_product( $order_product_id ); $variations = $product->get_available_variations(); foreach ( $variations as $variation ) { if ( $variation['variation_id'] == $order_variation_id ) { continue; //if this variation is the one we have in our order } if ( ! isset( $variation['attributes']['attribute_pa_admissible-emploi-quebec'] ) || !isset( $variation['attributes']['attribute_pa_dates'] ) ) { continue; //if this variation does not have the color or date attrib } if ( $variation['attributes']['attribute_pa_dates'] == $current_date_attrib ) { /* * wc_update_product_stock function sets the stock quantity if the variation stock management is enabled * NOTE: This function may cause a negative stock even if the variation backorder is set to false */ //wc_update_product_stock( $variation['variation_id'], $order_variation_count, 'decrease' ); //Update stock of other variation with the stock number of the one just bought wc_update_product_stock( $variation['variation_id'], $new_stock, 'set' ); wc_delete_product_transients($variation['variation_id']); // Clear/refresh the variation cache (optionally if needed) } } } }
And here is the code on StackOverflow
And thanks again, Internet is a better place with peoples like you!Hi all!
Excellent sleuthing ?? I am going to go ahead and mark this thread as
Resolved
. Take care! -
This reply was modified 5 years, 9 months ago by
- The topic ‘Need help with variation and stock’ is closed to new replies.