WooCommerce實現門市不用運費,宅配滿額增加運費功能

需求的情境為業主需求可以自取,也可以宅配的購物站

自取的話,當然就不用運費囉~,宅配則未滿3000元運費160元

由於我們不用WooCommerce內建的運費功能,因此可把內建運費相關的功能設成0元,運費的部份我們在結帳時加入運費(商品)



// 在結帳頁地址欄位之前添加自取選項
add_action( 'woocommerce_before_checkout_billing_form', 'add_factory_pickup_radio_buttons_to_checkout' );

function add_factory_pickup_radio_buttons_to_checkout() {
    $session_value = WC()->session->get('pickup_option'); // 獲取 session 中的值

    // 添加選項
    echo '<div style="margin-bottom: 20px;">';
    echo '<label>';
    echo '<input type="radio" name="pickup_option" value="factory" ' . checked( $session_value, 'factory', false ) . '> 門市1自取';
    echo '</label><br>';
    echo '<label>';
    echo '<input type="radio" name="pickup_option" value="store" ' . checked( $session_value, 'store', false ) . '> 門市2自取';
    echo '</label><br>';
    echo '<label>';
    echo '<input type="radio" name="pickup_option" value="delivery" ' . checked( $session_value, 'delivery', false ) . '> 宅配';
    echo '</label>';
    echo '</div>';

    // 添加 jQuery 來監聽選項的變動,並確保觸發 AJAX 和自動填入備註
    ?>
    <script type="text/javascript">
        jQuery(document).ready(function($) {
            // 監聽選項的變動
            $(document).on('change', 'input[name="pickup_option"]', function() {
                var selectedOption = $('input[name="pickup_option"]:checked').val();
                var commentText = '';

                // 根據選擇的自取方式填寫備註
                if (selectedOption === 'factory') {
                    commentText = '選擇了門市1自取';
                } else if (selectedOption === 'store') {
                    commentText = '選擇了門市2自取';
                } else if (selectedOption === 'delivery') {
                    commentText = '選擇了宅配';
                }

                // 填入備註欄位
                $('#order_comments').val(commentText);

                // 發起 AJAX 請求來更新購物車和 session 狀態
                $.ajax({
                    type: 'POST',
                    url: '<?php echo admin_url('admin-ajax.php'); ?>',
                    data: {
                        action: 'handle_pickup_option',
                        selected_option: selectedOption
                    },
                    success: function(response) {
                        // 更新購物車摘要或其他元素,而不重新加載整個頁面
                        $(document.body).trigger('update_checkout');
                    },
                    error: function(xhr, status, error) {
                        console.log('AJAX Error: ' + error);
                    }
                });
            });

            // 初次加載時運行一次,如果有預設選擇
            var initialOption = $('input[name="pickup_option"]:checked').val();
            if (initialOption) {
                $('input[name="pickup_option"]:checked').trigger('change');
            }
        });
    </script>
    <?php
}

// 處理 AJAX 請求來更新 session 狀態
add_action( 'wp_ajax_handle_pickup_option', 'handle_pickup_option' );
add_action( 'wp_ajax_nopriv_handle_pickup_option', 'handle_pickup_option' );

function handle_pickup_option() {
    if ( isset( $_POST['selected_option'] ) ) {
        $selected_option = sanitize_text_field( $_POST['selected_option'] );
        WC()->session->set('pickup_option', $selected_option);

        $product_id_delivery = 1234; // 宅配產品 ID

        // 根據選擇的選項進行處理
        if ( $selected_option === 'delivery' ) {
            update_cart_for_delivery($product_id_delivery);
        } else {
            // 移除宅配產品
            remove_cart_product($product_id_delivery);
        }
    }

    wp_die(); // 結束 AJAX 請求
}

function update_cart_for_delivery($product_id_delivery) {
    // 獲取購物車總金額(排除稅金及運費)
    $cart_total = WC()->cart->get_subtotal();

    if ( floatval( $cart_total ) < 3000 ) {
        // 如果金額小於 3000 元,添加宅配產品
        handle_cart_product_delivery($product_id_delivery);
    } else {
        // 如果金額大於或等於 3000 元,移除宅配產品
        remove_cart_product($product_id_delivery);
    }
}

function handle_cart_product_delivery($product_id_delivery) {
    // 檢查是否已經存在要添加的產品
    $is_added = false;
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        if ( $cart_item['product_id'] == $product_id_delivery ) {
            $is_added = true;
            break;
        }
    }

    // 如果產品不在購物車中,則添加
    if ( ! $is_added ) {
        WC()->cart->add_to_cart( $product_id_delivery, 1 );
    }
}

function remove_cart_product($product_id) {
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        if ( $cart_item['product_id'] == $product_id ) {
            WC()->cart->remove_cart_item( $cart_item_key );
        }
    }
}

