@facturacr/atv-sdk 0.0.1-beta → 0.0.2-beta

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 (142) hide show
  1. package/.env.example +7 -0
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  4. package/.github/pull_request_template.md +7 -0
  5. package/.github/workflows/ci.yml +3 -3
  6. package/CODE_OF_CONDUCT.md +128 -0
  7. package/LICENSE +21 -0
  8. package/README.md +8 -1
  9. package/__tests__/stubs/dummyKeys/README.md +19 -0
  10. package/__tests__/stubs/frontendRequest.stub.ts +3 -2
  11. package/__tests__/stubs/token.stub.ts +18 -0
  12. package/__tests__/tests/electronicBill.test.ts +28 -0
  13. package/__tests__/tests/lib/getClave.test.ts +11 -0
  14. package/__tests__/tests/services/getToken.test.ts +15 -0
  15. package/atv-structures/4.3/FacturaElectronicaExportacion_V4.3.xsd.xml +1747 -0
  16. package/atv-structures/4.3/FacturaElectronica_V4.3.xsd.xml +1781 -0
  17. package/dist/__tests__/stubs/frontendRequest.stub.js +3 -2
  18. package/dist/__tests__/stubs/frontendRequest.stub.js.map +1 -1
  19. package/dist/__tests__/stubs/token.stub.d.ts +17 -0
  20. package/dist/__tests__/stubs/token.stub.js +21 -0
  21. package/dist/__tests__/stubs/token.stub.js.map +1 -0
  22. package/dist/__tests__/tests/electronicBill.test.d.ts +1 -0
  23. package/dist/__tests__/tests/electronicBill.test.js +38 -0
  24. package/dist/__tests__/tests/electronicBill.test.js.map +1 -0
  25. package/dist/__tests__/tests/getClave.test.d.ts +1 -0
  26. package/dist/__tests__/tests/getClave.test.js +15 -0
  27. package/dist/__tests__/tests/getClave.test.js.map +1 -0
  28. package/dist/__tests__/tests/getToken.test.d.ts +0 -0
  29. package/dist/__tests__/tests/getToken.test.js +28 -0
  30. package/dist/__tests__/tests/getToken.test.js.map +1 -0
  31. package/dist/__tests__/tests/lib/getClave.test.d.ts +1 -0
  32. package/dist/__tests__/tests/lib/getClave.test.js +15 -0
  33. package/dist/__tests__/tests/lib/getClave.test.js.map +1 -0
  34. package/dist/__tests__/tests/services/getToken.test.d.ts +1 -0
  35. package/dist/__tests__/tests/services/getToken.test.js +27 -0
  36. package/dist/__tests__/tests/services/getToken.test.js.map +1 -0
  37. package/dist/examples/confirmXML.js +3 -3
  38. package/dist/examples/confirmXML.js.map +1 -1
  39. package/dist/examples/consultXML.js +2 -2
  40. package/dist/examples/consultXML.js.map +1 -1
  41. package/dist/examples/createAndSend.js +6 -5
  42. package/dist/examples/createAndSend.js.map +1 -1
  43. package/dist/examples/createCreditNote.js +2 -2
  44. package/dist/examples/createCreditNote.js.map +1 -1
  45. package/dist/examples/createDebitNote.js +2 -2
  46. package/dist/examples/createDebitNote.js.map +1 -1
  47. package/dist/examples/genBasicXML.js +4 -4
  48. package/dist/examples/genBasicXML.js.map +1 -1
  49. package/dist/examples/getClave.js +1 -1
  50. package/dist/examples/getClave.js.map +1 -1
  51. package/dist/examples/getToken.js +1 -1
  52. package/dist/examples/getToken.js.map +1 -1
  53. package/dist/src/confirmXML.js +10 -10
  54. package/dist/src/confirmXML.js.map +1 -1
  55. package/dist/src/creditNote.d.ts +2 -2
  56. package/dist/src/creditNote.js +14 -14
  57. package/dist/src/creditNote.js.map +1 -1
  58. package/dist/src/data/codigoMoneda.d.ts +1 -0
  59. package/dist/src/data/codigoMoneda.js +184 -0
  60. package/dist/src/data/codigoMoneda.js.map +1 -0
  61. package/dist/src/data/exoneracion.d.ts +1 -0
  62. package/dist/src/data/exoneracion.js +15 -0
  63. package/dist/src/data/exoneracion.js.map +1 -0
  64. package/dist/src/data/impuestos.d.ts +2 -0
  65. package/dist/src/data/impuestos.js +25 -1
  66. package/dist/src/data/impuestos.js.map +1 -1
  67. package/dist/src/data/tipoCedula.d.ts +1 -0
  68. package/dist/src/data/tipoCedula.js +8 -1
  69. package/dist/src/data/tipoCedula.js.map +1 -1
  70. package/dist/src/data/unidadesMedida.d.ts +1 -0
  71. package/dist/src/data/unidadesMedida.js +99 -1
  72. package/dist/src/data/unidadesMedida.js.map +1 -1
  73. package/dist/src/debitNote.d.ts +2 -2
  74. package/dist/src/debitNote.js +14 -14
  75. package/dist/src/debitNote.js.map +1 -1
  76. package/dist/src/electronicBill.d.ts +1 -1
  77. package/dist/src/electronicBill.js +15 -9
  78. package/dist/src/electronicBill.js.map +1 -1
  79. package/dist/src/helpers/comprobantes.d.ts +2 -2
  80. package/dist/src/index.js +5 -1
  81. package/dist/src/index.js.map +1 -1
  82. package/dist/src/lib/genClave/index.d.ts +2 -2
  83. package/dist/src/lib/genClave/index.js +1 -1
  84. package/dist/src/lib/genClave/index.js.map +1 -1
  85. package/dist/src/lib/genJSON/confirmXML.d.ts +1 -1
  86. package/dist/src/lib/genJSON/confirmXML.js +1 -1
  87. package/dist/src/lib/genJSON/confirmXML.js.map +1 -1
  88. package/dist/src/lib/genJSON/index.d.ts +1 -1
  89. package/dist/src/lib/genJSON/index.js +18 -16
  90. package/dist/src/lib/genJSON/index.js.map +1 -1
  91. package/dist/src/lib/genXML/index.js +6 -12
  92. package/dist/src/lib/genXML/index.js.map +1 -1
  93. package/dist/src/lib/genXML/sigXML/index.js +3 -3
  94. package/dist/src/lib/genXML/sigXML/index.js.map +1 -1
  95. package/dist/src/lib/genXML/xmlConfig.d.ts +8 -1
  96. package/dist/src/lib/genXML/xmlConfig.js +5 -1
  97. package/dist/src/lib/genXML/xmlConfig.js.map +1 -1
  98. package/dist/src/services/getToken/index.d.ts +1 -1
  99. package/dist/src/services/send/index.js +4 -3
  100. package/dist/src/services/send/index.js.map +1 -1
  101. package/dist/src/types/xml/notaDeCredito.d.ts +1 -1
  102. package/dist/src/types/xml/notaDeDebito.d.ts +1 -1
  103. package/examples/README.md +6 -1
  104. package/examples/createAndSend.ts +7 -8
  105. package/examples/getToken.ts +6 -9
  106. package/jest.config.js +20 -3
  107. package/package.json +10 -11
  108. package/src/ATV.ts +28 -0
  109. package/src/confirmXML.ts +4 -4
  110. package/src/creditNote.ts +6 -6
  111. package/src/data/codigoMoneda.ts +180 -0
  112. package/src/data/exoneracion.ts +11 -0
  113. package/src/data/impuestos.ts +26 -0
  114. package/src/data/tipoCedula.ts +8 -0
  115. package/src/data/unidadesMedida.ts +99 -0
  116. package/src/debitNote.ts +6 -6
  117. package/src/electronicBill.ts +14 -6
  118. package/src/helpers/comprobantes.ts +2 -2
  119. package/src/lib/genClave/index.ts +3 -3
  120. package/src/lib/genJSON/confirmXML.ts +2 -2
  121. package/src/lib/genJSON/index.ts +20 -18
  122. package/src/lib/genXML/index.ts +3 -9
  123. package/src/lib/genXML/sigXML/genKeysAndCert.ts +1 -5
  124. package/src/lib/genXML/sigXML/index.ts +1 -1
  125. package/src/lib/genXML/xmlConfig.ts +14 -1
  126. package/src/services/getToken/GetToken.ts +54 -0
  127. package/src/services/getToken/__tests__/GetToken.test.ts +82 -0
  128. package/src/services/getToken/index.ts +1 -1
  129. package/src/services/getToken/types.ts +30 -0
  130. package/src/services/send/index.ts +2 -2
  131. package/src/types/facturaInterfaces.d.ts +18 -1
  132. package/src/types/globalInterfaces.d.ts +2 -1
  133. package/src/types/xml/notaDeCredito.ts +1 -1
  134. package/src/types/xml/notaDeDebito.ts +1 -1
  135. package/tools/strToClave.ts +1 -1
  136. package/tools/xsdToJsonSchema.ts +108 -0
  137. package/tsconfig.json +1 -1
  138. package/dist/src/types/facturaInterfaces.d.ts +0 -88
  139. package/dist/src/types/facturaInterfaces.js +0 -7
  140. package/dist/src/types/facturaInterfaces.js.map +0 -1
  141. /package/__tests__/{unit → tests}/getClave.test.ts +0 -0
  142. /package/__tests__/{unit → tests}/getToken.test.ts +0 -0
