Как сделать бесплатную доставку для всех товаров в корзине, если она будет хотя бы у одного из товаров?
Клиент хочет, чтобы если в корзине есть товар, у которого бесплатная доставка, то для всех товаров, которые в этом заказе, чтобы тоже применялась бесплатная доставка, а если товара с бесплатной доставкой в данном заказе нет - то чтобы стоимость доставки каждого товара не менялась.
По-любому условие должно быть через мета-поле. Как лучше сделать - задать класс доставки? Это же тоже мета-поле.
Поискал емного информацию на стаке, должно быть что-то вроде такого хука?
add_filter('woocommerce_package_rates', 'conditional_shipping_class_cost', 15, 2); function conditional_shipping_class_cost( $rates, $package ){ if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return $rates; // HERE define the targeted shipping method $shipping_class = 'Extra'; // Initializing variables $found = $others = false; // Loop through cart items and checking for the specific product foreach( $package['contents'] as $item ) { if( $item['data']->get_shipping_class() == sanitize_title($shipping_class) ){ $found = true; // Has the shipping class } else { $others = true; // NOT the shipping class } } // When items with the defined shipping are not alone in cart if( $found && $others ){ // Loop through shipping rates foreach ( $rates as $rate_key => $rate ){ // For Flat rate and Local pickup shipping methods if( $rate->method_id == 'flat_rate' ) { // Set the cost to zero $rates[$rate_key]->cost = 0; $rates[$rate_key]->label = 'f: '.$found.' | o: '.$others.' '; // Initializing variables $has_taxes = false; $taxes = []; // Loop through the shipping taxes array (as they can be many) foreach ($rates[$rate_key]->taxes as $key => $tax){ if( $rates[$rate_key]->taxes[$key] > 0 ){ // Set the tax cost to zero $taxes[$key] = 0; $has_taxes = true; } } // Set new taxes cost array if( $has_taxes ) $rates[$rate_key]->taxes = $taxes; } } } return $rates; } |
add_filter('woocommerce_package_rates', 'conditional_shipping_class_cost', 15, 2); function conditional_shipping_class_cost( $rates, $package ){ if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return $rates; // HERE define the targeted shipping method $shipping_class = 'Extra'; // Initializing variables $found = $others = false; // Loop through cart items and checking for the specific product foreach( $package['contents'] as $item ) { if( $item['data']->get_shipping_class() == sanitize_title($shipping_class) ){ $found = true; // Has the shipping class } else { $others = true; // NOT the shipping class } } // When items with the defined shipping are not alone in cart if( $found && $others ){ // Loop through shipping rates foreach ( $rates as $rate_key => $rate ){ // For Flat rate and Local pickup shipping methods if( $rate->method_id == 'flat_rate' ) { // Set the cost to zero $rates[$rate_key]->cost = 0; $rates[$rate_key]->label = 'f: '.$found.' | o: '.$others.' '; // Initializing variables $has_taxes = false; $taxes = []; // Loop through the shipping taxes array (as they can be many) foreach ($rates[$rate_key]->taxes as $key => $tax){ if( $rates[$rate_key]->taxes[$key] > 0 ){ // Set the tax cost to zero $taxes[$key] = 0; $has_taxes = true; } } // Set new taxes cost array if( $has_taxes ) $rates[$rate_key]->taxes = $taxes; } } } return $rates; }
Как вообще лучше подойти к такому вопросу? С классами доставки или через что лучше такое настроить?
Дополнительно:
Ответы:
Вот что говорит ИИ на этот счёт:
Для реализации бесплатной доставки для всех товаров в корзине, если она есть хотя бы у одного товара, вам потребуется настроить соответствующие правила доставки в WooCommerce. Вот как это можно сделать:
1. В административной панели WooCommerce перейдите в раздел "Настройки" и выберите вкладку "Доставка".
2. Создайте новый метод доставки, который будет представлять бесплатную доставку. Для этого нажмите на кнопку "Добавить способ доставки".
3. В разделе "Настройки способа доставки" выберите "Бесплатная доставка" из выпадающего списка.
4. Перейдите во вкладку "Условия" и настройте правила для применения бесплатной доставки. Для этого выберите "Добавить условие" и установите следующие параметры:
Поле: "Общая стоимость товаров"
Оператор: "Больше или равно"
Значение: "0" (или любую другую сумму, если вы хотите установить минимальную стоимость для бесплатной доставки)
Сохраните изменения.
Теперь, когда в корзине присутствует хотя бы один товар с бесплатной доставкой, все остальные товары в этом заказе также будут иметь бесплатную доставку. Если же товара с бесплатной доставкой в заказе нет, стоимость доставки каждого товара останется без изменений.
Обратите внимание, что реализация бесплатной доставки может варьироваться в зависимости от выбранной вами темы или установленных плагинов. Предоставленные инструкции основаны на стандартных функциях WooCommerce.
- Проверить пока не могу.) Но он парень весёлый, может и фигню посоветовать.))
- Nik Master, ага, мне для нового фотика чтобы поставить штамп-дату, как на старом ПОСОВЕТОВАЛ УСТАНОВИТЬ ОТДЕЛЬНУЮ ПРОГРАММУ! на полном серьезе. хотя ИИ наверно думал - как это я на полном серьезе хочу дату, от которой все наоборот отказались.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Да, это лучше делать на уровне расчета доставки WooCommerce через фильтр
woocommerce_package_rates. Для признака "этот товар дает бесплатную доставку всей корзине" можно использовать класс доставки или отдельное метаполе товара. Класс доставки удобен для админки, метаполе удобнее, если логика должна быть независимой от настроек доставки.Пример через метаполе товара
_free_shipping_for_cartсо значениемyes:add_filter('woocommerce_package_rates', 'site_free_shipping_if_cart_has_marked_product', 20, 2); function site_free_shipping_if_cart_has_marked_product($rates, $package) { if (is_admin() && !defined('DOING_AJAX')) { return $rates; } $has_free_shipping_product = false; foreach ($package['contents'] as $cart_item) { $product_id = $cart_item['variation_id'] ?: $cart_item['product_id']; if ('yes' === get_post_meta($product_id, '_free_shipping_for_cart', true)) { $has_free_shipping_product = true; break; } } if (!$has_free_shipping_product) { return $rates; } foreach ($rates as $rate_key => $rate) { $rates[$rate_key]->cost = 0; if (!empty($rates[$rate_key]->taxes)) { foreach ($rates[$rate_key]->taxes as $tax_key => $tax) { $rates[$rate_key]->taxes[$tax_key] = 0; } } } return $rates; }
Если хотите использовать класс доставки, проверяйте
$cart_item['data']->get_shipping_class()или ID класса. Класс удобен тем, что менеджер может назначать его в карточке товара без ACF.После изменения правил доставки очистите transient-кэш доставки WooCommerce: достаточно поменять адрес в корзине или очистить сессии WooCommerce. При тесте проверяйте три сценария: