обновить корзину woocommerce после изменения способа доставки

В настоящее время я работаю над интернет-магазином с WooCommerce. Я столкнулся с проблемой, что хочу предоставить скидку клиентам, выбравшим конкретный способ доставки. Скидка составляет 0,50 на каждый продукт. Я в основном решил эту проблему с помощью следующего кода в моем "functions.php":

add_action('woocommerce_before_calculate_totals', 'woo_add_cart_fee');

function woo_add_cart_fee() {

    global $woocommerce;
    $cart = $woocommerce->cart->get_cart();
    //Calculating Quantity
    foreach ($cart as $cart_val => $cid) {
        $qty += $cid['quantity'];
    }

    if ($woocommerce->cart->shipping_label == "specific shipping method") {
        $woo_fee = $qty * (-0.5);
        $woo_name = "discount for specific shipping method";
    }

    $woocommerce->cart->add_fee(__($woo_name, 'woocommerce'), $woo_fee, true);
}

Код технически работает, единственная проблема, с которой я сейчас сталкиваюсь, заключается в том, что если клиент меняет способ доставки, то есть с «определенного способа доставки» на «обычный» (без какой-либо скидки) или наоборот, он всегда отображает и вычисляет размер скидки от ранее выбранного способа доставки. Другими словами, это всегда один шаг назад, и поэтому покупателю отображается неверная общая сумма.

Есть ли у кого-нибудь идея решить эту проблему?


person sRos    schedule 25.12.2013    source источник


Ответы (3)


Это решение для Woocommerce 2.1.X!

Я не уверен, что это поможет. Я столкнулся с аналогичной проблемой, когда мне нужно было получить выбранный способ доставки. В файле \wp-content\plugins\woocommerce\includes\wc-cart-functions.php я нашел метод под названием wc_cart_totals_shipping_html().

В этом методе выполняется проверка текущего выбранного способа доставки, который содержит следующий код:

$packages = WC()->shipping->get_packages();
foreach ( $packages as $i => $package ) {
    $chosen_method = isset( WC()->session->chosen_shipping_methods[ $i ] ) ? WC()->session->chosen_shipping_methods[ $i ] : '';
}

Я использовал этот код в своем собственном functions.php, чтобы проверить текущий выбранный способ доставки, и он работает. Пример:

add_filter( 'woocommerce_billing_fields', 'wc_change_required_fields');

function wc_change_required_fields($address_fields) {
    $packages = WC()->shipping->get_packages();
    foreach ( $packages as $i => $package ) {
        $chosen_method = isset( WC()->session->chosen_shipping_methods[ $i ] ) ? WC()->session->chosen_shipping_methods[ $i ] : '';
    }
    if ($chosen_method == 'local_delivery') {
        $address_fields['billing_address_1']['required'] = true;
        // place your changes that depend on the shipping method here...
    }
}

Надеюсь, это поможет!

person Richard R    schedule 27.02.2014

Это очень давно, но я сам столкнулся с этой проблемой и должен был найти решение.

Woocommerce хранит предварительно рассчитанные суммы корзины в базе данных, а не рассчитывает их на лету. Но выбор способа доставки сохраняется как переменная сеанса. Таким образом, изменения в доставке не отражаются сразу при оформлении заказа без посещения или обновления страницы корзины.

В исходном опубликованном коде изменения доставки не были отражены, потому что они не пересчитывались и не сохранялись. Для этого функцию нужно обмануть, заставив сначала думать, что это страница корзины, а затем пересчитать итоги, которые нужно сохранить.

GLOBAL $woocommerce;
if ( ! defined('WOOCOMMERCE_CART') ) {
  define( 'WOOCOMMERCE_CART', true );
}

А затем в конце функции, после того, как были внесены все желаемые изменения, обновите и сохраните.

WC()->cart->calculate_totals();

См. Также CODEX для WC_AJAX :: update_shipping_method ()

http://docs.woothemes.com/wc-apidocs/source-class-WC_AJAX.html#148-174

person Mark    schedule 24.03.2015

Ответ Марка сработал для меня, однако мне пришлось удалить все временные значения перед запуском кода. В противном случае он просто восстановит сохраненные значения.

public function clear_shipping_transients() {
  global $wpdb;

  $wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('_transient_cp_quote_%') OR `option_name` LIKE ('_transient_timeout_cp_quote_%') OR `option_name` LIKE ('_transient_wc_ship_%')" );
}
person mathee    schedule 18.08.2015