diff --git a/includes/API/Orders_Controller.php b/includes/API/Orders_Controller.php index c77cc4b9..b641d058 100644 --- a/includes/API/Orders_Controller.php +++ b/includes/API/Orders_Controller.php @@ -536,6 +536,7 @@ public function wcpos_tax_based_on( $value, $option ) { // try to get POS tax settings from order meta $raw_data = $this->wcpos_request->get_json_params(); + if ( isset( $raw_data['meta_data'] ) ) { foreach ( $raw_data['meta_data'] as $meta ) { if ( '_woocommerce_pos_tax_based_on' == $meta['key'] ) { diff --git a/tests/includes/API/Test_Order_Taxes.php b/tests/includes/API/Test_Order_Taxes.php new file mode 100644 index 00000000..5c157e07 --- /dev/null +++ b/tests/includes/API/Test_Order_Taxes.php @@ -0,0 +1,208 @@ +endpoint = new Orders_Controller(); + update_option( 'woocommerce_calc_taxes', 'yes' ); + + // Set default address + // update_option( 'woocommerce_default_country', 'GB' ); + + /** + * Init Taxes + * + * use WooCommerce Tax Dummy Data + */ + TaxHelper::create_tax_rate( + array( + 'country' => 'GB', + 'rate' => '20.000', + 'name' => 'VAT', + 'priority' => 1, + 'compound' => true, + 'shipping' => true, + ) + ); + TaxHelper::create_tax_rate( + array( + 'country' => 'GB', + 'rate' => '5.000', + 'name' => 'VAT', + 'priority' => 1, + 'compound' => true, + 'shipping' => true, + 'class' => 'reduced-rate', + ) + ); + TaxHelper::create_tax_rate( + array( + 'country' => 'GB', + 'rate' => '0.000', + 'name' => 'VAT', + 'priority' => 1, + 'compound' => true, + 'shipping' => true, + 'class' => 'zero-rate', + ) + ); + TaxHelper::create_tax_rate( + array( + 'country' => 'US', + 'rate' => '10.000', + 'name' => 'US', + 'priority' => 1, + 'compound' => true, + 'shipping' => true, + ) + ); + TaxHelper::create_tax_rate( + array( + 'country' => 'US', + 'state' => 'AL', + 'postcode' => '12345; 123456', + 'rate' => '2.000', + 'name' => 'US AL', + 'priority' => 2, + 'compound' => true, + 'shipping' => true, + ) + ); + } + + public function tearDown(): void { + parent::tearDown(); + } + + /** + * Create a new order. + */ + public function test_create_order_with_tax(): void { + $request = $this->wp_rest_post_request( '/wcpos/v1/orders' ); + $request->set_body_params( + array( + 'payment_method' => 'pos_cash', + 'line_items' => array( + array( + 'product_id' => 1, + 'quantity' => 1, + 'price' => 10, + 'total' => '10.00', + ), + ), + 'billing' => array( + 'email' => '', + 'first_name' => '', + 'last_name' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + 'phone' => '', + ), + ) + ); + + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 201, $response->get_status() ); + + // line item taxes + $this->assertEquals( 1, \count( $data['line_items'] ) ); + $this->assertEquals( 1, \count( $data['line_items'][0]['taxes'] ) ); + $this->assertEquals( '1', $data['line_items'][0]['taxes'][0]['total'] ); + + // order taxes + $this->assertEquals( 1, \count( $data['tax_lines'] ) ); + $this->assertEquals( '1.00', $data['tax_lines'][0]['tax_total'] ); + $this->assertEquals( 'US', $data['tax_lines'][0]['label'] ); + $this->assertEquals( '10', $data['tax_lines'][0]['rate_percent'] ); + } + + /** + * Create a new order with customer billing address as tax location. + */ + public function test_create_order_with_customer_billing_address_as_tax_location(): void { + $request = $this->wp_rest_post_request( '/wcpos/v1/orders' ); + // Prepare your data as an array and then JSON-encode it + $data = array( + 'payment_method' => 'pos_cash', + 'line_items' => array( + array( + 'product_id' => 1, + 'quantity' => 1, + 'price' => 10, + 'total' => '10.00', + ), + ), + 'billing' => array( + 'email' => '', + 'first_name' => '', + 'last_name' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => 'GB', + 'phone' => '', + ), + 'meta_data' => array( + array( + 'key' => '_woocommerce_pos_tax_based_on', + 'value' => 'billing', + ), + ), + ); + + // Set the body to a JSON string + $request->set_header( 'Content-Type', 'application/json' ); + $request->set_body( wp_json_encode( $data ) ); + + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 201, $response->get_status() ); + + // check meta data + $count = 0; + $tax_based_on = ''; + + // Look for the _woocommerce_pos_uuid key in meta_data + foreach ( $data['meta_data'] as $meta ) { + if ( '_woocommerce_pos_tax_based_on' === $meta['key'] ) { + $count++; + $tax_based_on = $meta['value']; + } + } + + $this->assertEquals( 1, $count, 'There should only be one _woocommerce_pos_tax_based_on.' ); + $this->assertEquals( 'billing', $tax_based_on, 'The value of _woocommerce_pos_tax_based_on should be billing.' ); + + // line item taxes + $this->assertEquals( 1, \count( $data['line_items'] ) ); + $this->assertEquals( 1, \count( $data['line_items'][0]['taxes'] ) ); + $this->assertEquals( '2', $data['line_items'][0]['taxes'][0]['total'] ); + + // order taxes + $this->assertEquals( 1, \count( $data['tax_lines'] ) ); + $this->assertEquals( '2.00', $data['tax_lines'][0]['tax_total'] ); + $this->assertEquals( 'VAT', $data['tax_lines'][0]['label'] ); + $this->assertEquals( '20', $data['tax_lines'][0]['rate_percent'] ); + } +} diff --git a/tests/includes/API/Test_Products_Controller.php b/tests/includes/API/Test_Products_Controller.php index 6e9959c1..f4840d5b 100644 --- a/tests/includes/API/Test_Products_Controller.php +++ b/tests/includes/API/Test_Products_Controller.php @@ -464,11 +464,15 @@ public function test_product_update_decimal_quantities(): void { $product->save(); $request = $this->wp_rest_patch_request( '/wcpos/v1/products/' . $product->get_id() ); - $request->set_body_params( - array( - 'stock_quantity' => '3.85', + $request->set_header( 'Content-Type', 'application/json' ); + $request->set_body( + wp_json_encode( + array( + 'stock_quantity' => '3.85', + ) ) ); + $response = $this->server->dispatch( $request ); $data = $response->get_data(); diff --git a/tests/includes/Helpers/TaxHelper.php b/tests/includes/Helpers/TaxHelper.php index 7c6c2734..492b1037 100644 --- a/tests/includes/Helpers/TaxHelper.php +++ b/tests/includes/Helpers/TaxHelper.php @@ -13,27 +13,27 @@ class TaxHelper { * * @return int|WP_Error The newly created tax rate ID or a WP_Error object. */ - public static function create_tax_rate($data): int { + public static function create_tax_rate( $data ): int { $tax_id = WC_Tax::_insert_tax_rate( array( - 'tax_rate_country' => $data['country'], - 'tax_rate_state' => $data['state'], + 'tax_rate_country' => $data['country'] ?? '', + 'tax_rate_state' => $data['state'] ?? '', 'tax_rate' => $data['rate'], 'tax_rate_name' => $data['name'], - 'tax_rate_priority' => $data['priority'], + 'tax_rate_priority' => $data['priority'] ?? 1, 'tax_rate_compound' => $data['compound'] ? 1 : 0, 'tax_rate_shipping' => $data['shipping'] ? 1 : 0, - 'tax_rate_order' => $data['order'] ?? 0, + 'tax_rate_order' => $data['order'] ?? 1, 'tax_rate_class' => $data['class'] ?? '', ) ); - if (isset($data['postcode'])) { - WC_Tax::_update_tax_rate_postcodes($tax_id, $data['postcode']); + if ( isset( $data['postcode'] ) ) { + WC_Tax::_update_tax_rate_postcodes( $tax_id, $data['postcode'] ); } - if (isset($data['city'])) { - WC_Tax::_update_tax_rate_cities($tax_id, $data['city']); + if ( isset( $data['city'] ) ) { + WC_Tax::_update_tax_rate_cities( $tax_id, $data['city'] ); } return $tax_id; @@ -48,67 +48,77 @@ public static function create_tax_rate($data): int { * * @return bool|WP_Error True on success, WP_Error on failure. */ - public static function delete_tax_rate(int $tax_rate_id) { - return WC_Tax::_delete_tax_rate($tax_rate_id); + public static function delete_tax_rate( int $tax_rate_id ) { + return WC_Tax::_delete_tax_rate( $tax_rate_id ); } /** * Match the sample data given by WooCommerce. */ public static function create_sample_tax_rates_GB(): array { - $id1 = self::create_tax_rate(array( - 'country' => 'GB', - 'rate' => '20.0000', - 'name' => 'VAT', - 'priority' => 1, - 'compound' => true, - 'shipping' => true, - 'class' => '', - )); - $id2 = self::create_tax_rate(array( - 'country' => 'GB', - 'rate' => '5.0000', - 'name' => 'VAT', - 'priority' => 1, - 'compound' => true, - 'shipping' => true, - 'class' => 'reduced-rate', - )); - $id3 = self::create_tax_rate(array( - 'country' => 'GB', - 'rate' => '0.0000', - 'name' => 'VAT', - 'priority' => 1, - 'compound' => true, - 'shipping' => true, - 'class' => 'zero-rate', - )); + $id1 = self::create_tax_rate( + array( + 'country' => 'GB', + 'rate' => '20.0000', + 'name' => 'VAT', + 'priority' => 1, + 'compound' => true, + 'shipping' => true, + 'class' => '', + ) + ); + $id2 = self::create_tax_rate( + array( + 'country' => 'GB', + 'rate' => '5.0000', + 'name' => 'VAT', + 'priority' => 1, + 'compound' => true, + 'shipping' => true, + 'class' => 'reduced-rate', + ) + ); + $id3 = self::create_tax_rate( + array( + 'country' => 'GB', + 'rate' => '0.0000', + 'name' => 'VAT', + 'priority' => 1, + 'compound' => true, + 'shipping' => true, + 'class' => 'zero-rate', + ) + ); - return array($id1, $id2, $id3); + return array( $id1, $id2, $id3 ); } public static function create_sample_tax_rates_US(): array { - $id1 = self::create_tax_rate(array( - 'country' => 'US', - 'rate' => '10.0000', - 'name' => 'US', - 'priority' => 1, - 'compound' => true, - 'shipping' => true, - 'class' => '', - )); - $id2 = self::create_tax_rate(array( - 'country' => 'US', - 'state' => 'AL', - 'postcode' => '12345; 123456', - 'rate' => '2.0000', - 'name' => 'US AL', - 'priority' => 2, - 'compound' => true, - 'shipping' => true, - 'class' => '', - )); + $id1 = self::create_tax_rate( + array( + 'country' => 'US', + 'rate' => '10.0000', + 'name' => 'US', + 'priority' => 1, + 'compound' => true, + 'shipping' => true, + 'class' => '', + ) + ); + $id2 = self::create_tax_rate( + array( + 'country' => 'US', + 'state' => 'AL', + 'postcode' => '12345; 123456', + 'rate' => '2.0000', + 'name' => 'US AL', + 'priority' => 2, + 'compound' => true, + 'shipping' => true, + 'class' => '', + ) + ); - return array($id1, $id2); + return array( $id1, $id2 ); } }