在单个产品页面上添加一个复选框,这会在Woocommerce中增加额外的费用 [英] Add a checkbox on single product pages that adds an additional cost in Woocommerce

查看:104
本文介绍了在单个产品页面上添加一个复选框,这会在Woocommerce中增加额外的费用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在woocommerce中,我使用以下代码在管理产品编辑页面上显示输入文本字段,这使我可以向该产品添加附加定价选项:

add_action( 'woocommerce_product_options_pricing', 'wc_cost_product_field' );
function wc_cost_product_field() {
    woocommerce_wp_text_input( array( 'id' => 'repair_price', 'class' => 'wc_input_price short', 'label' => __( 'Repair Cost', 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')' ) );
}

add_action( 'save_post', 'wc_cost_save_product' );
function wc_cost_save_product( $product_id ) {

     // stop the quick edit interferring as this will stop it saving properly, when a user uses quick edit feature
     if (wp_verify_nonce($_POST['_inline_edit'], 'inlineeditnonce'))
        return;

    // If this is a auto save do nothing, we only save when update button is clicked
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        return;
    if ( isset( $_POST['repair_price'] ) ) {
        if ( is_numeric( $_POST['repair_price'] ) )
            update_post_meta( $product_id, 'repair_price', $_POST['repair_price'] );
    } else delete_post_meta( $product_id, 'repair_price' );
}

现在在产品页面(位于前端)上,我需要一个复选框维修费用$ 20" ,当产品自定义字段定价选项填充了某些价格时,该复选框就会出现.

如果客户添加此选项,它将在产品上增加20美元的额外费用,并且也应反映在购物车和结帐页面上.

任何帮助将不胜感激.

解决方案

在以下代码中,我再次回顾了您的实际代码,并添加了所有必需的代码,以在单个产品页面中启用复选框选项(如果定价选项中的产品填充为(针对非销售的非可变产品类型).

当客户选择该选项时,产品价格会上涨,当添加到购物车中时,价格变化会反映在购物车和结帐页面中(请参见最后的屏幕截图).. >

代码:

// Backend: Additional pricing option custom field
add_action( 'woocommerce_product_options_pricing', 'wc_cost_product_field' );
function wc_cost_product_field() {
    woocommerce_wp_text_input( array(
        'id'        => '_repair_price',
        'class'     => 'wc_input_price short',
        'label'     => __( 'Repair Cost', 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')'
    ));
}

// Backend: Saving product pricing option custom field value
add_action( 'woocommerce_admin_process_product_object', 'save_product_custom_meta_data', 100, 1 );
function save_product_custom_meta_data( $product ){
    if ( isset( $_POST['_repair_price'] ) )
        $product->update_meta_data( '_repair_price', sanitize_text_field($_POST['_repair_price']) );
}

// Front: Add a text input field inside the add to cart form on single product page
add_action('woocommerce_single_product_summary','add_repair_price_option_to_single_product', 2 );
function add_repair_price_option_to_single_product(){
    global $product;

    if( $product->is_type('variable') || ! $product->get_meta( '_repair_price' ) ) return;

    add_action('woocommerce_before_add_to_cart_button', 'product_option_custom_field', 30 );
}

function product_option_custom_field(){
    global $product;

    $active_price = (float) $product->get_price();
    $repair_price = (float) $product->get_meta( '_repair_price' );
    $repair_price_html   = strip_tags( wc_price( wc_get_price_to_display( $product, array('price' => $repair_price ) ) ) );
    $active_price_html   = wc_price( wc_get_price_to_display( $product ) );
    $disp_price_sum_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $repair_price ) ) );

    echo '<div class="hidden-field">
    <p class="form-row form-row-wide" id="repair_option_field" data-priority="">
    <span class="woocommerce-input-wrapper"><label class="checkbox"> ' . __("Repair Option:", "Woocommerce") .
    ' <input type="checkbox" class="input-checkbox " name="repair_option" id="repair_option" value="1"> + ' . $repair_price_html .
    '</label></span></p>
    <input type="hidden" name="repair_price" value="' . $repair_price . '">
    <input type="hidden" name="active_price" value="' . $active_price . '"></div>';

    // Jquery: Update displayed price
    ?>
    <script type="text/javascript">
    jQuery(function($) {
        var cb = 'input[name="repair_option"]'
            pp = 'p.price';

        // On change / select a variation
        $('form.cart').on( 'change', cb, function(){
            if( $(cb).prop('checked') === true )
                $(pp).html('<?php echo $disp_price_sum_html; ?>');
            else
                $(pp).html('<?php echo $active_price_html; ?>');
        })

    });
    </script>
    <?php
}

