Check if the order needs shipping before validating shipping address (#51630)
This commit is contained in:
parent
442cb4e81b
commit
94460bb394
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Fix an issue where virtual products could not be purchased when using the Additional Fields API
|
|
@ -201,6 +201,7 @@ class Checkout extends AbstractCartRoute {
|
|||
|
||||
$address_fields = $this->additional_fields_controller->get_fields_for_location( 'address' );
|
||||
if ( ! empty( $address_fields ) ) {
|
||||
$needs_shipping = WC()->cart->needs_shipping();
|
||||
foreach ( $address_fields as $field_key => $address_field ) {
|
||||
if ( $address_field['required'] && ! isset( $request['billing_address'][ $field_key ] ) ) {
|
||||
throw new RouteException(
|
||||
|
@ -210,7 +211,7 @@ class Checkout extends AbstractCartRoute {
|
|||
400
|
||||
);
|
||||
}
|
||||
if ( $address_field['required'] && ! isset( $request['shipping_address'][ $field_key ] ) ) {
|
||||
if ( $needs_shipping && $address_field['required'] && ! isset( $request['shipping_address'][ $field_key ] ) ) {
|
||||
throw new RouteException(
|
||||
'woocommerce_rest_checkout_missing_required_field',
|
||||
/* translators: %s: is the field label */
|
||||
|
|
|
@ -72,6 +72,24 @@ class AdditionalFields extends MockeryTestCase {
|
|||
'weight' => 10,
|
||||
)
|
||||
),
|
||||
$fixtures->get_simple_product(
|
||||
array(
|
||||
'name' => 'Virtual Test Product 3',
|
||||
'stock_status' => 'instock',
|
||||
'regular_price' => 10,
|
||||
'weight' => 10,
|
||||
'virtual' => true,
|
||||
)
|
||||
),
|
||||
$fixtures->get_simple_product(
|
||||
array(
|
||||
'name' => 'Downloadable Test Product 4',
|
||||
'stock_status' => 'instock',
|
||||
'regular_price' => 10,
|
||||
'weight' => 10,
|
||||
'downloadable' => true,
|
||||
)
|
||||
),
|
||||
);
|
||||
$this->reset_session();
|
||||
}
|
||||
|
@ -1682,6 +1700,91 @@ class AdditionalFields extends MockeryTestCase {
|
|||
$this->assertFalse( $this->controller->is_field( $id ), \sprintf( '%s is still registered', $id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures an order for a virtual product can be placed without a shipping address, but an order for a downloadable
|
||||
* non-virtual cannot.
|
||||
*/
|
||||
public function test_place_virtual_downloadable_product_order() {
|
||||
WC()->cart->empty_cart();
|
||||
WC()->cart->add_to_cart( $this->products[2]->get_id(), 2 );
|
||||
$id = 'plugin-namespace/my-required-field';
|
||||
$label = 'My Required Field';
|
||||
\woocommerce_register_additional_checkout_field(
|
||||
array(
|
||||
'id' => $id,
|
||||
'label' => $label,
|
||||
'location' => 'address',
|
||||
'type' => 'text',
|
||||
'required' => true,
|
||||
)
|
||||
);
|
||||
|
||||
$request = new \WP_REST_Request( 'POST', '/wc/store/v1/checkout' );
|
||||
$request->set_header( 'Nonce', wp_create_nonce( 'wc_store_api' ) );
|
||||
$request->set_body_params(
|
||||
array(
|
||||
'billing_address' => (object) array(
|
||||
'first_name' => 'test',
|
||||
'last_name' => 'test',
|
||||
'company' => '',
|
||||
'address_1' => 'test',
|
||||
'address_2' => '',
|
||||
'city' => 'test',
|
||||
'state' => '',
|
||||
'postcode' => 'cb241ab',
|
||||
'country' => 'GB',
|
||||
'phone' => '',
|
||||
'email' => 'testaccount@test.com',
|
||||
'plugin-namespace/gov-id' => 'gov id',
|
||||
'plugin-namespace/my-required-field' => 'req. field',
|
||||
),
|
||||
'payment_method' => 'bacs',
|
||||
'additional_fields' => array(
|
||||
'plugin-namespace/job-function' => 'engineering',
|
||||
),
|
||||
)
|
||||
);
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$this->assertEquals( 200, $response->get_status(), print_r( $data, true ) );
|
||||
|
||||
// Test with downloadable, but not virtual product.
|
||||
WC()->cart->empty_cart();
|
||||
WC()->cart->add_to_cart( $this->products[3]->get_id(), 2 );
|
||||
|
||||
$request = new \WP_REST_Request( 'POST', '/wc/store/v1/checkout' );
|
||||
$request->set_header( 'Nonce', wp_create_nonce( 'wc_store_api' ) );
|
||||
$request->set_body_params(
|
||||
array(
|
||||
'billing_address' => (object) array(
|
||||
'first_name' => 'test',
|
||||
'last_name' => 'test',
|
||||
'company' => '',
|
||||
'address_1' => 'test',
|
||||
'address_2' => '',
|
||||
'city' => 'test',
|
||||
'state' => '',
|
||||
'postcode' => 'cb241ab',
|
||||
'country' => 'GB',
|
||||
'phone' => '',
|
||||
'email' => 'testaccount@test.com',
|
||||
'plugin-namespace/gov-id' => 'gov id',
|
||||
'plugin-namespace/my-required-field' => 'req. field',
|
||||
),
|
||||
'payment_method' => 'bacs',
|
||||
'additional_fields' => array(
|
||||
'plugin-namespace/job-function' => 'engineering',
|
||||
),
|
||||
)
|
||||
);
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
// The product is downloadable, but not virtual, so should still require a shipping address.
|
||||
$this->assertEquals( 400, $response->get_status(), print_r( $data, true ) );
|
||||
$this->assertEquals( 'There was a problem with the provided shipping address: Government ID is required', $data['message'], print_r( $data, true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures an error is returned when required fields in Contact are missing.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue