4.2 KiB
Document Series Design
Objetivo del módulo
document-series es un módulo propio porque la serie documental no es un catálogo estático: mantiene reglas de vigencia, flags de activación, defaults y estado transaccional de numeración.
Por qué no vive en catalogs
Los catálogos del ERP resuelven valores de referencia. Aquí hay concurrencia, bloqueo de fila y mutación transaccional de next_number, así que el comportamiento es operativo y no meramente descriptivo.
Por qué numeración y serie viven juntas
La numeración depende del estado de la serie:
- si está activa
- si está vigente
- si es la serie por defecto
- cuál es su prefijo, sufijo y padding
Separarlo introduciría doble escritura o lecturas no atómicas.
Modelo conceptual
DocumentType: tipo documental cerrado en V1DocumentSeries: agregado con configuración y contadorAssignedDocumentNumber: resultado de asignación atómica
Campos principales
companyId,branchIddocumentTypecode,name,descriptionprefix,suffixnextNumber,paddingvalidFrom,validToisDefault,isActive
Reglas V1
- tipos soportados:
proforma,issued_invoice - no asigna si la serie está inactiva
- no asigna si la serie está fuera de vigencia
- default por empresa + tipo, con prioridad de
branch_idcuando aplica - formato de referencia:
prefix + padded(next_number) + suffix
Concurrencia
La asignación usa transacción obligatoria y bloqueo de fila con LOCK.UPDATE sobre document_series. El incremento de next_number se persiste dentro de la misma transacción y con comprobación optimista del valor previo para evitar dobles consumos.
Integracion con customer-invoices
En V1:
issued-invoicesdelega la asignacion de numero endocument-seriesproformasdelega la asignacion de referencia endocument-seriesproformaspersistedocument_series_idyproforma_numbercomo snapshot tecnico adicional aproforma_referenceproformas.document_series_ididentifica la serie documental usada para numerar la proformaproformas.proforma_numberguarda el numero propio de la proformaproformas.proforma_referenceguarda la referencia visible de la proformaproforma_series_codees el input funcional de create para elegir la serie dedocument_type = proformaproformas.target_invoice_series_codees opcional y, cuando existe, apunta a una serie deissued_invoice, nunca a una serie deproforma- create de proforma solo usa
document-seriespara numerar la cabecera inicial; no calcula impuestos reales por si mismo - una proforma puede crearse sin lineas y seguir siendo valida como borrador inicial
- si no hay lineas valoradas,
proforma_taxesdebe quedar vacia y los totales monetarios a0 - si
proformas.target_invoice_series_codeesNULL, la emision resuelve la serie default activa deissued_invoice - en Fase 2E,
seriesdeja de ser el contrato nuevo para create/update de proformas - la UI consulta
GET /document-seriescon filtro pordocument_typee idealmenteis_active = true /catalogs/invoice-seriesdeja de existir como endpoint runtimecustomer_invoice_seriesno participa ya en flujos activos de lectura o numeracion
Migracion conservadora
- la migracion historica de
issued_invoiceparte decustomer_invoice_series - la creacion de series default de
proformausacompaniescomo fuente - las validaciones SQL se mantienen separadas del script de migracion
- no hay ejecucion automatica ni cutover productivo en esta fase
- la DDL de
proformasusainformation_schema+ SQL dinamico para mantener compatibilidad MariaDB/MySQL sin depender deIF NOT EXISTSenALTER TABLE
Branch scope pendiente
El modelo ya contempla branchId, y la resolucion default da prioridad a branch_id cuando existe. Aun asi, customer-invoices no propaga un contexto real de sucursal hasta assignNextNumber(...), asi que en esta fase toda la integracion sigue operando con alcance de empresa.
Límites V1
- sin
format_pattern - sin reseteos anuales automáticos
- sin reservas de numeración
- sin huecos justificados
- sin migración productiva automática de legacy
Extensiones futuras
- nuevos
DocumentType - seeds/migraciones controladas de series heredadas