// Front: Calculate new item price and add it as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_product_data', 10, 3);
function add_custom_product_data( $cart_item_data, $product_id, $variation_id ) {
    if (isset($_POST['repair_option']) && !empty($_POST['repair_option'])) {
        $cart_item_data['new_price'] = (float) ($_POST['active_price'] + $_POST['repair_price']);
        $cart_item_data['repair_price'] = (float) $_POST['repair_price'];
        $cart_item_data['active_price'] = (float) $_POST['active_price'];
        $cart_item_data['unique_key'] = md5(microtime().rand());
    }

    return $cart_item_data;
}

// Front: Set the new calculated cart item price
add_action('woocommerce_before_calculate_totals', 'extra_price_add_custom_price', 20, 1);

function extra_price_add_custom_price($cart) {
    if (is_admin() && !defined('DOING_AJAX'))
        return;

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

    foreach($cart->get_cart() as $cart_item) {
        if (isset($cart_item['new_price']))
            $cart_item['data']->set_price((float) $cart_item['new_price']);
    }
}

// Front: Display option in cart item
add_filter('woocommerce_get_item_data', 'display_custom_item_data', 10, 2);

function display_custom_item_data($cart_item_data, $cart_item) {
    if (isset($cart_item['repair_price'])) {
        $cart_item_data[] = array(
            'name' => __("Repair option", "woocommerce"),
            'value' => strip_tags( '+ ' . wc_price( wc_get_price_to_display( $cart_item['data'], array('price' => $cart_item['repair_price'] ) ) ) )
        );
    }

    return $cart_item_data;
}

代码进入您的活动子主题(或活动主题)的function.php文件中.经过测试并可以正常工作.


基于此答案的添加:

代码进入您的活动子主题(或活动主题)的function.php文件中.经过测试并可以正常工作.

In woocommerce, I am using the following code to display an input text field on admin product edit pages, that allow me to add an additonal pricing option to the product:

add_action( 'woocommerce_product_options_pricing', 'wc_cost_product_field' );
function wc_cost_product_field() {
    woocommerce_wp_text_input( array( 'id' => 'repair_price', 'class' => 'wc_input_price short', 'label' => __( 'Repair Cost', 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')' ) );
}

add_action( 'save_post', 'wc_cost_save_product' );
function wc_cost_save_product( $product_id ) {

     // stop the quick edit interferring as this will stop it saving properly, when a user uses quick edit feature
     if (wp_verify_nonce($_POST['_inline_edit'], 'inlineeditnonce'))
        return;

    // If this is a auto save do nothing, we only save when update button is clicked
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        return;
    if ( isset( $_POST['repair_price'] ) ) {
        if ( is_numeric( $_POST['repair_price'] ) )
            update_post_meta( $product_id, 'repair_price', $_POST['repair_price'] );
    } else delete_post_meta( $product_id, 'repair_price' );
}

Now on the product page (in the front end) I need a checkbox "Repair cost $20", that will appear when the product custom field pricing option is filled with some price.

If customer add this option, it will add an additional cost of $20 on the product and it should also be reflected on the cart and checkout pages.

Any help will be appreciated.

解决方案

In the following code, I have revisited a bit your actual code and added all necessary code to enable the checkbox option in single product page if the pricing option in the product is filled (for non variable products type that are not on sale).

When the option is selected by the customer, the product price is increased and when added to cart the price change is reflected in cart and checkout pages (see the screenshots at the end).

The code:

// Backend: Additional pricing option custom field
add_action( 'woocommerce_product_options_pricing', 'wc_cost_product_field' );
function wc_cost_product_field() {
    woocommerce_wp_text_input( array(
        'id'        => '_repair_price',
        'class'     => 'wc_input_price short',
        'label'     => __( 'Repair Cost', 'woocommerce' ) . ' (' . get_woocommerce_currency_symbol() . ')'
    ));
}

// Backend: Saving product pricing option custom field value
add_action( 'woocommerce_admin_process_product_object', 'save_product_custom_meta_data', 100, 1 );
function save_product_custom_meta_data( $product ){
    if ( isset( $_POST['_repair_price'] ) )
        $product->update_meta_data( '_repair_price', sanitize_text_field($_POST['_repair_price']) );
}

// Front: Add a text input field inside the add to cart form on single product page
add_action('woocommerce_single_product_summary','add_repair_price_option_to_single_product', 2 );
function add_repair_price_option_to_single_product(){
    global $product;

    if( $product->is_type('variable') || ! $product->get_meta( '_repair_price' ) ) return;

    add_action('woocommerce_before_add_to_cart_button', 'product_option_custom_field', 30 );
}

function product_option_custom_field(){
    global $product;

    $active_price = (float) $product->get_price();
    $repair_price = (float) $product->get_meta( '_repair_price' );
    $repair_price_html   = strip_tags( wc_price( wc_get_price_to_display( $product, array('price' => $repair_price ) ) ) );
    $active_price_html   = wc_price( wc_get_price_to_display( $product ) );
    $disp_price_sum_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $repair_price ) ) );

    echo '<div class="hidden-field">
    <p class="form-row form-row-wide" id="repair_option_field" data-priority="">
    <span class="woocommerce-input-wrapper"><label class="checkbox"> ' . __("Repair Option:", "Woocommerce") .
    ' <input type="checkbox" class="input-checkbox " name="repair_option" id="repair_option" value="1"> + ' . $repair_price_html .
    '</label></span></p>
    <input type="hidden" name="repair_price" value="' . $repair_price . '">
    <input type="hidden" name="active_price" value="' . $active_price . '"></div>';

    // Jquery: Update displayed price
    ?>
    <script type="text/javascript">
    jQuery(function($) {
        var cb = 'input[name="repair_option"]'
            pp = 'p.price';

        // On change / select a variation
        $('form.cart').on( 'change', cb, function(){
            if( $(cb).prop('checked') === true )
                $(pp).html('<?php echo $disp_price_sum_html; ?>');
            else
                $(pp).html('<?php echo $active_price_html; ?>');
        })

    });
    </script>
    <?php
}

