Uecko_ERP/docs/document-series/document-series-design.md

4.3 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 V1
  • DocumentSeries: agregado con configuración y contador
  • AssignedDocumentNumber: resultado de asignación atómica

Campos principales

  • companyId, branchId
  • documentType
  • code, name, description
  • prefix, suffix
  • nextNumber, padding
  • validFrom, validTo
  • isDefault, 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_id cuando 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-invoices delega la asignacion de numero en document-series
  • proformas delega la asignacion de referencia en document-series
  • proformas persiste document_series_id y proforma_number como snapshot tecnico adicional a proforma_reference
  • proformas.document_series_id identifica la serie documental usada para numerar la proforma
  • proformas.proforma_number guarda el numero propio de la proforma
  • proformas.proforma_reference guarda la referencia visible de la proforma
  • proforma_series_code es el input funcional de create para elegir la serie de document_type = proforma
  • proformas.target_invoice_series_code es opcional y, cuando existe, apunta a una serie de issued_invoice, nunca a una serie de proforma
  • create de proforma solo usa document-series para numerar la cabecera inicial
  • create de proforma puede persistir tax_config sin materializar impuestos
  • una proforma puede crearse sin lineas y seguir siendo valida como borrador inicial
  • si no hay lineas valoradas, proforma_taxes debe quedar vacia y los totales monetarios a 0
  • si proformas.target_invoice_series_code es NULL, la emision resuelve la serie default activa de issued_invoice
  • en Fase 2E, series deja de ser el contrato nuevo para create/update de proformas
  • la UI consulta GET /document-series con filtro por document_type y is_active = true
  • la UI no consume POST /document-series/assign-next para previsualizar numeracion
  • /catalogs/invoice-series deja de existir como endpoint runtime
  • customer_invoice_series no participa ya en flujos activos de lectura o numeracion

Migracion conservadora

  • la migracion historica de issued_invoice parte de customer_invoice_series
  • la creacion de series default de proforma usa companies como fuente
  • las validaciones SQL se mantienen separadas del script de migracion
  • no hay ejecucion automatica ni cutover productivo en esta fase
  • la DDL de proformas usa information_schema + SQL dinamico para mantener compatibilidad MariaDB/MySQL sin depender de IF NOT EXISTS en ALTER 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