WooCommerce: как правильно настроить подразделения магазина с разными складскими запасами

Диагностика задачи: почему нужны разные складские запасы для подразделений

В типовом WooCommerce все товары хранятся в единой базе с одним запасом. Если у вас несколько складов или магазинов (офлайн и онлайн, региональные точки), это создаёт проблему: нельзя управлять остатками раздельно. Клиенты могут купить товар, который на конкретном складе отсутствует, что ведёт к ошибкам в заказах и недовольству.

Чтобы решить эту задачу, необходимо реализовать учёт запасов по подразделениям внутри WooCommerce, сохраняя при этом удобство работы с товарами.

Варианты решения управления запасами по подразделениям

Основные подходы:

  • Плагины для мультискладского учёта — расширяют WooCommerce, добавляя поля и логику;
  • Кастомные метаполя и хуки — самостоятельная реализация управления запасами с помощью кода;
  • Отдельные товары или магазины для каждого склада — менее удобно, но возможно;

Рассмотрим практическую реализацию на базе кастомных метаполей и хуков, чтобы контролировать остатки в разных подразделениях.

Пошаговое решение: кастомный учёт складских запасов по подразделениям

1. Добавляем метаполя для складских запасов

Для каждого товара создадим метаполя для хранения остатков на складах. Например, склад 1 и склад 2.

function add_custom_stock_fields() {
    woocommerce_wp_text_input(
        array(
            'id' => '_stock_warehouse_1',
            'label' => __('Stock Warehouse 1', 'woocommerce'),
            'desc_tip' => 'true',
            'description' => __('Enter stock quantity for Warehouse 1', 'woocommerce'),
            'type' => 'number',
            'custom_attributes' => array('min' => '0')
        )
    );
    woocommerce_wp_text_input(
        array(
            'id' => '_stock_warehouse_2',
            'label' => __('Stock Warehouse 2', 'woocommerce'),
            'desc_tip' => 'true',
            'description' => __('Enter stock quantity for Warehouse 2', 'woocommerce'),
            'type' => 'number',
            'custom_attributes' => array('min' => '0')
        )
    );
}
add_action('woocommerce_product_options_inventory_product_data', 'add_custom_stock_fields');

2. Сохраняем введённые значения

function save_custom_stock_fields($post_id) {
    $stock_1 = isset($_POST['_stock_warehouse_1']) ? intval($_POST['_stock_warehouse_1']) : 0;
    $stock_2 = isset($_POST['_stock_warehouse_2']) ? intval($_POST['_stock_warehouse_2']) : 0;
    update_post_meta($post_id, '_stock_warehouse_1', $stock_1);
    update_post_meta($post_id, '_stock_warehouse_2', $stock_2);
}
add_action('woocommerce_process_product_meta', 'save_custom_stock_fields');

3. Перекрываем логику проверки остатка товара

По умолчанию WooCommerce использует _stock. Чтобы проверять остаток для нужного склада, нужно указать склад при оформлении заказа, а затем на этапе проверки и списания делать выбор нужного поля.

Пример для выбора склада в корзине через пользовательское поле (например, select с выбором склада):

add_action('woocommerce_before_cart', function() {
    echo '<label for="select_warehouse">Выберите склад:</label>';
    echo '<select id="select_warehouse" name="select_warehouse">';
    echo '<option value="warehouse_1">Склад 1</option>';
    echo '<option value="warehouse_2">Склад 2</option>';
    echo '</select>';
});

Обработка выбранного склада и корректировка проверки остатков:

add_filter('woocommerce_product_is_in_stock', 'check_stock_by_warehouse', 10, 2);
function check_stock_by_warehouse($is_in_stock, $product) {
    if (is_admin()) return $is_in_stock; // не трогаем админку

    $warehouse = isset($_POST['select_warehouse']) ? sanitize_text_field($_POST['select_warehouse']) : 'warehouse_1';
    $stock = 0;
    if ($warehouse === 'warehouse_1') {
        $stock = intval(get_post_meta($product->get_id(), '_stock_warehouse_1', true));
    } elseif ($warehouse === 'warehouse_2') {
        $stock = intval(get_post_meta($product->get_id(), '_stock_warehouse_2', true));
    } else {
        return $is_in_stock;
    }

    return $stock > 0;
}

4. Обновление запасов при заказе

add_action('woocommerce_order_status_processing', 'reduce_stock_by_warehouse', 10, 1);
function reduce_stock_by_warehouse($order_id) {
    $order = wc_get_order($order_id);
    $warehouse = 'warehouse_1'; // здесь можно получить из заказа или сессии

    foreach ($order->get_items() as $item) {
        $product_id = $item->get_product_id();
        $qty = $item->get_quantity();
        $stock_key = ($warehouse === 'warehouse_1') ? '_stock_warehouse_1' : '_stock_warehouse_2';
        $current_stock = intval(get_post_meta($product_id, $stock_key, true));
        update_post_meta($product_id, $stock_key, max(0, $current_stock - $qty));
    }
}

Проверка результата после внедрения

  • В админке товара заполните поля «Stock Warehouse 1» и «Stock Warehouse 2» разными значениями.
  • На странице корзины выберите склад через селект и добавьте товар в корзину, убедитесь, что проверка остатков учитывает выбранный склад.
  • Оформите заказ и после смените статус на «Обрабатывается» — проверьте, что запасы нужного склада уменьшились.
  • Попробуйте добавить товар с нулевым остатком на выбранном складе — должен быть запрет на добавление.

Частые ошибки и как исправить

  • Запасы не уменьшаются после заказа: проверьте, что хук woocommerce_order_status_processing срабатывает и что склад выбирается корректно.
  • Выбранный склад не передаётся в корзину: убедитесь, что поле выбора склада отправляется и сохраняется через сессию или пользовательские данные.
  • Неверная проверка остатков: проверьте, что фильтр woocommerce_product_is_in_stock не конфликтует с другими плагинами и правильно получает метаполя.

Практические советы по производительности и безопасности

  • Кэшируйте значения складских запасов в transient или объектном кэше на время сессии пользователя, чтобы не нагружать базу при каждом просмотре товара.
  • Валидация и санитизация пользовательских данных обязательна — используйте sanitize_text_field и intval.
  • Разграничьте права доступа к метаполям — только администраторы могут редактировать запасы складов.
  • Для упрощения управления и избежания ошибок рассмотрите интеграцию с плагином Clearfy Pro (https://wpshop.ru/plugins/clearfy?utm_source=wp-shablon.ru&utm_medium=article&utm_campaign=woocommerce-kak-pravilno-nastroit-raznye-skaldskie-zapasy-v-podrazdeleniyah-magazina) для дополнительной оптимизации базы и очистки дублей метаданных.

Сравнение вариантов реализации мультискладского учёта

ПодходПлюсыМинусыКогда использовать
Плагины мультискладского учётаГотовое решение, поддержка, интеграция с WooCommerceСтоимость, возможные конфликты, избыточностьСложные задачи, многоскладовость
Кастомные метаполя и хукиГибкость, точное подстроение под задачуТребует разработки, тестированияНебольшое число складов, уникальные требования
Отдельные товары/магазиныПростота реализацииДублирование данных, неудобство управленияМинимальные требования, экспериментальные проекты
Как добавить вывод данных в WordPress по хукам
21.11.2025
Как автоматизировать обновление шаблонов WordPress без рисков
16.04.2026
Как добавить динамический фильтр записей в шаблон WordPress
04.02.2026
WooCommerce: использование атрибутов товаров для фильтрации и SEO
23.05.2026
WooCommerce: автоматическое удаление неактивных заказов с подробным разбором
20.06.2026