Диагностика проблемы: зачем нужна автоматизация изменения цены и остатков
В стандартном WooCommerce изменение цены товара или складского остатка напрямую через админку при обновлении заказа не всегда удобно или возможно. Особенно если магазин использует сложные бизнес-правила, например, скидки за объем, динамическое ценообразование или автоматическое списание остатков при изменении заказа клиентом.
Проблемы, которые возникают:
- Стоимость товара не обновляется автоматически при изменении количества в заказе.
- Складской остаток не корректируется при отмене или изменении заказа.
- Ручные изменения приводят к ошибкам и рассинхронизации данных.
Обзор основных хуков WooCommerce для решения задачи
Для автоматизации потребуется использовать хуки, срабатывающие при изменении или обновлении заказа, а также функции для корректировки метаданных товаров.
woocommerce_order_item_quantity_changed— срабатывает при изменении количества товара в заказе.woocommerce_order_status_changed— позволяет отследить смену статуса заказа (например, оплачен, отменен).wc_update_product_stock— функция для обновления складского остатка товара.
Пошаговое решение: как автоматически менять цену и остаток
1. Создаем функцию для изменения цены товара в заказе
При изменении количества товара в заказе меняем цену в соответствии с заданной логикой (например, скидка 10% при покупке от 10 штук):
add_action('woocommerce_order_item_quantity_changed', 'custom_update_order_item_price', 10, 3);function custom_update_order_item_price($item_id, $quantity, $old_quantity) { $order = wc_get_order(wc_get_order_item($item_id)->get_order_id()); $item = $order->get_item($item_id); $product = $item->get_product(); if (!$product) return; $base_price = $product->get_regular_price(); // Пример: скидка 10% при количестве от 10 if ($quantity >= 10) { $new_price = $base_price * 0.9; } else { $new_price = $base_price; } $item->set_subtotal($new_price * $quantity); $item->set_total($new_price * $quantity); $item->save(); $order->calculate_totals();}2. Автоматическое изменение складского остатка при смене статуса заказа
При смене статуса заказа на "завершенный" списываем товары со склада, при отмене — возвращаем:
add_action('woocommerce_order_status_changed', 'custom_adjust_stock_on_status_change', 10, 4);function custom_adjust_stock_on_status_change($order_id, $old_status, $new_status, $order) { if ($new_status === 'completed') { foreach ($order->get_items() as $item) { $product = $item->get_product(); if (!$product || ! $product->managing_stock()) continue; $qty = $item->get_quantity(); wc_update_product_stock($product, $qty, 'decrease'); } } elseif ($new_status === 'cancelled' || $new_status === 'refunded') { foreach ($order->get_items() as $item) { $product = $item->get_product(); if (!$product || ! $product->managing_stock()) continue; $qty = $item->get_quantity(); wc_update_product_stock($product, $qty, 'increase'); } }}Проверка результата после внедрения
- Создайте тестовый заказ с товаром и количеством менее 10 штук. Проверьте, что цена в заказе соответствует базовой цене.
- Измените количество товара в заказе на 10 или больше через админку. Убедитесь, что цена пересчиталась с 10% скидкой.
- Смените статус заказа на "завершенный" и проверьте, что остаток товара уменьшился на количество в заказе.
- Отмените заказ и убедитесь, что остаток товара увеличился обратно.
Частые ошибки и как их исправить
- Изменение цены не сохраняется в заказе
Причина: не вызвана функция$order->calculate_totals(). Обязательно вызывайте её после изменения позиций заказа. - Остаток не меняется после смены статуса
Причина: товар не управляет складом (managing_stock()вернул false). Проверьте настройки товара и наличие управления складом. - Цены меняются неправильно при повторном сохранении
Причина: логика скидок реализована неправильно или не учитывает предыдущие изменения. Используйте базовую цену из продукта, не из заказа.
Практические советы по безопасности и производительности
- Вызывайте функции обновления цены и склада только при необходимости, чтобы избежать лишних запросов к базе данных.
- Используйте кэширование и минимизируйте количество обращений к объектам заказа и товаров.
- Проверяйте права пользователя перед изменениями, чтобы защитить админку от несанкционированных изменений.
- Тестируйте на staging-сайте перед внедрением на боевой, чтобы избежать ошибок с потерей данных.
Сравнение подходов: плагин vs кастомный код
| Критерий | Плагин (например, Dynamic Pricing) | Кастомный код (описанный выше) | Компромисс |
|---|---|---|---|
| Гибкость | Высокая, готовые сценарии | Максимальная, под свои правила | Код требует поддержки |
| Производительность | Может нагружать систему | Оптимизирован под задачи | Необходим опыт разработки |
| Стоимость | Платный или freemium | Бесплатно, кроме времени разработчика | Зависит от бюджета |
| Обновления | Поддерживаются разработчиками | Нужно поддерживать самостоятельно | Риск устаревания кода |