@facturacr/atv-sdk 0.0.7-beta → 0.0.9-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 (167) hide show
  1. package/.github/workflows/ci.yml +7 -4
  2. package/__tests__/stubs/commonExpectedXml.xml +94 -0
  3. package/__tests__/stubs/createDocument.stub.ts +80 -0
  4. package/__tests__/tests/ATV/__snapshots__/index.test.ts.snap +3 -0
  5. package/__tests__/tests/ATV/index.test.ts +50 -0
  6. package/doc/atv-structures/4.3/ANEXOS Y ESTRUCTURAS_V4.3.pdf +0 -0
  7. package/doc/atv-structures/4.3/API Ministerio de Hacienda /342/200/223 Dropbox Paper.pdf +0 -0
  8. package/doc/atv-structures/4.3/MensajeHacienda_V4.3.xsd.xml +179 -0
  9. package/doc/atv-structures/4.3/MensajeReceptor_V4.3.xsd.xml +163 -0
  10. package/doc/atv-structures/4.3/NotaCreditoElectronica_V4.3.xsd.xml +1804 -0
  11. package/doc/atv-structures/4.3/NotaDebitoElectronica_V4.3.xsd.xml +1804 -0
  12. package/examples/confirmXML.ts +1 -1
  13. package/examples/createAndSend.ts +27 -32
  14. package/examples/getToken.ts +3 -2
  15. package/jest-setup.js +5 -0
  16. package/jest.config.js +6 -5
  17. package/package.json +18 -14
  18. package/src/ATV/core/Clave.ts +41 -0
  19. package/src/ATV/core/Document.ts +123 -0
  20. package/src/ATV/core/DocumentType.ts +23 -0
  21. package/src/ATV/core/FullConsecutive.ts +29 -0
  22. package/src/ATV/core/OrderLine.ts +95 -0
  23. package/src/ATV/core/Person.ts +68 -0
  24. package/src/ATV/core/Summary.type.ts +20 -0
  25. package/src/ATV/core/documentNames.types.ts +5 -0
  26. package/src/ATV/index.ts +101 -0
  27. package/src/ATV/mappers/billDocToAtv.ts +103 -0
  28. package/src/ATV/types.ts +37 -0
  29. package/src/ATV/useCases/createDocument/index.ts +137 -0
  30. package/src/ATV/useCases/createDocument/types.ts +79 -0
  31. package/src/helpers/comprobantes.ts +1 -1
  32. package/src/lib/genJSON/confirmXML.ts +1 -1
  33. package/src/lib/genJSON/index.ts +2 -2
  34. package/src/lib/genXML/xmlConfig.ts +2 -2
  35. package/src/services/getToken/GetToken.ts +2 -2
  36. package/src/services/send/index.ts +1 -1
  37. package/src/types/facturaInterfaces.d.ts +27 -20
  38. package/tools/xsdToJsonSchema.ts +2 -2
  39. package/__tests__/tests/electronicBill.test.ts +0 -28
  40. package/dist/__tests__/stubs/frontendRequest.stub.d.ts +0 -3
  41. package/dist/__tests__/stubs/frontendRequest.stub.js +0 -61
  42. package/dist/__tests__/stubs/frontendRequest.stub.js.map +0 -1
  43. package/dist/__tests__/stubs/token.stub.d.ts +0 -17
  44. package/dist/__tests__/stubs/token.stub.js +0 -21
  45. package/dist/__tests__/stubs/token.stub.js.map +0 -1
  46. package/dist/__tests__/tests/electronicBill.test.d.ts +0 -1
  47. package/dist/__tests__/tests/electronicBill.test.js +0 -38
  48. package/dist/__tests__/tests/electronicBill.test.js.map +0 -1
  49. package/dist/__tests__/tests/getClave.test.d.ts +0 -1
  50. package/dist/__tests__/tests/getClave.test.js +0 -15
  51. package/dist/__tests__/tests/getClave.test.js.map +0 -1
  52. package/dist/__tests__/tests/getToken.test.d.ts +0 -0
  53. package/dist/__tests__/tests/getToken.test.js +0 -28
  54. package/dist/__tests__/tests/getToken.test.js.map +0 -1
  55. package/dist/__tests__/tests/lib/getClave.test.d.ts +0 -1
  56. package/dist/__tests__/tests/lib/getClave.test.js +0 -15
  57. package/dist/__tests__/tests/lib/getClave.test.js.map +0 -1
  58. package/dist/__tests__/tests/services/getToken.test.d.ts +0 -1
  59. package/dist/__tests__/tests/services/getToken.test.js +0 -27
  60. package/dist/__tests__/tests/services/getToken.test.js.map +0 -1
  61. package/dist/examples/confirmXML.d.ts +0 -1
  62. package/dist/examples/confirmXML.js +0 -89
  63. package/dist/examples/confirmXML.js.map +0 -1
  64. package/dist/examples/consultXML.d.ts +0 -1
  65. package/dist/examples/consultXML.js +0 -55
  66. package/dist/examples/consultXML.js.map +0 -1
  67. package/dist/examples/createAndSend.d.ts +0 -1
  68. package/dist/examples/createAndSend.js +0 -77
  69. package/dist/examples/createAndSend.js.map +0 -1
  70. package/dist/examples/createCreditNote.d.ts +0 -1
  71. package/dist/examples/createCreditNote.js +0 -52
  72. package/dist/examples/createCreditNote.js.map +0 -1
  73. package/dist/examples/createDebitNote.d.ts +0 -1
  74. package/dist/examples/createDebitNote.js +0 -52
  75. package/dist/examples/createDebitNote.js.map +0 -1
  76. package/dist/examples/genBasicXML.d.ts +0 -1
  77. package/dist/examples/genBasicXML.js +0 -44
  78. package/dist/examples/genBasicXML.js.map +0 -1
  79. package/dist/examples/getClave.d.ts +0 -1
  80. package/dist/examples/getClave.js +0 -12
  81. package/dist/examples/getClave.js.map +0 -1
  82. package/dist/examples/getToken.d.ts +0 -1
  83. package/dist/examples/getToken.js +0 -16
  84. package/dist/examples/getToken.js.map +0 -1
  85. package/dist/src/ATV.d.ts +0 -17
  86. package/dist/src/ATV.js +0 -16
  87. package/dist/src/ATV.js.map +0 -1
  88. package/dist/src/confirmXML.d.ts +0 -8
  89. package/dist/src/confirmXML.js +0 -44
  90. package/dist/src/confirmXML.js.map +0 -1
  91. package/dist/src/creditNote.d.ts +0 -14
  92. package/dist/src/creditNote.js +0 -77
  93. package/dist/src/creditNote.js.map +0 -1
  94. package/dist/src/data/codigoMoneda.d.ts +0 -1
  95. package/dist/src/data/codigoMoneda.js +0 -184
  96. package/dist/src/data/codigoMoneda.js.map +0 -1
  97. package/dist/src/data/exoneracion.d.ts +0 -1
  98. package/dist/src/data/exoneracion.js +0 -15
  99. package/dist/src/data/exoneracion.js.map +0 -1
  100. package/dist/src/data/impuestos.d.ts +0 -25
  101. package/dist/src/data/impuestos.js +0 -51
  102. package/dist/src/data/impuestos.js.map +0 -1
  103. package/dist/src/data/tipoCedula.d.ts +0 -7
  104. package/dist/src/data/tipoCedula.js +0 -17
  105. package/dist/src/data/tipoCedula.js.map +0 -1
  106. package/dist/src/data/tipoDocumento.d.ts +0 -26
  107. package/dist/src/data/tipoDocumento.js +0 -30
  108. package/dist/src/data/tipoDocumento.js.map +0 -1
  109. package/dist/src/data/unidadesMedida.d.ts +0 -5
  110. package/dist/src/data/unidadesMedida.js +0 -141
  111. package/dist/src/data/unidadesMedida.js.map +0 -1
  112. package/dist/src/debitNote.d.ts +0 -14
  113. package/dist/src/debitNote.js +0 -77
  114. package/dist/src/debitNote.js.map +0 -1
  115. package/dist/src/electronicBill.d.ts +0 -3
  116. package/dist/src/electronicBill.js +0 -61
  117. package/dist/src/electronicBill.js.map +0 -1
  118. package/dist/src/helpers/comprobantes.d.ts +0 -7
  119. package/dist/src/helpers/comprobantes.js +0 -92
  120. package/dist/src/helpers/comprobantes.js.map +0 -1
  121. package/dist/src/index.d.ts +0 -8
  122. package/dist/src/index.js.map +0 -1
  123. package/dist/src/lib/genClave/index.d.ts +0 -9
  124. package/dist/src/lib/genClave/index.js +0 -119
  125. package/dist/src/lib/genClave/index.js.map +0 -1
  126. package/dist/src/lib/genJSON/confirmXML.d.ts +0 -7
  127. package/dist/src/lib/genJSON/confirmXML.js +0 -46
  128. package/dist/src/lib/genJSON/confirmXML.js.map +0 -1
  129. package/dist/src/lib/genJSON/index.d.ts +0 -3
  130. package/dist/src/lib/genJSON/index.js +0 -133
  131. package/dist/src/lib/genJSON/index.js.map +0 -1
  132. package/dist/src/lib/genXML/index.d.ts +0 -7
  133. package/dist/src/lib/genXML/index.js +0 -51
  134. package/dist/src/lib/genXML/index.js.map +0 -1
  135. package/dist/src/lib/genXML/sigXML/genKeysAndCert.d.ts +0 -6
  136. package/dist/src/lib/genXML/sigXML/genKeysAndCert.js +0 -72
  137. package/dist/src/lib/genXML/sigXML/genKeysAndCert.js.map +0 -1
  138. package/dist/src/lib/genXML/sigXML/index.d.ts +0 -1
  139. package/dist/src/lib/genXML/sigXML/index.js +0 -86
  140. package/dist/src/lib/genXML/sigXML/index.js.map +0 -1
  141. package/dist/src/lib/genXML/xmlConfig.d.ts +0 -55
  142. package/dist/src/lib/genXML/xmlConfig.js +0 -36
  143. package/dist/src/lib/genXML/xmlConfig.js.map +0 -1
  144. package/dist/src/services/getToken/GetToken.d.ts +0 -8
  145. package/dist/src/services/getToken/GetToken.js +0 -66
  146. package/dist/src/services/getToken/GetToken.js.map +0 -1
  147. package/dist/src/services/getToken/__tests__/GetToken.test.d.ts +0 -1
  148. package/dist/src/services/getToken/__tests__/GetToken.test.js +0 -86
  149. package/dist/src/services/getToken/__tests__/GetToken.test.js.map +0 -1
  150. package/dist/src/services/getToken/index.d.ts +0 -3
  151. package/dist/src/services/getToken/index.js +0 -22
  152. package/dist/src/services/getToken/index.js.map +0 -1
  153. package/dist/src/services/getToken/types.d.ts +0 -27
  154. package/dist/src/services/getToken/types.js +0 -3
  155. package/dist/src/services/getToken/types.js.map +0 -1
  156. package/dist/src/services/send/index.d.ts +0 -2
  157. package/dist/src/services/send/index.js +0 -40
  158. package/dist/src/services/send/index.js.map +0 -1
  159. package/dist/src/types/xml/notaDeCredito.d.ts +0 -21
  160. package/dist/src/types/xml/notaDeCredito.js +0 -3
  161. package/dist/src/types/xml/notaDeCredito.js.map +0 -1
  162. package/dist/src/types/xml/notaDeDebito.d.ts +0 -21
  163. package/dist/src/types/xml/notaDeDebito.js +0 -3
  164. package/dist/src/types/xml/notaDeDebito.js.map +0 -1
  165. package/src/ATV.ts +0 -28
  166. /package/{atv-structures → doc/atv-structures}/4.3/FacturaElectronicaExportacion_V4.3.xsd.xml +0 -0
  167. /package/{atv-structures → doc/atv-structures}/4.3/FacturaElectronica_V4.3.xsd.xml +0 -0
