Skip to content

feat: [TESIS-999003] move stock between warehouses from the product detail - #61

Closed
LauAubert wants to merge 1 commit into
TESIS-999002-product-detail-backend-statusfrom
TESIS-999003-stock-transfers-from-product-detail
Closed

LauAubert wants to merge 1 commit into
TESIS-999002-product-detail-backend-statusfrom
TESIS-999003-stock-transfers-from-product-detail

Conversation

@LauAubert

Copy link
Copy Markdown
Member

Ticket de Jira

https://proyectofinalfrlp.atlassian.net/browse/TESIS-999003

ID provisorio: se reemplaza por la clave real al cargar la card en Jira. Card: cards/003.md.


Descripción

La API de transferencias entre depósitos existe desde TESIS-103 (POST /stock-transfers, GET /stock-transfers, /receive, /cancel) y el catálogo ya muestra «+N en tránsito», pero no había ninguna pantalla para mover unidades: sólo se podía desde la consola o el backoffice. Este PR suma al detalle de producto la tarjeta «Transferencias en curso», con el alta, la recepción y la cancelación.

PR apilado sobre proyecto-web#60 (card 002): usa el stockStatus por fila y la distribución con entrantes que arma esa rama. Se revisa y mergea después de #60, que a su vez espera a proyecto-api#99.

Decisiones que conviene mirar:

Sin maqueta. S12 no tiene esta tarjeta. Sigue la forma de la «Distribución por depósito» (misma cabecera y separadores) y usa ModalFrame y ConfirmDialog del DS. Va debajo de la grilla para no tocar la maqueta existente.

Qué ofrece el modal. El origen sólo lista depósitos con unidades del producto: transferir desde uno vacío siempre termina en 422. El destino lista cualquier otro depósito de la empresa, tenga o no stock del producto. El tope de cantidad sale del origen elegido y vive en el schema de Zod (transferStockSchema se arma con las unidades de cada origen), así que el error aparece en el campo antes de llegar a la API.

Errores de la API, traducidos. 422 (el origen ya no tiene esas unidades porque alguien las movió con el modal abierto) y 409 (otra operación tiene tomado el stock del producto, WithStockLock) se explican dentro del modal, que queda abierto con lo cargado. Al recibir o cancelar, un 409 quiere decir que la transferencia ya se liquidó en otro lado: el hook invalida también al fallar, así que la lista se actualiza, y el aviso dice por qué desapareció.

Confirmación. Recibir pide confirmación con tono normal; cancelar, con tono destructivo («no se puede deshacer»): devuelve las unidades al origen y la transferencia queda cerrada.

  • Agrega fetchTransfers, createTransfer y settleTransfer en api.ts, con su traducción a StockTransfer.
  • Agrega useProductTransfers, useCreateTransfer y useSettleTransfer; las mutaciones invalidan todo el dominio inventory (cambian total_stock, el en tránsito y la distribución).
  • Agrega TransferStockModal (presentacional, RHF + Zod) y ProductTransfers (lista + acciones + diálogos) y los monta en ProductDetailPage.
  • Agrega la clave inventoryKeys.transfers(productId), colgada de all para que las invalidaciones existentes la alcancen.
  • Documenta las piezas nuevas en docs/guidelines/architecture.md.

Evidencia visual

Pendiente de captura con la API levantada. El comportamiento está cubierto por los tests de TransferStockModal y ProductTransfers.


Cómo probar

Precondición: API con proyecto-api#99, bin/rails db:seed, login con un usuario de Norte.

  1. Abrir el detalle de NOR-003 → tarjeta «Transferencias en curso» vacía.
  2. «Transferir stock» → el origen ofrece sólo Central (100) y Satélite (30). Elegir Central; el destino no ofrece Central.
  3. Pedir 101 unidades → «El origen tiene 100 unidades.» sin llamar a la API.
  4. Transferir 10 de Central a Satélite → toast «Transferencia creada», Central baja a 90, la cubeta «En tránsito» y la fila de Satélite muestran 10, y la transferencia aparece en la lista.
  5. «Recibir» → confirmar → Satélite sube a 40 y la transferencia desaparece de la lista.
  6. Crear otra y «Cancelar» → confirmación destructiva → las unidades vuelven a Central.
  7. Recibir la misma transferencia desde dos pestañas → la segunda muestra «Esa transferencia ya se había liquidado» y la lista se actualiza.

Verificación: npm run test (693 tests, 0 fallas), npm run lint, npm run format:check y npm run build limpios.


Impacto y consideraciones

¿Introduce breaking changes?
No

¿Requiere nuevas variables de entorno?
No

¿Afecta la arquitectura o genera un nuevo patrón?
No. Mismo patrón que los modales de producto (presentacional + hooks de React Query en quien lo monta).

🤖 Generated with Claude Code

…etail

The stock transfers API (TESIS-103) had no screen: units could only be moved
from the console or the backoffice. The product detail now lists the
transfers in flight of the product and lets the operator create one, receive
it or cancel it.

The transfer modal only offers warehouses holding units as origin, leaves the
origin out of the destinations and caps the quantity at what the origin holds.
A 422 (the units were moved meanwhile) or a 409 (another operation holds the
stock) is explained inside the modal. Receiving and cancelling ask first, and
a 409 on them refreshes the list because someone else already settled it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@TomasMartin2004

Copy link
Copy Markdown
Contributor

Revisado. No lo mergearía para esta entrega.

El trabajo está bien y la carencia que describe es cierta: la API de transferencias existe desde TESIS-103 y mover unidades entre depósitos sólo se podía desde la consola o desde Avo.

Lo dejo afuera por dos razones:

  1. No hay RF que lo comprometa. Revisé los 27 requisitos de E4a: RF-09 modela el stock distribuido y RF-10 es el ABM de productos con stock consolidado, pero ninguno pide una pantalla de transferencias, y tampoco aparece en el módulo B de E4b ni en la matriz de trazabilidad §3. A diferencia de feat: [TESIS-145] manage the company warehouses from their own screen #62 (RF-03) y feat: [TESIS-147] show and operate the failed events queue #63 (RF-16), acá no hay un hueco contra la línea base: hay una funcionalidad que estaría buena.
  2. Es el PR más grande de los que levantaste (1040 líneas) y está apilado sobre feat: [TESIS-144] take the product detail status and units in flight from the API #60, así que arrastra ese orden de merge.

Para el backlog, sin problema. Antes de la entrega, no.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants