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