Диагностика проблемы: зачем удалять товары с нулевым остатком и без продаж
В интернет-магазинах на WooCommerce часто накапливаются товары, которые не пользуются спросом и при этом имеют нулевой остаток на складе. Это негативно влияет на производительность сайта и усложняет управление каталогом. Автоматическое удаление таких товаров помогает поддерживать актуальность ассортимента и снижает нагрузку на базу данных.
Как определить товары для удаления
Критерии для удаления:
- Количество на складе равно нулю (
_stock = 0) - Товар не продавался за последние 90 дней
- Товар не имеет активных заказов в обработке
Для реализации понадобится запрос к базе данных, который позволит выбрать только те продукты, которые соответствуют этим условиям.
Пошаговое решение: автоматизация удаления товаров
1. Создание функции для выборки и удаления товаров
Добавьте следующий код в файл functions.php вашей темы или в отдельный плагин:
function wps_delete_old_out_of_stock_products() {
if ( ! class_exists('WooCommerce') ) {
return; // WooCommerce не активен
}
global $wpdb;
$days = 90; // период в днях для проверки продаж
$date_threshold = date('Y-m-d H:i:s', strtotime("-{$days} days"));
// Получаем ID товаров с нулевым остатком
$product_ids = $wpdb->get_col( $wpdb->prepare(
"SELECT p.ID FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm_stock ON p.ID = pm_stock.post_id
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND pm_stock.meta_key = '_stock'
AND pm_stock.meta_value = '0'"
));
if ( empty($product_ids) ) {
return;
}
foreach ( $product_ids as $product_id ) {
// Проверяем дату последней продажи
$last_order_date = $wpdb->get_var( $wpdb->prepare(
"SELECT MAX(p.post_date) FROM {$wpdb->posts} p
INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON oi.order_id = p.ID
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oim.order_item_id = oi.order_item_id
WHERE p.post_type = 'shop_order'
AND p.post_status IN ('wc-completed', 'wc-processing', 'wc-on-hold')
AND oim.meta_key = '_product_id'
AND oim.meta_value = %d",
$product_id
));
if ( ! $last_order_date || $last_order_date < $date_threshold ) {
// Удаляем товар
wp_delete_post( $product_id, true );
}
}
}
2. Настройка планового запуска
Чтобы функция выполнялась автоматически, зарегистрируйте крон-задачу:
if ( ! wp_next_scheduled( 'wps_delete_old_products_event' ) ) {
wp_schedule_event( time(), 'daily', 'wps_delete_old_products_event' );
}
add_action( 'wps_delete_old_products_event', 'wps_delete_old_of_stock_products' );
function wps_delete_old_of_stock_products() {
wps_delete_old_out_of_stock_products();
}
Проверка результата после внедрения
- В админке WooCommerce перейдите в раздел «Товары» и отфильтруйте по нулевому остатку.
- Запустите функцию вручную, например, вызвав
wps_delete_old_out_of_stock_products()через WP-CLI или временно добавив вызов вfunctions.php. - Проверьте, что товары, которые не продавались более 90 дней и имеют нулевой остаток, исчезли из каталога.
- Убедитесь, что товары с активными заказами или с недавними продажами остались.
Частые ошибки и как их исправить
- Ошибка: Функция не удаляет товары.
Причина: Неверно указан ключ метаданных или статус поста.
Решение: Проверьте, что в базе данных товары имеют мета_stockс числовым значением, а статусы заказов совпадают с реальными в вашей системе. - Ошибка: Удаляются нужные товары.
Причина: Некорректная логика выбора даты последней продажи.
Решение: Проверьте правильность SQL-запроса на получение даты последней продажи, учитывайте все статусы заказов, которые считаются завершёнными или активными. - Ошибка: Крон-задача не срабатывает.
Причина: Крон не активен или нет посещений сайта.
Решение: Используйте WP-CLI или внешний сервис для вызова wp-cron.php или настройте системный cron на сервере.
Практические советы по безопасности и производительности
- Перед удалением рекомендуем делать резервное копирование базы данных.
- Для больших магазинов разбивайте удаление на партии, чтобы избежать таймаутов.
- Добавьте логирование удалённых товаров для последующего анализа.
- Используйте
wp_delete_post( $id, true )с параметромtrue, чтобы удалять товары без возможности восстановления, если это необходимо.
Сравнение методов удаления
| Метод | Плюсы | Минусы |
|---|---|---|
| Удаление через плагин (например, WP Bulk Delete) | Простота использования, UI | Меньше гибкости, нагрузка при больших объемах |
| Кастомный PHP-скрипт с WP-Cron | Автоматизация, точный контроль, расширяемость | Требует навыков разработки, возможны ошибки в логике |
| Ручное удаление через админку | Безопасно, контроль | Трудозатратно, не подходит для больших каталогов |