Code for shipping per product id, split orders for both initial order and recurring order with shipping methods triggered woocommerce

Viewed 28

Any suggestions would be helpful on this...

item 1: if the shipping method "local delivery" doesn't fall in the range of customer address or shipping address (shipping zones by drawing map), then I need for the shipping to fall back to local pickup or no shipping available for certain product_id items.

item 2: recurring totals are showing duplicate shipping and the wrong options I would like the recurring orders to only show options of shipping for flat rate or local pickup, and delivery if available in their area based on "shipping zones by drawing map".

the reasoning for this is we have products that are only local pickup or delivery and cannot be shipped. We also provide subscription orders, so some things seem to be conflicting in the code and are not calling certain items needed as well as duplications on the recurring subscriptions.

Below is the code:

// SETTINGS BELOW: Custom function that handle your settings
function custom_shipping_settings() {
    return array(
        'product_ids' => array( 1501, 1504 ), // Define the products that need to be in a separated shipping package (local delivery)
        'allowed_zones_ids' => array(5,9), // Define the allowed zones IDs
    );
}


// Splitting cart items into 2 shipping packages
add_filter( 'woocommerce_cart_shipping_packages', 'split_shipping_packages' );
function split_shipping_packages( $packages ) {
    extract(custom_shipping_settings()); // Load and extract settings

    $customer       = WC()->customer;
    $destination    = array(
        'country'   => $customer->get_shipping_country(),
        'state'     => $customer->get_shipping_state(),
        'postcode'  => $customer->get_shipping_postcode(),
        'city'      => $customer->get_shipping_city(),
        'address'   => $customer->get_shipping_address(),
        'address_2' => $customer->get_shipping_address_2()
    );
    $package_dest   = array( 'destination' => $destination );
    $zone           = wc_get_shipping_zone( $package_dest );

    if ( ! in_array( $zone->get_id(), $allowed_zones_ids ) ) {

        // Reset packages and initialize variables
        $packages = $splitted_cart_items = array();

        // Loop through cart items
        foreach ( WC()->cart->get_cart() as $item_key => $item ) {
            if ( is_a($item['data'], 'WC_Product') && $item['data']->needs_shipping() ) {
                if ( ! array_intersect( array($item['product_id'], $item['variation_id']), $product_ids ) ) {
                    $splitted_cart_items[0][$item_key] = $item; // Regular items
                } else {
                    $splitted_cart_items[1][$item_key] = $item; // Special separated items
                }
            }
        }

        if ( count($splitted_cart_items) < 2 )
            return $packages;

        // Loop through spitted cart items
        foreach ( $splitted_cart_items as $key => $items ) {
            // Set each cart items group in a shipping package
            $packages[$key] = array(
                'contents'        => $items,
                'contents_cost'   => array_sum( wp_list_pluck( $items, 'line_total' ) ),
                'applied_coupons' => WC()->cart->get_applied_coupons(),
                'user'            => array( 'ID' => get_current_user_id() ),
                'destination'     => $destination,
            );
        }
    }
    return $packages;
}

// Force local pickup for specific splitted shipping package (for the defined products)
add_filter( 'woocommerce_package_rates', 'filter_wc_package_rates', 10, 2 );
function filter_wc_package_rates( $rates, $package ) {
    extract(custom_shipping_settings()); // Load and extract settings

    $zone  = wc_get_shipping_zone( $package ); // Get current shipping zone
    $found = false;

    // For all others shipping zones than allowed zones
    if ( ! in_array( $zone->get_id(), $allowed_zones_ids ) ) {
        // Loop through cart items for current shipping package
        foreach( $package['contents'] as $item ) {
            // Look for defined specific product Ids
            if ( array_intersect( array($item['product_id'], $item['variation_id']), $product_ids ) ) {
                $found = true; // Flag as found
                break; // Stop the loop
            }
        }

        // If any defined product is in cart
        if ( $found ) {
            // Loop through shipping rates
            foreach ( $rates as $rate_key => $rate ) {
                // Hide all shipping methods keeping "Local pickup"
                if ( 'local_pickup' !== $rate->method_id ) {
                    unset( $rates[$rate_key] );
                }
            }
        }
    }
    return $rates;
}

As you can see in the image link it shows delivery even though that option isn't available. This is on the reocurring order as well. Any help would be very welcomed.

https://snipboard.io/VO2Mhy.jpg https://snipboard.io/fwqdxn.jpg

0 Answers
Related