@dwast/verifactu-lib 0.1.0-beta.1 → 0.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/dist/cjs/aeat/client.d.ts +118 -13
  2. package/dist/cjs/aeat/client.d.ts.map +1 -1
  3. package/dist/cjs/aeat/client.js +221 -45
  4. package/dist/cjs/aeat/client.js.map +1 -1
  5. package/dist/cjs/aeat/index.d.ts +1 -0
  6. package/dist/cjs/aeat/index.d.ts.map +1 -1
  7. package/dist/cjs/aeat/index.js +1 -0
  8. package/dist/cjs/aeat/index.js.map +1 -1
  9. package/dist/cjs/aeat/response.d.ts +78 -0
  10. package/dist/cjs/aeat/response.d.ts.map +1 -0
  11. package/dist/cjs/aeat/response.js +117 -0
  12. package/dist/cjs/aeat/response.js.map +1 -0
  13. package/dist/cjs/core/hash/chain.d.ts +42 -0
  14. package/dist/cjs/core/hash/chain.d.ts.map +1 -1
  15. package/dist/cjs/core/hash/chain.js +40 -0
  16. package/dist/cjs/core/hash/chain.js.map +1 -1
  17. package/dist/cjs/core/index.d.ts +2 -0
  18. package/dist/cjs/core/index.d.ts.map +1 -1
  19. package/dist/cjs/core/index.js +2 -0
  20. package/dist/cjs/core/index.js.map +1 -1
  21. package/dist/cjs/core/models/invoice.d.ts +42 -17
  22. package/dist/cjs/core/models/invoice.d.ts.map +1 -1
  23. package/dist/cjs/core/utils/date.d.ts +16 -0
  24. package/dist/cjs/core/utils/date.d.ts.map +1 -0
  25. package/dist/cjs/core/utils/date.js +27 -0
  26. package/dist/cjs/core/utils/date.js.map +1 -0
  27. package/dist/cjs/core/utils/index.d.ts +2 -0
  28. package/dist/cjs/core/utils/index.d.ts.map +1 -0
  29. package/dist/cjs/core/utils/index.js +18 -0
  30. package/dist/cjs/core/utils/index.js.map +1 -0
  31. package/dist/cjs/core/validation/index.d.ts +2 -0
  32. package/dist/cjs/core/validation/index.d.ts.map +1 -0
  33. package/dist/cjs/core/validation/index.js +18 -0
  34. package/dist/cjs/core/validation/index.js.map +1 -0
  35. package/dist/cjs/core/validation/validate.d.ts +18 -0
  36. package/dist/cjs/core/validation/validate.d.ts.map +1 -0
  37. package/dist/cjs/core/validation/validate.js +65 -0
  38. package/dist/cjs/core/validation/validate.js.map +1 -0
  39. package/dist/cjs/core/xml/generator.d.ts +119 -11
  40. package/dist/cjs/core/xml/generator.d.ts.map +1 -1
  41. package/dist/cjs/core/xml/generator.js +226 -64
  42. package/dist/cjs/core/xml/generator.js.map +1 -1
  43. package/dist/cjs/integration/accountability.d.ts +41 -0
  44. package/dist/cjs/integration/accountability.d.ts.map +1 -0
  45. package/dist/cjs/integration/accountability.js +92 -0
  46. package/dist/cjs/integration/accountability.js.map +1 -0
  47. package/dist/cjs/integration/index.d.ts +2 -0
  48. package/dist/cjs/integration/index.d.ts.map +1 -1
  49. package/dist/cjs/integration/index.js +2 -0
  50. package/dist/cjs/integration/index.js.map +1 -1
  51. package/dist/cjs/integration/p12.d.ts +58 -0
  52. package/dist/cjs/integration/p12.d.ts.map +1 -0
  53. package/dist/cjs/integration/p12.js +127 -0
  54. package/dist/cjs/integration/p12.js.map +1 -0
  55. package/dist/cjs/integration/repository.d.ts +2 -0
  56. package/dist/cjs/integration/repository.d.ts.map +1 -1
  57. package/dist/cjs/integration/service.d.ts +11 -2
  58. package/dist/cjs/integration/service.d.ts.map +1 -1
  59. package/dist/cjs/integration/service.js +99 -13
  60. package/dist/cjs/integration/service.js.map +1 -1
  61. package/dist/cjs/integration/tenant-credentials.d.ts +44 -0
  62. package/dist/cjs/integration/tenant-credentials.d.ts.map +1 -0
  63. package/dist/cjs/integration/tenant-credentials.js +62 -0
  64. package/dist/cjs/integration/tenant-credentials.js.map +1 -0
  65. package/dist/esm/aeat/client.d.ts +118 -13
  66. package/dist/esm/aeat/client.d.ts.map +1 -1
  67. package/dist/esm/aeat/client.js +216 -44
  68. package/dist/esm/aeat/client.js.map +1 -1
  69. package/dist/esm/aeat/index.d.ts +1 -0
  70. package/dist/esm/aeat/index.d.ts.map +1 -1
  71. package/dist/esm/aeat/index.js +1 -0
  72. package/dist/esm/aeat/index.js.map +1 -1
  73. package/dist/esm/aeat/response.d.ts +78 -0
  74. package/dist/esm/aeat/response.d.ts.map +1 -0
  75. package/dist/esm/aeat/response.js +114 -0
  76. package/dist/esm/aeat/response.js.map +1 -0
  77. package/dist/esm/core/hash/chain.d.ts +42 -0
  78. package/dist/esm/core/hash/chain.d.ts.map +1 -1
  79. package/dist/esm/core/hash/chain.js +37 -0
  80. package/dist/esm/core/hash/chain.js.map +1 -1
  81. package/dist/esm/core/index.d.ts +2 -0
  82. package/dist/esm/core/index.d.ts.map +1 -1
  83. package/dist/esm/core/index.js +2 -0
  84. package/dist/esm/core/index.js.map +1 -1
  85. package/dist/esm/core/models/invoice.d.ts +42 -17
  86. package/dist/esm/core/models/invoice.d.ts.map +1 -1
  87. package/dist/esm/core/utils/date.d.ts +16 -0
  88. package/dist/esm/core/utils/date.d.ts.map +1 -0
  89. package/dist/esm/core/utils/date.js +24 -0
  90. package/dist/esm/core/utils/date.js.map +1 -0
  91. package/dist/esm/core/utils/index.d.ts +2 -0
  92. package/dist/esm/core/utils/index.d.ts.map +1 -0
  93. package/dist/esm/core/utils/index.js +2 -0
  94. package/dist/esm/core/utils/index.js.map +1 -0
  95. package/dist/esm/core/validation/index.d.ts +2 -0
  96. package/dist/esm/core/validation/index.d.ts.map +1 -0
  97. package/dist/esm/core/validation/index.js +2 -0
  98. package/dist/esm/core/validation/index.js.map +1 -0
  99. package/dist/esm/core/validation/validate.d.ts +18 -0
  100. package/dist/esm/core/validation/validate.d.ts.map +1 -0
  101. package/dist/esm/core/validation/validate.js +62 -0
  102. package/dist/esm/core/validation/validate.js.map +1 -0
  103. package/dist/esm/core/xml/generator.d.ts +119 -11
  104. package/dist/esm/core/xml/generator.d.ts.map +1 -1
  105. package/dist/esm/core/xml/generator.js +220 -64
  106. package/dist/esm/core/xml/generator.js.map +1 -1
  107. package/dist/esm/integration/accountability.d.ts +41 -0
  108. package/dist/esm/integration/accountability.d.ts.map +1 -0
  109. package/dist/esm/integration/accountability.js +88 -0
  110. package/dist/esm/integration/accountability.js.map +1 -0
  111. package/dist/esm/integration/index.d.ts +2 -0
  112. package/dist/esm/integration/index.d.ts.map +1 -1
  113. package/dist/esm/integration/index.js +2 -0
  114. package/dist/esm/integration/index.js.map +1 -1
  115. package/dist/esm/integration/p12.d.ts +58 -0
  116. package/dist/esm/integration/p12.d.ts.map +1 -0
  117. package/dist/esm/integration/p12.js +119 -0
  118. package/dist/esm/integration/p12.js.map +1 -0
  119. package/dist/esm/integration/repository.d.ts +2 -0
  120. package/dist/esm/integration/repository.d.ts.map +1 -1
  121. package/dist/esm/integration/service.d.ts +11 -2
  122. package/dist/esm/integration/service.d.ts.map +1 -1
  123. package/dist/esm/integration/service.js +101 -15
  124. package/dist/esm/integration/service.js.map +1 -1
  125. package/dist/esm/integration/tenant-credentials.d.ts +44 -0
  126. package/dist/esm/integration/tenant-credentials.d.ts.map +1 -0
  127. package/dist/esm/integration/tenant-credentials.js +58 -0
  128. package/dist/esm/integration/tenant-credentials.js.map +1 -0
  129. package/package.json +3 -1
  130. package/readme.md +566 -42
  131. package/src/aeat/client.ts +296 -55
  132. package/src/aeat/index.ts +1 -0
  133. package/src/aeat/response.ts +195 -0
  134. package/src/core/hash/chain.ts +68 -0
  135. package/src/core/index.ts +2 -0
  136. package/src/core/models/invoice.ts +40 -18
  137. package/src/core/utils/date.ts +27 -0
  138. package/src/core/utils/index.ts +1 -0
  139. package/src/core/validation/index.ts +1 -0
  140. package/src/core/validation/validate.ts +71 -0
  141. package/src/core/xml/generator.ts +306 -73
  142. package/src/integration/accountability.ts +125 -0
  143. package/src/integration/index.ts +2 -0
  144. package/src/integration/p12.ts +155 -0
  145. package/src/integration/repository.ts +2 -0
  146. package/src/integration/service.ts +113 -14
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Respuesta de AEAT para un registro de facturación (alta/anulación).
3
+ *
4
+ * AEAT devuelve un SOAP XML; este tipo es el resultado normalizado a JSON
5
+ * para que el sistema consumidor lo persista y lo maneje con facilidad.
6
+ */
7
+ export interface RegistroResponse {
8
+ /** Estado del registro devuelto por AEAT. */
9
+ estadoRegistro?: string;
10
+ /** Código de error del registro (si lo hay). */
11
+ codigoErrorRegistro?: string;
12
+ /** Descripción del error del registro (si lo hay). */
13
+ descripcionErrorRegistro?: string;
14
+ /** CSV (Código Seguro de Verificación) si AEAT lo devuelve. */
15
+ csv?: string;
16
+ /** Huella (hash) del registro confirmado por AEAT. */
17
+ huella?: string;
18
+ /** Fecha/hora de generación del registro en AEAT. */
19
+ fechaHoraHusoGenRegistro?: string;
20
+ /** Identificador de la factura (si AEAT lo devuelve). */
21
+ idFactura?: string;
22
+ }
23
+ /**
24
+ * Respuesta de AEAT para una consulta de estado de operación.
25
+ */
26
+ export interface ConsultaResponse {
27
+ /** Estado de la operación consultada. */
28
+ estado?: string;
29
+ /** Código de error (si lo hay). */
30
+ codigoError?: string;
31
+ /** Descripción del error (si lo hay). */
32
+ descripcionError?: string;
33
+ /** CSV de la operación consultada. */
34
+ csv?: string;
35
+ /** Huella (hash) de la operación consultada. */
36
+ huella?: string;
37
+ /** Registros devueltos por la consulta. */
38
+ registros?: RegistroResponse[];
39
+ }
40
+ /**
41
+ * Respuesta de AEAT para un registro de evento.
42
+ */
43
+ export interface EventoResponse {
44
+ /** Estado del evento devuelto por AEAT. */
45
+ estadoEvento?: string;
46
+ /** Código de error del evento (si lo hay). */
47
+ codigoErrorEvento?: string;
48
+ /** Descripción del error del evento (si lo hay). */
49
+ descripcionErrorEvento?: string;
50
+ /** CSV del evento si AEAT lo devuelve. */
51
+ csv?: string;
52
+ /** Huella (hash) del evento confirmado por AEAT. */
53
+ huella?: string;
54
+ }
55
+ /**
56
+ * Resultado normalizado de una respuesta SOAP de AEAT.
57
+ */
58
+ export interface SoapResponse {
59
+ /** Nombre del elemento raíz del body SOAP (p. ej. `RespuestaRegFactuSistemaFacturacion`). */
60
+ operation: string;
61
+ /** Objeto JSON completo parseado del body SOAP. */
62
+ body: Record<string, unknown>;
63
+ /** Respuesta tipada de registro (si la operación es de registro). */
64
+ registro?: RegistroResponse;
65
+ /** Respuesta tipada de consulta (si la operación es de consulta). */
66
+ consulta?: ConsultaResponse;
67
+ /** Respuesta tipada de evento (si la operación es de evento). */
68
+ evento?: EventoResponse;
69
+ }
70
+ /**
71
+ * Convierte un XML SOAP de AEAT a un objeto JSON normalizado.
72
+ *
73
+ * Extrae el body del sobre SOAP y mapea los campos a las interfaces tipadas
74
+ * (`RegistroResponse`, `ConsultaResponse`, `EventoResponse`). Si el XML no
75
+ * es parseable, devuelve `null`.
76
+ */
77
+ export declare function parseSoapResponse(xml: string): SoapResponse | null;
78
+ //# sourceMappingURL=response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../src/aeat/response.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6CAA6C;IAC7C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sDAAsD;IACtD,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sCAAsC;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,0CAA0C;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,iEAAiE;IACjE,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAUD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAqClE"}
@@ -0,0 +1,114 @@
1
+ import { XMLParser } from 'fast-xml-parser';
2
+ const parser = new XMLParser({
3
+ ignoreAttributes: false,
4
+ attributeNamePrefix: '@_',
5
+ removeNSPrefix: true,
6
+ parseTagValue: false,
7
+ trimValues: true,
8
+ });
9
+ /**
10
+ * Convierte un XML SOAP de AEAT a un objeto JSON normalizado.
11
+ *
12
+ * Extrae el body del sobre SOAP y mapea los campos a las interfaces tipadas
13
+ * (`RegistroResponse`, `ConsultaResponse`, `EventoResponse`). Si el XML no
14
+ * es parseable, devuelve `null`.
15
+ */
16
+ export function parseSoapResponse(xml) {
17
+ // Solo procesar si parece XML (evita parsear JSON u otros textos).
18
+ if (typeof xml !== 'string' || !xml.trim().startsWith('<')) {
19
+ return null;
20
+ }
21
+ let parsed;
22
+ try {
23
+ parsed = parser.parse(xml);
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ // Navegar hasta el body del sobre SOAP (removeNSPrefix elimina el prefijo).
29
+ const envelope = (parsed['Envelope'] ?? parsed);
30
+ const body = (envelope['Body'] ?? envelope);
31
+ // El body contiene un único elemento de operación.
32
+ const keys = Object.keys(body).filter((k) => k !== 'Body');
33
+ const operation = keys[0] ?? '';
34
+ const opBody = body[operation];
35
+ const result = {
36
+ operation,
37
+ body: (opBody ?? body),
38
+ };
39
+ // Mapear según el tipo de operación.
40
+ if (/RegFactu|Registro/i.test(operation)) {
41
+ result.registro = mapRegistro(opBody);
42
+ }
43
+ else if (/Consulta/i.test(operation)) {
44
+ result.consulta = mapConsulta(opBody);
45
+ }
46
+ else if (/Evento/i.test(operation)) {
47
+ result.evento = mapEvento(opBody);
48
+ }
49
+ return result;
50
+ }
51
+ function mapRegistro(opBody) {
52
+ if (!opBody)
53
+ return undefined;
54
+ const rf = (opBody['RegistroFactura'] ?? opBody);
55
+ return {
56
+ estadoRegistro: str(rf['EstadoRegistro']),
57
+ codigoErrorRegistro: str(rf['CodigoErrorRegistro']),
58
+ descripcionErrorRegistro: str(rf['DescripcionErrorRegistro']),
59
+ csv: str(rf['CSV']),
60
+ huella: str(rf['Huella']),
61
+ fechaHoraHusoGenRegistro: str(rf['FechaHoraHusoGenRegistro']),
62
+ idFactura: str(rf['IDFactura']),
63
+ };
64
+ }
65
+ function mapConsulta(opBody) {
66
+ if (!opBody)
67
+ return undefined;
68
+ // La consulta devuelve los registros en `RegistroRespuestaConsultaFactuSistemaFacturacion`
69
+ // (o `RegistroFactura`/`Registros` en otros formatos).
70
+ const registrosRaw = opBody['RegistroRespuestaConsultaFactuSistemaFacturacion'] ??
71
+ opBody['RegistroFactura'] ??
72
+ opBody['Registros'];
73
+ const registros = Array.isArray(registrosRaw)
74
+ ? registrosRaw.map((r) => mapRegistroConsulta(r)).filter(Boolean)
75
+ : registrosRaw
76
+ ? [mapRegistroConsulta(registrosRaw)]
77
+ : undefined;
78
+ return {
79
+ estado: str(opBody['Estado']),
80
+ codigoError: str(opBody['CodigoError']),
81
+ descripcionError: str(opBody['DescripcionError']),
82
+ csv: str(opBody['CSV']),
83
+ huella: registros?.[0]?.huella,
84
+ registros: registros,
85
+ };
86
+ }
87
+ /** Mapea un registro de la respuesta de consulta (con `DatosRegistroFacturacion`). */
88
+ function mapRegistroConsulta(raw) {
89
+ const datos = (raw['DatosRegistroFacturacion'] ?? raw);
90
+ const estado = (raw['EstadoRegistro'] ?? {});
91
+ return {
92
+ estadoRegistro: str(estado['EstadoRegistro']),
93
+ huella: str(datos['Huella']),
94
+ fechaHoraHusoGenRegistro: str(datos['FechaHoraHusoGenRegistro']),
95
+ idFactura: str(raw['IDFactura']),
96
+ };
97
+ }
98
+ function mapEvento(opBody) {
99
+ if (!opBody)
100
+ return undefined;
101
+ return {
102
+ estadoEvento: str(opBody['EstadoEvento']),
103
+ codigoErrorEvento: str(opBody['CodigoErrorEvento']),
104
+ descripcionErrorEvento: str(opBody['DescripcionErrorEvento']),
105
+ csv: str(opBody['CSV']),
106
+ huella: str(opBody['Huella']),
107
+ };
108
+ }
109
+ function str(value) {
110
+ if (value === undefined || value === null)
111
+ return undefined;
112
+ return String(value);
113
+ }
114
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../../../src/aeat/response.ts"],"names":[],"mappings":"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"}
@@ -73,6 +73,44 @@ export declare function verifyRegistroAlta(input: RegistroAltaInput, expectedHas
73
73
  * Verifica que el hash de un registro de anulación coincide con el esperado.
74
74
  */
75
75
  export declare function verifyRegistroAnulacion(input: RegistroAnulacionInput, expectedHash: string): boolean;
76
+ /**
77
+ * Campos de un registro de evento (RegistroEvento).
78
+ *
79
+ * Nota: el nombre `NIF` aparece DOS veces (posiciones 1 y 6): una para el
80
+ * sistema informático y otra para el obligado a emitir.
81
+ */
82
+ export interface RegistroEventoInput {
83
+ /** NIF del sistema informático (NIF, posición 1). */
84
+ nifSistemaInformatico: string;
85
+ /** Identificador del evento (ID). */
86
+ id: string;
87
+ /** Identificador del sistema informático. */
88
+ idSistemaInformatico: string;
89
+ /** Versión del sistema informático. */
90
+ version: string;
91
+ /** Número de instalación. */
92
+ numeroInstalacion: string;
93
+ /** NIF del obligado a emitir (NIF, posición 6). */
94
+ nifObligado: string;
95
+ /** Tipo de evento. */
96
+ tipoEvento: string;
97
+ /** Huella (hash) del registro anterior, o null para el primero. */
98
+ huellaAnterior: string | null;
99
+ /** Fecha/hora de generación con huso horario. */
100
+ fechaHoraHusoGenEvento: string;
101
+ }
102
+ /**
103
+ * Construye la cadena canónica a hashear de un registro de evento.
104
+ */
105
+ export declare function concatenateRegistroEvento(input: RegistroEventoInput): string;
106
+ /**
107
+ * Calcula la huella (hash) de un registro de evento.
108
+ */
109
+ export declare function computeRegistroEvento(input: RegistroEventoInput): string;
110
+ /**
111
+ * Verifica que el hash de un registro de evento coincide con el esperado.
112
+ */
113
+ export declare function verifyRegistroEvento(input: RegistroEventoInput, expectedHash: string): boolean;
76
114
  /**
77
115
  * Cadena de hash con estado, para encadenar registros de forma secuencial.
78
116
  */
@@ -91,6 +129,10 @@ export declare class HashChain {
91
129
  * Encadena un nuevo registro de anulación y devuelve su huella.
92
130
  */
93
131
  pushAnulacion(input: Omit<RegistroAnulacionInput, 'huellaAnterior'>): string;
132
+ /**
133
+ * Encadena un nuevo registro de evento y devuelve su huella.
134
+ */
135
+ pushEvento(input: Omit<RegistroEventoInput, 'huellaAnterior'>): string;
94
136
  /** Reinicia la cadena. */
95
137
  reset(): void;
96
138
  }
@@ -1 +1 @@
1
- {"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../../../../src/core/hash/chain.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC,GAAG,MAAM,CAO5F;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,eAAe,EAAE,MAAM,CAAC;IACxB,yCAAyC;IACzC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,qBAAqB;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iDAAiD;IACjD,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,4CAA4C;IAC5C,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iDAAiD;IACjD,6BAA6B,EAAE,MAAM,CAAC;IACtC,2CAA2C;IAC3C,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,iDAAiD;IACjD,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAWxE;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAQlF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM,CAEpE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM,CAE9E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAE1F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,sBAAsB,EAC7B,YAAY,EAAE,MAAM,GACnB,OAAO,CAET;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,MAAM,CAAK;IAEnB,2EAA2E;IAC3E,IAAI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAE5B;IAED,mDAAmD;IACnD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,GAAG,MAAM;IAOlE;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,sBAAsB,EAAE,gBAAgB,CAAC,GAAG,MAAM;IAO5E,0BAA0B;IAC1B,KAAK,IAAI,IAAI;CAId"}
1
+ {"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../../../../src/core/hash/chain.ts"],"names":[],"mappings":"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"}
@@ -74,6 +74,34 @@ export function verifyRegistroAlta(input, expectedHash) {
74
74
  export function verifyRegistroAnulacion(input, expectedHash) {
75
75
  return computeRegistroAnulacion(input).toLowerCase() === expectedHash.toLowerCase();
76
76
  }
77
+ /**
78
+ * Construye la cadena canónica a hashear de un registro de evento.
79
+ */
80
+ export function concatenateRegistroEvento(input) {
81
+ return concatenateFields([
82
+ ['NIF', input.nifSistemaInformatico],
83
+ ['ID', input.id],
84
+ ['IdSistemaInformatico', input.idSistemaInformatico],
85
+ ['Version', input.version],
86
+ ['NumeroInstalacion', input.numeroInstalacion],
87
+ ['NIF', input.nifObligado],
88
+ ['TipoEvento', input.tipoEvento],
89
+ ['HuellaEvento', input.huellaAnterior],
90
+ ['FechaHoraHusoGenEvento', input.fechaHoraHusoGenEvento],
91
+ ]);
92
+ }
93
+ /**
94
+ * Calcula la huella (hash) de un registro de evento.
95
+ */
96
+ export function computeRegistroEvento(input) {
97
+ return sha256(concatenateRegistroEvento(input));
98
+ }
99
+ /**
100
+ * Verifica que el hash de un registro de evento coincide con el esperado.
101
+ */
102
+ export function verifyRegistroEvento(input, expectedHash) {
103
+ return computeRegistroEvento(input).toLowerCase() === expectedHash.toLowerCase();
104
+ }
77
105
  /**
78
106
  * Cadena de hash con estado, para encadenar registros de forma secuencial.
79
107
  */
@@ -106,6 +134,15 @@ export class HashChain {
106
134
  this._count += 1;
107
135
  return hash;
108
136
  }
137
+ /**
138
+ * Encadena un nuevo registro de evento y devuelve su huella.
139
+ */
140
+ pushEvento(input) {
141
+ const hash = computeRegistroEvento({ ...input, huellaAnterior: this._lastHash });
142
+ this._lastHash = hash;
143
+ this._count += 1;
144
+ return hash;
145
+ }
109
146
  /** Reinicia la cadena. */
110
147
  reset() {
111
148
  this._lastHash = null;
@@ -1 +1 @@
1
- {"version":3,"file":"chain.js","sourceRoot":"","sources":["../../../../src/core/hash/chain.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chain.js","sourceRoot":"","sources":["../../../../src/core/hash/chain.ts"],"names":[],"mappings":"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"}
@@ -2,4 +2,6 @@ export * from './models/index.js';
2
2
  export * from './hash/index.js';
3
3
  export * from './xml/index.js';
4
4
  export * from './qr/index.js';
5
+ export * from './validation/index.js';
6
+ export * from './utils/index.js';
5
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
@@ -2,4 +2,6 @@ export * from './models/index.js';
2
2
  export * from './hash/index.js';
3
3
  export * from './xml/index.js';
4
4
  export * from './qr/index.js';
5
+ export * from './validation/index.js';
6
+ export * from './utils/index.js';
5
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC"}
@@ -38,36 +38,48 @@ export type TipoFactura = 'F1' | 'F2' | 'F3' | 'F4' | 'F5' | 'F6' | 'F7' | 'F8'
38
38
  */
39
39
  export type TipoDesglose = 'S1' | 'S2' | 'S3' | 'S4' | 'S5' | 'S6';
40
40
  /**
41
- * Detalle de IVA de una línea de desglose.
41
+ * Detalle de desglose de una línea (DetalleType del XSD de AEAT).
42
42
  */
43
- export interface DetalleIva {
43
+ export interface DetalleDesglose {
44
+ /** Calificación de la operación (p. ej. '01'). */
45
+ calificacionOperacion: string;
46
+ /** Clave de régimen (obligatoria si Impuesto es IVA/IPSI/IGIC). */
47
+ claveRegimen?: string;
44
48
  /** Tipo impositivo (%). */
45
- tipoImpositivo: number;
46
- /** Base imponible. */
49
+ tipoImpositivo?: number;
50
+ /** Base imponible o importe no sujeto. */
47
51
  baseImponible: number;
48
52
  /** Cuota repercutida. */
49
- cuotaRepercutida: number;
53
+ cuotaRepercutida?: number;
50
54
  }
51
55
  /**
52
- * Desglose de la operación por tipo de operación e IVA.
53
- */
54
- export interface DesgloseTipoOperacion {
55
- /** Clave de tipo de operación (p. ej. '01'). */
56
- tipoOperacion: string;
57
- /** Detalles de IVA. */
58
- detallesIva: DetalleIva[];
59
- }
60
- /**
61
- * Desglose completo de la factura.
56
+ * Desglose completo de la factura (DesgloseType del XSD de AEAT).
62
57
  */
63
58
  export interface Desglose {
64
- /** Desglose por tipo de operación. */
65
- tipoOperaciones: DesgloseTipoOperacion[];
59
+ /** Detalles de desglose (DetalleDesglose). */
60
+ detalles: DetalleDesglose[];
66
61
  /** Cuota total de la factura. */
67
62
  cuotaTotal: number;
68
63
  /** Importe total de la factura. */
69
64
  importeTotal: number;
70
65
  }
66
+ /**
67
+ * Sistema informático que genera el registro (SistemaInformaticoType del XSD).
68
+ */
69
+ export interface SistemaInformatico {
70
+ /** Nombre o razón social del titular. */
71
+ nombreRazon: string;
72
+ /** NIF del titular. */
73
+ nif: string;
74
+ /** Nombre del sistema informático. */
75
+ nombreSistemaInformatico: string;
76
+ /** Identificador del sistema informático. */
77
+ idSistemaInformatico: string;
78
+ /** Versión del sistema informático. */
79
+ version: string;
80
+ /** Número de instalación. */
81
+ numeroInstalacion: string;
82
+ }
71
83
  /**
72
84
  * Factura en el modelo de datos Verifactu.
73
85
  */
@@ -84,6 +96,19 @@ export interface Invoice {
84
96
  tipoDesglose: TipoDesglose;
85
97
  /** Descripción de la operación. */
86
98
  descripcion?: string;
99
+ /** Destinatarios de la operación (obligatorio para F1/F3/R1-R4). */
100
+ destinatarios?: {
101
+ nombreRazon: string;
102
+ nif: string;
103
+ }[];
104
+ /** Sistema informático que genera el registro. */
105
+ sistemaInformatico: SistemaInformatico;
106
+ /** Fecha/hora de generación con huso horario (ISO 8601). */
107
+ fechaHoraHusoGenRegistro: string;
108
+ /** Huella (hash) del registro. */
109
+ huella: string;
110
+ /** Versión del esquema (por defecto '1.0'). */
111
+ idVersion?: string;
87
112
  /** Metadatos adicionales libres. */
88
113
  metadata?: Record<string, unknown>;
89
114
  }
@@ -1 +1 @@
1
- {"version":3,"file":"invoice.d.ts","sourceRoot":"","sources":["../../../../src/core/models/invoice.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,sBAAsB;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,6BAA6B;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,eAAe,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,CAAC;AAET;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,2BAA2B;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,sBAAsB;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB;IACvB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,sCAAsC;IACtC,eAAe,EAAE,qBAAqB,EAAE,CAAC;IACzC,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,oCAAoC;IACpC,EAAE,EAAE,SAAS,CAAC;IACd,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,uBAAuB;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,wBAAwB;IACxB,YAAY,EAAE,YAAY,CAAC;IAC3B,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC"}
1
+ {"version":3,"file":"invoice.d.ts","sourceRoot":"","sources":["../../../../src/core/models/invoice.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Utilidades de fecha/hora para Verifactu.
3
+ *
4
+ * AEAT exige que `FechaHoraHusoGenRegistro` sea la fecha/hora actual del
5
+ * sistema con su huso horario (margen de 240 segundos). Este helper genera
6
+ * ese valor detectando automáticamente el offset de zona, sin asumir un
7
+ * huso fijo (p. ej. `+02:00`).
8
+ */
9
+ /**
10
+ * Devuelve la fecha/hora actual en formato ISO 8601 con el offset de zona
11
+ * detectado automáticamente, p. ej. `2026-09-07T10:12:41+02:00`.
12
+ *
13
+ * @param date Fecha a formatear (por defecto, ahora).
14
+ */
15
+ export declare function nowIsoWithOffset(date?: Date): string;
16
+ //# sourceMappingURL=date.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/date.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,GAAE,IAAiB,GAAG,MAAM,CAShE"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Utilidades de fecha/hora para Verifactu.
3
+ *
4
+ * AEAT exige que `FechaHoraHusoGenRegistro` sea la fecha/hora actual del
5
+ * sistema con su huso horario (margen de 240 segundos). Este helper genera
6
+ * ese valor detectando automáticamente el offset de zona, sin asumir un
7
+ * huso fijo (p. ej. `+02:00`).
8
+ */
9
+ const pad = (n) => String(n).padStart(2, '0');
10
+ /**
11
+ * Devuelve la fecha/hora actual en formato ISO 8601 con el offset de zona
12
+ * detectado automáticamente, p. ej. `2026-09-07T10:12:41+02:00`.
13
+ *
14
+ * @param date Fecha a formatear (por defecto, ahora).
15
+ */
16
+ export function nowIsoWithOffset(date = new Date()) {
17
+ const off = -date.getTimezoneOffset();
18
+ const sign = off >= 0 ? '+' : '-';
19
+ const abs = Math.abs(off);
20
+ return (`${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` +
21
+ `T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}` +
22
+ `${sign}${pad(Math.floor(abs / 60))}:${pad(abs % 60)}`);
23
+ }
24
+ //# sourceMappingURL=date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.js","sourceRoot":"","sources":["../../../../src/core/utils/date.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAEtD;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAa,IAAI,IAAI,EAAE;IACtD,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,CACL,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;QAC1E,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE;QAC9E,GAAG,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,CACvD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './date.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './date.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './validate.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/validation/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './validate.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/validation/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Invoice } from '../models/invoice.js';
2
+ /**
3
+ * Resultado de la validación de una factura.
4
+ */
5
+ export interface ValidationResult {
6
+ /** `true` si la factura es válida. */
7
+ valid: boolean;
8
+ /** Lista de errores (campos obligatorios o con formato incorrecto). */
9
+ errors: string[];
10
+ }
11
+ /**
12
+ * Valida una factura antes de enviarla a AEAT.
13
+ *
14
+ * Comprueba los campos obligatorios y el formato de las fechas (el XSD
15
+ * `fecha` de AEAT usa `DD-MM-YYYY`). Devuelve `{ valid, errors }`.
16
+ */
17
+ export declare function validateInvoice(invoice: Invoice): ValidationResult;
18
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/core/validation/validate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sCAAsC;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,uEAAuE;IACvE,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAoDlE"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Valida una factura antes de enviarla a AEAT.
3
+ *
4
+ * Comprueba los campos obligatorios y el formato de las fechas (el XSD
5
+ * `fecha` de AEAT usa `DD-MM-YYYY`). Devuelve `{ valid, errors }`.
6
+ */
7
+ export function validateInvoice(invoice) {
8
+ const errors = [];
9
+ // Identificación de la factura.
10
+ if (!invoice.id?.numero)
11
+ errors.push('id.numero es obligatorio');
12
+ if (!invoice.id?.fechaExpedicion) {
13
+ errors.push('id.fechaExpedicion es obligatorio');
14
+ }
15
+ else if (!/^\d{2}-\d{2}-\d{4}$/.test(invoice.id.fechaExpedicion)) {
16
+ errors.push('id.fechaExpedicion debe tener formato DD-MM-YYYY');
17
+ }
18
+ // Emisor.
19
+ if (!invoice.emisor?.nif)
20
+ errors.push('emisor.nif es obligatorio');
21
+ if (!invoice.emisor?.nombreRazon)
22
+ errors.push('emisor.nombreRazon es obligatorio');
23
+ // Tipo de factura.
24
+ if (!invoice.tipoFactura)
25
+ errors.push('tipoFactura es obligatorio');
26
+ // Desglose.
27
+ if (!invoice.desglose?.detalles?.length) {
28
+ errors.push('desglose.detalles debe tener al menos un detalle');
29
+ }
30
+ else {
31
+ invoice.desglose.detalles.forEach((d, i) => {
32
+ if (!d.calificacionOperacion)
33
+ errors.push(`desglose.detalles[${i}].calificacionOperacion es obligatorio`);
34
+ if (d.baseImponible === undefined || d.baseImponible === null) {
35
+ errors.push(`desglose.detalles[${i}].baseImponible es obligatorio`);
36
+ }
37
+ if (d.tipoImpositivo !== undefined && !d.claveRegimen) {
38
+ errors.push(`desglose.detalles[${i}].claveRegimen es obligatorio si hay tipoImpositivo`);
39
+ }
40
+ });
41
+ }
42
+ if (invoice.desglose?.cuotaTotal === undefined)
43
+ errors.push('desglose.cuotaTotal es obligatorio');
44
+ if (invoice.desglose?.importeTotal === undefined)
45
+ errors.push('desglose.importeTotal es obligatorio');
46
+ // Destinatarios obligatorios para F1/F3 (según AEAT).
47
+ if (['F1', 'F3'].includes(invoice.tipoFactura) && !invoice.destinatarios?.length) {
48
+ errors.push('destinatarios es obligatorio para tipoFactura F1/F3');
49
+ }
50
+ // Sistema informático.
51
+ if (!invoice.sistemaInformatico?.nif)
52
+ errors.push('sistemaInformatico.nif es obligatorio');
53
+ if (!invoice.sistemaInformatico?.idSistemaInformatico) {
54
+ errors.push('sistemaInformatico.idSistemaInformatico es obligatorio');
55
+ }
56
+ // Fecha/hora de generación.
57
+ if (!invoice.fechaHoraHusoGenRegistro) {
58
+ errors.push('fechaHoraHusoGenRegistro es obligatorio');
59
+ }
60
+ return { valid: errors.length === 0, errors };
61
+ }
62
+ //# sourceMappingURL=validate.js.map