WooCommerce: автоматическое изменение доступности товаров в зависимости от количества заказов

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

В интернет-магазинах на WooCommerce часто возникает задача динамически изменять доступность товара в зависимости от его популярности и текущих заказов. Например, если товар заказывают слишком часто и склад истощается, нужно автоматически помечать его как "нет в наличии" или "под заказ". Ручное управление статусами при большом ассортименте и высоком трафике ведёт к ошибкам и недовольству клиентов.

Типичные симптомы, что нужно автоматизировать смену доступности:

  • Товары остаются доступными, когда их фактически нет на складе
  • Невозможно быстро обновлять статусы при изменении количества заказов
  • Появляется много отменённых заказов из-за несоответствия статусов

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

1. Определяем критерии для изменения статуса

Например, если количество заказов товара за последние 7 дней превысило заданный порог, меняем статус на "нет в наличии" или "под заказ".

2. Подключаемся к событию обновления заказа

Используем хук woocommerce_order_status_changed для отслеживания изменений статусов заказов.

3. Считаем количество заказанных товаров за период

Пример функции для подсчёта заказов по ID товара за последние 7 дней:

function count_product_orders_last_7_days($product_id) {
    global $wpdb;
    $date = date('Y-m-d H:i:s', strtotime('-7 days'));
    $query = $wpdb->prepare(
        "SELECT SUM(oi.meta_value) FROM {$wpdb->prefix}woocommerce_order_items AS oi
         
         INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS oim ON oi.order_item_id = oim.order_item_id
         
         INNER JOIN {$wpdb->posts} AS p ON p.ID = oi.order_id
         
         WHERE oim.meta_key = '_product_id' AND oim.meta_value = %d
         
         AND p.post_type = 'shop_order'
         
         AND p.post_status IN ('wc-completed', 'wc-processing')
         
         AND p.post_date > %s
         
         AND EXISTS (
            SELECT 1 FROM {$wpdb->prefix}woocommerce_order_itemmeta AS qty_meta
            WHERE qty_meta.order_item_id = oi.order_item_id AND qty_meta.meta_key = '_qty'
         )",
        $product_id,
        $date
    );
    $result = $wpdb->get_var($query);
    return intval($result);
}

Примечание: в данном примере важно использовать правильные join и фильтры по статусу заказа.

4. Меняем статус товара по результатам подсчёта

Пример функции для обновления статуса товара:

function update_product_availability($product_id, $threshold) {
    $orders_count = count_product_orders_last_7_days($product_id);
    $product = wc_get_product($product_id);
    if (!$product) return;
    if ($orders_count >= $threshold) {
        // Меняем статус на 'нет в наличии'
        $product->set_stock_status('outofstock');
        $product->save();
    } else {
        // Возвращаем в наличие
        $product->set_stock_status('instock');
        $product->save();
    }
}

5. Запускаем проверку при изменении заказа

add_action('woocommerce_order_status_changed', 'check_and_update_product_availability', 10, 4);
function check_and_update_product_availability($order_id, $old_status, $new_status, $order) {
    $threshold = 10; // например, порог 10 заказов за 7 дней
    foreach ($order->get_items() as $item) {
        $product_id = $item->get_product_id();
        update_product_availability($product_id, $threshold);
    }
}

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

  • Создайте тестовый заказ с товарами, количество которых близко к порогу.
  • Измените статус заказа на "завершён" или "обрабатывается" и проверьте, что статус товара обновился.
  • Перейдите в админку WooCommerce → Товары → нужный продукт и убедитесь, что поле "Наличие" изменилось на "нет в наличии" или "в наличии" в зависимости от количества заказов.
  • Также можно проверить на фронтенде, как отображается статус товара.

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

  • Неверные запросы к базе данных: неправильные JOIN или WHERE условия приводят к некорректному подсчёту. Рекомендуется тестировать SQL-запрос отдельно и использовать $wpdb->prepare для безопасности.
  • Отсутствие проверки существования продукта: перед вызовом методов продукта проверяйте, что объект не null.
  • Ошибка в хукe: неверно переданы параметры или приоритет, из-за чего функция не срабатывает. Используйте правильный синтаксис и проверяйте, что хук срабатывает через логи.
  • Проблемы с кэшированием: если на сайте работает кэш, изменения видны не сразу. Очистите кэш или отключите его для тестов.

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

  • Оптимизируйте SQL-запросы, особенно если база большая. Используйте индексы по полям post_date и post_status.
  • Кэшируйте результаты подсчётов, например, сохраняйте в transient на 5-10 минут, чтобы не запускать запрос при каждом обновлении заказа.
  • Ограничьте доступ к этим функциям, чтобы никто из пользователей не мог напрямую менять статусы товаров через нестандартные запросы.
  • Логируйте изменения статусов для отладки и мониторинга, особенно при автоматизации управления складом.

Сравнение подходов: плагин vs. кастомный код

МетодПреимуществаНедостатки
Использование плагина (например, WooCommerce Stock Manager)Простая настройка, готовый интерфейс, поддержка обновленийМожет не иметь гибких условий, нагрузка на сайт, платные функции
Кастомный код (как в статье)Максимальная гибкость, точечное решение, интеграция под задачиТребует навыков разработки, нужно тестировать и поддерживать
WooCommerce: автоматическое изменение статуса заказа по региональному признаку
05.08.2026
Как создать автоматический импорт продуктов WooCommerce из CSV файла
12.04.2026
WooCommerce: автоматическое отключение оплаты для товаров с определённым статусом
29.06.2026
Как отключить XML-RPC в WordPress без поломки авторизации и внешних синхронизаций
16.08.2026
WooCommerce: удаление товаров по значению мета-поля с помощью кода
22.06.2026