Skip to content

Commit 9913d92

Browse files
committed
Implement Shipping Zones support
This allows for statesOrRegions limits.
1 parent ae41eec commit 9913d92

File tree

1 file changed

+118
-8
lines changed

1 file changed

+118
-8
lines changed

includes/class-wc-amazon-payments-advanced-api.php

Lines changed: 118 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,121 @@ protected static function get_client() {
127127
return self::$amazonpay_client;
128128
}
129129

130+
/**
131+
* Location type detection.
132+
*
133+
* @param object $location Location to check.
134+
* @return boolean
135+
*/
136+
private static function location_is_continent( $location ) {
137+
return 'continent' === $location->type;
138+
}
139+
140+
/**
141+
* Location type detection.
142+
*
143+
* @param object $location Location to check.
144+
* @return boolean
145+
*/
146+
private static function location_is_country( $location ) {
147+
return 'country' === $location->type;
148+
}
149+
150+
/**
151+
* Location type detection.
152+
*
153+
* @param object $location Location to check.
154+
* @return boolean
155+
*/
156+
private static function location_is_state( $location ) {
157+
return 'state' === $location->type;
158+
}
159+
160+
/**
161+
* Location type detection.
162+
*
163+
* @param object $location Location to check.
164+
* @return boolean
165+
*/
166+
private static function location_is_postcode( $location ) {
167+
return 'postcode' === $location->type;
168+
}
169+
170+
protected static function get_shipping_restrictions() {
171+
$data_store = WC_Data_Store::load( 'shipping-zone' );
172+
$raw_zones = $data_store->get_zones();
173+
$zones = array();
174+
175+
$all_continents = WC()->countries->get_continents();
176+
$all_countries = WC()->countries->get_countries();
177+
$all_states = WC()->countries->get_states();
178+
179+
$row_zone = new WC_Shipping_Zone( 0 );
180+
$methods = $row_zone->get_shipping_methods( true, 'json' );
181+
if ( ! empty( $methods ) ) {
182+
// Rest of the World has shipping methods, so we can assume we can ship to all shipping countries
183+
// Skip the whole thing
184+
$countries = WC()->countries->get_shipping_countries();
185+
if ( count( $countries ) !== count( $all_countries ) ) {
186+
foreach ( $countries as $country => $name ) {
187+
$zones[ $country ] = new stdClass(); // If we use an empty array it'll be treated as an array in JSON
188+
}
189+
return $zones;
190+
} else {
191+
return false; // No restrictions
192+
}
193+
}
194+
195+
foreach ( $raw_zones as $raw_zone ) {
196+
$zone = new WC_Shipping_Zone( $raw_zone );
197+
$methods = $zone->get_shipping_methods( true, 'json' );
198+
if ( empty( $methods ) ) {
199+
continue; // If no shipping methods, we assume no support on this region
200+
}
201+
202+
$locations = $zone->get_zone_locations( 'json' );
203+
$continents = array_filter( $locations, array( __CLASS__, 'location_is_continent' ) );
204+
$countries = array_filter( $locations, array( __CLASS__, 'location_is_country' ) );
205+
$states = array_filter( $locations, array( __CLASS__, 'location_is_state' ) );
206+
$postcodes = array_filter( $locations, array( __CLASS__, 'location_is_postcode' ) ); // HARD TODO: Postcode wildcards can't be implemented afaik
207+
208+
foreach ( $continents as $location ) {
209+
foreach ( $all_continents[ $location->code ]['countries'] as $country ) {
210+
if ( ! isset( $zones[ $country ] ) ) {
211+
$zones[ $country ] = new stdClass(); // If we use an empty array it'll be treated as an array in JSON
212+
}
213+
}
214+
}
215+
216+
foreach ( $countries as $location ) {
217+
$country = $location->code;
218+
if ( ! isset( $zones[ $country ] ) ) {
219+
$zones[ $country ] = new stdClass(); // If we use an empty array it'll be treated as an array in JSON
220+
}
221+
}
222+
223+
foreach ( $states as $location ) {
224+
$location_codes = explode( ':', $location->code );
225+
$country = strtoupper( $location_codes[0] );
226+
$state = $location_codes[1];
227+
if ( ! isset( $zones[ $country ] ) ) {
228+
$zones[ $country ] = new stdClass(); // If we use an empty array it'll be treated as an array in JSON
229+
}
230+
231+
if ( ! isset( $zones[ $country ]->statesOrRegions ) ) {
232+
$zones[ $country ]->statesOrRegions = array();
233+
}
234+
235+
$zones[ $country ]->statesOrRegions[] = $state;
236+
if ( 'US' !== $country ) {
237+
$zones[ $country ]->statesOrRegions[] = $all_states[ $country ][ $state ];
238+
}
239+
}
240+
}
241+
242+
return $zones;
243+
}
244+
130245
protected static function create_checkout_session_params( $redirect_url = null ) {
131246

132247
$settings = self::get_settings();
@@ -142,13 +257,8 @@ protected static function create_checkout_session_params( $redirect_url = null )
142257
),
143258
);
144259

145-
$countries = WC()->countries->get_shipping_countries();
146-
$all_countries = WC()->countries->get_countries();
147-
if ( count( $countries ) !== count( $all_countries ) ) {
148-
$restrictions = array();
149-
foreach ( $countries as $country => $name ) {
150-
$restrictions[ $country ] = new stdClass(); // If we use an empty array it'll be treated as an array in JSON
151-
}
260+
$restrictions = self::get_shipping_restrictions();
261+
if ( $restrictions ) {
152262
$payload['deliverySpecifications'] = array(
153263
'addressRestrictions' => array(
154264
'type' => 'Allowed',
@@ -157,7 +267,7 @@ protected static function create_checkout_session_params( $redirect_url = null )
157267
);
158268
}
159269

160-
$payload = wp_json_encode( $payload, JSON_UNESCAPED_SLASHES );
270+
$payload = wp_json_encode( $payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
161271

162272
return $payload;
163273

0 commit comments

Comments
 (0)