基于 WooCommerce 中 Dokan 供应商数量的货到付款费用

Cash On Delivery fee based on Dokan vendors count in WooCommerce

在 WooCommerce Dokan 多供应商商店中,我为客户提供货到付款 (COD) 付款。

我创建了一个代码来计算购物车中的供应商,并将它们乘以我想要的每个供应商的费用。在我的示例中,每个供应商 2 欧元。所以假设我们在购物车上有每个供应商的 1 个产品(现在我们有 2 个供应商)。那应该是 2 * 2 = 4 欧元的 COD 总成本。

效果很好,但是当我收到订单时,我只在主订单中看到费用,而在子订单中看不到。一个子订单应该是 2 欧元,另一个子订单应该是 2 欧元。

它一直在工作,但自 2021 年 2 月 11 日起突然停止。有什么想法可以帮助我吗?

这是我正在使用的代码:

// 2 € Fee COD - Add a custom fee based on cart subtotal: 
add_action( 'woocommerce_cart_calculate_fees', 'custom_fee_for_dokan', 999, 1 );
function custom_fee_for_dokan ( $cart ) {
    $car_items  = WC()->cart->get_cart(); // Cart items

    $items_sort = array(); // Initializing

    // Loop through cart items
    foreach ( $car_items as $cart_item_key => $cart_item ) {
        // Get the vendor_id
        $vendor_id   = get_post_field( 'post_author', $cart_item['product_id'] );
    
        $store_info  = dokan_get_store_info( $vendor_id ); // Get the store data
        $store_name  = $store_info['store_name'];          // Get the store name
    
        // Set in multidimentional array the vendor and then the cart item key
        $items_sort[$store_name][$cart_item_key] = $vendor_id;
    }

    if ( count($car_items) > 1 ) {
        ksort( $items_sort ); // Sorting by vendor name
    }

    $vendors = 0;

    // Loop by vendor name
    foreach ( $items_sort as $store_name => $values ) {
        $vendor_id  = reset($values); // The vendor id
        $store_url = dokan_get_store_url( $vendor_id );  // Get the store URL (if needed)
        $vendors++;
    } 

    // End of Loop

    $flatrate = $vendors * 2;

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

    if ( ! ( is_checkout() && ! is_wc_endpoint_url() ) )
        return; // Only checkout page

    $payment_method = WC()->session->get( 'chosen_payment_method' );

    if ( 'cod' == $payment_method ) {
       // $surcharge == $vendors;
        $cart->add_fee( 'Pay on delivery', $flatrate , true );
    }
}

// jQuery - Update checkout on methode payment change
add_action( 'wp_footer', 'nik_checkout' );
function nik_checkout() {
    if ( ! ( is_checkout() && ! is_wc_endpoint_url() ) )
        return; // Only checkout page
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $('form.checkout').on('change', 'input[name="payment_method"]', function(){
            $(document.body).trigger('update_checkout');
        });
    });
    </script>
    <?php
}

The issue is related to Dokan plugin that does not split the fee by suborders anymore in the plugin recent versions. So you should ask Dokan support, to check if it's not a bug introduced on last updates or if it's not a new available setting.

现在你的代码已经过时而且复杂了。它可以真正地简化和优化

以下代码将根据 dokan 供应商数量设置 COD 费用:

// COD Fee based on vendors count 
add_action( 'woocommerce_cart_calculate_fees', 'dokan_cod_fee_vendors_based' );
function dokan_cod_fee_vendors_based ( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    
    // Only checkout page
    if ( ! ( is_checkout() && ! is_wc_endpoint_url() ) )
        return;
        
    $fee_by_vendor = 2; // HERE set the fee by vendor
    $vendors_array = array(); // Initializing

    // Loop through cart items
    foreach ( $cart->get_cart() as $item ) {
        $vendor_id = get_post_field('post_author', $item['product_id']); // Get the vendor_id
    
        // Set in an indexed array to get how many vendors
        $vendors_array[$vendor_id] = $vendor_id;
    }

    $fee_total = count($vendors_array) * $fee_by_vendor; // Get fee total by vendor

    if ( 'cod' === WC()->session->get( 'chosen_payment_method' ) ) {
        $cart->add_fee( 'Cash On Delivery Fee', $fee_total, true ); // Apply the fee
    }
}

// jQuery - Update checkout on methode payment change
add_action( 'wp_footer', 'payment_refresh_checkout_js' );
function payment_refresh_checkout_js() {
    // Only checkout page
    if ( ! ( is_checkout() && ! is_wc_endpoint_url() ) )
        return; // Exit
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $('form.checkout').on('change', 'input[name="payment_method"]', function(){
            $(document.body).trigger('update_checkout');
        });
    });
    </script>
    <?php
}

代码进入活动子主题(或活动主题)的 functions.php 文件。它应该有效。