Задача. Часть товаров продаются по цене за м², но в упаковках. Необходимо на таких страницах товаров добавить поле ввода числа упаковок при изменении которого будет изменяться стандартное поле количества товаров. Также нужно настроить поле количества товаров так, чтобы можно было вводить дробные числа, т.к. в упаковке, в большинстве случаев, будет дробное число (Пример №1).
Решение №1. Алгоритм вывода кастомного поля товара и настройки дробного количества товара:
- Сделать пользовательское поле в настройках товара (Код №1.1) в котором будем задавать шаг количества товара (оно же количество товара в одной упаковке).
- Вывести на странице товара поле количества упаковок и цену за упаковки (Код №1.2).
- Сделать поле количества товара дробным в том случае, если в товаре задано значение поля шага из п.1.
- Через код JavaScript настроить изменения полей количества товара и упаковок при изменении каждого. Также нужно чтобы был подсчет общей суммы за упаковки (Код №1.3).
Коды №1.1 и №1.2 добавляем в functions.php
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
## Создание пользовательского поля в товарах (раздел основное)
add_action( ‘woocommerce_product_options_general_product_data’, ‘wpcrft_add_step_qty_woo_cf’ );
function wpcrft_add_step_qty_woo_cf() {
echo ‘<div class=”options_group”>’;// Группировка полей
// Числовое поле
woocommerce_wp_text_input( array(
‘id’ => ‘_step_qty_field_product’,
‘label’ => __( ‘* Шаг количества товара (товара в 1-й упаковке)’, ‘woocommerce’ ),
‘placeholder’ => ‘0’,
‘desc_tip’ => ‘true’,
‘description’ => __( ‘Могут быть дробные числа’, ‘woocommerce’ ),
‘type’ => ‘number’,
‘custom_attributes’ => array(
‘step’ => ‘0.01’,
‘min’ => ‘0’,
),
) );
echo ‘</div>’;
}
/*
* Сохраняем значение полей
*/
function wpcrft_save_step_qty_woo_cf( $post_id ) {
// Вызываем объект класса
$product = wc_get_product( $post_id );
// Сохранение цифрового поля
$number_field = isset( $_POST[‘_step_qty_field_product’] ) ? sanitize_text_field( $_POST[‘_step_qty_field_product’] ) : ”;
$product–>update_meta_data( ‘_step_qty_field_product’, $number_field );
// Сохраняем все значения
$product–>save();
}
add_action( ‘woocommerce_process_product_meta’, ‘wpcrft_save_step_qty_woo_cf’, 10 );
## end Создание пользовательского поля
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
## Дробный Шаг количества товара с полем упаковки
/* Есть цена товара за 1 кв.м. Товар продается в упаковках, поэтому нужно отобразить
сколько кв.м товара содержится в упаковке. При изменении количества упаковок должно меняться
количество товара в соответсвии.
*/
// Функция вывода поля количества упаковок, Общей цены и скрытого элемента с ценой одного товара
function wpcrft_add_qty_package(){
global $product;
$price = $product–>get_price(); // Получаем цену товара
echo ‘<div class=”wpcr-package-block”><span style=”font-weight: 600;”>Упаковка: </span><input type=”number” id=”qty-pak” class=”” step=”1″ min=”1″ max=”” name=”” value=”1″ title=”Кол-во” size=”4″ placeholder=”шт.” inputmode=”numeric” autocomplete=”off”></input><div class=”wpcr-price” style=”display:none;”>’ . $price . ‘</div><div><span>Итого: </span><span class=”wpcr-sum-price” style=”font-weight: 600;”></span> <span> руб.</span></div></div>’;
/* JS для взаимодействия работы всех добавленных полей
Код описан ниже. Можно разместить также в файле, вывести прямо здесь
или подключить файл через хук wp_enqueue_scripts */
echo ‘<script src=“/wp-content/themes/my-theme/js/step-qty-product-package.js” type=“text/javascript” defer=“”></script>‘;
}
function wpcrft_fractional_quantity($args, $product) {
$product_id = $product–>get_id(); // Получаем ID товара
// Получаем значени пользовательского поля товара из Кода №1.1
$step_qty = get_post_meta( $product_id, ‘_step_qty_field_product’, true );
if ( $step_qty > 0 ) { // Если в кастомном поле нет значения, то просто возвращаем $args
if ( is_product() ) { // Если стр. Товара. На стр. Корзины ненужно, т.к. передается из заказа
$args[‘input_value’] = $step_qty; // Стартовое значение для карточки товара
}
if ( is_product() || is_cart() ) { // Если стр. Товара или Корзина
$args[‘min_value’] = $step_qty; // Минимальное значение
$args[‘step’] = $step_qty; // Шаг (количество товара в 1 упаковке)
$args[‘placeholder’] = ‘м²’; // Векст в поле, когда оно пустое
}
// Добавляем вывод полей из wpcrft_add_qty_package перед кнопкой добавления в корзину
add_filter(‘woocommerce_after_add_to_cart_button’, ‘wpcrft_add_qty_package’);
}
return $args;
}
// Хук вывода количества для формы добавления в корзину
add_filter(‘woocommerce_quantity_input_args’, ‘wpcrft_fractional_quantity’, 100, 2);
// Дополнительная функция если используется AJAX при добавлении товаров в корзину
function wpcrft_fractional_quantity_ajax($wp_parse_args, $product) {
$step_qty = get_post_meta( $product_id, ‘_step_qty_field_product’, true );
if( $step_qty > 0 ){
$args[‘quantity’] = $step_qty;
}
return $args;
}
add_filter(‘woocommerce_loop_add_to_cart_args’, ‘wpcrft_fractional_quantity_ajax’, 100, 2);
// Дополнительная функция для вариативных товаров
function wpcrft_fractional_quantity_variation($data, $product, $variation) {
$step_qty = get_post_meta( $product_id, ‘_step_qty_field_product’, true );
if( $step_qty > 0 ){
$args[‘min_qty’] = $step_qty; // Минимальное значение
}
return $data;
}
add_filter(‘woocommerce_available_variation’, ‘wpcrft_fractional_quantity_variation’, 100, 3);
// Для переопределения стартового и минимального значения, а также шага в товаре и корзине
remove_filter(‘woocommerce_stock_amount’, ‘intval’);
add_filter(‘woocommerce_stock_amount’, ‘floatval’);
## end Дробный Шаг количества товара
|
Полезные ссылки по теме:
- Большая инструкция по добавлению произвольных полей в товарах Woocommerce [wpruse.ru]
- Как изменить символ валюты у цены например ( на руб/м²) в зависимости от категории товара.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
document.addEventListener(‘DOMContentLoaded’, function(){
let y = document.querySelector(“#qty-pak”); // Поле упаковок
let x = document.querySelector(“form.cart .quantity input.qty”); // Поле количества товара
let price = document.querySelector(“.wpcr-price”); // Цена товара 1 единицы
let sumPrice = document.querySelector(“.wpcr-sum-price”); // Общая цена упаковок
function updateSumPrice (){ // Обновить Общая цену
sumPrice.innerHTML = ( x.value * price.innerHTML ).toFixed(2);
}
updateSumPrice();
// При изменении упаковок (y) изменить количество товара (x)
function upgradeXbyY(){
x.value = (y.value * x.step).toFixed(2);
let event = new Event(‘change’); // обновить поле количества товара событием ‘change’
x.dispatchEvent(event);
updateSumPrice();
}
y.addEventListener(‘input’, upgradeXbyY);
// При изменении количество товара (x) изменить упаковки (y)
function upgradeYbyX(){
// Округляем в большую сторону упаковку, т.к. если в 1 упаковке
// 1,33м, то 1,34м это уже 2 упаковки (неполные)
y.value = Math.ceil(x.value*1000 / x.step/1000); // */1000 из-за образования дробного хвоста в следствии деления
updateSumPrice ();
}
x.addEventListener(‘input’, upgradeYbyX);
});
|
* Попробовал запаковать все это в небольшой плагин. Скачать. Но есть проблема с тем что если добавлять код через плагин, а не через
functions.php
, то в корзине не выводится дробное число. И в итоге в заказ передается целое число. Если есть предположения почему так происходит — прошу подсказать.