@@ -0,0 +1,82 @@
1
+ /* eslint-disable @typescript-eslint/camelcase */
2
+ import axios from 'axios'
3
+ import qs from 'querystring'
4
+ import { GetToken } from '../GetToken'
5
+ import { ATV } from '@src/ATV'
6
+ import { GetTokenDto } from '../types'
7
+
8
+ jest.mock('@src/ATV')
9
+ jest.mock('axios')
10
+ jest.mock('querystring')
11
+
12
+ const fetchResponse = {
13
+ data: {
14
+ access_token: 'access_token',
15
+ expires_in: 3600,
16
+ refresh_token: 'refresh_token',
17
+ refresh_expires_in: 1209600,
18
+ session_state: 'session_state',
19
+ token_type: 'Bearer',
20
+ scope: 'openid'
21
+ }
22
+ }
23
+ describe('GetToken', () => {
24
+ let atv: ATV
25
+ let getToken: GetToken
26
+
27
+ beforeEach(() => {
28
+ atv = new ATV()
29
+ getToken = new GetToken(atv)
30
+ ;(axios.post as jest.Mock).mockResolvedValue(fetchResponse)
31
+ })
32
+
33
+ afterEach(() => {
34
+ jest.resetAllMocks()
35
+ })
36
+
37
+ it('should call axios.post with correct parameters', async () => {
38
+ // Arrange
39
+ const dto: GetTokenDto = {
40
+ username: 'testuser',
41
+ password: 'testpassword'
42
+ }
43
+ const expectedUrl = 'https://idp.comprobanteselectronicos.go.cr/auth/realms/rut/protocol/openid-connect/token'
44
+ const expectedData = qs.stringify({
45
+ client_id: 'api-stag',
46
+ grant_type: 'password',
47
+ client_secret: '',
48
+ username: 'testuser',
49
+ password: 'testpassword'
50
+ })
51
+ const expectedConfig = {
52
+ headers: {
53
+ 'Content-Type': 'application/x-www-form-urlencoded'
54
+ }
55
+ }
56
+
57
+ // Act
58
+ await getToken.execute(dto)
59
+
60
+ // Assert
61
+ expect(axios.post).toHaveBeenCalledWith(expectedUrl, expectedData, expectedConfig)
62
+ })
63
+
64
+ it('should return expected response', async () => {
65
+ // Arrange
66
+ const expectedResponse = {
67
+ accessToken: 'access_token',
68
+ expiresIn: 3600,
69
+ refreshToken: 'refresh_token',
70
+ refreshExpiresIn: 1209600,
71
+ sessionState: 'session_state',
72
+ tokenType: 'Bearer',
73
+ scope: 'openid'
74
+ }
75
+
76
+ // Act
77
+ const result = await getToken.execute({ username: 'testuser', password: 'testpassword' })
78
+
79
+ // Assert
80
+ expect(result).toEqual(expectedResponse)
81
+ })
82
+ })
@@ -1,6 +1,6 @@
1
1
  import axios from 'axios'
