I need create custom order tracking functionality in woo commerce - woocommerce

Hello I have a woo commerce website and I am selling some books every thing is cleared but I need create custom order tracking functionality in woo commerce code to add order tracking functionality for end user is it possible if possible how can I do this please help me.
I create a custom page name as woocommerce-custom-order-tracking.php
and code is given below
<?php
// Register a custom endpoint to handle order tracking
function wc_register_order_tracking_endpoint() {
add_rewrite_endpoint( 'order-tracking', EP_PAGES );
}
add_action( 'init', 'wc_register_order_tracking_endpoint' );
// Display the order tracking form
function wc_display_order_tracking_form() {
if ( ! is_wc_endpoint_url( 'order-tracking' ) ) {
return;
}
// Get the order id from the query string
$order_id = absint( $_GET['order_id'] );
// Get the order
$order = wc_get_order( $order_id );
if ( $order ) {
// Display the order tracking information
echo '<p>Order Number: ' . $order->get_order_number() . '</p>';
echo '<p>Order Status: ' . wc_get_order_status_name( $order->get_status() ) . '</p>';
echo '<p>Tracking Number: ' . get_post_meta( $order_id, '_tracking_number', true ) . '</p>';
} else {
echo '<p>Invalid order ID.</p>';
}
}
add_action( 'woocommerce_before_single_product', 'wc_display_order_tracking_form' );

Related

Redirecting customers to custom page after sale in WooCommerce

I'm trying to learn WooCommerce and WordPress plugins so I'm tweaking around. I'm trying to create a plugin that redirects customer to a custom page after checkout. The custom page/url can be defined when I create the product. Here is my code:
<?php
/*
Plugin Name: Custom Redirect After Sale
Description: Redirects customers to a custom page after a successful sale.
*/
// Register a new meta field for products
add_action( 'add_meta_boxes', 'custom_redirect_meta_box' );
function custom_redirect_meta_box() {
add_meta_box( 'custom_redirect_meta_box', 'Custom Redirect URL', 'custom_redirect_meta_box_callback', 'product', 'side' );
}
function custom_redirect_meta_box_callback( $post ) {
$value = get_post_meta( $post->ID, '_custom_redirect_url', true );
echo '<label for="custom_redirect_url">Custom Redirect URL:</label>';
echo '<input type="text" id="custom_redirect_url" name="custom_redirect_url" value="' . esc_attr( $value ) . '" style="width:100%">';
}
// Save the meta field value when the product is saved
add_action( 'save_post_product', 'save_custom_redirect_meta_box_data' );
function save_custom_redirect_meta_box_data( $post_id ) {
if ( isset( $_POST['custom_redirect_url'] ) ) {
update_post_meta( $post_id, '_custom_redirect_url', sanitize_text_field( $_POST['custom_redirect_url'] ) );
}
}
// Redirect to the custom page after a successful sale
add_action( 'woocommerce_payment_complete', 'custom_redirect_after_sale' );
function custom_redirect_after_sale( $order_id ) {
$order = wc_get_order( $order_id );
//$order->update_status( 'completed' );
$items = $order->get_items();
// Get the first product in the order
$product = reset($items);
// Get the custom redirect URL for the product
//$redirect_url = get_post_meta( $product->get_product_id(), '_custom_redirect_url', true );
$redirect_url = get_post_meta( $product->get_id(), '_custom_redirect_url', true );
//echo "Meta retrieved: " . $redirect_url;
//error_log("callback fired");
//echo "Payment complete ho ho ho";
if( $redirect_url ) {
wp_redirect( $redirect_url );
exit;
}
}
It seems the woocommerce_payment_complete hook is not firing. I tried to echo out the redirect url and text but it doesn't seem to work.
I'm on localhost and I'm using the cash on delivery payment method.
Basing this answer on the great https://rudrastyh.com/ - specifically this tutorial https://rudrastyh.com/woocommerce/thank-you-page.html#redirects this is the code that should work for what you are trying to do.
First, you hook into the template_redirect action to determine the URL where the customer needs to go
Getting the Order ID, you can get the products purchased for that order
Once you have the purchased products, you can get their ID and meta data, the redirect URL you saved for each. Note that while you use WP functions for handling meta, when working with WooCommerce it is best practice to use its CRUD methods. In case in the future they port products to custom tables, your code will continue working.
Implement the redirect with the WP function wp_safe_redirect
Note that what you are trying to achieve will have problems if customers purchase orders with more than 1 product, and you have more than 1 redirect URL. In this implementation, the first product in the order that has a saved redirect URL will override all others
add_action( 'template_redirect', 'purchased_product_redirect');
function purchased_product_redirect(){
if( !function_exists( 'is_wc_endpoint_url' )){
return;
}
// do nothing if we are not on the order received page
if( ! is_wc_endpoint_url( 'order-received' ) || empty( $_GET[ 'key' ] ) ) {
return;
}
// Get the order ID
$order_id = wc_get_order_id_by_order_key( $_GET[ 'key' ] );
// Get an instance of the WC_Order object
$order = wc_get_order( $order_id );
// Get and Loop Over Order Items
foreach ( $order->get_items() as $item_id => $item ) {
$product_id = $item->get_product_id();
$product = wc_get_product($product_id);
if(!$product){
continue;
}
//Get the first product's redirect URL
$product_redirect_url = $product->get_meta('_custom_redirect_url');
if(!$product_redirect_url){
continue;
}
wp_safe_redirect( $product_redirect_url );
exit; // always exit after using wp_safe_redirect
}
}

