簡體   English   中英

通過 WooCommerce 中的管理員編輯訂單自動添加或更新自定義費用

[英]Auto add or update a custom fee via admin edit orders in WooCommerce

我們有一個特殊情況,我們會在收到訂單后向客戶開具付款發票,而不是讓他們在結賬時付款。 運費是手動計算並添加到訂單中的,然后我們會在總計上加收 3% 的信用卡費用。

為了自動化這個過程,我創建了一個腳本,一旦通過后端設置了運費,它就會計算 3% 的費用,並自動將這個費用項目添加到訂單中。 這在我們添加運費並一次單擊保存/重新計算時有效。

add_action( 'woocommerce_order_after_calculate_totals', "custom_order_after_calculate_totals", 10, 2);
function custom_order_after_calculate_totals($and_taxes, $order) {

    if ( did_action( 'woocommerce_order_after_calculate_totals' ) >= 2 )
    return;

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

    $percentage = 0.03;
    $total = $order->get_total();
    $surcharge = $total * $percentage;
    $feeArray = array(
        'name' => '3% CC Fee',
        'amount' =>  wc_format_decimal($surcharge),
        'taxable' => false,
        'tax_class' => ''
    );

    //Get fees
    $fees = $order->get_fees();
    if(empty($fees)){
        //Add fee
        $fee_object = (object) wp_parse_args( $feeArray );
        $order->add_fee($fee_object);
    } else {
        //Update fee
        foreach($fees as $item_id => $item_fee){
            if($item_fee->get_name() == "3% CC Fee"){
                $order->update_fee($item_id,$feeArray);
            }
        }
    }
}

如果我們不小心添加了錯誤的運費並嘗試更新它,上面的代碼會再次觸發並更新費用,但是$total不會從更新的運費中獲得新的訂單總額,因此費用不會改變。 奇怪的是,如果我嘗試刪除費用項目,則會計算出新的費用並加回正確的費用金額。

任何人都知道我該如何解決這個問題?

由於您使用訂單總額來計算您的費用,並且您使用的鈎子位於calculate_totals()方法內,一旦訂單更新,您將始終需要按“重新計算”按鈕以獲取正確的費用總額和正確的訂單總額和正確的金額

由於 WooCommerce 3 您的代碼已經過時並且有點過時並出現一些錯誤......例如add_fee()update_fee()方法已被棄用並被其他一些方法取代。

改用以下內容:

add_action( 'woocommerce_order_after_calculate_totals', "custom_order_after_calculate_totals", 10, 2 );
function custom_order_after_calculate_totals( $and_taxes, $order ) {
    if ( did_action( 'woocommerce_order_after_calculate_totals' ) >= 2 )
        return;

    $percentage = 0.03; // Fee percentage

    $fee_data   = array(
        'name'       => __('3% CC Fee'),
        'amount'     => wc_format_decimal( $order->get_total() * $percentage ),
        'tax_status' => 'none',
        'tax_class'  => ''
    );

    $fee_items  = $order->get_fees(); // Get fees

    // Add fee
    if( empty($fee_items) ){
        $item = new WC_Order_Item_Fee(); // Get an empty instance object

        $item->set_name( $fee_data['name'] );
        $item->set_amount( $fee_data['amount'] );
        $item->set_tax_class($fee_data['tax_class']);
        $item->set_tax_status($fee_data['tax_status']);
        $item->set_total($fee_data['amount']);

        $order->add_item( $item );
        $item->save(); // (optional) to be sure
    }
    // Update fee
    else {
        foreach ( $fee_items as $item_id => $item ) {
            if( $item->get_name() === $fee_data['name'] ) {
                $item->set_amount($fee_data['amount']);
                $item->set_tax_class($fee_data['tax_class']);
                $item->set_tax_status($fee_data['tax_status']);
                $item->set_total($fee_data['amount']);
                $item->save();
            }
        }
    }
}

代碼進入活動子主題(或活動主題)的functions.php文件。 測試和工作。

一旦訂單更新並按下重新計算按鈕(以獲得正確的訂單總數)后,自動添加和更新的費用都會很好地工作。

相關: 在 Woocommerce 3 中以編程方式向訂單添加費用


更新

現在,如果它由於任何原因不起作用,您應該刪除相關項目以更新並添加一個新項目,如下所示:

add_action( 'woocommerce_order_after_calculate_totals', "custom_order_after_calculate_totals", 10, 2 );
function custom_order_after_calculate_totals( $and_taxes, $order ) {
    if ( did_action( 'woocommerce_order_after_calculate_totals' ) >= 2 )
        return;

    $percentage = 0.03; // Fee percentage

    $fee_data   = array(
        'name'       => __('3% CC Fee'),
        'amount'     => wc_format_decimal( $order->get_total() * $percentage ),
        'tax_status' => 'none',
        'tax_class'  => ''
    );

    $fee_items  = $order->get_fees(); // Get fees

    // Add fee
    if( empty($fee_items) ){
        $item = new WC_Order_Item_Fee(); // Get an empty instance object

        $item->set_name( $fee_data['name'] );
        $item->set_amount( $fee_data['amount'] );
        $item->set_tax_class($fee_data['tax_class']);
        $item->set_tax_status($fee_data['tax_status']);
        $item->set_total($fee_data['amount']);

        $order->add_item( $item );
        $item->save(); // (optional) to be sure
    }
    // Update fee
    else {
        foreach ( $fee_items as $item_id => $item ) {
            if( $item->get_name() === $fee_data['name'] ) {
                $item->remove_item( $item_id ); // Remove the item

                $item = new WC_Order_Item_Fee(); // Get an empty instance object

                $item->set_name( $fee_data['name'] );
                $item->set_amount( $fee_data['amount'] );
                $item->set_tax_class($fee_data['tax_class']);
                $item->set_tax_status($fee_data['tax_status']);
                $item->set_total($fee_data['amount']);

                $order->add_item( $item );
                $item->save(); // (optional) to be sure
            }
        }
    }
}

更新

需要使用 $order object 中的 remove_item。WC_Order_Item_Fee Class 中沒有 remove_item function。從訂單中刪除項目后調用訂單上的 save() function。

$order_fees = reset( $order->get_items('fee') );
        $fee_data   = array(
            'name'       => __( 'Delivery Fee', 'dsfw' ),
            'amount'     => wc_format_decimal( $day_fee + $timeslot_fee ),
        );

        if( !empty( $order_fees ) && $order_fees instanceof WC_Order_Item_Fee ) {
            // update fee

            if( $order_fees->get_name() === $fee_data['name'] ) {
                $order->remove_item( (int)$order_fees->get_id() );
                $order->save();

                $item = new WC_Order_Item_Fee();
                $item->set_name( $fee_data['name'] );
                $item->set_amount( $fee_data['amount'] );
                $item->set_total( $fee_data['amount'] );
                $order->add_item( $item );  
                $item->save();

            }
        } else {
            // add fee
            $item = new WC_Order_Item_Fee();

            $item->set_name( $fee_data['name'] );
            $item->set_amount( $fee_data['amount'] );
            $item->set_total( $fee_data['amount'] );

            $order->add_item( $item );
            $item->save();
        }

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM