Update cart-shipping template, when using “Calculate Shipping costs for each Shops” option
As default, when using Single Shop Check-out type, WooCommerce calculates the shipping costs globally for all products in the cart, independently of the origin of the item, to what shop it belongs in the network. The used shipping rules and rates are the one’s set up on the shop being used for the check-out process. This is enough for most shop administrators, if providing a single package with all customer items.
The new functionality controlled through the Calculate Shipping costs for each Shops option, provides a way to calculate separate shipping costs for the products in the cart, grouped by the shop they belong. This is useful when each of the shops send separate packages with the purchased goods. The applied shipping rules and rates are specific to each of the shop set-up, they can be different.
The functionality works out of the box and requires an update of the theme cart-shipping.php template file to allow separate shipping selection for the shops. If the theme/child theme do not contain such file at /woocommerce/cart/cart-shipping.php it should be copied over from WooCommerce plugin ( see /templates/cart/ )
The default template appears like this, the highlighted section require updates:
//... $formatted_destination = isset( $formatted_destination ) ? $formatted_destination : WC()->countries->get_formatted_address( $package['destination'], ', ' ); $has_calculated_shipping = ! empty( $has_calculated_shipping ); $show_shipping_calculator = ! empty( $show_shipping_calculator ); $calculator_text = ''; ?> <tr class="woocommerce-shipping-totals shipping"> <th><?php echo wp_kses_post( $package_name ); ?></th> <td data-title="<?php echo esc_attr( $package_name ); ?>"> <?php if ( $available_methods ) : ?> <ul id="shipping_method" class="woocommerce-shipping-methods"> <?php foreach ( $available_methods as $method ) : ?> <li> <?php if ( 1 < count( $available_methods ) ) { printf( '<input type="radio" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" class="shipping_method" %4$s />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ), checked( $method->id, $chosen_method, false ) ); // WPCS: XSS ok. } else { printf( '<input type="hidden" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" class="shipping_method" />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ) ); // WPCS: XSS ok. } printf( '<label for="shipping_method_%1$s_%2$s">%3$s</label>', $index, esc_attr( sanitize_title( $method->id ) ), wc_cart_totals_shipping_method_label( $method ) ); // WPCS: XSS ok. do_action( 'woocommerce_after_shipping_rate', $method, $index ); ?> </li> <?php endforeach; ?> </ul> <?php if ( is_cart() ) : ?> <p class="woocommerce-shipping-destination"> <?php if ( $formatted_destination ) { //..
This is the updated code:
//... $formatted_destination = isset( $formatted_destination ) ? $formatted_destination : WC()->countries->get_formatted_address( $package['destination'], ', ' ); $has_calculated_shipping = ! empty( $has_calculated_shipping ); $show_shipping_calculator = ! empty( $show_shipping_calculator ); $calculator_text = ''; $chosen_methods = isset( WC()->session->chosen_shipping_methods[ $index ] ) ? (array)WC()->session->chosen_shipping_methods[ $index ] : array(); if ( ! empty ( $chosen_methods ) && ! is_array ( $chosen_methods ) ) $chosen_methods = (array)$chosen_methods; ?> <tr class="woocommerce-shipping-totals shipping"> <th><?php echo wp_kses_post( $package_name ); ?></th> <td data-title="<?php echo esc_attr( $package_name ); ?>"> <?php if ( $available_methods ) : if ( defined ( 'WOOGC_CALCULATE_SHIPPING_COSTS_EACH_SHOP' ) && WOOGC_CALCULATE_SHIPPING_COSTS_EACH_SHOP === TRUE ) { $content_products_blogs_map = array(); foreach ( $package['contents'] as $data) $content_products_blogs_map[ $data['blog_id']] = TRUE; foreach ( $content_products_blogs_map as $_blog_id => $found ) { $chosen_method = ''; foreach ( (array)$chosen_methods as $method ) { if ( strpos( $method, $_blog_id . "|" ) === 0 ) { $chosen_method = $method; break; } } if ( empty ( $chosen_method ) ) continue; $blog_details = get_blog_details( $_blog_id ); echo '<b>Blog '. $blog_details->blogname . '</b>'; ?> <ul id="shipping_method" class="woocommerce-shipping-methods"> <?php foreach ( $available_methods as $key => $method ) { if ( strpos( $key, $_blog_id . "|" ) !== 0 ) continue; ?> <li> <?php if ( 1 < count( $available_methods ) ) { printf( '<input type="radio" name="shipping_method[%1$d][%5$d]" data-index="%1$d" data-blog_id="%5$d" id="shipping_method_%1$d_%5$d_%2$s" value="%3$s" class="shipping_method" %4$s />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $key ), checked( $key, $chosen_method, false ), $_blog_id ); // WPCS: XSS ok. } else { printf( '<input type="hidden" name="shipping_method[%1$d][%5$d]" data-index="%1$d" data-blog_id="%5$d" id="shipping_method_%1$d_%5$d_%2$s" value="%3$s" class="shipping_method" />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $key ), Null, $_blog_id ); // WPCS: XSS ok. } printf( '<label for="shipping_method_%1$s_%4$d_%2$s">%3$s</label>', $index, esc_attr( sanitize_title( $method->id ) ), wc_cart_totals_shipping_method_label( $method ), $_blog_id ); // WPCS: XSS ok. do_action( 'woocommerce_after_shipping_rate', $method, $index ); ?> </li> <?php } ?> </ul> <?php } } else { ?> <ul id="shipping_method" class="woocommerce-shipping-methods"> <?php foreach ( $available_methods as $method ) : ?> <li> <?php if ( 1 < count( $available_methods ) ) { printf( '<input type="radio" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" class="shipping_method" %4$s />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ), checked( $method->id, $chosen_method, false ) ); // WPCS: XSS ok. } else { printf( '<input type="hidden" name="shipping_method[%1$d]" data-index="%1$d" id="shipping_method_%1$d_%2$s" value="%3$s" class="shipping_method" />', $index, esc_attr( sanitize_title( $method->id ) ), esc_attr( $method->id ) ); // WPCS: XSS ok. } printf( '<label for="shipping_method_%1$s_%2$s">%3$s</label>', $index, esc_attr( sanitize_title( $method->id ) ), wc_cart_totals_shipping_method_label( $method ) ); // WPCS: XSS ok. do_action( 'woocommerce_after_shipping_rate', $method, $index ); ?> </li> <?php endforeach; ?> </ul> <?php } ?> <?php if ( is_cart() ) : ?> <p class="woocommerce-shipping-destination"> <?php if ( $formatted_destination ) { //..
On the front side, at the cart / check-out area the shipping selection appears as following, in this example there are products from 2 different shops.