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

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

Related

Woocommerce How do I add kilojoules from products to each other in the cart

I have a website where each product (food items), lists all the Caloric quantity in KJ. (added as a custom field on the single product page via Woocommerce Nutrition Info plugin)
As the products get added to the cart, I need a total KJ section near the totals, so my customer can see if the mix they are making is appropriate.
Eg. add 1 from A, and 0 to 3 of B, C, D E F. Letters being food items to make their own mix,
Knowing that WooCommerce adds prices, it would make sense that it could somehow do this too in the cart but I'm not smart enough to begin to know how to do it.
I have only limited PHP and Javascript knowledge, so I am totally out of my league and doing my head in.
Does anyone know how to I would add (I'm guessing) custom fields quantities to each other and display a running total to the cart?
I tried writing some code and big surprise it doesn't work, (trying not to be hard on myself but failing abysmally because I'm not a php coder YET!) and I don't know how to make it add up exponentially as products are added to the cart. I have spent weeks googling and Google doesn't understand my question either, hence me reaching out.
add_action( 'nutrition-table-kj', 'kj-value-add-to_cart_function' );
kj-amount-add_to_cart_function () {
$product_id = all;
if ( WC()->cart->get_cart_nutrition-table-kj-value () {
WC()->cart->add_to_cart( $nutrition-table-values );
}
}

WooCommerce ignoring decimal price

I have a WooCommerce 7.0.0 shop for which I'm programmatically creating products.
The price of these products is calculated according to various user input values.
I've done it before on other sites without problem, but I'm currently facing an issue : when the calculated price is a float, on the review order table, the price is not displayed correctly, and I'm getting a notice : A non well formed numeric value encountered in class-wc-cart.php on line 2151
Eg. if the price is 5.24€, I get 5.00€ on the product detail, subtotal, and total of the cart.
However, the price is displayed correctly as 5.24€ in the back-office.
Also, it is stored correctly in database.
Here's 2 methods I've tried to save the price before getting to checkout :
// Method 1
$product->set_price($total);
$product->set_regular_price($total);
$product->save();
// Method 2
add_post_meta($pID, '_regular_price', $total);
add_post_meta($pID, '_price', $total);
I tried various casting and rounding methods before saving (flotval, number_format, sprintf('%.2F') ) to no avail.
I also tried both , and . separators on the WooCommerce settings.
I'm running out of ideas, I must have missed something obvious but as it is, I can't put my finger on it.
Maybe something has changed on the newer versions of WooCommerce ? The last version I've used where I created products in the same way without issue, was 6.3.1.
Any help is welcome :)
Thanks,

Woocommerce Subscription - add coupon to existing subscription

I am looking to add the function, where I can offer a user a discount code that affects their next subscription amount.
For example:
I give customer code 1234 to give them 10% off their next months renewal
They enter the code in their My Account area and then Stripe knows that next month to charge them 10% less then the usual amount.
I have seen a few questions on here asking something similar but no answers so thought I would ask myself and see if anyone can offer their assistance.
This is what worked for me. The coupon has a discount type of Recurring Product % Discount and it applies on the next renewal(s) . You can set for how many renewals it is applied to. The code to apply it is:
$subscription->apply_coupon('your-coupon-code');
And I use it like this on the form handler:
if(isset($_POST['sid']) && $_POST['sid'] != ""){
$subscription = wcs_get_subscription( $_POST['sid'] );
if($subscription->get_status()=="active"){
$subscription->apply_coupon($_POST['coupon']); // returns true on success
}
}

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: 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