Диагностика проблемы: зачем отключать отгрузку товаров без запаса
В WooCommerce товары с нулевым или отрицательным запасом часто остаются доступными для заказа, что ведёт к ошибкам в обработке заказов и недовольству клиентов. Стандартные настройки WooCommerce позволяют скрывать товары без запаса, но не всегда достаточно эффективно управлять именно статусом отгрузки, особенно если используются сторонние системы складского учёта.
Цель — автоматически отключать возможность отгрузки тех товаров, у которых запас равен нулю или меньше, сохраняя при этом видимость товара в каталоге для информирования клиентов.
Как проверить, что проблема актуальна
- Перейдите в админку WooCommerce в раздел Товары и проверьте наличие товаров с запасом 0 или отрицательным.
- Откройте карточку товара на сайте и попробуйте добавить его в корзину при пустом запасе.
- Если товар можно добавить и оформить заказ, значит, автоматическое отключение отгрузки не настроено.
Пошаговое решение: автоматическое отключение отгрузки товаров без запаса
1. Использование хука для проверки запаса и изменения статуса товара
Добавьте следующий код в файл functions.php активной темы или в собственный плагин:
add_action('woocommerce_product_set_stock', 'disable_shipping_for_out_of_stock_products', 10, 1);
function disable_shipping_for_out_of_stock_products($product) {
if (!$product instanceof WC_Product) return;
$stock_quantity = $product->get_stock_quantity();
// Проверяем запас
if ($stock_quantity <= 0) {
// Отключаем возможность отгрузки (shipping)
$product->set_shipping_class_id(0); // Сброс класса доставки
$product->set_catalog_visibility('visible'); // Оставляем товар видимым
$product->save();
}
}Этот код срабатывает при изменении запаса товара и сбрасывает класс доставки, что в большинстве настроек WooCommerce отключает отгрузку.
2. Более точечное управление статусом доставки
Если в вашем магазине настроены классы доставки, можно создать отдельный класс "Не отгружается" и присваивать его товарам без запаса:
add_action('woocommerce_product_set_stock', 'set_no_shipping_class_for_out_of_stock', 10, 1);
function set_no_shipping_class_for_out_of_stock($product) {
if (!$product instanceof WC_Product) return;
$stock_quantity = $product->get_stock_quantity();
$no_shipping_class_slug = 'no-shipping'; // Слаг класса доставки
$shipping_class_term = get_term_by('slug', $no_shipping_class_slug, 'product_shipping_class');
if (!$shipping_class_term) return; // Класс не найден
if ($stock_quantity <= 0) {
$product->set_shipping_class_id($shipping_class_term->term_id);
} else {
// При появлении запаса сбрасываем класс
$product->set_shipping_class_id(0);
}
$product->save();
}Создайте класс доставки с слагом no-shipping в WooCommerce → Настройки → Доставка → Классы доставки.
Проверка результата
- Измените запас товара в админке на 0 и обновите.
- Обновите страницу товара на сайте и проверьте, что опция доставки изменена (при использовании стандартных классов доставки — доставка должна быть отключена).
- Попробуйте оформить заказ с этим товаром и убедитесь, что доставка не рассчитывается или товар нельзя добавить в корзину, если настроено соответствующее поведение.
Частые ошибки и как их исправить
- Класс доставки с указанным слагом не создан — создайте класс доставки с точным слагом
no-shippingв настройках WooCommerce. - Кэширование мешает увидеть изменения — очистите кэш сайта и браузера после внесения изменений.
- Некорректный тип объекта в хуке — проверяйте, что переданный объект действительно наследует
WC_Product. - Конфликты с плагинами доставки — после внедрения тестируйте совместимость с плагинами, которые могут управлять доставкой.
Практические советы по безопасности и производительности
- Вместо выполнения операций при каждом обновлении запаса можно использовать
wp_cronдля периодической проверки товаров с нулевым запасом и массового обновления их статусов. - Поддерживайте резервные копии перед внесением изменений в код.
- Для больших магазинов с тысячами товаров рекомендуется оптимизировать запросы к базе и не вызывать сохранение объекта без необходимости.
Сравнение вариантов реализации
| Вариант | Плюсы | Минусы |
|---|---|---|
| Сброс класса доставки при изменении запаса | Простота реализации, быстрое срабатывание | Может конфликтовать с пользовательскими классами доставки |
| Присвоение специального класса "no-shipping" | Чёткий контроль, гибкость настройки | Требует создания класса доставки, сложнее отладка |
| Полное скрытие товара при нулевом запасе (через видимость) | Не вводит клиента в заблуждение, простой пользовательский опыт | Потеря видимости товаров на сайте, уменьшение SEO |