如何根据 Select 交货日期 woocommerce 结帐添加订单费用?

How to add order fee based on Select Delivery Date woo commerce checkout?

我在 woo-commerce 结账时使用 xdsoft 日期时间选择器,如果用户在日期时间选择器上选择同一天或明天,则需要添加额外费用。我不确定该怎么做,如果有人能帮助我,我将不胜感激。

下面是我目前使用的代码,它在这种情况下工作正常。

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 );

您可以使用woocommerce_cart_calculate_fees添加费用。

使用add_fee()功能添加费用。您需要计算今天和明天的 datediff。此外,您可以看到 PHP: How to check if a date is a today, yesterday or tomorrow 试试下面的代码。

/**
 * 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' );
  

在datetimepicker中可以使用onSelectDate and onSelectTime事件触发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 );

保存 Select Delivery Date 并在订单编辑页面和电子邮件中显示。

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 );