Agregue un costo adicional al envío de tarifa plana cada 2 artículos de una categoría específica en WooCommerce

Jan 16 2021

Basado en Agregar un costo adicional al envío de tarifa plana cada 3 artículos en el código de respuesta de Woocommerce , hice algunos cambios para agregar un costo adicional al método de envío fijo por cada 2 artículos (en lugar de cada 3 artículos) y solo cuando hay artículos exclusivamente de una categoría específica (aquí categoría "Camisetas").

Aquí está mi intento de código:

// add X amount to shipping for every 2 items added to the cart (flat rate only)
add_filter('woocommerce_package_rates', 'shipping_additional_cost_each_three_items', 100, 2);
function shipping_additional_cost_each_three_items( $rates, $package ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return $rates; // HERE set your additional shipping cost $additional_cost = 8.40;
    $items_count = WC()->cart->get_cart_contents_count(); // Define/replace here your correct category slug (!) $product_category = 't-shirts';
    $prod_cat = false; // Going through each item in cart to see if there is anyone of your category foreach ( WC()->cart->get_cart() as $cart_item ) {
        $product_id = $cart_item['product_id'];
        if ( has_term( $product_category, 'product_cat', $product_id ) ){
            $prod_cat = true; } } // Loop through the shipping taxes array foreach ( $rates as $rate_key => $rate ){
        $has_taxes = false; // Targetting "flat rate" if( 'flat_rate' === $rate->method_id ){

            // Get the initial cost
            $initial_cost = $new_cost = $rates[$rate_key]->cost;

            // Adding the additional cost if product in T-Shirt category after every 2 items (3, 6, 9 …)
            if ( $prod_cat ) { for($i = 0; $i <= $items_count; $i+=3){ $new_cost += $additional_cost; } } // Set the new cost $rates[$rate_key]->cost = $new_cost;

            // Taxes rate cost (if enabled)
            $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 ){
                    // Get the initial tax cost
                    $initial_tax_cost = $new_tax_cost = $rates[$rate_key]->taxes[$key]; // Get the tax rate conversion $tax_rate    = $initial_tax_cost / $initial_cost;

                    // Set the new tax cost
                    $taxes[$key] = $new_cost * $tax_rate;
                    $has_taxes = true; // Enabling tax } } } if( $has_taxes )
            $rates[$rate_key]->taxes = $taxes; return $rates;
    }
}

Para el método de envío elegido con "tarifa plana", el código funciona bien cuando los artículos de la categoría "camisetas" están en el carrito. Pero si hay un artículo que no pertenece a la categoría "camiseta", la tarifa simplemente desaparece y muestra el título sin importe.

¿Alguien puede decirme dónde tengo que colocar la condición 'si la categoría es X', para que ese código sea funcional?

Respuestas

1 LoicTheAztec Jan 16 2021 at 14:15

Hay algunos errores en su código (como return $rates;ese debería ser justo antes del último corchete de cierre). En su lugar, pruebe el siguiente código revisado:

add_filter('woocommerce_package_rates', 'shipping_additional_cost_each_three_items', 100, 2);
function shipping_additional_cost_each_three_items( $rates, $package ){ if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return $rates;

    // HERE set your additional shipping cost
    $additional_cost = 8.40; $each_items      = 2; // Number of items (for additional cost)

    // Her set your category(ies) (can be term Ids slugs or names)
    $product_categories = array('t-shirts'); $items_cat_count    = 0; // Initializing

    // Loop through cart items for the current shipping package        
    foreach( $package['contents'] as $cart_item ) {
        if ( ! has_term( $product_categories, 'product_cat', $cart_item['product_id'] ) ){
            $items_cat_count += $cart_item['quantity']; // Count items from defined category
        }
    }
    
    if ( $items_cat_count >= $each_items ) {
       // Loop through the shipping taxes array
        foreach ( $rates as $rate_key => $rate ){ // Targetting "flat rate" if( 'flat_rate' === $rate->method_id ){
                $initial_cost = $new_cost = $rate->cost; // Get the initial cost $has_taxes    = false; // Initializing
                $taxes = array(); // Initializing // Adding to cost the additional cost each 2 items (2, 4, 6 …) for($i = 0; $i <= $items_cat_count; $i += $each_items){
                    $new_cost += $additional_cost;
                }
                $rates[$rate_key]->cost = $new_cost; // Set the new cost // Taxes rate cost (if any) - Loop through taxes array (as they can be many) foreach ($rate->taxes as $key => $tax){
                    if( $tax > 0 ){ // Get the initial tax cost $initial_tax_cost = $new_tax_cost = $tax;
    
                        // Get the tax rate conversion
                        $tax_rate = $initial_tax_cost / $initial_cost; // Set the new tax cost in the array $taxes[$key] = $new_cost * $tax_rate; $has_taxes   = true; // Enabling tax changes
                    }
                }
                // set array of shipping tax cost
                if( $has_taxes ) { $rates[$rate_key]->taxes = $taxes; 
                }
            } 
        }
    }
    return $rates;
}

El código va en el archivo functions.php del tema hijo activo (o tema activo). Debería funcionar.

No olvide vaciar su carrito para actualizar los datos de envío almacenados en caché.