如何根据取货和送货日期的计算来更改结算时的小计和总计?

huangapple go评论56阅读模式
英文:

How to change the subtotal and total based on the calculation of pickup and delivery date on checkout?

问题

我需要帮助使用wp日期选择器。我想要的是 - 结账页面上的客户可以选择提取和交付日期。选择日期后,购物车摘要显示计算 - 例如,如果我选择从24.07 - 26.07,那么计算显示为2天,并将产品价格乘以2。我会添加一个我需要的截图。

我现在有这个(functions.php) -

// 添加自定义结账日期选择器字段
add_action('woocommerce_before_order_notes', 'datepicker_custom_fields');
function datepicker_custom_fields($checkout) {
    $pickup_datepicker_slug = 'pickup_datepicker';
    $delivery_datepicker_slug = 'delivery_datepicker';

    echo '<div id="datepicker-wrapper">';

    woocommerce_form_field($pickup_datepicker_slug, array(
        'type' => 'text',
        'class'=> array('form-row-first my-datepicker'),
        'label' => __('Pickup date'),
        'required' => true,
    ), '');

    woocommerce_form_field($delivery_datepicker_slug, array(
        'type' => 'text',
        'class'=> array('form-row-first my-datepicker'),
        'label' => __('Delivery date'),
        'required' => true,
    ), '');

    echo '<br clear="all"></div>';

    // Jquery: 启用日期选择器
    ?>
    <script language="javascript">
    jQuery( function($){
        var pickup = '#<?php echo $pickup_datepicker_slug ?>';
        var delivery = '#<?php echo $delivery_datepicker_slug ?>';
        $(pickup).datepicker({
            dateFormat: 'dd.mm.yy', // ISO格式化日期
        });
        $(delivery).datepicker({
            dateFormat: 'dd.mm.yy', // ISO格式化日期
        });
    });
    </script>
    <?php
}

// 在结账后订单总额后显示额外信息
add_action('woocommerce_review_order_after_order_total', 'display_additional_info_after_total');
function display_additional_info_after_total() {
    // 从POST请求(结账页面)获取提取和交付日期
    $pickup_date = isset( $_POST['pickup_datepicker'] ) ? sanitize_text_field( $_POST['pickup_datepicker'] ) : '';
    $delivery_date = isset( $_POST['delivery_datepicker'] ) ? sanitize_text_field( $_POST['delivery_datepicker'] ) : '';

    // 计算提取日期和交付日期之间的天数差异
    $pickup_timestamp = strtotime( $pickup_date );
    $delivery_timestamp = strtotime( $delivery_date );
    $days_difference = ceil( ( $delivery_timestamp - $pickup_timestamp ) / ( 60 * 60 * 24 ) );

    // 基于购物车小计和天数差异计算费用
    $cart = WC()->cart;
    $fee = $cart->subtotal * $days_difference; // 根据需要修改此公式

    // 显示额外信息
    if ( $days_difference > 0 ) {
        echo '<p>Total ' . wc_price( $cart->subtotal + $fee ) . ' ( ' . wc_price( $fee ) . ' x ' . $days_difference . ' dienas )</p>';
    }
}

如何根据取货和送货日期的计算来更改结算时的小计和总计?

英文:

I need help with a wp date picker. The thing that I want is - customers on the checkout page can choose the pickup and delivery date. After choosing the date, the in-cart summary shows the calculation - For example, if I choose from 24.07 - 26.07, then the calculation shows 2 days and multiply the price of the product x2. I'll add a screenshot of what I need.

Right now I have this (functions.php) -

