## 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
157 lines
3.7 KiB
PHP
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;
|
|
}
|
|
}
|