Preferred Delivery Date Field at Checkout
Adds a date picker to the classic checkout so customers can choose a delivery date after your lead time, then shows the date on the order screen and in emails.
Opens WPIDE on
Code
$wpide_delivery = array(
'label' => 'Preferred delivery date',
'lead_days' => 2, // Earliest date = today + this many days.
'max_days' => 60, // Latest date customers can pick.
'required' => false,
'skip_weekends' => true,
);
add_filter( 'woocommerce_checkout_fields', function ( $fields ) use ( $wpide_delivery ) {
$fields['order']['wpide_delivery_date'] = array(
'type' => 'date',
'label' => $wpide_delivery['label'],
'required' => $wpide_delivery['required'],
'priority' => 5,
'custom_attributes' => array(
'min' => wp_date( 'Y-m-d', strtotime( '+' . $wpide_delivery['lead_days'] . ' days' ) ),
'max' => wp_date( 'Y-m-d', strtotime( '+' . $wpide_delivery['max_days'] . ' days' ) ),
),
);
return $fields;
} );
add_action( 'woocommerce_after_checkout_validation', function ( $data, $errors ) use ( $wpide_delivery ) {
$value = (string) ( $data['wpide_delivery_date'] ?? '' );
if ( '' === $value ) {
return;
}
$date = DateTime::createFromFormat( '!Y-m-d', $value, wp_timezone() );
if ( ! $date || $date->format( 'Y-m-d' ) !== $value ) {
$errors->add( 'validation', 'Please choose a valid delivery date.' );
return;
}
$earliest = new DateTime( 'today +' . $wpide_delivery['lead_days'] . ' days', wp_timezone() );
if ( $date < $earliest ) {
$errors->add( 'validation', sprintf( 'The earliest delivery date is %s.', esc_html( wp_date( get_option( 'date_format' ), $earliest->getTimestamp() ) ) ) );
} elseif ( $wpide_delivery['skip_weekends'] && (int) $date->format( 'N' ) >= 6 ) {
$errors->add( 'validation', 'We do not deliver at weekends. Please choose a weekday.' );
}
}, 10, 2 );
add_action( 'woocommerce_checkout_create_order', function ( $order, $data ) {
if ( ! empty( $data['wpide_delivery_date'] ) ) {
$order->update_meta_data( '_wpide_delivery_date', sanitize_text_field( $data['wpide_delivery_date'] ) );
}
}, 10, 2 );
$wpide_delivery_label = $wpide_delivery['label'];
add_action( 'woocommerce_admin_order_data_after_shipping_address', function ( $order ) use ( $wpide_delivery_label ) {
$date = $order->get_meta( '_wpide_delivery_date' );
if ( $date ) {
printf( '<p><strong>%s:</strong> %s</p>', esc_html( $wpide_delivery_label ), esc_html( wp_date( get_option( 'date_format' ), strtotime( $date ) ) ) );
}
} );
add_filter( 'woocommerce_email_order_meta_fields', function ( $fields, $sent_to_admin, $order ) use ( $wpide_delivery_label ) {
$date = $order->get_meta( '_wpide_delivery_date' );
if ( $date ) {
$fields['wpide_delivery_date'] = array( 'label' => $wpide_delivery_label, 'value' => wp_date( get_option( 'date_format' ), strtotime( $date ) ) );
}
return $fields;
}, 10, 3 );
Notes
Uses the browser's date picker; set 'lead_days' for the earliest date and 'skip_weekends' to refuse Saturdays and Sundays.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.