首页 > 解决方案 > Woocommerce 订单到期日

问题描述

我使用 WooCommerce 销售分阶段的设计服务(草稿、批准、客户审查、第 2 阶段、最终交付......)。我正在使用订单状态管理器在每次状态更新时都有自定义状态和电子邮件客户。我需要为每个订单的每个阶段设置一个截止日期。

基本上结果是:

Order: #100 - Status: Pending Payment Confirmation - Due Date: None
Order: #100 - Status: Send initial draft - Due Date: June 22, 2018
Order: #100 - Status: Send review - Due Date: June 24, 2018
Order: #100 - Status: Send final version - Due Date: June 26, 2018

基本上:在 WooCommerce 订单页面的新自定义列中自己设置日期。

这些日期不应该对客户可见。截止日期是我们自己的控制。

这是结果应该是什么的图像

标签: phpwordpresswoocommerce

解决方案


所以基本上你想要两件事。

  1. 将自定义字段“到期日”添加到每个订单。
  2. 在订单状态更改时,相应地设置到期日。

更新,OP改变了问题。

创建自定义列以显示自定义订单元数据非常简单。如果您想直接在列中设置(保存)数据,您必须决定如何执行此操作,恕我直言 Ajax 是最佳解决方案。

简而言之,下面的代码执行以下操作:

  • 在 wc 订单页面上创建自定义到期日期列。
  • 使用输入填充自定义列。
  • 处理 wp ajax 调用服务器端。
  • 加载设置日期选择器并使用 Ajax 保存新截止日期的 JS 页脚脚本。

将此代码放在您的孩子-themefunctions.php中。使用子主题,因此您仍然可以更新您的主题!

经 WOO 3.4.2 测试

请参阅代码注释以获取更多信息。

/**
 * Load jQuery datepicker on WC orders page
**/
add_action( 'admin_enqueue_scripts', 'wc_orders_page_enqueue_datepicker' );
function wc_orders_page_enqueue_datepicker() {
  global $pagenow;
  if ( $pagenow == 'edit.php' && $_GET['post_type'] == 'shop_order' ) {
    wp_enqueue_script('jquery-ui-datepicker');
  }
}

/**
 * Add due date column to WC orders page before the order_total column
**/
add_filter( 'manage_edit-shop_order_columns', 'wc_due_date_order_column' );
function wc_due_date_order_column( $columns ) {
  $new_columns = array();
  foreach ( $columns as $column_name => $column_info ) {
    if ( $column_name == 'order_total' ) {
      $new_columns['order_due_date'] = 'Due Date';
    }
    $new_columns[ $column_name ] = $column_info;
  }
  return $new_columns;
}

/**
 * Set due date column content
**/
add_action( 'manage_shop_order_posts_custom_column', 'wc_due_date_column_content' );
function wc_due_date_column_content( $column ) {
  global $post;
  if ( $column == 'order_due_date' ) {
    $order = wc_get_order( $post->ID );
    $due_date = $order->get_meta( '_order_due_date', true );
    error_log('due date: '.$due_date);

    // a tag is needed to break default wc 'go to order on tr click' behaviour
    echo '<a id="'.$post->ID.'" href="#"><input type="text" class="order_due_date" name="order_due_date" style="width:65%" value="'.$due_date.'"/><div class="ajax_due_date_notice" style="display:inline-block; width:32%; margin-left:2%;"></div></a>';
  }
}

/**
 * Handle save due date ajax call
**/
add_action( 'wp_ajax_save_due_date', 'ajax_save_due_date' );
function ajax_save_due_date() {
  check_ajax_referer( 'dgfdgDFSKF32', 'security' ); // if check failed, this method will run wp_die()
  $order_id = intval( $_POST['order_id'] );
  $new_due_date = $_POST['new_due_date'];

  if($order_id && $new_due_date) {
    $order = wc_get_order( $order_id );
    if($order) {
      $order->update_meta_data( '_order_due_date', $new_due_date );
      $order->save();
      echo '1';
    } else {
      echo '0';
    }
  } else {
    echo '0';
  }
  wp_die(); // this is required to return a proper result
}

/**
 * Admin footer script that sets the datepicker and handles due date input changes
**/
add_action( 'admin_footer', 'wc_due_date_footer_script' );
function wc_due_date_footer_script() {
  global $pagenow;
  $ajax_nonce = wp_create_nonce( "dgfdgDFSKF32" );

  if (( $pagenow == 'edit.php' ) && ($_GET['post_type'] == 'shop_order')) :
  ?>
  <script type="text/javascript">
    jQuery(document).ready(function($) {

      $('.order_due_date').datepicker({
        dateFormat : 'dd-mm-yy'
      });

      $( "input[name='order_due_date']" ).change(function() {
        var order_id = $(this).closest('a').attr('id');
        var new_due_date = $(this).val();
        var ajax_notice = $(this).closest('a').find('.ajax_due_date_notice');
        if(order_id && new_due_date) {
          ajax_notice.html('Saving...');
          ajax_save_order_due_date(order_id, new_due_date);
        }
      });

      // save due date with ajax
      var ajax_save_order_due_date = function(order_id, new_due_date) {
        var data = {
          action: 'save_due_date',
          security: '<?php echo $ajax_nonce; ?>',
          order_id: order_id,
          new_due_date: new_due_date
        };
        $.post( ajaxurl, data, function( response ) {
          console.log('response: ',response);
          if(response === '1') {
            $('a#'+order_id).find('.ajax_due_date_notice').html('<span style="color:green;">Saved!</span>');
            setTimeout(function(){ $('a#'+order_id).find('.ajax_due_date_notice').html(''); }, 3000);
          } else {
            $('a#'+order_id).find('.ajax_due_date_notice').html('<span style="color:red;">Saving failed!</span>');
          }
        });
      }

    });
  </script>
  <?php
  endif;
}

推荐阅读