How to check WooCommerce order meta before sending email notification

I'm trying to add custom meta to my new order emails. At this moment, custom meta shows up when I use the "Resend new order notification", but it doesn't when a purchase is made through the website.
I suspect this has to do with my code not being able to check the Order Details before sending the email notification. Here's the code I came up with so far..
// Ref: https://www.businessbloomer.com/woocommerce-add-extra-content-order-email/
function custom_order_type_number_email( $order, $sent_to_admin, $plain_text, $email ) {
// Get custom Order Type and Order Number meta keys
$custom_order_type = get_post_meta( $order->get_id(), 'custom_order_type', true );
$custom_order_number = get_post_meta( $order->get_id(), 'custom_order_number', true );
// Add for New Order email notification only
if ( $email->id == 'new_order' ) {
if ( !empty( $custom_order_type ) ) {
echo '<p><b>Order type :</b> ' . $custom_order_type . '</p>';
} else {
echo '<p><b>Order type :</b> Website</p>';
}
if ( !empty( $custom_order_number ) ) {
echo '<p><b>Order no :</b> ' . $custom_order_number . '</p>';
} else {
echo '<p><b>Order no :</b> New</p>';
}
}
}
add_action( 'woocommerce_email_after_order_table', 'custom_order_type_number_email', 20, 4 );
What I'm trying to do ideally is..
When the customer purchases from the website, this new order will be without the custom meta. So the custom meta in the email will show Order type: Website / Order number: New.
And if the admin manually adds a new order with defined custom meta, this new order email notification would get and show the saved custom meta later.
I hope this made sense. (>_<) And thanks in advance for the help.

Add custom field to the custom Woocommerce Emails

I want to add delivery date in woocommerce emails, the hook I am using is
add_action( 'woocommerce_order_details_after_order_table', 'action_woocommerce_order_details_after_order_table', 10, 1 );
function action_woocommerce_order_details_after_order_table( $order ) {
...
$order_expected_delivery_date = get_post_meta($order_id, 'order_expected_delivery_date_'.$order_id, true);
if(!$order_expected_delivery_date) {
$delivery_date = getExpectedDeliveryDate($order);
update_post_meta($order_id, 'order_expected_delivery_date_'.$order_id, $delivery_date);
echo "<header><h2>Expected Delivery Date</h2></header><p style='font-size: 20px;'>".$delivery_date."<p>";
} else {
echo "<header><h2>Expected Delivery Date</h2></header><p style='font-size: 20px;'>".$order_expected_delivery_date."<p>";
}
}
but this hook is only called when the woocommerce order emails are triggered. I have made a custom email for sending to the warehouse as per requirement. This hook is not working for the custom emails.
I have tried to add the shortcode to the custom emails but that short code is also not working.
function delivery_date_shortcode( $atts, $content = null ) {
if( is_numeric($content) ) {
$order = wc_get_order( $content );
$order_data = $order->get_data();
return '<span class="caption">' . $order_data . '</span>';
}
}
add_shortcode( 'delivery', 'delivery_date_shortcode' );
I forgot to tell you that this issue is resolved.
// shortcode to display expected delivery date in warehouse email
function delivery_date_shortcode( $atts, $content = null ) {
$order = new \WC_Order($content);
$delivery_date = getExpectedDeliveryDate($order);
return "<header><h2 style='margin: 40px 0 18px;'>Expected Delivery Date</h2></header><p style='font-size: 20px;'>".$delivery_date."<p>";
}
add_shortcode( 'delivery', 'delivery_date_shortcode' );
The function getExpectedDeliveryDate($order) takes the order id and returns the expected delivery date.
Thank You.

Show the name of the chosen variation under the product title on the My Account > Downloads page

