Проблема: некорректное обновление наличия товара при изменении заказа в WooCommerce
По умолчанию WooCommerce автоматически обновляет количество товаров на складе при создании, оплате и отмене заказа. Однако при ручном изменении заказа (например, добавлении или удалении товаров в админке) остатки склада не всегда корректно пересчитываются. Это приводит к расхождениям между реальным и доступным количеством, что влияет на продажи и отчетность.
Диагностика проблемы
Чтобы проверить, есть ли проблема с обновлением остатков при изменении заказа, выполните следующие шаги:
- В админке WooCommerce откройте существующий заказ с товарами.
- Добавьте новый товар или измените количество уже добавленного товара.
- Сохраните заказ.
- Перейдите в раздел Продукты и проверьте количество товара на складе.
Если количество товара не изменилось или изменилось некорректно, проблема подтверждается.
Причина
По умолчанию WooCommerce не всегда вызывает функции перерасчета остатка при редактировании заказа вручную, так как изменения не проходят стандартный путь создания/оплаты заказа.
Пошаговое решение
Нужно самостоятельно добавить обработчик, который будет обновлять остатки товаров при изменении заказа в админке. Для этого используем хук woocommerce_update_order, который вызывается после сохранения заказа.
add_action('woocommerce_update_order', 'custom_update_stock_on_order_edit', 10, 1);
function custom_update_stock_on_order_edit($order_id) {
if (!$order_id) return;
$order = wc_get_order($order_id);
if (!$order) return;
// Восстановим количество для всех товаров
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if (!$product || !$product->managing_stock()) continue;
// Сначала восстановим склад, чтобы избежать двойного списания
wc_update_product_stock($product, $item->get_quantity(), 'increase');
}
// Затем уменьшим по актуальному количеству
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if (!$product || !$product->managing_stock()) continue;
wc_update_product_stock($product, $item->get_quantity(), 'decrease');
}
}Объяснение кода:
- Сначала мы увеличиваем складской запас на количество товаров из заказа — на случай, если остатки были списаны ранее.
- Затем уменьшаем склад на актуальное количество товаров в заказе, учитывая последние изменения.
Это гарантирует, что остаток всегда соответствует содержимому заказа.
Альтернативный подход — использовать хук woocommerce_order_status_changed
Если нужно обновлять остатки при смене статуса заказа, можно использовать этот хук, но при редактировании вручную он не всегда срабатывает.
Проверка результата
После внедрения кода:
- Отредактируйте заказ в админке — добавьте или удалите товар, измените количество.
- Сохраните заказ.
- Проверьте остатки товара на складе в разделе «Продукты».
Остаток должен измениться в соответствии с содержимым заказа. Если остались расхождения, проверьте логи ошибок и убедитесь, что товары действительно управляют запасами (опция Управление запасами включена).
Частые ошибки и как их исправить
- Ошибка: Остаток не меняется после редактирования заказа.
Причина: Возможно, товар не настроен для управления запасами или код не подключен в functions.php или в плагине.
Исправление: Проверьте, что у товара включена опция «Управление запасами». Убедитесь, что код добавлен в правильное место и активен. - Ошибка: Остаток списывается дважды.
Причина: Логика увеличения и уменьшения остатков нарушена.
Исправление: Используйте подход с увеличением запасов перед уменьшением, как показано в коде. - Ошибка: Ошибки PHP при сохранении заказа.
Причина: Возможно, переданные параметры невалидны.
Исправление: Добавьте проверки на существование заказа и продукта, как в примере.
Практические советы по производительности и безопасности
- Добавляйте код в виде плагина или в дочернюю тему, чтобы избежать потери при обновлениях.
- Кэширование остатков может мешать проверке — отключите кэш при тестировании.
- При большом количестве товаров в заказе учитывайте, что частые обновления остатков могут увеличить нагрузку на базу данных.
- Проверяйте права пользователя: только администратор или менеджер заказа должен иметь возможность изменять остатки.
Сравнение вариантов обновления остатков товаров
| Метод | Плюсы | Минусы |
|---|---|---|
| Стандартное поведение WooCommerce | Простота, работает при создании и оплате заказа | Не обновляет остатки при ручном редактировании заказа |
Код на хуке woocommerce_update_order (предложенный) | Обновляет остатки при любом изменении заказа вручную | Небольшая нагрузка при большом числе товаров в заказе |
Хук woocommerce_order_status_changed | Обновление при смене статуса заказа | Не срабатывает при редактировании заказа без изменения статуса |