// Front: Calculate new item price and add it as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_product_data', 10, 3);
function add_custom_product_data( $cart_item_data, $product_id, $variation_id ) {
    if (isset($_POST['repair_option']) && !empty($_POST['repair_option'])) {
        $cart_item_data['new_price'] = (float) ($_POST['active_price'] + $_POST['repair_price']);
        $cart_item_data['repair_price'] = (float) $_POST['repair_price'];
        $cart_item_data['active_price'] = (float) $_POST['active_price'];
        $cart_item_data['unique_key'] = md5(microtime().rand());
    }

    return $cart_item_data;
}

// Front: Set the new calculated cart item price
add_action('woocommerce_before_calculate_totals', 'extra_price_add_custom_price', 20, 1);

function extra_price_add_custom_price($cart) {
    if (is_admin() && !defined('DOING_AJAX'))
        return;

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

    foreach($cart->get_cart() as $cart_item) {
        if (isset($cart_item['new_price']))
            $cart_item['data']->set_price((float) $cart_item['new_price']);
    }
}

// Front: Display option in cart item
add_filter('woocommerce_get_item_data', 'display_custom_item_data', 10, 2);

function display_custom_item_data($cart_item_data, $cart_item) {
    if (isset($cart_item['repair_price'])) {
        $cart_item_data[] = array(
            'name' => __("Repair option", "woocommerce"),
            'value' => strip_tags( '+ ' . wc_price( wc_get_price_to_display( $cart_item['data'], array('price' => $cart_item['repair_price'] ) ) ) )
        );
    }

    return $cart_item_data;
}

Code goes in function.php file of your active child theme (or active theme). tested and works.


Addition based on this answer: Display product optional cost in Woocommerce in order details

Allow to save the repair price as order item meta data and display it everywhere on orders and email notifications:

// Save chosen seats to each order item as custom meta data and display order items Warrenty everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_product_waranty', 10, 4 );
function save_order_item_product_waranty( $item, $cart_item_key, $values, $order ) {
    if( isset($values['repair_price']) && $values['repair_price'] > 0 ) {
        $key = __("Repair option", "woocommerce");
        $value = strip_tags( '+ '. wc_price( wc_get_price_to_display( $values['data'], array('price' => $values['repair_price']) ) ) );
        $item->update_meta_data( $key, $value );
    }
}

Code goes in function.php file of your active child theme (or active theme). tested and works.

这篇关于在单个产品页面上添加一个复选框,这会在Woocommerce中增加额外的费用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