/ Плагины / Шаг количества товара

Шаг количества товара

HIT

19.06.2018

7178

3

Шаг количества товара или кратность в некоторых сферах интернет торговли является важной составляющей. Рассмотрим варианты создания данного функционала.

Quantities and Units for WooCommerce

Плагин Quantities and Units for WooCommerce (3,000+) дает возможность создавать как массовые правила для различных групп товаров (категорий, меток, ролей пользователей), так и индивидуальные игнорируя массовые. Можно назначить шаг количества (в т.ч. десятичные значения), минимальное (должно быть не меньше количества шага) и максимальное количество, минимальное и максимальное количество чтобы считать товар не в наличии (если на сайте учитываются остатки), а также приоритет правила.

Приятным бонусом плагина является добавление единицы измерения в каждый товар. Как создавать единицу измерения товара без плагина описано здесь.
Данный плагин начинает конфликтовать с кнопкой минус, если из этого решения по изменению вида quantity

Просто надо обновить скрипты:

$(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 вместе работают отлично. Больше ничего и не нужно. Ниже уже вариации на тему.

Если массово проставлять товарам различные значения шага и минимума, у них также должно быть проставлено поле _wpbo_override со значением on. Это включение индивидуальной настройки шага товара.

Используя десятичные значения количества можно немного переработать миникорзину под вывод количества наименований.

У плагина Quantities and Units for WooCommerce при активации режима WP_DEBUG обнаружились не фатальные ошибки связанные с устаревшими функциями при переходе на WC 3.0. Плагин давно не обновлялся поэтому это приходиться делать самому.

Нашелся еще один недочет этого плагина, помимо того что в коде много устаревших вызовов 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).

Выборку по категориям настроить нельзя.

Поделиться в соц. сетях:

  • Похожие записи
  • Комментарии
  • Вложения
Woocommerce и валюта

Woocommerce и валюта

Разбираем различные решения по работе с валютами (не мультивалютность, это отдельная тема). Курс в другой валюте Если мы торгуем на сайте в рублях, но нам нужно чтобы рядом с каждой Читать далее »

Адаптация woocommerce под свой шаблон

Адаптация woocommerce под свой шаблон

Первое что мы должны сделать при разработке темы включающей в себя функционал интернет-магазина — адаптировать woocommerce под свой шаблон. Локализация woocommerce Для адаптации woocommerce в нашем шаблоне необходимо: Создать в Читать далее »

Обзор плагинов по фильтрации товаров WC

Обзор плагинов по фильтрации товаров WC

В данном обзоре мы будем приводить сильные и слабые стороны различных плагинов по созданию фильтрации товаров WC. Причем рассмотрим как платные, так и бесплатные решения. WooCommerce Products Filter (50 000) Читать далее »

/

Добавить комментарий

3 комментария

  1. Иннокентий

    А какие именно скрипты нужно поправить, что бы кнопка минус заработала?

    1. Alexandr

      Вот в этой статье есть решение Изменить вид quantity. К нему есть скрипт. Так вот для корректной работы с плагином Quantities and Units for WooCommerce нужно обновить скрипт на тот который я прописал выше.

  2. Евгений

    Подскажи пожалуйста WooCommerce Advanced Quantity не работает в мини корзине с темой Астра — duhi.md сайт. 
    Не могу понять почему не передается количество товара в мини корзину а в корзине все отображается нормально.

Акция 20% на каждый второй и 30% на каждый 3 товар
Рекомендации для васАкция 20% на каждый второй и 30% на каждый 3 товарOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.