Диагностика проблемы: зачем менять стоимость и остаток при обновлении заказа
В стандартном WooCommerce при обновлении заказа цена товара и складской остаток остаются неизменными. Это становится проблемой, если вы хотите автоматизировать динамическое ценообразование или корректировать остатки при изменении количества в заказе вручную или через сторонние интеграции. Например, при изменении количества товара в заказе цена должна пересчитываться с учетом скидок, акций или новых цен, а складской остаток — всегда отражать текущее состояние.
Пошаговое решение: как реализовать автоматическое обновление цены и остатка
1. Отслеживаем событие обновления заказа
Для начала нужно поймать момент, когда заказ обновляется. В WooCommerce есть хук woocommerce_update_order, который срабатывает после обновления объекта WC_Order.
2. Перебираем товары в заказе и корректируем цену и склад
Далее необходимо пройтись по всем позициям заказа, получить их ID продукта, количество, и применить нужные правила для цены и остатка.
3. Обновляем цену позиции и складской запас
Используем методы set_total() и save() у WC_Order_Item_Product. Для изменения остатка — функцию wc_update_product_stock().
add_action('woocommerce_update_order', 'custom_update_order_prices_and_stock', 10, 1);
function custom_update_order_prices_and_stock(\WC_Order $order) {
// Проходим по товарам заказа
foreach ( $order->get_items() as $item_id => $item ) {
$product = $item->get_product();
if ( ! $product || ! $product->exists() ) continue;
$qty = $item->get_quantity();
// Пример: новая цена с 10% скидкой
$new_price = $product->get_regular_price() * 0.9;
// Обновляем цену товара в позиции заказа
$item->set_subtotal( $new_price * $qty );
$item->set_total( $new_price * $qty );
$item->save();
// Обновляем складской остаток: вычитаем количество из текущего
$current_stock = $product->get_stock_quantity();
if ( $current_stock !== null ) {
$new_stock = max(0, $current_stock - $qty);
wc_update_product_stock( $product, $new_stock );
}
}
// Пересчитываем итоги заказа
$order->calculate_totals();
$order->save();
}
Проверка результата после внедрения
- Создайте тестовый заказ с несколькими товарами.
- Обновите заказ через админку, например, измените количество товаров.
- Проверьте, что цены товаров в заказе изменились согласно формуле (в нашем случае -10%).
- Проверьте складской остаток товаров в каталоге — он должен уменьшиться на количество из заказа.
- Убедитесь, что итоговая сумма заказа пересчиталась корректно.
Для отладки можно добавить error_log() внутри функции, чтобы убедиться, что она срабатывает.
Частые ошибки и как их исправить
- Обновление цены не сохраняется. Проверьте, что вызывается
$item->save();и$order->save();. - Склад не меняется или становится отрицательным. Используйте
max(0, $new_stock)для защиты от отрицательных значений. Убедитесь, что у товаров включён контроль остатков (Manage stock). - Функция не срабатывает. Проверьте правильность хука и что функция подключена в
functions.phpили в плагине. - Проблемы с кешированием. После обновления заказа очистите кеш (если есть) и проверьте данные через базу.
Практические советы по безопасности и производительности
- Не используйте тяжелые операции в хуках, которые могут тормозить обновление заказа.
- Проверяйте права пользователя, чтобы не позволять менять цены и остатки неавторизованным.
- Делайте резервные копии базы перед изменением складских остатков.
- Для крупных магазинов рассмотрите отдельные фоновые задачи (WP-Cron или внешние сервисы) для обновления остатков.
- Используйте
wc_update_product_stock()вместо прямой записи в базу — она запускает все нужные хуки WooCommerce.
Сравнение вариантов реализации
| Метод | Плюсы | Минусы |
|---|---|---|
| Код в functions.php (как выше) | Быстрая настройка, гибкость, без плагинов | Требует навыков разработки, возможные конфликты при обновлении WooCommerce |
| Использование плагинов динамического ценообразования | Готовые решения, поддержка, расширенный функционал | Платные, могут замедлять сайт, не всегда учитывают склад |
| Сторонние ERP или 1С-интеграции | Автоматизация складского учета, точность | Сложность интеграции, стоимость внедрения |