0

I have some custom calculation in my woocommerce project and need to get the most expensive product in my cart to apply the correct (insurance) fee.

It's working so far with this code:

/**
 * use woocommerce fee api
 * calculate insurances and assign to checkout
 */

public function add_cart_versicherung_fee() {
    global $woocommerce;

    session_start();

    if ( isset( $_SESSION['versicherung_one'] ) ) {
        foreach ( $_SESSION['versicherung_one'] as $key => $value ) {
            if ( $value == 'ja-ohne-sb' ) {

                $fee = [];

                $prices = [
                    300  => 26,
                    400  => 29,
                    500  => 36,
                    600  => 39,
                    800  => 44,
                    1000 => 49
                ];

                $total = WC()->cart->cart_contents_total;

                foreach ( $prices as $amount => $fee_value ) {

                    if ( $total < $amount ) {
                        array_push( $fee, $amount );
                    }
                }

                $current_fee = $prices[ $fee[0] ];


                WC()->cart->add_fee( '1. Teilnehmer: Versicherung (ohne Selbstbeteiligung)', $current_fee );

            } elseif ( $value == 'ja-ohne-sb-jahr' ) {

                $fee = [];

                $prices = [
                    750  => 49,
                    1000 => 59
                ];

                $total = WC()->cart->cart_contents_total;

                foreach ( $prices as $amount => $fee_value ) {

                    if ( $total < $amount ) {
                        array_push( $fee, $amount );
                    }
                }

                $current_fee = $prices[ $fee[0] ];


                WC()->cart->add_fee( '1. Teilnehmer: Jahresversicherung (ohne Selbstbeteiligung)', $current_fee );

            } elseif ( $value == 'ja-mit-sb' ) {

                $fee = [];

                $prices = [
                    300  => 14,
                    400  => 18,
                    500  => 22,
                    600  => 28,
                    800  => 34,
                    1000 => 39
                ];

                $total = WC()->cart->cart_contents_total;

                foreach ( $prices as $amount => $fee_value ) {

                    if ( $total < $amount ) {
                        array_push( $fee, $amount );
                    }
                }

                $current_fee = $prices[ $fee[0] ];

                WC()->cart->add_fee( '1. Teilnehmer: Versicherung (mit Selbstbeteiligung)', $current_fee );

            } elseif ( $value == 'ja-mit-sb-jahr' ) {

                $fee = [];

                $prices = [
                    750  => 29,
                    1000 => 34
                ];

                $total = WC()->cart->cart_contents_total;

                foreach ( $prices as $amount => $fee_value ) {

                    if ( $total < $amount ) {
                        array_push( $fee, $amount );
                    }
                }

                $current_fee = $prices[ $fee[0] ];

                WC()->cart->add_fee( '1. Teilnehmer: Jahresversicherung (mit Selbstbeteiligung) ', $current_fee );

            } elseif ( $value == 'nein' ) {

                WC()->cart->add_fee( '1. Teilnehmer: Keine Versicherung', 0 );

            }
        }
    }

But it takes the total cart price at the end. I want that the different insurances fees to orientate towards the most expensive product price.

Any ideas how I could get the value for $total of what I need?

Thanks for any help.

Johnny Kermode
  • 75
  • 2
  • 12

1 Answers1

3

If I have correctly understood, try the following, where you will get the highest product price in cart and the corresponding fee will be applied:

public function add_cart_versicherung_fee() {
    session_start();

    if ( isset( $_SESSION['versicherung_one'] ) ) {

    $fee_rates = [
        'ja-mit-sb' => [
            14 => [0, 300],
            18 => [300, 400],
            22 => [400, 500],
            28 => [500, 600],
            34 => [600, 800],
            39 => [800, 1000],
        ],
        'ja-ohne-sb' => [
            26 => [0, 300],
            29 => [300, 400],
            36 => [400, 500],
            39 => [500, 600],
            44 => [600, 800],
            49 => [800, 1000],
        ],
       'ja-mit-sb-jahr' => [
            29 => [0, 750],
            34 => [750, 1000],

        ],
        'ja-ohne-sb-jahr' => [
            49 => [0, 750],
            59 => [750, 1000],
        ],
        'nein' => 0,
    ];

    $texts = [
        'ja-ohne-sb'        => 'Versicherung (ohne Selbstbeteiligung)',
        'ja-ohne-sb-jahr'   => 'Jahresversicherung (ohne Selbstbeteiligung)',
        'ja-mit-sb'         => 'Versicherung (mit Selbstbeteiligung)',
        'ja-mit-sb-jahr'    => 'Jahresversicherung (mit Selbstbeteiligung)',
        'nein'              => 'Keine Versicherung',
    ];

        $product_prices = [];
        $fee = 0;

        // Loop Through cart items - Collect product prices
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            $product_prices[] = $cart_item['data']->get_price();
        }

        // Sorting prices DESC and keep highest price
        rsort($product_prices); // Sorting prices (Desc)
        $highest_price = reset($product_prices);

        // Loop through versicherung session array
        foreach ( $_SESSION['versicherung_one'] as $value ) {
            if ( isset( $fee_rates[$value]) ) {

                // Loop through fee rates multi array to get the fee
                foreach ( $fee_rates[$value] as $rate => $range ) {
                    if( $value == 'nein' ) break;

                    if ( $highest_price > $range[0] && $highest_price <= $range[1]) {
                        $fee = $rate;
                        break;
                    }
                }

                WC()->cart->add_fee( '1. Teilnehmer: '.$texts[$value], $fee );
                break;
            }
        }
    }
}

If needed, for product price including or excluding taxes you can replace this line:

$product_prices[] = $cart_item['data']->get_price();

1) product price including taxes:

$product_prices[] = wc_get_price_including_tax( $cart_item['data'] );

2) product price excluding taxes:

$product_prices[] = wc_get_price_excluding_tax( $cart_item['data'] );
Johnny Kermode
  • 75
  • 2
  • 12
LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Thank you very much for your commitment, this is awesome. This looks good so far, but there are 4 different (insurances) cases depending on the user selection and I think this way the fees are all treated as the same. When the user selects $value == 'ja-ohne-sb' the fees from 26 to 49 are applied, but if he chooses another insurance like ''ja-ohne-sb-jahr' or 'ja-mit-sb' the fees are different. I have edited my entry post to show you the full code. I've also tried myself to figure it out, but I'm stuck at the elseif cases with your code. Would be possible that you could help me again? – Johnny Kermode May 05 '18 at 20:18
  • @JohnnyKermode Ok try that … I have updated my code. – LoicTheAztec May 05 '18 at 21:16
  • You ROCK! Thank you very much! I just had to fix 2-3 typos ('ja-ohne-sb-jahr' was twice) and it's works like a charme! PS: I've send you a message through your contact form. – Johnny Kermode May 05 '18 at 22:21