• Hola, a ver si alguien me puede ayudar.

    En woocommerce tengo zona de envio «Europa» y métodos de envio «Precio fijo» para artículos de decoración con coste de envio 30€ y el resto de productos 15€. Ahora quiero poner el resto de los artículos con coste de envio 0 si el pedido supera los 120€, como lo hago?

    He probado insertando codigo en el function.php del child theme pero ninguno me funciona. Os pongo el fragmento:

    add_filter( 'woocommerce_package_rates', 'adjust_shipping_rates_for_europe', 10, 2 );
    
    function adjust_shipping_rates_for_europe( $rates, $package ) {
    
        // Verificar si la dirección de envío está en la zona de Europa
    
        $is_europe_zone = false;
    
        $europa_countries = array( 'ES', 'FR', 'IT', 'BE', 'NL', 'GR' ); // Países de la zona de Europa
    
        // Verificar si la dirección de envío del cliente está en la zona de Europa
    
        if ( in_array( $package['destination']['country'], $europa_countries ) ) {
    
            $is_europe_zone = true;
    
        }
    
        // Si la dirección de envío está en la zona de Europa, aplicar ajustes de envío
    
        if ( $is_europe_zone ) {
    
            $subtotal = WC()->cart->subtotal;
    
            // Verificar si hay productos con la clase de envío 'Deco' en el carrito
    
            $has_deco = false;
    
            foreach ( WC()->cart->get_cart() as $cart_item ) {
    
                if ( has_term( 'deco', 'product_shipping_class', $cart_item['product_id'] ) ) {
    
                    $has_deco = true;
    
                    break;
    
                }
    
            }
    
            // Si hay productos con la clase de envío 'Deco' o el subtotal es inferior a 120€, eliminar el envío gratuito
    
            if ( $has_deco || $subtotal < 120 ) {
    
                foreach ( $rates as $rate_key => $rate ) {
    
                    if ( 'free_shipping:38' === $rate->method_id ) { // Slug para 'Free Shipping'
    
                        unset( $rates[$rate_key] );
    
                    }
    
                }
    
            }
    
            // Si el pedido es mayor de 120€ y aparece el envío gratuito, eliminar el método de envío fijo
    
            if ( $subtotal >= 120 && isset( $rates['free_shipping:38'] ) ) { // Slug para 'Free Shipping'
    
                foreach ( $rates as $rate_key => $rate ) {
    
                    if ( 'flat_rate:23' === $rate->method_id ) { // Slug para 'Flat Rate'
    
                        unset( $rates[$rate_key] );
    
                    }
    
                }
    
            }
    
        }
    
        return $rates;
    
    }

    No se si el problema está en los slug que no son correctos…

    Gracias de antemano

Viendo 3 respuestas - de la 1 a la 3 (de un total de 3)
  • Hola @mnroediger

    Prueba con este código:

    add_filter( 'woocommerce_package_rates', 'adjust_shipping_rates_for_europe', 10, 2 );
    
    function adjust_shipping_rates_for_europe( $rates, $package ) {
        $shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package );
        $is_europe_zone = ($shipping_zone && $shipping_zone->get_zone_name() === 'Europa');
    
        if ( $is_europe_zone ) {
            $subtotal = WC()->cart->subtotal;
    
            $deco_product_ids = wc_get_product_ids_by_shipping_class( 'deco' );
            $has_deco = !empty( array_intersect( $deco_product_ids, wp_list_pluck( WC()->cart->get_cart(), 'product_id' ) ) );
    
            if ( $has_deco || $subtotal < 120 ) {
                unset( $rates['free_shipping:38'] ); // Asegúrate de usar el slug correcto
            }
    
            if ( $subtotal >= 120 && isset( $rates['free_shipping:38'] ) ) {
                unset( $rates['flat_rate:23'] ); // Asegúrate de usar el slug correcto
            }
        }
    
        return $rates;
    }
    

    Verifica que los slugs de los métodos de envío sean los correctos.

    Realiza pruebas con diferentes combinaciones de productos y cantidades para asegurarte de que la lógica funciona como esperas.

    Y recuerda hacer siempre una copia de seguridad del sitio antes de hacer cualquier cambio de este tipo.

    Saludos.

    Iniciador del debate mnroediger

    (@mnroediger)

    Hola Jose Ramón, gracias por tu respuesta.

    He probado el fragmento de código pero me da un error de sintaxis ($shipping_zone) en la linea:

     $shipping_zone = WC_Shipping_Zones::get_zone_matching_package( $package );

    Alguna sugerencia? Gracias!

    ¿Estás usando la última versión de Woocommerce?

    La función WC_Shipping_Zones::get_zone_matching_package() fue introducida en una de las versiones más recientes. Si estás utilizando una versión anterior, es posible que no esté disponible y por eso te dé un error de sintaxis.

    Hay una forma alternativa de obtener la zona de envío:

    add_filter( 'woocommerce_package_rates', 'adjust_shipping_rates_for_europe', 10, 2 );
    
    function adjust_shipping_rates_for_europe( $rates, $package ) {
        $destination_country = $package['destination']['country'];
        $shipping_zones = WC_Shipping_Zones::get_zones();
    
        $is_europe_zone = false;
    
        foreach ( $shipping_zones as $zone ) {
            if ( in_array( $destination_country, $zone['zone_locations'] ) && $zone['zone_name'] === 'Europa' ) {
                $is_europe_zone = true;
                break;
            }
        }
    
        if ( $is_europe_zone ) {
            $subtotal = WC()->cart->subtotal;
    
            $deco_product_ids = wc_get_product_ids_by_shipping_class( 'deco' );
            $has_deco = !empty( array_intersect( $deco_product_ids, wp_list_pluck( WC()->cart->get_cart(), 'product_id' ) ) );
    
            if ( $has_deco || $subtotal < 120 ) {
                unset( $rates['free_shipping:38'] ); // Asegúrate de usar el slug correcto
            }
    
            if ( $subtotal >= 120 && isset( $rates['free_shipping:38'] ) ) {
                unset( $rates['flat_rate:23'] ); // Asegúrate de usar el slug correcto
            }
        }
    
        return $rates;
    }
    

    Prueba a ver.

Viendo 3 respuestas - de la 1 a la 3 (de un total de 3)
  • El debate ‘Envio gratis y clase de envio’ está cerrado a nuevas respuestas.