Search code examples
phpjquerywordpresswoocommerceproduct

Display product total price and mesurements based on quantity and product category in WooCommerce


I'm sorry to bring this code snippet to here once again. I am trying to learn hard though from the help I've been getting, so I really appreciate the help.

I have a code snippet to calculate the amount of fabric being purchased in 1/2 meter lengths. This helps the customer work out how much they are buying.

The code below is working perfect.

I need to add an additional bit of code for 1/4 meter which will be assigned to the product category 'quarter-metre.

I tried duplicating the snippet and amending the code, but you can't call the function twice.

Here is a half meter product with the snippet: https://thefabricboutique.co.uk/product/stonewashed-ramie-cotton-blend-indigo/

Here is a quarter meter fabric which needs the alternative code: https://thefabricboutique.co.uk/product/tilda-jubilee-collection-bird-tree-blue/

Example: Add 1 unit for 0.25 metre (£5.50)

add_action( 'woocommerce_before_add_to_cart_quantity', 'display_product_total_amount_html' );
function display_product_total_amount_html() {
    global $product;
    if( ! has_term( array('half-metre'), 'product_cat', $product->get_id() ) ) return;
    
    $metres_per_qty  = 0.5;
    $display_price   = wc_get_price_to_display($product);
    $formatted_price = '<span class="price-amount">'. number_format($display_price, 2) . '</span>';

    // Output product total price amount
    $price_string = sprintf( __('Add %s for %s (%s)', 'woocommerce'),
        '<span class="qty-units">1 unit</span>', 
        '<span class="qty-metres">' . $metres_per_qty . ' metre</span>',
        str_replace('0.00', $formatted_price, wc_price(0)) );

    // Output product total price amount
    echo '<div class="total-price_qty" style="margin-bottom:20px;">'.$price_string.'</div>'
    ?>
    <script>
    jQuery(function($){
        $('input[name=quantity]').on( 'input change', function(){
            const qty = $(this).val();
            if ( qty != 0 ) {
                const qtyTxt    = qty > 1 ? ' units' : ' unit',
                      lengthTxt = qty > 2 ? ' metres' : ' metre';
                $('.total-price_qty .qty-units').html( parseInt(qty)+qtyTxt );
                $('.total-price_qty .qty-metres').html( parseFloat(<?php echo $metres_per_qty; ?> * qty)+lengthTxt );
                $('.total-price_qty .price-amount').html( parseFloat(<?php echo $display_price; ?> * qty).toFixed(2) );
            }
        });
    });
    </script>
    <?php 
}

Solution

  • Try the following revised code that will handle your 2 length units (product category based):

    add_action( 'woocommerce_before_add_to_cart_quantity', 'display_product_total_amount_html' );
    function display_product_total_amount_html() {
        global $product;
    
        $is_quarter = has_term('quarter-metre', 'product_cat', $product->get_id());
        $is_half    = has_term('half-metre', 'product_cat', $product->get_id());
    
        if( ! ($is_quarter || $is_half) ) return;
    
        $metres_per_qty  = $is_half ? 0.5 : 0.25;
        $display_price   = wc_get_price_to_display($product);
        $formatted_price = '<span class="price-amount">'. number_format($display_price, 2) . '</span>';
        $price_string    = sprintf( __('Add %s for %s (%s)', 'woocommerce'),
            '<span class="qty-units">1 unit</span>', 
            '<span class="qty-metres">' . $metres_per_qty . ' metre</span>',
            str_replace('0.00', $formatted_price, wc_price(0)) );
    
        // Output HTML
        printf('<div class="total-price_qty" style="margin-bottom:20px;">%s</div>', $price_string);
        
        // Enqueue Javascript code
        wc_enqueue_js( "$('input[name=quantity]').on('input change', function(){
            const qty = $(this).val();
            if ( qty != 0 ) {
                const   qtyTxt    = qty > 1 ? ' units' : ' unit',
                        lengthTxt = qty > ".intval(1 / $metres_per_qty)." ? ' metres' : ' metre';
                    $('.total-price_qty .qty-units').html( parseInt(qty)+qtyTxt );
                    $('.total-price_qty .qty-metres').html( parseFloat({$metres_per_qty} * qty)+lengthTxt );
                    $('.total-price_qty .price-amount').html( parseFloat({$display_price} * qty).toFixed(2) );
                }
        });" );
    }
    

    For "quarter-metre" category you will get something like:

    enter image description here

    For "half-metre" category you will get something like:

    enter image description here

    Related: Display formated product total and mesurements based on quantity in WooCommerce