Set a custom calculated price in Woocommerce Befor

2019-08-11 23:47发布

问题:

So I have setup woocommerce with Advance Seat Reservation Management for WooCommerce plugin but I'm running into pricing issues as the Minicart widget shows the item price divided by 2.

Appreciate any help.

Here is the related involved plugin code:

add_action( 'woocommerce_before_calculate_totals', 'srw_add_custom_price' );
function srw_add_custom_price( $cart_object ){
global $wpdb;

foreach( $cart_object->cart_contents as $key => $value ){
    $proId = $value['data']->id;

    if(isset($_SESSION["seats".$proId])) {
        $seatsSec = $_SESSION["seats".$proId];
    }else{
        $seatsSec = '';
    }
    $seatsSecF = explode("@", $seatsSec);
    if(count($seatsSecF) > 0){
        $checkProfileTable = $wpdb->prefix . 'srw_seat_reservation_product';
        $profile = $wpdb->get_results("SELECT * from $checkProfileTable where proId = ".$proId);
        $fileId = $profile[0]->profileID;

        $mapTable = $wpdb->prefix . 'srw_seat_reservation_map';
        $maps = $wpdb->get_results("SELECT * from $mapTable where profileID = ".$fileId);
        $mapId = $maps[0]->profileID;

        $mapValueTable = $wpdb->prefix . 'srw_seat_reservation_map_value';
        $proValueTable = $wpdb->prefix . 'srw_seat_reservation_product_value';

        $checkConfig = $wpdb->prefix . 'srw_seat_reservation_config';
        $profile = $wpdb->get_results("SELECT * from $checkConfig");
        $pricewrong = $profile[0]->price;

        foreach($seatsSecF as $seat){
            $checkSeat = explode(".", $seat);
            $column = $checkSeat[1];
            $row = $checkSeat[0];

            $mapvalues = $wpdb->get_results("SELECT * from $mapValueTable where mapId = ".$mapId." and mapcolumn = '".$column."' and row = '".$row."'");
            $type = $mapvalues[0]->type;

            $checkPrice = $wpdb->get_results("SELECT * from $proValueTable where proId = ".$proId." and color = '".$type."'");
            $price = $checkPrice[0]->price;

            if($pricewrong == "yes"){
                if(is_user_logged_in())
                    $value['data']->price += $price / 2;
                else
                    $value['data']->price += $price;
            }else
                $value['data']->price += $price;
        }
        $value['data']->set_price( $value['data']->price );
    }
  }
}

回答1:

You should always comment your code, as nobody can understand what is done in those SQL queries and price calculations. Your calculations need to be done before on woocommerce_add_cart_item_data hook.

It seems that there is some errors, mistakes and repetitions in the code. for example $value['data']->price += $price; is not correct and will not work in Woocommerce 3. The code below use the correct way to make that work.

The code:

// Calculate custom price and add it as cart item data
add_filter('woocommerce_add_cart_item_data', 'srw_add_custom_price_to_cart_item_data', 30, 2 );
function srw_add_custom_price_to_cart_item_data( $cart_item_data, $product_id ){
    global $wpdb;

    $proId = $product_id;

    if(isset($_SESSION["seats".$proId])) {
        $seatsSec = $_SESSION["seats".$proId];
    }else{
        $seatsSec = '';
    }
    $seatsSecF = explode("@", $seatsSec);
    if(count($seatsSecF) > 0){
        $checkProfileTable = $wpdb->prefix . 'srw_seat_reservation_product';
        $profile = $wpdb->get_results("SELECT * from $checkProfileTable where proId = ".$proId);
        $fileId = $profile[0]->profileID;

        $mapTable = $wpdb->prefix . 'srw_seat_reservation_map';
        $maps = $wpdb->get_results("SELECT * from $mapTable where profileID = ".$fileId);
        $mapId = $maps[0]->profileID;

        $mapValueTable = $wpdb->prefix . 'srw_seat_reservation_map_value';
        $proValueTable = $wpdb->prefix . 'srw_seat_reservation_product_value';

        $checkConfig = $wpdb->prefix . 'srw_seat_reservation_config';
        $profile = $wpdb->get_results("SELECT * from $checkConfig");
        $pricewrong = $profile[0]->price;

        $calculated_price = 0;

        foreach($seatsSecF as $seat){
            $checkSeat = explode(".", $seat);
            $column = $checkSeat[1];
            $row = $checkSeat[0];

            $mapvalues = $wpdb->get_results("SELECT * from $mapValueTable where mapId = ".$mapId." and mapcolumn = '".$column."' and row = '".$row."'");
            $type = $mapvalues[0]->type;

            $checkPrice = $wpdb->get_results("SELECT * from $proValueTable where proId = ".$proId." and color = '".$type."'");
            $price = $checkPrice[0]->price;

            $calculated_price += $price;
        }
        if( $calculated_price > 0 ){
            $cart_item_data['new_price'] = $calculated_price;
            $cart_item_data['unique_key']    = md5( microtime() . rand() );
        }
        return $cart_item_data;

    }
}

// Set the custom cart item calculated price
add_action( 'woocommerce_before_calculate_totals', 'srw_add_custom_price' );
function srw_add_custom_price( $cart_object ){
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
        return;

    foreach ( $cart_object->get_cart() as $cart_item ) {
        if( isset($cart_item['new_price']) )
            $cart_item['data']->set_price( $cart_item['new_price'] );
    }
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.