Woocommerce add_to_cart without variation id - woocommerce

I have this code:
WC()->cart->add_to_cart( $product_id );
And If I try to on product which has variation, this still works and the product is added to the cart (although I havent provided other parameters for variation). Is this intended behavior, is there an error handler in case it fails?

This is an interesting case. This will pass only if the request is through ajax.
It should fail if its through the regular HTTP request due to the additional check in add_to_cart_handler_variable() function
if It's an ajax request, The variable product will be added and the product will take the lowest price ( the lowest regular/sale price from all variations ).
you should avoid doing that. you should pass the variation id too.

Related

Running $cart_item['data']->set_price() with $_GET is not working

I refer to this SO answer: WooCommerce rounding before calculate totals
I set the price using
$cart_item['data']->set_price(floatval($_GET ["productPrice"]));.
This works fine only for the 1st call of the hook.
The further hook call sets $_GET ["wc-ajax"] == "update_order_review" while the parameter productPrice is not provided anymore.
OK, I thought I ignore the call when $_GET ["wx-ajax"] == "update_order_review" but surprisingly, in the shopping cart, the product price has been reset to it's default value, this means, the preciously call
$cart_item['data']->set_price(floatval($_GET ["productPrice"]));
gets lost.
My question:
What is the correct approach for this so I can set the price from $_GET ["productPrice"] in the current shopping cart session without modifying the product price in the database and the price remains?
I am using one product where I have to change - depending on some conditions - the price directly in the shopping cart.
When I use $cart_item['data']->set_price(50.25); then it works because even while the AJAX call the price is static.

Creating WooCommerce placeholder for Emails sent

My client, a courier company, is using delivery software that is able to track with both WooCommerce order no. and ID, which means it requires both order no. and ID ("wc_order_abcdefg") to work, I believe this falls in the phpmyadmin database of post_password column.
Full tracking ID goes like: wc_order_abcdefg.66
So in the WooCommerce email settings, it only has {order_number}. How do I create one for {order_id}?
It looks like, your shipment tracking number is {order_key}.{order_number}.
Once you get hold of the order object, you can get its key simply with: $order->get_order_key().
{order_key} is not available as an email placeholder. So in order to include it in the email sent to the customer, you have different options depending on where you want it to be displayed. For example:
You could include the tracking number in the body of the email. In this case, you can override one of the WooCommerce email templates (e.g. email-order-details.php). See the WooCommerce docs for more info on how to override templates.
You could include the tracking number in the subject of the email. In this case, you can use the woocommerce_email_subject_customer_completed_order filter. E.g. (this snippet should be added to your functions.php):
add_filter( 'woocommerce_email_subject_customer_completed_order', 'add_tracking_number_to_email_subject', 1, 2 );
function add_tracking_number_to_email_subject( $subject, $order ) {
return sprintf( 'Thank you for your order! Your shipment tracking number is: %s.%s', $order->get_order_key(), $order->get_id() );
}

WooCommerce If order status is in processing then products in that specific order will be hide from the shop

I have a shopping website with limited products. I'm looking for a solution in which, if Order status is "Processing", then Products in that specific Order remains hide from the Shop and Search result, unless Order status changed to Completed. (which means product is back in shop for purchase).
Moreover, all products will be sold individually.
You can use woocommerce_order_status_changed hooks. Using these hook you will get 3 params called $old_status, $new_status and $order_id.
Then you just check is $new_status is processing or not. if processing then gets the order using $order_id and then create a loop for line_items. For each line item, you will get product_id and check the product is publish or not. If Publish then just make the product in draft status, if not then just continue the loop.
Like the same procedure, you can also check for Completed status. If the status is completed just loop through the order items and make each product draft to publish.
Hope you understand. If not, then let me know. I will share the code snippet

WooCommerce - Change customer order after it has been placed and paid

Using three plugins:
WooCommerce
Subscriptio
WooEvents
I have created a product which allows for a customer to pay for an event over five instalments.
A customer has placed an order and made their first of the five payments via PayPal and has then contacted me to advise they have booked the wrong event.
The correct event is exactly the same except the dates are a month sooner.
I have added the following snippet to be able to edit 'processing' orders:
add_filter( 'wc_order_is_editable', 'wc_make_processing_orders_editable', 10, 2 );
function wc_make_processing_orders_editable( $is_editable, $order ) {
if ( $order->get_status() == 'processing' ) {
$is_editable = true;
}
return $is_editable;
}
From the order screen within the back-end of WordPress I can see that the the order can be edit by way of removing the product from the order or editing the meta data and cost.
The correct product that should have been ordered has a different product/variation ID.
My question is simply:
Should I remove the incorrectly ordered product from the order and add the correct product (both have the same properties with the exception of the courses dates); or
Should I just change the meta data and increase the stock levels for the incorrectly product back to X and reduce the stock level for the correct product?
Your second option is much better. Change the meta from database if its accessible and then manage the stock accordingly.
I have not yet done this, but according to this exchange ...
How can I add a product to an existing and paid Woocommerce order?
... you can set the order status to "On Hold" and make changes to the order itself. I presume you would then return the status to "Processing".
I would expect that if the application permits those changes, then it would be doing the background meta changes to inventory levels, etc., and spare you the problem of doing so (and the potential errors that may occur when messing with the data tables outside of the application).
Like I said, I haven't done this. But it might be worthwhile doing a little test to make sure it works as it seems to be described in the answer to the other question.
J

Woocommerce: how do I add metadata to a cart item?

I have a digital product which is described by a quantity and a price, but which also needs 3 more numbers to completely specify it (Unix dates, etc). Problem: how do I get these numbers into the cart?
As far as I can see, there are 2 possible ways to handle this:
A product variation
A product custom field
It looks like variations can only handle discrete values with a limited range (ie. red/yellow/green, S/M/L, etc), and can't handle general integers, like dates. That leaves custom fields. I think I'm right in saying that custom fields are ordinary meta data on the product post page, so I can handle them with get_post_meta and update_post_meta.
So, if I go for custom fields, then I would update the product page field during ordering, and then I would read back the field during checkout, when the WC_Order is created, and add the field to the new order. However, this won't work. I can't change metadata on the product page, because the product is global to all customers, and this operation would interfere with other customers. In other words, you can't store order-specific information in a product, so neither of these options would work.
So, how do I store temporary product metadata and pass it between the ordering and checkout phases (ie. between WC_Cart and WC_Order)?
One option would be to store it as user metadata (or as session data?), but there's got to be a better way - any ideas?
It turns out to be easy to do this with session data. When you're adding an item to the cart (see the source for add_to_cart_action) you create a session variable, containing all your additional meta data:
WC()->session->set(
'my_session_var_name',
array(
'members' => $members,
'start' => $start,
'expiry' => $expiry,
'etc' => $etc));
When the user checks out, the cart data disappears, and a new order is created. You can hook into woocommerce_add_order_item_meta to add the session meta data to the order meta data:
add_action(
'woocommerce_add_order_item_meta', 'hook_new_order_item_meta', 10, 3);
function hook_new_order_item_meta($item_id, $values, $cart_item_key) {
$session_var = 'my_session_var_name';
$session_data = WC()->session->get($session_var);
if(!empty($session_data))
wc_add_order_item_meta($item_id, $session_var, $session_data);
else
error_log("no session data", 0);
}
That's it. You do have to figure out how to get the order metadata out and do something useful with it, though. You may also want to clear the session data, from hooks into woocommerce_before_cart_item_quantity_zero, and woocommerce_cart_emptied. There's gist here which has some example code for this.

Resources