diff --git a/admin-spa/src/routes/Orders/partials/OrderForm.tsx b/admin-spa/src/routes/Orders/partials/OrderForm.tsx index f6fd754..fd84203 100644 --- a/admin-spa/src/routes/Orders/partials/OrderForm.tsx +++ b/admin-spa/src/routes/Orders/partials/OrderForm.tsx @@ -185,26 +185,43 @@ export default function OrderForm({ enabled: items.length > 0, }); + // Get effective shipping address (use billing if not shipping to different address) + const effectiveShippingAddress = React.useMemo(() => { + if (shipDiff) { + return shippingData; + } + // Use billing address + return { + country: bCountry, + state: bState, + city: bCity, + postcode: bPost, + address_1: bAddr1, + address_2: '', + }; + }, [shipDiff, shippingData, bCountry, bState, bCity, bPost, bAddr1]); + // Check if shipping address is complete enough to calculate rates const isShippingAddressComplete = React.useMemo(() => { + const addr = effectiveShippingAddress; // Need at minimum: country, state (if applicable), city - if (!shippingData.country) return false; - if (!shippingData.city) return false; + if (!addr.country) return false; + if (!addr.city) return false; // If country has states, require state - const countryStates = states[shippingData.country]; - if (countryStates && Object.keys(countryStates).length > 0 && !shippingData.state) { + const countryStates = states[addr.country]; + if (countryStates && Object.keys(countryStates).length > 0 && !addr.state) { return false; } return true; - }, [shippingData.country, shippingData.state, shippingData.city, states]); + }, [effectiveShippingAddress, states]); // Calculate shipping rates dynamically const { data: shippingRates, isLoading: shippingLoading } = useQuery({ - queryKey: ['shipping-rates', items.map(i => ({ product_id: i.product_id, qty: i.qty })), shippingData.country, shippingData.state, shippingData.city, shippingData.postcode, shippingData.address_1], + queryKey: ['shipping-rates', items.map(i => ({ product_id: i.product_id, qty: i.qty })), effectiveShippingAddress.country, effectiveShippingAddress.state, effectiveShippingAddress.city, effectiveShippingAddress.postcode, effectiveShippingAddress.address_1], queryFn: async () => { return api.post('/shipping/calculate', { items: items.map(i => ({ product_id: i.product_id, qty: i.qty })), - shipping: shippingData, + shipping: effectiveShippingAddress, }); }, enabled: isShippingAddressComplete && items.length > 0, diff --git a/includes/Api/OrdersController.php b/includes/Api/OrdersController.php index 01e7731..cae3c0a 100644 --- a/includes/Api/OrdersController.php +++ b/includes/Api/OrdersController.php @@ -1293,12 +1293,25 @@ class OrdersController { // Set customer shipping address if ( ! empty( $shipping ) ) { - WC()->customer->set_shipping_country( $shipping['country'] ?? '' ); - WC()->customer->set_shipping_state( $shipping['state'] ?? '' ); - WC()->customer->set_shipping_postcode( $shipping['postcode'] ?? '' ); - WC()->customer->set_shipping_city( $shipping['city'] ?? '' ); - WC()->customer->set_shipping_address( $shipping['address_1'] ?? '' ); - WC()->customer->set_shipping_address_2( $shipping['address_2'] ?? '' ); + $country = $shipping['country'] ?? ''; + $state = $shipping['state'] ?? ''; + $postcode = $shipping['postcode'] ?? ''; + $city = $shipping['city'] ?? ''; + $address_1 = $shipping['address_1'] ?? ''; + $address_2 = $shipping['address_2'] ?? ''; + + WC()->customer->set_shipping_country( $country ); + WC()->customer->set_shipping_state( $state ); + WC()->customer->set_shipping_postcode( $postcode ); + WC()->customer->set_shipping_city( $city ); + WC()->customer->set_shipping_address( $address_1 ); + WC()->customer->set_shipping_address_2( $address_2 ); + + // Also set billing for tax calculation context + WC()->customer->set_billing_country( $country ); + WC()->customer->set_billing_state( $state ); + WC()->customer->set_billing_postcode( $postcode ); + WC()->customer->set_billing_city( $city ); } // Calculate shipping