diff --git a/METABOX_COMPAT.md b/METABOX_COMPAT.md index ebbed0e..cbef6c1 100644 --- a/METABOX_COMPAT.md +++ b/METABOX_COMPAT.md @@ -604,7 +604,7 @@ update_post_meta($order_id, '_tracking_number', '1234567890'); update_post_meta($order_id, '_tracking_provider', 'JNE'); ``` -**Plugin registers fields for WooNooW (optional, for better UX):** +**Plugin registers fields for WooNooW (REQUIRED for UI display):** ```php // In plugin's main file or init hook add_action('woonoow/register_meta_fields', function() { @@ -649,7 +649,7 @@ update_field('custom_field', 'value', $product_id); // Stored as: update_post_meta($product_id, 'custom_field', 'value'); ``` -**Register for WooNooW (optional):** +**Register for WooNooW (REQUIRED for UI display):** ```php add_action('woonoow/register_meta_fields', function() { \WooNooW\Compat\MetaFieldsRegistry::register_product_field('custom_field', [ @@ -666,7 +666,7 @@ add_action('woonoow/register_meta_fields', function() { - ✅ Synced with ACF - ✅ Works with both admins -### Example 3: Custom Plugin (No Registration) +### Example 3: Public Meta (Auto-Exposed, No Registration Needed) **Plugin stores data:** ```php @@ -793,10 +793,41 @@ MetaFieldsRegistry::register_order_field('_field_name', [ **For Plugin Developers:** 1. ✅ Continue using standard WP/WooCommerce meta storage -2. ✅ Optionally register fields for better UX -3. ✅ No special integration needed +2. ✅ **MUST register private meta fields** (starting with `_`) for UI display +3. ✅ Public meta (no `_`) auto-exposed, no registration needed 4. ✅ Works with both classic and WooNooW admin +**⚠️ CRITICAL: Private Meta Field Registration** + +Private meta fields (starting with `_`) **MUST be registered** to appear in WooNooW UI: + +**Why?** +- Security: Private meta is hidden by default +- Privacy: Prevents exposing sensitive data +- Control: Plugins explicitly declare what should be visible + +**The Flow:** +1. Plugin registers field → Field appears in UI (even if empty) +2. Admin inputs data → Saved to database +3. Data visible in both admins + +**Without Registration:** +- Private meta: ❌ Not exposed, not editable +- Public meta: ✅ Auto-exposed, auto-editable + +**Example:** +```php +// This field will NOT appear without registration +update_post_meta($order_id, '_tracking_number', '123'); + +// Register it to make it appear +add_action('woonoow/register_meta_fields', function() { + MetaFieldsRegistry::register_order_field('_tracking_number', [...]); +}); + +// Now admin can see and edit it, even when empty! +``` + **For WooNooW Core:** 1. ✅ Zero addon dependencies 2. ✅ Provides mechanism, not integration diff --git a/admin-spa/src/routes/Orders/partials/OrderForm.tsx b/admin-spa/src/routes/Orders/partials/OrderForm.tsx index 5c36bd3..d1b361a 100644 --- a/admin-spa/src/routes/Orders/partials/OrderForm.tsx +++ b/admin-spa/src/routes/Orders/partials/OrderForm.tsx @@ -314,11 +314,18 @@ export default function OrderForm({ ); // Calculate shipping cost + // In edit mode: use existing order shipping total (fixed unless address changes) + // In create mode: calculate from selected shipping method const shippingCost = React.useMemo(() => { + if (mode === 'edit' && initial?.totals?.shipping !== undefined) { + // Use existing shipping total from order + return Number(initial.totals.shipping) || 0; + } + // Create mode: calculate from shipping method if (!shippingMethod) return 0; const method = shippings.find(s => s.id === shippingMethod); return method ? Number(method.cost) || 0 : 0; - }, [shippingMethod, shippings]); + }, [mode, initial?.totals?.shipping, shippingMethod, shippings]); // Calculate discount from validated coupons const couponDiscount = React.useMemo(() => {