Add the delivery time to WooCommerce displayed shipping methods based on cart items stock status

39 Views Asked by At

We have an online store and I would like to modify the label below the shipping method (hook: woocommerce_cart_shipping_method_full_label) based on the stock status of the products in the cart.

Basically, if there is 1 product whose stock status is "to order", then the label for shipping method 1 = "48/72h" and the label for shipping method 2 = "48/72h".

If there is 1 product that is "limited stock", then shipping method label 1 = "24/48h" and shipping method label 2 = "48/72h".

Otherwise (that is, all products are "in stock") the label = ""Shipping by 4pm".

My closest attempt was like this: (but it checks for each product, that is, it adds a label as many times as the number of products in the cart - which is wrong)

add_filter( 'woocommerce_cart_item_name', 'custom_text_based_status_name', 10, 3 );
function custom_text_based_status_name( $item_name, $cart_item, $cart_item_key ) {
if( ! ( is_checkout() ) )
return $item_name;
$shipping_class_1 = 'onbackorder';
$shipping_class   = $cart_item['data']->get_stock_status();
if( $shipping_class === $shipping_class_1 ) {
add_filter( 'woocommerce_cart_shipping_method_full_label', 'custom_shipping_methods_label', 10, 2 ); 
function custom_shipping_methods_label( $label, $method ) { 
switch ( $method->id ) {
case 'fish_n_ships:62': //Portugal Continental - Transportadora
$txt = __('Expedição estimada: 24 a 48h úteis''); // <= Additional text
break;
case 'fish_n_ships:63': //Portugal Continental - Gratuito
$txt =  __('Expedição estimada: 72 a 96h úteis'); // <= Additional text
break;
default: //nos restantes casos
$txt =  __('Confirmaremos assim que possível'); // <= Additional text
}
return $label . '<br /><small style="color:#777777">' . $txt . '</small>';
}
}    
return $item_name; 
}`

I also tried but show critical error:

add_filter( 'woocommerce_cart_shipping_method_full_label', 'custom_shipping_method_label', 10, 3 ); 
function custom_shipping_method_label( $label, $method, $cart_item ) { 
switch ([$method->id, $cart_item['data']->get_stock_status]) {
case ['fish_n_ships:62', 'instock']: //Portugal Continental - Transportadora
$txt = __('Expedição estimada: 24 a 48h úteis'); // <= Additional text
break;
case ['fish_n_ships:62', 'stock_limitado']: //Portugal Continental - Transportadora
$txt = __('Expedição estimada: 24 a 48h úteis'); // <= Additional text
break;
default: //nos restantes casos
$txt =  __('Confirmaremos assim que possível'); // <= Additional text
}
return $label . '<br /><small style="color:#777777">' . $txt . '</small>';
}
1

There are 1 best solutions below

0
LoicTheAztec On

There are mistakes and missing things in your code attempts.

To resume, you have 2 shipping methods:

  • Shipping method 1: fish_n_ships:62 (Portugal Continental - Paid),
  • Shipping method 2: fish_n_ships:63 (Portugal Continental - Free).

Your request (related to cart items):

  • If there is at least 1 item with "onbackorder" stock status, then add "Expedição estimada: 48 a 72h úteis" to the shipping label for both shipping methods,
  • If there is at least 1 item with "limited_stock" stock status, then add:
    • "Expedição estimada: 24 a 48h úteis" to the shipping label for shipping method 1,
    • "Expedição estimada: 48 a 72h úteis" to the shipping label for shipping method 2,
  • If all items have "instock" stock status, then add "Expedição às 16h" to the shipping label for both shipping methods.

Try the following:

// Utility function that get the stock status (prioritized) from cart items
function cart_items_stock_status(){
    // Define all stock status
    $data = array('instock' => 0, 'stock_limitado' => 0, 'onbackorder' => 0 );
    // Loop through cart items
    foreach ( WC()->cart->get_cart() as $item ) {
        $data[$item['data']->get_stock_status()] += $item['quantity'];
    }

    if ( $data['onbackorder'] > 0 ) {
        return 'onbackorder';
    } elseif ( $data['stock_limitado'] > 0 ) {
        return 'stock_limitado';
    } else {
        return 'instock';
    }
}

// Add the delivery estimated time to the shipping label
add_filter( 'woocommerce_cart_shipping_method_full_label', 'custom_shipping_method_label', 10, 3 ); 
function custom_shipping_method_label( $label, $method ) { 
    $stock_status = cart_items_stock_status();
    
    if ( $stock_status === 'onbackorder' ) {
        $text = __('Expedição estimada: 48 a 72h úteis');
    } 
    elseif ( $stock_status === 'stock_limitado' ) {
        if ( $method->id === 'fish_n_ships:62' ) {
            $text = __('Expedição estimada: 24 a 48h úteis');
        } 
        elseif ( $method->id === 'fish_n_ships:63' ) {
            $text = __('Expedição estimada: 48 a 72h úteis');
        }
    } 
    else {
        $text = __('Expedição às 16h'); // In stock
    }

    if ( $method->id === 'fish_n_ships:62' || $method->id === 'fish_n_ships:63' ) {
        $label .= '<br /><small style="color:#777777">' . $text . '</small>';
    }
    return $label;
}

Code goes in functions.php file of your child theme (or in a plugin). It should work.