How to add an additional unique reference number to woocommerce orders - wordpress

I would like to know how can I add a unique random number to my WooCommerce orders which are visible to the customer and at WooCommerce orders.
For example,
When there is a new order. It will have it's usual order ID and an additional reference ID.
This reference number has to be unique for each order. So that, can be used as a way to identify each order.
Thanks in advance :)

The basic idea is to generate a random number and add it as order meta. This would something like the following. This mayn't be the perfect one, but will lead you to it.
function create_reference_id( $order, $data ){
$random = write_function_for_random_id(); //Write the function to create random ID
$order->update_meta_data( 'custom_id', $random ); // replace custom_id with your meta key name.
}
add_action('woocommerce_checkout_create_order', 'create_reference_id', 10, 2);
This will add ID to WooCommerce Order object. Then you need to write code to show ID in email.
UPDATE
For the random number function you can use combination of order id and the value returned from wp_rand() function.
If that's the case then you need to write as following.
function create_order_reference_id( $order_id, $data ){
$random = $order_id.'_'.wp_rand(1, 1000);
$order = wc_get_order( $order_id );
$order->update_meta_data( 'custom_id', $random );
$order->save();
}
add_action('woocommerce_checkout_update_order_meta', 'create_order_reference_id', 10, 2);

Related

How to bulk change external column values defined in Orders table and stored in database?

I am working on return processes in Woocommerce. I am getting returned or not returned information from table named return_table. I added this information to a new column in the orders table. The table is simply as follows:
I need to make changes to the column I just added. For example, I want to update the value from no return to returned. For this, I should make a new definition in the default actions column or add a new bulk action. I decided to add bulk action as it is more functional:
However, I was unable to make any progress after that. I've done research on Stackoverflow or other platforms. I found an answer to add buttons (new actions) but still couldn't solve the problem:
Source-1
Others I've found are mostly geared towards changing the "Order Status":
Source-2, Source-3, Source-4...
So, i've been researching this for a while and haven't found a solution. I will be grateful if anyone can help.
My Code:
<?php
// Add new column
add_filter( 'manage_edit-shop_order_columns', 'return_column', 11);
function return_column( $columns ) {
$columns['return_column'] = 'Return Status';
return $columns;
}
// Add the data to the custom columns
add_action( 'manage_shop_order_posts_custom_column', 'return_column_content',11);
function return_column_content ($column){
if($column == 'return_column'){
// Create required global variables
global $post, $wpdb;
$order = wc_get_order( $post->ID );
$order_id = $order->get_id();
$result = $wpdb->get_results("SELECT return_status FROM {$wpdb->prefix}return_table WHERE order_id ='$order_id' LIMIT 1");
if(count($result)):
echo $result[0]->return_status;
else:
echo '-';
endif;
}
}
//Add new order status to bulk change
add_filter( 'bulk_actions-edit-shop_order', 'refund_register_bulk_action' );
function refund_register_bulk_action( $bulk_actions ) {
$bulk_actions['mark_returned'] = 'Returned';
$bulk_actions['mark_not_returned'] = 'Not Returned';
return $bulk_actions;
}

woocommerce recalculate price programmatically

11/5/21 Update
It's really tricky that find out the wc_order couldn't access the calculate_totals and calculate_taxes.I find out the solution is put $order = wc_get_order( $order->get_id() ); before calulation. The 2 $order type is different , one is (object)WC_Order and another one is (Object)Automattic\WooCommerce\Admin\Overrides\Order. The method of second object works.
I wanna make the AJAX function to place an order programmatically. The product price is base on metadata so I have to calculate every line item. It doesn't with any issue from the client side that sends the post the request to place. The problem point, even I set the price to the line item, and use calculate_totals for the WC_Order but the price didn't correct. The only correction is the cost and subtotal. Though I hit the recalculate button the price would be right.
code
function place_an_order($data){
$screen_prodcut = new WC_Product_Simple(6310);
$userid = get_current_user_id();
$order = wc_create_order(array('customer_id'=>$userid));
$screen_quantity = 2;
$item_id = $order->add_product($screen_prodcut,$screen_quantity);
wc_add_order_item_meta($item_id,'width','1201');
wc_add_order_item_meta($item_id,'height','1201');
wc_add_order_item_meta($item_id,'note','** this is testing**');
$screen_price = 50;
$new_line_screen_price = $screen_price * $screen_quantity;
$item = $order->get_item($item_id);
$item->set_subtotal( $new_line_screen_price / 11 * 10 );
$item->set_total( $new_line_screen_price / 11 * 10 );
$item->save();
// ###section 1###
$order->calculate_taxes();
$order->calculate_totals();
// ###section 2###
}
When run in section 1, the $item subtotal and total are correct. But run in section 2 there is the failure out when printing $order and retrieve the total is wrong. In the dashboard, the price would be shown wrong but the total and subtotal are correct.
After clicking the recalculate, the order total is corrected.
I have no idea why calculate_totals and calculate_taxes don't work. woocommerce_calc_line_taxes is the AJAX action via hit the recalculate button. Usage is calculate_totals and taxes as well. Alternatively, I have to use the set_total instead of calculate_totals?

Make a filter for WooCommerce Order Search