// Add custom checkout date picker fields
add_action( &#39;woocommerce_before_order_notes&#39;, &#39;datepicker_custom_fields&#39; );
function datepicker_custom_fields( $checkout ) {
$pickup_datepicker_slug = &#39;pickup_datepicker&#39;;
$delivery_datepicker_slug = &#39;delivery_datepicker&#39;;
echo &#39;&lt;div id=&quot;datepicker-wrapper&quot;&gt;&#39;;
woocommerce_form_field( $pickup_datepicker_slug, array(
&#39;type&#39; =&gt; &#39;text&#39;,
&#39;class&#39;=&gt; array( &#39;form-row-first my-datepicker&#39;),
&#39;label&#39; =&gt; __(&#39;Pickup date&#39;),
&#39;required&#39; =&gt; true,
), &#39;&#39; );
woocommerce_form_field( $delivery_datepicker_slug, array(
&#39;type&#39; =&gt; &#39;text&#39;,
&#39;class&#39;=&gt; array( &#39;form-row-first my-datepicker&#39;),
&#39;label&#39; =&gt; __(&#39;Delivery date&#39;),
&#39;required&#39; =&gt; true,
), &#39;&#39; );
echo &#39;&lt;br clear=&quot;all&quot;&gt;&lt;/div&gt;&#39;;
// Jquery: Enable the Datepicker
?&gt;
&lt;script language=&quot;javascript&quot;&gt;
jQuery( function($){
var pickup = &#39;#&lt;?php echo $pickup_datepicker_slug ?&gt;&#39;;
var delivery = &#39;#&lt;?php echo $delivery_datepicker_slug ?&gt;&#39;;
$(pickup).datepicker({
dateFormat: &#39;dd.mm.yy&#39;, // ISO formatting date
});
$(delivery).datepicker({
dateFormat: &#39;dd.mm.yy&#39;, // ISO formatting date
});
});
&lt;/script&gt;
&lt;?php
}
// Display additional information after order total in checkout
add_action( &#39;woocommerce_review_order_after_order_total&#39;, &#39;display_additional_info_after_total&#39; );
function display_additional_info_after_total() {
// Get the pickup and delivery dates from the POST request (checkout page)
$pickup_date = isset( $_POST[&#39;pickup_datepicker&#39;] ) ? sanitize_text_field( $_POST[&#39;pickup_datepicker&#39;] ) : &#39;&#39;;
$delivery_date = isset( $_POST[&#39;delivery_datepicker&#39;] ) ? sanitize_text_field( $_POST[&#39;delivery_datepicker&#39;] ) : &#39;&#39;;
// Calculate the difference in days between pickup and delivery dates
$pickup_timestamp = strtotime( $pickup_date );
$delivery_timestamp = strtotime( $delivery_date );
$days_difference = ceil( ( $delivery_timestamp - $pickup_timestamp ) / ( 60 * 60 * 24 ) );
// Calculate the fee based on the cart subtotal and days difference
$cart = WC()-&gt;cart;
$fee = $cart-&gt;subtotal * $days_difference; // Modify this formula if needed
// Display the additional information
if ( $days_difference &gt; 0 ) {
echo &#39;&lt;p&gt;Total &#39; . wc_price( $cart-&gt;subtotal + $fee ) . &#39; ( &#39; . wc_price( $fee ) . &#39; x &#39; . $days_difference . &#39; dienas )&lt;/p&gt;&#39;;
}
}

如何根据取货和送货日期的计算来更改结算时的小计和总计?

答案1

得分: 0

以下是翻译好的部分:

我不确定您正在使用的主题,但您可以像这样做。

在日期选择器的`onSelect`事件中,您可以通过这个WooCommerce调用的`woocommerce_before_calculate_totals`来触发`update_checkout`

// 添加自定义结帐日期选择器字段
function datepicker_custom_fields( $checkout ) {
    $pickup_datepicker_slug = 'pickup_datepicker';
    $delivery_datepicker_slug = 'delivery_datepicker';

    echo '<div id="datepicker-wrapper">';

    woocommerce_form_field( $pickup_datepicker_slug, array(
        'type' => 'text',
        'class'=> array( 'form-row-first my-datepicker'),
        'label' => __('Pickup date'),
        'required' => true,
    ), WC()->session->get( 'pickup_datepicker' ) );

    woocommerce_form_field( $delivery_datepicker_slug, array(
        'type' => 'text',
        'class'=> array( 'form-row-first my-datepicker'),
        'label' => __('Delivery date'),
        'required' => true,
    ), WC()->session->get( 'delivery_datepicker' ) );

    echo '<br clear="all"></div>';

    ?>
    <script type="text/javascript">
        jQuery(document).ready(function($) {

            var pickup = '#pickup_datepicker';
            var delivery = '#delivery_datepicker';
            $(pickup).datepicker({
                dateFormat: 'dd.mm.yy', // ISO formatting date
                onSelect: function(selected) {
                    var selectedDate = selected.split('.').reverse().join('-'); // Convert to 'yy-mm-dd' format
                    var minDate = new Date(selectedDate);
                    minDate.setDate(minDate.getDate() + 1);
                    $(delivery).datepicker("option", "minDate", minDate);
                    calculateDays();
                }
            });
            $(delivery).datepicker({
                dateFormat: 'dd.mm.yy', // ISO formatting date
                onSelect: function(selected) {
                    calculateDays();
                }
            });

            // Function to calculate the days between two dates
            function calculateDays() {
                $( document.body ).trigger( 'update_checkout' );
            }

        });
    </script>
    <?php

}
add_action( 'woocommerce_before_order_notes', 'datepicker_custom_fields' );

在这个过滤器中,您可以捕获您的`pickup_datepicker`和`delivery_datepicker`的值,并使用`DateTime`类和`diff`函数来计算天数,并使用`set_price`函数来设置购物车项目价格。

function override_cart_item_price( $cart ) {

    if ( is_admin() && ! defined( 'DOING_AJAX' ) ){
        return;
    }

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ){
        return;
    }

    parse_str($_POST['post_data'], $post_data);

    if (isset($post_data['pickup_datepicker']) && $post_data['pickup_datepicker'] != '' && isset($post_data['delivery_datepicker']) && $post_data['delivery_datepicker'] != '') {

        WC()->session->set('pickup_datepicker', sanitize_text_field($post_data['pickup_datepicker']));
        WC()->session->set('delivery_datepicker', sanitize_text_field($post_data['delivery_datepicker']));

        $pickup_datepicker = sanitize_text_field($post_data['pickup_datepicker']);
        $delivery_datepicker = sanitize_text_field($post_data['delivery_datepicker']);

        $pickup_date_obj = new DateTime($pickup_datepicker);
        $delivery_date_obj = new DateTime($delivery_datepicker);

        $interval = $pickup_date_obj->diff($delivery_date_obj);
        $days = $interval->days;
        $days = ( $days > 1 ) ? $days : 1 ;

        WC()->session->set('delivery_days', $days );

        foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
            // Calculate the new subtotal and total based on the number of days
            $new_price = $cart_item['data']->get_price() * $days;
            $cart_item['data']->set_price( $new_price );
            $cart_item['days'] = $days;
        }
    }

}
add_action( 'woocommerce_before_calculate_totals', 'override_cart_item_price', 99, 1 );

通过使用这个过滤器,您可以在价格旁边显示天数。

function add_days_woocommerce_cart_item_subtotal( $total, $cart_item, $cart_item_key ){
    $delivery_days = WC()->session->get( 'delivery_days' );
    if( $delivery_days ){
        $day_label = 'day';
        $product  = wc_get_product( $cart_item['product_id'] );
        if( $delivery_days > 1 ){
            $day_label = 'days';
        }
        $total = wc_price( $product->get_price() ) . ' x '. $delivery_days. '('.$day_label.')' . ' = '. $total;
    }
    return $total;
}

add_filter( 'woocommerce_cart_item_subtotal', 'add_days_woocommerce_cart_item_subtotal', 10, 3 );
英文:

I am not sure about which theme you are using but you can do something like this.

On date picker onSelect event you can trigger update_checkout by this woocommerce called woocommerce_before_calculate_totals

// Add custom checkout datepicker fields
function datepicker_custom_fields( $checkout ) {
$pickup_datepicker_slug = &#39;pickup_datepicker&#39;;
$delivery_datepicker_slug = &#39;delivery_datepicker&#39;;
echo &#39;&lt;div id=&quot;datepicker-wrapper&quot;&gt;&#39;;
woocommerce_form_field( $pickup_datepicker_slug, array(
&#39;type&#39; =&gt; &#39;text&#39;,
&#39;class&#39;=&gt; array( &#39;form-row-first my-datepicker&#39;),
&#39;label&#39; =&gt; __(&#39;Pickup date&#39;),
&#39;required&#39; =&gt; true,
), WC()-&gt;session-&gt;get( &#39;pickup_datepicker&#39; ) );
woocommerce_form_field( $delivery_datepicker_slug, array(
&#39;type&#39; =&gt; &#39;text&#39;,
&#39;class&#39;=&gt; array( &#39;form-row-first my-datepicker&#39;),
&#39;label&#39; =&gt; __(&#39;Delivery date&#39;),
&#39;required&#39; =&gt; true,
), WC()-&gt;session-&gt;get( &#39;delivery_datepicker&#39; ) );
echo &#39;&lt;br clear=&quot;all&quot;&gt;&lt;/div&gt;&#39;;
?&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
jQuery(document).ready(function($) {
var pickup = &#39;#pickup_datepicker&#39;;
var delivery = &#39;#delivery_datepicker&#39;;
$(pickup).datepicker({
dateFormat: &#39;dd.mm.yy&#39;, // ISO formatting date
onSelect: function(selected) {
var selectedDate = selected.split(&#39;.&#39;).reverse().join(&#39;-&#39;); // Convert to &#39;yy-mm-dd&#39; format
var minDate = new Date(selectedDate);
minDate.setDate(minDate.getDate() + 1);
$(delivery).datepicker(&quot;option&quot;, &quot;minDate&quot;, minDate);
calculateDays();
}
});
$(delivery).datepicker({
dateFormat: &#39;dd.mm.yy&#39;, // ISO formatting date
onSelect: function(selected) {
calculateDays();
}
});
// Function to calculate the days between two dates
function calculateDays() {
$( document.body ).trigger( &#39;update_checkout&#39; );
}
});
&lt;/script&gt;
&lt;?php
}
add_action( &#39;woocommerce_before_order_notes&#39;, &#39;datepicker_custom_fields&#39; );

In this filter, you can catch your pickup_datepicker and delivery_datepicker value and calculate days using the DateTime class and diff function. and set the cart item price using the set_price function.

function override_cart_item_price( $cart ) {
if ( is_admin() &amp;&amp; ! defined( &#39;DOING_AJAX&#39; ) ){
return;
}
if ( did_action( &#39;woocommerce_before_calculate_totals&#39; ) &gt;= 2 ){
return;
}
parse_str($_POST[&#39;post_data&#39;], $post_data);
if (isset($post_data[&#39;pickup_datepicker&#39;]) &amp;&amp; $post_data[&#39;pickup_datepicker&#39;] != &#39;&#39; &amp;&amp; isset($post_data[&#39;delivery_datepicker&#39;]) &amp;&amp; $post_data[&#39;delivery_datepicker&#39;] != &#39;&#39;) {
WC()-&gt;session-&gt;set(&#39;pickup_datepicker&#39;, sanitize_text_field($post_data[&#39;pickup_datepicker&#39;]));
WC()-&gt;session-&gt;set(&#39;delivery_datepicker&#39;, sanitize_text_field($post_data[&#39;delivery_datepicker&#39;]));
$pickup_datepicker = sanitize_text_field($post_data[&#39;pickup_datepicker&#39;]);
$delivery_datepicker = sanitize_text_field($post_data[&#39;delivery_datepicker&#39;]);
$pickup_date_obj = new DateTime($pickup_datepicker);
$delivery_date_obj = new DateTime($delivery_datepicker);
$interval = $pickup_date_obj-&gt;diff($delivery_date_obj);
$days = $interval-&gt;days;
$days = ( $days &gt; 1 ) ? $days : 1 ;
WC()-&gt;session-&gt;set(&#39;delivery_days&#39;, $days );
foreach ( $cart-&gt;get_cart() as $cart_item_key =&gt; $cart_item ) {
// Calculate the new subtotal and total based on the number of days
$new_price = $cart_item[&#39;data&#39;]-&gt;get_price() * $days;
$cart_item[&#39;data&#39;]-&gt;set_price( $new_price );    
$cart_item[&#39;days&#39;] = $days;
}
}
}
add_action( &#39;woocommerce_before_calculate_totals&#39;, &#39;override_cart_item_price&#39;, 99, 1 );

By using this filter you can show a number of days beside the price.

function add_days_woocommerce_cart_item_subtotal( $total, $cart_item, $cart_item_key ){
$delivery_days = WC()-&gt;session-&gt;get( &#39;delivery_days&#39; );
if( $delivery_days ){
$day_label = &#39;day&#39;;
$product  = wc_get_product( $cart_item[&#39;product_id&#39;] );
if( $delivery_days &gt; 1 ){
$day_label = &#39;days&#39;;
}
$total = wc_price( $product-&gt;get_price() ) . &#39; x &#39;. $delivery_days. &#39;(&#39;.$day_label.&#39;)&#39; . &#39; = &#39;. $total;
}
return $total;
}
add_filter( &#39;woocommerce_cart_item_subtotal&#39;, &#39;add_days_woocommerce_cart_item_subtotal&#39;, 10, 3 );

References:

Tested and working.

如何根据取货和送货日期的计算来更改结算时的小计和总计?

UPDATE as per OP's comment.

You can override plugins/woocommerce/templates/checkout/review-order.php to your theme yourthemename/woocommerce/checkout/review-order.php

Reference

You will find this below code. and change according to your requirement.

&lt;tr class=&quot;order-total&quot;&gt;
&lt;th&gt;&lt;?php esc_html_e( &#39;Total&#39;, &#39;woocommerce&#39; ); ?&gt;&lt;/th&gt;
&lt;td&gt;&lt;?php wc_cart_totals_order_total_html(); ?&gt;&lt;/td&gt;
&lt;/tr&gt;

huangapple
  • 本文由 发表于 2023年7月24日 19:53:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76754222.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定