Установите минимум, максимум и шаг количества на уровне продукта в Woocommerce

Я использую установить минимальное и максимальное допустимые количества продукта для добавления в корзину WooCommerce, чтобы требовать минимального и максимального количества заказа.

Теперь мне нужно ввести для нескольких продуктов (не для всех) многократное количество. Например: 6 бутылок, 12 бутылок, 18 бутылок (кратно 6) или для других 12 бутылок, 24 бутылки (кратно 12).

Я нашел решение, но оно подходит для каждого продукта с уникальной ценностью, и я не могу управлять им в бэк-офисе для каждого продукта в отдельности. Мне нужно управлять множественным количеством в Backoffice.

Спасибо, если вы можете мне помочь


person microb14    schedule 16.07.2020    source источник


Ответы (1)


Обновлено декабрь 2020 г.

Следующий измененный код позволит дополнительно обрабатывать шаги количества.

Я изменил расположение настроек полей количества на вкладку Общие настройки.

Я добавил флажок, который включает или отключает эти дополнительные настройки количества на уровне продукта (отображение или скрытие полей настроек динамически):

Когда флажок снят (поля не отображаются, а настройки количества отключены):

введите описание изображения здесь

Когда установлен флажок (поля видны, а настройки количества включены):

введите описание изображения здесь

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

Начиная с WooCommerce версии 3, все сильно изменилось, поэтому я внес некоторые изменения, улучшив и обновив код до чего-то более нового.

Также хорошо работает с Ajax add to cart для простых продуктов, для вариаций продуктов из переменных продуктов, а также с полем ввода количества корзины.

Весь код:

// Displaying quantity setting fields on admin product pages
add_action( 'woocommerce_product_options_pricing', 'wc_qty_add_product_field' );
function wc_qty_add_product_field() {
    global $product_object;

    $values = $product_object->get_meta('_qty_args');

    echo '</div><div class="options_group quantity hide_if_grouped">
    <style>div.qty-args.hidden { display:none; }</style>';

    woocommerce_wp_checkbox( array( // Checkbox.
        'id'            => 'qty_args',
        'label'         => __( 'Quantity settings', 'woocommerce' ),
        'value'         => empty($values) ? 'no' : 'yes',
        'description'   => __( 'Enable this to show and enable the additional quantity setting fields.', 'woocommerce' ),
    ) );

    echo '<div class="qty-args hidden">';

    woocommerce_wp_text_input( array(
            'id'                => 'qty_min',
            'type'              => 'number',
            'label'             => __( 'Minimum Quantity', 'woocommerce-max-quantity' ),
            'placeholder'       => '',
            'desc_tip'          => 'true',
            'description'       => __( 'Set a minimum allowed quantity limit (a number greater than 0).', 'woocommerce' ),
            'custom_attributes' => array( 'step'  => 'any', 'min'   => '0'),
            'value'             => isset($values['qty_min']) && $values['qty_min'] > 0 ? (int) $values['qty_min'] : 0,
    ) );

    woocommerce_wp_text_input( array(
            'id'                => 'qty_max',
            'type'              => 'number',
            'label'             => __( 'Maximum Quantity', 'woocommerce-max-quantity' ),
            'placeholder'       => '',
            'desc_tip'          => 'true',
            'description'       => __( 'Set the maximum allowed quantity limit (a number greater than 0). Value "-1" is unlimited', 'woocommerce' ),
            'custom_attributes' => array( 'step'  => 'any', 'min'   => '-1'),
            'value'             => isset($values['qty_max']) && $values['qty_max'] > 0 ? (int) $values['qty_max'] : -1,
    ) );

    woocommerce_wp_text_input( array(
            'id'                => 'qty_step',
            'type'              => 'number',
            'label'             => __( 'Quantity step', 'woocommerce-quantity-step' ),
            'placeholder'       => '',
            'desc_tip'          => 'true',
            'description'       => __( 'Optional. Set quantity step  (a number greater than 0)', 'woocommerce' ),
            'custom_attributes' => array( 'step'  => 'any', 'min'   => '1'),
            'value'             => isset($values['qty_step']) && $values['qty_step'] > 1 ? (int) $values['qty_step'] : 1,
    ) );

    echo '</div>';
}

// Show/hide setting fields (admin product pages)
add_action( 'admin_footer', 'product_type_selector_filter_callback' );
function product_type_selector_filter_callback() {
    global $pagenow, $post_type;

    if( in_array($pagenow, array('post-new.php', 'post.php') ) && $post_type === 'product' ) :
    ?>
    <script>
    jQuery(function($){
        if( $('input#qty_args').is(':checked') && $('div.qty-args').hasClass('hidden') ) {
            $('div.qty-args').removeClass('hidden')
        }
        $('input#qty_args').click(function(){
            if( $(this).is(':checked') && $('div.qty-args').hasClass('hidden')) {
                $('div.qty-args').removeClass('hidden');
            } else if( ! $(this).is(':checked') && ! $('div.qty-args').hasClass('hidden')) {
                $('div.qty-args').addClass('hidden');
            }
        });
    });
    </script>
    <?php
    endif;
}

