Wiki
Ciclo de vida de las ofertas
Analisis detallado de transiciones de estado, reglas de validacion y audit trail en las ofertas de QuoteNode.
Ciclo de vida de las ofertas y maquina de estados
Cada oferta en QuoteNode sigue un ciclo de vida estricto y validado. El sistema aplica solo transiciones validas y rechaza cualquier intento de mover una oferta a un estado invalido.
Definiciones de estado
| Estado | Descripcion | Editable | Terminal |
|---|---|---|---|
| DRAFT | La oferta se esta preparando. Aun no es visible para el cliente. | Si | No |
| SENT | La oferta se entrego al cliente por email o enlace publico. | No | No |
| OPENED | El cliente ha visto el enlace publico al menos una vez. | No | No |
| NEGOTIATION | El cliente respondio con una pregunta o contrapropuesta. | No | No |
| ACCEPTED | El cliente confirmo el pedido. | No | Si |
| REJECTED | El cliente rechazo la oferta. | No | Si |
| EXPIRED | La validez vencio sin decision. | No | Si |
| ARCHIVED | Archivada manualmente por el comercial. | No | Si |
Reglas de transicion
DRAFT ──────────► SENT
│ │
│ ▼
│ OPENED
│ │
│ ├──► NEGOTIATION
│ │ │
│ ├──► ACCEPTED (terminal)
│ ├──► REJECTED (terminal)
│ └──► EXPIRED (terminal)
│
└──► ARCHIVED (terminal)
Transiciones validas
- DRAFT → SENT - cuando el comercial envia la oferta o genera un enlace publico
- SENT → OPENED - cuando el cliente abre el enlace publico por primera vez
- OPENED → NEGOTIATION - cuando el cliente envia una respuesta
- OPENED → ACCEPTED - cuando el cliente pulsa
Accept - OPENED → REJECTED - cuando el cliente pulsa
Decline - SENT/OPENED/NEGOTIATION → EXPIRED - cuando pasa
valid_until - DRAFT → ARCHIVED - cuando el comercial archiva una oferta no enviada
- NEGOTIATION → ACCEPTED - cuando el cliente acepta tras negociar
- NEGOTIATION → REJECTED - cuando el cliente rechaza tras negociar
Transiciones invalidas
- SENT → DRAFT
- ACCEPTED → cualquier otro estado
- REJECTED → cualquier otro estado
- EXPIRED → cualquier otro estado
- ARCHIVED → cualquier otro estado
Que ocurre en cada transicion
DRAFT → SENT
- El sistema valida que la oferta tenga al menos una linea
- Se crea un snapshot inmutable en JSON con el estado completo de la oferta
- Si se envia por email, se encola el correo con PDF y/o enlace publico
- Si se genera enlace publico, se crea un token aleatorio de 256 bits y solo se guarda su hash SHA-256
- El estado cambia a SENT
- Se registra un evento en la timeline del cliente
- Se escribe una entrada en el audit log
SENT → OPENED
- El cliente accede a la URL publica
- El hash del token se valida en la base de datos
- El estado cambia a OPENED solo en la primera vista
- Se registra el evento web con timestamp, IP, user agent y pais GeoIP
- El comercial recibe una notificacion si esta configurada
OPENED → ACCEPTED
- El cliente pulsa
Accepten la pagina publica - Se validan rate limiting y deteccion de bots
- Se pueden capturar datos opcionales de order intent
- El estado cambia a ACCEPTED
- El comercial recibe una notificacion inmediata
- Se registra el evento en la timeline
Snapshots
Un snapshot es un registro completo e inmutable de la oferta en el momento del envio:
- datos del cliente
- todas las lineas con productos, cantidades, precios, descuentos y tipos de IVA
- totales calculados, incluido shipping y desglose de IVA
- tipo de cambio usado
- configuracion de branding
- ajustes de plantilla
Los snapshots nunca se modifican. Si una oferta se reenvia tras cambios, se crea una nueva version de snapshot con un numero incremental.
Los PDF siempre se generan desde snapshots, nunca desde datos vivos. Eso garantiza que el PDF coincide exactamente con lo que vio el cliente.
Audit trail
Cada transicion de estado escribe una entrada inmutable en el audit log con:
- identificador y rol del actor o
systemsi fue automatico - direccion IP de origen
- estado anterior y nuevo
- timestamp del servidor
- comentario opcional, por ejemplo el motivo de rechazo
El audit log es append-only. Las entradas no pueden editarse ni borrarse, ni siquiera por administradores.
Operaciones despues de estados terminales
Las ofertas terminales, como ACCEPTED, REJECTED, EXPIRED y ARCHIVED, no se pueden modificar, pero si reutilizar como base de nuevas ofertas:
- Clone - crea un nuevo DRAFT con los mismos items y precios
- Extend Validity - clona la oferta con nueva fecha de validez
- Update Prices - clona y recalcula desde el catalogo y los tipos FX actuales
- Use as Template - clona sin cliente ni precios
Estas operaciones siempre crean una oferta nueva con nuevo ID y estado DRAFT. La oferta original permanece intacta.