2
2
  import qs from 'querystring'
3
- import { postTokenOptions } from './interfaces'
3
+ import { postTokenOptions } from '@src/services/getToken/interfaces'
4
4
 
5
5
  const MAIN_DOMAIN = 'https://idp.comprobanteselectronicos.go.cr'
6
6
  const RUT = (process.env.IS_STG) ? 'rut-stag' : 'rut'
@@ -0,0 +1,30 @@
1
+ export type GetTokenDto = {
2
+ username: string;
3
+ password: string;
4
+ }
5
+
6
+ export type GetTokenInternalProps = {
7
+ serviceUrl: string;
8
+ clientId: string;
9
+ };
10
+
11
+ export type GetTokenRawResponse = {
12
+ access_token: string;
13
+ expires_in: number;
14
+ refresh_expires_in: number;
15
+ refresh_token: string;
16
+ token_type: string;
17
+ 'not-before-policy': number;
18
+ session_state: string;
19
+ scope: string;
20
+ }
21
+
22
+ export type GetTokenResponse = {
23
+ accessToken: string;
24
+ expiresIn: number;
25
+ refreshExpiresIn: number;
26
+ refreshToken: string;
27
+ tokenType: string;
28
+ sessionState: string;
29
+ scope: string;
30
+ }
@@ -3,8 +3,8 @@ import axios from 'axios'
3
3
  const MAIN_DOMAIN = 'https://api.comprobanteselectronicos.go.cr/'
