2026-07-30 10:45:33 +00:00
|
|
|
# Duplicado de proformas
|
|
|
|
|
|
|
|
|
|
## Endpoint
|
|
|
|
|
|
|
|
|
|
- `POST /proformas/:proforma_id/duplicate`
|
|
|
|
|
|
|
|
|
|
## Semántica
|
|
|
|
|
|
|
|
|
|
- Permite duplicar cualquier proforma no eliminada.
|
|
|
|
|
- La proforma origen puede estar archivada.
|
|
|
|
|
- Si la proforma origen está eliminada lógicamente, el endpoint responde como no disponible.
|
|
|
|
|
- El duplicado siempre nace en `draft`, activo, con `archived_at = NULL`, `deleted_at = NULL` y `linked_invoice_id = NULL`.
|
|
|
|
|
- La numeración siempre es nueva y se consume desde `document-series`.
|
|
|
|
|
- Se intenta reutilizar la misma serie documental del origen si sigue activa; si no, se usa la serie por defecto de `document_type=proforma`.
|
|
|
|
|
- `target_invoice_series_code` solo se conserva si sigue siendo una serie activa de `issued_invoice`; si no, pasa a `NULL`.
|
|
|
|
|
- Se copian datos comerciales y fiscales del origen.
|
2026-08-17 09:25:34 +00:00
|
|
|
- Si el `PaymentTerm` original sigue activo, se copia el mismo `paymentTermId`.
|
|
|
|
|
- Si el `PaymentTerm` original está inactivo, no se reutiliza como nueva asignación. El duplicado resuelve:
|
|
|
|
|
1. `Customer.paymentTermId`, solo si está activo
|
|
|
|
|
2. `Company.defaultPaymentTermId`, solo si está activo
|
|
|
|
|
3. `null`
|
|
|
|
|
- Si el Customer tiene un plazo inactivo, se ignora para esta nueva asignación.
|
|
|
|
|
- Si Company tiene por datos legacy un default inactivo, no se usa y el flujo cae a `null`.
|
2026-07-30 10:45:33 +00:00
|
|
|
- Se copian las líneas con nuevos IDs y se recalculan impuestos y totales con el motor actual.
|
|
|
|
|
|
2026-08-17 09:25:34 +00:00
|
|
|
Fuente funcional principal para `Payment Terms`:
|
|
|
|
|
|
|
|
|
|
- [Plazos de pago](../catalogs/payment-terms.md)
|
|
|
|
|
|
2026-07-30 10:45:33 +00:00
|
|
|
## Response
|
|
|
|
|
|
|
|
|
|
- `201 Created`
|
|
|
|
|
- Devuelve el snapshot completo de la nueva proforma.
|
2026-08-17 09:25:34 +00:00
|
|
|
- Si el plazo de pago original estaba inactivo y hubo adaptación, la respuesta incluye metadata funcional equivalente a:
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
payment_term_adaptation:
|
|
|
|
|
null
|
|
|
|
|
o
|
|
|
|
|
{
|
|
|
|
|
source: "inactive_original",
|
|
|
|
|
resolution: "customer" | "company" | "none"
|
|
|
|
|
}
|
|
|
|
|
```
|
2026-07-30 10:45:33 +00:00
|
|
|
|
|
|
|
|
## UI
|
|
|
|
|
|
|
|
|
|
- Acción de fila `Duplicar` en `/proformas` y `/proformas/archived`.
|
|
|
|
|
- No muestra `Duplicar` en `/proformas/deleted`.
|
|
|
|
|
- Tras duplicar redirige a `/proformas/:id/edit`.
|
2026-08-17 09:25:34 +00:00
|
|
|
- Si el plazo original estaba inactivo y fue sustituido o eliminado, la UI informa del ajuste después de duplicar.
|