@@ -43,7 +43,7 @@ async function main(): Promise<void> {
43
43
  }
44
44
  const data = await confirmXML({
45
45
  token: token.data.access_token,
46
- consecutivo: consecutivo,
46
+ consecutivo,
47
47
  xmlStr: xml,
48
48
  tipoDocKey: 'CCE',
49
49
  pemOpt: {
@@ -1,8 +1,6 @@
1
- import { ClientPayload } from '@src/types/globalInterfaces'
2
- import requestStub from '@test/stubs/frontendRequest.stub'
3
- import { eletronicBill, sendToCustomURL } from '@src/index'
4
1
  import fs from 'fs'
5
2
  import { ATV } from '@src/ATV'
3
+ import { createDocumentInputStub } from '@test/stubs/createDocument.stub'
6
4
 
7
5
  const IS_STG = process.env.IS_STG
8
6
  const USERNAME_TEST = process.env.USERNAME_TEST
@@ -18,22 +16,22 @@ if (!SOURCE_P12_PASSPORT || !SOURCE_P12_URI) {
18
16
 
19
17
  const pem = fs.readFileSync(SOURCE_P12_URI, 'binary')
20
18
 
21
- const frontEndRequest: ClientPayload = requestStub
19
+ console.log('requestStub consecutivo', createDocumentInputStub.consecutiveIdentifier)
22
20
 
23
- console.log('requestStub consecutivo', requestStub.consecutivo)
21
+ // TODO: dynamic param --identifier 1 args[x]
22
+ createDocumentInputStub.consecutiveIdentifier = '1'
24
23
 
25
- function decodeBase64(encodedStr: string): string {
26
- const buff = Buffer.from(encodedStr, 'base64')
27
- return buff.toString('ascii')
28
- }
29
-
30
- function getConfimation(token: string, data: any, ms: number): Promise<any> {
24
+ function getConfimation(atv: ATV, token: string, location: string, ms: number): Promise<any> {
31
25
  return new Promise((resolve, reject): any => {
32
26
  setTimeout(() => {
33
- const location = data?.headers?.location
34
27
  console.log('location', location)
35
- sendToCustomURL(token, location)
36
- .then(data => resolve(data))
28
+ atv.sendConfirmation({
29
+ url: location,
30
+ headers: {
31
+ 'Content-Type': 'application/json',
32
+ Authorization: 'bearer ' + token
33
+ }
34
+ }).then(data => resolve(data))
37
35
  .catch(err => reject(err))
38
36
  }, ms)
39
37
  })
@@ -45,26 +43,23 @@ async function main(): Promise<void> {
45
43
  username: USERNAME_TEST,
46
44
  password: PASSWORD_TEST
47
45
  })
48
- const token = tokenData.accessToken
49
- const data = await eletronicBill(token, frontEndRequest, {
50
- buffer: pem,
51
- password: SOURCE_P12_PASSPORT
52
- })
53
- if (data) {
54
- const secondResponse = await getConfimation(token, data, 5000)
55
- .catch(err => {
56
- const response = err.response || {}
57
- console.log('response', response)
58
- })
59
- const XMLResponse = secondResponse.data['respuesta-xml']
60
- if (!XMLResponse) {
61
- const state = secondResponse.data['ind-estado']
62
- console.log('state', state)
63
- return
46
+ const { command, extraData } = await atv.createDocumentCommand({
47
+ document: createDocumentInputStub,
48
+ token: tokenData.accessToken,
49
+ signatureOptions: {
50
+ buffer: pem,
51
+ password: SOURCE_P12_PASSPORT
64
52
  }
65
- const text = decodeBase64(XMLResponse)
66
- console.log('secondResponse', text)
53
+ })
54
+ // console.log('command', command)
55
+ // console.log('extraData', extraData)
56
+ const response = await atv.sendDocument(command)
57
+ if (response.errorCause) {
58
+ console.log('error response', response)
59
+ return
67
60
  }
61
+ const confirmationResponse = await getConfimation(atv, tokenData.accessToken, response.location, 1000)
62
+ console.log({ MensajeHacienda: confirmationResponse.confirmation })
68
63
  }
69
64
 
70
65
  main()
@@ -4,8 +4,9 @@ const IS_STG = process.env.IS_STG
4
4
  const USERNAME_TEST = process.env.USERNAME_TEST
5
5
  const PASSWORD_TEST = process.env.PASSWORD_TEST
6
6
  console.log('process.env.IS_STG', IS_STG)
7
-
8
- const atv = new ATV({}, 'stg')
7
+ console.log('password', PASSWORD_TEST)
8
+ const mode = IS_STG ? 'stg' : undefined
9
+ const atv = new ATV({}, mode)
9
10
  const tokenData = atv.getToken({
10
11
  username: USERNAME_TEST,
11
12
  password: PASSWORD_TEST
package/jest-setup.js ADDED
@@ -0,0 +1,5 @@
1
+ module.exports = async function (globalConfig, projectConfig) {
2
+ process.env.TZ = 'UTC';
3
+ };
4
+
5
+
package/jest.config.js CHANGED
@@ -10,15 +10,16 @@ module.exports = {
10
10
  },
11
11
  coverageThreshold: {
12
12
  global: {
13
- statements: 58,
14
- branches: 35,
15
- functions: 58,
16
- lines: 58
13
+ statements: 54,
14
+ branches: 38,
15
+ functions: 65,
16
+ lines: 54
17
17
  }
18
18
  },
19
19
  restoreMocks: true,
20
20
  collectCoverage: true,
21
21
  collectCoverageFrom: [
22
22
  'src/**/*.{ts,js}'
23
- ]
23
+ ],
24
+ globalSetup: './jest-setup.js'
24
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@facturacr/atv-sdk",
3
- "version": "0.0.7-beta",
3
+ "version": "0.0.9-beta",
4
4
  "description": "Librería (SDK) de Javascript/NodeJS para acceder al API de Administración Tributaria Virtual (ATV) del Ministerio de Hacienda.",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -10,11 +10,13 @@
10
10
  "test": "__test__"
11
11
  },
12
12
  "scripts": {
13
- "test": "npx jest",
13
+ "test": "npx jest --no-coverage",
14
+ "test:cov": "npx jest",
14
15
  "dev": "dotenv -- nodemon -e ts,graphql -x 'yarn lint & ts-node -r tsconfig-paths/register src/index.ts'",
15
16
  "build": "yarn lint & tsc",
16
17
  "lint": "eslint --ext .ts, --ignore-path .gitignore .",
17
- "publish": "yarn build & npm publish"
18
+ "publish": "yarn build & npm publish",
19
+ "test:createAndSend": "yarn ts-node -r tsconfig-paths/register --require dotenv/config examples/createAndSend.ts"
18
20
  },
19
21
  "repository": {
20
22
  "type": "git",
@@ -31,28 +33,30 @@
31
33
  },
32
34
  "homepage": "https://github.com/facturacr/facturar-costa-rica-lib#readme",
33
35
  "devDependencies": {
34
- "@types/jest": "^26.0.15",
36
+ "@types/jest": "^29.5",
35
37
  "@types/node": "^14.14.39",
36
- "@typescript-eslint/eslint-plugin": "^2.3.0",
37
- "@typescript-eslint/parser": "^2.3.0",
38
+ "@typescript-eslint/eslint-plugin": "^7.4.0",
39
+ "@typescript-eslint/parser": "^7.4.0",
38
40
  "dotenv-cli": "^4.0.0",
39
- "eslint": "^6.4.0",
40
- "eslint-config-standard": "^14.1.0",
41
- "eslint-plugin-import": "^2.18.2",
41
+ "eslint": "^8.57.0",
42
+ "eslint-config-standard": "^17.1.0",
43
+ "eslint-plugin-import": "^2.29.1",
44
+ "eslint-plugin-n": "^16.6.2",
42
45
  "eslint-plugin-node": "^11.1.0",
43
- "eslint-plugin-promise": "^4.3.1",
46
+ "eslint-plugin-promise": "^6.1.1",
44
47
  "eslint-plugin-standard": "^5.0.0",
45
- "jest": "^26.6.3",
48
+ "jest": "^29.7",
49
+ "jest-xml-matcher": "^1.2.0",
46
50
  "nodemon": "^2.0.19",
47
- "ts-jest": "^26.5.6",
51
+ "ts-jest": "^29.1",
48
52
  "ts-node": "10.9.1",
49
53
  "tsc": "^1.20150623.0",
50
- "tsconfig-paths": "^3.9.0",
54
+ "tsconfig-paths": "^4.2.0",
51
55
  "typescript": "^4.2.4"
52
56
  },
53
57
  "dependencies": {
54
58
  "@peculiar/webcrypto": "^1.1.6",
55
- "axios": "^0.21.1",
59
+ "axios": "^0.28.0",
56
60
  "fast-xml-parser": "^3.19.0",
57
61
  "node-forge": "^1.3.0",
58
62
  "xadesjs": "^2.1.2",
@@ -0,0 +1,41 @@
1
+ import { genClaveObj, genString } from '@src/lib/genClave'
2
+
3
+ type ClaveProps = {
4
+ countryCode: string; // codigoPais
5
+ docKeyType: string; // tipoDocKey
6
+ identifierType: string; // tipoCedula
7
+ emitterIdentifier: string; // cedulaEmisor
8
+ ceSituation: string; // situacionCE
9
+ consecutiveIdentifier: string; // consecutivo
10
+ securityCode: string; // codigoSeguridad
11
+ branch: string; // sucursal
12
+ terminal: string; // terminal
13
+ }
14
+
15
+ export class Clave {
16
+ private props: ClaveProps
17
+
18
+ get value(): string {
19
+ const claveObj = genClaveObj({
20
+ cedulaEmisor: this.props.emitterIdentifier,
21
+ codigoPais: this.props.countryCode,
22
+ codigoSeguridad: this.props.securityCode,
23
+ consecutivo: this.props.consecutiveIdentifier,
24
+ situacionCE: this.props.ceSituation,
25
+ sucursal: this.props.branch,
26
+ terminal: this.props.terminal,
27
+ tipoCedula: this.props.identifierType,
28
+ tipoDocKey: this.props.docKeyType
29
+ })
30
+ const claveStr = genString(claveObj)
31
+ return claveStr
32
+ }
33
+
34
+ constructor(props: ClaveProps) {
35
+ this.props = props
36
+ }
37
+
38
+ public static create(props: ClaveProps): Clave {
39
+ return new Clave(props)
40
+ }
41
+ }
@@ -0,0 +1,123 @@
1
+ import { Clave } from './Clave'
2
+ import { FullConsecutive } from './FullConsecutive'
3
+ import { OrderLine } from './OrderLine'
4
+ import { Person } from './Person'
5
+ import { SummaryProps } from './Summary.type'
6
+
7
+ export type InvoiceProps = {
8
+ clave: Clave;
9
+ fullConsecutive: FullConsecutive;
10
+ activityCode: string; // CodigoActividad
11
+ issueDate: Date; // FechaEmision
12
+ emitter: Person; // Emisor
13
+ receiver: Person; // Receptor
14
+ orderLines: OrderLine[];
15
+ conditionSale?: string; // CondicionVenta
16
+ deadlineCredit?: string; // PlazoCredito
17
+ paymentMethod?: string; // MedioPago
18
+ summaryInvoice?: SummaryProps; // ResumenFactura
19
+ others?: { // Otros
20
+ OtroTexto: string;
21
+ };
22
+ }
23
+
24
+ type OrderLineSum = {
25
+ totalAmount: number;
26
+ totalTaxes: number;
27
+ }
28
+
29
+ export class Document {
30
+ public readonly props: InvoiceProps
31
+ constructor(props: InvoiceProps) {
32
+ this.props = props
33
+ }
34
+
35
+ get clave(): string {
36
+ return this.props.clave.value
37
+ }
38
+
39
+ get fullConsecutive(): string {
40
+ return this.props.fullConsecutive.value
41
+ }
42
+
43
+ get activityCode(): string {
44
+ return this.props.activityCode
45
+ }
46
+
47
+ get issueDate(): Date {
48
+ return this.props.issueDate
49
+ }
50
+
51
+ get emitter(): Person {
52
+ return this.props.emitter
53
+ }
54
+
55
+ get receiver(): Person {
56
+ return this.props.receiver
57
+ }
58
+
59
+ get orderLines(): OrderLine[] {
60
+ return this.props.orderLines
61
+ }
62
+
63
+ get conditionSale(): string | undefined {
64
+ return this.props.conditionSale
65
+ }
66
+
67
+ get deadlineCredit(): string | undefined {
68
+ return this.props.deadlineCredit
69
+ }
70
+
71
+ get paymentMethod(): string | undefined {
72
+ return this.props.paymentMethod
73
+ }
74
+
75
+ get others(): { OtroTexto: string } | undefined {
76
+ return this.props.others
77
+ }
78
+
79
+ get summaryInvoice(): SummaryProps {
80
+ if (this.props.summaryInvoice) {
81
+ return this.props.summaryInvoice
82
+ }
83
+ const orderLineSumResult = this.sumCreditLines()
84
+ const summary = {
85
+ currency: {
86
+ code: 'CRC',
87
+ exchangeRate: '585.69'
88
+ },
89
+ totalExemptServices: 0,
90
+ totalEncumberedServices: 0,
91
+ totalExonerated: 0,
92
+ totalTaxedServices: 0,
93
+ totalTaxes: orderLineSumResult.totalTaxes,
94
+ totalDiscounts: 0,
95
+ totalEncumberedMerchandise: orderLineSumResult.totalAmount,
96
+ totalTaxed: orderLineSumResult.totalTaxes,
97
+ totalExemptMerchandise: 0,
98
+ totalExempt: 0,
99
+ totalNetSale: orderLineSumResult.totalAmount,
100
+ totalEncumbered: orderLineSumResult.totalAmount
101
+ }
102
+ const totalSale = summary.totalEncumbered + summary.totalExempt + summary.totalExonerated
103
+ return {
104
+ ...summary,
105
+ totalSale,
106
+ totalNetSale: totalSale - summary.totalDiscounts,
107
+ totalVoucher: summary.totalNetSale + summary.totalTaxed
108
+ }
109
+ }
110
+
111
+ sumCreditLines(): OrderLineSum {
112
+ return this.orderLines.reduce<OrderLineSum>((previousValue, currentValue) => {
113
+ return {
114
+ totalAmount: previousValue.totalAmount + currentValue.totalAmount,
115
+ totalTaxes: previousValue.totalTaxes + currentValue.tax.amount
116
+ }
117
+ }, { totalAmount: 0, totalTaxes: 0 })
118
+ }
119
+
120
+ public static create(props: InvoiceProps): Document {
121
+ return new Document(props)
122
+ }
123
+ }
@@ -0,0 +1,23 @@
1
+ import { DocumentNames } from './documentNames.types'
2
+
3
+ const map: {[key: string]: DocumentTypeValues} = {
4
+ FacturaElectronica: 'FE',
5
+ FacturaElectronicaExportacion: 'FE',
6
+ NotaCreditoElectronica: 'NC',
7
+ NotaDebitoElectronica: 'NC'
8
+ }
9
+
10
+ type DocumentTypeValues = 'FE' | 'ND' | 'NC' | 'TE'
11
+
12
+ export class DocumentType {
13
+ value: DocumentTypeValues
14
+
15
+ constructor(value: DocumentTypeValues) {
16
+ this.value = value
17
+ }
18
+
19
+ static create(documentName: DocumentNames): DocumentType {
20
+ const value = map[documentName]
21
+ return new DocumentType(value)
22
+ }
23
+ }
@@ -0,0 +1,29 @@
1
+ import { consecutivoStr } from '@src/lib/genClave'
2
+
3
+ type FullConsecutiveProps = {
4
+ consecutiveIdentifier: string;
5
+ documentType?: string;
6
+ branch?: string;
7
+ terminal?: string;
8
+ }
9
+
10
+ export class FullConsecutive {
11
+ private props: FullConsecutiveProps
12
+
13
+ get value(): string {
14
+ return consecutivoStr({
15
+ tipoDocKey: this.props.documentType,
16
+ sucursal: this.props.branch,
17
+ terminal: this.props.terminal,
18
+ consecutivo: this.props.consecutiveIdentifier
19
+ })
20
+ }
21
+
22
+ constructor(props: FullConsecutiveProps) {
23
+ this.props = props
24
+ }
25
+
26
+ public static create(props: FullConsecutiveProps): FullConsecutive {
27
+ return new FullConsecutive(props)
28
+ }
29
+ }
@@ -0,0 +1,95 @@
1
+ type TaxProps = {
2
+ code: string;
3
+ rateCode: string;
4
+ rate: number;
5
+ amount?: number;
6
+ }
7
+
8
+ type OrderLineProps = {
9
+ detail: string;
10
+ unitaryPrice: number;
11
+ lineNumber?: string;
12
+ code?: string; // CAByS - https://www.bccr.fi.cr/seccion-indicadores-economicos/cat%C3%A1logo-de-bienes-y-servicios
13
+ quantity?: number;
14
+ measureUnit?: string;
15
+ totalAmount?: number;
16
+ subTotal?: number;
17
+ tax?: TaxProps;
18
+ totalOrderLineAmount?: number;
19
+ // BaseImponible?: number;
20
+ }
21
+
22
+ export class OrderLine {
23
+ props: OrderLineProps
24
+
25
+ constructor(props: OrderLineProps) {
26
+ this.props = props
27
+ }
28
+
29
+ get detail(): string {
30
+ return this.props.detail
31
+ }
32
+
33
+ get unitaryPrice(): number {
34
+ return this.props.unitaryPrice
35
+ }
36
+
37
+ get lineNumber(): string | undefined {
38
+ return this.props.lineNumber
39
+ }
40
+
41
+ get code(): string | undefined {
42
+ return this.props.code
43
+ }
44
+
45
+ get quantity(): number {
46
+ return this.props.quantity || 1
47
+ }
48
+
49
+ get measureUnit(): string {
50
+ return this.props.measureUnit || 'Sp'
51
+ }
52
+
53
+ get subTotal(): number {
54
+ return this.props.subTotal || this.props.unitaryPrice * this.quantity // subtract discounts
55
+ }
56
+
57
+ get totalAmount(): number {
58
+ return this.props.totalAmount || this.props.unitaryPrice * this.quantity
59
+ }
60
+
61
+ get totalOrderLineAmount(): number {
62
+ return this.props.totalOrderLineAmount || this.subTotal + this.tax.amount
63
+ }
64
+
65
+ get tax(): TaxProps {
66
+ const rate = this.props.tax.rate
67
+ return {
68
+ rate,
69
+ code: this.props.tax.code,
70
+ rateCode: this.props.tax.rateCode,
71
+ amount: this.subTotal * (rate / 100)
72
+ }
73
+ }
74
+
75
+ public static create(props: OrderLineProps): OrderLine {
76
+ const orderLineProps = {
77
+ lineNumber: props.lineNumber,
78
+ code: props.code,
79
+ quantity: props.quantity || 1,
80
+ measureUnit: props.measureUnit || 'Sp',
81
+ detail: props.detail,
82
+ unitaryPrice: props.unitaryPrice,
83
+ totalAmount: props.totalAmount
84
+ }
85
+ const tax: TaxProps = {
86
+ code: props.tax.code,
87
+ rate: props.tax.rate || 13,
88
+ rateCode: props.tax.rateCode
89
+ }
90
+ return new OrderLine({
91
+ ...orderLineProps,
92
+ tax
93
+ })
94
+ }
95
+ }
@@ -0,0 +1,68 @@
1
+ export type LocationProps = {
2
+ province: '1' | '2' | '3' | '4' | '5' | '6' | '7';
3
+ canton: string;
4
+ district: string;
5
+ neighborhood: string;
6
+ details?: string;
7
+ }
8
+
9
+ export type PhoneProps = {
10
+ countryCode: string;
11
+ number: string;
12
+ }
13
+
14
+ export type PersonProps = {
15
+ fullName: string;
16
+ identifier: {
17
+ type: '01' | '02';
18
+ id: string;
19
+ };
20
+ commercialName: string;
21
+ location?: LocationProps;
22
+ phone?: PhoneProps;
23
+ fax?: PhoneProps;
24
+ email?: string;
25
+ }
26
+
27
+ export class Person {
28
+ props: PersonProps
29
+ constructor(props: PersonProps) {
30
+ this.props = props
31
+ }
32
+
33
+ get fullName(): string {
34
+ return this.props.fullName
35
+ }
36
+
37
+ get identifierType(): string | undefined {
38
+ return this.props.identifier.type
39
+ }
40
+
41
+ get identifierId(): string {
42
+ return this.props.identifier.id
43
+ }
44
+
45
+ get commercialName(): string {
46
+ return this.props.commercialName
47
+ }
48
+
49
+ get location(): LocationProps | undefined {
50
+ return this.props.location
51
+ }
52
+
53
+ get phone(): PhoneProps | undefined {
54
+ return this.props.phone
55
+ }
56
+
57
+ get fax(): PhoneProps | undefined {
58
+ return this.props.fax
59
+ }
60
+
61
+ get email(): string | undefined {
62
+ return this.props.email
63
+ }
64
+
65
+ public static create(props: PersonProps): Person {
66
+ return new Person(props)
67
+ }
68
+ }
@@ -0,0 +1,20 @@
1
+ export type SummaryProps = {
2
+ currency?: {
3
+ code: string;
4
+ exchangeRate: string;
5
+ };
6
+ totalTaxedServices: number; // TotalServGravados
7
+ totalExemptServices: number; // TotalServExentos
8
+ totalEncumberedServices: number; // TotalServExonerado
9
+ totalExemptMerchandise?: number; // TotalMercanciasGravadas
10
+ totalEncumberedMerchandise?: number; // TotalMercanciasExentas
11
+ totalEncumbered: number; // TotalGravado
12
+ totalTaxed?: number;
13
+ totalExempt: number; // TotalExento
14
+ totalExonerated: number; // TotalExonerado
15
+ totalSale: number; // TotalVenta
16
+ totalDiscounts?: number; // TotalDescuentos
17
+ totalNetSale?: number; // TotalVentaNeta
18
+ totalTaxes: number; // TotalImpuesto
19
+ totalVoucher: number; // TotalComprobante
20
+ }
@@ -0,0 +1,5 @@
1
+ export type DocumentNames =
2
+ 'FacturaElectronica' |
3
+ 'FacturaElectronicaExportacion' |
4
+ 'NotaCreditoElectronica' |
5
+ 'NotaDebitoElectronica'