WordPress custom order field - wordpress

I have a requirement where, I have a list of pin codes which are serviceable by different courier partners. What I want is, Once someone books a order, I want to first check the pin code and accordingly add the respective Courier partner name in the order meta field. For that I have created a custom checkout field. And once someone submits the address I can check through the pincodes and add respective courier.
But now after this, I also have a list of awb numbers given by respective courier partners. And I would also like to add respective courier awb number to the order and also send the same in the order recived email to the customer.
I am looking out, is there any action hook from Woocommerce which allows me to check the pincode and accordingly add the AWB number and send the same to customer/admin invoice. The only twist is, I want to add a function of assigning awb number after the order is marked as processing and before email-invoice is sent to the customer.
Is there any action hook which allows me to get order detail and add awb number after order is set as processing and before email-invoice is sent to the customer?

I think you should try woocommerce_order_status_processing with a high priority.
add_action('woocommerce_order_status_processing', 'your_fn', 0);
function your_fn( $order_id )
{
$order = wc_get_order( $order_id );
// ...
}

Related

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 - Do not authorize or capture on new order

Is there a way to set all new orders to "pending payment" (or some other status, maybe custom status?) without it auto changing to "on hold" or "processing"? What I'm wanting to do is basically have all new orders not only not capture CC payment (using Stripe), but also wanting it to not authorize. So, what I'm wanting to do is:
Submitted
"Pending Payment" (new order created, but not authorized or captured. Order status stay here until manual advance. I put in quotes because if this status HAS to be kept as-is with it auto connecting to the gateway, then maybe a custom status goes in between a submitted new order and Pending Payment...)
Processing (authorize and capture payment)
Completed
The whole reason for this is because my products are large and require us to box/weigh and manually get shipping prices (from various freight companies, etc). As it is now, new orders will auto authorize an amount and then put on hold. The problem is, we need to be able to manually go in and adjust shipping prices once we have a price and then add that to the order. There is no way to "re-authorize" for a higher amount (since we added shipping). So either we add a set flat rate amount per item for shipping (which would have to be more than the actual shipping rates could be) then come in and manually lower the shipping rate before capturing payment, OR we somehow don't let the new order to auto send to authorize.
Thanks for any help!
You can use this function to set the status of all upcoming new orders to 'Pending payment' regardless of any original status. Please note that the default order status is set by the payment method and you can't override it. The 'Pending payment' status will be set next to the default order status.
Add this to your theme's 'functions.php'.
add_action( 'woocommerce_thankyou', 'change_new_order_status', 10, 1 );
function change_new_order_status( $order_id ){
if( ! $order_id ) return;
$order = wc_get_order( $order_id );
$order->update_status( 'pending' ); //set status to Pending payment
}
There should be an option in Stripe payment method plugin to just authorize and not capture. You can enable that option but note that you cannot disable authorize.

Status of the Woocommerce order change from processing to complete after the order is placed with COD?

I have an online store where customers place an order and it is done with payment as COD. It is integrated with our warehouse management where it will export all the orders at the end of the day to the system from the site.
The status of the orders places are processing.
I am trying to make a php cron job where the order status of all these order set as completed when the list of orders are exported.
I have looked at various solutions and all change the order status at the time of placing the order while i want it later, once the data is exported.
If somebody can help me with the php function that sets all the order in the woocommerce to "complete" at some trigger, I would be really grateful.
In your cron function you may have a loop to get the order ID that needs to be exported, so just pass the Order ID to the given function it'll update the Order Status to wc-complete, you can also pass an order note if you need.
function wh_mark_order_as_omplete($order_id, $note = '')
{
//this check is option if you do not need this you can remove it.
//for COD order only
if ('cod' != get_post_meta($order_id, '_payment_method', true))
return;
$order = wc_get_order($order_id);
if (empty($note)):
$order->update_status('completed');
else:
$order->update_status('completed', $note);
endif;
}
Hope this helps!

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