Диагностика проблемы: зачем удалять товары из отменённых заказов в WooCommerce
По умолчанию WooCommerce сохраняет данные всех заказов, включая отменённые и отменённые частично. В некоторых случаях необходимо полностью очистить товары из отменённых заказов, чтобы не засорять базу данных, не влиять на отчёты и статистику, а также исключить путаницу при ведении инвентаризации.
Типичный сценарий: заказ был отменён, но товары в нём остались привязаны к записи, что мешает автоматизации учёта остатков или влияет на логику кастомных отчётов.
Как проверить, что товары остались в отменённых заказах
Для проверки можно воспользоваться следующим SQL-запросом, который покажет товары в отменённых заказах:
SELECT order_items.order_item_name, posts.ID AS order_id, posts.post_status
FROM wp_woocommerce_order_items AS order_items
INNER JOIN wp_posts AS posts ON posts.ID = order_items.order_id
WHERE posts.post_status = 'wc-cancelled';Если запрос возвращает строки — значит товары продолжают числиться в отменённых заказах.
Пошаговое решение: автоматическое удаление товаров из отменённых заказов с помощью кода
1. Добавляем хук на смену статуса заказа
WooCommerce триггерит событие при смене статуса заказа. Нам нужно отследить переход к статусу wc-cancelled и удалить товары из заказа.
add_action('woocommerce_order_status_cancelled', 'remove_items_from_cancelled_order', 10, 1);
function remove_items_from_cancelled_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
if ( ! $order ) {
return;
}
// Получаем все позиции заказа
$items = $order->get_items();
// Удаляем каждую позицию
foreach ( $items as $item_id => $item ) {
$order->remove_item( $item_id );
}
// Сохраняем изменения
$order->save();
}2. Где разместить код
Рекомендуется добавить этот код в functions.php дочерней темы или в кастомный плагин, чтобы избежать потери при обновлении.
Проверка результата после внедрения
Создайте тестовый заказ, добавьте товары и переведите его в статус «Отменён». Затем проверьте в админке WooCommerce или через SQL запрос:
SELECT order_items.order_item_name, posts.ID AS order_id, posts.post_status
FROM wp_woocommerce_order_items AS order_items
INNER JOIN wp_posts AS posts ON posts.ID = order_items.order_id
WHERE posts.ID = {ID_теста} AND posts.post_status = 'wc-cancelled';Если запрос не вернёт товаров, значит удаление сработало.
Частые ошибки и как их исправить
- Код не срабатывает при смене статуса: Убедитесь, что используете правильный хук
woocommerce_order_status_cancelled. Для других статусов —woocommerce_order_status_{$old_status}_to_{$new_status}. - Позиции не удаляются, но заказ обновляется: Проверьте, что вызов
$order->save()стоит после удаления всех позиций. - Ошибка доступа к объекту заказа: Убедитесь, что функция вызывается с ID заказа и что он существует.
Практические советы по безопасности и производительности
- Не удаляйте товары из заказов без крайней необходимости, так как это влияет на целостность данных.
- Перед внедрением сделайте резервную копию базы.
- Используйте проверку в коде, чтобы не удалять позиции из заказов с другими статусами.
- Для больших магазинов с сотнями заказов в секунду добавьте логи для быстрого аудита работы функции.
Сравнение вариантов решения
| Метод | Плюсы | Минусы |
|---|---|---|
| Код на хуке (как в статье) | Простота, контроль, без сторонних плагинов | Требует базовых знаний PHP, возможны ошибки при неправильном внедрении |
| Ручное удаление через админку | Простота без кода | Трудозатратно, не автоматично |
| Плагин для управления заказами | Интуитивно, дополнительные функции | Нагрузка на сайт, зависимость от стороннего кода |