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

В чем суть задачи: автоматическое обновление наличия товаров на складе

В стандартном WooCommerce изменение количества товаров в уже созданном заказе не всегда корректно отражается на остатках товаров на складе. Особенно это актуально для магазинов с управлением запасами, где администратор вручную корректирует заказ (добавляет или уменьшает количество позиций) после оформления. Без дополнительной логики складские остатки могут не обновляться, приводя к рассинхронизации и ошибкам при дальнейших заказах.

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

  • Откройте любой сделанный заказ в админке WooCommerce.
  • Измените количество товара в заказе (например, увеличьте на 1).
  • Сохраните заказ и проверьте в разделе «Товары» остаток на складе по этому товару.
  • Если остаток не изменился, значит автоматическое обновление не происходит.

Также можно проверить логи WooCommerce или включить WP_DEBUG для выявления возможных ошибок при сохранении заказа.

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

По умолчанию WooCommerce обновляет склад при создании заказа и при смене статуса заказа (например, на «завершен»), но не отслеживает изменения позиций и количества в уже существующих заказах. Для автоматического обновления нужно самостоятельно добавить логику, которая будет:

  • Определять разницу в количестве товара между старым и новым значением.
  • Корректировать остаток на складе с учетом этой разницы.

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

1. Отслеживаем изменение заказа в админке

Для этого используем хук woocommerce_saved_order_items, который вызывается после сохранения позиций заказа.

2. Сохраняем текущие количества товаров в заказе перед изменениями

Чтобы вычислить разницу, нужно знать старые значения. Воспользуемся get_items() и сохраним данные в transient перед редактированием.

3. Вычисляем разницу и обновляем складские запасы

Сравниваем старые и новые количества и сдвигаем остаток на складе.

Пример кода для functions.php темы или плагина

<?php
// Сохраняем текущие количества товаров при загрузке страницы редактирования заказа
add_action('load-post.php', function() {
    global $post;
    if (get_post_type($post) === 'shop_order') {
        $order = wc_get_order($post->ID);
        $items = $order->get_items();
        $quantities = [];
        foreach ($items as $item) {
            $quantities[$item->get_id()] = $item->get_quantity();
        }
        set_transient('order_item_quantities_' . $post->ID, $quantities, 3600); // храним 1 час
    }
});

// После сохранения позиций заказа корректируем остатки
add_action('woocommerce_saved_order_items', function($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return;

    $old_quantities = get_transient('order_item_quantities_' . $order_id);
    if (!$old_quantities) return;

    $items = $order->get_items();

    foreach ($items as $item) {
        $item_id = $item->get_id();
        $new_qty = $item->get_quantity();
        $old_qty = isset($old_quantities[$item_id]) ? $old_quantities[$item_id] : 0;
        $difference = $new_qty - $old_qty;

        if ($difference !== 0) {
            $product = $item->get_product();
            if ($product && $product->managing_stock()) {
                $stock_qty = $product->get_stock_quantity();
                $product->set_stock_quantity($stock_qty - $difference);
                $product->save();
            }
        }
    }

    delete_transient('order_item_quantities_' . $order_id);
});
?>

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

  • Откройте заказ в админке WooCommerce.
  • Измените количество товара в заказе (увеличьте или уменьшите).
  • Сохраните заказ и обновите страницу товара в разделе «Товары».
  • Проверьте, что изменился остаток на складе на соответствующее количество.

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

  • Не сохраняются транзиенты: убедитесь, что у вас работает механизм transient API (например, не отключен кеш в базе данных).
  • Функция не вызывается: проверьте, что код подключен и нет синтаксических ошибок.
  • Обновление остатков не происходит: проверьте, что товар управляет запасами ($product->managing_stock() возвращает true).
  • Изменение остатков идет в неправильную сторону: перепроверьте вычисление разницы ($difference = $new_qty - $old_qty;), возможно логика инвертирована.

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

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

Сравнение вариантов решения

МетодПреимуществаНедостатки
Код из примера (хук woocommerce_saved_order_items)Полный контроль, без сторонних плагинов, гибкостьТребует тестирования, ручная поддержка
Сторонние плагины управления складомГотовые решения, поддержка, интерфейсМожет быть дорого, избыточно для задачи, нагрузка
Ручное обновление остатковПростота, минимальные измененияРиск ошибок, рассинхронизация
Как создать обновляемые данные в реальном времени в WordPress
23.11.2025
Автоматическое создание и удаление записей в WordPress по расписанию
30.03.2026
Автоматическое удаление старых постов в WordPress: практическое руководство
05.01.2026
Как создать автоматический канонический URL в WordPress
25.01.2026
Как создать собственный шорткод в WordPress
05.11.2025