1
votes

I'm trying to edit the backorder notification on the cart page in WooCommerce so that the number of backorders show for each cart item (I'm using variations).

So if a cart item has a quantity of 7 but the stock is 5, the backorder should be 2. (This information is shown on order emails by default in Woocommerce but not on the cart page before the order is made).

The code below works as long as there is only 1 cart item in the cart. But if there is more than 1 cart item, the same number of backorders is returned for all cart items with backorders.

Does anyone know what I should change so that the backorder notification will display the correct number of backorders for each individual cart item that has backorders - no matter how many cart items with backorders there are in the cart?

I'm using the filter hook woocommerce_cart_item_backorder_notification

    function backorder_info() {
  
    // Loop through cart items
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        // Get an instance of the WC_Product Object
        $product = $cart_item['data'];
        // Get stock quantity
        $stock_qty = $product->get_stock_quantity();
        // get cart item quantity
        $item_qty  = $cart_item['quantity'];
        // Calculate number of backorders
        $backorder_qty = $item_qty - $stock_qty;
        $html = '<p class="backorder_notification">' .__( " " .$backorder_qty. " i restordre","woocommerce").'</p>';

      // return backorder quantity
    return $html;
    }   
}


// Display backorder notification on cart page
add_filter( 'woocommerce_cart_item_backorder_notification', 'custom_cart_item_backorder_notification', 10, 2 );

function custom_cart_item_backorder_notification($html, $product_id) {
    
    $html = backorder_info();
    return $html;   
}
1

1 Answers

0
votes

As you can see the woocommerce_cart_item_backorder_notification filter hook contains the productID as the second argument.

Only this is the parentID, and therefore not so easy to determine for variable products which variant (variantID) is currently in cart.

That is why we are going to first ensure through the following code that not the parentID but the real productID is passed to the woocommerce_cart_item_backorder_notification filter hook

function filter_woocommerce_cart_item_product_id( $cart_item_product_id, $cart_item, $cart_item_key ) {
    // Return real product ID instead of parent ID
    $cart_item_product_id = $cart_item['variation_id'] > 0 ? $cart_item['variation_id'] : $cart_item['product_id'];

    return $cart_item_product_id;
}
add_filter( 'woocommerce_cart_item_product_id', 'filter_woocommerce_cart_item_product_id', 10, 3 );

And then you get, to change the backorder_notification based on number of backorders

function custom_cart_item_backorder_notification( $html, $product_id ) {
    // Get cart items quantities
    $cart_item_quantities = WC()->cart->get_cart_item_quantities();

    // Product quantity in cart
    $product_qty_in_cart = isset( $cart_item_quantities[ $product_id ] ) ? $cart_item_quantities[ $product_id ] : 0;
    
    // Get product
    $product = wc_get_product( $product_id );
    
    // Get stock quantity
    $stock_qty = $product->get_stock_quantity();
    
    // Still in stock
    if ( $stock_qty >= 1 ) {
        // Calculate number of backorders
        $backorder_qty = $product_qty_in_cart - $stock_qty;     
    } else {
        // Calculate number of backorders
        $backorder_qty = $product_qty_in_cart;          
    }
    
    // Output
    $html = '<p class="backorder_notification">' . sprintf( __( '%s in backorder', 'woocommerce' ), $backorder_qty ) . '</p>';

    return $html;
}
add_filter( 'woocommerce_cart_item_backorder_notification', 'custom_cart_item_backorder_notification', 10, 2 );