Salida · consolidación · diseño esencial

Carga. Llena.
Cierra.

La segunda forma de despachar: el contenedor arranca vacío y se llena hasta que no cabe más. Aquí no hay manifiesto que verificar — el manifiesto nace al cerrar. China deja de ser verificador y pasa a ser productor del dato (append-only, como pide el spec). En vez de una cuenta regresiva, un medidor de tanque: cargas, el nivel sube, sigues hasta lleno.

Mismo hardware — iData T1 Pro + Q3000 · escaneo híbrido (carga libre + barrido de sincronía)
La otra opción · Salida planificada (manifiesto) → design.cresco.so/mogos/salida
Elige Carga Barre Llena Cierra Despacha
1Consolidación — llena el contenedor

El operador abre un contenedor de un destino y le mete lo que vaya saliendo hacia ahí, hasta que no cabe más. La pistola lleva el conteo y el volumen; cuando el operador decide que está lleno, cierra y el manifiesto se genera solo. El mismo hogar y la misma calma de la V1; solo cambia la pregunta: ya no “¿está todo?”, sino “¿cuánto más cabe?”.

ALos dos bordes — la ruta y el sobrante

Sin manifiesto, la validación es por caja al escanear (solo destino) y el “faltan” se vuelve “lo que no cupo”. Dos bordes, misma calma: el operador nunca se detiene.

±Estados que el diseño contempla

Los mismos susurros recuperables de la V1, más los propios del llenado. Nunca pérdida de datos.

Pistola desconectada

El conteo se congela y sube el chip Q3000 · reconecta. Lo cargado vive en SQLite — desconexión ≠ pérdida.

Reanudar el contenedor

Si muere la batería, el contenedor abierto se reanuda en su nivel: 77%, 96 cajas, continúa. Cada caja se vacía a SQLite al instante.

Sobrepeso antes que volumen

Si el peso llega al límite antes que el volumen (carga densa), el medidor cambia a kg y avisa: cierra por peso, no por m³.

Caja dañada

Una caja rota se marca dañada · no embarca; no suma al tanque y se reporta — no se cuela como cargada.

Sello obligatorio

Sellar y despachar se desbloquea solo con precinto y foto — cadena de custodia, como en la V1.

Tag sin dueño

Un EPC que no resuelve a ninguna orden local es desconocido · apartar y reportar, no se fuerza al contenedor.

Dos formas de despachar — elige por contenedor

No es “una u otra para siempre”: conviven. Un contenedor reservado por un cliente se carga contra su manifiesto (V1); un contenedor de consolidación se llena hasta tope (V2). Mismo hogar, mismo hardware, misma calma — cambia la pregunta que hace el operador.

V1 · PlanificadaV2 · Consolidación
El manifiestoInput — ya existe, lo verificasOutput — nace al cerrar
El héroeContador 58/62 hacia una metaMedidor de tanque (cuán lleno)
La pregunta¿Está todo lo planeado?¿Cuánto más cabe?
El faltante“Faltan” — cajas del plan sin leer“No cupo” — va al próximo contenedor
El ajeno“Sobran” — reconcilia al finalPor caja al escanear (solo destino)
CierreManifiesto completoNo cabe más — operador + umbral
Cuándo usarContenedor pre-reservado / FCLConsolidación / groupage (lo común)
Filosofía specChina verifica el planChina produce el dato (append-only)
BLa ingeniería — el manifiesto como output

La V2 reusa casi todo de la V1: el mismo módulo idata-rfid, el mismo EPC de recepción, el mismo esqueleto offline-first. Lo único nuevo es el contenedor como entidad con capacidad y la inversión del dato: las lecturas no se comparan contra un manifiesto, lo generan. No hay ZPL nuevo — la etiqueta combo UHF+QR ya se imprime en recepción.

El contenedor abierto — entidad con capacidad
nuevo
Container.openel contenedor en consolidación
{ id, destino, modo:'consolidacion', capacityM3, maxKg, status:'abierto' } — lo nuevo frente a la V1: el contenedor existe sin manifiesto previo
useContainerFill(containerId)el draft de llenado
apps/warehouse/hooks/shipment/use-container-fill.tsx — { loaded:Map<epc,box>, usedM3, usedKg, offRoute[], overflow[], sealNumber } · espejo de use-reception-draft.tsx
capacity.ts (puro)el medidor
apps/warehouse/lib/shipment/capacity.ts — usedM3 = Σ cbm por caja (el campo cbm que captura recepción); fillPct = usedM3 / capacityM3; testeable sin hardware
Validación al escanear — solo destino
nuevo
onTagRead(epc)caja por caja
lookup order por EPC en SQLite → order.destino === container.destino ? suma al tanque : marca offRoute — pago/hold NO se evalúan (USA concilia)
Híbrido de escaneoreusa idata-rfid
carga libre + startInventory() para barrer y sincronizar el conteo + un barrido final; de-dup por EPC en el Map reusa V1
Cierre genera el manifiestola inversión
sealContainer() → congela el set de EPCs cargados = el manifiesto → escribe a la cola de lib/sync; los offRoute/overflow se mueven a otro contenedor

Secuencia — carga y cierre. Cada caja suma su CBM al medidor; al cerrar, lo escaneado se vuelve la verdad.

Operador Q3000 (pistola) useContainerFill() SQLite local capacity.ts Pantalla / cola T1 ProUHF · híbridohooks/shipmentórdenes pre-syncΣ cbmmedidor · lib/sync loop · por cada caja que entra al contenedor carga + barre onTagRead(epc) order WHERE epc · ¿destino = Caracas? sí → usedM3 += box.cbm fillPct → tanque 77% cierra (97%) congela EPCs = manifiesto → cola lib/sync
Dos opciones, lado a lado. Esta es la V2 · Consolidación (design.cresco.so/mogos/salida-consolidacion). La V1 · Planificada vive en /mogos/salida. Comparten hogar, hardware y módulo idata-rfid; la app elige el flujo por el tipo de contenedor. Decide cuál es tu default — o déjalas convivir.