Local Pickup: merge packages into a single package

This commit is contained in:
Mike Jolley 2022-10-20 16:31:37 +01:00 committed by Nadir Seghir
parent 16fa7f7b85
commit bc2a52b85d
1 changed files with 54 additions and 37 deletions

View File

@ -14,7 +14,9 @@ class ShippingController {
*/
public function init() {
add_action( 'woocommerce_load_shipping_methods', array( $this, 'register_shipping_methods' ) );
add_filter( 'woocommerce_customer_taxable_address', array( $this, 'handle_customer_taxable_address' ) );
add_filter( 'woocommerce_shipping_packages', array( $this, 'filter_shipping_packages' ) );
add_filter( 'woocommerce_local_pickup_methods', array( $this, 'filter_local_pickup_methods' ) );
add_filter( 'woocommerce_customer_taxable_address', array( $this, 'pickup_location_customer_tax_location' ) );
}
/**
@ -25,51 +27,66 @@ class ShippingController {
wc()->shipping->register_shipping_method( $pickup );
}
/**
* Disable local pickup if multiple packages are present.
*
* @param array $packages Array of shipping packages.
* @return array
*/
public function filter_shipping_packages( $packages ) {
if ( 1 === count( $packages ) ) {
return $packages;
}
foreach ( $packages as $package_id => $package ) {
$package_rates = $package['rates'];
foreach ( $package_rates as $rate_id => $rate ) {
$method_id = $rate->get_method_id();
if ( 'pickup_location' === $method_id ) {
unset( $packages[ $package_id ]['rates'][ $rate_id ] );
}
}
}
return $packages;
}
/**
* Declares the Pickup Location shipping method as being a Local Pickup method.
*
* @param array $methods Shipping method ids.
* @return array
*/
public function filter_local_pickup_methods( $methods ) {
$methods[] = 'pickup_location';
return $methods;
}
/**
* Filter the location used for taxes based on the chosen pickup location.
*
* @param array $address Location args.
* @return array
*/
public function handle_customer_taxable_address( $address ) {
$controller = new CartController();
$packages = $controller->get_shipping_packages( false );
$selected_rates = wc()->session->get( 'chosen_shipping_methods', array() );
$pickup_locations = get_option( 'pickup_location_pickup_locations', [] );
public function pickup_location_customer_tax_location( $address ) {
// We only need to select from the first package, since pickup_location only supports a single package.
$chosen_method = current( WC()->session->get( 'chosen_shipping_methods', array() ) ) ?? '';
$chosen_method_id = explode( ':', $chosen_method )[0];
$chosen_method_instance = explode( ':', $chosen_method )[1] ?? 0;
if ( empty( $packages ) || empty( $selected_rates ) || empty( $pickup_locations ) ) {
return $address;
}
if ( $chosen_method_id && true === apply_filters( 'woocommerce_apply_base_tax_for_local_pickup', true ) && 'pickup_location' === $chosen_method_id ) {
$pickup_locations = get_option( 'pickup_location_pickup_locations', [] );
$location_ids = [];
// Require pickup for all packages.
foreach ( $packages as $package_id => $package ) {
$selected_rate = $selected_rates[ $package_id ] ?? '';
$method_id = explode( ':', $selected_rate )[0];
if ( 'pickup_location' !== $method_id ) {
return $address;
if ( ! empty( $pickup_locations[ $chosen_method_instance ] ) && ! empty( $pickup_locations[ $chosen_method_instance ]['address']['country'] ) ) {
$address = array(
$pickup_locations[ $chosen_method_instance ]['address']['country'],
$pickup_locations[ $chosen_method_instance ]['address']['state'],
$pickup_locations[ $chosen_method_instance ]['address']['postcode'],
$pickup_locations[ $chosen_method_instance ]['address']['city'],
);
}
$location_ids[] = explode( ':', $selected_rate )[1] ?? null;
}
$location_ids = array_unique( $location_ids );
if ( count( $location_ids ) > 1 ) {
return $address;
}
$location_id = $location_ids[0];
if ( ! empty( $pickup_locations[ $location_id ] ) && ! empty( $pickup_locations[ $location_id ]['address']['country'] ) ) {
return array(
$pickup_locations[ $location_id ]['address']['country'],
$pickup_locations[ $location_id ]['address']['state'],
$pickup_locations[ $location_id ]['address']['postcode'],
$pickup_locations[ $location_id ]['address']['city'],
);
}
return $address;