diff --git a/.vscode/settings.json b/.vscode/settings.json
index 6f618606..6a4aa238 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -60,12 +60,5 @@
// other vscode settings
"[sql]": {
"editor.defaultFormatter": "cweijan.vscode-mysql-client2"
- },
- "chat.tools.terminal.autoApprove": {
- "/^cd /home/rodax/Documentos/uecko-erp/apps/web/src/layout && python3 - <<'PY'\nfrom pathlib import Path\nfiles = \\{\n 'app-layout\\.tsx': '''import type \\* as React from \"react\"\nimport \\{ SidebarInset, SidebarProvider \\} from \"@repo/shadcn-ui/components\"\nimport \\{ Outlet \\} from \"react-router\"\n\nimport \\{ AppMain \\} from \"\\./app-main\"\nimport \\{ AppSidebar \\} from \"\\./app-sidebar\"\nimport \\{ AppTopbar \\} from \"\\./app-topbar\"\n\nexport const AppLayout = \\(\\) => \\{\n return \\(\n \n \n \n \n \n \n \n \n \n \\)\n\\}\n''',\n 'app-main\\.tsx': '''import type \\* as React from \"react\"\n\nimport \\{ cn \\} from \"@repo/shadcn-ui/utils\"\n\ninterface AppMainProps \\{\n children: React\\.ReactNode\n className\\?: string\n\\}\n\nexport const AppMain = \\(\\{ children, className \\}: AppMainProps\\) => \\{\n return \\(\n \n \\{children\\}\n \n \\)\n\\}\n''',\n 'app-sidebar\\.config\\.ts': '''import \\{\n BanknoteIcon,\n BarChart3Icon,\n BoxesIcon,\n Building2Icon,\n ClipboardListIcon,\n CoinsIcon,\n CreditCardIcon,\n FileTextIcon,\n LandmarkIcon,\n PackageIcon,\n PercentIcon,\n ReceiptIcon,\n RefreshCcwIcon,\n SettingsIcon,\n ShoppingCartIcon,\n SlidersHorizontalIcon,\n TruckIcon,\n UserCogIcon,\n UsersIcon,\n WarehouseIcon,\n\\} from \"lucide-react\"\nimport type \\{ LucideIcon \\} from \"lucide-react\"\n\nexport interface AppSidebarNavItem \\{\n title: string\n href: string\n icon: LucideIcon\n\\}\n\nexport interface AppSidebarNavSection \\{\n title: string\n items: AppSidebarNavItem\\[\\]\n\\}\n\nexport const appSidebarNavSections: AppSidebarNavSection\\[\\] = \\[\n \\{\n title: \"Ventas\",\n items: \\[\n \\{ title: \"Proformas\", href: \"/proformas\", icon: FileTextIcon \\},\n \\{ title: \"Pedidos de venta\", href: \"/sales-orders\", icon: ShoppingCartIcon \\},\n \\{ title: \"Clientes\", href: \"/customers\", icon: UsersIcon \\},\n \\{ title: \"Facturación\", href: \"/customer-invoices\", icon: ReceiptIcon \\},\n \\{ title: \"Cobros\", href: \"/collections\", icon: CreditCardIcon \\},\n \\{ title: \"Devoluciones\", href: \"/sales-returns\", icon: RefreshCcwIcon \\},\n \\],\n \\},\n \\{\n title: \"Compras\",\n items: \\[\n \\{ title: \"Pedidos de compra\", href: \"/purchase-orders\", icon: ClipboardListIcon \\},\n \\{ title: \"Proveedores\", href: \"/suppliers\", icon: TruckIcon \\},\n \\{ title: \"Facturas de compra\", href: \"/supplier-invoices\", icon: ReceiptIcon \\},\n \\{ title: \"Pagos\", href: \"/payments\", icon: BanknoteIcon \\},\n \\{ title: \"Devoluciones\", href: \"/purchase-returns\", icon: RefreshCcwIcon \\},\n \\],\n \\},\n \\{\n title: \"Inventario\",\n items: \\[\n \\{ title: \"Productos\", href: \"/products\", icon: PackageIcon \\},\n \\{ title: \"Almacenes\", href: \"/warehouses\", icon: WarehouseIcon \\},\n \\{ title: \"Movimientos\", href: \"/stock-movements\", icon: BoxesIcon \\},\n \\{ title: \"Ajustes de stock\", href: \"/stock-adjustments\", icon: SlidersHorizontalIcon \\},\n \\{ title: \"Categorías\", href: \"/product-categories\", icon: ClipboardListIcon \\},\n \\],\n \\},\n \\{\n title: \"Contabilidad\",\n items: \\[\n \\{ title: \"Plan contable\", href: \"/accounting/chart\", icon: LandmarkIcon \\},\n \\{ title: \"Asientos contables\", href: \"/accounting/entries\", icon: FileTextIcon \\},\n \\{ title: \"Diario\", href: \"/accounting/journal\", icon: ClipboardListIcon \\},\n \\{ title: \"Informes financieros\", href: \"/accounting/reports\", icon: BarChart3Icon \\},\n \\],\n \\},\n \\{\n title: \"Configuración\",\n items: \\[\n \\{ title: \"Usuarios y roles\", href: \"/settings/users\", icon: UserCogIcon \\},\n \\{ title: \"Impuestos\", href: \"/settings/taxes\", icon: PercentIcon \\},\n \\{ title: \"Monedas\", href: \"/settings/currencies\", icon: CoinsIcon \\},\n \\{ title: \"Empresas\", href: \"/settings/companies\", icon: Building2Icon \\},\n \\{ title: \"Parámetros\", href: \"/settings\", icon: SettingsIcon \\},\n \\],\n \\},\n\\]\n''',\n 'app-sidebar\\.tsx': '''import type \\* as React from \"react\"\nimport \\{\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarHeader,\n SidebarRail,\n SidebarTrigger,\n\\} from \"@repo/shadcn-ui/components\"\nimport \\{ cn \\} from \"@repo/shadcn-ui/utils\"\n\nimport \\{ AppSidebarNav \\} from \"\\./app-sidebar-nav\"\nimport \\{ appSidebarNavSections \\} from \"\\./app-sidebar\\.config\"\n\ninterface AppSidebarProps \\{\n className\\?: string\n\\}\n\nexport const AppSidebar = \\(\\{ className \\}: AppSidebarProps\\) => \\{\n return \\(\n \n \n \n \n\n \n \n \n\n \n \n
\n AM\n
\n
\n
Ana Martínez
\n
\n Administrador\n
\n
\n
\n \n\n \n \n \\)\n\\}\n''',\n 'app-sidebar-nav\\.tsx': '''import type \\{ AppSidebarNavSection \\} from \"\\./app-sidebar\\.config\"\nimport \\{ NavLink \\} from \"react-router\"\nimport \\{\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n\\} from \"@repo/shadcn-ui/components\"\nimport \\{ cn \\} from \"@repo/shadcn-ui/utils\"\n\ninterface AppSidebarNavProps \\{\n sections: AppSidebarNavSection\\[\\]\n\\}\n\nexport const AppSidebarNav = \\(\\{ sections \\}: AppSidebarNavProps\\) => \\{\n return \\(\n \n \\)\n\\}\n''',\n 'app-topbar\\.tsx': '''import \\{\n BellIcon,\n ChevronDownIcon,\n MessageSquareIcon,\n SearchIcon,\n\\} from \"lucide-react\"\nimport \\{\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n Input,\n SidebarTrigger,\n\\} from \"@repo/shadcn-ui/components\"\n\nexport const AppTopbar = \\(\\) => \\{\n return \\(\n \n \\)\n\\}\n'''\n\\}\nfor name, content in files\\.items\\(\\):\n Path\\(name\\)\\.write_text\\(content, encoding='utf-8'\\)\nPY$/": {
- "approve": true,
- "matchCommandLine": true
- },
- "pnpm": true
- } // <- your root font size here
+ }
}
diff --git a/docs/customer-invoices/document-series-snapshot-contract.md b/docs/customer-invoices/document-series-snapshot-contract.md
new file mode 100644
index 00000000..6e3cea18
--- /dev/null
+++ b/docs/customer-invoices/document-series-snapshot-contract.md
@@ -0,0 +1,31 @@
+# Document Series Snapshot Contract
+
+## Regla base
+
+- `document-series` asigna numero y referencia.
+- `proformas` e `issued_invoices` persisten un snapshot inmutable del resultado.
+- las referencias visibles no se recalculan en lecturas normales.
+
+## Snapshot persistido
+
+### Proformas
+
+- `document_series_id`
+- `proforma_series_code`
+- `proforma_number`
+- `proforma_reference`
+
+### Issued invoices
+
+- `document_series_id`
+- `invoice_series_code`
+- `invoice_number`
+- `invoice_reference`
+
+## Motivo
+
+- `document_series_id` conserva trazabilidad tecnica exacta.
+- `series_code` conserva un snapshot legible e historico.
+- `number` conserva el valor estructurado y consultable.
+- `reference` conserva el valor visible/legal final.
+- una factura emitida es historica e inalterable aunque luego cambie la configuracion viva de `document_series`.
diff --git a/docs/customer-invoices/issued-invoice-series-contract.md b/docs/customer-invoices/issued-invoice-series-contract.md
new file mode 100644
index 00000000..d7217d12
--- /dev/null
+++ b/docs/customer-invoices/issued-invoice-series-contract.md
@@ -0,0 +1,42 @@
+# Issued Invoice Series Contract
+
+## Objetivo
+
+Definir el contrato backend para la numeracion documental de `issued_invoices`.
+
+## Snapshot persistido
+
+Una factura emitida debe persistir estos cuatro datos de numeracion:
+
+- `document_series_id`
+- `invoice_series_code`
+- `invoice_number`
+- `invoice_reference`
+
+## Regla operativa
+
+- `document-series` es la unica fuente de verdad para asignar numeracion de `document_type = issued_invoice`.
+- `customer-invoices` no recompone manualmente la referencia final si `document-series` ya la devuelve.
+- `invoice_reference` se calcula en el momento de emision.
+- `invoice_reference` se persiste como snapshot documental inmutable.
+- `invoice_reference` no se recalcula despues aunque cambie la configuracion de `document_series`.
+
+## Emision desde proforma
+
+- si `target_invoice_series_code` tiene valor, se usa como `seriesCode` de `issued_invoice`
+- si `target_invoice_series_code` es `NULL`, `document-series` resuelve la serie default activa
+- la respuesta de `assignNextNumber(...)` debe aportar `series_id`, `series_code`, `number` y `reference`
+- `issued_invoices` debe persistir `document_series_id`, `invoice_series_code`, `invoice_number` e `invoice_reference`
+
+## Semantica de campos
+
+- `document_series_id`: id tecnico de la serie exacta usada al emitir para trazabilidad y backoffice
+- `invoice_number`: numero secuencial dentro de la serie
+- `invoice_reference`: referencia final visible/legal compuesta por la serie documental
+- `reference`: referencia comercial libre del documento, si aplica; no sustituye a `invoice_reference`
+
+## Regla de no contaminacion
+
+- `proforma_reference` nunca se reutiliza como `invoice_reference`
+- `target_invoice_series_code` solo selecciona la serie futura y no es en si mismo la referencia final
+- no se usa `MAX(invoice_number)` para recomponer numeracion
diff --git a/docs/customer-invoices/proforma-series-contract.md b/docs/customer-invoices/proforma-series-contract.md
index df7bdcf6..16b69255 100644
--- a/docs/customer-invoices/proforma-series-contract.md
+++ b/docs/customer-invoices/proforma-series-contract.md
@@ -9,6 +9,7 @@ Normalizar el contrato publico de proformas para separar definitivamente la seri
En proformas:
- `document_series_id` identifica la serie documental propia de la proforma
+- `proforma_series_code` guarda el codigo snapshot de la serie propia de la proforma
- `proforma_number` guarda el numero propio de la proforma
- `proforma_reference` guarda la referencia visible de la proforma, por ejemplo `PF-0139`
- `proforma_series_code` es el codigo funcional que se usa solo en create para elegir una serie de `document_type = proforma`
@@ -92,7 +93,7 @@ Si el request informa `proforma_series_code`:
- debe corresponder a una serie activa de `document_type = proforma`
- solo se usa para numerar la proforma en create
-- despues queda congelado en `document_series_id`, `proforma_number` y `proforma_reference`
+- despues queda congelado en `document_series_id`, `proforma_series_code`, `proforma_number` y `proforma_reference`
## Retirada futura de `series`
diff --git a/docs/customer-invoices/split-proformas-issued-invoices-migration.md b/docs/customer-invoices/split-proformas-issued-invoices-migration.md
index 809c82ef..76b9d340 100644
--- a/docs/customer-invoices/split-proformas-issued-invoices-migration.md
+++ b/docs/customer-invoices/split-proformas-issued-invoices-migration.md
@@ -32,7 +32,7 @@ Preparar el esquema fisico para separar:
- `target_invoice_series_code` es opcional y solo puede apuntar a una serie de `issued_invoice`.
- una serie `PF` o cualquier otra serie de `document_type = proforma` nunca debe persistirse en `target_invoice_series_code`.
- si `target_invoice_series_code` queda `NULL`, la emision de la factura usara la serie default activa de `issued_invoice`.
-- `issued_invoices` usa `invoice_series_code`, `invoice_number`, `invoice_date` y `source_proforma_id`.
+- `issued_invoices` usa `invoice_series_code`, `invoice_number`, `invoice_reference`, `invoice_date` y `source_proforma_id`.
- `proformas` no guarda `issued_invoice_id`; la relacion se resuelve con `issued_invoices.source_proforma_id`.
- Los impuestos del esquema actual son por documento, no por linea: `proforma_taxes` y `issued_invoice_taxes`.
- `payment_method` y `payment_term` en `issued_invoices` son snapshot historico, no estado vivo de cobro.
@@ -119,6 +119,8 @@ Preparar el esquema fisico para separar:
- al emitir una proforma, la factura definitiva se numera con `document_type = issued_invoice`
- si la proforma trae `target_invoice_series_code`, se usa como `seriesCode`
- si `target_invoice_series_code` es `NULL`, `document-series` resuelve la serie default activa de `issued_invoice`
+- la referencia final devuelta por `document-series` se persiste en `issued_invoices.invoice_reference`
+- `invoice_reference` es snapshot documental y no se recalcula despues
- `proforma_series_code` es un input de create para `document_type = proforma` y no vuelve a ser editable despues
## Estado Fase 2B
@@ -218,6 +220,7 @@ Preparar el esquema fisico para separar:
- `source_proforma_id`
- `invoice_series_code`
- `invoice_number`
+- `invoice_reference`
- `invoice_date`
- `operation_date`
- `reference`
diff --git a/docs/customer-invoices/sql/README.md b/docs/customer-invoices/sql/README.md
index 3df3e315..fceb0c01 100644
--- a/docs/customer-invoices/sql/README.md
+++ b/docs/customer-invoices/sql/README.md
@@ -8,6 +8,8 @@ Este directorio mezcla SQL vigentes de soporte con SQL historicos/transicionales
- `add-proforma-document-series-columns.sql`
- `add-proforma-tax-config-columns.sql`
+- `add-issued-invoice-reference.sql`
+- `normalize-document-series-snapshots.sql`
- `fix-proforma-series-semantics.sql`
- `validate-proforma-tax-config.sql`
- `validate-proforma-soft-delete.sql`
@@ -24,8 +26,9 @@ Estos archivos no deben tratarse como el camino normal de entornos nuevos salvo
1. Verificar que la BD objetivo es inequívocamente de desarrollo.
2. Hacer backup o confirmar que los datos son descartables.
3. Ejecutar el DDL vigente que falte para `proformas`.
-4. Ejecutar las validaciones SQL vigentes.
-5. Levantar backend V2 y validar flujos funcionales.
+4. Ejecutar `normalize-document-series-snapshots.sql` para completar snapshots y validaciones de seriado.
+5. Ejecutar las validaciones SQL vigentes.
+6. Levantar backend V2 y validar flujos funcionales.
## Propiedades de los scripts históricos de split
diff --git a/docs/customer-invoices/sql/add-issued-invoice-reference.sql b/docs/customer-invoices/sql/add-issued-invoice-reference.sql
new file mode 100644
index 00000000..839d227b
--- /dev/null
+++ b/docs/customer-invoices/sql/add-issued-invoice-reference.sql
@@ -0,0 +1,53 @@
+-- Estado: vigente / manual.
+-- Objetivo:
+-- 1. Anadir `issued_invoices.invoice_reference` si no existe.
+-- 2. Backfill conservador para facturas emitidas existentes.
+-- 3. Validar que no quedan filas sin snapshot documental.
+-- 4. Endurecer a NOT NULL cuando la validacion sea correcta.
+--
+-- No ejecutar automaticamente desde backend.
+-- Revisar antes el nombre real de la tabla `document_series` y sus columnas
+-- `prefix`, `padding`, `suffix` en el entorno objetivo.
+
+START TRANSACTION;
+
+ALTER TABLE issued_invoices
+ADD COLUMN IF NOT EXISTS invoice_reference VARCHAR(64) NULL AFTER invoice_number;
+
+UPDATE issued_invoices ii
+JOIN document_series ds
+ ON ds.company_id = ii.company_id
+ AND ds.code = ii.invoice_series_code
+ AND ds.document_type = 'issued_invoice'
+SET ii.invoice_reference = CONCAT(
+ COALESCE(ds.prefix, ''),
+ LPAD(CAST(ii.invoice_number AS CHAR), ds.padding, '0'),
+ COALESCE(ds.suffix, '')
+)
+WHERE ii.invoice_reference IS NULL;
+
+SELECT id, source_proforma_id, invoice_series_code, invoice_number, invoice_reference
+FROM issued_invoices
+WHERE invoice_reference IS NULL;
+
+SELECT
+ ii.id,
+ ii.invoice_series_code,
+ ii.invoice_number,
+ ii.invoice_reference,
+ ds.prefix,
+ ds.padding,
+ ds.suffix
+FROM issued_invoices ii
+JOIN document_series ds
+ ON ds.company_id = ii.company_id
+ AND ds.code = ii.invoice_series_code
+ AND ds.document_type = 'issued_invoice'
+ORDER BY ii.created_at DESC
+LIMIT 20;
+
+-- Ejecutar solo cuando la consulta anterior no devuelva filas.
+ALTER TABLE issued_invoices
+MODIFY COLUMN invoice_reference VARCHAR(64) NOT NULL;
+
+COMMIT;
diff --git a/docs/customer-invoices/sql/dev-split-proformas-issued-invoices.sql b/docs/customer-invoices/sql/dev-split-proformas-issued-invoices.sql
index 4b9e094b..e3dfea14 100644
--- a/docs/customer-invoices/sql/dev-split-proformas-issued-invoices.sql
+++ b/docs/customer-invoices/sql/dev-split-proformas-issued-invoices.sql
@@ -170,6 +170,7 @@ CREATE TABLE IF NOT EXISTS issued_invoices (
source_proforma_id CHAR(36) NULL,
invoice_series_code VARCHAR(10) NOT NULL,
invoice_number VARCHAR(12) NOT NULL,
+ invoice_reference VARCHAR(64) NOT NULL,
invoice_date DATE NOT NULL,
operation_date DATE NULL,
reference VARCHAR(255) NULL,
diff --git a/docs/customer-invoices/sql/normalize-document-series-snapshots.sql b/docs/customer-invoices/sql/normalize-document-series-snapshots.sql
new file mode 100644
index 00000000..a3e116d2
--- /dev/null
+++ b/docs/customer-invoices/sql/normalize-document-series-snapshots.sql
@@ -0,0 +1,85 @@
+-- Normaliza snapshots documentales en `proformas` e `issued_invoices`.
+-- Fases:
+-- 1. DDL conservadora.
+-- 2. Backfill de snapshots.
+-- 3. Diagnostico/validacion.
+-- 4. Endurecimiento opcional cuando no queden nulos.
+
+ALTER TABLE proformas
+ ADD COLUMN IF NOT EXISTS proforma_series_code VARCHAR(10) NULL AFTER document_series_id;
+
+ALTER TABLE issued_invoices
+ ADD COLUMN IF NOT EXISTS document_series_id CHAR(36) NULL AFTER source_proforma_id,
+ ADD COLUMN IF NOT EXISTS invoice_reference VARCHAR(64) NULL AFTER invoice_number;
+
+UPDATE proformas p
+JOIN document_series ds ON ds.id = p.document_series_id
+SET p.proforma_series_code = ds.code
+WHERE p.proforma_series_code IS NULL;
+
+SELECT id, document_series_id, proforma_series_code, proforma_number, proforma_reference
+FROM proformas
+WHERE proforma_series_code IS NULL;
+
+SELECT
+ ds.company_id,
+ ds.document_type,
+ ds.code,
+ COUNT(*) AS series_count
+FROM document_series ds
+WHERE ds.document_type = 'issued_invoice'
+GROUP BY ds.company_id, ds.document_type, ds.code
+HAVING COUNT(*) > 1;
+
+UPDATE issued_invoices ii
+JOIN document_series ds
+ ON ds.company_id = ii.company_id
+ AND ds.document_type = 'issued_invoice'
+ AND ds.code = ii.invoice_series_code
+SET ii.document_series_id = ds.id
+WHERE ii.document_series_id IS NULL;
+
+SELECT id, invoice_series_code, invoice_number
+FROM issued_invoices
+ORDER BY created_at DESC
+LIMIT 20;
+
+UPDATE issued_invoices ii
+JOIN document_series ds ON ds.id = ii.document_series_id
+SET ii.invoice_reference = CONCAT(
+ COALESCE(ds.prefix, ''),
+ LPAD(CAST(ii.invoice_number AS UNSIGNED), ds.padding, '0'),
+ COALESCE(ds.suffix, '')
+)
+WHERE ii.invoice_reference IS NULL;
+
+SELECT id, source_proforma_id, document_series_id, invoice_series_code, invoice_number, invoice_reference
+FROM issued_invoices
+WHERE document_series_id IS NULL
+ OR invoice_reference IS NULL;
+
+SELECT company_id, proforma_series_code, proforma_number, COUNT(*) AS c
+FROM proformas
+WHERE deleted_at IS NULL
+GROUP BY company_id, proforma_series_code, proforma_number
+HAVING c > 1;
+
+SELECT company_id, invoice_series_code, invoice_number, COUNT(*) AS c
+FROM issued_invoices
+WHERE deleted_at IS NULL
+GROUP BY company_id, invoice_series_code, invoice_number
+HAVING c > 1;
+
+CREATE INDEX idx_proformas_document_series_id
+ON proformas (document_series_id);
+
+CREATE INDEX idx_issued_invoices_document_series_id
+ON issued_invoices (document_series_id);
+
+-- Ejecutar solo cuando las validaciones anteriores devuelvan 0 filas pendientes.
+-- ALTER TABLE proformas
+-- MODIFY proforma_series_code VARCHAR(10) NOT NULL;
+--
+-- ALTER TABLE issued_invoices
+-- MODIFY document_series_id CHAR(36) NOT NULL,
+-- MODIFY invoice_reference VARCHAR(64) NOT NULL;
diff --git a/docs/document-series/document-series-design.md b/docs/document-series/document-series-design.md
index c3a6abe6..785ad054 100644
--- a/docs/document-series/document-series-design.md
+++ b/docs/document-series/document-series-design.md
@@ -52,8 +52,11 @@ La asignación usa transacción obligatoria y bloqueo de fila con `LOCK.UPDATE`
En V1:
- `issued-invoices` delega la asignacion de numero en `document-series`
+- `document-series.assignNextNumber(...)` devuelve `series_id`, `series_code`, `number` y `reference`
- `proformas` delega la asignacion de referencia en `document-series`
- `proformas` persiste `document_series_id` y `proforma_number` como snapshot tecnico adicional a `proforma_reference`
+- `issued-invoices` persiste `invoice_reference` como snapshot documental inmutable adicional a `invoice_number`
+- `issued-invoices.invoice_reference` no se recalcula si luego cambia `prefix`, `suffix` o `padding` de la serie
- `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
diff --git a/modules/customer-invoices/src/api/application/invoice-series/services/invoice-series-number-assigner.ts b/modules/customer-invoices/src/api/application/invoice-series/services/invoice-series-number-assigner.ts
index a536d267..c2434d06 100644
--- a/modules/customer-invoices/src/api/application/invoice-series/services/invoice-series-number-assigner.ts
+++ b/modules/customer-invoices/src/api/application/invoice-series/services/invoice-series-number-assigner.ts
@@ -5,7 +5,7 @@ import type { InvoiceNumber, InvoiceSerie } from "../../../domain";
export interface InvoiceSeriesAssignment {
invoiceNumber: InvoiceNumber;
- formattedNumber: string;
+ invoiceReference: string;
invoiceSeriesId: string;
invoiceSeriesCode: InvoiceSerie;
}
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/models/issued-invoice-summary.ts b/modules/customer-invoices/src/api/application/issued-invoices/models/issued-invoice-summary.ts
index 3ca46483..8cbc8b65 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/models/issued-invoice-summary.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/models/issued-invoice-summary.ts
@@ -14,7 +14,10 @@ export type IssuedInvoiceSummary = {
id: UniqueID;
companyId: UniqueID;
+ documentSeriesId: Maybe;
+ invoiceSeriesCode: Maybe;
invoiceNumber: InvoiceNumber;
+ invoiceReference: string;
status: InvoiceStatus;
series: Maybe;
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-creator.ts b/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-creator.ts
index 59518a2f..3e98062a 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-creator.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-creator.ts
@@ -1,5 +1,5 @@
import type { UniqueID } from "@repo/rdx-ddd";
-import { Result } from "@repo/rdx-utils";
+import { Maybe, Result } from "@repo/rdx-utils";
import { IssuedInvoice } from "../../../domain";
import type { IInvoiceSeriesNumberAssigner } from "../../invoice-series";
@@ -45,13 +45,13 @@ export class IssuedInvoiceCreator implements IIssuedInvoiceCreator {
return Result.fail(numberResult.error);
}
- const invoiceNumber = numberResult.data.invoiceNumber;
-
const invoiceResult = IssuedInvoice.create(
{
...props,
+ documentSeriesId: Maybe.some(numberResult.data.invoiceSeriesId),
series: numberResult.data.invoiceSeriesCode,
- invoiceNumber,
+ invoiceNumber: numberResult.data.invoiceNumber,
+ invoiceReference: numberResult.data.invoiceReference,
companyId,
},
id
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-document-metadata-factory.ts b/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-document-metadata-factory.ts
index 95c4da08..050cdbf7 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-document-metadata-factory.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-document-metadata-factory.ts
@@ -34,8 +34,7 @@ export class IssuedInvoiceDocumentMetadataFactory
}
private buildFilename(snapshot: IIssuedInvoiceReportSnapshot): string {
- // Ejemplo: factura-F2024-000123-FULANITO.pdf
- return `factura-${snapshot.series}${snapshot.invoice_number}-${snapshot.recipient.name}.pdf`;
+ return `factura-${snapshot.invoice_reference}-${snapshot.recipient.name}.pdf`;
}
private buildCacheKey(snapshot: IIssuedInvoiceReportSnapshot): string {
@@ -43,8 +42,7 @@ export class IssuedInvoiceDocumentMetadataFactory
return [
"issued-invoice",
snapshot.company_id,
- snapshot.series,
- snapshot.invoice_number,
+ snapshot.invoice_reference,
"v1",
].join(":");
}
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-document-properties-factory.ts b/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-document-properties-factory.ts
index 2526af5e..bd60e806 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-document-properties-factory.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/services/issued-invoice-document-properties-factory.ts
@@ -1,6 +1,6 @@
import type { IDocumentProperties, IDocumentPropertiesFactory } from "@erp/core/api";
-import type { IssuedInvoiceReportSnapshot } from "../models";
+import type { IIssuedInvoiceReportSnapshot } from "../snapshot-builders";
/**
* Construye los metadatos del documento PDF de una factura emitida.
@@ -10,11 +10,11 @@ import type { IssuedInvoiceReportSnapshot } from "../models";
* - Sin IO
*/
export class IssuedInvoiceDocumentPropertiesFactory
- implements IDocumentPropertiesFactory
+ implements IDocumentPropertiesFactory
{
- build(snapshot: IssuedInvoiceReportSnapshot): IDocumentProperties {
+ build(snapshot: IIssuedInvoiceReportSnapshot): IDocumentProperties {
return {
- title: snapshot.reference,
+ title: snapshot.invoice_reference,
subject: "issued-invoice",
author: snapshot.company_slug,
creator: "FactuGES ERP",
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/services/proforma-to-issued-invoice-props-converter.ts b/modules/customer-invoices/src/api/application/issued-invoices/services/proforma-to-issued-invoice-props-converter.ts
index b06b711f..46da5173 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/services/proforma-to-issued-invoice-props-converter.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/services/proforma-to-issued-invoice-props-converter.ts
@@ -19,7 +19,7 @@ import type { ProformaIssueReadModel } from "../models";
export type ProformaToIssuedInvoiceCreateProps = Omit<
IIssuedInvoiceCreateProps,
- "invoiceNumber" | "series"
+ "documentSeriesId" | "invoiceNumber" | "invoiceReference" | "series"
> & {
series: Maybe;
};
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot-builder.ts
index 1ffef9f3..4511d743 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot-builder.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot-builder.ts
@@ -1,5 +1,6 @@
import type { ISnapshotBuilder } from "@erp/core/api";
import { maybeToNullable } from "@repo/rdx-ddd";
+import { Maybe } from "@repo/rdx-utils";
import type { IssuedInvoice } from "../../../../domain";
@@ -41,7 +42,10 @@ export class IssuedInvoiceFullSnapshotBuilder implements IIssuedInvoiceFullSnaps
company_id: invoice.companyId.toString(),
is_proforma: false,
+ document_series_id: maybeToNullable(invoice.documentSeriesId, (value) => value),
+ invoice_series_code: maybeToNullable(Maybe.some(invoice.series), (value) => value.toString()),
invoice_number: invoice.invoiceNumber.toString(),
+ invoice_reference: invoice.invoiceReference,
status: invoice.status.toPrimitive(),
series: invoice.series.toString(),
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot.interface.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot.interface.ts
index e3e6de5c..6a7d0264 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot.interface.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot.interface.ts
@@ -19,7 +19,10 @@ export interface IIssuedInvoiceFullSnapshot {
company_id: string;
is_proforma: boolean;
+ document_series_id: string | null;
+ invoice_series_code: string | null;
invoice_number: string;
+ invoice_reference: string;
status: string;
series: string;
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-item-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-item-snapshot-builder.ts
index 33f482ab..981d6dee 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-item-snapshot-builder.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-item-snapshot-builder.ts
@@ -15,7 +15,7 @@ export class IssuedInvoiceReportItemSnapshotBuilder
items: IIssuedInvoiceItemFullSnapshot[],
params?: ISnapshotBuilderParams
): IIssuedInvoiceReportItemSnapshot[] {
- const locale = params?.locale as string;
+ const locale = (params as { locale?: string } | undefined)?.locale ?? "es";
const moneyOptions = {
hideZeros: true,
@@ -23,7 +23,7 @@ export class IssuedInvoiceReportItemSnapshotBuilder
};
return items.map((item) => ({
- description: item.description,
+ description: item.description ?? "",
quantity: QuantityDTOHelper.format(item.quantity, locale, { minimumFractionDigits: 0 }),
unit_amount: MoneyDTOHelper.format(item.unit_amount, locale, moneyOptions),
subtotal_amount: MoneyDTOHelper.format(item.subtotal_amount, locale, moneyOptions),
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-snapshot-builder.ts
index 3b40ec6f..c4871fcd 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-snapshot-builder.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-snapshot-builder.ts
@@ -21,7 +21,7 @@ export class IssuedInvoiceReportSnapshotBuilder implements IIssuedInvoiceReportS
snapshot: IIssuedInvoiceFullSnapshot,
params?: ISnapshotBuilderParams
): IIssuedInvoiceReportSnapshot {
- const locale = params?.locale as string;
+ const locale = (params as { locale?: string } | undefined)?.locale ?? "es";
const moneyOptions = {
hideZeros: true,
@@ -33,6 +33,7 @@ export class IssuedInvoiceReportSnapshotBuilder implements IIssuedInvoiceReportS
company_id: snapshot.company_id,
company_slug: "rodax",
invoice_number: snapshot.invoice_number,
+ invoice_reference: snapshot.invoice_reference,
series: snapshot.series,
status: snapshot.status,
reference: snapshot.reference,
@@ -43,7 +44,7 @@ export class IssuedInvoiceReportSnapshotBuilder implements IIssuedInvoiceReportS
invoice_date: DateHelper.format(snapshot.invoice_date, locale),
payment_method: snapshot.payment_method?.payment_description ?? "",
- notes: snapshot.notes,
+ notes: snapshot.notes ?? "",
recipient: {
name: snapshot.recipient.name,
@@ -65,7 +66,8 @@ export class IssuedInvoiceReportSnapshotBuilder implements IIssuedInvoiceReportS
verifactu: {
...snapshot.verifactu,
- qr_code: snapshot.verifactu.qr_code.replace("data:image/png;base64,", ""),
+ url: snapshot.verifactu.url ?? "",
+ qr_code: (snapshot.verifactu.qr_code ?? "").replace("data:image/png;base64,", ""),
},
};
}
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-snapshot.interface.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-snapshot.interface.ts
index 4d43148e..70e3ed37 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-snapshot.interface.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-snapshot.interface.ts
@@ -6,9 +6,10 @@ export interface IIssuedInvoiceReportSnapshot {
company_id: string;
company_slug: string;
invoice_number: string;
+ invoice_reference: string;
series: string;
status: string;
- reference: string;
+ reference: string | null;
language_code: string;
currency_code: string;
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-tax-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-tax-snapshot-builder.ts
index bfd16691..4ea68d6d 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-tax-snapshot-builder.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/report/issued-invoice-report-tax-snapshot-builder.ts
@@ -15,7 +15,7 @@ export class IssuedInvoiceReportTaxSnapshotBuilder
taxes: IIssuedInvoiceTaxFullSnapshot[],
params?: ISnapshotBuilderParams
): IIssuedInvoiceReportTaxSnapshot[] {
- const locale = params?.locale as string;
+ const locale = (params as { locale?: string } | undefined)?.locale ?? "es";
const moneyOptions = {
hideZeros: true,
@@ -29,11 +29,11 @@ export class IssuedInvoiceReportTaxSnapshotBuilder
iva_percentage: PercentageDTOHelper.format(tax.iva_percentage, locale),
iva_amount: MoneyDTOHelper.format(tax.iva_amount, locale, moneyOptions),
- rec_code: tax.rec_code,
+ rec_code: tax.rec_code ?? "",
rec_percentage: PercentageDTOHelper.format(tax.rec_percentage, locale),
rec_amount: MoneyDTOHelper.format(tax.rec_amount, locale, moneyOptions),
- retention_code: tax.retention_code,
+ retention_code: tax.retention_code ?? "",
retention_percentage: PercentageDTOHelper.format(tax.retention_percentage, locale),
retention_amount: MoneyDTOHelper.format(tax.retention_amount, locale, moneyOptions),
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/summary/issued-invoice-summary-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/summary/issued-invoice-summary-snapshot-builder.ts
index 4998826c..cada9d78 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/summary/issued-invoice-summary-snapshot-builder.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/summary/issued-invoice-summary-snapshot-builder.ts
@@ -32,7 +32,10 @@ export class IssuedInvoiceSummarySnapshotBuilder implements IIssuedInvoiceSummar
id: invoice.id.toString(),
company_id: invoice.companyId.toString(),
+ document_series_id: maybeToNullable(invoice.documentSeriesId, (value) => value),
+ invoice_series_code: maybeToNullable(invoice.invoiceSeriesCode, (value) => value.toString()),
invoice_number: invoice.invoiceNumber.toString(),
+ invoice_reference: invoice.invoiceReference,
status: invoice.status.toPrimitive(),
series: maybeToEmptyString(invoice.series, (v) => v.toString()),
diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/summary/issued-invoice-summary-snapshot.interface.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/summary/issued-invoice-summary-snapshot.interface.ts
index ab2d3dbc..5df811f0 100644
--- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/summary/issued-invoice-summary-snapshot.interface.ts
+++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/summary/issued-invoice-summary-snapshot.interface.ts
@@ -5,7 +5,10 @@ export interface IIssuedInvoiceSummarySnapshot {
id: string;
company_id: string;
+ document_series_id: string | null;
+ invoice_series_code: string | null;
invoice_number: string;
+ invoice_reference: string;
status: string;
series: string;
diff --git a/modules/customer-invoices/src/api/application/proformas/models/proforma-summary.ts b/modules/customer-invoices/src/api/application/proformas/models/proforma-summary.ts
index e18f0585..bac5900f 100644
--- a/modules/customer-invoices/src/api/application/proformas/models/proforma-summary.ts
+++ b/modules/customer-invoices/src/api/application/proformas/models/proforma-summary.ts
@@ -13,6 +13,9 @@ export type ProformaSummary = {
id: UniqueID;
companyId: UniqueID;
+ documentSeriesId: Maybe;
+ proformaSeriesCode: Maybe;
+ proformaNumber: Maybe;
proformaReference: InvoiceNumber;
status: InvoiceStatus;
archivedAt: Maybe;
diff --git a/modules/customer-invoices/src/api/application/proformas/services/proforma-creator.ts b/modules/customer-invoices/src/api/application/proformas/services/proforma-creator.ts
index a8a4f619..4c51f66c 100644
--- a/modules/customer-invoices/src/api/application/proformas/services/proforma-creator.ts
+++ b/modules/customer-invoices/src/api/application/proformas/services/proforma-creator.ts
@@ -6,6 +6,7 @@ import {
type IProformaCreateProps,
type IProformaItemCreateProps,
InvoiceNumber,
+ InvoiceSerie,
Proforma,
ProformaTaxConfig,
} from "../../../domain";
@@ -98,6 +99,12 @@ export class ProformaCreator implements IProformaCreator {
return Result.fail(proformaNumberResult.error);
}
+ const proformaSeriesCodeResult = InvoiceSerie.create(numberResult.data.documentSeriesCode);
+
+ if (proformaSeriesCodeResult.isFailure) {
+ return Result.fail(proformaSeriesCodeResult.error);
+ }
+
const proformaReference = proformaReferenceResult.data;
// 2. Crear agregado
@@ -107,6 +114,7 @@ export class ProformaCreator implements IProformaCreator {
companyId,
archivedAt: Maybe.none(),
documentSeriesId: Maybe.some(numberResult.data.documentSeriesId),
+ proformaSeriesCode: Maybe.some(proformaSeriesCodeResult.data),
proformaNumber: Maybe.some(proformaNumberResult.data),
proformaReference,
targetInvoiceSeriesCode: resolvedPropsResult.data.targetInvoiceSeriesCode,
@@ -142,7 +150,10 @@ export class ProformaCreator implements IProformaCreator {
transaction?: unknown
): Promise<
Result<
- Omit,
+ Omit<
+ IProformaCreateProps,
+ "proformaReference" | "proformaNumber" | "documentSeriesId" | "proformaSeriesCode"
+ >,
Error
>
> {
diff --git a/modules/customer-invoices/src/api/application/proformas/services/proforma-document-properties-factory.ts b/modules/customer-invoices/src/api/application/proformas/services/proforma-document-properties-factory.ts
index e803945c..0552a8d5 100644
--- a/modules/customer-invoices/src/api/application/proformas/services/proforma-document-properties-factory.ts
+++ b/modules/customer-invoices/src/api/application/proformas/services/proforma-document-properties-factory.ts
@@ -14,7 +14,7 @@ export class ProformaDocumentPropertiesFactory
{
build(snapshot: ProformaReportSnapshot): IDocumentProperties {
return {
- title: snapshot.reference ?? `Proforma ${snapshot.series}${snapshot.invoice_number}`,
+ title: snapshot.reference ?? snapshot.proforma_reference,
subject: "proforma",
author: snapshot.company.legalName,
creator: "FactuGES ERP",
diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts
index ddb1c0bc..82934044 100644
--- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts
+++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts
@@ -40,6 +40,11 @@ export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder
id: proforma.id.toString(),
company_id: proforma.companyId.toString(),
+ document_series_id: maybeToNullable(proforma.documentSeriesId, (value) => value),
+ proforma_series_code: maybeToNullable(proforma.proformaSeriesCode, (value) =>
+ value.toString()
+ ),
+ proforma_number: maybeToNullable(proforma.proformaNumber, (value) => value.toString()),
proforma_reference: proforma.proformaReference.toString(),
status: proforma.status.toPrimitive() as ProformaFullSnapshot["status"],
archived_at: maybeToNullable(proforma.archivedAt, (value) => value.toISOString()),
diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/issue/issue-proforma-response.snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/issue/issue-proforma-response.snapshot-builder.ts
index c0767efa..0a156119 100644
--- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/issue/issue-proforma-response.snapshot-builder.ts
+++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/issue/issue-proforma-response.snapshot-builder.ts
@@ -12,8 +12,11 @@ export class IssueProformaResponseSnapshotBuilder implements IIssueProformaRespo
issued_invoice: {
id: invoice.id.toString(),
proforma_id: invoice.linkedProformaId.toString(),
+ document_series_id: invoice.documentSeriesId.getOrUndefined() ?? null,
+ invoice_series_code: invoice.series.toString(),
series: invoice.series.toString(),
invoice_number: invoice.invoiceNumber.toString(),
+ invoice_reference: invoice.invoiceReference,
invoice_date: invoice.invoiceDate.toDateString(),
status: "issued",
recipient: {
diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/report/proforma-report-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/report/proforma-report-snapshot-builder.ts
index 087c19a7..cf080192 100644
--- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/report/proforma-report-snapshot-builder.ts
+++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/report/proforma-report-snapshot-builder.ts
@@ -53,6 +53,7 @@ export class ProformaReportSnapshotBuilder implements IProformaReportSnapshotBui
return {
id: snapshot.id,
company_id: snapshot.company_id,
+ proforma_reference: snapshot.proforma_reference,
invoice_number: snapshot.invoice_number,
series: snapshot.series,
status: snapshot.status,
diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/report/proforma-report-snapshot.interface.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/report/proforma-report-snapshot.interface.ts
index bd467e12..dd1c3767 100644
--- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/report/proforma-report-snapshot.interface.ts
+++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/report/proforma-report-snapshot.interface.ts
@@ -5,6 +5,7 @@ import type { ProformaReportTaxSnapshot } from "./proforma-report-tax-snapshot.i
export interface ProformaReportSnapshot {
id: string;
company_id: string;
+ proforma_reference: string;
invoice_number: string;
series: string | null;
status: string;
diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/summary/proforma-summary-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/summary/proforma-summary-snapshot-builder.ts
index 26bf8dd1..bf40bfae 100644
--- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/summary/proforma-summary-snapshot-builder.ts
+++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/summary/proforma-summary-snapshot-builder.ts
@@ -15,11 +15,18 @@ export class ProformaSummarySnapshotBuilder implements IProformaSummarySnapshotB
id: proforma.id.toString(),
company_id: proforma.companyId.toString(),
+ document_series_id: maybeToNullable(proforma.documentSeriesId, (value) => value),
+ proforma_series_code: maybeToNullable(proforma.proformaSeriesCode, (value) =>
+ value.toString()
+ ),
+ proforma_number: maybeToNullable(proforma.proformaNumber, (value) => value.toString()),
proforma_reference: proforma.proformaReference.toString(),
status: proforma.status.toPrimitive() as ProformaSummaryDTO["status"],
archived_at: maybeToNullable(proforma.archivedAt, (value) => value.toISOString()),
- target_invoice_series_code: maybeToNullable(proforma.series, (value) => value.toString()),
- series: maybeToNullable(proforma.series, (value) => value.toString()),
+ target_invoice_series_code: maybeToNullable(proforma.targetInvoiceSeriesCode, (value) =>
+ value.toString()
+ ),
+ series: maybeToNullable(proforma.targetInvoiceSeriesCode, (value) => value.toString()),
proforma_date: proforma.proformaDate.toDateString(),
operation_date: maybeToNullable(proforma.operationDate, (value) => value.toDateString()),
diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts b/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts
index 1239ded9..652c0743 100644
--- a/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts
+++ b/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts
@@ -35,8 +35,10 @@ export interface IIssuedInvoiceCreateProps {
linkedProformaId: UniqueID; // <- id de la proforma padre en caso de issue
+ documentSeriesId: Maybe;
series: InvoiceSerie;
invoiceNumber: InvoiceNumber;
+ invoiceReference: string;
invoiceDate: UtcDate;
operationDate: Maybe;
@@ -151,6 +153,16 @@ export class IssuedInvoice
);
}
+ if (!props.invoiceReference.trim()) {
+ return Result.fail(
+ new DomainValidationError(
+ "MISSING_INVOICE_REFERENCE",
+ "invoiceReference",
+ "Issued invoice requires invoice reference"
+ )
+ );
+ }
+
return Result.ok();
}
@@ -194,6 +206,10 @@ export class IssuedInvoice
return this.props.linkedProformaId;
}
+ public get documentSeriesId(): Maybe {
+ return this.props.documentSeriesId;
+ }
+
public get status(): InvoiceStatus {
return this.props.status;
}
@@ -206,6 +222,10 @@ export class IssuedInvoice
return this.props.invoiceNumber;
}
+ public get invoiceReference(): string {
+ return this.props.invoiceReference;
+ }
+
public get invoiceDate(): UtcDate {
return this.props.invoiceDate;
}
diff --git a/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts b/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts
index b324ca98..deb1f2e3 100644
--- a/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts
+++ b/modules/customer-invoices/src/api/domain/proformas/aggregates/proforma.aggregate.ts
@@ -51,6 +51,7 @@ export interface IProformaCreateProps {
archivedAt: Maybe;
documentSeriesId: Maybe;
+ proformaSeriesCode: Maybe;
proformaNumber: Maybe;
proformaReference: InvoiceNumber;
targetInvoiceSeriesCode: Maybe;
@@ -105,6 +106,7 @@ export interface IProforma {
archivedAt: Maybe;
documentSeriesId: Maybe;
+ proformaSeriesCode: Maybe;
proformaNumber: Maybe;
targetInvoiceSeriesCode: Maybe;
proformaReference: InvoiceNumber;
@@ -266,6 +268,10 @@ export class Proforma extends AggregateRoot implements IP
return this.props.documentSeriesId;
}
+ public get proformaSeriesCode(): Maybe {
+ return this.props.proformaSeriesCode;
+ }
+
public get proformaNumber(): Maybe {
return this.props.proformaNumber;
}
diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/sequelize-issued-invoice.model.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/sequelize-issued-invoice.model.ts
index 6198a268..571086ab 100644
--- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/sequelize-issued-invoice.model.ts
+++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/sequelize-issued-invoice.model.ts
@@ -44,8 +44,10 @@ export class IssuedInvoiceModel extends Model<
declare status: string;
declare source_proforma_id: CreationOptional;
+ declare document_series_id: CreationOptional;
declare invoice_series_code: string;
declare invoice_number: string;
+ declare invoice_reference: string;
declare invoice_date: string;
declare operation_date: CreationOptional;
@@ -231,6 +233,13 @@ export default (database: Sequelize) => {
charset: "utf8mb4",
collate: "utf8mb4_bin",
} as any,
+ document_series_id: {
+ type: DataTypes.UUID,
+ allowNull: true,
+ defaultValue: null,
+ charset: "utf8mb4",
+ collate: "utf8mb4_bin",
+ } as any,
invoice_series_code: {
type: new DataTypes.STRING(10),
@@ -240,6 +249,10 @@ export default (database: Sequelize) => {
type: new DataTypes.STRING(12),
allowNull: false,
},
+ invoice_reference: {
+ type: new DataTypes.STRING(64),
+ allowNull: false,
+ },
invoice_date: {
type: new DataTypes.DATEONLY(),
allowNull: false,
@@ -502,6 +515,10 @@ export default (database: Sequelize) => {
name: "idx_issued_invoices_company",
fields: ["company_id"],
},
+ {
+ name: "idx_issued_invoices_document_series_id",
+ fields: ["document_series_id"],
+ },
{
name: "uq_issued_invoice_company_series_number",
fields: ["company_id", "invoice_series_code", "invoice_number"],
diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/sequelize-proforma.model.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/sequelize-proforma.model.ts
index 10c97489..0eae915e 100644
--- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/sequelize-proforma.model.ts
+++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/sequelize-proforma.model.ts
@@ -37,6 +37,7 @@ export class ProformaModel extends Model<
declare archived_at: CreationOptional;
declare document_series_id: CreationOptional;
+ declare proforma_series_code: CreationOptional;
declare proforma_number: CreationOptional;
declare proforma_reference: string;
declare proforma_date: string;
@@ -192,6 +193,11 @@ export default (database: Sequelize) => {
charset: "utf8mb4",
collate: "utf8mb4_bin",
} as any,
+ proforma_series_code: {
+ type: new DataTypes.STRING(10),
+ allowNull: true,
+ defaultValue: null,
+ },
proforma_number: {
type: new DataTypes.STRING(32),
allowNull: true,
@@ -479,6 +485,15 @@ export default (database: Sequelize) => {
name: "idx_proformas_company_document_series",
fields: ["company_id", "document_series_id"],
},
+ {
+ name: "idx_proformas_document_series_id",
+ fields: ["document_series_id"],
+ },
+ {
+ name: "uq_proformas_company_series_number",
+ fields: ["company_id", "proforma_series_code", "proforma_number"],
+ unique: true,
+ },
{
name: "uq_proformas_company_reference",
fields: ["company_id", "proforma_reference"],
diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/di/issued-invoice-public-services.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/di/issued-invoice-public-services.ts
index a9eac281..aa35e5c4 100644
--- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/di/issued-invoice-public-services.ts
+++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/di/issued-invoice-public-services.ts
@@ -60,7 +60,7 @@ export function buildIssuedInvoicePublicServices(
return Result.ok({
invoiceNumber: invoiceNumberResult.data,
- formattedNumber: assignResult.data.reference,
+ invoiceReference: assignResult.data.reference,
invoiceSeriesId: assignResult.data.series_id,
invoiceSeriesCode: assignedSeriesResult.data,
});
diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts
index 9b5b076b..ef7e55c2 100644
--- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts
+++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts
@@ -83,6 +83,11 @@ export class SequelizeIssuedInvoiceDomainMapper extends SequelizeDomainMapper<
"invoice_number",
errors
);
+ const invoiceReference = extractOrPushError(
+ Result.ok(`${String(raw.series ?? "")}${String(raw.invoice_number ?? "")}`),
+ "invoice_reference",
+ errors
+ );
// Fechas
const invoiceDate = extractOrPushError(
@@ -281,6 +286,7 @@ export class SequelizeIssuedInvoiceDomainMapper extends SequelizeDomainMapper<
status,
series,
invoiceNumber,
+ invoiceReference,
invoiceDate,
operationDate,
reference,
@@ -375,6 +381,7 @@ export class SequelizeIssuedInvoiceDomainMapper extends SequelizeDomainMapper<
status: attributes.status!,
series: attributes.series!,
invoiceNumber: attributes.invoiceNumber!,
+ invoiceReference: attributes.invoiceReference!,
invoiceDate: attributes.invoiceDate!,
operationDate: attributes.operationDate!,
diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.ts
index 9216cae6..0e4a2040 100644
--- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.ts
+++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.ts
@@ -62,6 +62,11 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper<
"source_proforma_id",
errors
);
+ const documentSeriesId = extractOrPushError(
+ maybeFromNullableResult(raw.document_series_id, (value) => Result.ok(String(value))),
+ "document_series_id",
+ errors
+ );
const status = extractOrPushError(InvoiceStatus.create(raw.status), "status", errors);
const series = extractOrPushError(
InvoiceSerie.create(raw.invoice_series_code ?? ""),
@@ -73,6 +78,11 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper<
"invoice_number",
errors
);
+ const invoiceReference = extractOrPushError(
+ Result.ok(String(raw.invoice_reference ?? "")),
+ "invoice_reference",
+ errors
+ );
const invoiceDate = extractOrPushError(
UtcDate.createFromISO(raw.invoice_date),
"invoice_date",
@@ -217,9 +227,11 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper<
companyId,
customerId,
linkedProformaId,
+ documentSeriesId,
status,
series,
invoiceNumber,
+ invoiceReference,
invoiceDate,
operationDate,
reference,
@@ -294,8 +306,10 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper<
const invoiceProps: InternalIssuedInvoiceProps = {
companyId: attributes.companyId!,
status: attributes.status!,
+ documentSeriesId: attributes.documentSeriesId!,
series: attributes.series!,
invoiceNumber: attributes.invoiceNumber!,
+ invoiceReference: attributes.invoiceReference!,
invoiceDate: attributes.invoiceDate!,
operationDate: attributes.operationDate!,
customerId: attributes.customerId!,
@@ -372,8 +386,10 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper<
company_id: source.companyId.toPrimitive(),
status: source.status.toPrimitive(),
source_proforma_id: source.linkedProformaId.toPrimitive(),
+ document_series_id: maybeToNullable(source.documentSeriesId, (value) => value),
invoice_series_code: source.series.toPrimitive(),
invoice_number: source.invoiceNumber.toPrimitive(),
+ invoice_reference: source.invoiceReference,
invoice_date: source.invoiceDate.toPrimitive(),
operation_date: maybeToNullable(source.operationDate, (v) => v.toPrimitive()),
language_code: source.languageCode.toPrimitive(),
diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/summary/sequelize-issued-invoice-summary.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/summary/sequelize-issued-invoice-summary.mapper.ts
index 6304fb61..c4fc13f5 100644
--- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/summary/sequelize-issued-invoice-summary.mapper.ts
+++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/summary/sequelize-issued-invoice-summary.mapper.ts
@@ -92,6 +92,7 @@ export class SequelizeIssuedInvoiceSummaryMapper extends SequelizeQueryMapper<
status: attributes.status!,
series: attributes.series!,
invoiceNumber: attributes.invoiceNumber!,
+ invoiceReference: attributes.invoiceReference!,
invoiceDate: attributes.invoiceDate!,
operationDate: attributes.operationDate!,
@@ -141,6 +142,11 @@ export class SequelizeIssuedInvoiceSummaryMapper extends SequelizeQueryMapper<
"invoice_number",
errors
);
+ const invoiceReference = extractOrPushError(
+ Result.ok(`${String(raw.series ?? "")}${String(raw.invoice_number ?? "")}`),
+ "invoice_reference",
+ errors
+ );
const invoiceDate = extractOrPushError(
UtcDate.createFromISO(raw.invoice_date),
@@ -237,6 +243,7 @@ export class SequelizeIssuedInvoiceSummaryMapper extends SequelizeQueryMapper<
status,
series,
invoiceNumber,
+ invoiceReference,
invoiceDate,
operationDate,
reference,
diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/summary/sequelize-issued-invoice-v2-summary.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/summary/sequelize-issued-invoice-v2-summary.mapper.ts
index ce7fa101..87cb807b 100644
--- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/summary/sequelize-issued-invoice-v2-summary.mapper.ts
+++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/summary/sequelize-issued-invoice-v2-summary.mapper.ts
@@ -75,9 +75,12 @@ export class SequelizeIssuedInvoiceV2SummaryMapper extends SequelizeQueryMapper<
id: attributes.invoiceId!,
companyId: attributes.companyId!,
isProforma: false,
+ documentSeriesId: attributes.documentSeriesId!,
+ invoiceSeriesCode: attributes.series!,
status: attributes.status!,
series: attributes.series!,
invoiceNumber: attributes.invoiceNumber!,
+ invoiceReference: attributes.invoiceReference!,
invoiceDate: attributes.invoiceDate!,
operationDate: attributes.operationDate!,
description: attributes.description!,
@@ -102,6 +105,11 @@ export class SequelizeIssuedInvoiceV2SummaryMapper extends SequelizeQueryMapper<
const invoiceId = extractOrPushError(UniqueID.create(raw.id), "id", errors);
const companyId = extractOrPushError(UniqueID.create(raw.company_id), "company_id", errors);
const customerId = extractOrPushError(UniqueID.create(raw.customer_id), "customer_id", errors);
+ const documentSeriesId = extractOrPushError(
+ maybeFromNullableResult(raw.document_series_id, (value) => Result.ok(String(value))),
+ "document_series_id",
+ errors
+ );
const status = extractOrPushError(InvoiceStatus.create(raw.status), "status", errors);
const series = extractOrPushError(
maybeFromNullableResult(raw.invoice_series_code, (value) => InvoiceSerie.create(value)),
@@ -113,6 +121,11 @@ export class SequelizeIssuedInvoiceV2SummaryMapper extends SequelizeQueryMapper<
"invoice_number",
errors
);
+ const invoiceReference = extractOrPushError(
+ Result.ok(String(raw.invoice_reference ?? "")),
+ "invoice_reference",
+ errors
+ );
const invoiceDate = extractOrPushError(
UtcDate.createFromISO(raw.invoice_date),
"invoice_date",
@@ -182,9 +195,11 @@ export class SequelizeIssuedInvoiceV2SummaryMapper extends SequelizeQueryMapper<
invoiceId,
companyId,
customerId,
+ documentSeriesId,
status,
series,
invoiceNumber,
+ invoiceReference,
invoiceDate,
operationDate,
reference,
diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/repositories/issued-invoice-v2.repository.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/repositories/issued-invoice-v2.repository.ts
index 8669587a..188fbede 100644
--- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/repositories/issued-invoice-v2.repository.ts
+++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/repositories/issued-invoice-v2.repository.ts
@@ -175,10 +175,11 @@ export class SequelizeIssuedInvoiceRepositoryV2
try {
const criteriaConverter = new CriteriaToSequelizeConverter();
const criteriaQuery = criteriaConverter.convert(criteria, {
- searchableFields: ["invoice_number", "reference", "description"],
+ searchableFields: ["invoice_number", "invoice_reference", "reference", "description"],
mappings: {
invoice_date: { type: "root", column: "invoice_date" },
invoice_number: { type: "root", column: "invoice_number" },
+ invoice_reference: { type: "root", column: "invoice_reference" },
reference: { type: "root", column: "reference" },
description: { type: "root", column: "description" },
recipient_name: { type: "root", column: "customer_name" },
diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/documents/services/proforma-html-preview-document-metadata-factory.ts b/modules/customer-invoices/src/api/infrastructure/proformas/documents/services/proforma-html-preview-document-metadata-factory.ts
index 0158c9b5..a3b40b5f 100644
--- a/modules/customer-invoices/src/api/infrastructure/proformas/documents/services/proforma-html-preview-document-metadata-factory.ts
+++ b/modules/customer-invoices/src/api/infrastructure/proformas/documents/services/proforma-html-preview-document-metadata-factory.ts
@@ -13,7 +13,7 @@ export class ProformaHtmlPreviewDocumentMetadataFactory
companySlug: snapshot.company.slug,
format: "HTML",
languageCode: snapshot.localization.languageCode,
- filename: `proforma-${snapshot.series}${snapshot.invoice_number}.html`,
+ filename: `proforma-${snapshot.proforma_reference}.html`,
};
}
}
diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/documents/services/proforma-pdf-document-metadata-factory.ts b/modules/customer-invoices/src/api/infrastructure/proformas/documents/services/proforma-pdf-document-metadata-factory.ts
index c83d2f22..faa35e0f 100644
--- a/modules/customer-invoices/src/api/infrastructure/proformas/documents/services/proforma-pdf-document-metadata-factory.ts
+++ b/modules/customer-invoices/src/api/infrastructure/proformas/documents/services/proforma-pdf-document-metadata-factory.ts
@@ -13,7 +13,7 @@ export class ProformaPdfDocumentMetadataFactory
companySlug: snapshot.company.slug,
format: "PDF",
languageCode: snapshot.localization.languageCode,
- filename: `proforma-${snapshot.series}${snapshot.invoice_number}.pdf`,
+ filename: `proforma-${snapshot.proforma_reference}.pdf`,
storageKey: this.buildStorageKey(snapshot),
};
}
diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-v2-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-v2-domain.mapper.ts
index da1a3f13..492b9793 100644
--- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-v2-domain.mapper.ts
+++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-v2-domain.mapper.ts
@@ -61,6 +61,11 @@ export class SequelizeProformaV2DomainMapper extends SequelizeDomainMapper<
"document_series_id",
errors
);
+ const proformaSeriesCode = extractOrPushError(
+ maybeFromNullableResult(raw.proforma_series_code, (value) => InvoiceSerie.create(value)),
+ "proforma_series_code",
+ errors
+ );
const targetInvoiceSeriesCode = extractOrPushError(
maybeFromNullableResult(raw.target_invoice_series_code, (value) =>
InvoiceSerie.create(value)
@@ -167,6 +172,7 @@ export class SequelizeProformaV2DomainMapper extends SequelizeDomainMapper<
status,
archivedAt,
documentSeriesId,
+ proformaSeriesCode,
proformaNumber,
targetInvoiceSeriesCode,
proformaReference,
@@ -220,6 +226,7 @@ export class SequelizeProformaV2DomainMapper extends SequelizeDomainMapper<
status: attributes.status!,
archivedAt: attributes.archivedAt!,
documentSeriesId: attributes.documentSeriesId!,
+ proformaSeriesCode: attributes.proformaSeriesCode!,
proformaNumber: attributes.proformaNumber!,
targetInvoiceSeriesCode: attributes.targetInvoiceSeriesCode!,
proformaReference: attributes.proformaReference!,
@@ -286,6 +293,9 @@ export class SequelizeProformaV2DomainMapper extends SequelizeDomainMapper<
status: source.status.toPrimitive(),
archived_at: maybeToNullable(source.archivedAt, (value) => value.toPrimitive()),
document_series_id: maybeToNullable(source.documentSeriesId, (value) => value),
+ proforma_series_code: maybeToNullable(source.proformaSeriesCode, (value) =>
+ value.toPrimitive()
+ ),
proforma_number: maybeToNullable(source.proformaNumber, (value) => value.toPrimitive()),
proforma_reference: source.proformaReference.toPrimitive(),
proforma_date: source.proformaDate.toPrimitive(),
diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/summary/sequelize-proforma-v2-summary.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/summary/sequelize-proforma-v2-summary.mapper.ts
index ffb97334..b5888fe0 100644
--- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/summary/sequelize-proforma-v2-summary.mapper.ts
+++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/summary/sequelize-proforma-v2-summary.mapper.ts
@@ -59,6 +59,9 @@ export class SequelizeProformaV2SummaryMapper extends SequelizeQueryMapper<
return Result.ok({
id: attributes.invoiceId!,
companyId: attributes.companyId!,
+ documentSeriesId: attributes.documentSeriesId!,
+ proformaSeriesCode: attributes.proformaSeriesCode!,
+ proformaNumber: attributes.proformaNumber!,
status: attributes.status!,
archivedAt: attributes.archivedAt!,
targetInvoiceSeriesCode: attributes.targetInvoiceSeriesCode!,
@@ -92,6 +95,21 @@ export class SequelizeProformaV2SummaryMapper extends SequelizeQueryMapper<
"archived_at",
errors
);
+ const documentSeriesId = extractOrPushError(
+ maybeFromNullableResult(raw.document_series_id, (value) => Result.ok(String(value))),
+ "document_series_id",
+ errors
+ );
+ const proformaSeriesCode = extractOrPushError(
+ maybeFromNullableResult(raw.proforma_series_code, (value) => InvoiceSerie.create(value)),
+ "proforma_series_code",
+ errors
+ );
+ const proformaNumber = extractOrPushError(
+ maybeFromNullableResult(raw.proforma_number, (value) => InvoiceNumber.create(value)),
+ "proforma_number",
+ errors
+ );
const targetInvoiceSeriesCode = extractOrPushError(
maybeFromNullableResult(raw.target_invoice_series_code, (value) =>
InvoiceSerie.create(value)
@@ -172,6 +190,9 @@ export class SequelizeProformaV2SummaryMapper extends SequelizeQueryMapper<
invoiceId,
companyId,
customerId,
+ documentSeriesId,
+ proformaSeriesCode,
+ proformaNumber,
status,
archivedAt,
targetInvoiceSeriesCode,
diff --git a/modules/customer-invoices/src/common/dto/response/issued-invoices/get-issued-invoice-by-id.response.dto.ts b/modules/customer-invoices/src/common/dto/response/issued-invoices/get-issued-invoice-by-id.response.dto.ts
index 36df02c1..00728f78 100644
--- a/modules/customer-invoices/src/common/dto/response/issued-invoices/get-issued-invoice-by-id.response.dto.ts
+++ b/modules/customer-invoices/src/common/dto/response/issued-invoices/get-issued-invoice-by-id.response.dto.ts
@@ -22,7 +22,10 @@ export const GetIssuedInvoiceByIdResponseSchema = z.object({
id: z.uuid(),
company_id: z.uuid(),
+ document_series_id: z.uuid().nullable(),
+ invoice_series_code: z.string().nullable(),
invoice_number: z.string(),
+ invoice_reference: z.string(),
status: IssuedInvoiceStatusSchema,
series: z.string(),
diff --git a/modules/customer-invoices/src/common/dto/response/proformas/get-proforma-by-id.response.dto.ts b/modules/customer-invoices/src/common/dto/response/proformas/get-proforma-by-id.response.dto.ts
index f8769f01..4dc531ed 100644
--- a/modules/customer-invoices/src/common/dto/response/proformas/get-proforma-by-id.response.dto.ts
+++ b/modules/customer-invoices/src/common/dto/response/proformas/get-proforma-by-id.response.dto.ts
@@ -25,6 +25,9 @@ export const GetProformaByIdResponseSchema = z.object({
id: z.uuid(),
company_id: z.uuid(),
+ document_series_id: z.uuid().nullable(),
+ proforma_series_code: z.string().nullable(),
+ proforma_number: z.string().nullable(),
proforma_reference: z.string(),
status: ProformaStatusSchema,
archived_at: z.iso.datetime().nullable(),
diff --git a/modules/customer-invoices/src/common/dto/response/proformas/issue-proforma-by-id.response.dto.ts b/modules/customer-invoices/src/common/dto/response/proformas/issue-proforma-by-id.response.dto.ts
index 5672821d..26450963 100644
--- a/modules/customer-invoices/src/common/dto/response/proformas/issue-proforma-by-id.response.dto.ts
+++ b/modules/customer-invoices/src/common/dto/response/proformas/issue-proforma-by-id.response.dto.ts
@@ -19,8 +19,11 @@ export const IssueProformaIssuedInvoiceTotalsSchema = z.object({
export const IssueProformaIssuedInvoiceSchema = z.object({
id: z.uuid(),
proforma_id: z.uuid().nullable(),
+ document_series_id: z.uuid().nullable(),
+ invoice_series_code: z.string(),
series: z.string(),
invoice_number: z.string(),
+ invoice_reference: z.string(),
invoice_date: IsoDateSchema,
status: IssuedInvoiceStatusSchema,
recipient: IssueProformaIssuedInvoiceRecipientSchema,
diff --git a/modules/customer-invoices/src/common/dto/shared/issued-invoices/issued-invoice-summary.dto.ts b/modules/customer-invoices/src/common/dto/shared/issued-invoices/issued-invoice-summary.dto.ts
index bd87eba5..2bc361c8 100644
--- a/modules/customer-invoices/src/common/dto/shared/issued-invoices/issued-invoice-summary.dto.ts
+++ b/modules/customer-invoices/src/common/dto/shared/issued-invoices/issued-invoice-summary.dto.ts
@@ -9,7 +9,10 @@ export const IssuedInvoiceSummarySchema = z.object({
id: z.uuid(),
company_id: z.uuid(),
+ document_series_id: z.uuid().nullable(),
+ invoice_series_code: z.string().nullable(),
invoice_number: z.string(),
+ invoice_reference: z.string(),
status: IssuedInvoiceStatusSchema,
series: z.string(),
diff --git a/modules/customer-invoices/src/common/dto/shared/proforma/proforma-summary.dto.ts b/modules/customer-invoices/src/common/dto/shared/proforma/proforma-summary.dto.ts
index 32f13b9c..b5742d85 100644
--- a/modules/customer-invoices/src/common/dto/shared/proforma/proforma-summary.dto.ts
+++ b/modules/customer-invoices/src/common/dto/shared/proforma/proforma-summary.dto.ts
@@ -8,6 +8,9 @@ export const ProformaSummarySchema = z.object({
id: z.uuid(),
company_id: z.uuid(),
+ document_series_id: z.uuid().nullable(),
+ proforma_series_code: z.string().nullable(),
+ proforma_number: z.string().nullable(),
proforma_reference: z.string(),
status: ProformaStatusSchema,
archived_at: z.iso.datetime().nullable(),