I was volunteering on the WordPress support forms and someone asked how they could use decimal quantities with WooCommerce stock.
This would take care of situations where you’re selling half of a sandwich, for example.
Let’s start off with some simple code: this will allow you to start inserting values as decimal quantities from the back end, removing the limit that is originally set which only permits you to add whole number quantities.
remove_filter('woocommerce_stock_amount','intval');
add_filter('woocommerce_stock_amount', 'floatval');
Now we’re going to enter in code that will adjust the minimum quantity price as well as the step value when a user selects a quantity when purchasing an item.
First, we’ll deal with the step value.

If the quantity is not a whole number then we want the customer to be able to increase or decrease a quantity by a decimal, otherwise we want to have the step value be a whole number:
add_filter('woocommerce_quantity_input_step','ian_sackofwits_woo_decimal_step', 10, 2);
function ian_sackofwits_woo_decimal_step($val, $product) {
$qnt = $product->get_stock_quantity();
$num_decimals = strlen(substr(strrchr($qnt, "."), 1));
$step = is_float($qnt) ? "." . "0" * $num_decimals . "1" : '1';
return $step;
}
Now, onto the minimum quantity that can be selected.

Now, we will use the same logic in determining the minimum value for the quantity:
add_filter('woocommerce_quantity_input_min','ian_sackofwits_woo_decimal_min', 10, 2);
function ian_sackofwits_woo_decimal_min($val, $product) {
$qnt = $product->get_stock_quantity();
$num_decimals = strlen(substr(strrchr($qnt, "."), 1));
$step = is_float($qnt) ? "." . "0" * $num_decimals . "1" : '1';
return $step;
}
And, finally, now we have to deal with an issue showing the unit price for processed orders. :
add_filter('woocommerce_order_amount_item_total', 'ian_sackofwits_unit_total_fix', 10, 5);
function ian_sackofwits_unit_total_fix($total, $order, $item, $inc_tax = false, $round = true) {
$qnt = (!empty($item['qty']) && $item['qty'] != 0) ? $item['qty'] : 1;
$total = $inc_tax ? $item['line_total'] + $item['line_tax'] / $qnt : $total = $item['line_total'] / $qnt;
$total = $round ? round( $total, 2 ) : $total;
return $total;
}
Here’s the full complete code:
remove_filter('woocommerce_stock_amount','intval');
add_filter('woocommerce_stock_amount', 'floatval');
add_filter('woocommerce_quantity_input_step','ian_sackofwits_woo_decimal_step', 10, 2);
function ian_sackofwits_woo_decimal_step($val, $product) {
$qnt = $product->get_stock_quantity();
$num_decimals = strlen(substr(strrchr($qnt, "."), 1));
$step = is_float($qnt) ? "." . "0" * $num_decimals . "1" : '1';
return $step;
}
add_filter('woocommerce_quantity_input_min','ian_sackofwits_woo_decimal_min', 10, 2);
function ian_sackofwits_woo_decimal_min($val, $product) {
$qnt = $product->get_stock_quantity();
$num_decimals = strlen(substr(strrchr($qnt, "."), 1));
$step = is_float($qnt) ? "." . "0" * $num_decimals . "1" : '1';
return $step;
}
add_filter('woocommerce_order_amount_item_total', 'ian_sackofwits_unit_total_fix', 10, 5);
function ian_sackofwits_unit_total_fix($total, $order, $item, $inc_tax = false, $round = true) {
$qnt = (!empty($item['qty']) && $item['qty'] != 0) ? $item['qty'] : 1;
$total = $inc_tax ? $item['line_total'] + $item['line_tax'] / $qnt : $total = $item['line_total'] / $qnt;
$total = $round ? round( $total, 2 ) : $total;
return $total;
}
Add this code to your theme’s functions.php file or use a plugin such as Code Snippets.
Thank yo uso much! I was going crazy with this one!