4
4
  const RUT = (process.env.IS_STG) ? 'recepcion-sandbox' : 'recepcion'
5
5
  const PATH = `${RUT}/v1/recepcion/`
6
-
7
- const URL = MAIN_DOMAIN + PATH
6
+ const SANBOX_URL = 'https://api-sandbox.comprobanteselectronicos.go.cr/recepcion/v1/recepcion'
7
+ const URL = (process.env.IS_STG) ? SANBOX_URL : MAIN_DOMAIN + PATH
8
8
 
9
9
  export function send(token: string, postOptions: any): Record<string, any> {
10
10
  return axios({
@@ -95,6 +95,23 @@ export interface FacturaElectronica {
95
95
  };
96
96
  }
97
97
 
98
+ export interface FacturaElectronicaExportacion {
99
+ Clave: string;
100
+ CodigoActividad: string;
101
+ NumeroConsecutivo: string;
102
+ FechaEmision?: Date;
103
+ Emisor: Persona;
104
+ Receptor: Persona;
105
+ CondicionVenta?: string;
106
+ PlazoCredito?: string;
107
+ MedioPago?: string;
108
+ DetalleServicio?: DetalleServicio;
109
+ ResumenFactura: Resumen;
110
+ Otros?: {
111
+ OtroTexto: string;
112
+ };
113
+ }
114
+
98
115
  export interface FacturaElectronicaContenedor {
99
- FacturaElectronica: FacturaElectronica;
116
+ [key: 'FacturaElectronica' | 'FacturaElectronicaExportacion']: FacturaElectronica | FacturaElectronicaExportacion;
100
117
  }
@@ -1,4 +1,4 @@
1
- import { Persona, LineaDetalle } from './facturaInterfaces'
1
+ import { Persona, LineaDetalle } from '@src/types/facturaInterfaces'
2
2
 
3
3
  export interface ClientPayload {
4
4
  Emisor: Persona;
@@ -14,6 +14,7 @@ export interface ClientPayload {
14
14
  total?: number; // deprecated
15
15
  impuesto?: number; // deprecated
16
16
  LineasDetalle: Array<LineaDetalle>;
17
+ facturaElectronicaType?: 'FacturaElectronica' | 'FacturaElectronicaExportacion';
17
18
  }
18
19
 
19
20
  export interface ClaveOpts {
@@ -1,4 +1,4 @@
1
- import { Persona, DetalleServicio, Resumen } from '../facturaInterfaces'
1
+ import { Persona, DetalleServicio, Resumen } from '@src/types/facturaInterfaces'
2
2
 
3
3
  type NotaCreditoElectronica = {
4
4
  Clave: string;
@@ -1,4 +1,4 @@
1
- import { Persona, DetalleServicio, Resumen } from '../facturaInterfaces'
1
+ import { Persona, DetalleServicio, Resumen } from '@src/types/facturaInterfaces'
2
2
 
3
3
  type NotaDebitoElectronica = {
4
4
  Clave: string;
@@ -1,4 +1,4 @@
1
- import { stringToClave } from '../../src/lib/genClave'
1
+ import { stringToClave } from '@src/lib/genClave'
2
2
 
3
3
  const output = stringToClave('50608022000310275915700100001010000000006100012313')
4
4
  console.log('output', output)
@@ -0,0 +1,108 @@
1
+ /* ======================================= */
2
+ /* ============== WIP ==================== */
3
+ /* ======================================= */
4
+ /* Util to import ATV xsd and get some info like enums */
5
+ import fs from 'fs'
6
+ import * as Parser from 'fast-xml-parser'
7
+
8
+ const options = {
9
+ ignoreAttributes: false,
10
+ ignoreNameSpace: true,
11
+ parseNodeValue: false,
12
+ attrNodeName: 'attributes',
13
+ attributeNamePrefix: ''
14
+ }
15
+ const sourceURI = process.env.XSD_SOURCE
16
+ const xmlString = fs.readFileSync(sourceURI, 'utf8')
17
+
18
+ const json = Parser.parse(xmlString, options)
19
+ const originalShema = json?.schema
20
+ const parentElement = originalShema?.element
21
+
22
+ const complexElements = originalShema?.complexType
23
+ const singleElements = originalShema?.simpleType
24
+
25
+ function processEnumerations(array: Array<any>): any {
26
+ return array.map((enumeration) => {
27
+ return enumeration?.attributes?.value
28
+ })
29
+ }
30
+
31
+ function processLoop(array: Array<any>): any {
32
+ const newObj = {}
33
+ for (let i = 0; i < array.length; i++) {
34
+ const element = array[i]
35
+ const propKey = element?.attributes?.name
36
+ if (propKey) {
37
+ newObj[propKey] = {
38
+ description: element?.annotation?.documentation
39
+ }
40
+ }
41
+ }
42
+ return newObj
43
+ }
44
+
45
+ function processObject(object: any): any {
46
+ const props = processLoop(object?.complexType?.sequence?.element)
47
+ const newObject = {}
48
+ newObject[object?.attributes?.name] = {
49
+ type: 'object',
50
+ properties: props
51
+ }
52
+ return newObject
53
+ }
54
+
55
+ function processSimpleType(object: any): any {
56
+ const newObject = {}
57
+ const enumeration = object.restriction?.enumeration || []
58
+ const enumationList = processEnumerations(enumeration)
59
+ newObject[object?.attributes?.name] = {
60
+ type: object.restriction?.attributes?.base,
61
+ enum: enumationList,
62
+ pattern: object.restriction?.pattern
63
+ }
64
+ return newObject
65
+ }
66
+
67
+ function processElementsFromComplexType(array: Array<any>): any {
68
+ const newObj = {}
69
+ for (let i = 0; i < array.length; i++) {
70
+ const element = array[i]
71
+ const propKey = element?.attributes?.name
72
+ const simpleType = element?.simpleType ? processSimpleType(element?.simpleType) : {}
73
+ if (propKey) {
74
+ newObj[propKey] = {
75
+ description: element?.annotation?.documentation,
76
+ simpleType: simpleType
77
+ }
78
+ }
79
+ }
80
+ return newObj
81
+ }
82
+
83
+ function processComplexType(object: any): any {
84
+ const elements = processElementsFromComplexType(object?.sequence?.element)
85
+ const newObject = {}
86
+ newObject[object?.attributes?.name] = {
87
+ elements: elements
88
+ }
89
+ return newObject
90
+ }
91
+
92
+ const schema: Record<string, any> = {
93
+ $schema: 'https://json-schema.org/draft/2020-12/schema',
94
+ $id: 'https://facere.cr/schema.json',
95
+ title: 'undefined',
96
+ description: 'undefined',
97
+ type: 'object',
98
+ properties: {}
99
+ }
100
+
101
+ schema.properties = processObject(parentElement)
102
+ schema.singleElements = singleElements.map(processSimpleType)
103
+ schema.complexElements = complexElements.map(processComplexType)
104
+
105
+ const data = JSON.stringify(schema, null, 2)
106
+ fs.writeFile('./out.json', data, (err) => {
107
+ if (err) throw err
108
+ })
package/tsconfig.json CHANGED
@@ -19,6 +19,6 @@
19
19
  "@test/*": ["__tests__/*"]
20
20
  }
21
21
  },
22
- "include": ["./src/**/*", "./test/**/*", "__tests__/stubs", "examples"],
22
+ "include": ["./src/**/*", "__tests__/**/*", "__tests__/stubs", "examples"],
23
23
  "exclude": ["node_modules/**/*"]
24
24
  }
@@ -1,88 +0,0 @@
1
- export interface Impuesto {
2
- Codigo: string;
3
- CodigoTarifa: string;
4
- Tarifa: number;
5
- Monto?: number;
6
- }
7
- export interface LineaDetalle {
8
- NumeroLinea?: string;
9
- Codigo?: string;
10
- Cantidad?: number;
11
- UnidadMedida?: string;
12
- Detalle: string;
13
- PrecioUnitario: number;
14
- MontoTotal?: number;
15
- SubTotal?: number;
16
- BaseImponible?: number;
17
- Impuesto?: Impuesto;
18
- MontoTotalLinea?: number;
19
- }
20
- export interface DetalleServicio {
21
- LineaDetalle: Array<LineaDetalle>;
22
- }
23
- export interface Resumen {
24
- CodigoTipoMoneda?: {
25
- CodigoMoneda: string;
26
- TipoCambio: string;
27
- };
28
- TotalServGravados: number;
29
- TotalServExentos: number;
30
- TotalServExonerado: number;
31
- TotalMercanciasGravadas?: number;
32
- TotalMercanciasExentas?: number;
33
- TotalGravado?: number;
34
- TotalExento: number;
35
- TotalExonerado: number;
36
- TotalVenta: number;
37
- TotalDescuentos?: number;
38
- TotalVentaNeta?: number;
39
- TotalImpuesto: number;
40
- TotalComprobante: number;
41
- }
42
- export interface Persona {
43
- Nombre: string;
44
- Identificacion: {
45
- Tipo?: string;
46
- Numero: string;
47
- };
48
- NombreComercial?: string;
49
- Ubicacion?: {
50
- Provincia?: '1' | '2' | '3' | '4' | '5' | '6' | '7';
51
- Canton?: string;
52
- Distrito?: string;
53
- Barrio?: string;
54
- OtrasSenas?: string;
55
- };
56
- Telefono?: {
57
- CodigoPais?: string;
58
- NumTelefono?: string;
59
- };
60
- Fax?: {
61
- CodigoPais?: string;
62
- NumTelefono?: string;
63
- };
64
- CorreoElectronico?: string;
65
- }
66
- export interface Message {
67
- Mensaje: string;
68
- DetalleMensaje: string;
69
- }
70
- export interface FacturaElectronica {
71
- Clave: string;
72
- CodigoActividad: string;
73
- NumeroConsecutivo: string;
74
- FechaEmision?: Date;
75
- Emisor: Persona;
76
- Receptor: Persona;
77
- CondicionVenta?: string;
78
- PlazoCredito?: string;
79
- MedioPago?: string;
80
- DetalleServicio?: DetalleServicio;
81
- ResumenFactura: Resumen;
82
- Otros?: {
83
- OtroTexto: string;
84
- };
85
- }
86
- export interface FacturaElectronicaContenedor {
87
- FacturaElectronica: FacturaElectronica;
88
- }
@@ -1,7 +0,0 @@
1
- "use strict";
2
- /* references
3
- https://www.hacienda.go.cr/ATV/ComprobanteElectronico/frmAnexosyEstructuras.aspx#
4
- https://www.hacienda.go.cr/ATV/ComprobanteElectronico/docs/esquemas/2016/v4/ANEXOS%20Y%20ESTRUCTURAS.pdf
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- //# sourceMappingURL=facturaInterfaces.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"facturaInterfaces.js","sourceRoot":"","sources":["../../../src/types/facturaInterfaces.ts"],"names":[],"mappings":";AAAA;;;EAGE"}
File without changes
File without changes