# Order Calculation - WooCommerce Native Implementation ## ✅ BACKEND COMPLETE ### New Endpoints: 1. **POST `/woonoow/v1/shipping/calculate`** - Input: `{ items: [], shipping: {} }` - Output: `{ methods: [{ id, method_id, instance_id, label, cost, taxes, meta_data }] }` - Returns live rates from UPS, FedEx, etc. - Returns service-level options (UPS Ground, UPS Express) 2. **POST `/woonoow/v1/orders/preview`** - Input: `{ items: [], billing: {}, shipping: {}, shipping_method: '', coupons: [] }` - Output: `{ subtotal, shipping_total, total_tax, total, ... }` - Calculates taxes correctly - Applies coupons - Uses WooCommerce cart engine --- ## 🔄 FRONTEND TODO ### 1. Update OrderForm.tsx #### A. Add Shipping Rate Calculation Query ```tsx // Query shipping rates when address changes const { data: shippingRates, refetch: refetchShipping } = useQuery({ queryKey: ['shipping-rates', items, shippingData], queryFn: async () => { if (!hasPhysicalProduct || !shippingData.country) return null; return api.post('/shipping/calculate', { items: items.map(i => ({ product_id: i.product_id, qty: i.qty })), shipping: shippingData, }); }, enabled: hasPhysicalProduct && !!shippingData.country, }); ``` #### B. Add Order Preview Query ```tsx // Query order preview for totals const { data: orderPreview } = useQuery({ queryKey: ['order-preview', items, bCountry, shippingData, shippingMethod, validatedCoupons], queryFn: async () => { if (items.length === 0) return null; return api.post('/orders/preview', { items: items.map(i => ({ product_id: i.product_id, qty: i.qty })), billing: { country: bCountry, state: bState, postcode: bPost, city: bCity }, shipping: shipDiff ? shippingData : undefined, shipping_method: shippingMethod, coupons: validatedCoupons.map(c => c.code), }); }, enabled: items.length > 0, }); ``` #### C. Update Shipping Method Dropdown **Current:** ```tsx ``` **New:** ```tsx ``` #### D. Update Order Summary Display **Add tax breakdown:** ```tsx
Items {items.length}
Subtotal {money(orderPreview?.subtotal || 0)}
{orderPreview?.shipping_total > 0 && (
Shipping {money(orderPreview.shipping_total)}
)} {orderPreview?.total_tax > 0 && (
Tax {money(orderPreview.total_tax)}
)} {orderPreview?.discount_total > 0 && (
Discount -{money(orderPreview.discount_total)}
)}
Total {money(orderPreview?.total || 0)}
``` #### E. Trigger Recalculation ```tsx // Refetch shipping when address changes useEffect(() => { if (hasPhysicalProduct && shippingData.country) { refetchShipping(); } }, [shippingData.country, shippingData.postcode, shippingData.state]); ``` --- ## 📋 Implementation Steps 1. ✅ Backend endpoints created 2. ⏳ Add shipping rate calculation query 3. ⏳ Add order preview query 4. ⏳ Update shipping method dropdown to show services 5. ⏳ Update order summary to show tax 6. ⏳ Add loading states 7. ⏳ Test with UPS Live Rates 8. ⏳ Test tax calculation --- ## 🎯 Expected Result ### Before: - Shipping: "UPS Live Rates - RM0.00" - Total: RM97,000 (no tax) ### After: - Shipping dropdown shows: - UPS Ground - RM15,000 - UPS Express - RM25,000 - UPS Next Day Air - RM35,000 - Order summary shows: - Subtotal: RM97,000 - Shipping: RM15,000 - Tax (11%): RM12,320 - **Total: RM124,320** --- ## 🔧 Testing Checklist - [ ] Select UPS Live Rates → Shows service options - [ ] Select UPS Ground → Updates total - [ ] Change address → Recalculates rates - [ ] Add item → Recalculates totals - [ ] Apply coupon → Updates discount and total - [ ] Tax shows 11% of subtotal + shipping - [ ] Digital products → No shipping, no shipping tax - [ ] Physical products → Shipping + tax calculated --- ## ⚠️ Important Notes 1. **Don't reinvent calculation** - Use WooCommerce cart engine 2. **Clean up cart** - Always `WC()->cart->empty_cart()` after calculation 3. **Session handling** - Use `WC()->session` for chosen shipping method 4. **Tax context** - Set both billing and shipping addresses for accurate tax 5. **Live rates** - May take 1-2 seconds to calculate, show loading state