I am trying to get the date when an order was marked as Status: "Cancelled".
My current approach involves getting all order notes using wc_get_order_notes()
.
Any better approach to get this information?
function get_cancellation_date_with_timezone($order_id) {
$order = wc_get_order($order_id);
if (!$order) {
return false; // Order not found
}
// Retrieve all order notes
$notes = wc_get_order_notes(array('order_id' => $order_id));
foreach ($notes as $note) {
// Check if the note indicates a status change to 'Cancelled'
if (strpos($note->content, 'Order status changed from') !== false && strpos($note->content, 'to Cancelled') !== false) {
// Get the date created and timezone
$date_created = $note->date_created;
$timezone = new DateTimeZone($date_created->getTimezone()->getName());
// Create a DateTime object with timezone
$date = new DateTime($date_created->date('Y-m-d H:i:s'), $timezone);
// Format the date with timezone
return $date;
}
}
return false; // Cancellation note not found
}
$cancellation_date = get_cancellation_date_with_timezone($order_id = 1234);
echo $cancellation_date->format('Y-m-d\TH:i:sP');
You could use woocommerce_order_status_cancelled
dedicated hook to add the cancelled date as WC_Order custom metadata, when an order is cancelled, like (compatible with HPOS):
add_action( 'woocommerce_order_status_cancelled', 'add_order_cancellation_date', 10, 2 );
function add_order_cancellation_date( $order_id, $order ) {
$created_date = $order->get_date_created(); // Get date (WC_DateTime object)
$date_timezone = $created_date->getTimezone(); // Get time zone (DateTimeZone Object)
$date_cancelled = new WC_DateTime(); // Get current date (WC_DateTime object)
$date_cancelled->setTimezone($date_timezone); // Set time zone
// Add cancelled date as custom metadata and save
$order->update_meta_data('date_cancelled', $date_cancelled->format( DateTime::ATOM ));
$order->save();
}
Code goes in functions.php file of your child theme (or in a plugin).
Then you can get the cancelled order date, from the WC_Order object, using:
$date_cancelled = $order->get_meta('date_cancelled');
Now for previous canceled orders, you could take the order modified date that reflect the order date of the last edit, using get_date_modified()
method like:
$date_cancelled = $order->get_date_modified(); // WC_DateTime object
The you could use add follwowing function that will handle all cases, to get the order cancelled date (return false if the order is not cancelled):
function wc_get_order_cancelled_date( $order ) {
if ( ! $order->has_status('cancelled') ) {
return false;
}
if ( $date_cancelled = $order->get_meta('date_cancelled') ) {
return $date_cancelled;
} else {
return $order->get_date_modified()->format( DateTime::ATOM );
}
}
Code goes in functions.php file of your child theme (or in a plugin).
Then you can get the cancelled order date, from the WC_Order object, using:
$date_cancelled = wc_get_order_cancelled_date( $order ); // Formatted date string or false