commit1dc4e29c69Author: ncoronel <ncoronel@quo.ar> Date: Wed Aug 19 13:58:03 2026 -0300 refactor(reservations): unify expiration command commit093e894cc3Author: ncoronel <ncoronel@quo.ar> Date: Wed Aug 19 13:48:09 2026 -0300 feat(cart): expire abandoned stock reservations commitfdf0f3328fAuthor: ncoronel <ncoronel@quo.ar> Date: Wed Aug 19 12:53:12 2026 -0300 refactor(stock): implement expiration for stock reservations and add configuration commit8d6bcdcc43Author: ncoronel <ncoronel@quo.ar> Date: Wed Aug 19 12:38:21 2026 -0300 refactor(cart): invalidate payment on actual changes commit3206e293ebAuthor: ncoronel <ncoronel@quo.ar> Date: Wed Aug 19 12:24:48 2026 -0300 refactor(cart): own checkout item editing commitaed99bd05eAuthor: ncoronel <ncoronel@quo.ar> Date: Wed Aug 19 12:14:57 2026 -0300 refactor(checkout): remove legacy purchase item reservations commitf1649e0e4bAuthor: ncoronel <ncoronel@quo.ar> Date: Wed Aug 19 12:06:29 2026 -0300 refactor(checkout): materialize purchase items on confirmation commite6c4b40a37Author: ncoronel <ncoronel@quo.ar> Date: Wed Aug 19 12:06:19 2026 -0300 feat(inventory): add traceable cart stock reservations
38 lines
2.6 KiB
Markdown
38 lines
2.6 KiB
Markdown
# Dominio Purchase
|
|
|
|
## Propósito
|
|
|
|
Implementa el ciclo de compra y checkout: crea la cabecera de compra desde un carrito, mantiene sus líneas vivas contra catálogo durante el checkout, inicia el pago y materializa el snapshot definitivo al confirmar, o cancela y vence la operación.
|
|
|
|
## Modelo
|
|
|
|
- `Purchase`: raíz de la compra; estados `created`, `pending_payment`, `paid`, `cancelled`, `rejected` y `expired`.
|
|
- `PurchaseItem`: snapshot definitivo del producto o variante, creado recién al confirmar la compra.
|
|
- `TelepagosQr` y `TelepagosPayment`: datos del QR e intentos/resultados del proveedor.
|
|
- `PurchasePaid`: evento emitido una sola vez al pasar a pagada bajo bloqueo transaccional.
|
|
|
|
## Servicios de checkout
|
|
|
|
`CheckoutService` es la fachada estable. Delega en:
|
|
|
|
- `StartCheckoutService`: inicia la compra desde el carrito o crea un carrito técnico para compra directa, sin crear todavía `PurchaseItem`.
|
|
- `EditCheckoutService`: modifica los datos del comprador antes del cierre.
|
|
- `CompleteCheckoutService`: completa, envía a revisión o materializa los `PurchaseItem` al confirmar el pago.
|
|
- `ReleaseCheckoutService`: cancela, vence y procesa vencimientos pendientes.
|
|
- `SourceCartService`: restaura o finaliza el carrito fuente.
|
|
- `CatalogSelectionResolver` y `PurchaseItemSnapshotFactory`: resuelven selecciones y generan snapshots.
|
|
|
|
Durante `created` y `pending_payment`, `PurchaseResource` publica las líneas del carrito con `items_source=cart`; una compra materializada publica `items_source=purchase`. Los datos descriptivos y económicos del checkout se resuelven siempre desde el catálogo vigente.
|
|
|
|
Las cantidades y variantes se editan mediante el dominio Cart. El endpoint autenticado `PATCH /checkout-carts/{cart}/items/{cartItem}` valida que el carrito pertenezca al usuario y a una compra editable. Cuando existe un cambio real, invalida atómicamente el intento de pago anterior, recalcula el total y renueva la reserva; Purchase no expone operaciones sobre líneas antes de la confirmación.
|
|
|
|
`UserPurchaseLimitService` controla límites de compra y `CheckoutService` conserva el punto de entrada para controladores e integraciones.
|
|
|
|
## Endpoints
|
|
|
|
Bajo `/tenants/{tenant:codigo}/compras`, con `auth:sanctum`: listado, inicio, detalle, edición de ítems, datos del cliente, intención de pago, finalización, revisión y cancelación.
|
|
|
|
## Dependencias y reglas
|
|
|
|
Depende de `Cart`, `Catalog`, `Tenant`, `Auth` e `Integration`; emite eventos consumidos por `Ticket` y `Notification`. Los cambios de estado e inventario deben ser transaccionales y usar los servicios del checkout, no actualizaciones directas del modelo.
|