Ibtekarlabs
Ibtekarlabs

Reputation: 43

Complicated Woocommerce shipping Rules issue

I am trying to apply complicated shipping rules in Woocommerce.

I have basic products which is:

Spend Shipping cost
less than 300 30$
300 or more Free

But I also have some large products and products with special delivery requirements

product Shipping Class cost
large box Truck with crane 1000$
large Box Truck only 200$
Gazebo (Choice1: Delivery Only) Delivery & Assebly 200$
Gazebo (Choice2: Delivery & Assembly) Delivery & Assebly 350$

Below is my shipping methods

Shipping Methods

Standerd rates

Shipping With Assembly

For basic products everything is working well,

Also for large boxes its well as it shows in Standard shipping.

But when I add the (shipping with assembly) shipping method it still appear as choice even if no product with this class is in the cart.

I just need it to appear only when gazebo is in the cart

add_filter( 'woocommerce_package_rates', 'hide_shipping_when_class_is_in_cart', 100, 2 );

function hide_shipping_when_class_is_in_cart( $rates, $package ) {

$free_shipping_method = 'free_shipping:13';
$shipping_classes = array('truck-crane','large-furniture','furniture-assembly');
$class_exists = false;
$cart_classes = array();
$shipping_methods = $shipping_zone->get_shipping_methods();

foreach( $package['contents'] as $cart_item )
        $cart_item_class = $cart_item['data']->get_shipping_class();
    if( in_array($cart_item_class ,  $shipping_classes ) ) {//Check if any shipping class exist
        array_push($cart_classes,$cart_item_class); //push cart classes to array
        $class_exists = true;
        //break; 
    }


foreach($shipping_methods as $method){
    $method_classes = $method->get_shipping_classes();

  //Here i want to unset shipping methods which has no avaiable class in cart items

}

if( $class_exists )
    unset( $rates[$free_shipping_method] );

return $rates;

}

Upvotes: 1

Views: 126

Answers (1)

Ibtekarlabs
Ibtekarlabs

Reputation: 43

I ended up adding the service like 'assembly' as a choice that comes with the product

my code below

/**
 ** Display Fields
 */
add_action('woocommerce_product_options_shipping', 'woocommerce_product_custom_product_service');
function woocommerce_product_custom_product_service()
{
    global $woocommerce, $post;
    echo '<div class="product_custom_field"><span class="wrap">';
    woocommerce_wp_text_input(
        array(
            'id' => '_custom_product_service_label',
            'placeholder' => 'Service Label',
            'label' => __('Custom Service', 'woocommerce'),

        )
    );
    woocommerce_wp_text_input(
        array(
            'id' => '_custom_product_service_fees',
            'placeholder' => 'Service Fees',
            'type' => 'number',
            'custom_attributes' => array(
                'step' => 'any',
                'min' => '0'
            )
        )
    );
echo '</span></div>';
}

/**
 ** Save Fields
 */ 
add_action('woocommerce_process_product_meta', 'woocommerce_product_custom_product_service_save');

function woocommerce_product_custom_product_service_save($post_id)
{
    $woocommerce_custom_product_service_label = $_POST['_custom_product_service_label'];
    $woocommerce_custom_product_service_fees = $_POST['_custom_product_service_fees'];

    if (!empty($woocommerce_custom_product_service_label) && !empty($woocommerce_custom_product_service_fees)){
        update_post_meta($post_id, '_custom_product_service_label', esc_attr($woocommerce_custom_product_service_label));
        update_post_meta($post_id, '_custom_product_service_fees', esc_attr($woocommerce_custom_product_service_fees));
    }elseif(empty($woocommerce_custom_product_service_label) && empty($woocommerce_custom_product_service_fees)){
            update_post_meta($post_id, '_custom_product_service_label', '');
            update_post_meta($post_id, '_custom_product_service_fees', '');
        }
}





/**
 ** Product page form
 */ 
add_action('woocommerce_single_product_summary','add_custom_product_service_to_single_product', 2 );
function add_custom_product_service_to_single_product(){
    global $product;

    if( !$product->get_meta( '_custom_product_service_label' ) && !$product->get_meta( '_custom_product_service_fees' )) return;

    add_action('woocommerce_before_add_to_cart_button', 'add_custom_product_service_option', 30 );
}

