skip to Main Content

Based on Product custom field to enable a specific fee in Woocommerce answer, I have the following code:

// Create and display Backend Product custom field
add_action('woocommerce_product_options_general_product_data', 'ba_adding_custom_product_general_field');
function ba_adding_custom_product_general_field()
{
    global $woocommerce, $post;
    echo '<div class="options_group">';

    // Custom fields will be created here...

    woocommerce_wp_text_input(array(
        'id' => '_number_field',
        'label' => __('Environmental fee', 'woocommerce'),
        'placeholder' => '',
        'description' => __('Enter the custom value here.', 'woocommerce'),
        'type' => 'number',
        'custom_attributes' => array(
            'step' => 'any',
            'min' => '0'
        )
    ));

    echo '</div>';
}

// Save the submitted data from Backend Product custom field
add_action('woocommerce_process_product_meta', 'ba_saving_custom_product_general_field');
function ba_saving_custom_product_general_field($post_id)
{

    // Get the submitted value
    $woocommerce_number_field = isset($_POST['_number_field']) ? $_POST['_number_field'] : '';

    // Create/Update the submitted value in postmeta table for this product
    update_post_meta($post_id, '_number_field', esc_attr($woocommerce_number_field));
}

// Adding a custom fee to cart based on a product custom field value calculation
add_action('woocommerce_cart_calculate_fees', 'ba_custom_cart_fee');
function ba_custom_cart_fee($cart_object)
{
    // Initializing variables
    $fee = 0;

    // Iterating through each cart items
    foreach ($cart_object->get_cart() as $cart_item) {
        $item_fee = 0;

        if ($cart_item['variation_id'] > 0) {
            // If it's a variation, get its custom field value
            $item_id = $cart_item['variation_id'];
            $item_fee = get_post_meta($item_id, '_number_field_variation', true);
        } else {
            // If it's a simple product, get its custom field value
            $item_id = $cart_item['product_id'];
            $item_fee = get_post_meta($item_id, '_number_field', true);
        }

        // Adding the calculation to the fee
        $fee += $cart_item['quantity'] * $item_fee;
    }

    // Adding fee to cart if it's not zero
    if ($fee != 0) {
        $cart_object->add_fee(__('Handling fee', 'woocommerce'), $fee, true, 'standard');
    }
}

// Adding custom text on product page for the custom fee
add_action('woocommerce_single_product_summary', 'ba_display_custom_product_text', 25);
function ba_display_custom_product_text()
{
    global $product;

    // Getting the corresponding product custom field value
    $item_fee = get_post_meta($product->get_id(), '_number_field', true);

    // Getting the currency symbol
    $currency_symbol = get_woocommerce_currency_symbol();

    // Displaying custom text if fee is set
    if ($item_fee) {
        echo '<p style="margin-top: 10px; color: red;">You pay ' . $item_fee . ' ' . $currency_symbol . ' warranty for this product.</p>';
    }
}

// Create and display Backend Product custom field for variations
add_action('woocommerce_product_after_variable_attributes', 'ba_adding_custom_variation_field', 10, 3);
function ba_adding_custom_variation_field($loop, $variation_data, $variation)
{
    woocommerce_wp_text_input(array(
        'id' => '_number_field_variation[' . $variation->ID . ']',
        'label' => __('Environmental fee', 'woocommerce'),
        'placeholder' => '',
        'description' => __('Enter the custom value here.', 'woocommerce'),
        'type' => 'number',
        'custom_attributes' => array(
            'step' => 'any',
            'min' => '0'
        ),
        'value' => get_post_meta($variation->ID, '_number_field_variation', true)
    ));
}

// Save the submitted data from Backend Product custom field for variations
add_action('woocommerce_save_product_variation', 'ba_saving_custom_variation_field', 10, 2);
function ba_saving_custom_variation_field($variation_id, $i)
{
    if (isset($_POST['_number_field_variation'][$variation_id])) {
        update_post_meta($variation_id, '_number_field_variation', sanitize_text_field($_POST['_number_field_variation'][$variation_id]));
    }
}

