Шаг количества товара или кратность в некоторых сферах интернет торговли является важной составляющей. Рассмотрим варианты создания данного функционала.
Quantities and Units for WooCommerce
Плагин Quantities and Units for WooCommerce (3,000+) дает возможность создавать как массовые правила для различных групп товаров (категорий, меток, ролей пользователей), так и индивидуальные игнорируя массовые. Можно назначить шаг количества (в т.ч. десятичные значения), минимальное (должно быть не меньше количества шага) и максимальное количество, минимальное и максимальное количество чтобы считать товар не в наличии (если на сайте учитываются остатки), а также приоритет правила.
Просто надо обновить скрипты:
$(document).ready(function(){
$('.quantity').on('click', '.plus', function() {
$input = $(this).prev('input.qty');
var val = parseFloat($input.val());
var step = parseFloat($input.attr('step'));
$input.val( val+step ).change();
});
$('.quantity').on('click', '.minus', function() {
$input = $(this).next('input.qty');
var val = parseFloat($input.val());
var step = parseFloat($input.attr('step'));
var min = parseFloat($input.attr('min'));
if (val > min) { $input.val( val-step ).change(); }
});
});
// Скрипт для кнопок + и - в шаблоне Корзина
$(document).ready(function(){
$('body').on('click', '.plus', function(e) {
$input = $(this).prev('input.qty');
var val = parseFloat($input.val());
var step = parseFloat($input.attr('step'));
$input.val( val+step ).change();
});
$('body').on('click', '.minus', function(e) {
$input = $(this).next('input.qty');
var val = parseFloat($input.val());
var step = parseFloat($input.attr('step'));
var min = parseFloat($input.attr('min'));
if (val > min) { $input.val( val-step ).change(); }
});
});
//Кнопка Обновить в Корзине изначально активна
$(document).bind('ready ajaxComplete', function(){
$('[name="update_cart"]').attr("disabled",false);
});
Плагин Quantities and Units for WooCommerce и доработка кнопок quantity вместе работают отлично. Больше ничего и не нужно. Ниже уже вариации на тему.
Используя десятичные значения количества можно немного переработать миникорзину под вывод количества наименований.
Нашелся еще один недочет этого плагина, помимо того что в коде много устаревших вызовов WC (более 4-х лет не обновлялся), но это можно поправить вручную, кратность некорректно работает при добавлении товаров из категории ajax. Происходит переход в карточку с предупреждением
WooCommerce Advanced Quantity
Есть еще один плагин дающий тот же функционал — WooCommerce Advanced Quantity, но он платный — 27$ (19.06). Протестировав могу сказать, что он включает в себя весь функционал предыдущего плагина, и исправно работает с добавлением товара ajax’ом. 01.06.21 этот плагин стоит 45$.
При использовании своего скрипта по добавлению кнопок + — некоторые цифры становятся с большим количеством десятичных цифр, исправить это можно, принудительно указав в скрипте округлять до определенного знака:
var calc = val-step;
if (val > min) { $input.val( calc.toFixed(1) ).change(); }
var calc = val+step;
$input.val( calc.toFixed(1) ).change();
toFixed(1) — до одного знака после запятой.
Глобальное изменение шага
add_filter( 'woocommerce_quantity_input_args', 'jk_woocommerce_quantity_input_args', 10, 2 ); // Simple products
function jk_woocommerce_quantity_input_args( $args, $product ) {
if ( is_singular( 'product' ) ) {
$args['input_value'] = 2; // Starting value (we only want to affect product pages, not cart)
}
$args['max_value'] = 80; // Maximum value
$args['min_value'] = 2; // Minimum value
$args['step'] = 2; // Quantity steps
return $args;
}
add_filter( 'woocommerce_available_variation', 'jk_woocommerce_available_variation' ); // Variations
function jk_woocommerce_available_variation( $args ) {
$args['max_qty'] = 80; // Maximum value (variations)
$args['min_qty'] = 2; // Minimum value (variations)
return $args;
}
Шаг товара из метаполя
Дорабатываем предыдущий скрипт и привязываем к нему метаполе с шагом количества.
// Simple products
add_filter( 'woocommerce_quantity_input_args', 'jk_woocommerce_quantity_input_args', 10, 2 );
function jk_woocommerce_quantity_input_args( $args, $product ) {
$pcs_pack = get_post_meta($product->post->ID, "step_text_field", true);
//$args['max_value'] = 80; // Maximum value
$args['min_value'] = $pcs_pack; // Minimum value
if ( !empty($pcs_pack) ) { $args['step'] = $pcs_pack; }
else { $args['step'] = 1; }
return $args;
}
// Variations
add_filter( 'woocommerce_available_variation', 'jk_woocommerce_available_variation' );
function jk_woocommerce_available_variation( $args ) {
//$args['max_qty'] = 80; // Maximum value (variations)
$args['min_qty'] = $pcs_pack; // Minimum value (variations)
return $args;
}
Создаем метаполе
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_step_field' );
function woo_add_step_field() {
global $woocommerce, $post;
echo '<div class="options_group">';
// Add Text field in woocommerce
woocommerce_wp_text_input(
array(
'id' => 'step_text_field',
'label' => __( 'Шаг количества', 'woocommerce' ),
'placeholder' => 'шаг количества',
'desc_tip' => 'true',
'description' => __( 'Введите шаг количества.', 'woocommerce' ),
'type' => 'number'
)
);
echo '</div>';}
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_step_field_save' );
function woo_add_custom_step_field_save( $post_id ){
// Text Field
$woocommerce_text_field = $_POST['step_text_field'];
if( !empty( $woocommerce_text_field ) )
update_post_meta( $post_id, 'step_text_field', esc_attr( $woocommerce_text_field ) );
}
Если используется решение по изменению кнопок (+ и -) необходимо доработать скрипты для товаров:
$(document).ready(function(){
$('.quantity').on('click', '.plus', function() {
$input = $(this).prev('input.qty');
var val = parseInt($input.val());
var step = parseInt($input.attr('step'));
$input.val( val+step ).change();
});
$('.quantity').on('click', '.minus', function() {
$input = $(this).next('input.qty');
var val = parseInt($input.val());
var step = parseInt($input.attr('step'));
if (val > step) { $input.val( val-step ).change(); }
});
});
и корзины:
$(document).ready(function(){
$('body').on('click', '.plus', function(e) {
$input = $(this).prev('input.qty');
var val = parseInt($input.val());
var step = parseInt($input.attr('step'));
$input.val( val+step ).change();
});
$('body').on('click', '.minus', function(e) {
$input = $(this).next('input.qty');
var val = parseInt($input.val());
var step = parseInt($input.attr('step'));
if (val > step) { $input.val( val-step ).change(); }
});
});
А шаблон quantity-input.php должен выглядеть примерно так:
<input class="minus" type="button" value="-">
<input
type="number"
id="<?php echo esc_attr( $input_id ); ?>"
class="input-text qty text"
step="<?php echo esc_attr( $step ); ?>"
min="<?php echo esc_attr( $min_value ); ?>"
max="<?php echo esc_attr( 0 < $max_value ? $max_value : '' ); ?>"
name="<?php echo esc_attr( $input_name ); ?>"
value="<?php echo esc_attr( $input_value ); ?>"
title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ); ?>"
size="4"
pattern="<?php echo esc_attr( $pattern ); ?>"
inputmode="<?php echo esc_attr( $inputmode ); ?>"
aria-labelledby="<?php echo esc_attr( $labelledby ); ?>" />
<input class="plus" type="button" value="+">
Минимальное количество товара из метаполя
Добавляем еще одно метаполе — как это сделать см. выше. Немного меняем функцию формирования количества:
function jk_woocommerce_quantity_input_args( $args, $product ) {
$pcs_step = get_post_meta($product->post->ID, "step_text_field", true);
$pcs_min = get_post_meta($product->post->ID, "min_text_field", true);
//$args['max_value'] = 80; // Maximum value
if ( !empty($pcs_step) ) { $args['min_value'] = $pcs_min; }
else { $args['min_value'] = 1; }
if ( !empty($pcs_step) ) { $args['step'] = $pcs_step; }
else { $args['step'] = 1; }
return $args;
}
И снова нужно доработать скрипты кнопок — и + (если используются), добавив в части минуса захват значения min
var min = parseInt($input.attr('min'));
if (val > min) { $input.val( val-step ).change(); }
Вводим десятичность
Глобально уменьшить шаг до десятичных чисел можно таким образом:
// Add min value to the quantity field (default = 1)
add_filter('woocommerce_quantity_input_min', 'min_decimal');
function min_decimal($val) { return 0.5; }
// Add step value to the quantity field (default = 1)
add_filter('woocommerce_quantity_input_step', 'nsk_allow_decimal');
function nsk_allow_decimal($val) { return 0.5; }
// Removes the WooCommerce filter, that is validating the quantity to be an int
remove_filter('woocommerce_stock_amount', 'intval');
// Add a filter, that validates the quantity to be a float
add_filter('woocommerce_stock_amount', 'floatval');
// Add unit price fix when showing the unit price on processed orders
add_filter('woocommerce_order_amount_item_total', 'unit_price_fix', 10, 5);
function unit_price_fix($price, $order, $item, $inc_tax = false, $round = true) {
$qty = (!empty($item['qty']) && $item['qty'] != 0) ? $item['qty'] : 1;
if($inc_tax) {
$price = ($item['line_total'] + $item['line_tax']) / $qty;
} else {
$price = $item['line_total'] / $qty;
}
$price = $round ? round( $price, 2 ) : $price;
return $price;
}
Но данные функции не работают с предыдущими решениями (функции из предыдущих решений их перекрывают).
Корректно работают с кнопками + и — только нужно изменить преобразование до целого числа на преобразование на число с плавающей точкой, заменив parseInt на parseFloat.
Вывод данных в шаблоне товара
С данными (кратность, минимальное количество) далее можно экспериментировать и выводить данные где угодно. Пример (сайт по продаже ламината):
// Вывод данных по количеству
function wc_get_step_size() {
global $product;
$step_size = get_post_meta($product->post->ID, "_wpbo_step", true);
$step_min = get_post_meta($product->post->ID, "_wpbo_minimum", true);
$step_unit = get_post_meta($product->post->ID, "unit_text_field", true);
$price_pack = $product->get_price() * $step_size;
if ( !empty($step_size) ) { echo '
В упаковке '.$step_size.' '.$step_unit.' ('.$price_pack.' руб.)
'; }
if ( !empty($step_min) ) { echo '
Мин. количество заказа — '.$step_min.' '.$step_unit.'
'; }
}
add_filter( 'woocommerce_single_product_summary', 'wc_get_step_size', 16 );
unit_text_field — это поле из моей функции по созданию единиц измерения товара.
Другие плагины по данному функционалу
All in One Product Quantity for WooCommerce (WPWhale, 3000)
В бесплатной версии отсутствует возможность управлять полем на уровне товара, только глобальные настройки. Зато в Pro-версии каждым аспектом можно управлять на уровне и товаров и категорий. Также плагин предоставляет функционал единицы измерения товара.
WPC Product Quantity for WooCommerce (WPClever, 1000)
В free-версии только глобальные настройки. Настройки на уровне товара в Pro-версии за 34,80 $ (01.06.21).
Выборку по категориям настроить нельзя.
[site-socialshare]
А какие именно скрипты нужно поправить, что бы кнопка минус заработала?
Вот в этой статье есть решение Изменить вид quantity. К нему есть скрипт. Так вот для корректной работы с плагином Quantities and Units for WooCommerce нужно обновить скрипт на тот который я прописал выше.
Подскажи пожалуйста WooCommerce Advanced Quantity не работает в мини корзине с темой Астра — duhi.md сайт.
Не могу понять почему не передается количество товара в мини корзину а в корзине все отображается нормально.