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
This commit is contained in:
156
includes/Api/TaxController.php
Normal file
156
includes/Api/TaxController.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user