@facturacr/atv-sdk 2.0.0 → 2.0.2-alpha
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/.eslintignore +3 -0
- package/.eslintrc.js +23 -23
- package/.github/dependabot.yml +11 -0
- package/.github/workflows/ci.yml +14 -12
- package/README.md +9 -2
- package/__tests__/stubs/commonExpectedXml.xml +14 -16
- package/__tests__/stubs/createDocument.data.ts +18 -1
- package/__tests__/stubs/frontendRequest.stub.ts +0 -1
- package/__tests__/stubs/token.stub.ts +9 -9
- package/__tests__/tests/ATV/__snapshots__/create-document.test.ts.snap +1 -1
- package/__tests__/tests/ATV/create-document.test.ts +8 -8
- package/__tests__/tests/ATV/create-receptor-message.test.ts +41 -36
- package/dist/src/ATV/core/CreateDocFactory.d.ts +11 -3
- package/dist/src/ATV/core/CreateDocFactory.js +3 -3
- package/dist/src/ATV/core/CreateDocFactory.js.map +1 -1
- package/dist/src/ATV/core/Document.d.ts +2 -2
- package/dist/src/ATV/core/Document.js +15 -5
- package/dist/src/ATV/core/Document.js.map +1 -1
- package/dist/src/ATV/core/DocumentType.d.ts +2 -3
- package/dist/src/ATV/core/DocumentType.js +1 -0
- package/dist/src/ATV/core/DocumentType.js.map +1 -1
- package/dist/src/ATV/core/FullConsecutive.d.ts +2 -1
- package/dist/src/ATV/core/FullConsecutive.js.map +1 -1
- package/dist/src/ATV/core/OrderLine.js +8 -1
- package/dist/src/ATV/core/OrderLine.js.map +1 -1
- package/dist/src/ATV/core/Person.d.ts +2 -2
- package/dist/src/ATV/core/ReceptorConsecutive.js.map +1 -1
- package/dist/src/ATV/core/ReferenceInformation.js.map +1 -1
- package/dist/src/ATV/core/Summary.type.d.ts +5 -0
- package/dist/src/ATV/core/types.d.ts +3 -2
- package/dist/src/ATV/core/types.js.map +1 -1
- package/dist/src/ATV/index.d.ts +2 -2
- package/dist/src/ATV/index.js +2 -2
- package/dist/src/ATV/mappers/billDocToAtv.js +32 -26
- package/dist/src/ATV/mappers/billDocToAtv.js.map +1 -1
- package/dist/src/ATV/types.d.ts +1 -1
- package/dist/src/ATV/useCases/createDocument/index.js +5 -9
- package/dist/src/ATV/useCases/createDocument/index.js.map +1 -1
- package/dist/src/ATV/useCases/createDocument/types.d.ts +4 -3
- package/dist/src/ATV/useCases/createReceptorMessage/index.d.ts +6 -5
- package/dist/src/ATV/useCases/createReceptorMessage/index.js +3 -3
- package/dist/src/ATV/useCases/createReceptorMessage/index.js.map +1 -1
- package/dist/src/helpers/comprobantes.js +10 -1
- package/dist/src/helpers/comprobantes.js.map +1 -1
- package/dist/src/lib/genClave/index.d.ts +8 -1
- package/dist/src/lib/genClave/index.js +5 -0
- package/dist/src/lib/genClave/index.js.map +1 -1
- package/dist/src/lib/genXML/index.js +6 -4
- package/dist/src/lib/genXML/index.js.map +1 -1
- package/dist/src/lib/genXML/sigXML/index.js +7 -4
- package/dist/src/lib/genXML/sigXML/index.js.map +1 -1
- package/dist/src/services/getToken/GetToken.js +0 -3
- package/dist/src/services/getToken/GetToken.js.map +1 -1
- package/dist/src/services/getToken/__tests__/GetToken.test.js +0 -1
- package/dist/src/services/getToken/__tests__/GetToken.test.js.map +1 -1
- package/dist/src/types/facturaInterfaces.d.ts +9 -3
- package/dist/src/xmlSchemaHeaderMap.d.ts +70 -0
- package/dist/src/xmlSchemaHeaderMap.js +30 -0
- package/dist/src/xmlSchemaHeaderMap.js.map +1 -0
- package/doc/atv-structures/4.3/FacturaElectronica_V4.3.xsd.xml +1633 -478
- package/doc/atv-structures/4.4/TiqueteElectronico_V4.4.xsd.xml +2817 -0
- package/doc/json-schemas/4.4/fe.json +544 -0
- package/doc/json-schemas/4.4/te.json +420 -0
- package/doc/testing.md +27 -0
- package/examples/README.md +10 -35
- package/examples/atvAccept.ts +18 -9
- package/examples/consultXML.ts +1 -0
- package/examples/{createAndSend.ts → createAndSendFE.ts} +11 -8
- package/examples/createAndSendTE.ts +73 -0
- package/examples/createCreditNote.ts +10 -6
- package/examples/createDebitNote.ts +2 -0
- package/examples/getToken.ts +2 -0
- package/package.json +3 -2
- package/src/ATV/core/CreateDocFactory.ts +32 -23
- package/src/ATV/core/Document.ts +15 -8
- package/src/ATV/core/DocumentType.ts +10 -3
- package/src/ATV/core/FullConsecutive.ts +2 -1
- package/src/ATV/core/OrderLine.ts +7 -1
- package/src/ATV/core/Person.ts +2 -2
- package/src/ATV/core/ReceptorConsecutive.ts +16 -16
- package/src/ATV/core/ReferenceInformation.ts +6 -6
- package/src/ATV/core/Summary.type.ts +5 -0
- package/src/ATV/core/types.ts +7 -6
- package/src/ATV/index.ts +3 -3
- package/src/ATV/mappers/billDocToAtv.ts +35 -15
- package/src/ATV/types.ts +1 -1
- package/src/ATV/useCases/createDocument/index.ts +8 -8
- package/src/ATV/useCases/createDocument/types.ts +5 -6
- package/src/ATV/useCases/createReceptorMessage/index.ts +94 -93
- package/src/helpers/comprobantes.ts +10 -1
- package/src/lib/genClave/index.ts +10 -3
- package/src/lib/genXML/index.ts +3 -1
- package/src/lib/genXML/sigXML/index.ts +6 -3
- package/src/services/getToken/GetToken.ts +0 -3
- package/src/services/getToken/__tests__/GetToken.test.ts +0 -1
- package/src/types/facturaInterfaces.ts +10 -4
- package/src/xmlSchemaHeaderMap.ts +37 -0
- package/tools/readXML.ts +2 -0
- package/tools/xsdToJsonSchema.ts +1 -0
- package/tsconfig.json +1 -0
- package/dist/src/ATV/core/documentNames.types.d.ts +0 -1
- package/dist/src/ATV/core/documentNames.types.js +0 -3
- package/dist/src/ATV/core/documentNames.types.js.map +0 -1
- package/dist/src/lib/genXML/xmlConfig.d.ts +0 -55
- package/dist/src/lib/genXML/xmlConfig.js +0 -42
- package/dist/src/lib/genXML/xmlConfig.js.map +0 -1
- package/src/ATV/core/documentNames.types.ts +0 -6
- package/src/lib/genXML/xmlConfig.ts +0 -60
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import { TEInputExample } from '@test/stubs/createDocument.data'
|
|
3
|
+
import { ATV } from '../dist/src'
|
|
4
|
+
import { PersonProps } from 'dist/src/ATV/core/Person'
|
|
5
|
+
|
|
6
|
+
const USERNAME_TEST = process.env.USERNAME_TEST
|
|
7
|
+
const PASSWORD_TEST = process.env.PASSWORD_TEST
|
|
8
|
+
|
|
9
|
+
const SOURCE_P12_URI = process.env.SOURCE_P12_URI
|
|
10
|
+
const SOURCE_P12_PASSPORT = process.env.SOURCE_P12_PASSPORT
|
|
11
|
+
|
|
12
|
+
if (!SOURCE_P12_PASSPORT || !SOURCE_P12_URI) {
|
|
13
|
+
throw new Error('No environment. For running examples set .env before.')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const pem = fs.readFileSync(SOURCE_P12_URI, 'binary')
|
|
17
|
+
|
|
18
|
+
const paramConsecutive = process.argv[2]
|
|
19
|
+
console.log('paramConsecutive', paramConsecutive)
|
|
20
|
+
|
|
21
|
+
// TODO: dynamic param --identifier 1 args[x]
|
|
22
|
+
// @ts-expect-error migration - for example purposes
|
|
23
|
+
TEInputExample.consecutiveIdentifier = paramConsecutive || process.env.TEST_CONSECUTIVE
|
|
24
|
+
TEInputExample.emitter.identifier.id = process.env.EMITTER_IDENTIFIER_ID as string
|
|
25
|
+
TEInputExample.emitter.identifier.type = process.env.EMITTER_IDENTIFIER_TYPE as PersonProps['identifier']['type']
|
|
26
|
+
|
|
27
|
+
console.log('requestStub consecutivo', TEInputExample.consecutiveIdentifier)
|
|
28
|
+
|
|
29
|
+
function getConfimation(atv: ATV, token: string, location: string, ms: number): Promise<any> {
|
|
30
|
+
return new Promise((resolve, reject): any => {
|
|
31
|
+
setTimeout(() => {
|
|
32
|
+
console.log('location', location)
|
|
33
|
+
atv.sendConfirmation({
|
|
34
|
+
url: location,
|
|
35
|
+
headers: {
|
|
36
|
+
'Content-Type': 'application/json',
|
|
37
|
+
Authorization: 'bearer ' + token
|
|
38
|
+
}
|
|
39
|
+
}).then(data => resolve(data))
|
|
40
|
+
.catch(err => reject(err))
|
|
41
|
+
}, ms)
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function main(): Promise<void> {
|
|
46
|
+
const atv = new ATV({}, 'stg')
|
|
47
|
+
const tokenData = await atv.getToken({
|
|
48
|
+
// @ts-expect-error migration - for example purposes
|
|
49
|
+
username: USERNAME_TEST,
|
|
50
|
+
// @ts-expect-error migration - for example purposes
|
|
51
|
+
password: PASSWORD_TEST
|
|
52
|
+
})
|
|
53
|
+
const { command, extraData } = await atv.createDocumentCommand({
|
|
54
|
+
document: TEInputExample,
|
|
55
|
+
token: tokenData.accessToken,
|
|
56
|
+
signatureOptions: {
|
|
57
|
+
buffer: pem,
|
|
58
|
+
// @ts-expect-error migration - for example purposes
|
|
59
|
+
password: SOURCE_P12_PASSPORT
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
console.log('extraData', extraData)
|
|
63
|
+
const response = await atv.sendDocument(command)
|
|
64
|
+
if (response.errorCause) {
|
|
65
|
+
console.log('error response', response)
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
// @ts-expect-error pending-to-fix migration
|
|
69
|
+
const confirmationResponse = await getConfimation(atv, tokenData.accessToken, response.location, 2000)
|
|
70
|
+
console.log({ MensajeHacienda: confirmationResponse.confirmation })
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
main()
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
|
-
import {
|
|
2
|
+
import { FEInputExample, creditNoteReferenceInfoExample } from '@test/stubs/createDocument.data'
|
|
3
3
|
import { ATV } from '../dist/src'
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
const IS_STG = process.env.IS_STG
|
|
7
6
|
const USERNAME_TEST = process.env.USERNAME_TEST
|
|
8
7
|
const PASSWORD_TEST = process.env.PASSWORD_TEST
|
|
@@ -17,10 +16,10 @@ if (!SOURCE_P12_PASSPORT || !SOURCE_P12_URI) {
|
|
|
17
16
|
|
|
18
17
|
const pem = fs.readFileSync(SOURCE_P12_URI, 'binary')
|
|
19
18
|
|
|
20
|
-
console.log('requestStub consecutivo',
|
|
19
|
+
console.log('requestStub consecutivo', FEInputExample.consecutiveIdentifier)
|
|
21
20
|
|
|
22
21
|
// TODO: dynamic param --identifier 1 args[x]
|
|
23
|
-
|
|
22
|
+
FEInputExample.consecutiveIdentifier = '5'
|
|
24
23
|
|
|
25
24
|
function getConfimation(atv: ATV, token: string, location: string, ms: number): Promise<any> {
|
|
26
25
|
return new Promise((resolve, reject): any => {
|
|
@@ -41,18 +40,22 @@ function getConfimation(atv: ATV, token: string, location: string, ms: number):
|
|
|
41
40
|
async function main(): Promise<void> {
|
|
42
41
|
const atv = new ATV({}, 'stg')
|
|
43
42
|
const tokenData = await atv.getToken({
|
|
43
|
+
// @ts-expect-error migration - for example purposes
|
|
44
44
|
username: USERNAME_TEST,
|
|
45
|
+
// @ts-expect-error migration - for example purposes
|
|
45
46
|
password: PASSWORD_TEST
|
|
46
47
|
})
|
|
47
48
|
const { command, extraData } = await atv.createDocumentCommand({
|
|
48
49
|
document: {
|
|
49
|
-
...
|
|
50
|
+
...FEInputExample,
|
|
50
51
|
documentName: 'NotaCreditoElectronica',
|
|
51
|
-
referenceInfo: creditNoteReferenceInfoExample
|
|
52
|
+
referenceInfo: creditNoteReferenceInfoExample,
|
|
53
|
+
receiver: FEInputExample.receiver // Ensure receiver is always present
|
|
52
54
|
},
|
|
53
55
|
token: tokenData.accessToken,
|
|
54
56
|
signatureOptions: {
|
|
55
57
|
buffer: pem,
|
|
58
|
+
// @ts-expect-error migration - for example purposes
|
|
56
59
|
password: SOURCE_P12_PASSPORT
|
|
57
60
|
}
|
|
58
61
|
})
|
|
@@ -62,6 +65,7 @@ async function main(): Promise<void> {
|
|
|
62
65
|
console.log('error response', response)
|
|
63
66
|
return
|
|
64
67
|
}
|
|
68
|
+
// @ts-expect-error pending-to-fix migration
|
|
65
69
|
const confirmationResponse = await getConfimation(atv, tokenData.accessToken, response.location, 2000)
|
|
66
70
|
console.log({ MensajeHacienda: confirmationResponse.confirmation })
|
|
67
71
|
}
|
|
@@ -9,6 +9,7 @@ const USERNAME_TEST = process.env.USERNAME_TEST
|
|
|
9
9
|
const PASSWORD_TEST = process.env.PASSWORD_TEST
|
|
10
10
|
const SOURCE_P12_URI = process.env.SOURCE_P12_URI
|
|
11
11
|
const SOURCE_P12_PASSPORT = process.env.SOURCE_P12_PASSPORT
|
|
12
|
+
// @ts-expect-error migration - for example purposes
|
|
12
13
|
const pem = fs.readFileSync(SOURCE_P12_URI, 'binary')
|
|
13
14
|
|
|
14
15
|
async function main(): Promise<void> {
|
|
@@ -28,6 +29,7 @@ async function main(): Promise<void> {
|
|
|
28
29
|
const data = await debitNote({
|
|
29
30
|
token,
|
|
30
31
|
frontEndRequest,
|
|
32
|
+
// @ts-expect-error migration - for example purposes
|
|
31
33
|
xmlOpt
|
|
32
34
|
})
|
|
33
35
|
console.log(typeof data)
|
package/examples/getToken.ts
CHANGED
|
@@ -8,7 +8,9 @@ console.log('password', PASSWORD_TEST)
|
|
|
8
8
|
const mode = IS_STG ? 'stg' : undefined
|
|
9
9
|
const atv = new ATV({}, mode)
|
|
10
10
|
const tokenData = atv.getToken({
|
|
11
|
+
// @ts-expect-error migration - for example purposes
|
|
11
12
|
username: USERNAME_TEST,
|
|
13
|
+
// @ts-expect-error migration - for example purposes
|
|
12
14
|
password: PASSWORD_TEST
|
|
13
15
|
})
|
|
14
16
|
tokenData.then((resp) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@facturacr/atv-sdk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2-alpha",
|
|
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",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"test": "npx jest --no-coverage",
|
|
14
14
|
"test:cov": "npx jest",
|
|
15
|
+
"type:check": "tsc --noEmit",
|
|
15
16
|
"dev": "dotenv -- nodemon -e ts,graphql -x 'yarn lint & ts-node -r tsconfig-paths/register src/index.ts'",
|
|
16
17
|
"build": "rm -r dist; tspc -p tsconfig-prod.json",
|
|
17
18
|
"lint": "eslint --ext .ts, --ignore-path .gitignore .",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
},
|
|
57
58
|
"dependencies": {
|
|
58
59
|
"@peculiar/webcrypto": "^1.1.6",
|
|
59
|
-
"axios": "^0.
|
|
60
|
+
"axios": "^0.30.0",
|
|
60
61
|
"fast-xml-parser": "^3.19.0",
|
|
61
62
|
"node-forge": "^1.3.0",
|
|
62
63
|
"xadesjs": "^2.1.2",
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { Person, PersonProps } from '@src/ATV/core/Person'
|
|
2
|
-
import { DocumentNames } from '@src/ATV/core/documentNames.types'
|
|
3
2
|
import { OrderLine } from '@src/ATV/core/OrderLine'
|
|
4
3
|
import { FullConsecutive } from '@src/ATV/core/FullConsecutive'
|
|
5
4
|
import { Document } from '@src/ATV/core/Document'
|
|
6
5
|
import { Clave } from '@src/ATV/core/Clave'
|
|
7
|
-
import { DocumentType } from '@src/ATV/core/DocumentType'
|
|
6
|
+
import { DocumentNames, DocumentType } from '@src/ATV/core/DocumentType'
|
|
8
7
|
import { ReferenceInformation, ReferenceInformationProps } from './ReferenceInformation'
|
|
9
8
|
import { ReceptorMessageProps } from './types'
|
|
10
9
|
|
|
@@ -32,24 +31,34 @@ type OrderInput = {
|
|
|
32
31
|
totalOrderLineAmount?: number;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
type
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
34
|
+
type DocumentInputBase = {
|
|
35
|
+
emitter: PersonInput;
|
|
36
|
+
branch: string;
|
|
37
|
+
terminal: string;
|
|
38
|
+
documentName: DocumentNames;
|
|
39
|
+
providerId: string;
|
|
40
|
+
countryCode: string;
|
|
41
|
+
securityCode: string;
|
|
42
|
+
activityCode: string;
|
|
43
|
+
consecutiveIdentifier: string;
|
|
44
|
+
ceSituation: string;
|
|
45
|
+
orderLines: OrderInput[];
|
|
46
|
+
referenceInfo?: ReferenceInfoInput;
|
|
47
|
+
conditionSale: string;
|
|
48
|
+
paymentMethod: string;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
type DocumentInputTiquete = DocumentInputBase & {
|
|
52
|
+
documentName: 'TiqueteElectronico';
|
|
53
|
+
receiver?: PersonInput; // optional
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export type DocumentInputWithReceiver = DocumentInputBase & {
|
|
57
|
+
documentName: Exclude<DocumentNames, 'TiqueteElectronico'>;
|
|
58
|
+
receiver: PersonInput; // required
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
type DocumentInput = DocumentInputTiquete | DocumentInputWithReceiver;
|
|
53
62
|
|
|
54
63
|
export type CreateDocumentInput = {
|
|
55
64
|
document: DocumentInput;
|
|
@@ -74,10 +83,10 @@ export class CreateDocFactory {
|
|
|
74
83
|
providerId: document.providerId,
|
|
75
84
|
issueDate: new Date(),
|
|
76
85
|
emitter: Person.create(document.emitter),
|
|
77
|
-
receiver: Person.create(document.receiver),
|
|
86
|
+
receiver: document.receiver ? Person.create(document.receiver) : undefined,
|
|
78
87
|
conditionSale: document.conditionSale,
|
|
79
88
|
paymentMethod: document.paymentMethod,
|
|
80
|
-
referenceInformation: document.referenceInfo ? ReferenceInformation.create(document.referenceInfo) : undefined
|
|
89
|
+
referenceInformation: document.referenceInfo ? ReferenceInformation.create(document.referenceInfo) : undefined
|
|
81
90
|
})
|
|
82
91
|
}
|
|
83
92
|
|
|
@@ -113,7 +122,7 @@ export class CreateDocFactory {
|
|
|
113
122
|
countryCode: dto.countryCode,
|
|
114
123
|
docKeyType: docType.value,
|
|
115
124
|
emitterIdentifier: dto.emitter.identifier.id,
|
|
116
|
-
identifierType: dto.emitter.identifier.type
|
|
125
|
+
identifierType: dto.emitter.identifier.type || '01',
|
|
117
126
|
securityCode: dto.securityCode,
|
|
118
127
|
terminal: dto.terminal
|
|
119
128
|
})
|
package/src/ATV/core/Document.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type InvoiceProps = {
|
|
|
11
11
|
fullConsecutive: FullConsecutive;
|
|
12
12
|
issueDate: Date; // FechaEmision
|
|
13
13
|
emitter: Person; // Emisor
|
|
14
|
-
receiver
|
|
14
|
+
receiver?: Person; // Receptor
|
|
15
15
|
orderLines: OrderLine[];
|
|
16
16
|
conditionSale?: string; // CondicionVenta
|
|
17
17
|
deadlineCredit?: string; // PlazoCredito
|
|
@@ -58,7 +58,7 @@ export class Document {
|
|
|
58
58
|
return this.props.emitter
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
get receiver(): Person {
|
|
61
|
+
get receiver(): Person | undefined {
|
|
62
62
|
return this.props.receiver
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -92,7 +92,7 @@ export class Document {
|
|
|
92
92
|
const summary = {
|
|
93
93
|
currency: {
|
|
94
94
|
code: 'CRC',
|
|
95
|
-
exchangeRate: '
|
|
95
|
+
exchangeRate: '1'
|
|
96
96
|
},
|
|
97
97
|
totalExemptServices: 0,
|
|
98
98
|
totalEncumberedServices: servicesLineSumResult.totalAmount,
|
|
@@ -105,7 +105,14 @@ export class Document {
|
|
|
105
105
|
totalExemptMerchandise: 0,
|
|
106
106
|
totalExempt: 0,
|
|
107
107
|
totalNetSale: orderLineSumResult.totalAmount,
|
|
108
|
-
totalEncumbered: orderLineSumResult.totalAmount
|
|
108
|
+
totalEncumbered: orderLineSumResult.totalAmount,
|
|
109
|
+
totalTaxBreakdown: [
|
|
110
|
+
{
|
|
111
|
+
code: '01', // Static value for testing
|
|
112
|
+
taxRateCode: '08', // Static value for testing
|
|
113
|
+
totalTaxAmount: 100.00 // Static value for testing
|
|
114
|
+
}
|
|
115
|
+
]
|
|
109
116
|
}
|
|
110
117
|
const totalSale = summary.totalEncumbered + summary.totalExempt + summary.totalExonerated
|
|
111
118
|
return {
|
|
@@ -121,7 +128,7 @@ export class Document {
|
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
private isAService(orderLine: OrderLine): boolean {
|
|
124
|
-
const servicesMeasurementUnits = ['Sp', 'St', 'Spe']
|
|
131
|
+
const servicesMeasurementUnits = ['Sp', 'St', 'Spe']
|
|
125
132
|
return servicesMeasurementUnits.includes(orderLine.measureUnit)
|
|
126
133
|
}
|
|
127
134
|
|
|
@@ -129,7 +136,7 @@ export class Document {
|
|
|
129
136
|
return this.orderLines.filter(this.isAService).reduce<OrderLineSum>((previousValue, currentValue) => {
|
|
130
137
|
return {
|
|
131
138
|
totalAmount: previousValue.totalAmount + currentValue.totalAmount,
|
|
132
|
-
totalTaxes: previousValue.totalTaxes + currentValue.tax
|
|
139
|
+
totalTaxes: previousValue.totalTaxes + (currentValue.tax?.amount ?? 0)
|
|
133
140
|
}
|
|
134
141
|
}, { totalAmount: 0, totalTaxes: 0 })
|
|
135
142
|
}
|
|
@@ -138,7 +145,7 @@ export class Document {
|
|
|
138
145
|
return this.orderLines.filter((ol) => !this.isAService(ol)).reduce<OrderLineSum>((previousValue, currentValue) => {
|
|
139
146
|
return {
|
|
140
147
|
totalAmount: previousValue.totalAmount + currentValue.totalAmount,
|
|
141
|
-
totalTaxes: previousValue.totalTaxes + currentValue.tax
|
|
148
|
+
totalTaxes: previousValue.totalTaxes + (currentValue.tax?.amount ?? 0)
|
|
142
149
|
}
|
|
143
150
|
}, { totalAmount: 0, totalTaxes: 0 })
|
|
144
151
|
}
|
|
@@ -147,7 +154,7 @@ export class Document {
|
|
|
147
154
|
return this.orderLines.reduce<OrderLineSum>((previousValue, currentValue) => {
|
|
148
155
|
return {
|
|
149
156
|
totalAmount: previousValue.totalAmount + currentValue.totalAmount,
|
|
150
|
-
totalTaxes: previousValue.totalTaxes + currentValue.tax
|
|
157
|
+
totalTaxes: previousValue.totalTaxes + (currentValue.tax?.amount ?? 0)
|
|
151
158
|
}
|
|
152
159
|
}, { totalAmount: 0, totalTaxes: 0 })
|
|
153
160
|
}
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
export type DocumentNames =
|
|
2
|
+
'FacturaElectronica' |
|
|
3
|
+
'TiqueteElectronico' |
|
|
4
|
+
'FacturaElectronicaExportacion' |
|
|
5
|
+
'NotaCreditoElectronica' |
|
|
6
|
+
'NotaDebitoElectronica' |
|
|
7
|
+
'MensajeReceptor'
|
|
8
|
+
|
|
9
|
+
export type DocumentTypeValues = 'FE' | 'ND' | 'NC' | 'TE'
|
|
2
10
|
|
|
3
11
|
const map: {[key: string]: DocumentTypeValues} = {
|
|
4
12
|
FacturaElectronica: 'FE',
|
|
5
13
|
FacturaElectronicaExportacion: 'FE',
|
|
14
|
+
TiqueteElectronico: 'TE',
|
|
6
15
|
NotaCreditoElectronica: 'NC',
|
|
7
16
|
NotaDebitoElectronica: 'NC'
|
|
8
17
|
}
|
|
9
18
|
|
|
10
|
-
type DocumentTypeValues = 'FE' | 'ND' | 'NC' | 'TE'
|
|
11
|
-
|
|
12
19
|
export class DocumentType {
|
|
13
20
|
value: DocumentTypeValues
|
|
14
21
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { consecutivoStr } from '@src/lib/genClave'
|
|
2
|
+
import { DocumentTypeValues } from './DocumentType'
|
|
2
3
|
|
|
3
4
|
type FullConsecutiveProps = {
|
|
4
5
|
consecutiveIdentifier: string;
|
|
5
|
-
documentType
|
|
6
|
+
documentType: DocumentTypeValues;
|
|
6
7
|
branch?: string;
|
|
7
8
|
terminal?: string;
|
|
8
9
|
}
|
|
@@ -59,14 +59,17 @@ export class OrderLine {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
get totalOrderLineAmount(): number {
|
|
62
|
-
return this.props.totalOrderLineAmount || this.subTotal + this.tax
|
|
62
|
+
return this.props.totalOrderLineAmount || this.subTotal + (this.tax?.amount ?? 0)
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
get tax(): TaxProps {
|
|
66
|
+
// @ts-expect-error pending-to-fix
|
|
66
67
|
const rate = this.props.tax.rate
|
|
67
68
|
return {
|
|
68
69
|
rate,
|
|
70
|
+
// @ts-expect-error pending-to-fix
|
|
69
71
|
code: this.props.tax.code,
|
|
72
|
+
// @ts-expect-error pending-to-fix
|
|
70
73
|
rateCode: this.props.tax.rateCode,
|
|
71
74
|
amount: this.subTotal * (rate / 100)
|
|
72
75
|
}
|
|
@@ -83,8 +86,11 @@ export class OrderLine {
|
|
|
83
86
|
totalAmount: props.totalAmount
|
|
84
87
|
}
|
|
85
88
|
const tax: TaxProps = {
|
|
89
|
+
// @ts-expect-error pending-to-fix
|
|
86
90
|
code: props.tax.code,
|
|
91
|
+
// @ts-expect-error pending-to-fix
|
|
87
92
|
rate: typeof props.tax.rate === 'number' ? props.tax.rate : 13,
|
|
93
|
+
// @ts-expect-error pending-to-fix
|
|
88
94
|
rateCode: props.tax.rateCode
|
|
89
95
|
}
|
|
90
96
|
return new OrderLine({
|
package/src/ATV/core/Person.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type PhoneProps = {
|
|
|
14
14
|
export type PersonProps = {
|
|
15
15
|
fullName: string;
|
|
16
16
|
identifier: {
|
|
17
|
-
type: '01' | '02';
|
|
17
|
+
type: '01' | '02' | undefined;
|
|
18
18
|
id: string;
|
|
19
19
|
};
|
|
20
20
|
commercialName: string;
|
|
@@ -35,7 +35,7 @@ export class Person {
|
|
|
35
35
|
return this.props.fullName
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
get identifierType(): '
|
|
38
|
+
get identifierType(): PersonProps['identifier']['type'] {
|
|
39
39
|
return this.props.identifier.type
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -6,22 +6,22 @@ type ReceptorConsecutiveProps = {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export class ReceptorConsecutive {
|
|
9
|
-
|
|
9
|
+
private props: ReceptorConsecutiveProps
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
constructor(props: ReceptorConsecutiveProps) {
|
|
12
|
+
this.props = props
|
|
13
|
+
}
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
get value(): string {
|
|
16
|
+
return Object.values(this.props).join('')
|
|
17
|
+
}
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
19
|
+
public static create(props: ReceptorConsecutiveProps): ReceptorConsecutive {
|
|
20
|
+
return new ReceptorConsecutive({
|
|
21
|
+
branch: props.branch.padStart(3, '0'),
|
|
22
|
+
terminal: props.terminal.padStart(5, '0'),
|
|
23
|
+
documentType: props.documentType,
|
|
24
|
+
consecutive: props.consecutive.padStart(10, '0')
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -14,28 +14,28 @@ export class ReferenceInformation {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
get docType(): string {
|
|
17
|
-
return this.props.docType
|
|
17
|
+
return this.props.docType
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
get refNumber(): string {
|
|
21
|
-
return this.props.refNumber
|
|
21
|
+
return this.props.refNumber
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
get issueDate(): Date {
|
|
25
|
-
return this.props.issueDate
|
|
25
|
+
return this.props.issueDate
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
get code(): string {
|
|
29
|
-
return this.props.code
|
|
29
|
+
return this.props.code
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
get reason(): string {
|
|
33
|
-
return this.props.reason
|
|
33
|
+
return this.props.reason
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
public static create(props: ReferenceInformationProps): ReferenceInformation {
|
|
37
37
|
return new ReferenceInformation({
|
|
38
|
-
...props
|
|
38
|
+
...props
|
|
39
39
|
})
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -16,5 +16,10 @@ export type SummaryProps = {
|
|
|
16
16
|
totalDiscounts?: number; // TotalDescuentos
|
|
17
17
|
totalNetSale?: number; // TotalVentaNeta
|
|
18
18
|
totalTaxes: number; // TotalImpuesto
|
|
19
|
+
totalTaxBreakdown?: Array<{
|
|
20
|
+
code: string; // Codigo
|
|
21
|
+
taxRateCode?: string; // CodigoTarifaIVA
|
|
22
|
+
totalTaxAmount: number; // TotalMontoImpuesto
|
|
23
|
+
}>; // TotalDesgloseImpuesto
|
|
19
24
|
totalVoucher: number; // TotalComprobante
|
|
20
25
|
}
|
package/src/ATV/core/types.ts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
+
import { PersonProps } from './Person'
|
|
2
|
+
|
|
1
3
|
export enum AceptationStates {
|
|
2
4
|
ACCEPTED = 1,
|
|
3
5
|
PARTIALLY_ACCEPTED = 2,
|
|
4
6
|
DECLINED = 3
|
|
5
7
|
}
|
|
6
|
-
|
|
8
|
+
|
|
7
9
|
export type ReceptorMessageProps = {
|
|
8
10
|
clave: string;
|
|
9
11
|
emitterIdentifier: string;
|
|
10
|
-
emitterIdentifierType:
|
|
12
|
+
emitterIdentifierType: PersonProps['identifier']['type'];
|
|
11
13
|
receptorIdentifier: string;
|
|
12
|
-
receptorIdentifierType:
|
|
14
|
+
receptorIdentifierType: PersonProps['identifier']['type'];
|
|
13
15
|
documentIssueDate: Date;
|
|
14
16
|
activityCode: string;
|
|
15
17
|
aceptationState: AceptationStates
|
|
16
18
|
aceptationDetailMessage: string;
|
|
17
19
|
receptorConcecutive: string;
|
|
18
20
|
taxCondition: string;
|
|
19
|
-
totalTaxes: number;
|
|
20
|
-
totalSale:
|
|
21
|
+
totalTaxes: number;
|
|
22
|
+
totalSale: number;
|
|
21
23
|
}
|
|
22
|
-
|
package/src/ATV/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { CreateDocumentInput } from './core/CreateDocFactory'
|
|
|
11
11
|
import { CreateReceptorMessageCommand, CreateReceptorMessageCommandInput } from './useCases/createReceptorMessage'
|
|
12
12
|
|
|
13
13
|
export class ATV {
|
|
14
|
-
public readonly options: ATVOptions
|
|
14
|
+
public readonly options: ATVOptions | undefined
|
|
15
15
|
constructor(options?: ATVOptions, public readonly mode: Mode = 'prod') {
|
|
16
16
|
this.options = options
|
|
17
17
|
}
|
|
@@ -67,14 +67,14 @@ export class ATV {
|
|
|
67
67
|
confirmation: this.parseConfirmationMessage(xmlString),
|
|
68
68
|
xml: xmlString,
|
|
69
69
|
rawResponse: response,
|
|
70
|
-
errorCause: null
|
|
70
|
+
errorCause: null
|
|
71
71
|
}
|
|
72
72
|
} catch (error) {
|
|
73
73
|
const response = error.response || {}
|
|
74
74
|
return {
|
|
75
75
|
status: response.status || 500,
|
|
76
76
|
errorCause: response.statusText || error.message,
|
|
77
|
-
rawResponse: response
|
|
77
|
+
rawResponse: response
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
}
|