Стандартно средствами самого VM - никак
Под 1.1.4 могу предложить хак, который работает в реальном магазине экзотических морепродуктов, продающихся на развес...
ПЕРЕД ВЫПОЛНЕНИЕМ МАНИПУЛЯЦИЙ СДЕЛАЙТЕ БЕКАП БАЗЫ ДАННЫХ И РЕЗЕРВНЫЕ КОПИИ ИЗМЕНЯЕМЫХ ФАЙЛОВИзменения в базах данныхЗамена полей количества типа INT на DECIMAL(12,2) - длину поля и разрядность корректируйте под свои потребности.
Если выбраны не стандартные префиксы jos и vm, то измените на свои...
1) jos_vm_order_item
ALTER TABLE jos_vm_order_item MODIFY product_quantity DECIMAL(12,2)
2) jos_vm_product
ALTER TABLE jos_vm_product MODIFY product_sales DECIMAL(12,2)
ALTER TABLE jos_vm_product MODIFY product_in_stock DECIMAL(12,2)
3) jos_vm_product_price
ALTER TABLE jos_vm_product_price MODIFY price_quantity_start DECIMAL(12,2)
ALTER TABLE jos_vm_product_price MODIFY price_quantity_end DECIMAL(12,2)
Меняем код в классах VM - папка administrator/components/com_virtuemart/classesps_cart.php-----------
Перестановкой стандартных блоков кода исправлена "железная логика" программистов VM, которые сначала проверяют введенное количество на отрицательное значение и уж только потом проверяют, является ли оно числовым

Также принудительно заменяется десятичный разделитель с запятой на точку и заменяется округление до целого значения на округление до необходимого количества десятичных знаков.
* Строка 154
Найти:
// Check for negative quantity
if ($quantity < 0) {
vmRequest::setVar('product_id', $product_id );
$vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_NO_NEGATIVE',false) );
return False;
}
if ( !is_numeric($quantity) ) {
vmRequest::setVar('product_id', $product_id );
$vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_NO_VALID_QUANTITY',false) );
return False;
}
$quantity = intval($quantity);
Заменить:
$quantity = ereg_replace(",",".",$quantity );
if ( !is_numeric($quantity) ) {
vmRequest::setVar('product_id', $product_id );
$vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_NO_VALID_QUANTITY',false) );
return False;
}
// Check for negative quantity
if ($quantity < 0) {
vmRequest::setVar('product_id', $product_id );
$vmLogger->warning( $VM_LANG->_('PHPSHOP_CART_ERROR_NO_NEGATIVE',false) );
return False;
}
$quantity = round($quantity, 2);
$quantity = ereg_replace(",",".",$quantity ); - принудительная замена запятой на точку
$quantity = round($quantity, 2); - вместо 2 ставим свое количество десятичных знаков
ps_checkout.php---------------
Убираем округление до целого при расчете остатков на складе и количественном учете продаж
* Строка 1126
Найти:
$q .= "SET product_in_stock = product_in_stock - ".(int)$cart[$i]["quantity"];
Заменить:
$q .= "SET product_in_stock = product_in_stock - ".$cart[$i]["quantity"];
* Строка 1131
Найти:
$q .= "SET product_sales= product_sales + ".(int)$cart[$i]["quantity"];
Заменить:
$q .= "SET product_sales= product_sales + ".$cart[$i]["quantity"];
* Строка 1149
Найти:
$q .= "SET product_in_stock = product_in_stock + ".(int)$cart[$i]["quantity"];
Заменить:
$q .= "SET product_in_stock = product_in_stock + ".$cart[$i]["quantity"];
ps_product.php--------------
Коррекция кода отвечающего за вывод дискретного количества
* Строка 2595
Найти:
function set_quantity_options( &$d ) {
return vmGet($d,'quantity_box').","
.vmRequest::getInt('quantity_start').","
.vmRequest::getInt('quantity_end').","
.vmRequest::getInt('quantity_step');
}
Заменить:
function set_quantity_options( &$d ) {
return vmGet($d,'quantity_box').","
.vmRequest::getFloat('quantity_start').","
.vmRequest::getFloat('quantity_end').","
.vmRequest::getFloat('quantity_step');
}
* Строка 2609
Найти:
$quantity_options = array('quantity_start' => 0, 'quantity_end' => 0, 'quantity_step' => 1 );
Заменить:
$quantity_options = array('quantity_start' => 0, 'quantity_end' => 0, 'quantity_step' > 0 );
Шаблоныcomponents/com_virtuemart/themes/default/templates/product_details/quantity_box_general.tpl.phpДля корректной работы окошка ввода количества с кнопками увеличения/уменьшения количества изменяем код шаблона, чтобы вместо значения по умолчания 1 использовался параметр Step Value из Drop Down Box Values, т.е. шаг изменения количества в выпадающем списке.
* Строка 46
Найти:
<input type="button" class="quantity_box_button quantity_box_button_up" onclick="var qty_el = document.getElementById(\'quantity'.$prod_id.'\'); var qty = qty_el.value; if( !isNaN( qty )) qty_el.value++;return false;" />
<input type="button" class="quantity_box_button quantity_box_button_down" onclick="var qty_el = document.getElementById(\'quantity'.$prod_id.'\'); var qty = qty_el.value; if( !isNaN( qty ) && qty > 0 ) qty_el.value--;return false;" />
Заменить:
<input type="button" class="quantity_box_button quantity_box_button_up" onclick="var qty_el = document.getElementById(\'quantity'.$prod_id.'\'); var qty = qty_el.value; if( !isNaN( qty )) qty_el.value=Number(qty_el.value)+Number('.$quantity_step.'); qty_el.value=Math.round(qty_el.value*100)/100; return false;" />
<input type="button" class="quantity_box_button quantity_box_button_down" onclick="var qty_el = document.getElementById(\'quantity'.$prod_id.'\'); var qty = qty_el.value; if( !isNaN( qty ) && qty > 0 ) qty_el.value=Number(qty_el.value)-Number('.$quantity_step.'); qty_el.value=Math.round(qty_el.value*100)/100;; return false;" />
Обратите внимание на выражение: qty_el.value=Math.round(qty_el.value*100)/100 - здесь задается округление до необходимого количества десятичных знаков. В примере 100 - это 2 знака, соответсвенно qty_el.value=Math.round(qty_el.value*10)/10 - будет 1 знак, qty_el.value=Math.round(qty_el.value*1000)/1000 - 3 знака и т.д.
Вот вкратце (хм...

) и все