facturas 0.5.2 → 0.6.0
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/README.md +2 -0
- package/dist/errors.d.ts +16 -1
- package/dist/errors.mjs +14 -0
- package/dist/errors.mjs.map +1 -1
- package/dist/fiscal-evidence-DbbFH74x.d.ts +69 -0
- package/dist/{index-CqXVyU0E.d.ts → index-3fdgJ3c2.d.ts} +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.mjs +919 -265
- package/dist/index.mjs.map +1 -1
- package/dist/padron.d.ts +2 -2
- package/dist/padron.mjs.map +1 -1
- package/dist/{types-CKKe1Oo4.d.ts → types-Cup-oevW.d.ts} +2 -0
- package/dist/types.d.ts +1 -1
- package/dist/wsfe.d.ts +32 -3
- package/dist/wsfe.mjs +477 -108
- package/dist/wsfe.mjs.map +1 -1
- package/dist/wsmtxca.d.ts +64 -8
- package/dist/wsmtxca.mjs +543 -156
- package/dist/wsmtxca.mjs.map +1 -1
- package/package.json +1 -1
package/dist/wsmtxca.mjs
CHANGED
|
@@ -7,158 +7,293 @@ var ArcaError = class extends Error {
|
|
|
7
7
|
this.code = code;
|
|
8
8
|
}
|
|
9
9
|
};
|
|
10
|
+
var ArcaTransportError = class extends ArcaError {
|
|
11
|
+
name = "ArcaTransportError";
|
|
12
|
+
statusCode;
|
|
13
|
+
contentType;
|
|
14
|
+
responseBody;
|
|
15
|
+
constructor(message, options) {
|
|
16
|
+
super(message, "ARCA_TRANSPORT_ERROR", options);
|
|
17
|
+
this.statusCode = options?.statusCode;
|
|
18
|
+
this.contentType = options?.contentType;
|
|
19
|
+
this.responseBody = options?.responseBody;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var ArcaSoapFaultError = class extends ArcaError {
|
|
23
|
+
name = "ArcaSoapFaultError";
|
|
24
|
+
faultCode;
|
|
25
|
+
detail;
|
|
26
|
+
constructor(message, options) {
|
|
27
|
+
super(message, "ARCA_SOAP_FAULT", options);
|
|
28
|
+
this.faultCode = options?.faultCode;
|
|
29
|
+
this.detail = options?.detail;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var ArcaInvalidSoapResponseError = class extends ArcaError {
|
|
33
|
+
name = "ArcaInvalidSoapResponseError";
|
|
34
|
+
service;
|
|
35
|
+
operation;
|
|
36
|
+
endpointUrl;
|
|
37
|
+
statusCode;
|
|
38
|
+
contentType;
|
|
39
|
+
responseBodyLength;
|
|
40
|
+
responseBodyPreview;
|
|
41
|
+
parsedDetail;
|
|
42
|
+
constructor(message, options) {
|
|
43
|
+
super(message, "ARCA_INVALID_SOAP_RESPONSE", options);
|
|
44
|
+
this.service = options?.service;
|
|
45
|
+
this.operation = options?.operation;
|
|
46
|
+
this.endpointUrl = options?.endpointUrl;
|
|
47
|
+
this.statusCode = options?.statusCode;
|
|
48
|
+
this.contentType = options?.contentType;
|
|
49
|
+
this.responseBodyLength = options?.responseBodyLength;
|
|
50
|
+
this.responseBodyPreview = options?.responseBodyPreview;
|
|
51
|
+
this.parsedDetail = options?.parsedDetail;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
10
54
|
var ArcaServiceError = class extends ArcaError {
|
|
11
55
|
name = "ArcaServiceError";
|
|
12
56
|
serviceCode;
|
|
57
|
+
service;
|
|
58
|
+
operation;
|
|
59
|
+
result;
|
|
60
|
+
resultLevel;
|
|
61
|
+
results;
|
|
62
|
+
cae;
|
|
63
|
+
issues;
|
|
13
64
|
detail;
|
|
14
65
|
constructor(message, options) {
|
|
15
66
|
super(message, "ARCA_SERVICE_ERROR", options);
|
|
16
67
|
this.serviceCode = options?.serviceCode;
|
|
68
|
+
this.service = options?.service;
|
|
69
|
+
this.operation = options?.operation;
|
|
70
|
+
this.result = options?.result;
|
|
71
|
+
this.resultLevel = options?.resultLevel;
|
|
72
|
+
this.results = options?.results;
|
|
73
|
+
this.cae = options?.cae;
|
|
74
|
+
this.issues = options?.issues;
|
|
17
75
|
this.detail = options?.detail;
|
|
18
76
|
}
|
|
19
77
|
};
|
|
20
78
|
|
|
21
79
|
// src/services/wsmtxca.ts
|
|
22
80
|
function createWsmtxcaService(options) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
const raw = unwrapWsmtxcaOperationResponse(
|
|
44
|
-
response.result,
|
|
45
|
-
"autorizarComprobante"
|
|
46
|
-
);
|
|
47
|
-
const authorizationPayload = extractWsmtxcaAuthorizationPayload(raw);
|
|
48
|
-
const messages = extractWsmtxcaMessages(raw);
|
|
49
|
-
const resultado = raw.resultado ?? authorizationPayload.resultado;
|
|
50
|
-
const caeValue = authorizationPayload.CAE ?? authorizationPayload.codigoAutorizacion ?? raw.codigoAutorizacion;
|
|
51
|
-
if (resultado === "R" || caeValue == null) {
|
|
52
|
-
throw new ArcaServiceError(
|
|
53
|
-
messages.join(" | ") || "WSMTXCA rejected the voucher authorization",
|
|
54
|
-
{ detail: raw }
|
|
55
|
-
);
|
|
81
|
+
async function executeWsmtxcaAuthenticatedOperation(operation, input, body = {}, retries) {
|
|
82
|
+
const auth = await options.auth.login("wsmtxca", {
|
|
83
|
+
representedTaxId: input.representedTaxId,
|
|
84
|
+
forceRefresh: input.forceRefresh
|
|
85
|
+
});
|
|
86
|
+
const response = await options.soap.execute({
|
|
87
|
+
service: "wsmtxca",
|
|
88
|
+
operation,
|
|
89
|
+
...retries === void 0 ? {} : { retries },
|
|
90
|
+
bodyElementName: `${operation}Request`,
|
|
91
|
+
bodyElementNamespaceMode: "prefix",
|
|
92
|
+
body: {
|
|
93
|
+
authRequest: createWsmtxcaAuth(
|
|
94
|
+
input.representedTaxId ?? options.config.taxId,
|
|
95
|
+
auth.token,
|
|
96
|
+
auth.sign
|
|
97
|
+
),
|
|
98
|
+
...body
|
|
56
99
|
}
|
|
100
|
+
});
|
|
101
|
+
return unwrapWsmtxcaOperationResponse(response.result, operation);
|
|
102
|
+
}
|
|
103
|
+
async function executeWsmtxcaAuthorization({
|
|
104
|
+
representedTaxId,
|
|
105
|
+
data,
|
|
106
|
+
forceRefresh
|
|
107
|
+
}) {
|
|
108
|
+
try {
|
|
109
|
+
const raw = await executeWsmtxcaAuthenticatedOperation(
|
|
110
|
+
"autorizarComprobante",
|
|
111
|
+
{ representedTaxId, forceRefresh },
|
|
112
|
+
data,
|
|
113
|
+
0
|
|
114
|
+
);
|
|
115
|
+
return { outcome: classifyWsmtxcaAuthorization(raw) };
|
|
116
|
+
} catch (error) {
|
|
57
117
|
return {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
authorizationPayload.fechaVencimientoCAE ?? authorizationPayload.fechaVencimiento ?? raw.fechaVencimiento
|
|
61
|
-
),
|
|
62
|
-
voucherNumber: parseWsmtxcaVoucherNumber(
|
|
63
|
-
authorizationPayload.numeroComprobante ?? raw.numeroComprobante,
|
|
64
|
-
"WSMTXCA did not return the authorized voucher number",
|
|
65
|
-
raw
|
|
66
|
-
),
|
|
67
|
-
messages,
|
|
68
|
-
raw
|
|
118
|
+
outcome: createWsmtxcaIndeterminateOutcome(error),
|
|
119
|
+
error
|
|
69
120
|
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async function authorizeVoucherOutcome(input) {
|
|
124
|
+
return (await executeWsmtxcaAuthorization(input)).outcome;
|
|
125
|
+
}
|
|
126
|
+
async function authorizeVoucher(input) {
|
|
127
|
+
const execution = await executeWsmtxcaAuthorization(input);
|
|
128
|
+
if (execution.error) {
|
|
129
|
+
throw execution.error;
|
|
130
|
+
}
|
|
131
|
+
if (execution.outcome.kind !== "authorized") {
|
|
132
|
+
throw createWsmtxcaOutcomeError(execution.outcome);
|
|
133
|
+
}
|
|
134
|
+
const { outcome } = execution;
|
|
135
|
+
return {
|
|
136
|
+
cae: outcome.cae,
|
|
137
|
+
...outcome.caeExpiry === void 0 ? {} : { caeExpiry: outcome.caeExpiry },
|
|
138
|
+
voucherNumber: outcome.voucherNumber,
|
|
139
|
+
messages: formatWsmtxcaIssues([
|
|
140
|
+
...outcome.errors,
|
|
141
|
+
...outcome.observations
|
|
142
|
+
]),
|
|
143
|
+
raw: outcome.raw ?? {}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
async function getLastAuthorizedVoucher({
|
|
147
|
+
representedTaxId,
|
|
148
|
+
voucherType,
|
|
149
|
+
salesPoint,
|
|
150
|
+
forceRefresh
|
|
151
|
+
}) {
|
|
152
|
+
const operation = "consultarUltimoComprobanteAutorizado";
|
|
153
|
+
const raw = await executeWsmtxcaAuthenticatedOperation(
|
|
154
|
+
operation,
|
|
155
|
+
{ representedTaxId, forceRefresh },
|
|
156
|
+
{
|
|
157
|
+
consultaUltimoComprobanteAutorizadoRequest: {
|
|
158
|
+
codigoTipoComprobante: voucherType,
|
|
159
|
+
numeroPuntoVenta: salesPoint
|
|
96
160
|
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
161
|
+
}
|
|
162
|
+
);
|
|
163
|
+
const errors = extractWsmtxcaIssues(raw, operation, "error");
|
|
164
|
+
if (errors.length > 0 && errors.every((issue) => issue.code === "1502")) {
|
|
165
|
+
return { voucherNumber: 0, raw };
|
|
166
|
+
}
|
|
167
|
+
if (errors.length > 0) {
|
|
168
|
+
throw createWsmtxcaServiceError(operation, raw, errors);
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
voucherNumber: parseWsmtxcaVoucherNumber(
|
|
172
|
+
raw.numeroComprobante ?? raw.cbteNro ?? raw.nroComprobante,
|
|
173
|
+
"WSMTXCA did not return the last authorized voucher number",
|
|
174
|
+
raw,
|
|
175
|
+
true
|
|
176
|
+
),
|
|
177
|
+
raw
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
async function getSalesPoints({
|
|
181
|
+
representedTaxId,
|
|
182
|
+
forceRefresh
|
|
183
|
+
}) {
|
|
184
|
+
const raw = await executeWsmtxcaAuthenticatedOperation(
|
|
185
|
+
"consultarPuntosVenta",
|
|
186
|
+
{ representedTaxId, forceRefresh }
|
|
187
|
+
);
|
|
188
|
+
const rawSalesPoints = toRecord(raw.arrayPuntosVenta)?.puntoVenta;
|
|
189
|
+
const entries = Array.isArray(rawSalesPoints) ? rawSalesPoints : rawSalesPoints ? [rawSalesPoints] : [];
|
|
190
|
+
const salesPoints = entries.flatMap((entry) => {
|
|
191
|
+
const record = toRecord(entry);
|
|
192
|
+
const number = parseOptionalPositiveInteger(record?.numeroPuntoVenta);
|
|
193
|
+
if (number === void 0) {
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
const deletedAt = normalizeWsmtxcaResponseDate(record?.fechaBaja);
|
|
197
|
+
return [
|
|
198
|
+
{
|
|
199
|
+
number,
|
|
200
|
+
blocked: String(record?.bloqueado ?? "N").toUpperCase() === "S",
|
|
201
|
+
...deletedAt === void 0 ? {} : { deletedAt }
|
|
202
|
+
}
|
|
203
|
+
];
|
|
204
|
+
});
|
|
205
|
+
return { salesPoints, raw };
|
|
206
|
+
}
|
|
207
|
+
async function lookupVoucher({
|
|
208
|
+
representedTaxId,
|
|
209
|
+
voucherType,
|
|
210
|
+
salesPoint,
|
|
211
|
+
voucherNumber,
|
|
212
|
+
forceRefresh
|
|
213
|
+
}) {
|
|
214
|
+
const operation = "consultarComprobante";
|
|
215
|
+
const raw = await executeWsmtxcaAuthenticatedOperation(
|
|
216
|
+
operation,
|
|
217
|
+
{ representedTaxId, forceRefresh },
|
|
218
|
+
{
|
|
219
|
+
consultaComprobanteRequest: {
|
|
220
|
+
codigoTipoComprobante: voucherType,
|
|
221
|
+
numeroPuntoVenta: salesPoint,
|
|
222
|
+
numeroComprobante: voucherNumber
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
const errors = extractWsmtxcaIssues(raw, operation, "error");
|
|
227
|
+
const observations = extractWsmtxcaIssues(raw, operation, "observation");
|
|
228
|
+
if (errors.length > 0 && errors.every((issue) => issue.code === "1503")) {
|
|
102
229
|
return {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
230
|
+
kind: "not_found",
|
|
231
|
+
service: "wsmtxca",
|
|
232
|
+
operation,
|
|
233
|
+
errors,
|
|
234
|
+
observations,
|
|
108
235
|
raw
|
|
109
236
|
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
service: "wsmtxca",
|
|
124
|
-
operation: "consultarComprobante",
|
|
125
|
-
bodyElementName: "consultarComprobanteRequest",
|
|
126
|
-
bodyElementNamespaceMode: "prefix",
|
|
127
|
-
body: {
|
|
128
|
-
authRequest: createWsmtxcaAuth(
|
|
129
|
-
representedTaxId ?? options.config.taxId,
|
|
130
|
-
auth.token,
|
|
131
|
-
auth.sign
|
|
132
|
-
),
|
|
133
|
-
consultaComprobanteRequest: {
|
|
134
|
-
codigoTipoComprobante: voucherType,
|
|
135
|
-
numeroPuntoVenta: salesPoint,
|
|
136
|
-
numeroComprobante: voucherNumber
|
|
137
|
-
}
|
|
237
|
+
}
|
|
238
|
+
if (errors.length > 0) {
|
|
239
|
+
throw createWsmtxcaServiceError(operation, raw, errors);
|
|
240
|
+
}
|
|
241
|
+
const voucher = extractWsmtxcaVoucherPayload(raw);
|
|
242
|
+
if (voucher === raw && !toRecord(raw.comprobante)) {
|
|
243
|
+
throw new ArcaServiceError(
|
|
244
|
+
"WSMTXCA did not return the voucher issue date",
|
|
245
|
+
{
|
|
246
|
+
service: "wsmtxca",
|
|
247
|
+
operation,
|
|
248
|
+
issues: observations,
|
|
249
|
+
detail: raw
|
|
138
250
|
}
|
|
139
|
-
});
|
|
140
|
-
const raw = unwrapWsmtxcaOperationResponse(
|
|
141
|
-
response.result,
|
|
142
|
-
"consultarComprobante"
|
|
143
251
|
);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
kind: "found",
|
|
255
|
+
service: "wsmtxca",
|
|
256
|
+
operation,
|
|
257
|
+
voucher: mapWsmtxcaVoucherInfo(voucher),
|
|
258
|
+
observations,
|
|
259
|
+
raw
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
async function getVoucher(input) {
|
|
263
|
+
const lookup = await lookupVoucher(input);
|
|
264
|
+
if (lookup.kind === "not_found") {
|
|
265
|
+
throw createWsmtxcaServiceError(
|
|
266
|
+
lookup.operation,
|
|
267
|
+
lookup.raw,
|
|
268
|
+
lookup.errors
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
const invoiceDate = lookup.voucher.invoiceDate;
|
|
272
|
+
if (!invoiceDate) {
|
|
273
|
+
throw new ArcaServiceError(
|
|
274
|
+
formatWsmtxcaIssues(lookup.observations)[0] ?? "WSMTXCA did not return the voucher issue date",
|
|
275
|
+
{
|
|
276
|
+
service: "wsmtxca",
|
|
277
|
+
operation: lookup.operation,
|
|
278
|
+
issues: lookup.observations,
|
|
279
|
+
detail: lookup.raw
|
|
280
|
+
}
|
|
148
281
|
);
|
|
149
|
-
if (!invoiceDate) {
|
|
150
|
-
throw new ArcaServiceError(
|
|
151
|
-
messages[0] ?? "WSMTXCA did not return the voucher issue date",
|
|
152
|
-
{ detail: raw }
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
return {
|
|
156
|
-
invoiceDate,
|
|
157
|
-
voucher,
|
|
158
|
-
messages,
|
|
159
|
-
raw
|
|
160
|
-
};
|
|
161
282
|
}
|
|
283
|
+
return {
|
|
284
|
+
invoiceDate,
|
|
285
|
+
voucher: lookup.voucher.raw,
|
|
286
|
+
messages: formatWsmtxcaIssues(lookup.observations),
|
|
287
|
+
raw: lookup.raw
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
return {
|
|
291
|
+
authorizeVoucherOutcome,
|
|
292
|
+
authorizeVoucher,
|
|
293
|
+
getLastAuthorizedVoucher,
|
|
294
|
+
getSalesPoints,
|
|
295
|
+
lookupVoucher,
|
|
296
|
+
getVoucher
|
|
162
297
|
};
|
|
163
298
|
}
|
|
164
299
|
function createWsmtxcaAuth(representedTaxId, token, sign) {
|
|
@@ -169,7 +304,7 @@ function createWsmtxcaAuth(representedTaxId, token, sign) {
|
|
|
169
304
|
};
|
|
170
305
|
}
|
|
171
306
|
function toRecord(value) {
|
|
172
|
-
return value && typeof value === "object" ? value : void 0;
|
|
307
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
173
308
|
}
|
|
174
309
|
function unwrapWsmtxcaOperationResponse(response, operation) {
|
|
175
310
|
const responseRecord = toRecord(response) ?? {};
|
|
@@ -179,6 +314,9 @@ function unwrapWsmtxcaOperationResponse(response, operation) {
|
|
|
179
314
|
if (operation === "consultarComprobante") {
|
|
180
315
|
return toRecord(responseRecord.consultarComprobanteResponse) ?? toRecord(responseRecord.consultaComprobanteResponse) ?? toRecord(responseRecord.consultarComprobanteResult) ?? responseRecord;
|
|
181
316
|
}
|
|
317
|
+
if (operation === "consultarPuntosVenta") {
|
|
318
|
+
return toRecord(responseRecord.consultarPuntosVentaResponse) ?? toRecord(responseRecord.consultarPuntosVentaResult) ?? responseRecord;
|
|
319
|
+
}
|
|
182
320
|
return toRecord(responseRecord.consultarUltimoComprobanteAutorizadoResponse) ?? toRecord(responseRecord.consultaUltimoComprobanteAutorizadoResponse) ?? toRecord(responseRecord.consultarUltimoComprobanteAutorizadoResult) ?? responseRecord;
|
|
183
321
|
}
|
|
184
322
|
function extractWsmtxcaAuthorizationPayload(raw) {
|
|
@@ -187,42 +325,291 @@ function extractWsmtxcaAuthorizationPayload(raw) {
|
|
|
187
325
|
function extractWsmtxcaVoucherPayload(raw) {
|
|
188
326
|
return toRecord(raw.comprobanteResponse) ?? toRecord(raw.comprobante) ?? toRecord(raw.cmp) ?? raw;
|
|
189
327
|
}
|
|
190
|
-
function
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
328
|
+
function classifyWsmtxcaAuthorization(raw) {
|
|
329
|
+
const operation = "autorizarComprobante";
|
|
330
|
+
const payload = extractWsmtxcaAuthorizationPayload(raw);
|
|
331
|
+
const result = normalizeWsmtxcaResult(raw.resultado ?? payload.resultado);
|
|
332
|
+
const cae = normalizeWsmtxcaString(
|
|
333
|
+
payload.CAE ?? payload.codigoAutorizacion ?? raw.codigoAutorizacion
|
|
334
|
+
);
|
|
335
|
+
const caeExpiry = normalizeWsmtxcaResponseDate(
|
|
336
|
+
payload.fechaVencimientoCAE ?? payload.fechaVencimiento ?? raw.fechaVencimiento
|
|
337
|
+
);
|
|
338
|
+
const voucherNumber = parseOptionalPositiveInteger(
|
|
339
|
+
payload.numeroComprobante ?? raw.numeroComprobante
|
|
340
|
+
);
|
|
341
|
+
const errors = extractWsmtxcaIssues(raw, operation, "error");
|
|
342
|
+
const observations = extractWsmtxcaIssues(raw, operation, "observation");
|
|
343
|
+
const base = {
|
|
344
|
+
service: "wsmtxca",
|
|
345
|
+
operation,
|
|
346
|
+
results: createWsmtxcaResults(result),
|
|
347
|
+
errors,
|
|
348
|
+
observations,
|
|
349
|
+
raw
|
|
350
|
+
};
|
|
351
|
+
if ((result === "A" || result === "O") && cae && voucherNumber !== void 0 && errors.length === 0) {
|
|
352
|
+
return {
|
|
353
|
+
...base,
|
|
354
|
+
kind: "authorized",
|
|
355
|
+
result,
|
|
356
|
+
resultLevel: "operation",
|
|
357
|
+
cae,
|
|
358
|
+
...caeExpiry === void 0 ? {} : { caeExpiry },
|
|
359
|
+
voucherNumber
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
if (result === "R" && !cae && errors.length > 0) {
|
|
363
|
+
return {
|
|
364
|
+
...base,
|
|
365
|
+
kind: "rejected",
|
|
366
|
+
result: "R",
|
|
367
|
+
resultLevel: "operation"
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
const outcome = {
|
|
371
|
+
...base,
|
|
372
|
+
kind: "indeterminate",
|
|
373
|
+
reason: result === "R" && Boolean(cae) || (result === "A" || result === "O") && Boolean(errors.length) ? "contradictory_response" : "incomplete_response",
|
|
374
|
+
...result === void 0 ? {} : { result },
|
|
375
|
+
...result === void 0 ? {} : { resultLevel: "operation" }
|
|
376
|
+
};
|
|
377
|
+
assignWsmtxcaValue(outcome, "cae", cae);
|
|
378
|
+
assignWsmtxcaValue(outcome, "caeExpiry", caeExpiry);
|
|
379
|
+
assignWsmtxcaValue(outcome, "voucherNumber", voucherNumber);
|
|
380
|
+
return outcome;
|
|
381
|
+
}
|
|
382
|
+
function createWsmtxcaIndeterminateOutcome(error) {
|
|
383
|
+
return {
|
|
384
|
+
kind: "indeterminate",
|
|
385
|
+
service: "wsmtxca",
|
|
386
|
+
operation: "autorizarComprobante",
|
|
387
|
+
results: {},
|
|
388
|
+
reason: getWsmtxcaIndeterminateReason(error),
|
|
389
|
+
errors: [],
|
|
390
|
+
observations: []
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
function getWsmtxcaIndeterminateReason(error) {
|
|
394
|
+
if (error instanceof ArcaTransportError) {
|
|
395
|
+
return "transport_error";
|
|
396
|
+
}
|
|
397
|
+
if (error instanceof ArcaSoapFaultError) {
|
|
398
|
+
return "soap_fault";
|
|
399
|
+
}
|
|
400
|
+
if (error instanceof ArcaInvalidSoapResponseError) {
|
|
401
|
+
return "invalid_response";
|
|
402
|
+
}
|
|
403
|
+
return "unexpected_error";
|
|
404
|
+
}
|
|
405
|
+
function createWsmtxcaOutcomeError(outcome) {
|
|
406
|
+
const issues = [...outcome.errors, ...outcome.observations];
|
|
407
|
+
const messages = formatWsmtxcaIssues(issues);
|
|
408
|
+
const firstIssue = issues[0];
|
|
409
|
+
return new ArcaServiceError(
|
|
410
|
+
messages.join(" | ") || (outcome.kind === "rejected" ? "WSMTXCA rejected the voucher authorization" : "WSMTXCA did not return conclusive voucher authorization data"),
|
|
411
|
+
{
|
|
412
|
+
service: "wsmtxca",
|
|
413
|
+
operation: outcome.operation,
|
|
414
|
+
...firstIssue?.code === void 0 ? {} : { serviceCode: firstIssue.code },
|
|
415
|
+
...outcome.result === void 0 ? {} : { result: outcome.result },
|
|
416
|
+
...outcome.resultLevel === void 0 ? {} : { resultLevel: outcome.resultLevel },
|
|
417
|
+
results: outcome.results,
|
|
418
|
+
...outcome.kind === "indeterminate" && outcome.cae ? { cae: outcome.cae } : {},
|
|
419
|
+
issues,
|
|
420
|
+
detail: outcome.raw
|
|
199
421
|
}
|
|
200
|
-
|
|
201
|
-
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
function createWsmtxcaResults(operationResult) {
|
|
425
|
+
const results = {};
|
|
426
|
+
assignWsmtxcaValue(results, "operation", operationResult);
|
|
427
|
+
return results;
|
|
428
|
+
}
|
|
429
|
+
function createWsmtxcaServiceError(operation, raw, issues) {
|
|
430
|
+
const firstIssue = issues[0];
|
|
431
|
+
return new ArcaServiceError(
|
|
432
|
+
formatWsmtxcaIssues(issues).join(" | ") || "WSMTXCA returned a service error",
|
|
433
|
+
{
|
|
434
|
+
service: "wsmtxca",
|
|
435
|
+
operation,
|
|
436
|
+
...firstIssue?.code === void 0 ? {} : { serviceCode: firstIssue.code },
|
|
437
|
+
issues,
|
|
438
|
+
detail: raw
|
|
202
439
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
function extractWsmtxcaIssues(raw, operation, source) {
|
|
443
|
+
const container = toRecord(
|
|
444
|
+
source === "error" ? raw.arrayErrores : raw.arrayObservaciones
|
|
445
|
+
);
|
|
446
|
+
return normalizeWsmtxcaIssueEntries(container?.codigoDescripcion).map(
|
|
447
|
+
(entry) => ({
|
|
448
|
+
service: "wsmtxca",
|
|
449
|
+
operation,
|
|
450
|
+
source,
|
|
451
|
+
category: source === "observation" ? "observation" : operation === "autorizarComprobante" ? "business" : "unknown",
|
|
452
|
+
...entry.code === void 0 ? {} : { code: entry.code },
|
|
453
|
+
message: entry.message,
|
|
454
|
+
...operation === "autorizarComprobante" ? { resultLevel: "operation" } : {}
|
|
455
|
+
})
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
function normalizeWsmtxcaIssueEntries(value) {
|
|
459
|
+
const entries = Array.isArray(value) ? value : value ? [value] : [];
|
|
460
|
+
return entries.map((entry) => {
|
|
461
|
+
const record = toRecord(entry) ?? {};
|
|
462
|
+
const code = record.codigo;
|
|
463
|
+
const description = record.descripcion;
|
|
464
|
+
return {
|
|
465
|
+
...code === void 0 || code === null ? {} : { code: String(code) },
|
|
466
|
+
message: description === void 0 || description === null ? "Unknown WSMTXCA issue" : String(description)
|
|
467
|
+
};
|
|
209
468
|
});
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
469
|
+
}
|
|
470
|
+
function formatWsmtxcaIssues(issues) {
|
|
471
|
+
return issues.map((issue) => {
|
|
472
|
+
const prefix = issue.source === "error" ? "Error" : "Obs";
|
|
473
|
+
return `${prefix}${issue.code ? ` ${issue.code}` : ""}: ${issue.message}`;
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
function mapWsmtxcaVoucherInfo(raw) {
|
|
477
|
+
const voucher = { raw };
|
|
478
|
+
const invoiceDate = normalizeWsmtxcaResponseDate(
|
|
479
|
+
raw.fechaEmision ?? raw.fecha ?? raw.CbteFch
|
|
480
|
+
);
|
|
481
|
+
const cae = normalizeWsmtxcaString(raw.codigoAutorizacion ?? raw.CAE);
|
|
482
|
+
const caeExpiry = normalizeWsmtxcaResponseDate(
|
|
483
|
+
raw.fechaVencimiento ?? raw.fechaVencimientoCAE
|
|
484
|
+
);
|
|
485
|
+
const vatAmount = sumWsmtxcaVatAmounts(raw.arraySubtotalesIVA);
|
|
486
|
+
assignWsmtxcaValue(
|
|
487
|
+
voucher,
|
|
488
|
+
"voucherNumber",
|
|
489
|
+
parseOptionalPositiveInteger(raw.numeroComprobante)
|
|
490
|
+
);
|
|
491
|
+
assignWsmtxcaValue(voucher, "invoiceDate", invoiceDate);
|
|
492
|
+
assignWsmtxcaValue(
|
|
493
|
+
voucher,
|
|
494
|
+
"salesPoint",
|
|
495
|
+
parseOptionalPositiveInteger(raw.numeroPuntoVenta)
|
|
216
496
|
);
|
|
217
|
-
|
|
497
|
+
assignWsmtxcaValue(
|
|
498
|
+
voucher,
|
|
499
|
+
"voucherType",
|
|
500
|
+
parseOptionalPositiveInteger(raw.codigoTipoComprobante)
|
|
501
|
+
);
|
|
502
|
+
assignWsmtxcaValue(
|
|
503
|
+
voucher,
|
|
504
|
+
"concept",
|
|
505
|
+
parseOptionalNumber(raw.codigoConcepto)
|
|
506
|
+
);
|
|
507
|
+
assignWsmtxcaValue(
|
|
508
|
+
voucher,
|
|
509
|
+
"documentType",
|
|
510
|
+
parseOptionalNumber(raw.codigoTipoDocumento)
|
|
511
|
+
);
|
|
512
|
+
assignWsmtxcaValue(
|
|
513
|
+
voucher,
|
|
514
|
+
"documentNumber",
|
|
515
|
+
normalizeWsmtxcaString(raw.numeroDocumento)
|
|
516
|
+
);
|
|
517
|
+
assignWsmtxcaValue(
|
|
518
|
+
voucher,
|
|
519
|
+
"receiverVatConditionId",
|
|
520
|
+
parseOptionalNumber(raw.condicionIVAReceptor)
|
|
521
|
+
);
|
|
522
|
+
assignWsmtxcaValue(
|
|
523
|
+
voucher,
|
|
524
|
+
"totalAmount",
|
|
525
|
+
parseOptionalNumber(raw.importeTotal)
|
|
526
|
+
);
|
|
527
|
+
assignWsmtxcaValue(
|
|
528
|
+
voucher,
|
|
529
|
+
"subtotalAmount",
|
|
530
|
+
parseOptionalNumber(raw.importeSubtotal)
|
|
531
|
+
);
|
|
532
|
+
assignWsmtxcaValue(
|
|
533
|
+
voucher,
|
|
534
|
+
"taxableAmount",
|
|
535
|
+
parseOptionalNumber(raw.importeGravado)
|
|
536
|
+
);
|
|
537
|
+
assignWsmtxcaValue(
|
|
538
|
+
voucher,
|
|
539
|
+
"nonTaxableAmount",
|
|
540
|
+
parseOptionalNumber(raw.importeNoGravado)
|
|
541
|
+
);
|
|
542
|
+
assignWsmtxcaValue(
|
|
543
|
+
voucher,
|
|
544
|
+
"exemptAmount",
|
|
545
|
+
parseOptionalNumber(raw.importeExento)
|
|
546
|
+
);
|
|
547
|
+
assignWsmtxcaValue(
|
|
548
|
+
voucher,
|
|
549
|
+
"taxAmount",
|
|
550
|
+
parseOptionalNumber(raw.importeOtrosTributos)
|
|
551
|
+
);
|
|
552
|
+
assignWsmtxcaValue(voucher, "vatAmount", vatAmount);
|
|
553
|
+
assignWsmtxcaValue(
|
|
554
|
+
voucher,
|
|
555
|
+
"currencyId",
|
|
556
|
+
normalizeWsmtxcaString(raw.codigoMoneda)
|
|
557
|
+
);
|
|
558
|
+
assignWsmtxcaValue(
|
|
559
|
+
voucher,
|
|
560
|
+
"exchangeRate",
|
|
561
|
+
parseOptionalNumber(raw.cotizacionMoneda)
|
|
562
|
+
);
|
|
563
|
+
assignWsmtxcaValue(voucher, "cae", cae);
|
|
564
|
+
assignWsmtxcaValue(voucher, "caeExpiry", caeExpiry);
|
|
565
|
+
return voucher;
|
|
566
|
+
}
|
|
567
|
+
function sumWsmtxcaVatAmounts(value) {
|
|
568
|
+
const subtotals = toRecord(value)?.subtotalIVA;
|
|
569
|
+
const entries = Array.isArray(subtotals) ? subtotals : subtotals ? [subtotals] : [];
|
|
570
|
+
const amounts = entries.map((entry) => parseOptionalNumber(toRecord(entry)?.importe)).filter((amount) => amount !== void 0);
|
|
571
|
+
return amounts.length > 0 ? amounts.reduce((total, amount) => total + amount, 0) : void 0;
|
|
218
572
|
}
|
|
219
|
-
function parseWsmtxcaVoucherNumber(value, message, detail) {
|
|
573
|
+
function parseWsmtxcaVoucherNumber(value, message, detail, allowZero = false) {
|
|
220
574
|
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
221
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
222
|
-
throw new ArcaServiceError(message, {
|
|
575
|
+
if (!Number.isFinite(parsed) || (allowZero ? parsed < 0 : parsed <= 0)) {
|
|
576
|
+
throw new ArcaServiceError(message, {
|
|
577
|
+
service: "wsmtxca",
|
|
578
|
+
detail
|
|
579
|
+
});
|
|
223
580
|
}
|
|
224
581
|
return parsed;
|
|
225
582
|
}
|
|
583
|
+
function parseOptionalPositiveInteger(value) {
|
|
584
|
+
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
585
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
586
|
+
}
|
|
587
|
+
function parseOptionalNumber(value) {
|
|
588
|
+
if (value === void 0 || value === null || value === "") {
|
|
589
|
+
return void 0;
|
|
590
|
+
}
|
|
591
|
+
const parsed = Number(value);
|
|
592
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
593
|
+
}
|
|
594
|
+
function normalizeWsmtxcaResult(value) {
|
|
595
|
+
if (typeof value !== "string") {
|
|
596
|
+
return void 0;
|
|
597
|
+
}
|
|
598
|
+
const normalized = value.trim().toUpperCase();
|
|
599
|
+
return normalized || void 0;
|
|
600
|
+
}
|
|
601
|
+
function normalizeWsmtxcaString(value) {
|
|
602
|
+
if (value === void 0 || value === null) {
|
|
603
|
+
return void 0;
|
|
604
|
+
}
|
|
605
|
+
const normalized = String(value).trim();
|
|
606
|
+
return normalized || void 0;
|
|
607
|
+
}
|
|
608
|
+
function assignWsmtxcaValue(target, key, value) {
|
|
609
|
+
if (value !== void 0) {
|
|
610
|
+
target[key] = value;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
226
613
|
function normalizeWsmtxcaResponseDate(value) {
|
|
227
614
|
if (typeof value === "number" && Number.isInteger(value)) {
|
|
228
615
|
return formatCompactDateToIso(value);
|