# TPV-FIXES — Bug 400 Fix (pos/sales) ## Problema Error 400 en `/api/pos/sales` cuando se intenta dejar un ticket pendiente nuevamente después de recuperarlo. ## Causa Raíz Cuando se recuperan items de una venta pendiente (`listOrderItems`), el endpoint **no devuelve** `variantId` ni `productId`. El código de recuperación pone `variantId: null`. Cuando se intentaba crear una nueva venta con esos items, el backend Zod validaba que `variantId` sea UUID válido para items de tipo `stock`, causando 400. ## Solución En todos los lugares donde se envía `createSale`, convertir items sin `variantId` a **free items** (no requieren variantId). ### Archivos Modificados `project/apps/pos/src/app/(terminal)/page.tsx`: 1. **`doCheckout`** (checkout con pago): Convierte items sin `variantId` a free items 2. **`doParkSale`** (aparcar sin/com con nombre): Convierte items sin `variantId` a free items 3. **`parkAndRecover`** (aparcar y recuperar): Convierte items sin `variantId` a free items ### Código Común Agregado ```typescript // TPV-FIXES: items without variantId (recovered sales) must be sent as free items const saleItems = cart.map((item) => { if (item.kind === 'free' || !item.variantId) { return { kind: 'free' as const, name: item.name, unitPriceCents: item.unitPriceCents, quantity: item.quantity, }; } return { kind: 'stock' as const, variantId: item.variantId, quantity: item.quantity, discountCents: item.discountCents, }; }); ``` ## Testing 1. Recuperar una venta pendiente sin items en carrito → pagar → debe funcionar 2. Recuperar una venta pendiente CON items en carrito → "Dejar actual pendiente y recuperar" → debe funcionar 3. Crear carrito sin cliente → aparcar sin nombre → debe funcionar