In WP I have a WooCommerce order database of about 35k orders. The wp_postmeta table is about 2 million records because all order data is stored as metadata. Therefore the order search is quite slow.
I changed the default wc order search to only search specific metadata fields with this snippet:
function custom_woocommerce_shop_order_search_fields( $search_fields ) {
// error_log( 'currently searching in these order fields: ' . print_r($search_fields, true) );
unset( $search_fields );
$search_fields[] = '_order_key';
$search_fields[] = '_billing_company';
$search_fields[] = 'serialnumbers';
$search_fields[] = 'information';
// error_log( 'now only searching in these order fields: ' . print_r($search_fields, true) );
return $search_fields;
}
add_filter( 'woocommerce_shop_order_search_fields', 'custom_woocommerce_shop_order_search_fields' );
So the wc order search now only searches these 4 types of metadata, but is still quite slow because of the large size of some of them.
I'd like to extend the wc order search with a dropdown filter 'orderkey, company, serials, info' so the search only searches for the metadata key selected in the dropdown. So if I select 'serialnumbers' in the dropdown, the wc order search will only look for my searchterm in the metadata serialnumbers and not in the others. Not only for speed but also for usability.
I'm not really a programmer so help is much appreciated!
Thanx for the help! In Filter orders by specific meta fields in WooCommerce admin orders list a similar problem was addressed. A custom filter was made to filter orders by meta key. The last (optional) part was to add all the meta keys from the filter to the search query.
I changed that last part to the snippet below. I now look for the selected value and if it's set I unset the order search and then only add the selected meta key from the dropdown. In the case below the search only searches for the 1 selected meta key. If nothing is selected it uses the default search.
// Make only the selected custom meta field searchable from the admin order list search field
add_filter( 'woocommerce_shop_order_search_fields', 'shop_order_meta_search_fields', 10, 1 );
function shop_order_meta_search_fields( $meta_keys ){
$filter_id = 'filter_shop_order_by_meta';
if ( isset( $_GET[$filter_id] ) && ! empty($_GET[$filter_id]) ) {
unset( $meta_keys );
$meta_keys[] = $_GET[$filter_id];
}
return $meta_keys;
}
Note: the the above snippet only works in combination with the rest of the code from the other topic to make the filter that's used in this snippet.

How to get ACF data from WooCommerce customers for order export

On a Wordpress-Shop I use WooCommerce (WC) with Advenced-Custom-Fields (ACF)
and WP-All-Import (WPAI) + WP-All-Export (WPAE).
I added a ACF field CustomerNumber to the WC-Customer (which enhanced the WP-User).
On the WPAI-XML-Import I set the CustomerNumber with a value from a ERP.
So all customers have a unique CustomerNumber.
I now need to export the WC-Orders (to import them in the ERP again).
The Order-XML must include the CustomerNumber from the Customer belongs to the Order.
As I see, the other standard fields from the customer – like name and address – are copied automatically to the order (by WooCommerce itself).
My question is now: How I have to do this for the ACF’s?
Did I have to do this by code on my own? Adding the same AC-fields to the WC-Order and hook into the order checkout and copy the values from the customer to the order?
Or is there some kind of setup which do that and which I did not recognize?
Thx
I did not really found an answer.
My current solution is now as I described it in my question.
I added a new rule for these acf to also make them available on the orders.
Then I added a hook to new created orders, determine the acf from the user and copied the necessary values into the order acf.
function di_woocommerce_new_order( $order_id ) {
$order = new WC_Order( $order_id );
if ( !$order ) return;
$customer_id = $order->get_customer_id();
if ( !$customer_id ) return;
$customer = new WC_Customer($customer_id);
if ( !$customer ) return;
$customer_number = $customer->get_meta('customernumber');
if ( !$customer_number ) return;
// add customer number
$order->add_meta_data('customernumber', $customer_number);
// update order modified timestamp
$order->add_meta_data('order_last_updated', current_time( 'mysql' ));
$order->save_meta_data();
}
add_action( 'woocommerce_checkout_order_processed', 'di_woocommerce_new_order', 10, 1);

How to retrieve the latest categories assigned to a post currently under editing?

I need to limit the post tile length of a post belonging to a specific category while editing. So I need to check what categories have been assigned to the post under editing and decide whether to limit or not its post title.
I use "wp_insert_post_data" to do the job
add_filter( 'wp_insert_post_data' , 'limit_title_length' , '99', 2 );
But what I found is that the categories returned from passed $postarr are existing categories. Not the latest categories. So it would not work for new post or if categories being changed while editing.
$post_category = $postarr['post_category'];
I also checked get_the_category() inside the function, and that also returns existing categories, not the latest categories if category assignment changed.
My codes so far...
function limit_title_length( $data, $postarr ) {
// set up variables like max length, category id to limit
...
// get post id, title and categories from $data and $postarr passed
$title = $data['post_title'];
$id = $postarr['ID'];
$post_category = $postarr['post_category'];
// check if the specified category exists in the categories assigned to this post
...
// process $title, reset $post_title in $data
...
$data['post_title'] = $title;
return $data;
}
add_filter( 'wp_insert_post_data' , 'limit_title_length' , '99', 2 );
wp_insert_post_data fires in the very late stage of post publishing. I expected to get the latest categories from $postarr['post_category'];
but it's not in my case here. Any solutions or alternatives?
So just to be clear - You want to identify the most recent category added to a post?
If this is the case you will be hard pressed to do so as Wordpress does not save meta for added categories. If you are skilled enough you could script such a function and save the data in a custom table. Then retrieve it for use.
If you know the name of the category you are looking for you can use has_category! .

Resources