Dmitry
Dmitry

Reputation: 155

Calculate and show the new price after choosing the weight of the product in WooCommerce

In WooCommerce, I use a code that shows the steak weight selection form, saves the selection data and displays this data in the cart, on the checkout page, when editing the order and in email notifications.

// Display Custom Checkbox Field
add_action('woocommerce_product_options_general_product_data', 'steak_custom_field_add');
function steak_custom_field_add(){
    global $post;

    // Checkbox
    woocommerce_wp_checkbox(
        array(
            'id' => '_steak_checkbox',
            'label' => __('Steak Weight', 'woocommerce' ),
            'description' => __( 'If necessary, enable steak weight selection', 'woocommerce' )
        )
    );
}

// Save Custom Checkbox Field
add_action('woocommerce_process_product_meta', 'steak_custom_field_save');
function steak_custom_field_save($post_id){
    // Custom Product Checkbox Field
    $steak_checkbox = isset( $_POST['_steak_checkbox'] ) ? 'yes' : 'no';
    update_post_meta($post_id, '_steak_checkbox', esc_attr( $steak_checkbox ));
}

// Display Custom Select Box
add_action( 'woocommerce_before_add_to_cart_button', 'display_steak_custom_field', 0 );
function display_steak_custom_field() {
    global $product;

    // If is single product page and have the "steak_checkbox" enabled we display the field
    if ( $product->get_meta( '_steak_checkbox' ) === 'yes' ) {

        echo '<div class="steak_select_box">';

        $select = woocommerce_form_field( 'steak_custom_options', array(
            'type'          => 'select',
            'class'         => array('my-steak-select-box form-row-wide'),
            'label'         => __('Steak Weight'),
            'required'      => false,
            'return'       => false,
            'options'   => array(
                ''      => 'Select...',
                '300g'  => '300g',
                '400g'  => '400g',
                '500g'  => '500g',
                '600g'  => '600g',
                '700g'  => '700g',
                '800g'  => '800g',
                '900g'  => '900g',
                '1000g'  => '1000g'
            )
        ), '' );
        echo $select;
        echo '</div>';
    }
}

// Add as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_steak_cart_item_data', 10, 21 );
function add_custom_steak_cart_item_data($cart_item_data, $product_id, $variation_id ){

    if( isset( $_POST['steak_custom_options'] ) ) {
        $cart_item_data['steak_option'] = wc_clean( $_POST['steak_custom_options'] );
    }
    return $cart_item_data;
}

// Add custom fields values under cart item name in cart
add_filter( 'woocommerce_cart_item_name', 'steak_custom_field_add_cart', 10, 21 );
function steak_custom_field_add_cart( $item_name, $cart_item, $cart_item_key ) {
    if( ! is_cart() )
        return $item_name;

    if( isset($cart_item['steak_option']) ) {
        $item_name .= '<div class="my-steak-class"><strong>' . __("Steak Weight", "woocommerce") . ':</strong> ' . $cart_item['steak_option'] . '</div>';
    }
    return $item_name;
}

// Display custom fields values under item name in checkout
add_filter( 'woocommerce_checkout_cart_item_quantity', 'steak_custom_checkout_cart_item_name', 10, 21 );
function steak_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {
    if( isset($cart_item['steak_option']) ) {
        $item_qty .= '<div class="my-steak-class"><strong>' . __("Steak Weight", "woocommerce") . ':</strong> ' . $cart_item['steak_option'] . 'гр.</div>';
    }
    return $item_qty;
}


// Save chosen select field value to each order item as custom meta data and display it everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_steak_field', 10, 21 );
function save_order_item_steak_field( $item, $cart_item_key, $values, $order ) {
    if( isset($values['steak_option']) ) {
        $key = __('Steak Weight', 'woocommerce');
        $value = $values['steak_option'];
        $item->update_meta_data( $key, $value ,$item->get_id());
    }
}

add_action('wp_footer','add_footer_steak_script');
function add_footer_steak_script(){
    ?>
    <script>
       ( function( $ ) {
   $( document ).ready( function() {
       $(document).on('change', '#steak_custom_options' ,function() {
           $('.add_to_cart_button').data('steak_custom_options', this.value)
       });
   });
 }( jQuery ) );
    </script>
    <?php
}

But unfortunately, I do not know how to solve one problem ...

The price of this product is calculated per 100 grams. The minimum order quantity is 300 grams. And I need that, when choosing the weight of the product, the final cost of this product should be calculated accordingly.

For example:

for 300g - $regular_price * 3 = $new_price
for 500g - $regular_price * 5 = $new_price
for 1000g - $regular_price * 10 = $new_price

etc.

The total cost of this product should be shown next to the main price per 100 grams.

I think this code will be useful to other developers as well. I will be very happy for your help!

Upvotes: 3

Views: 1528

Answers (1)

7uc1f3r
7uc1f3r

Reputation: 29614

To adjust the product price, on the cart page, etc.. based on the weight selected from the dropdown, add the following code

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

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

    // Loop through cart items
    foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {     
        if( isset( $cart_item['steak_option'] ) ) {

            // Remove the last 2 zeros (100g becomes 1, 300g becomes 3, 1000g becomes 10, etc...)
            // Remove 'g' from grams
            // convert string to integer
            $chosen_weight = (int) str_replace( '00', '', str_replace('g', '', $cart_item['steak_option']) );

            // Get current price
            $current_price = $cart_item['data']->get_price();

            // Set new price, price is already known per 100g
            $cart_item['data']->set_price( $current_price * $chosen_weight );
        }
    }
}
add_action( 'woocommerce_before_calculate_totals', 'my_before_calculate_totals', 10, 1 );

To change the price on the single product page, based on the dropdown menu, add this

function add_footer_steak_script() {
    global $woocommerce, $product;
    ?>
    <script type="text/javascript">
        jQuery(document).ready(function ($) {
            console.log('JS works!');

            var price = <?php echo $product->get_price(); ?>, currency = '<?php echo get_woocommerce_currency_symbol(); ?>';

            $( '[name=steak_custom_options]' ).change(function(){
                if (!(this.value < 1)) {
                    var dropdown_val = this.value;
                    var remove_g = dropdown_val.replace( 'g', '' );
                    var remove_double_zero = remove_g.replace( '00', '' );

                    var product_total = parseFloat( price * remove_double_zero );

                    $( '.woocommerce-Price-amount' ).html( currency + product_total.toFixed(2));

                }
            });
        });
    </script>
    <?php
}
add_action('wp_footer','add_footer_steak_script');

Upvotes: 2

Related Questions