// Adding custom text on product loop for the custom fee
add_action('woocommerce_after_shop_loop_item', 'ba_display_custom_product_text_loop', 9);
function ba_display_custom_product_text_loop()
{
    global $product;

    // Getting the corresponding product custom field value
    $item_fee = get_post_meta($product->get_id(), '_number_field', true);

    // Getting the currency symbol
    $currency_symbol = get_woocommerce_currency_symbol();

    // Displaying custom text if fee is set
    if ($item_fee) {
        echo '<p style="margin-top: 10px; color: red;">You pay ' . $item_fee . ' ' . $currency_symbol . ' warranty for this product.</p>';
    }
}


The code allows me to add a fee for simple and variable products (including variations). The total amount of the tax is displayed in the cart and checkout. In the store and on the product page, the amount of the fee per item is displayed. How to make that for variable products to display the fee of the selected variation?
I tried using Replace WooCommerce product short description by selected variation description answer, but I didn’t manage to make it functional.

2

Answers


  1. Chosen as BEST ANSWER

    I managed to modify @LoicTheAztec's code and made it work almost as I wanted. The problem I still have: if I don't set the additional fee (warranty) at the product level (leave the field empty), the message with zero euro additional fee is displayed in the index. In order not to display that message, I have to press the delete key when editing the product (although nothing was filled in). I did not manage to find any solution to not display that text if the field is not filled. This problem only happens for variable products (even for those that do not have an additional fee added to the variations).

    My code:

    // add an input number field to Admin product edit pages
    add_action('woocommerce_product_options_general_product_data', 'add_admin_product_warranty_fee_field');
    function add_admin_product_warranty_fee_field() {
        echo '<div class="options_group">';
    
        woocommerce_wp_text_input( array(
            'id'                => '_warranty_fee',
            'type'              => 'number',
            'label'             => __('Environmental fee', 'woocommerce'),
            'placeholder'       => '',
            'description'       => __('Enter the custom value here.', 'woocommerce'),
            'desc_tip'          => 'true',
            'custom_attributes' => array( 'step' => 'any', 'min' => '0' )
        ) );
    
        echo '</div>';
    }
    
    // Save input number field value from product edit page
    add_action('woocommerce_admin_process_product_object', 'save_admin_product_warranty_fee_field_value');
    function save_admin_product_warranty_fee_field_value( $product ) {
        $product->update_meta_data('_warranty_fee', isset($_POST['_warranty_fee']) ? esc_attr($_POST['_warranty_fee']) : '');
    }
    
    // add an input number field to Admin product variations settings
    add_action('woocommerce_variation_options_pricing', 'add_admin_variation_warranty_fee_field', 10, 3);
    function add_admin_variation_warranty_fee_field($loop, $variation_data, $variation) {    
        $variation_object = wc_get_product($variation->ID);
        
        echo '<div class="custom-variation-field">';
        
        // Field for warranty fee
        woocommerce_wp_text_input(array(
            'id'                => "_warranty_fee[{$loop}]",
            'type'              => 'number',
            'label'             => __('Environmental fee', 'woocommerce'),
            'placeholder'       => '',
            'description'       => __('Enter the custom value here.', 'woocommerce'),
            'desc_tip'          => 'true',
            'wrapper_class'     => 'form-row form-row-first',
            'custom_attributes' => array( 'step' => 'any', 'min' => '0' ),
            'value'             => $variation_object->get_meta('_warranty_fee'),
        ));
        
        echo '</div>';
    }
    
    // Save input number field value from product variation settings
    add_action( 'woocommerce_admin_process_variation_object', 'save_admin_variation_custom_fields', 10, 2 );
    function save_admin_variation_custom_fields( $variation, $i ) {
        $variation->update_meta_data('_warranty_fee', isset($_POST['_warranty_fee'][$i]) ? esc_attr($_POST['_warranty_fee'][$i]) : '');
    }
    
    // Add the variation formatted warranty fee price to the form data
    add_filter( 'woocommerce_available_variation', 'available_variation_formatted_price_per_unit', 10, 3 );
    function available_variation_formatted_price_per_unit( $data, $product, $variation ) {
        if ($item_fee = $variation->get_meta('_warranty_fee')) {
            $data['warranty_fee'] = '<p style="margin-top: 10px; color: red;">' . 
            sprintf( __('You pay %s warranty for this product.', 'woocommerce'), 
            wp_strip_all_tags( wc_price($item_fee) ) ) . '</p>';
        }
        return $data;
    }
    
    // Display the selected
    add_action( 'woocommerce_after_variations_form', 'variations_form_warranty_fee_js', 10 );
    function variations_form_warranty_fee_js() {
        global $product; ?>
        <script>
        jQuery( function($){
            const originalFee = $('.warranty-fee').html()
            $('form.cart').on('show_variation', function(event, data) {
                if ( data.warranty_fee !== undefined ) {
                    $('.warranty-fee').html( data.warranty_fee );
                } else {
                    $('.warranty-fee').html( originalFee );
                }
            }).on('hide_variation', function(){
                $('.warranty-fee').html( originalFee );
            });
        });
        </script>
        <?php
    }
    
    // Display warranty fee on product page
    add_action('woocommerce_single_product_summary', 'display_single_product_warranty_fee', 25);
    function display_single_product_warranty_fee() {
        global $product;
    
        echo '<div class="warranty-fee">';
    
        // Check if product is variable and variation is selected
        if ($product->is_type('variable') && ! isset($_REQUEST['variation_id'])) {
            // Do nothing if it's a variable product and no variation is selected
        } else {
            if ($item_fee = $product->get_meta('_warranty_fee')) {
                echo '<p style="margin-top: 10px; color: red;">' . sprintf( 
                __('You pay %s warranty for this product.', 'woocommerce'), 
                wp_strip_all_tags( wc_price($item_fee) ) ) . '</p>';
            }
        }
        echo '</div>';
    }
    
    // Adding a custom fee to cart based on a product custom field value calculation
    add_action('woocommerce_cart_calculate_fees', 'add_custom_cart_fee');
    function add_custom_cart_fee($cart) {
        $fee = 0; // Initializing variables
    
        // Loop through cart items
        foreach ($cart->get_cart() as $item) {
            $item_fee = $item['data']->get_meta('_warranty_fee');
    
            if ( $item['variation_id'] > 0 && ! $item_fee ) {
                $parent_product = wc_get_product($item['product_id']);
                $item_fee       = $parent_product->get_meta('_warranty_fee');
            }
    
            if ( $item_fee > 0 ) {
                $fee += $item['quantity'] * $item_fee;
            }
        }
    
        // Adding fee to cart if it's not zero
        if ( $fee > 0 ) {
            $cart->add_fee(__('Handling fee', 'woocommerce'), $fee, true, 'standard');
        }
    }
    
    // Display warranty fee on shop page
    add_filter('woocommerce_loop_add_to_cart_link', 'display_shop_page_warranty_fee', 10, 2);
    function display_shop_page_warranty_fee($link, $product) {
        $item_fee = $product->get_meta('_warranty_fee');
    
        if ($item_fee) {
            $warranty_text = sprintf(__('Warranty: %s', 'woocommerce'), wp_strip_all_tags(wc_price($item_fee)));
            $link = '<span class="warranty-fee-text" style="color: red;">' . $warranty_text . '</span><br/>' . $link;
        }
    
        return $link;
    }
    
    
    

  2. Since WooCommerce 3, your code is a bit outdated, with some mistakes. I have completely revised your code, adding the missing code to display the selected variation warranty fee.

    // add an input number field to Admin Product edit pages
    add_action('woocommerce_product_options_general_product_data', 'add_admin_product_warranty_fee_field');
    function add_admin_product_warranty_fee_field() {
        echo '<div class="options_group">';
    
        woocommerce_wp_text_input( array(
            'id'                => '_warranty_fee',
            'type'              => 'number',
            'label'             => __('Environmental fee', 'woocommerce'),
            'placeholder'       => '',
            'description'       => __('Enter the custom value here.', 'woocommerce'),
            'desc_tip'          => 'true',
            'custom_attributes' => array( 'step' => 'any', 'min' => '0' )
        ) );
    
        echo '</div>';
    }
    
    // Save input number field value from product edit page
    add_action('woocommerce_admin_process_product_object', 'save_admin_product_warranty_fee_field_value');
    function save_admin_product_warranty_fee_field_value( $product ) {
        $product->update_meta_data('_warranty_fee', isset($_POST['_warranty_fee']) ? esc_attr($_POST['_warranty_fee']) : '');
    }
    
    // add an input number field to Admin product variations settings
    add_action('woocommerce_variation_options_pricing', 'add_admin_variation_warranty_fee_field', 10, 3);
    function add_admin_variation_warranty_fee_field($loop, $variation_data, $variation) {    
        $variation_object = wc_get_product($variation->ID);
    
        echo '<div class="custom-variation-field">';
    
        woocommerce_wp_text_input(array(
            'id'                => "_warranty_fee[{$loop}]",
            'type'              => 'number',
            'label'             => __('Environmental fee', 'woocommerce'),
            'placeholder'       => '',
            'description'       => __('Enter the custom value here.', 'woocommerce'),
            'desc_tip'          => 'true',
            'wrapper_class'     => 'form-row form-row-wide',
            'custom_attributes' => array( 'step' => 'any', 'min' => '0' ),
            'value'             => $variation_object->get_meta('_warranty_fee'),
        ));
    
        echo '</div>';
    }
    
    // Save input number field value from product variation settings
    add_action( 'woocommerce_admin_process_variation_object', 'save_admin_variation_custom_fields', 10, 2 );
    function save_admin_variation_custom_fields( $variation, $i ) {
        $variation->update_meta_data('_warranty_fee', isset($_POST['_warranty_fee'][$i]) ? esc_attr($_POST['_warranty_fee'][$i]) : '');
    }
    
    // Add the variation formatted warranty fee price to the form data
    add_filter( 'woocommerce_available_variation', 'available_variation_formatted_price_per_unit', 10, 3 );
    function available_variation_formatted_price_per_unit( $data, $product, $variation ) {
        if ($item_fee = $variation->get_meta('_warranty_fee')) {
            $data['warranty_fee'] = '<p style="margin-top: 10px; color: red;">' . 
            sprintf( __('You pay %s warranty for this product.', 'woocommerce'), 
            wp_strip_all_tags( wc_price($item_fee) ) ) . '</p>';
        }
        return $data;
    }
    
    // Display the selected
    add_action( 'woocommerce_after_variations_form', 'variations_form_warranty_fee_js', 10 );
    function variations_form_warranty_fee_js() {
        global $product; ?>
        <script>
        jQuery( function($){
            const originalFee = $('.warranty-fee').html()
            $('form.cart').on('show_variation', function(event, data) {
                if ( data.warranty_fee !== undefined ) {
                    $('.warranty-fee').html( data.warranty_fee );
                } else {
                    $('.warranty-fee').html( originalFee );
                }
            }).on('hide_variation', function(){
                $('.warranty-fee').html( originalFee );
            });
        });
        </script>
        <?php
    }
    
    // Display warranty fee on product page
    add_action('woocommerce_single_product_summary', 'display_single_product_warranty_fee', 25);
    function display_single_product_warranty_fee() {
        global $product;
    
        echo '<div class="warranty-fee">';
    
        if ( $item_fee = $product->get_meta('_warranty_fee') ) {
            echo '<p style="margin-top: 10px; color: red;">' . sprintf( 
            __('You pay %s warranty for this product.', 'woocommerce'), 
            wp_strip_all_tags( wc_price($item_fee) ) ) . '</p>';
        }
        echo '</div>';
    }
    
    // Adding a custom fee to cart based on a product custom field value calculation
    add_action('woocommerce_cart_calculate_fees', 'add_custom_cart_fee');
    function add_custom_cart_fee($cart) {
        $fee = 0; // Initializing variables
    
        // Loop through cart items
        foreach ($cart->get_cart() as $item) {
            $item_fee = $item['data']->get_meta('_warranty_fee');
    
            if ( $item['variation_id'] > 0 && ! $item_fee ) {
                $parent_product = wc_get_product($item['product_id']);
                $item_fee       = $parent_product->get_meta('_warranty_fee');
            }
    
            if ( $item_fee > 0 ) {
                $fee += $item['quantity'] * $item_fee;
            }
        }
    
        // Adding fee to cart if it's not zero
        if ( $fee > 0 ) {
            $cart->add_fee(__('Handling fee', 'woocommerce'), $fee, true, 'standard');
        }
    }
    

    Code goes in functions.php file of your child theme (or in a plugin). Tested and works.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search