0

The items added to the cart are dynamically priced models from an 3d-print-plugin. In the cart the below code calculate a reduced price per item with a fixed bulk table. But after the checkout, all totals are shown with the original price without discount. I.e. the order details and the notification email.

Here is my code:

add_action( 'woocommerce_before_calculate_totals', 'quantity_based_pricing', 9999 );
 
 function quantity_based_pricing( $cart ) {
  
     if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
  
     if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;

     // Define discount rules and thresholds
     $thresholds_and_discounts = array(
        array(
            'threshold' => 2,
            'discount' => 0.15
        ),
        array(
            'threshold' => 5,
            'discount' => 0.25
        ),
        array(
            'threshold' => 10,
            'discount' => 0.30
        ),
        array(
            'threshold' => 50,
            'discount' => 0.40
        ),
        array(
            'threshold' => 100000,
            'discount' => 0.40
        )
     );
  
     foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {

        foreach ( $thresholds_and_discounts as $key => $threshold_and_discount ) {
            $threshold = $threshold_and_discount['threshold'];
            $discount = $threshold_and_discount['discount'];
            $next_threshold = isset($thresholds_and_discounts[$key + 1]['threshold']) ? $thresholds_and_discounts[$key + 1]['threshold'] : null;
            if ( $next_threshold != '' ) { 
                if ( $cart_item['quantity'] >= $threshold && $cart_item['quantity'] < $next_threshold) {
                    $price = round(  $cart_item['data']->get_price() * ( 1 - $discount ), 2 );
                    // Set the new price as the cart item price
                    $cart_item['data']->set_price( $price );
                    // Set the new price as metadata
                    $cart_item['data']->update_meta_data( '_discounted_price', $price );
                }
            }
        }
    }
}

add_filter('woocommerce_cart_item_price', 'cart_item_price_discount', 1000, 3);

function cart_item_price_discount ($price_html, $cart_item, $cart_item_key) {
    if (!WC()->cart) return;
    $cart = WC()->cart->get_cart();
    
    if (isset($cart_item['3dp_options'])) {
        $original_price = $cart_item['3dp_options']['product-price'];
        $price = $cart_item['data']->get_price();
        if (is_numeric($price) && $price != $original_price) {
            $price_html = '<del>' . wc_price($original_price)  . '</del> &nbsp; <ins>' . wc_price($price) . '</ins>';  
        }
    }
    
    return $price_html;
}

add_filter('woocommerce_cart_item_subtotal', 'cart_item_subtotal', 10, 3);
function cart_item_subtotal ($price_html, $cart_item, $cart_item_key) {
    if (!WC()->cart) return;
    $cart = WC()->cart->get_cart();

    if (isset($cart_item['3dp_options'])) {
        $price = $cart_item['data']->get_price();
        $price *= $cart_item['quantity'];
        $price_html = wc_price($price);  
    }

    return $price_html;
}

I would expect, that the updated price in the cart overwrites the original price and then displayed correctly in the order summary, details and email.

Edit: I found out, that the WPML-Plugin (Multilingual Woocommerce) has something to do with this. If I turn off the cart sync between the languages, then the calculated summary is carried over to the order and notification email.

0 Answers0