Conversation
…celled The order ingestion accepts any known status, cancelled included, and took the units of every line regardless. A sale whose first notification already comes cancelled (a rejected payment in Mercado Libre) left its units deducted for good: a cancelled order cannot be modified nor cancelled again, so nothing ever gave them back, and the stock callbacks published the lower quantity to every channel. The sale is still recorded, so it leaves a trace, but its lines take no units and therefore record no warehouse, like the lines older than TESIS-126. Paid and pending sales deduct as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Revisado. Lo veo bien para implementar. El caso no es raro: en Mercado Libre un pago rechazado hace que la primera notificación de la venta llegue ya cancelada. Hoy esa venta se registra cancelada y se lleva el stock igual, y como una orden cancelada no se puede editar ( Lo que verifiqué
Lo que queda afuera Esto cubre la venta que nace cancelada. La que entra Antes de mergear El PR está CONFLICTING contra |
Ticket de Jira
https://proyectofinalfrlp.atlassian.net/browse/TESIS-999016
Descripción
Orders::ProcessWebhookOrder#statusacepta cualquier estado deOrder::STATUSES, incluidocancelled, ycreate_orderdescontaba stock por cada línea sin mirarlo. Una venta cuya primera notificación ya llega cancelada —en Mercado Libre es normal: un pago rechazado— quedaba registrada como cancelada con sus unidades descontadas para siempre: una orden cancelada no se puede modificar (UpdateOrder, 409) ni volver a cancelar, así que nada las devolvía. Y el callback deStockpublicaba el número rebajado en todos los canales.Repro en
master: plantilla conresponse_value_mapper {'cancelado' => 'cancelled'}, stock en 20, webhook{"id":"100","status":"cancelado","items":[{"id":"P1","qty":5}]}→ logprocessed, ordencancelled, stock en 15.Decisiones que conviene mirar:
Se registra, sin stock. Descartarla también resolvía el stock, pero se perdería el rastro de que la venta existió (y la idempotencia: si el canal la reenvía, se la reconoce como duplicada). Se crea la orden cancelada con sus líneas, y las líneas no se llevan unidades.
Líneas sin depósito. Sin descuento, el picking de
DeductStockno elige depósito, así que la línea queda conwarehouse_id: nil, igual que las anteriores a TESIS-126. Como la orden ya está cancelada, ninguna edición ni cancelación va a intentar devolverle unidades.Mapeo de productos, igual que antes. Una venta cancelada con un producto sin mapear sigue fallando y yendo a la DLQ: la orden necesita saber qué producto es cada línea. No se cambió ese criterio en esta card.
ProcessWebhookOrder#register_itemtoma unidades a través detake_units, que no descuenta para una ordencancelled.processedy sus líneas sin depósito; control negativo con una venta pagada que sí descuenta.Evidencia visual
N/A
Cómo probar
cancelled, mandar un webhook de una venta nueva con ese estado.cancelledy el stock de sus productos no cambia. Enmasterbaja.Verificación:
bundle exec rspec(1572 ejemplos, 0 fallas, cobertura 99.89% de línea),rubocopybrakemanlimpios.Dientes: sin la guarda de
take_units, fallan 2 de los specs nuevos.Impacto y consideraciones
¿Introduce breaking changes?
No. Corrige el stock de un caso que hoy lo deja mal.
¿Requiere nuevas variables de entorno?
No
¿Afecta la arquitectura o genera un nuevo patrón?
No
Fuera de alcance: una venta que entró pagada y después se cancela en el canal sigue sin devolver stock (ADR-013: «la cancelación sigue sin camino» para webhooks); proyecto-api#102 agrega la cancelación manual desde la API.
Conflicto esperable con
TESIS-138-shopify-integration: esa rama tocaorder_attributesen el mismo archivo; este cambio está enregister_item, otra zona.🤖 Generated with Claude Code