// Save quantity setting fields values
add_action( 'woocommerce_admin_process_product_object', 'wc_save_product_quantity_settings' );
function wc_save_product_quantity_settings( $product ) {
    if ( isset($_POST['qty_args']) ) {
        $values = $product->get_meta('_qty_args');

        $product->update_meta_data( '_qty_args', array(
            'qty_min' => isset($_POST['qty_min']) && $_POST['qty_min'] > 0 ? (int) wc_clean($_POST['qty_min']) : 0,
            'qty_max' => isset($_POST['qty_max']) && $_POST['qty_max'] > 0 ? (int) wc_clean($_POST['qty_max']) : -1,
            'qty_step' => isset($_POST['qty_step']) && $_POST['qty_step'] > 1 ? (int) wc_clean($_POST['qty_step']) : 1,
        ) );
    } else {
        $product->update_meta_data( '_qty_args', array() );
    }
}

// The quantity settings in action on front end
add_filter( 'woocommerce_quantity_input_args', 'filter_wc_quantity_input_args', 99, 2 );
function filter_wc_quantity_input_args( $args, $product ) {
    if ( $product->is_type('variation') ) {
        $parent_product = wc_get_product( $product->get_parent_id() );
        $values  = $parent_product->get_meta( '_qty_args' );
    } else {
        $values  = $product->get_meta( '_qty_args' );
    }

    if ( ! empty( $values ) ) {
        // Min value
        if ( isset( $values['qty_min'] ) && $values['qty_min'] > 1 ) {
            $args['min_value'] = $values['qty_min'];

            if( ! is_cart() ) {
                $args['input_value'] = $values['qty_min']; // Starting value
            }
        }

        // Max value
        if ( isset( $values['qty_max'] ) && $values['qty_max'] > 0 ) {
            $args['max_value'] = $values['qty_max'];

            if ( $product->managing_stock() && ! $product->backorders_allowed() ) {
                $args['max_value'] = min( $product->get_stock_quantity(), $args['max_value'] );
            }
        }

        // Step value
        if ( isset( $values['qty_step'] ) && $values['qty_step'] > 1 ) {
            $args['step'] = $values['qty_step'];
        }
    }
    return $args;
}

// Ajax add to cart, set "min quantity" as quantity on shop and archives pages
add_filter( 'woocommerce_loop_add_to_cart_args', 'filter_loop_add_to_cart_quantity_arg', 10, 2 );
function filter_loop_add_to_cart_quantity_arg( $args, $product ) {
    $values  = $product->get_meta( '_qty_args' );

    if ( ! empty( $values ) ) {
        // Min value
        if ( isset( $values['qty_min'] ) && $values['qty_min'] > 1 ) {
            $args['quantity'] = $values['qty_min'];
        }
    }
    return $args;
}

// The quantity settings in action on front end (For variable productsand their variations)
add_filter( 'woocommerce_available_variation', 'filter_wc_available_variation_price_html', 10, 3);
function filter_wc_available_variation_price_html( $data, $product, $variation ) {
    $values  = $product->get_meta( '_qty_args' );

    if ( ! empty( $values ) ) {
        if ( isset( $values['qty_min'] ) && $values['qty_min'] > 1 ) {
            $data['min_qty'] = $values['qty_min'];
        }

        if ( isset( $values['qty_max'] ) && $values['qty_max'] > 0 ) {
            $data['max_qty'] = $values['qty_max'];

            if ( $variation->managing_stock() && ! $variation->backorders_allowed() ) {
                $data['max_qty'] = min( $variation->get_stock_quantity(), $data['max_qty'] );
            }
        }
    }

    return $data;
}

Код находится в файле functions.php вашей активной дочерней темы (или активной темы). Проверено и работает.

person LoicTheAztec    schedule 17.07.2020
comment
Спасибо. Могу ли я удалить другой код (установить минимальный / максимальный допустимый продукт ...) - person microb14; 17.07.2020
comment
ОТЛИЧНО! это работает. СПАСИБО СПАСИБО и СПАСИБО - person microb14; 17.07.2020
comment
Спасибо, это действительно отличное решение! Однако он устанавливает минимальный / максимальный / количественный шаг для всего продукта. Если бы вам пришлось делать это для индивидуальных вариаций, как бы вы к этому подошли? Я думаю, мы можем использовать фильтр woocommerce_quantity_input_args и проверить, является ли продукт переменным, и установить минимальные максимальные значения в аргументах, как и вы, но как мне установить шаг количества для этого варианта? У аргументов нет индекса шага в этом массиве в соответствии с docs < / а>. Мысли? - person Ankit Shah; 18.03.2021
comment
@AnkitShah Управление аргументами количества на уровне вариации возможно только для минимального и максимального количества, но не для количества шагов. Найдите плагин, который может это сделать. - person LoicTheAztec; 18.03.2021
comment
Большой! Вы знаете, какие изменения в использовании количества шагов на странице продукта? С этим кодом работает только на странице корзины. Я имею в виду, если количество шагов равно 25. На странице продукта можно использовать кнопки + и -, добавляя 25 элементов за один клик, а не +1 (26)? - person JJMontalban; 10.05.2021