function add_custom_product_service_option(){
    global $product;

    $active_price = (float) $product->get_price();
    $service_label =  $product->get_meta( '_custom_product_service_label' );
    $service_price = (float) $product->get_meta( '_custom_product_service_fees' );
    $service_price_html   = strip_tags( wc_price( wc_get_price_to_display( $product, array('price' => $service_price ) ) ) );
    $active_price_html   = wc_price( wc_get_price_to_display( $product ) );
    $disp_price_sum_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $service_price ) ) );

    echo '<div class="hidden-field">
    <p class="form-row form-row-wide" id="service_option_field" data-priority="">
    <span class="woocommerce-input-wrapper"><label class="checkbox"> ' .$service_label.' '.__("Service:", "Woocommerce") .
    ' <input type="checkbox" class="input-checkbox " name="service_option" id="service_option" value="1"> +' . $service_price_html .
    '</label></span></p>
    <input type="hidden" name="service_price" value="' . $service_price . '">
    <input type="hidden" name="active_price" value="' . $active_price . '"></div>';

    // Jquery: Update displayed price
    ?>
    <script type="text/javascript">
    jQuery(function($) {
        var cb = 'input[name="service_option"]'
            pp = 'p.price';
        // On change / select a variation
        $('form.cart').on( 'change', cb, function(){
            if( $(cb).prop('checked') === true )
                $(pp).html('<?php echo $disp_price_sum_html.__("(Assembly Included)", "Woocommerce"); ?>');
            else
                $(pp).html('<?php echo $active_price_html; ?>');
        })
    });
    </script>
    <?php
}

/**
 ** Add to Cart
 */ 
add_filter('woocommerce_add_cart_item_data', 'add_custom_product_service_data', 10, 3);
function add_custom_product_service_data( $cart_item_data, $product_id, $variation_id ) {
    if (isset($_POST['service_option']) && !empty($_POST['service_option'])) {
        $cart_item_data['new_price'] = (float) ($_POST['active_price'] + $_POST['service_price']);
        $cart_item_data['service_price'] = (float) $_POST['service_price'];
        $cart_item_data['active_price'] = (float) $_POST['active_price'];

       foreach(WC()->cart->get_cart() as $cart_item){
            if(($product_id == $cart_item['product_id']) && !empty($cart_item['service_price'])){
             $unique_key = $cart_item['unique_key'];
            break;
            }
       }
   
        if(!empty($unique_key)){
            $cart_item_data['unique_key'] = $unique_key;
        }else{
            $cart_item_data['unique_key'] = md5(microtime().rand());
        }

    return $cart_item_data;
}}


/**
 ** Set the new calculated cart item price
 */  
add_action('woocommerce_before_calculate_totals', 'add_custom_product_service_custom_price', 20, 1);

function add_custom_product_service_custom_price($cart) {
    if (is_admin() && !defined('DOING_AJAX'))
        return;

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

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


/**
 ** Display in Cart
 */ 
add_filter('woocommerce_get_item_data', 'display_custom_product_service_item_data', 10, 2);

function display_custom_product_service_item_data($cart_item_data, $cart_item) {
        $_product = new WC_Product( $cart_item['product_id'] );
        $service_label = $_product->get_meta( '_custom_product_service_label' );
    if (isset($cart_item['service_price'])) {
        //$service_label = get_post_meta( $cart_item['product_id'], '_custom_product_service_label' );
        $cart_item_data[] = array(
            'name' => $service_label .__(" Service Fees", "woocommerce"),
            'value' => strip_tags( '+ ' . wc_price( wc_get_price_to_display( $cart_item['data'], array('price' => $cart_item['service_price'] ) ) ) )
        );
    }elseif(!empty($service_label)){
             $cart_item_data[] = array(
            'name' => $service_label .__(" Service Not Included", "woocommerce"),
           'value' => strip_tags( '+ ' . wc_price( wc_get_price_to_display( $cart_item['data'], array('price' => $cart_item['service_price'] ) ) ) )
        );
    }

    return $cart_item_data;
}

Upvotes: 1

Related Questions