# Product Create/Update Flow Audit Report **Date:** 2026-01-29 **Scope:** Full trace of product creation, update, SKU validation, variation handling, virtual product setting, and customer-facing add-to-cart --- ## Executive Summary **Total Issues Found: 4** - **CRITICAL:** 2 - **WARNING:** 1 - **INFO:** 1 --- ## Critical Issues ### 🔴 Issue #1: SKU Validation Blocks Variation Updates **Severity:** CRITICAL **Location:** [ProductsController.php#L1009](file:///Users/dwindown/Local%20Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Api/ProductsController.php#L1009) **Problem:** When updating a variable product, the `save_product_variations` method sets SKU unconditionally: ```php if (isset($var_data['sku'])) $variation->set_sku($var_data['sku']); ``` WooCommerce validates that SKU must be unique across all products. When updating a variation that already has that SKU, WooCommerce throws an exception because it sees the SKU as a duplicate. **Root Cause:** WooCommerce's `set_sku()` method checks for uniqueness but doesn't know the variation already owns that SKU during the update. **Fix Required:** Before setting SKU, check if the new SKU is the same as the current SKU: ```php if (isset($var_data['sku'])) { $current_sku = $variation->get_sku(); $new_sku = $var_data['sku']; // Only set if different (to avoid WC duplicate check issue) if ($current_sku !== $new_sku) { $variation->set_sku($new_sku); } } ``` --- ### 🔴 Issue #2: Variation Selection Fails (Attribute Format Mismatch) **Severity:** CRITICAL **Location:** - Backend: [ShopController.php#L363-365](file:///Users/dwindown/Local%20Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Frontend/ShopController.php#L363) - Frontend: [Product/index.tsx#L97-127](file:///Users/dwindown/Local%20Sites/woonoow/app/public/wp-content/plugins/woonoow/customer-spa/src/pages/Product/index.tsx#L97) **Problem:** "Please select all product options" error appears even when a variation is selected. **Root Cause:** Format mismatch between backend API and frontend matching logic: | Source | Format | Example | |--------|--------|---------| | API `variations.attributes` | `attribute_pa_color: "red"` | Lowercase, prefixed | | API `attributes` | `name: "Color"` | Human-readable | | Frontend `selectedAttributes` | `Color: "Red"` | Human-readable, case preserved | The matching logic at lines 100-120 has complex normalization but may fail at edge cases: - Taxonomy attributes use `pa_` prefix (e.g., `attribute_pa_color`) - Custom attributes use direct prefix (e.g., `attribute_size`) - The comparison normalizes both sides but attribute names in `selectedAttributes` are human-readable labels **Fix Required:** Improve variation matching by normalizing attribute names consistently: ```typescript // In find matching variation logic: const variation = (product.variations as any[]).find(v => { return Object.entries(selectedAttributes).every(([attrName, attrValue]) => { const normalizedAttrName = attrName.toLowerCase(); const normalizedValue = attrValue.toLowerCase(); // Try all possible attribute key formats const possibleKeys = [ `attribute_${normalizedAttrName}`, `attribute_pa_${normalizedAttrName}`, normalizedAttrName ]; for (const key of possibleKeys) { if (key in v.attributes) { return v.attributes[key].toLowerCase() === normalizedValue; } } return false; }); }); ``` --- ## Warning Issues ### 🟡 Issue #3: Virtual Product Setting May Not Persist for Variable Products **Severity:** WARNING **Location:** [ProductsController.php#L496-498](file:///Users/dwindown/Local%20Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Api/ProductsController.php#L496) **Problem:** User reports cannot change product to virtual. Investigation shows: - Admin-SPA correctly sends `virtual: true` in payload - Backend `update_product` correctly calls `$product->set_virtual()` - However, for variable products, virtual status may need to be set on each variation **Observation:** The backend code at lines 496-498 handles virtual correctly: ```php if (isset($data['virtual'])) { $product->set_virtual((bool) $data['virtual']); } ``` **Potential Issue:** WooCommerce may ignore parent product's virtual flag for variable products. Each variation may need to be set as virtual individually. **Fix Required:** When saving variations, also propagate virtual flag: ```php // In save_product_variations, after setting other fields: if ($product->is_virtual()) { $variation->set_virtual(true); } ``` --- ## Info Issues ### â„šī¸ Issue #4: Missing Error Handling in Add-to-Cart Backend **Severity:** INFO **Location:** [CartController.php#L202-203](file:///Users/dwindown/Local%20Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Api/Controllers/CartController.php#L202) **Observation:** When `add_to_cart()` returns false, the error message is generic: ```php if (!$cart_item_key) { return new WP_Error('add_to_cart_failed', 'Failed to add product to cart', ['status' => 400]); } ``` WooCommerce may have more specific notices in `wc_notice` stack that could provide better error messages. **Enhancement:** ```php if (!$cart_item_key) { $notices = wc_get_notices('error'); $message = !empty($notices) ? $notices[0]['notice'] : 'Failed to add product to cart'; wc_clear_notices(); return new WP_Error('add_to_cart_failed', $message, ['status' => 400]); } ``` --- ## Code Flow Summary ### Product Update Flow ```mermaid sequenceDiagram Admin SPA->>ProductsController: PUT /products/{id} ProductsController->>WC_Product: set_name, set_sku, etc. ProductsController->>WC_Product: set_virtual, set_downloadable ProductsController->>ProductsController: save_product_variations() ProductsController->>WC_Product_Variation: set_sku (BUG: no duplicate check) WC_Product_Variation-->>WooCommerce: validate_sku() WooCommerce-->>ProductsController: Exception (duplicate SKU) ``` ### Add-to-Cart Flow ```mermaid sequenceDiagram Customer SPA->>Product Page: Select variation Product Page->>useState: selectedAttributes = {Color: "Red"} Product Page->>useEffect: Find matching variation Note right of Product Page: Mismatch: API has attribute_pa_color Product Page-->>useState: selectedVariation = null Customer->>Product Page: Click Add to Cart Product Page->>Customer: "Please select all product options" ``` --- ## Files to Modify | File | Change | |------|--------| | `ProductsController.php` | Fix SKU check in `save_product_variations` | | `Product/index.tsx` | Fix variation matching logic | | `ProductsController.php` | Propagate virtual to variations | | `CartController.php` | (Optional) Improve error messages | --- ## Verification Plan After fixes: 1. Create a variable product with SKU on variations 2. Edit the product without changing SKU → should save successfully 3. Add products to cart → verify variation selection works 4. Test virtual product setting on simple and variable products