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

Зачем автоматизировать удаление проданных товаров в WooCommerce

В интернет-магазинах на WooCommerce часто накапливаются товары, которые были проданы и больше не актуальны. Это влияет на удобство управления каталогом, увеличивает нагрузку на базу данных и может замедлять работу сайта. Автоматическое удаление таких товаров по дате продажи позволяет поддерживать базу в актуальном состоянии без ручной работы.

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

Если в вашем магазине WooCommerce есть товарные позиции, которые были проданы более месяца назад и больше не нужны, стоит задуматься об их очистке. Основные признаки:

  • В каталоге отображаются товары со статусом "Продано", но с нулевым остатком.
  • В базе данных накапливается большое количество постов с типом product, которые уже не продаются.
  • Отчеты по товарным остаткам показывают много устаревших позиций.

Для проверки можно выполнить SQL-запрос к базе данных, чтобы найти товары без остатков и с датой последней продажи старше нужного периода:

SELECT p.ID, p.post_title, MAX(o.post_date) as last_order_date
FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_item_name = p.post_title
LEFT JOIN wp_posts o ON oi.order_id = o.ID AND o.post_type = 'shop_order'
WHERE p.post_type = 'product'
GROUP BY p.ID
HAVING last_order_date < DATE_SUB(NOW(), INTERVAL 30 DAY) OR last_order_date IS NULL;

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

Реализуем функцию, которая:

  1. Получит товары, проданные более 30 дней назад.
  2. Проверит остаток товара (stock_quantity).
  3. Удалит товар, если остаток равен нулю.

Для запуска кода используйте WP-Cron, чтобы задача выполнялась автоматически раз в сутки.

Код для автоматического удаления товаров

function wpreset_delete_old_sold_products() {
    $args = array(
        'post_type'      => 'product',
        'posts_per_page' => -1,
        'meta_query'     => array(
            array(
                'key'     => '_stock_status',
                'value'   => 'outofstock',
            ),
        ),
    );

    $products = get_posts( $args );

    foreach ( $products as $product_post ) {
        $product = wc_get_product( $product_post->ID );
        $last_order_date = wpreset_get_last_order_date( $product->get_id() );

        if ( ! $last_order_date ) {
            continue;
        }

        $date_threshold = strtotime( '-30 days' );
        $last_order_timestamp = strtotime( $last_order_date );

        if ( $last_order_timestamp <= $date_threshold ) {
            wp_delete_post( $product->get_id(), true );
        }
    }
}

function wpreset_get_last_order_date( $product_id ) {
    global $wpdb;

    $query = $wpdb->prepare(
        "SELECT MAX(p.post_date) FROM {$wpdb->prefix}posts p
         INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON p.ID = oi.order_id
         INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id
         WHERE p.post_type = 'shop_order'
         AND p.post_status IN ('wc-completed', 'wc-processing')
         AND oim.meta_key = '_product_id'
         AND oim.meta_value = %d",
        $product_id
    );

    return $wpdb->get_var( $query );
}

// Регистрируем задачу в WP-Cron
if ( ! wp_next_scheduled( 'wpreset_daily_delete_old_sold_products' ) ) {
    wp_schedule_event( time(), 'daily', 'wpreset_daily_delete_old_sold_products' );
}
add_action( 'wpreset_daily_delete_old_sold_products', 'wpreset_delete_old_sold_products' );

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

Чтобы убедиться, что удаление отработало корректно, выполните следующие шаги:

  • Проверьте список товаров в админке WooCommerce на предмет исчезновения проданных товаров с нулевым остатком, проданных более 30 дней назад.
  • Просмотрите логи WP-Cron или добавьте логирование в функцию wpreset_delete_old_sold_products для контроля удаляемых товаров.
  • Выполните SQL-запрос из раздела диагностики до и после запуска скрипта — количество подходящих товаров должно уменьшиться.

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

  • Удаление не тех товаров: Ошибка в логике выбора товаров. Проверьте корректность выборки в get_posts и функцию получения даты последнего заказа.
  • Функция не запускается автоматически: Проверьте регистрацию WP-Cron задачи и её наличие через wp_next_scheduled. Убедитесь, что на сайте посещения активируют WP-Cron.
  • Проблемы с производительностью при большом каталоге: Разбейте обработку товаров на партии с помощью параметров posts_per_page и пагинации.

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

  • Перед массовым удалением создавайте резервные копии базы данных, чтобы избежать потери важных данных.
  • Логируйте удаляемые ID товаров в отдельный файл или в системный лог для аудита.
  • Используйте транзакции при удалении, если в базе данных есть зависимости.
  • Настраивайте WP-Cron на выполнение в часы с низкой нагрузкой.
  • Если на сайте много товаров, используйте WP-CLI для запуска задач удаления с контролем прогресса.

Таблица сравнения способов удаления проданных товаров

МетодПлюсыМинусыПример кода
Ручное удаление через админкуПростота, контрольТрудоемко, риск ошибок
Автоматизация через WP-Cron и PHPПолная автоматизация, гибкостьТребует навыков, нагрузка на сайтВ статье выше
Плагины для очистки каталогаУдобство, готовое решениеЗависимость от сторонних разработчиков, возможные конфликтыWPReset, Clearfy Pro
Как удалить все записи WordPress одной кнопкой
09.12.2025
Как установить и настроить WooCommerce для массового экспорта и импорта товаров
31.05.2026
WooCommerce: автоматическое удаление старого контента и товаров
13.06.2026
Как использовать WPReset для автоматического восстановления WordPress после ошибок
23.12.2025
Как избежать конфликтов между плагинами WordPress: практические решения
17.03.2026