I need the following and i´m turning around the thing but can´t get a clean way on doing it:
Some products needs to belong to x category, if a customer buy one of those products, all the rest of the products behind that category should get outofstock or unpublished.
So i need a way to create a function that could run once a product is sold and then find all those products with same category and change their metadata, in this case i will solve the rest of the thing just changing the outofstock meta, but knowing that i guess i will also be able to edit any other post meta value.
I know how to update a meta value, i can´t imagine how to hook/filter the rest. Any ideas? Thanks
Have you taken a look at the WooCommerce hooks?
I would check out the woocommerce_order_status_.$new_status->slug hook for the status completed. So something like:
function the_function($order_id) {
// get the order object
$order = new WC_Order( $order_id );
}
add_action( 'woocommerce_order_status_completed', 'the_function' );
Related
I've been using some well documented code to programatically create Woocommerce orders. Working great. Reference here: https://quadlayers.com/add-products-woocommerce/
However I'd be keen to know if it's possible to define the order_id (or is that the post_id?) whilst creating my WC orders via a script. I run this code on my shop, which currently imports orders into Woocommerce from a marketplace online where orders already have an Order number and I'd be keen to cut out the cross-referencing via this hack, and pass along the existing Order number to WC.
Here's a rough idea of what I have;
$insert_marketplace_order_id = 1234567890;
$order = wc_create_order();
$order->set_order_id($insert_marketplace_order_id);
$order->set_date_created($date_here);
$order-> etc. etc.
$order->save();
I've obviously searched around, unfortunately the existence of a plugin - which seems to be all Google knows about it - doesn't help.
I would have though 'set_order_id' would do the trick, but perhaps there's an issue with where I'm placing it. Any other ideas?
In WooCommerce, the order Id is the post Id, so you can't insert an external reference Id as you are trying to do. WooCommerce orders are a custom post type and order Id (the post Id) is generated from last post Id used in wp_posts database table…
Now you can set instead an Order number using the filter hook woocommerce_order_number, to set your own order reference number as order number, which is not the WooCommerce Order Id (post Id).
So your code will be:
$insert_marketplace_order_id = 1234567890;
$order = new WC_Order();
$order->set_date_created($date_here);
// $order-> etc. etc.
$order->update_meta_data('_order_number', $insert_marketplace_order_id); // <== Here
$order->save();
Then you will add the following hooked function to be able to get and display the correct order number:
add_filter( 'woocommerce_order_number', 'wc_set_order_number', 10, 2 );
function wc_set_order_number( $order_id, $order ) {
// Get the order number (custom meta data)
$order_number = $order->get_meta('_order_number');
return empty($order_number) ? $order_id : $order_number;
}
Code goes in functions.php file of the active child theme (or active theme).
Now when using the WC_Order method get_order_number() WooCommerce will get/display the correct order number.
Note: As you don't use any arguments with wc_create_order() function is better to use $order = new WC_Order(); instead, which gives an empty WC_Order instance object without using save() method 2 times (so much lighter).
Related: Dynamic custom order numbers based on payment method
I am creating an eCommerce store for a relative's business. He has products that the user must personalize on the website. I am coding a separate page that will allow the user to do this, that will link back to the store and add the item to the cart when they are done.
I found a solution to add each product to the cart separately, instead of adding to the quantity (since each product added has been personalized), and a solution to change the price of items in the cart.
WooCommerce: Add product to cart with price override?
https://businessbloomer.com/woocommerce-display-separate-cart-items-product-quantity-1/
The problem is that all the items are changed, not just the last one added.
For example: User designs a ballpoint pen with her name on it. The price is $4. The user then designs a gel pen with her name. The cart will show two separate pens with an increased calculated price, but the price will increase for all pens, not just the last one added. I need to find a way to set the price for the last item added, based on the price sent from the product building page. So far, nothing I've tried has worked.
Variable products won't work for this site.
//To display a product separately every time it is added
function bbloomer_split_product_individual_cart_items( $cart_item_data, $product_id ){
$unique_cart_item_key = uniqid();
$cart_item_data['unique_key'] = $unique_cart_item_key;
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data','bbloomer_split_product_individual_cart_items', 10, 2 );
add_filter( 'woocommerce_is_sold_individually', '__return_true' );
//To change the item price programmatically. Changes all items with the same ID
//I need it to change only the last one added.
//Set to retrieve new price from the customizing page
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 10, 1);
/**
* #param $cart_obj
*/
function add_custom_price($cart_obj ) {
ob_start();
include 'createbb.php';
global $custom_price;
$target_product_id = 17;
// This is necessary for WC 3.0+
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
foreach ( $cart_obj->get_cart() as $key => $value ) {
if ($value['product_id'] == $target_product_id) {
$value['data']->set_price($custom_price);
}
}
ob_end_clean();
}
The type of functionality you are looking for is actually so common that it has a name "Product Options" (this is different to variations). This feature allows you to add configurable add-on's to the price of a product through a design on the edit product page. In a lot of eCommerce platforms like OpenCart you have this sort of functionality built in for free, however Automattic opted to keep it as a separate bolt on which they charge for:
https://woocommerce.com/products/product-add-ons/
Before you say it yes it is annoying that they charge for it, really this is such a common thing for people to request you can tell that it was a calculated decision to monetise it. And yes it is still very possible to program everything bespoke, but you are inevitably re-inventing the wheel for no reason other than to avoid paying for the feature (there are free versions of the plugin above that others have made, google is your friend).
Consider something, what if Automattic change their hooks in the future? you'll have to modify your code, assuming you find out before it borks the site. What if you wish to change options, or you need someone else to change them and you are not around?
If you weigh things up, you'll find the best option in the end is either to grab the official plug-in, or use one of the free alternatives. Trust me I am doing you a favour.
Koda
I've got a customized WooCommerce shop where I want to be able to grey out certain product variations based on conditions, but I'm not sure where in the code to do it.
I have two prices for each item, one is a member price and one is a retail price.
I want everyone to see each variation but not be able to select the one that isn't available to them, so that non-members can see the retail price but can't select it, and vice versa.
The other customization I want is the following: I want to be able to only allow members to buy 5 products at member price per month, and then it will switch them over to retail price, so I need to be able to grey out the member price for members based on certain conditions as well.
Can anyone point me to the files/hooks/actions where I can inject some custom code into the variation output so I can make this happen?
Thanks.
For your two questions you can use in a different way woocommerce_add_to_cart_validation filter hook. With some conditions based on your users roles and on existing function arguments, customer will be able to select a variation of your product, but will not be able to added it to cart, if he is not allowed. You can even display a notice when customer try to add something when is not allowed…
add_filter( 'woocommerce_add_to_cart_validation', 'custom_add_to_cart_validation', 10, 5 );
function custom_add_to_cart_validation( $passed, $product_id, $quantity, $variation_id, $variations ) {
// Your code goes here
// If $passed is set to "false", the product is not added
// $passed = false;
return $passed;
}
For your last question, you will need to set/update some custom user meta data regarding the 5 products by month for the members, each time they place an order. You can use for this the woocommerce_thankyou or woocommerce_order_status_completed action hooks to set that custom data in the user meta data. Then you will be able to check this data enabling or disabling the right product variation in the woocommerce_add_to_cart_validation filter hook.
To finish, if you really want to grey out some variations, you will have to use Javascript/jQuery, but is going to be quite difficult as there is already a lot of javascript/Ajax WooCommerce events on product variations, that will conflict yours. But in WooCommerce everything is possible depending on time and skills…
Woocommerce version 2.3.10
Wordpress 4.2.2
The related products are cycling through the same products, which seem to be the first few products added to the shop.
It displays them in random order, but doesn't randomly show all of the products in the category.
I've read that this could be due to a plugin conflict preventing random products from being shown, but I haven't been able to find any conflict.
Get the same problem here. Find something that worked: in related.php is like that:
$related = $product->get_related( '$posts_per_page' );
I changed the value "$posts_per_page" to "99", like this:
$related = $product->get_related( '99' );
So this worked! I was suspecting that the woo gets only the X number of products from the related and because of that was cycling through them (here was 4 products). Obviously the problem is in the value this variable gets, but for now i will leave like this.
I am looking for a way to add a serial number to each sold product, in the order display in WooCommerce. What I need is a manual solution, where the S/N of the sent product is added to the order before the package is sent. I have tried to show it on the following picture:
Originally, I thought about implementing it as a product meta (without really knowing how) but I realized that product metas can only be altered when the order is set on hold and not while processing.
Any ideas aboout how to proceed? Thanks already!
Not really sure what your trying to achieve but if you need a serial number for each product (just to display it in your cart page) you can add that data as an attribute to each listing then recall it in the checkout area and have it display using hooks. How do you want to process the serial number? is it purely for display on checkout? assuming it is...
add_filter( 'woocommerce_cart_item_name', recall_serial_number, 10, 2 );
function recall_serial_number() {
$serial = $item_data->get_attributes( 'serial-number' );
echo $serial;
}
Give this code a whirl if all you want to do is display the serial on the cart page without processing it any further. Make sure the name of the attribute is "Serial Number" not tested but should work.