// 根據選擇的自取方式自動填寫並禁用地址字段
add_action( 'wp_footer', 'auto_fill_and_disable_address_based_on_pickup_option' );
function auto_fill_and_disable_address_based_on_pickup_option() {
    if ( is_checkout() ) {
        ?>
        <script type="text/javascript">
            jQuery(document).ready(function($) {
                function fillAndDisableAddressFields() {
                    var selectedOption = $('input[name="pickup_option"]:checked').val();

                    if (selectedOption === 'factory') {
                        // 填寫工廠自取地址
                        $('#select2-billing_state-container').text('臺南市').trigger('change');
                        $('#select2-billing_city-container').text('東區').trigger('change');
                        $('#billing_address_1').val('門市1').trigger('change');

                        // 禁用地址字段
                        $('#select2-billing_state-container').prop('disabled', true);
                        $('#select2-billing_city-container').prop('disabled', true);
                        $('#billing_address_1').prop('disabled', true);
                    } else if (selectedOption === 'store') {
                        // 填寫門市自取地址
                        $('#select2-billing_state-container').text('臺南市').trigger('change');
                        $('#select2-billing_city-container').text('中西區').trigger('change');
                        $('#billing_address_1').val('門市2').trigger('change');

                        // 禁用地址字段
                        $('#select2-billing_state-container').prop('disabled', true);
                        $('#select2-billing_city-container').prop('disabled', true);
                        $('#billing_address_1').prop('disabled', true);
                    } else {
                        // 啟用地址字段
                        $('#select2-billing_state-container').prop('disabled', false);
                        $('#select2-billing_city-container').prop('disabled', false);
                        $('#billing_address_1').prop('disabled', false);
                    }
                }

                // 初次加載時運行一次
                fillAndDisableAddressFields();

                // WooCommerce 可能重新加載表單,需監控變動
                $(document.body).on('updated_checkout', function() {
                    fillAndDisableAddressFields();
                });

                // 監聽選項變動
                $(document).on('change', 'input[name="pickup_option"]', function() {
                    fillAndDisableAddressFields();
                });
            });
        </script>
        <?php
    }
}

// 監聽購物車變動來處理金額超過 3000 元的情況
add_action( 'woocommerce_after_calculate_totals', 'check_cart_total_for_delivery_product' );
function check_cart_total_for_delivery_product() {
    $product_id_delivery = 1234; // 運費 ID
    $cart_total = WC()->cart->get_subtotal();

    if ( floatval( $cart_total ) >= 3000 ) {
        remove_cart_product($product_id_delivery);
    }
}

// 保存選擇的自取地址
add_action( 'woocommerce_checkout_update_order_meta', 'save_custom_pickup_address' );
function save_custom_pickup_address( $order_id ) {
    if ( isset( $_POST['pickup_option'] ) ) {
        $pickup_option = sanitize_text_field( $_POST['pickup_option'] );
        
        if ( $pickup_option === 'factory' ) {
            // 門市1自取
            update_post_meta( $order_id, '_billing_state', '臺南市' );
            update_post_meta( $order_id, '_billing_city', '東區' );
            update_post_meta( $order_id, '_billing_address_1', '門市1' );
        } elseif ( $pickup_option === 'store' ) {
            // 門市2自取
            update_post_meta( $order_id, '_billing_state', '臺南市' );
            update_post_meta( $order_id, '_billing_city', '中西區' );
            update_post_meta( $order_id, '_billing_address_1', '門市2' );
        }
    }
}

// 自動選擇支付方式
add_action( 'wp_footer', 'auto_select_payment_method_based_on_pickup_option' );

function auto_select_payment_method_based_on_pickup_option() {
    if ( is_checkout() ) {
        ?>
        <script type="text/javascript">
            jQuery(document).ready(function($) {
                // 設置支付方式
                function setPaymentMethod() {
                    var selectedOption = $('input[name="pickup_option"]:checked').val();

                    if (selectedOption === 'factory' || selectedOption === 'store') {
                        // 預選工廠自取或門市自取時的支付方式
                        $('#payment_method_woocg-post-513').prop('checked', true).trigger('change');
                    } else if (selectedOption === 'delivery') {
                        // 預選宅配時的支付方式
                        $('#payment_method_ctbc-credit').prop('checked', true).trigger('change');
                    }
                }

                // 初次加載時運行一次
                setPaymentMethod();

                // 監聽選項變動來改變支付方式
                $(document).on('change', 'input[name="pickup_option"]', function() {
                    setPaymentMethod();
                });

                // WooCommerce 更新結帳表單時,重新設置支付方式
                $(document.body).on('updated_checkout', function() {
                    setPaymentMethod();
                });
            });
        </script>
        <?php
    }
}
瀏覽次數:4