Files
WooNooW/includes/Api/TaxController.php
dwindown 603d94b73c feat: Tax settings + unified addon guide + Biteship spec
## 1. Created BITESHIP_ADDON_SPEC.md 
- Complete plugin specification
- Database schema, API endpoints
- WooCommerce integration
- React components
- Implementation timeline

## 2. Merged Addon Documentation 
Created ADDON_DEVELOPMENT_GUIDE.md (single source of truth):
- Merged ADDON_INJECTION_GUIDE.md + ADDON_HOOK_SYSTEM.md
- Two addon types: Route Injection + Hook System
- Clear examples for each type
- Best practices and troubleshooting
- Deleted old documents

## 3. Tax Settings 
Frontend (admin-spa/src/routes/Settings/Tax.tsx):
- Enable/disable tax calculation toggle
- Display standard/reduced/zero tax rates
- Show tax options (prices include tax, based on, display)
- Link to WooCommerce for advanced config
- Clean, simple UI

Backend (includes/Api/TaxController.php):
- GET /settings/tax - Fetch tax settings
- POST /settings/tax/toggle - Enable/disable taxes
- Fetches rates from woocommerce_tax_rates table
- Clears WooCommerce cache on update

## 4. Advanced Local Pickup - TODO
Will be simple: Admin adds multiple pickup locations

## Key Decisions:
 Hook system = No hardcoding, zero coupling
 Tax settings = Simple toggle + view, advanced in WC
 Single addon guide = One source of truth

Next: Advanced Local Pickup locations
2025-11-09 23:13:52 +07:00

157 lines
3.7 KiB
PHP

<?php
/**
* Tax Settings REST API Controller
*
* @package WooNooW
*/
namespace WooNooW\Api;
use WP_REST_Controller;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;
class TaxController extends WP_REST_Controller {
/**
* Register routes
*/
public function register_routes() {
$namespace = 'woonoow/v1';
// Get tax settings
register_rest_route(
$namespace,
'/settings/tax',
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_settings' ),
'permission_callback' => array( $this, 'check_permission' ),
)
);
// Toggle tax calculation
register_rest_route(
$namespace,
'/settings/tax/toggle',
array(
'methods' => WP_REST_Server::CREATABLE,
'callback' => array( $this, 'toggle_tax' ),
'permission_callback' => array( $this, 'check_permission' ),
'args' => array(
'enabled' => array(
'required' => true,
'type' => 'boolean',
'sanitize_callback' => 'rest_sanitize_boolean',
),
),
)
);
}
/**
* Check permission
*/
public function check_permission() {
return current_user_can( 'manage_woocommerce' );
}
/**
* Get tax settings
*/
public function get_settings( WP_REST_Request $request ) {
try {
$settings = array(
'calc_taxes' => get_option( 'woocommerce_calc_taxes', 'no' ),
'prices_include_tax' => get_option( 'woocommerce_prices_include_tax', 'no' ),
'tax_based_on' => get_option( 'woocommerce_tax_based_on', 'shipping' ),
'tax_display_shop' => get_option( 'woocommerce_tax_display_shop', 'excl' ),
'tax_display_cart' => get_option( 'woocommerce_tax_display_cart', 'excl' ),
'standard_rates' => $this->get_tax_rates( 'standard' ),
'reduced_rates' => $this->get_tax_rates( 'reduced-rate' ),
'zero_rates' => $this->get_tax_rates( 'zero-rate' ),
);
return new WP_REST_Response( $settings, 200 );
} catch ( \Exception $e ) {
return new WP_REST_Response(
array(
'error' => 'fetch_failed',
'message' => $e->getMessage(),
),
500
);
}
}
/**
* Toggle tax calculation
*/
public function toggle_tax( WP_REST_Request $request ) {
try {
$enabled = $request->get_param( 'enabled' );
$value = $enabled ? 'yes' : 'no';
update_option( 'woocommerce_calc_taxes', $value );
// Clear WooCommerce cache
\WC_Cache_Helper::invalidate_cache_group( 'taxes' );
\WC_Cache_Helper::get_transient_version( 'shipping', true );
return new WP_REST_Response(
array(
'success' => true,
'enabled' => $enabled,
'message' => $enabled
? __( 'Tax calculation enabled', 'woonoow' )
: __( 'Tax calculation disabled', 'woonoow' ),
),
200
);
} catch ( \Exception $e ) {
return new WP_REST_Response(
array(
'error' => 'update_failed',
'message' => $e->getMessage(),
),
500
);
}
}
/**
* Get tax rates for a specific class
*/
private function get_tax_rates( $tax_class ) {
global $wpdb;
$rates = $wpdb->get_results(
$wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates
WHERE tax_rate_class = %s
ORDER BY tax_rate_order ASC",
$tax_class
)
);
$formatted_rates = array();
foreach ( $rates as $rate ) {
$formatted_rates[] = array(
'id' => $rate->tax_rate_id,
'country' => $rate->tax_rate_country,
'state' => $rate->tax_rate_state,
'rate' => $rate->tax_rate,
'name' => $rate->tax_rate_name,
'priority' => $rate->tax_rate_priority,
'compound' => $rate->tax_rate_compound,
'shipping' => $rate->tax_rate_shipping,
);
}
return $formatted_rates;
}
}