0
// Add custom quantity setting fields to the admin product pages
add_action('woocommerce_product_options_pricing', 'wc_qty_add_product_field');
function wc_qty_add_product_field() {
    global $product_object;

    // Retrieve existing meta values
    $values = $product_object->get_meta('_qty_args');

    echo '<div class="options_group quantity hide_if_grouped">
            <style>div.qty-args.hidden { display:none; }</style>';

    // Checkbox to enable quantity settings
    woocommerce_wp_checkbox(array(
        'id' => 'qty_args',
        'label' => __('Quantity settings', 'woocommerce'),
        'value' => !empty($values) ? 'yes' : 'no',
        'description' => __('Enable this to show and enable the additional quantity setting fields.', 'woocommerce'),
    ));

    // Quantity arguments container
    echo '<div class="qty-args hidden">';

    // Minimum Quantity
    woocommerce_wp_text_input(array(
        'id' => 'qty_min',
        'type' => 'number',
        'label' => __('Minimum Quantity', 'woocommerce-max-quantity'),
        'desc_tip' => true,
        'description' => __('Set a minimum allowed quantity limit (a number greater than 0).', 'woocommerce'),
        'custom_attributes' => array('step' => 'any', 'min' => '0'),
        'value' => isset($values['qty_min']) ? (float) $values['qty_min'] : 0,
    ));

    // Maximum Quantity
    woocommerce_wp_text_input(array(
        'id' => 'qty_max',
        'type' => 'number',
        'label' => __('Maximum Quantity', 'woocommerce-max-quantity'),
        'desc_tip' => true,
        'description' => __('Set the maximum allowed quantity limit (a number greater than 0). Value "-1" is unlimited', 'woocommerce'),
        'custom_attributes' => array('step' => 'any', 'min' => '-1'),
        'value' => isset($values['qty_max']) ? (float) $values['qty_max'] : -1,
    ));

    // Quantity Step
    woocommerce_wp_text_input(array(
        'id' => 'qty_step',
        'type' => 'number',
        'label' => __('Quantity step', 'woocommerce-quantity-step'),
        'desc_tip' => true,
        'description' => __('Optional. Set quantity step (a number greater than 0)', 'woocommerce'),
        'custom_attributes' => array('step' => 'any', 'min' => '0.01'), // Minimum step is 0.01 for decimal support
        'value' => isset($values['qty_step']) ? (float) $values['qty_step'] : 0.1, // Default step value as 0.1
    ));

    echo '</div></div>';
}

// Show/hide setting fields (admin product pages)
add_action('admin_footer', 'product_type_selector_filter_callback');
function product_type_selector_filter_callback() {
    global $pagenow, $post_type;

    if (in_array($pagenow, array('post-new.php', 'post.php')) && $post_type === 'product') :
        ?>
        <script>
            jQuery(function($) {
                const toggleQtyArgs = function() {
                    $('div.qty-args').toggleClass('hidden', !$('#qty_args').is(':checked'));
                };
                toggleQtyArgs();
                $('#qty_args').change(toggleQtyArgs);
            });
        </script>
        <?php
    endif;
}

// Save quantity setting fields values
add_action('woocommerce_admin_process_product_object', 'wc_save_product_quantity_settings');
function wc_save_product_quantity_settings($product) {
    if (isset($_POST['qty_args'])) {
        $product->update_meta_data('_qty_args', array(
            'qty_min' => isset($_POST['qty_min']) && $_POST['qty_min'] > 0 ? (float) wc_clean($_POST['qty_min']) : 0,
            'qty_max' => isset($_POST['qty_max']) ? (float) wc_clean($_POST['qty_max']) : -1,
            'qty_step' => isset($_POST['qty_step']) && $_POST['qty_step'] > 0 ? (float) wc_clean($_POST['qty_step']) : 0.1, // Default step is set to 0.1
        ));
    } else {
        $product->delete_meta_data('_qty_args'); // Clear settings if not enabled
    }
}

// Adjust quantity inputs on the front end
add_filter('woocommerce_quantity_input_args', 'filter_wc_quantity_input_args', 99, 2);
function filter_wc_quantity_input_args($args, $product) {
    $values = $product->is_type('variation') ? wc_get_product($product->get_parent_id())->get_meta('_qty_args') : $product->get_meta('_qty_args');

    if (!empty($values)) {
        // Set min, max, and step values
        $args['min_value'] = isset($values['qty_min']) ? (float) $values['qty_min'] : 0;
        $args['max_value'] = isset($values['qty_max']) && $values['qty_max'] > 0 ? (float) $values['qty_max'] : null;
        $args['step'] = isset($values['qty_step']) ? (float) $values['qty_step'] : 0.1; // Default step is set to 0.1

        // Set initial input value if not on cart page
        if (!is_cart()) {
            $args['input_value'] = $args['min_value'];
        }
    }
    return $args;
}

// Adjust add to cart quantity on shop and archives pages
add_filter('woocommerce_loop_add_to_cart_args', 'filter_loop_add_to_cart_quantity_arg', 10, 2);
function filter_loop_add_to_cart_quantity_arg($args, $product) {
    $values = $product->get_meta('_qty_args');

    if (!empty($values) && isset($values['qty_min']) && $values['qty_min'] > 0) {
        $args['quantity'] = (float) $values['qty_min']; // Ensure quantity is set as float
    }
    return $args;
}

// Apply quantity settings for variable products
add_filter('woocommerce_available_variation', 'filter_wc_available_variation_price_html', 10, 3);
function filter_wc_available_variation_price_html($data, $product, $variation) {
    $values = $product->get_meta('_qty_args');

    if (!empty($values)) {
        $data['min_qty'] = isset($values['qty_min']) ? (float) $values['qty_min'] : 0;
        $data['max_qty'] = isset($values['qty_max']) && $values['qty_max'] > 0 ? (float) $values['qty_max'] : null;

        // Adjust max_qty based on stock management settings
        if ($variation->managing_stock() && !$variation->backorders_allowed()) {
            $data['max_qty'] = min($variation->get_stock_quantity(), $data['max_qty']);
        }
    }
    return $data;
}

I'm looking for a way to set a decimal product quantity for each product in my woocommerce store. I have used already found code as a basis ( Set quantity minimum, maximum and step at product level in Woocommerce ), as different products in my store have different min/max values and quantity increments. I improved the code by giving it the ability to count decimal digits. They are applied in the product settings page, in the product page, but now I have a problem that the selected product quantity in the shopping cart is rounded. I can't find a way to solve this problem, maybe someone has already encountered a similar problem? The code snippet above is improved code with decimals

0

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.