By default WooCommerce shows the attribute of a variable product in the title and I'm using this code to show the attribute below the title in the cart and checkout pages:
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
add_filter( 'woocommerce_is_attribute_in_product_name', '__return_false' );
But that doesn't work in My Account page, users see the full product name with no attribute.
To fix it I'm using the code below to show the attribute in the product title:
function show_attributes_outside_title_1( $enabled ) {
if ( !is_account_page() ) {
$enabled = false;
}
return $enabled;
}
add_filter( 'woocommerce_product_variation_title_include_attributes', 'show_attributes_outside_title_1' );
function show_attributes_outside_title_2( $enabled ) {
if ( !is_account_page() ) {
$enabled = false;
}
return $enabled;
}
add_filter( 'woocommerce_is_attribute_in_product_name', 'show_attributes_outside_title_2' );
But I'd like to show the attribute below the title (or a new column), it's easier to read and goes with the same desing you see in the cart and checkout pages.
There is some confusion in the initial part of the question.
You say you want to show the attribute under the product title on the cart and checkout page but then return __return_false, do you intend to do the opposite?
SOLUTION #1
You may want to reverse the check to make sure that your chosen product variation attribute is shown under the product name on your account page under Downloads (as evidenced by your comment above):
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
add_filter( 'woocommerce_is_attribute_in_product_name', '__return_false' );
add_filter( 'woocommerce_product_variation_title_include_attributes', 'show_attributes_outside_title_1' );
function show_attributes_outside_title_1( $enabled ) {
if ( is_account_page() ) {
$enabled = true;
}
return $enabled;
}
add_filter( 'woocommerce_is_attribute_in_product_name', 'show_attributes_outside_title_2' );
function show_attributes_outside_title_2( $enabled ) {
if ( ! is_account_page() ) {
$enabled = false;
}
return $enabled;
}
SOLUTION #2
If you want to leave the code in your question unchanged you can use the woocommerce_account_downloads_column_download-product hook where download-product is the id of the product name column (in the /my-account/downloads/ page). Here the documentation.
Finally, with the wc_get_formatted_variation function you can get the name of the chosen variation. For more information on parameters read the documentation.
// shows the variation chosen in the product name in the download table of the my-account page
add_action( 'woocommerce_account_downloads_column_download-product', 'change_product_download_name', 10, 1 );
function change_product_download_name( $download ) {
// gets the product object
$product = wc_get_product( $download['product_id'] );
// gets the name of the produc
$product_name = $download['product_name'];
// if the product is a variation
if ( $product->is_type( 'variation' ) ) {
// gets the name of the product with the chosen variation
$product_name = $product->get_name() . " - " . wc_get_formatted_variation( $product, true, false, false );
}
// print the product name (with or without product url)
if ( $download['product_url'] ) {
echo '' . esc_html( $product_name ) . '';
} else {
echo esc_html( $product_name );
}
}
The code has been tested and works. Add it to your active theme's functions.php.
I changed Vincenzo's answer a bit to make it look the same way I see the attributes in my Cart and Checkout pages. Here's the code in case anybody else needs it:
// Shows the variation chosen in the product name in the download table of the my-account page
add_action( 'woocommerce_account_downloads_column_download-product', 'change_product_download_name', 10, 1 );
function change_product_download_name( $download ) {
// gets the product object
$product = wc_get_product( $download['product_id'] );
// gets the name of the product
$product_name = $download['product_name'];
// define variable
$product_attributes = '';
// if the product is a variation
if ( $product->is_type( 'variation' ) ) {
// gets the name of the product with the chosen variation
$product_name = $product->get_name();
$product_attributes = wc_get_formatted_variation( $product, true, true, false );
}
// print the product name (with or without product url)
if ( $download['product_url'] ) {
echo '' . esc_html( $product_name ) . '<p>' . esc_html( $product_attributes ) . '</p>';
} else {
echo esc_html( $product_name ) . '<p>' . esc_html( $product_attributes ) . '</p>';
}
}
// Shows variation outside title in cart and checkout pages
add_filter( 'woocommerce_product_variation_title_include_attributes', '__return_false' );
add_filter( 'woocommerce_is_attribute_in_product_name', '__return_false' );
The last two filters replace my code and the first part solves the issue in the Downloads page.

How to display customer name in woocommerce email template?

I'm new to Woocommerce, and I'm trying to show the name of the customer in the beginning of the email.
So the email will look something like this:
[HEADER]You order has been placed [/HEADER]
[H2]Hi {CUSTOMER_NAME}[/H2]
[P]Some text[/P]
[THE REST OF THE MAIL]
I've tried adding something like this to functions.php in my theme.
//add the first name of the person to the email.
add_filter('woocommerce_email_order_details','name_to_processing_customer_email', 10, 3);
function name_to_processing_customer_email( $order, $sent_to_admin, $plain_text, $email ) {
if( 'customer_processing_order' == $email->id ){
// Set here as you want your custom content (for customers and email notification related to processing orders only)
echo '<h2>Hej '.$order->billing_first_name .'</h2>';
}
}
But this doesn't work.
Can someone help?
Try this One ::
add_filter('woocommerce_email_order_details','name_to_processing_customer_email', 10, 3);
function name_to_processing_customer_email( $order_id, $sent_to_admin, $plain_text, $email ) {
$order = new WC_Order( $order_id );
echo '<h2>Hej '.$order->billing_first_name .' '.$order->billing_last_name.'</h2>';
}
add_action( 'woocommerce_email_after_order_table', 'name_to_processing_customer_email', 10, 2 );
function name_to_processing_customer_email( $order, $is_admin_email ) {
echo '<p><h4>Shipping:</h4> ' . $order->get_billing_first_name() . '</p>';
}
Check this WC3 snippet

Resources