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 ERP\n
\n\n
\n

\n Mi Empresa\n

\n
\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
\n \n \n \n
\n
\n\n
\n \n \n \n 3\n \n \n\n \n \n \n 7\n \n \n\n \n \n \n \n AM\n \n \n \n Ana Martínez\n \n \n Administrador\n \n \n \n \n \n\n \n Mi cuenta\n \n Perfil\n Preferencias\n Cerrar sesión\n \n \n
\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(),