Created ORDER_CALCULATION_PLAN.md with: - Backend endpoints documentation - Frontend implementation steps - Code examples for OrderForm.tsx - Testing checklist - Expected results Next: Implement frontend integration
5.1 KiB
5.1 KiB
Order Calculation - WooCommerce Native Implementation
✅ BACKEND COMPLETE
New Endpoints:
-
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)
- Input:
-
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
- Input:
🔄 FRONTEND TODO
1. Update OrderForm.tsx
A. Add Shipping Rate Calculation Query
// 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
// 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:
<Select value={shippingMethod} onValueChange={setShippingMethod}>
{shippings.map(s => (
<SelectItem value={s.id}>{s.title} - {s.cost}</SelectItem>
))}
</Select>
New:
<Select value={shippingMethod} onValueChange={setShippingMethod}>
{shippingRates?.methods?.map(rate => (
<SelectItem value={rate.id}>
{rate.label} - {money(rate.cost)}
</SelectItem>
))}
</Select>
D. Update Order Summary Display
Add tax breakdown:
<div className="space-y-2">
<div className="flex justify-between">
<span>Items</span>
<span>{items.length}</span>
</div>
<div className="flex justify-between">
<span>Subtotal</span>
<span>{money(orderPreview?.subtotal || 0)}</span>
</div>
{orderPreview?.shipping_total > 0 && (
<div className="flex justify-between">
<span>Shipping</span>
<span>{money(orderPreview.shipping_total)}</span>
</div>
)}
{orderPreview?.total_tax > 0 && (
<div className="flex justify-between">
<span>Tax</span>
<span>{money(orderPreview.total_tax)}</span>
</div>
)}
{orderPreview?.discount_total > 0 && (
<div className="flex justify-between text-green-600">
<span>Discount</span>
<span>-{money(orderPreview.discount_total)}</span>
</div>
)}
<div className="flex justify-between font-bold text-lg border-t pt-2">
<span>Total</span>
<span>{money(orderPreview?.total || 0)}</span>
</div>
</div>
E. Trigger Recalculation
// Refetch shipping when address changes
useEffect(() => {
if (hasPhysicalProduct && shippingData.country) {
refetchShipping();
}
}, [shippingData.country, shippingData.postcode, shippingData.state]);
📋 Implementation Steps
- ✅ Backend endpoints created
- ⏳ Add shipping rate calculation query
- ⏳ Add order preview query
- ⏳ Update shipping method dropdown to show services
- ⏳ Update order summary to show tax
- ⏳ Add loading states
- ⏳ Test with UPS Live Rates
- ⏳ 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
- Don't reinvent calculation - Use WooCommerce cart engine
- Clean up cart - Always
WC()->cart->empty_cart()after calculation - Session handling - Use
WC()->sessionfor chosen shipping method - Tax context - Set both billing and shipping addresses for accurate tax
- Live rates - May take 1-2 seconds to calculate, show loading state