I am using xdsoft date time picker at woo-commerce checkout and need to add an extra fee if a user selects the same day or tomorrow on the date time picker. I am not sure how to go with this and would appreciate it if someone can help me with this.
Below is the code I am using currently and it is working fine for the situation.
function date_time_picker( $checkout ) {
woocommerce_form_field( 'delivery_date', array(
'type' => 'text',
'class' => array('form-row-wide'),
'id' => 'datepicker',
'required' => true,
'label' => __('Select Delivery Date'),
'placeholder' => __('Click to select date'),
));
}
add_action( 'woocommerce_after_order_notes', 'date_time_picker' );
function validate_new_checkout_fields() {
if ( isset( $_POST['delivery_date'] ) && empty( $_POST['delivery_date'] ) ) wc_add_notice( __( 'Please select the Delivery Date' ), 'error' );
}
add_action( 'woocommerce_checkout_process', 'validate_new_checkout_fields' );
function enable_datepicker() {
?>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js"></script>
<?php
}
add_action( 'woocommerce_after_checkout_form', 'enable_datepicker', 10 );
function load_calendar_dates( $available_gateways ) {
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
jQuery.datetimepicker.setLocale('en');
var currentDate = new Date();
var minutes = currentDate.getMinutes();
var m = (Math.ceil(minutes/30) * 30) % 60;
currentDate.setMinutes(m);
jQuery('#datepicker').datetimepicker({
beforeShowDay: $.datepicker.noWeekends,
format: 'Y/m/d H:i:s',
minDate: 0,
minTime: '8:00',
step: "30",
allowTimes:[
'09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30',
'13:00', '13:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00'
]
});
});
</script>
<?php
}
add_action( 'woocommerce_after_checkout_form', 'load_calendar_dates', 20 );
You can use woocommerce_cart_calculate_fees
to add fees.
Use add_fee()
function to add fees. You need to calculate datediff for today and tomorrow day. furthermore, you can see PHP: How to check if a date is a today, yesterday or tomorrow Try the below code.
/**
* Add a standard $ value surcharge to all transactions in cart/checkout
*/
function wc_add_surcharge() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
return;
}
// change the $fee to set the surcharge to a value to suit
parse_str($_POST['post_data'], $post_data);
if( isset( $post_data['delivery_date'] ) && $post_data['delivery_date'] != '' ){
$current = strtotime(date("Y-m-d"));
$date = strtotime($post_data['delivery_date']);
$datediff = $date - $current;
$difference = floor($datediff/(60*60*24));
if( $difference == 0 || $difference == 1 ){
$fee = 5.00; // today and tomorrow
$woocommerce->cart->add_fee( 'Fast delivery charge', $fee, true, 'standard' );
} else {
// other day
$fees = WC()->cart->get_fees();
foreach ($fees as $key => $fee) {
if($fees[$key]->name === __( "Fast delivery charge")) {
unset($fees[$key]);
}
}
WC()->cart->fees_api()->set_fees($fees);
}
}
}
add_action( 'woocommerce_cart_calculate_fees','wc_add_surcharge' );
function date_time_picker( $checkout ) {
woocommerce_form_field( 'delivery_date', array(
'type' => 'text',
'class' => array('form-row-wide'),
'id' => 'datepicker',
'required' => true,
'label' => __('Select Delivery Date'),
'placeholder' => __('Click to select date'),
));
}
add_action( 'woocommerce_after_order_notes', 'date_time_picker' );
function validate_new_checkout_fields() {
if ( isset( $_POST['delivery_date'] ) && empty( $_POST['delivery_date'] ) ) wc_add_notice( __( 'Please select the Delivery Date' ), 'error' );
}
add_action( 'woocommerce_checkout_process', 'validate_new_checkout_fields' );
In datetimepicker You can use onSelectDate and onSelectTime event to trigger update_checkout
function load_calendar_dates( $available_gateways ) {
?>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($) {
jQuery.datetimepicker.setLocale('en');
var currentDate = new Date();
var minutes = currentDate.getMinutes();
var m = (Math.ceil(minutes/30) * 30) % 60;
currentDate.setMinutes(m);
jQuery('#datepicker').datetimepicker({
beforeShowDay: $.datepicker.noWeekends,
format: 'Y/m/d H:i:s',
minDate: 0,
minTime: '8:00',
step: "30",
allowTimes:[
'09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00'
],onSelectDate:function(ct,$i){
$( 'body' ).trigger( 'update_checkout' );
},onSelectTime:function(ct,$i){
$( 'body' ).trigger( 'update_checkout' );
}
});
});
</script>
<?php
}
add_action( 'woocommerce_after_checkout_form', 'load_calendar_dates', 20 );
Save Select Delivery Date
and show in Order edit page and emails.
function save_delivery_date_field( $order_id ) {
if ( $_POST['delivery_date'] ) update_post_meta( $order_id, 'delivery_date', esc_attr( $_POST['delivery_date'] ) );
}
add_action( 'woocommerce_checkout_update_order_meta', 'save_delivery_date_field' );
function show_delivery_date_field_order( $order ) {
$order_id = $order->get_id();
if ( get_post_meta( $order_id, 'delivery_date', true ) ) echo '<p><strong>Delivery Date:</strong> ' . get_post_meta( $order_id, 'delivery_date', true ) . '</p>';
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'show_delivery_date_field_order', 10, 1 );
function show_delivery_date_field_emails( $order, $sent_to_admin, $plain_text, $email ) {
if ( get_post_meta( $order->get_id(), 'delivery_date', true ) ) echo '<p><strong>Delivery Date:</strong> ' . get_post_meta( $order->get_id(), 'delivery_date', true ) . '</p>';
}
add_action( 'woocommerce_email_after_order_table', 'show_delivery_date_field_emails', 20, 4 );