WooCommerce: Cart price override with text

radug picture radug · Jun 27, 2016 · Viewed 8.2k times · Source

We have a bunch of products with either:

  • No price
  • Zero price

We made them purchasable with the built-in hook but the cart still displays them as having a 0 price during checkout.

We'd like the cart & checkout summary to display "Special order" or any other text, but it seems WooCommerce invalidates text-based prices.

Tried this : WooCommerce: Add product to cart with price override?

The above works fine with a number override, but when tried with a text override it defaults back to displaying a 0 price.

Why? These products are built-to-order and the shop admin will update price after talking to customer/supplier.

Answer

helgatheviking picture helgatheviking · Jun 27, 2016

You need to filter the strings that display the price and subtotal in the cart. The link you mentioned discussed changing the actual price. In your case the price is $0 until you set an actual price later on. There are probably filters for the cart totals too, but this should be a start:

add_filter( 'woocommerce_cart_item_price', 'so_38057349_cart_item_price', 10, 3 );
function so_38057349_cart_item_price( $price, $cart_item, $cart_item_key ) {

    if ( $cart_item[ 'data' ]->price == 0 ) {
        $price = __( 'Special Order', 'yourtheme' );
    }

    return $price;
}


add_filter( 'woocommerce_cart_item_subtotal', 'so_38057349_cart_item_subtotal', 10, 3 );
function so_38057349_cart_item_subtotal( $subtotal, $cart_item, $cart_item_key ) {

    if ( $cart_item[ 'data' ]->price == 0 ) {
        $subtotal = __( 'To be determined', 'yourtheme' );
    }

    return $subtotal;
}


add_filter( 'woocommerce_order_formatted_line_subtotal', 'so_38057349_order_item_subtotal', 10, 3 );
function so_38057349_order_item_subtotal( $subtotal, $item, $order ) {

    if ( isset( $item[ 'line_subtotal' ] ) && $item[ 'line_subtotal' ] == 0 ) {
        $subtotal = __( 'To be determined', 'yourtheme' );
    }

    return $subtotal;
}

Of course, this will also apply to any product with a 0 price and maybe not only the ones you have configured to be custom built, so you may need more conditional logic than I've supplied here.

To follow up on your comment.... woocommerce_order_amount_total is the numerical total and not the displayed html. You can see the functions being called in the cart-totals.php template.

function so_38057349_woocommerce_cart_subtotal( $cart_subtotal, $compound, $cart ) { 
    if( $cart->subtotal == 0 ){
        $cart_subtotal = __( 'Order subtotal to be determined', 'yourtheme' ); 
    }
    return $cart_subtotal; 
}; 
add_filter( 'woocommerce_cart_subtotal', 'so_38057349_woocommerce_cart_subtotal', 10, 3 ); 


// define the woocommerce_order_amount_total callback 
function so_38057349_woocommerce_order_amount_total( $order_total ) { 
    if( WC()->cart->get_total() == 0 ){
        $order_total = __( 'Order total to be determined', 'yourtheme' ); 
    }
    return $order_total; 
}; 
add_filter( 'woocommerce_cart_totals_order_total_html', 'so_38057349_woocommerce_order_amount_total' ); 

Updated screenshot: cart