@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.
- package/.github/workflows/ci.yml +7 -4
- package/__tests__/stubs/commonExpectedXml.xml +94 -0
- package/__tests__/stubs/createDocument.stub.ts +80 -0
- package/__tests__/tests/ATV/__snapshots__/index.test.ts.snap +3 -0
- package/__tests__/tests/ATV/index.test.ts +50 -0
- package/doc/atv-structures/4.3/ANEXOS Y ESTRUCTURAS_V4.3.pdf +0 -0
- package/doc/atv-structures/4.3/API Ministerio de Hacienda /342/200/223 Dropbox Paper.pdf +0 -0
- package/doc/atv-structures/4.3/MensajeHacienda_V4.3.xsd.xml +179 -0
- package/doc/atv-structures/4.3/MensajeReceptor_V4.3.xsd.xml +163 -0
- package/doc/atv-structures/4.3/NotaCreditoElectronica_V4.3.xsd.xml +1804 -0
- package/doc/atv-structures/4.3/NotaDebitoElectronica_V4.3.xsd.xml +1804 -0
- package/examples/confirmXML.ts +1 -1
- package/examples/createAndSend.ts +27 -32
- package/examples/getToken.ts +3 -2
- package/jest-setup.js +5 -0
- package/jest.config.js +6 -5
- package/package.json +18 -14
- package/src/ATV/core/Clave.ts +41 -0
- package/src/ATV/core/Document.ts +123 -0
- package/src/ATV/core/DocumentType.ts +23 -0
- package/src/ATV/core/FullConsecutive.ts +29 -0
- package/src/ATV/core/OrderLine.ts +95 -0
- package/src/ATV/core/Person.ts +68 -0
- package/src/ATV/core/Summary.type.ts +20 -0
- package/src/ATV/core/documentNames.types.ts +5 -0
- package/src/ATV/index.ts +101 -0
- package/src/ATV/mappers/billDocToAtv.ts +103 -0
- package/src/ATV/types.ts +37 -0
- package/src/ATV/useCases/createDocument/index.ts +137 -0
- package/src/ATV/useCases/createDocument/types.ts +79 -0
- package/src/helpers/comprobantes.ts +1 -1
- package/src/lib/genJSON/confirmXML.ts +1 -1
- package/src/lib/genJSON/index.ts +2 -2
- package/src/lib/genXML/xmlConfig.ts +2 -2
- package/src/services/getToken/GetToken.ts +2 -2
- package/src/services/send/index.ts +1 -1
- package/src/types/facturaInterfaces.d.ts +27 -20
- package/tools/xsdToJsonSchema.ts +2 -2
- package/__tests__/tests/electronicBill.test.ts +0 -28
- package/dist/__tests__/stubs/frontendRequest.stub.d.ts +0 -3
- package/dist/__tests__/stubs/frontendRequest.stub.js +0 -61
- package/dist/__tests__/stubs/frontendRequest.stub.js.map +0 -1
- package/dist/__tests__/stubs/token.stub.d.ts +0 -17
- package/dist/__tests__/stubs/token.stub.js +0 -21
- package/dist/__tests__/stubs/token.stub.js.map +0 -1
- package/dist/__tests__/tests/electronicBill.test.d.ts +0 -1
- package/dist/__tests__/tests/electronicBill.test.js +0 -38
- package/dist/__tests__/tests/electronicBill.test.js.map +0 -1
- package/dist/__tests__/tests/getClave.test.d.ts +0 -1
- package/dist/__tests__/tests/getClave.test.js +0 -15
- package/dist/__tests__/tests/getClave.test.js.map +0 -1
- package/dist/__tests__/tests/getToken.test.d.ts +0 -0
- package/dist/__tests__/tests/getToken.test.js +0 -28
- package/dist/__tests__/tests/getToken.test.js.map +0 -1
- package/dist/__tests__/tests/lib/getClave.test.d.ts +0 -1
- package/dist/__tests__/tests/lib/getClave.test.js +0 -15
- package/dist/__tests__/tests/lib/getClave.test.js.map +0 -1
- package/dist/__tests__/tests/services/getToken.test.d.ts +0 -1
- package/dist/__tests__/tests/services/getToken.test.js +0 -27
- package/dist/__tests__/tests/services/getToken.test.js.map +0 -1
- package/dist/examples/confirmXML.d.ts +0 -1
- package/dist/examples/confirmXML.js +0 -89
- package/dist/examples/confirmXML.js.map +0 -1
- package/dist/examples/consultXML.d.ts +0 -1
- package/dist/examples/consultXML.js +0 -55
- package/dist/examples/consultXML.js.map +0 -1
- package/dist/examples/createAndSend.d.ts +0 -1
- package/dist/examples/createAndSend.js +0 -77
- package/dist/examples/createAndSend.js.map +0 -1
- package/dist/examples/createCreditNote.d.ts +0 -1
- package/dist/examples/createCreditNote.js +0 -52
- package/dist/examples/createCreditNote.js.map +0 -1
- package/dist/examples/createDebitNote.d.ts +0 -1
- package/dist/examples/createDebitNote.js +0 -52
- package/dist/examples/createDebitNote.js.map +0 -1
- package/dist/examples/genBasicXML.d.ts +0 -1
- package/dist/examples/genBasicXML.js +0 -44
- package/dist/examples/genBasicXML.js.map +0 -1
- package/dist/examples/getClave.d.ts +0 -1
- package/dist/examples/getClave.js +0 -12
- package/dist/examples/getClave.js.map +0 -1
- package/dist/examples/getToken.d.ts +0 -1
- package/dist/examples/getToken.js +0 -16
- package/dist/examples/getToken.js.map +0 -1
- package/dist/src/ATV.d.ts +0 -17
- package/dist/src/ATV.js +0 -16
- package/dist/src/ATV.js.map +0 -1
- package/dist/src/confirmXML.d.ts +0 -8
- package/dist/src/confirmXML.js +0 -44
- package/dist/src/confirmXML.js.map +0 -1
- package/dist/src/creditNote.d.ts +0 -14
- package/dist/src/creditNote.js +0 -77
- package/dist/src/creditNote.js.map +0 -1
- package/dist/src/data/codigoMoneda.d.ts +0 -1
- package/dist/src/data/codigoMoneda.js +0 -184
- package/dist/src/data/codigoMoneda.js.map +0 -1
- package/dist/src/data/exoneracion.d.ts +0 -1
- package/dist/src/data/exoneracion.js +0 -15
- package/dist/src/data/exoneracion.js.map +0 -1
- package/dist/src/data/impuestos.d.ts +0 -25
- package/dist/src/data/impuestos.js +0 -51
- package/dist/src/data/impuestos.js.map +0 -1
- package/dist/src/data/tipoCedula.d.ts +0 -7
- package/dist/src/data/tipoCedula.js +0 -17
- package/dist/src/data/tipoCedula.js.map +0 -1
- package/dist/src/data/tipoDocumento.d.ts +0 -26
- package/dist/src/data/tipoDocumento.js +0 -30
- package/dist/src/data/tipoDocumento.js.map +0 -1
- package/dist/src/data/unidadesMedida.d.ts +0 -5
- package/dist/src/data/unidadesMedida.js +0 -141
- package/dist/src/data/unidadesMedida.js.map +0 -1
- package/dist/src/debitNote.d.ts +0 -14
- package/dist/src/debitNote.js +0 -77
- package/dist/src/debitNote.js.map +0 -1
- package/dist/src/electronicBill.d.ts +0 -3
- package/dist/src/electronicBill.js +0 -61
- package/dist/src/electronicBill.js.map +0 -1
- package/dist/src/helpers/comprobantes.d.ts +0 -7
- package/dist/src/helpers/comprobantes.js +0 -92
- package/dist/src/helpers/comprobantes.js.map +0 -1
- package/dist/src/index.d.ts +0 -8
- package/dist/src/index.js.map +0 -1
- package/dist/src/lib/genClave/index.d.ts +0 -9
- package/dist/src/lib/genClave/index.js +0 -119
- package/dist/src/lib/genClave/index.js.map +0 -1
- package/dist/src/lib/genJSON/confirmXML.d.ts +0 -7
- package/dist/src/lib/genJSON/confirmXML.js +0 -46
- package/dist/src/lib/genJSON/confirmXML.js.map +0 -1
- package/dist/src/lib/genJSON/index.d.ts +0 -3
- package/dist/src/lib/genJSON/index.js +0 -133
- package/dist/src/lib/genJSON/index.js.map +0 -1
- package/dist/src/lib/genXML/index.d.ts +0 -7
- package/dist/src/lib/genXML/index.js +0 -51
- package/dist/src/lib/genXML/index.js.map +0 -1
- package/dist/src/lib/genXML/sigXML/genKeysAndCert.d.ts +0 -6
- package/dist/src/lib/genXML/sigXML/genKeysAndCert.js +0 -72
- package/dist/src/lib/genXML/sigXML/genKeysAndCert.js.map +0 -1
- package/dist/src/lib/genXML/sigXML/index.d.ts +0 -1
- package/dist/src/lib/genXML/sigXML/index.js +0 -86
- package/dist/src/lib/genXML/sigXML/index.js.map +0 -1
- package/dist/src/lib/genXML/xmlConfig.d.ts +0 -55
- package/dist/src/lib/genXML/xmlConfig.js +0 -36
- package/dist/src/lib/genXML/xmlConfig.js.map +0 -1
- package/dist/src/services/getToken/GetToken.d.ts +0 -8
- package/dist/src/services/getToken/GetToken.js +0 -66
- package/dist/src/services/getToken/GetToken.js.map +0 -1
- package/dist/src/services/getToken/__tests__/GetToken.test.d.ts +0 -1
- package/dist/src/services/getToken/__tests__/GetToken.test.js +0 -86
- package/dist/src/services/getToken/__tests__/GetToken.test.js.map +0 -1
- package/dist/src/services/getToken/index.d.ts +0 -3
- package/dist/src/services/getToken/index.js +0 -22
- package/dist/src/services/getToken/index.js.map +0 -1
- package/dist/src/services/getToken/types.d.ts +0 -27
- package/dist/src/services/getToken/types.js +0 -3
- package/dist/src/services/getToken/types.js.map +0 -1
- package/dist/src/services/send/index.d.ts +0 -2
- package/dist/src/services/send/index.js +0 -40
- package/dist/src/services/send/index.js.map +0 -1
- package/dist/src/types/xml/notaDeCredito.d.ts +0 -21
- package/dist/src/types/xml/notaDeCredito.js +0 -3
- package/dist/src/types/xml/notaDeCredito.js.map +0 -1
- package/dist/src/types/xml/notaDeDebito.d.ts +0 -21
- package/dist/src/types/xml/notaDeDebito.js +0 -3
- package/dist/src/types/xml/notaDeDebito.js.map +0 -1
- package/src/ATV.ts +0 -28
- /package/{atv-structures → doc/atv-structures}/4.3/FacturaElectronicaExportacion_V4.3.xsd.xml +0 -0
- /package/{atv-structures → doc/atv-structures}/4.3/FacturaElectronica_V4.3.xsd.xml +0 -0
package/examples/confirmXML.ts
CHANGED
|
@@ -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
|
-
|
|
19
|
+
console.log('requestStub consecutivo', createDocumentInputStub.consecutiveIdentifier)
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
// TODO: dynamic param --identifier 1 args[x]
|
|
22
|
+
createDocumentInputStub.consecutiveIdentifier = '1'
|
|
24
23
|
|
|
25
|
-
function
|
|
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
|
-
|
|
36
|
-
|
|
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
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
66
|
-
|
|
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()
|
package/examples/getToken.ts
CHANGED
|
@@ -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
|
|
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
package/jest.config.js
CHANGED
|
@@ -10,15 +10,16 @@ module.exports = {
|
|
|
10
10
|
},
|
|
11
11
|
coverageThreshold: {
|
|
12
12
|
global: {
|
|
13
|
-
statements:
|
|
14
|
-
branches:
|
|
15
|
-
functions:
|
|
16
|
-
lines:
|
|
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.
|
|
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": "^
|
|
36
|
+
"@types/jest": "^29.5",
|
|
35
37
|
"@types/node": "^14.14.39",
|
|
36
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
37
|
-
"@typescript-eslint/parser": "^
|
|
38
|
+
"@typescript-eslint/eslint-plugin": "^7.4.0",
|
|
39
|
+
"@typescript-eslint/parser": "^7.4.0",
|
|
38
40
|
"dotenv-cli": "^4.0.0",
|
|
39
|
-
"eslint": "^
|
|
40
|
-
"eslint-config-standard": "^
|
|
41
|
-
"eslint-plugin-import": "^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": "^
|
|
46
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
44
47
|
"eslint-plugin-standard": "^5.0.0",
|
|
45
|
-
"jest": "^
|
|
48
|
+
"jest": "^29.7",
|
|
49
|
+
"jest-xml-matcher": "^1.2.0",
|
|
46
50
|
"nodemon": "^2.0.19",
|
|
47
|
-
"ts-jest": "^
|
|
51
|
+
"ts-jest": "^29.1",
|
|
48
52
|
"ts-node": "10.9.1",
|
|
49
53
|
"tsc": "^1.20150623.0",
|
|
50
|
-
"tsconfig-paths": "^
|
|
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.
|
|
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
|
+
}
|