This is my current recent order
I wish to add another column "Tracking Number" and it will show woocommerce "note to customer" inside.
result is like : Display last WooCommerce admin order note in customers order history
The difference is without clicking view order and my customer can get to known their tracking number.
But I totally no idea how this work because not familiar with php..
hope to make this done and learn something.
Thanks!
the result will
You Need to create a new column in My order page first
function order_note_in_column( $columns ) {
$new_columns = array();
foreach ( $columns as $key => $name ) {
$new_columns[ $key ] = $name;
// Your Column Name : Change Tracking Number with the Column Heading you Want
if ( 'order-status' === $key ) {
$new_columns['track-number'] = __( 'Tracking Number', 'textdomain' );
}
}
return $new_columns;
}
add_filter( 'woocommerce_my_account_my_orders_columns', 'order_note_in_column' );
Once you create a new column now the second step is to display Data in the column.keep type as internal to show private note, In this way customer notes will not be displayed at frontend
function order_note_value_in_column( $order ) {
//Get Notes by order ID & Here keep type as internal to show private note. In this way customer notes will not be displayed at frontend
$note = wc_get_order_notes([
'order_id' => $order->get_id(),
'type' => 'internal',
]);
// Displaying the latest Note. If no tracking number entered then order status will be displayed in column
print_r($note[0]->content);
}
add_action( 'woocommerce_my_account_my_orders_column_track-number', 'order_note_value_in_column' );
code goes in functions.php tested & works
Related
I'd like to add an order note to log the time I added tracking number to existing order. I'm using Advanced Custom Fields to store trackings. Tried function below, and it breaks my site:
function tt_add_tracking_note( $order ) {
$tt_order = $order->id;
if (get_field('tt-track', $tt_order)) {
$tt_tracknum_note = 'Added tracking number ' . the_field('tt-track', $tt_order);
}
$tt_order->add_order_note( $tt_tracknum_note );
}
add_action( 'woocommerce_process_shop_order_meta', 'tt_add_tracking_note', 10, 2 );
What is wrong and how do I add a note the right way?
I have been trying to add a custom 'select' field to a woocommerce checkout. The select options are comprised of entries in an array, which in turn is comprised of titles and dates from a query of custom post types.
This all works fine, I can add new custom posts and the title and dates are concatenated, added to the array and in turn added to the select drop-down at the checkout, however when I submit the form and complete the order the index of the chosen select field value is added to the meta data, not the value.
I have added images in here to show you what I mean. e.g. if I select the third option from the dropdown 'Tain Farmers Market' which is array index 2 that's what is saved for the order meta instead of the value at that index entry.
The screenshot includes the results of the var dump showing the array contents as well as the select field below it.
image of how the array appears in var dump
the order meta showing in the admin screen, displaying the index not the value
Here is my code covering this section, any pointers would be really handy. I feel there is probably some simple solution to get the value at the chosen index when the order is processed?
/**
* Add custom Pickup Field field to the checkout page
*/
add_filter( 'woocommerce_after_order_notes', 'hiwoo_add_checkout_fields' );
function hiwoo_add_checkout_fields( $checkout ) {
$args = array(
'post_type' => 'pickup-point',
'posts_per_page' => -1,
'post_status' => 'publish'
);
// Custom query to pull in the pickup points.
$query = new WP_Query( $args );
$pickup_comb_option = [];
while ($query->have_posts()) {
$query->the_post();
$postid = $post->ID;
$pickuptitle = get_the_title($post);
$pickupdate = get_post_meta(get_the_id($post), 'available_date', true);
$pickupoption = $pickuptitle . ' - ' . $pickupdate;
array_push($pickup_comb_option, $pickupoption);
}
var_dump($pickup_comb_option);
// Restore original post data.
wp_reset_postdata();
echo '<div id="custom_checkout_field"><h2>' . __('Order Pickup Location/Date') . '</h2>';
woocommerce_form_field( 'pickup_point_options', array(
'type' => 'select',
'class' => array(
'my-field-class form-row-wide'
) ,
'label' => __('Select Pickup Location/Date') ,
'placeholder' => __('Pickup Point') ,
'options' => $pickup_comb_option,
),
$checkout->get_value( 'pickup_point_options' ));
echo '</div>';
} /* Close custom field function */
/**
* Process the checkout
*/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST['pickup_point_options'] )
wc_add_notice( __( 'Please select a pickup location from the list.' ), 'error' );
}
/**
* Update the order meta with field value
*/
add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST['pickup_point_options'] ) ) {
update_post_meta( $order_id, 'Pickup Location/Date', sanitize_text_field( $_POST['pickup_point_options'] ) );
}
}
/**
* Display field value on the order edit page
*/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Pickup Location/Date').':</strong> ' . get_post_meta( $order->id, 'Pickup Location/Date', true ) . '</p>';
}
The html produced on the checkout page for the select field is:
array(3) {
[0]=>
string(32) "Tain Farmers Market - 2019-12-25"
[1]=>
string(30) "Hi Create Offices - 2019-10-25"
[2]=>
string(27) "Dornoch Stores - 2019-09-26"
}
<select name="pickup_point_options" id="pickup_point_options" class="select " data-placeholder="Pickup Point">
<option value="0">Tain Farmers Market - 2019-12-25</option>
<option value="1">Hi Create Offices - 2019-10-25</option>
<option value="2">Dornoch Stores - 2019-09-26</option>
</select>
According to your HTML I assume the value being saved in your example is "2" instead of "Tainy Farmers Market", right? If so, that is technically correct, as the value of a <select> being submitted on a form submit is always the value in the option's value attribute (<option value="2">) and not the text in between (<option value="2">Some text</option>)
To have it saving the text in between it has to be set inside the value-attribute. Therefor you need to change the option's array from numeric to associative, like so:
$pickup_comb_option = [];
while ($query->have_posts()) {
$query->the_post();
// ...
// change this line
array_push($pickup_comb_option, $pickupoption);
// to:
$pickup_comb_option[$pickupoption] = $pickupoption;
}
To verify this worked check for the generated HTML, it should look something like this:
<select>
<option value="Tain Farmers Market">Tain Farmers Market</option>
</select>
#edit
I should mention this approach has some downsides:
You should ensure that the string in $pickupoption is not used multiple times. It's also necessary that the string is valid for use as an array key (not NULL, not empty). Since the value is being written inside a html-attribute (value="$arrKey") you may also want to check how Woocommerce handle's such things as doublequotes inside the string. Just to avoid possible bugs beforehand.
An alternative approach could be to save an id instead of a string.
I want display the external table value in WooCommerce checkout from company name field. We can create external table and insert some of company name.
When user signup our service in checkout field, customer should select the company name in a custom select options field. This values should be displayed from a custom database table.
How can I achieve this?
Thanks in Advance.
We are going to first unset the field type of company, and then to change it to a type 'select' (selector). Then we will maque a query to get all options key/values from your custom database table (Let's say is called 'wp_companies'):
(ONLY FOR TESTING) NO database query here (with 3 options for companies):
add_filter( 'woocommerce_default_address_fields' , 'set_custom_company_checkout_field' );
function set_custom_company_checkout_field( $address_fields ) {
unset($fields['company']['type']);
$address_fields['company']['type'] = 'select';
$address_fields['company']['options'] = array(
'option_1' => 'Company 1',
'option_2' => 'Company 2',
'option_3' => 'Company 3'
);
// (optional)
// $address_fields['company']['default'] = 'Company 1';
return $address_fields;
}
Paste this code in function.php file located in your active child theme (or theme).
This code is tested and works…
THE REAL CODE: Making the query from database custom table (to be adapted):
add_filter( 'woocommerce_default_address_fields' , 'set_custom_company_checkout_field' );
function set_custom_company_checkout_field( $address_fields ) {
// Unset company field type
unset($fields['company']['type']);
global $wpdb;
$select_options = array();
// ### you will need to replace names table and columns and adapt this !!!
$query = "SELECT id, company FROM table";
$companies_name = $wpdb->get_results($query);
// Storing object $company_name keys/values in $select_options array
foreach ( $companies_name as $company_name )
{
$key = 'option_'. $company_name->ID;
$value = $company_name->custom_column_value;
$select_options[$key] = $value ;
}
$address_fields['company']['type'] = 'select';
$address_fields['company']['options'] = $select_options;
// (optional)
// $address_fields['company']['default'] = $select_options['option_1'];
return $address_fields;
}
Paste this code in function.php file located in your active child theme (or theme).
References:
WooThemes - Customizing checkout fields using actions and filters
WooCommerce - Overriding billing state and post code on existing checkout fields
I have a Woocommerce site, and I use Gravity Forms to further expand each order.
I am coding a management tool that consumes both APIs to make some statistics and other administration tools.
I can get a list of the Gravity Forms entries, and also a list of the orders. The problem I have is that I don't know how can I get the entry that is related to a particular order.
Is there a way to do this?
have you tried with the woocomerce history plugin or fetching the raw metadata out the item¿?
wc_get_order_item_meta($order_item_id, "_gravity_forms_history");
wc_get_order_item_meta($order_item_id, "_gravity_form_data");
keep in mind that this will require a new endpoint to be created is not put of the box.
The last time I worked with the WooCommerce Gravity Forms Product Addons (a year or so ago) it did not store the order ID in the entry (would have to happen after the entry is created and after the order is created), or the entry ID in the order. The latter probably makes more sense but both would require custom code.
Again, it's been some time since I worked with the add-on. I'd ping WC support and see if they any tips on implementing support for this.
This is where I found the link between WooCommerce and the gravity forms product addon:
In the database, find the order in the table your_table_prefix_posts, and grab its ID. I was filtering for the post_type "shop_order."
In the table your_table_prefix_woocommerce_order_items, find the ID just found and filter for "line_item" in the "order_item_type" column, and grab the "order_item_id."
Use that "order_item_id" to find the order's meta in the table your_table_prefix_woocommerce_order_itemmeta.
All of the order's gravity forms data is in there. It looks like there is no actual tie between what woo does and gravity, except that the form is filled out and it data is grabbed and stuck into your_table_prefix_woocommerce_order_itemmeta. I cannot find anything that ties a particular order to a particular gf entry, but you can get the data from Woo, and at least use that to search GF entries.
I was able to do this using Gravity Forms, Gravity Forms Product Addons, and Woocommerce using a three step process:
STEP 1: Get GF Entry ID/s as the entry is made and store it in a session. This happens before checkout is complete and sometimes before the user is logged in.
add_action( 'gform_after_submission', 'blb_get_lead_entry_id', 10, 2 );
function blb_get_lead_entry_id( $entry, $form ) {
$meta_value = $entry['id'];
//session array with all the entries because GF creates 2 entries each time for validation purposes apparently
if (!isset($_SESSION['entryclump'])) {
$_SESSION['entryclump'] = array();
}
$_SESSION['entryclump'][] = $meta_value;
//also an array with just the current entry which will end up be the later of the two entries added by GF
$_SESSION[ 'gf-entry-id' ] = $meta_value;
}
STEP 2: Include the entry you just gathered ($_SESSION[ 'gf-entry-id' ]) with the Cart Item Meta and then save it.
In this case, i am saving a field called "_gf_entry_ID" which will get added to the woocommerce_order_itemmeta table with the correct order_item_id and the later of the two GF entries as the meta_value.
//add cart item data
add_filter( 'woocommerce_add_cart_item_data', 'blb_add_gfentry_to_cart_data', 10, 3 );
function blb_add_gfentry_to_cart_data( $cartItemData, $productId, $variationId ) {
$entryid=$_SESSION[ 'gf-entry-id' ];
$cartItemData['GFentryID'] = $entryid;
return $cartItemData;
unset($_SESSION[ 'gf-entry-id' ]);
}
//add cart item data: session stuff
add_filter( 'woocommerce_get_cart_item_from_session', 'blb_cart_item_session', 10, 3 );
function blb_cart_item_session( $cartItemData, $cartItemSessionData, $cartItemKey ) {
if ( isset( $cartItemSessionData['GFentryID'] ) ) {
$cartItemData['GFentryID'] = $cartItemSessionData['GFentryID'];
}
return $cartItemData;
}
//save the data
add_action( 'woocommerce_add_order_item_meta', 'blb_save_gfentry', 10, 3 );
function blb_save_gfentry( $itemId, $values, $key ) {
if ( isset( $values['GFentryID'] ) ) {
wc_add_order_item_meta( $itemId, '_gf_entry_ID', $values['GFentryID'] );
}
}
STEP 3 (optional): Update the GF Form to reflect the correct created_by user ID. Now that checkout is complete and the user is logged in, we can do that.
function blb_woocommerce_thankyou( $order_id ) {
//Current User
$currentUserID = wp_get_current_user()->ID;
//GF Entry Array for Order
$order = new WC_Order( $order_id );
$items = $order->get_items();
$order_item_ids = array();
$gf_entry_ids = array();
foreach ( $items as $key=>$item ) {
$gf_entry_ids[] = $item['item_meta']['_gf_entry_ID'][0];
}
//First real quick clear all the entries in the entry clump (in case the user was already logged in)
//This is important because GF creates two forms for product add ons with Woocommerce and we only want one to show up in the list and edit plugin
$entryclump = $_SESSION[ 'entryclump' ];
foreach ( $entryclump as $entry ) {
global $wpdb;
$wpdb->update('wp_rg_lead', array('created_by' => null), array('id' => $entry));
}
//Update wp_rg_lead
if (($currentUserID!=0) && (isset($_SESSION[ 'entryclump' ])) ) {
foreach ( $gf_entry_ids as $gf_entry_id ) {
global $wpdb;
$wpdb->update('wp_rg_lead', array('created_by' => $currentUserID), array('id' => $gf_entry_id));
} //foreach
} //if
unset($_SESSION[ 'entryclump' ]);
};
add_action( 'woocommerce_thankyou', 'blb_woocommerce_thankyou', 10, 1 );
I have the following function that adds a column in the Sales Log so that I may show the Order Notes. Adding the column is good and showing the id of each item ($item->id) as test is good. Where I am getting stuck is how to display the actual order notes for each item.
Tried numerous things including ($purchlog_notes->notes);
This adds the column (all good)
`function addPurchaseLogColumnHead( $columns ){
$columns['OrderNotes']=__('Order Notes');
return $columns;
}
add_filter( 'manage_dashboard_page_wpsc-purchase-logs_columns', 'addPurchaseLogColumnHead');`
This is where I want to show Order Notes content for each sale (issue)
`function addPurchaseLogColumnContent( $default, $column_name, $item ) {
if ($column_name == 'OrderNotes'){
echo $item->notes;
}
}
add_filter( 'wpsc_manage_purchase_logs_custom_column' , 'addPurchaseLogColumnContent', 10, 3);`
Appreciate any ideas.
Thank you.