facturas 0.6.0 → 0.7.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 +9 -2
- package/dist/chunk-C55KOV5N.mjs +1586 -0
- package/dist/chunk-C55KOV5N.mjs.map +1 -0
- package/dist/chunk-EDY3PNKJ.mjs +106 -0
- package/dist/chunk-EDY3PNKJ.mjs.map +1 -0
- package/dist/chunk-IOKZX6CA.mjs +195 -0
- package/dist/chunk-IOKZX6CA.mjs.map +1 -0
- package/dist/chunk-MBWOFO67.mjs +215 -0
- package/dist/chunk-MBWOFO67.mjs.map +1 -0
- package/dist/chunk-PKE4Z4GE.mjs +702 -0
- package/dist/chunk-PKE4Z4GE.mjs.map +1 -0
- package/dist/chunk-VVY2LZIZ.mjs +61 -0
- package/dist/chunk-VVY2LZIZ.mjs.map +1 -0
- package/dist/constants.d.ts +32 -2
- package/dist/constants.mjs +14 -29
- package/dist/constants.mjs.map +1 -1
- package/dist/errors.d.ts +2 -92
- package/dist/errors.mjs +14 -92
- package/dist/errors.mjs.map +1 -1
- package/dist/fiscal-evidence-BQuBbJ3h.d.ts +189 -0
- package/dist/{index-3fdgJ3c2.d.ts → index-CVpygFb0.d.ts} +1 -1
- package/dist/index.d.ts +15 -8
- package/dist/index.mjs +269 -1878
- package/dist/index.mjs.map +1 -1
- package/dist/padron.d.ts +2 -2
- package/dist/padron.mjs +4 -117
- package/dist/padron.mjs.map +1 -1
- package/dist/{types-Cup-oevW.d.ts → types-BXq0da71.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/wsfe.d.ts +48 -7
- package/dist/wsfe.mjs +10 -1007
- package/dist/wsfe.mjs.map +1 -1
- package/dist/wsmtxca.d.ts +3 -3
- package/dist/wsmtxca.mjs +5 -641
- package/dist/wsmtxca.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/fiscal-evidence-DbbFH74x.d.ts +0 -69
package/dist/index.mjs
CHANGED
|
@@ -1,94 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
contentType;
|
|
28
|
-
responseBody;
|
|
29
|
-
constructor(message, options) {
|
|
30
|
-
super(message, "ARCA_TRANSPORT_ERROR", options);
|
|
31
|
-
this.statusCode = options?.statusCode;
|
|
32
|
-
this.contentType = options?.contentType;
|
|
33
|
-
this.responseBody = options?.responseBody;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
var ArcaSoapFaultError = class extends ArcaError {
|
|
37
|
-
name = "ArcaSoapFaultError";
|
|
38
|
-
faultCode;
|
|
39
|
-
detail;
|
|
40
|
-
constructor(message, options) {
|
|
41
|
-
super(message, "ARCA_SOAP_FAULT", options);
|
|
42
|
-
this.faultCode = options?.faultCode;
|
|
43
|
-
this.detail = options?.detail;
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
var ArcaInvalidSoapResponseError = class extends ArcaError {
|
|
47
|
-
name = "ArcaInvalidSoapResponseError";
|
|
48
|
-
service;
|
|
49
|
-
operation;
|
|
50
|
-
endpointUrl;
|
|
51
|
-
statusCode;
|
|
52
|
-
contentType;
|
|
53
|
-
responseBodyLength;
|
|
54
|
-
responseBodyPreview;
|
|
55
|
-
parsedDetail;
|
|
56
|
-
constructor(message, options) {
|
|
57
|
-
super(message, "ARCA_INVALID_SOAP_RESPONSE", options);
|
|
58
|
-
this.service = options?.service;
|
|
59
|
-
this.operation = options?.operation;
|
|
60
|
-
this.endpointUrl = options?.endpointUrl;
|
|
61
|
-
this.statusCode = options?.statusCode;
|
|
62
|
-
this.contentType = options?.contentType;
|
|
63
|
-
this.responseBodyLength = options?.responseBodyLength;
|
|
64
|
-
this.responseBodyPreview = options?.responseBodyPreview;
|
|
65
|
-
this.parsedDetail = options?.parsedDetail;
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
var ArcaServiceError = class extends ArcaError {
|
|
69
|
-
name = "ArcaServiceError";
|
|
70
|
-
serviceCode;
|
|
71
|
-
service;
|
|
72
|
-
operation;
|
|
73
|
-
result;
|
|
74
|
-
resultLevel;
|
|
75
|
-
results;
|
|
76
|
-
cae;
|
|
77
|
-
issues;
|
|
78
|
-
detail;
|
|
79
|
-
constructor(message, options) {
|
|
80
|
-
super(message, "ARCA_SERVICE_ERROR", options);
|
|
81
|
-
this.serviceCode = options?.serviceCode;
|
|
82
|
-
this.service = options?.service;
|
|
83
|
-
this.operation = options?.operation;
|
|
84
|
-
this.result = options?.result;
|
|
85
|
-
this.resultLevel = options?.resultLevel;
|
|
86
|
-
this.results = options?.results;
|
|
87
|
-
this.cae = options?.cae;
|
|
88
|
-
this.issues = options?.issues;
|
|
89
|
-
this.detail = options?.detail;
|
|
90
|
-
}
|
|
91
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
createPadronService
|
|
3
|
+
} from "./chunk-EDY3PNKJ.mjs";
|
|
4
|
+
import {
|
|
5
|
+
buildFacturaB,
|
|
6
|
+
buildFacturaC,
|
|
7
|
+
createWsfeService
|
|
8
|
+
} from "./chunk-C55KOV5N.mjs";
|
|
9
|
+
import "./chunk-VVY2LZIZ.mjs";
|
|
10
|
+
import {
|
|
11
|
+
createWsmtxcaService
|
|
12
|
+
} from "./chunk-PKE4Z4GE.mjs";
|
|
13
|
+
import "./chunk-IOKZX6CA.mjs";
|
|
14
|
+
import {
|
|
15
|
+
ArcaAuthenticationError,
|
|
16
|
+
ArcaConfigurationError,
|
|
17
|
+
ArcaError,
|
|
18
|
+
ArcaInputError,
|
|
19
|
+
ArcaInvalidSoapResponseError,
|
|
20
|
+
ArcaServiceError,
|
|
21
|
+
ArcaSoapFaultError,
|
|
22
|
+
ArcaTransportError,
|
|
23
|
+
createResponseBodyDiagnostic,
|
|
24
|
+
createSafeErrorDiagnostic,
|
|
25
|
+
isArcaAuthenticationError
|
|
26
|
+
} from "./chunk-MBWOFO67.mjs";
|
|
92
27
|
|
|
93
28
|
// src/config.ts
|
|
94
29
|
var ARCA_ENVIRONMENTS = ["production", "test"];
|
|
@@ -100,9 +35,10 @@ var ARCA_ENV_VARIABLES = {
|
|
|
100
35
|
};
|
|
101
36
|
var PRIVATE_KEY_PEM_PREFIXES = [
|
|
102
37
|
"-----BEGIN PRIVATE KEY-----",
|
|
103
|
-
"-----BEGIN RSA PRIVATE KEY-----"
|
|
104
|
-
"-----BEGIN ENCRYPTED PRIVATE KEY-----"
|
|
38
|
+
"-----BEGIN RSA PRIVATE KEY-----"
|
|
105
39
|
];
|
|
40
|
+
var ENCRYPTED_PRIVATE_KEY_PEM_PREFIX = "-----BEGIN ENCRYPTED PRIVATE KEY-----";
|
|
41
|
+
var LEGACY_ENCRYPTED_RSA_PRIVATE_KEY_PATTERN = /^-----BEGIN RSA PRIVATE KEY-----[\s\S]*^Proc-Type:\s*4,\s*ENCRYPTED\s*$/m;
|
|
106
42
|
var VALID_ARCA_LOG_LEVELS = ["debug", "info", "warn", "error"];
|
|
107
43
|
var DEFAULT_ARCA_TIMEOUT_MS = 3e4;
|
|
108
44
|
var DEFAULT_ARCA_RETRIES = 0;
|
|
@@ -133,6 +69,11 @@ function assertArcaClientConfig(config) {
|
|
|
133
69
|
const timeout = normalized.timeout ?? DEFAULT_ARCA_TIMEOUT_MS;
|
|
134
70
|
const retries = normalized.retries ?? DEFAULT_ARCA_RETRIES;
|
|
135
71
|
const retryDelay = normalized.retryDelay ?? DEFAULT_ARCA_RETRY_DELAY_MS;
|
|
72
|
+
if (normalized.privateKeyPem.startsWith(ENCRYPTED_PRIVATE_KEY_PEM_PREFIX) || LEGACY_ENCRYPTED_RSA_PRIVATE_KEY_PATTERN.test(normalized.privateKeyPem)) {
|
|
73
|
+
throw new ArcaConfigurationError(
|
|
74
|
+
"Encrypted private keys are not supported. Provide an unencrypted PKCS#8 or RSA private key PEM."
|
|
75
|
+
);
|
|
76
|
+
}
|
|
136
77
|
if (!/^\d{11}$/.test(normalized.taxId)) {
|
|
137
78
|
invalidFields.push("taxId");
|
|
138
79
|
}
|
|
@@ -235,1699 +176,115 @@ var ARCA_SERVICE_CONFIG = {
|
|
|
235
176
|
namespace: "http://a13.soap.ws.server.puc.sr/",
|
|
236
177
|
endpoint: {
|
|
237
178
|
production: "https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA13",
|
|
238
|
-
test: "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA13"
|
|
239
|
-
},
|
|
240
|
-
soapVersion: "1.1",
|
|
241
|
-
soapActionBase: "",
|
|
242
|
-
usesEmptySoapAction: true
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
function getArcaServiceConfig(service) {
|
|
246
|
-
const serviceConfig = ARCA_SERVICE_CONFIG[service];
|
|
247
|
-
if (!serviceConfig) {
|
|
248
|
-
throw new ArcaConfigurationError(
|
|
249
|
-
`Unsupported ARCA service configuration: ${service}`
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
return serviceConfig;
|
|
253
|
-
}
|
|
254
|
-
function normalizeArcaClientConfig(config) {
|
|
255
|
-
const normalizedEnvironment = normalizeEnvironmentValue(String(config.environment)) ?? config.environment;
|
|
256
|
-
const normalizedLoggerLevel = normalizeLogLevelValue(config.logger?.level);
|
|
257
|
-
return {
|
|
258
|
-
taxId: config.taxId.trim(),
|
|
259
|
-
certificatePem: config.certificatePem.trim(),
|
|
260
|
-
privateKeyPem: config.privateKeyPem.trim(),
|
|
261
|
-
environment: normalizedEnvironment,
|
|
262
|
-
timeout: config.timeout ?? DEFAULT_ARCA_TIMEOUT_MS,
|
|
263
|
-
retries: config.retries ?? DEFAULT_ARCA_RETRIES,
|
|
264
|
-
retryDelay: config.retryDelay ?? DEFAULT_ARCA_RETRY_DELAY_MS,
|
|
265
|
-
...config.logger === void 0 ? {} : {
|
|
266
|
-
logger: {
|
|
267
|
-
...config.logger,
|
|
268
|
-
...normalizedLoggerLevel === void 0 ? {} : { level: normalizedLoggerLevel }
|
|
269
|
-
}
|
|
270
|
-
},
|
|
271
|
-
...config.wsaaSessionStore === void 0 ? {} : { wsaaSessionStore: config.wsaaSessionStore }
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
function normalizeEnvironmentValue(value) {
|
|
275
|
-
if (!value) {
|
|
276
|
-
return void 0;
|
|
277
|
-
}
|
|
278
|
-
const normalized = value.trim().toLowerCase();
|
|
279
|
-
if (ARCA_ENVIRONMENTS.includes(normalized)) {
|
|
280
|
-
return normalized;
|
|
281
|
-
}
|
|
282
|
-
return void 0;
|
|
283
|
-
}
|
|
284
|
-
function readEnv(env, variableName) {
|
|
285
|
-
return env[variableName]?.trim() || void 0;
|
|
286
|
-
}
|
|
287
|
-
function normalizeLogLevelValue(value) {
|
|
288
|
-
if (!value) {
|
|
289
|
-
return void 0;
|
|
290
|
-
}
|
|
291
|
-
const normalized = value.trim().toLowerCase();
|
|
292
|
-
if (VALID_ARCA_LOG_LEVELS.includes(normalized)) {
|
|
293
|
-
return normalized;
|
|
294
|
-
}
|
|
295
|
-
return value;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// src/internal/logger.ts
|
|
299
|
-
var ARCA_LOG_LEVELS = ["debug", "info", "warn", "error"];
|
|
300
|
-
function createArcaLogger(config) {
|
|
301
|
-
const disabled = config?.disabled ?? false;
|
|
302
|
-
const level = resolveArcaLogLevel(config?.level);
|
|
303
|
-
const sink = config?.log ?? defaultArcaLog;
|
|
304
|
-
const log = (messageLevel, message, ...args) => {
|
|
305
|
-
if (disabled || !shouldLog(level, messageLevel)) {
|
|
306
|
-
return;
|
|
307
|
-
}
|
|
308
|
-
sink(messageLevel, message, ...args);
|
|
309
|
-
};
|
|
310
|
-
return {
|
|
311
|
-
disabled,
|
|
312
|
-
level,
|
|
313
|
-
log,
|
|
314
|
-
debug(message, ...args) {
|
|
315
|
-
log("debug", message, ...args);
|
|
316
|
-
},
|
|
317
|
-
info(message, ...args) {
|
|
318
|
-
log("info", message, ...args);
|
|
319
|
-
},
|
|
320
|
-
warn(message, ...args) {
|
|
321
|
-
log("warn", message, ...args);
|
|
322
|
-
},
|
|
323
|
-
error(message, ...args) {
|
|
324
|
-
log("error", message, ...args);
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
function resolveArcaLogLevel(level) {
|
|
329
|
-
if (isArcaLogLevel(level)) {
|
|
330
|
-
return level;
|
|
331
|
-
}
|
|
332
|
-
const envLevel = process.env.ARCA_LOG_LEVEL?.trim().toLowerCase();
|
|
333
|
-
if (isArcaLogLevel(envLevel)) {
|
|
334
|
-
return envLevel;
|
|
335
|
-
}
|
|
336
|
-
return "warn";
|
|
337
|
-
}
|
|
338
|
-
function shouldLog(threshold, messageLevel) {
|
|
339
|
-
return ARCA_LOG_LEVELS.indexOf(messageLevel) >= ARCA_LOG_LEVELS.indexOf(threshold);
|
|
340
|
-
}
|
|
341
|
-
function isArcaLogLevel(value) {
|
|
342
|
-
return ARCA_LOG_LEVELS.includes(value);
|
|
343
|
-
}
|
|
344
|
-
function defaultArcaLog(level, message, ...args) {
|
|
345
|
-
const method = level === "debug" ? console.debug : level === "info" ? console.info : level === "warn" ? console.warn : console.error;
|
|
346
|
-
method(message, ...args);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// src/services/padron.ts
|
|
350
|
-
function createPadronService(options) {
|
|
351
|
-
return {
|
|
352
|
-
async getTaxpayerDetails(taxId) {
|
|
353
|
-
const raw = await executePadronOperation(
|
|
354
|
-
options,
|
|
355
|
-
"padron-a5",
|
|
356
|
-
"getPersona_v2",
|
|
357
|
-
{
|
|
358
|
-
idPersona: Number.parseInt(String(taxId), 10)
|
|
359
|
-
}
|
|
360
|
-
);
|
|
361
|
-
if (!raw) {
|
|
362
|
-
return null;
|
|
363
|
-
}
|
|
364
|
-
const record = raw;
|
|
365
|
-
const datosGenerales = record.datosGenerales;
|
|
366
|
-
return {
|
|
367
|
-
taxId: String(record.idPersona ?? ""),
|
|
368
|
-
...record.tipoPersona === void 0 ? {} : { personType: String(record.tipoPersona) },
|
|
369
|
-
...datosGenerales ? { name: extractPadronName(datosGenerales) } : {},
|
|
370
|
-
raw: record
|
|
371
|
-
};
|
|
372
|
-
},
|
|
373
|
-
async getTaxIdByDocument(documentNumber) {
|
|
374
|
-
const raw = await executePadronOperation(
|
|
375
|
-
options,
|
|
376
|
-
"padron-a13",
|
|
377
|
-
"getIdPersonaListByDocumento",
|
|
378
|
-
{
|
|
379
|
-
documento: String(documentNumber)
|
|
380
|
-
}
|
|
381
|
-
);
|
|
382
|
-
if (!raw) {
|
|
383
|
-
return null;
|
|
384
|
-
}
|
|
385
|
-
const record = raw;
|
|
386
|
-
const idPersona = record.idPersona;
|
|
387
|
-
const taxIds = Array.isArray(idPersona) ? idPersona.map(String) : idPersona === void 0 ? [] : [String(idPersona)];
|
|
388
|
-
return {
|
|
389
|
-
taxIds,
|
|
390
|
-
raw: record
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
function extractPadronName(datosGenerales) {
|
|
396
|
-
if (typeof datosGenerales.razonSocial === "string") {
|
|
397
|
-
return datosGenerales.razonSocial;
|
|
398
|
-
}
|
|
399
|
-
const nombre = datosGenerales.nombre;
|
|
400
|
-
const apellido = datosGenerales.apellido;
|
|
401
|
-
if (typeof apellido === "string" && typeof nombre === "string") {
|
|
402
|
-
return `${apellido} ${nombre}`.trim();
|
|
403
|
-
}
|
|
404
|
-
if (typeof apellido === "string") {
|
|
405
|
-
return apellido;
|
|
406
|
-
}
|
|
407
|
-
if (typeof nombre === "string") {
|
|
408
|
-
return nombre;
|
|
409
|
-
}
|
|
410
|
-
return void 0;
|
|
411
|
-
}
|
|
412
|
-
async function executePadronOperation(options, service, operation, body) {
|
|
413
|
-
const auth = await options.auth.login(
|
|
414
|
-
service === "padron-a5" ? "ws_sr_constancia_inscripcion" : "ws_sr_padron_a13"
|
|
415
|
-
);
|
|
416
|
-
try {
|
|
417
|
-
const response = await options.soap.execute({
|
|
418
|
-
service,
|
|
419
|
-
operation,
|
|
420
|
-
bodyElementNamespaceMode: "prefix",
|
|
421
|
-
body: {
|
|
422
|
-
token: auth.token,
|
|
423
|
-
sign: auth.sign,
|
|
424
|
-
cuitRepresentada: Number.parseInt(options.config.taxId, 10),
|
|
425
|
-
...body
|
|
426
|
-
}
|
|
427
|
-
});
|
|
428
|
-
const operationResponse = response.result;
|
|
429
|
-
if (operation === "getPersona_v2") {
|
|
430
|
-
return operationResponse.personaReturn ?? null;
|
|
431
|
-
}
|
|
432
|
-
if (operation === "getIdPersonaListByDocumento") {
|
|
433
|
-
return operationResponse.idPersonaListReturn ?? null;
|
|
434
|
-
}
|
|
435
|
-
return operationResponse.return ?? null;
|
|
436
|
-
} catch (error) {
|
|
437
|
-
if (error instanceof ArcaSoapFaultError && // Public Padron A5/A13 WSDLs expose only a generic validation fault, so
|
|
438
|
-
// there is no documented not-found-specific fault code to match here.
|
|
439
|
-
// Keep the current message fallback, but treat it as fragile.
|
|
440
|
-
error.message.toLowerCase().includes("no existe")) {
|
|
441
|
-
return null;
|
|
442
|
-
}
|
|
443
|
-
throw error;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
// src/services/wsfe.ts
|
|
448
|
-
function createWsfeService(options) {
|
|
449
|
-
async function executeWsfeAuthenticatedRawOperation(operation, input, body = {}, retries) {
|
|
450
|
-
const auth = await options.auth.login("wsfe", {
|
|
451
|
-
representedTaxId: input.representedTaxId,
|
|
452
|
-
forceRefresh: input.forceRefresh
|
|
453
|
-
});
|
|
454
|
-
const response = await options.soap.execute({
|
|
455
|
-
service: "wsfe",
|
|
456
|
-
operation,
|
|
457
|
-
...retries === void 0 ? {} : { retries },
|
|
458
|
-
body: {
|
|
459
|
-
Auth: createWsfeAuth(
|
|
460
|
-
input.representedTaxId ?? options.config.taxId,
|
|
461
|
-
auth.token,
|
|
462
|
-
auth.sign
|
|
463
|
-
),
|
|
464
|
-
...body
|
|
465
|
-
}
|
|
466
|
-
});
|
|
467
|
-
return unwrapWsfeOperationEnvelope(operation, response.result);
|
|
468
|
-
}
|
|
469
|
-
async function executeWsfeAuthenticatedOperation(operation, input, body = {}) {
|
|
470
|
-
const result = await executeWsfeAuthenticatedRawOperation(
|
|
471
|
-
operation,
|
|
472
|
-
input,
|
|
473
|
-
body
|
|
474
|
-
);
|
|
475
|
-
throwForWsfeOperationErrors(operation, result);
|
|
476
|
-
return result;
|
|
477
|
-
}
|
|
478
|
-
async function executeWsfeOperation(operation, body = {}) {
|
|
479
|
-
const response = await options.soap.execute({
|
|
480
|
-
service: "wsfe",
|
|
481
|
-
operation,
|
|
482
|
-
body
|
|
483
|
-
});
|
|
484
|
-
const result = unwrapWsfeOperationEnvelope(operation, response.result);
|
|
485
|
-
throwForWsfeOperationErrors(operation, result);
|
|
486
|
-
return result;
|
|
487
|
-
}
|
|
488
|
-
async function getNextVoucherNumber({
|
|
489
|
-
representedTaxId,
|
|
490
|
-
salesPoint,
|
|
491
|
-
voucherType,
|
|
492
|
-
forceRefresh
|
|
493
|
-
}) {
|
|
494
|
-
const result = await executeWsfeAuthenticatedOperation(
|
|
495
|
-
"FECompUltimoAutorizado",
|
|
496
|
-
{
|
|
497
|
-
representedTaxId,
|
|
498
|
-
forceRefresh
|
|
499
|
-
},
|
|
500
|
-
{
|
|
501
|
-
PtoVta: salesPoint,
|
|
502
|
-
CbteTipo: voucherType
|
|
503
|
-
}
|
|
504
|
-
);
|
|
505
|
-
return Number(result.CbteNro ?? 0) + 1;
|
|
506
|
-
}
|
|
507
|
-
async function getWsfeCatalog(operation, resultKey, input) {
|
|
508
|
-
const result = await executeWsfeAuthenticatedOperation(operation, {
|
|
509
|
-
representedTaxId: input.representedTaxId,
|
|
510
|
-
forceRefresh: input.forceRefresh
|
|
511
|
-
});
|
|
512
|
-
return getWsfeResultEntries(result, resultKey).map(mapWsfeCatalogEntry);
|
|
513
|
-
}
|
|
514
|
-
function authorizeVoucher({
|
|
515
|
-
representedTaxId,
|
|
516
|
-
data,
|
|
517
|
-
voucherNumber,
|
|
518
|
-
forceRefresh
|
|
519
|
-
}) {
|
|
520
|
-
const normalizedInput = normalizeWsfeVoucherInput(data);
|
|
521
|
-
return authorizeNormalizedVoucher({
|
|
522
|
-
representedTaxId,
|
|
523
|
-
data: normalizedInput,
|
|
524
|
-
voucherNumber,
|
|
525
|
-
forceRefresh
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
function authorizeVoucherOutcome({
|
|
529
|
-
representedTaxId,
|
|
530
|
-
data,
|
|
531
|
-
voucherNumber,
|
|
532
|
-
forceRefresh
|
|
533
|
-
}) {
|
|
534
|
-
const normalizedInput = normalizeWsfeVoucherInput(data);
|
|
535
|
-
return executeWsfeAuthorization({
|
|
536
|
-
representedTaxId,
|
|
537
|
-
data: normalizedInput,
|
|
538
|
-
voucherNumber,
|
|
539
|
-
forceRefresh
|
|
540
|
-
}).then(({ outcome }) => outcome);
|
|
541
|
-
}
|
|
542
|
-
async function authorizeNormalizedVoucher({
|
|
543
|
-
representedTaxId,
|
|
544
|
-
data: normalizedInput,
|
|
545
|
-
voucherNumber,
|
|
546
|
-
forceRefresh
|
|
547
|
-
}) {
|
|
548
|
-
const execution = await executeWsfeAuthorization({
|
|
549
|
-
representedTaxId,
|
|
550
|
-
data: normalizedInput,
|
|
551
|
-
voucherNumber,
|
|
552
|
-
forceRefresh
|
|
553
|
-
});
|
|
554
|
-
if (execution.error) {
|
|
555
|
-
throw execution.error;
|
|
556
|
-
}
|
|
557
|
-
if (execution.outcome.kind !== "authorized") {
|
|
558
|
-
throw createWsfeOutcomeError(execution.outcome);
|
|
559
|
-
}
|
|
560
|
-
const { cae, caeExpiry, raw } = execution.outcome;
|
|
561
|
-
if (!(caeExpiry && raw)) {
|
|
562
|
-
throw new ArcaServiceError("WSFE did not return CAE authorization data", {
|
|
563
|
-
service: "wsfe",
|
|
564
|
-
operation: "FECAESolicitar",
|
|
565
|
-
result: execution.outcome.result,
|
|
566
|
-
resultLevel: execution.outcome.resultLevel,
|
|
567
|
-
results: execution.outcome.results,
|
|
568
|
-
cae,
|
|
569
|
-
issues: [
|
|
570
|
-
...execution.outcome.errors,
|
|
571
|
-
...execution.outcome.observations
|
|
572
|
-
],
|
|
573
|
-
detail: raw
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
return {
|
|
577
|
-
cae,
|
|
578
|
-
caeExpiry,
|
|
579
|
-
voucherNumber,
|
|
580
|
-
raw
|
|
581
|
-
};
|
|
582
|
-
}
|
|
583
|
-
async function executeWsfeAuthorization({
|
|
584
|
-
representedTaxId,
|
|
585
|
-
data: normalizedInput,
|
|
586
|
-
voucherNumber,
|
|
587
|
-
forceRefresh
|
|
588
|
-
}) {
|
|
589
|
-
const requestData = mapWsfeVoucherInput(normalizedInput, voucherNumber);
|
|
590
|
-
try {
|
|
591
|
-
const result = await executeWsfeAuthenticatedRawOperation(
|
|
592
|
-
"FECAESolicitar",
|
|
593
|
-
{ representedTaxId, forceRefresh },
|
|
594
|
-
{
|
|
595
|
-
FeCAEReq: {
|
|
596
|
-
FeCabReq: {
|
|
597
|
-
CantReg: 1,
|
|
598
|
-
PtoVta: normalizedInput.salesPoint,
|
|
599
|
-
CbteTipo: normalizedInput.voucherType
|
|
600
|
-
},
|
|
601
|
-
FeDetReq: {
|
|
602
|
-
FECAEDetRequest: requestData
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
},
|
|
606
|
-
0
|
|
607
|
-
);
|
|
608
|
-
return {
|
|
609
|
-
outcome: classifyWsfeAuthorization(result, voucherNumber)
|
|
610
|
-
};
|
|
611
|
-
} catch (error) {
|
|
612
|
-
return {
|
|
613
|
-
outcome: createWsfeIndeterminateOutcome(error),
|
|
614
|
-
error
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
async function lookupVoucher({
|
|
619
|
-
representedTaxId,
|
|
620
|
-
number,
|
|
621
|
-
salesPoint,
|
|
622
|
-
voucherType,
|
|
623
|
-
forceRefresh
|
|
624
|
-
}) {
|
|
625
|
-
const operation = "FECompConsultar";
|
|
626
|
-
const result = await executeWsfeAuthenticatedRawOperation(
|
|
627
|
-
operation,
|
|
628
|
-
{ representedTaxId, forceRefresh },
|
|
629
|
-
{
|
|
630
|
-
FeCompConsReq: {
|
|
631
|
-
CbteNro: number,
|
|
632
|
-
PtoVta: salesPoint,
|
|
633
|
-
CbteTipo: voucherType
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
);
|
|
637
|
-
const errors = extractWsfeGlobalIssues(result, operation);
|
|
638
|
-
if (errors.length > 0 && errors.every((issue) => issue.code === "602")) {
|
|
639
|
-
return {
|
|
640
|
-
kind: "not_found",
|
|
641
|
-
service: "wsfe",
|
|
642
|
-
operation,
|
|
643
|
-
errors,
|
|
644
|
-
observations: [],
|
|
645
|
-
raw: result
|
|
646
|
-
};
|
|
647
|
-
}
|
|
648
|
-
if (errors.length > 0) {
|
|
649
|
-
throw createWsfeServiceError(operation, result, errors);
|
|
650
|
-
}
|
|
651
|
-
const raw = toWsfeRecord(result.ResultGet);
|
|
652
|
-
if (!raw) {
|
|
653
|
-
throw new ArcaServiceError("WSFE did not return the consulted voucher", {
|
|
654
|
-
service: "wsfe",
|
|
655
|
-
operation,
|
|
656
|
-
detail: result
|
|
657
|
-
});
|
|
658
|
-
}
|
|
659
|
-
return {
|
|
660
|
-
kind: "found",
|
|
661
|
-
service: "wsfe",
|
|
662
|
-
operation,
|
|
663
|
-
voucher: mapWsfeVoucherInfo(raw),
|
|
664
|
-
observations: [],
|
|
665
|
-
raw: result
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
return {
|
|
669
|
-
authorizeVoucherOutcome,
|
|
670
|
-
authorizeVoucher,
|
|
671
|
-
async createNextVoucher({ representedTaxId, data, forceRefresh }) {
|
|
672
|
-
const normalizedInput = normalizeWsfeVoucherInput(data);
|
|
673
|
-
const voucherNumber = await getNextVoucherNumber({
|
|
674
|
-
representedTaxId,
|
|
675
|
-
salesPoint: normalizedInput.salesPoint,
|
|
676
|
-
voucherType: normalizedInput.voucherType,
|
|
677
|
-
forceRefresh
|
|
678
|
-
});
|
|
679
|
-
return authorizeNormalizedVoucher({
|
|
680
|
-
representedTaxId,
|
|
681
|
-
data: normalizedInput,
|
|
682
|
-
voucherNumber
|
|
683
|
-
});
|
|
684
|
-
},
|
|
685
|
-
getNextVoucherNumber,
|
|
686
|
-
getLastVoucher(input) {
|
|
687
|
-
return getNextVoucherNumber(input);
|
|
688
|
-
},
|
|
689
|
-
async getSalesPoints({ representedTaxId, forceRefresh }) {
|
|
690
|
-
const result = await executeWsfeAuthenticatedOperation(
|
|
691
|
-
"FEParamGetPtosVenta",
|
|
692
|
-
{
|
|
693
|
-
representedTaxId,
|
|
694
|
-
forceRefresh
|
|
695
|
-
}
|
|
696
|
-
);
|
|
697
|
-
const rawPoints = result.ResultGet?.PtoVenta;
|
|
698
|
-
if (!rawPoints) {
|
|
699
|
-
return [];
|
|
700
|
-
}
|
|
701
|
-
const entries = Array.isArray(rawPoints) ? rawPoints : [rawPoints];
|
|
702
|
-
return entries.map(mapWsfeSalesPoint);
|
|
703
|
-
},
|
|
704
|
-
getVoucherTypes(input) {
|
|
705
|
-
return getWsfeCatalog("FEParamGetTiposCbte", "CbteTipo", input);
|
|
706
|
-
},
|
|
707
|
-
getDocumentTypes(input) {
|
|
708
|
-
return getWsfeCatalog("FEParamGetTiposDoc", "DocTipo", input);
|
|
709
|
-
},
|
|
710
|
-
getConceptTypes(input) {
|
|
711
|
-
return getWsfeCatalog("FEParamGetTiposConcepto", "ConceptoTipo", input);
|
|
712
|
-
},
|
|
713
|
-
async getCurrencyTypes({ representedTaxId, forceRefresh }) {
|
|
714
|
-
const result = await executeWsfeAuthenticatedOperation(
|
|
715
|
-
"FEParamGetTiposMonedas",
|
|
716
|
-
{
|
|
717
|
-
representedTaxId,
|
|
718
|
-
forceRefresh
|
|
719
|
-
}
|
|
720
|
-
);
|
|
721
|
-
return getWsfeResultEntries(result, "Moneda").map(mapWsfeCurrencyType);
|
|
722
|
-
},
|
|
723
|
-
getVatRates(input) {
|
|
724
|
-
return getWsfeCatalog("FEParamGetTiposIva", "IvaTipo", input);
|
|
725
|
-
},
|
|
726
|
-
getTaxTypes(input) {
|
|
727
|
-
return getWsfeCatalog("FEParamGetTiposTributos", "TributoTipo", input);
|
|
728
|
-
},
|
|
729
|
-
getOptionalTypes(input) {
|
|
730
|
-
return getWsfeCatalog("FEParamGetTiposOpcional", "OpcionalTipo", input);
|
|
731
|
-
},
|
|
732
|
-
async getActivities({ representedTaxId, forceRefresh }) {
|
|
733
|
-
const result = await executeWsfeAuthenticatedOperation(
|
|
734
|
-
"FEParamGetActividades",
|
|
735
|
-
{
|
|
736
|
-
representedTaxId,
|
|
737
|
-
forceRefresh
|
|
738
|
-
}
|
|
739
|
-
);
|
|
740
|
-
return getWsfeResultEntries(result, "ActividadesTipo").map(
|
|
741
|
-
mapWsfeActivityType
|
|
742
|
-
);
|
|
743
|
-
},
|
|
744
|
-
async getReceiverVatConditions({
|
|
745
|
-
representedTaxId,
|
|
746
|
-
voucherClass,
|
|
747
|
-
forceRefresh
|
|
748
|
-
}) {
|
|
749
|
-
const result = await executeWsfeAuthenticatedOperation(
|
|
750
|
-
"FEParamGetCondicionIvaReceptor",
|
|
751
|
-
{
|
|
752
|
-
representedTaxId,
|
|
753
|
-
forceRefresh
|
|
754
|
-
},
|
|
755
|
-
{
|
|
756
|
-
...voucherClass === void 0 ? {} : { ClaseCmp: voucherClass }
|
|
757
|
-
}
|
|
758
|
-
);
|
|
759
|
-
return getWsfeResultEntries(result, "CondicionIvaReceptor").map(
|
|
760
|
-
mapWsfeReceiverVatCondition
|
|
761
|
-
);
|
|
762
|
-
},
|
|
763
|
-
async getServerStatus() {
|
|
764
|
-
const result = await executeWsfeOperation("FEDummy");
|
|
765
|
-
return mapWsfeServerStatus(result);
|
|
766
|
-
},
|
|
767
|
-
async getQuotation({ currencyId, representedTaxId, forceRefresh }) {
|
|
768
|
-
const result = await executeWsfeAuthenticatedOperation(
|
|
769
|
-
"FEParamGetCotizacion",
|
|
770
|
-
{
|
|
771
|
-
representedTaxId,
|
|
772
|
-
forceRefresh
|
|
773
|
-
},
|
|
774
|
-
{
|
|
775
|
-
MonId: currencyId
|
|
776
|
-
}
|
|
777
|
-
);
|
|
778
|
-
const raw = result.ResultGet ?? {};
|
|
779
|
-
return mapWsfeQuotation(raw);
|
|
780
|
-
},
|
|
781
|
-
async getVoucherInfo(input) {
|
|
782
|
-
const lookup = await lookupVoucher(input);
|
|
783
|
-
return lookup.kind === "found" ? lookup.voucher : null;
|
|
784
|
-
},
|
|
785
|
-
lookupVoucher
|
|
786
|
-
};
|
|
787
|
-
}
|
|
788
|
-
function mapWsfeVoucherInput(input, voucherNumber) {
|
|
789
|
-
const sendsSameForeignCurrencyCancellation = input.currencyId !== "PES" && input.sameCurrencyForeignCancellation === "S";
|
|
790
|
-
if (input.exchangeRate === void 0 && !sendsSameForeignCurrencyCancellation) {
|
|
791
|
-
throw new ArcaInputError(
|
|
792
|
-
"exchangeRate is required unless sameCurrencyForeignCancellation is S for a foreign-currency voucher."
|
|
793
|
-
);
|
|
794
|
-
}
|
|
795
|
-
const data = {
|
|
796
|
-
Concepto: input.concept,
|
|
797
|
-
DocTipo: input.documentType,
|
|
798
|
-
DocNro: input.documentNumber,
|
|
799
|
-
CbteDesde: voucherNumber,
|
|
800
|
-
CbteHasta: voucherNumber,
|
|
801
|
-
CbteFch: input.voucherDate,
|
|
802
|
-
ImpTotal: input.totalAmount,
|
|
803
|
-
ImpTotConc: input.nonTaxableAmount,
|
|
804
|
-
ImpNeto: input.netAmount,
|
|
805
|
-
ImpOpEx: input.exemptAmount,
|
|
806
|
-
ImpTrib: input.taxAmount,
|
|
807
|
-
ImpIVA: input.vatAmount,
|
|
808
|
-
MonId: input.currencyId,
|
|
809
|
-
PtoVta: input.salesPoint,
|
|
810
|
-
CbteTipo: input.voucherType
|
|
811
|
-
};
|
|
812
|
-
if (!sendsSameForeignCurrencyCancellation) {
|
|
813
|
-
data.MonCotiz = input.exchangeRate;
|
|
814
|
-
}
|
|
815
|
-
if (input.receiverVatConditionId !== void 0) {
|
|
816
|
-
data.CondicionIVAReceptorId = input.receiverVatConditionId;
|
|
817
|
-
}
|
|
818
|
-
if (input.currencyId !== "PES" && input.sameCurrencyForeignCancellation !== void 0) {
|
|
819
|
-
data.CanMisMonExt = input.sameCurrencyForeignCancellation;
|
|
820
|
-
}
|
|
821
|
-
if (input.serviceStartDate !== void 0) {
|
|
822
|
-
data.FchServDesde = input.serviceStartDate;
|
|
823
|
-
}
|
|
824
|
-
if (input.serviceEndDate !== void 0) {
|
|
825
|
-
data.FchServHasta = input.serviceEndDate;
|
|
826
|
-
}
|
|
827
|
-
if (input.paymentDueDate !== void 0) {
|
|
828
|
-
data.FchVtoPago = input.paymentDueDate;
|
|
829
|
-
}
|
|
830
|
-
if (input.associatedVouchers) {
|
|
831
|
-
data.CbtesAsoc = {
|
|
832
|
-
CbteAsoc: input.associatedVouchers.map((v) => ({
|
|
833
|
-
Tipo: v.type,
|
|
834
|
-
PtoVta: v.salesPoint,
|
|
835
|
-
Nro: v.number,
|
|
836
|
-
...v.taxId === void 0 ? {} : { Cuit: v.taxId },
|
|
837
|
-
...v.voucherDate === void 0 ? {} : { CbteFch: v.voucherDate }
|
|
838
|
-
}))
|
|
839
|
-
};
|
|
840
|
-
}
|
|
841
|
-
if (input.associatedPeriod) {
|
|
842
|
-
data.PeriodoAsoc = {
|
|
843
|
-
FchDesde: input.associatedPeriod.startDate,
|
|
844
|
-
FchHasta: input.associatedPeriod.endDate
|
|
845
|
-
};
|
|
846
|
-
}
|
|
847
|
-
if (input.taxes) {
|
|
848
|
-
data.Tributos = {
|
|
849
|
-
Tributo: input.taxes.map((t) => ({
|
|
850
|
-
Id: t.id,
|
|
851
|
-
...t.description === void 0 ? {} : { Desc: t.description },
|
|
852
|
-
BaseImp: t.baseAmount,
|
|
853
|
-
Alic: t.rate,
|
|
854
|
-
Importe: t.amount
|
|
855
|
-
}))
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
if (input.vatRates) {
|
|
859
|
-
data.Iva = {
|
|
860
|
-
AlicIva: input.vatRates.map((v) => ({
|
|
861
|
-
Id: v.id,
|
|
862
|
-
BaseImp: v.baseAmount,
|
|
863
|
-
Importe: v.amount
|
|
864
|
-
}))
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
if (input.optionalFields) {
|
|
868
|
-
data.Opcionales = {
|
|
869
|
-
Opcional: input.optionalFields.map((o) => ({
|
|
870
|
-
Id: o.id,
|
|
871
|
-
Valor: o.value
|
|
872
|
-
}))
|
|
873
|
-
};
|
|
874
|
-
}
|
|
875
|
-
if (input.buyers) {
|
|
876
|
-
data.Compradores = {
|
|
877
|
-
Comprador: input.buyers.map((b) => ({
|
|
878
|
-
DocTipo: b.documentType,
|
|
879
|
-
DocNro: b.documentNumber,
|
|
880
|
-
Porcentaje: b.percentage
|
|
881
|
-
}))
|
|
882
|
-
};
|
|
883
|
-
}
|
|
884
|
-
if (input.activities) {
|
|
885
|
-
data.Actividades = {
|
|
886
|
-
Actividad: input.activities.map((a) => ({
|
|
887
|
-
Id: a.id
|
|
888
|
-
}))
|
|
889
|
-
};
|
|
890
|
-
}
|
|
891
|
-
return data;
|
|
892
|
-
}
|
|
893
|
-
function normalizeWsfeVoucherInput(input) {
|
|
894
|
-
const {
|
|
895
|
-
voucherDate,
|
|
896
|
-
serviceStartDate,
|
|
897
|
-
serviceEndDate,
|
|
898
|
-
paymentDueDate,
|
|
899
|
-
associatedVouchers,
|
|
900
|
-
associatedPeriod,
|
|
901
|
-
...rest
|
|
902
|
-
} = input;
|
|
903
|
-
return {
|
|
904
|
-
...rest,
|
|
905
|
-
voucherDate: normalizeWsfeDateInput(voucherDate, "voucherDate"),
|
|
906
|
-
...serviceStartDate === void 0 ? {} : {
|
|
907
|
-
serviceStartDate: normalizeWsfeDateInput(
|
|
908
|
-
serviceStartDate,
|
|
909
|
-
"serviceStartDate"
|
|
910
|
-
)
|
|
911
|
-
},
|
|
912
|
-
...serviceEndDate === void 0 ? {} : {
|
|
913
|
-
serviceEndDate: normalizeWsfeDateInput(
|
|
914
|
-
serviceEndDate,
|
|
915
|
-
"serviceEndDate"
|
|
916
|
-
)
|
|
917
|
-
},
|
|
918
|
-
...paymentDueDate === void 0 ? {} : {
|
|
919
|
-
paymentDueDate: normalizeWsfeDateInput(
|
|
920
|
-
paymentDueDate,
|
|
921
|
-
"paymentDueDate"
|
|
922
|
-
)
|
|
923
|
-
},
|
|
924
|
-
...associatedVouchers === void 0 ? {} : {
|
|
925
|
-
associatedVouchers: associatedVouchers.map((voucher, index) => {
|
|
926
|
-
const { voucherDate: associatedVoucherDate, ...associatedRest } = voucher;
|
|
927
|
-
return {
|
|
928
|
-
...associatedRest,
|
|
929
|
-
...associatedVoucherDate === void 0 ? {} : {
|
|
930
|
-
voucherDate: normalizeWsfeDateInput(
|
|
931
|
-
associatedVoucherDate,
|
|
932
|
-
`associatedVouchers[${index}].voucherDate`
|
|
933
|
-
)
|
|
934
|
-
}
|
|
935
|
-
};
|
|
936
|
-
})
|
|
937
|
-
},
|
|
938
|
-
...associatedPeriod === void 0 ? {} : {
|
|
939
|
-
associatedPeriod: {
|
|
940
|
-
startDate: normalizeWsfeDateInput(
|
|
941
|
-
associatedPeriod.startDate,
|
|
942
|
-
"associatedPeriod.startDate"
|
|
943
|
-
),
|
|
944
|
-
endDate: normalizeWsfeDateInput(
|
|
945
|
-
associatedPeriod.endDate,
|
|
946
|
-
"associatedPeriod.endDate"
|
|
947
|
-
)
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
};
|
|
951
|
-
}
|
|
952
|
-
function normalizeWsfeDateInput(value, fieldName) {
|
|
953
|
-
if (typeof value !== "string") {
|
|
954
|
-
throw new ArcaInputError(
|
|
955
|
-
`Invalid WSFE ${fieldName}: expected a YYYY-MM-DD or YYYYMMDD string`,
|
|
956
|
-
{
|
|
957
|
-
detail: { field: fieldName, value }
|
|
958
|
-
}
|
|
959
|
-
);
|
|
960
|
-
}
|
|
961
|
-
const normalizedValue = value.trim();
|
|
962
|
-
const afipMatch = normalizedValue.match(/^(\d{4})(\d{2})(\d{2})$/);
|
|
963
|
-
if (afipMatch) {
|
|
964
|
-
const [, year, month, day] = afipMatch;
|
|
965
|
-
assertValidCalendarDate(year, month, day, fieldName, normalizedValue);
|
|
966
|
-
return normalizedValue;
|
|
967
|
-
}
|
|
968
|
-
const isoMatch = normalizedValue.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
969
|
-
if (isoMatch) {
|
|
970
|
-
const [, year, month, day] = isoMatch;
|
|
971
|
-
assertValidCalendarDate(year, month, day, fieldName, normalizedValue);
|
|
972
|
-
return `${year}${month}${day}`;
|
|
973
|
-
}
|
|
974
|
-
throw new ArcaInputError(
|
|
975
|
-
`Invalid WSFE ${fieldName}: expected a YYYY-MM-DD or YYYYMMDD string`,
|
|
976
|
-
{
|
|
977
|
-
detail: { field: fieldName, value: normalizedValue }
|
|
978
|
-
}
|
|
979
|
-
);
|
|
980
|
-
}
|
|
981
|
-
function assertValidCalendarDate(yearInput, monthInput, dayInput, fieldName, value) {
|
|
982
|
-
const year = Number(yearInput);
|
|
983
|
-
const month = Number(monthInput);
|
|
984
|
-
const day = Number(dayInput);
|
|
985
|
-
const candidate = new Date(Date.UTC(year, month - 1, day));
|
|
986
|
-
if (candidate.getUTCFullYear() !== year || candidate.getUTCMonth() !== month - 1 || candidate.getUTCDate() !== day) {
|
|
987
|
-
throw new ArcaInputError(
|
|
988
|
-
`Invalid WSFE ${fieldName}: received a non-existent calendar date`,
|
|
989
|
-
{
|
|
990
|
-
detail: { field: fieldName, value }
|
|
991
|
-
}
|
|
992
|
-
);
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
function mapWsfeSalesPoint(raw) {
|
|
996
|
-
const record = raw;
|
|
997
|
-
return {
|
|
998
|
-
number: Number(record.Nro ?? 0),
|
|
999
|
-
...record.EmisionTipo === void 0 ? {} : { emissionType: String(record.EmisionTipo) },
|
|
1000
|
-
...record.Bloqueado === void 0 ? {} : { blocked: String(record.Bloqueado) },
|
|
1001
|
-
...record.FchBaja === void 0 ? {} : { deletedSince: String(record.FchBaja) }
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
function mapWsfeCatalogEntry(raw) {
|
|
1005
|
-
const record = raw;
|
|
1006
|
-
return {
|
|
1007
|
-
id: Number(record.Id ?? 0),
|
|
1008
|
-
description: String(record.Desc ?? "")
|
|
1009
|
-
};
|
|
1010
|
-
}
|
|
1011
|
-
function mapWsfeActivityType(raw) {
|
|
1012
|
-
const record = raw;
|
|
1013
|
-
return {
|
|
1014
|
-
id: Number(record.Id ?? 0),
|
|
1015
|
-
description: String(record.Desc ?? ""),
|
|
1016
|
-
order: Number(record.Orden ?? 0)
|
|
1017
|
-
};
|
|
1018
|
-
}
|
|
1019
|
-
function mapWsfeReceiverVatCondition(raw) {
|
|
1020
|
-
const record = raw;
|
|
1021
|
-
return {
|
|
1022
|
-
id: Number(record.Id ?? 0),
|
|
1023
|
-
description: String(record.Desc ?? ""),
|
|
1024
|
-
voucherClass: String(record.Cmp_Clase ?? "")
|
|
1025
|
-
};
|
|
1026
|
-
}
|
|
1027
|
-
function mapWsfeCurrencyType(raw) {
|
|
1028
|
-
const record = raw;
|
|
1029
|
-
return {
|
|
1030
|
-
id: String(record.Id ?? ""),
|
|
1031
|
-
description: String(record.Desc ?? ""),
|
|
1032
|
-
validFrom: String(record.FchDesde ?? ""),
|
|
1033
|
-
validTo: String(record.FchHasta ?? "")
|
|
1034
|
-
};
|
|
1035
|
-
}
|
|
1036
|
-
function mapWsfeServerStatus(raw) {
|
|
1037
|
-
return {
|
|
1038
|
-
appServer: String(raw.AppServer ?? ""),
|
|
1039
|
-
dbServer: String(raw.DbServer ?? ""),
|
|
1040
|
-
authServer: String(raw.AuthServer ?? "")
|
|
1041
|
-
};
|
|
1042
|
-
}
|
|
1043
|
-
function mapWsfeQuotation(raw) {
|
|
1044
|
-
return {
|
|
1045
|
-
currencyId: String(raw.MonId ?? ""),
|
|
1046
|
-
rate: Number(raw.MonCotiz ?? 0),
|
|
1047
|
-
date: String(raw.FchCotiz ?? "")
|
|
1048
|
-
};
|
|
1049
|
-
}
|
|
1050
|
-
function mapWsfeVoucherInfo(raw) {
|
|
1051
|
-
const voucher = {
|
|
1052
|
-
voucherNumber: Number(raw.CbteDesde ?? raw.CbteHasta ?? 0),
|
|
1053
|
-
raw
|
|
1054
|
-
};
|
|
1055
|
-
assignWsfeValue(voucher, "voucherDate", normalizeWsfeString(raw.CbteFch));
|
|
1056
|
-
assignWsfeValue(voucher, "salesPoint", normalizeWsfeNumber(raw.PtoVta));
|
|
1057
|
-
assignWsfeValue(voucher, "voucherType", normalizeWsfeNumber(raw.CbteTipo));
|
|
1058
|
-
assignWsfeValue(voucher, "concept", normalizeWsfeNumber(raw.Concepto));
|
|
1059
|
-
assignWsfeValue(voucher, "documentType", normalizeWsfeNumber(raw.DocTipo));
|
|
1060
|
-
assignWsfeValue(voucher, "documentNumber", normalizeWsfeString(raw.DocNro));
|
|
1061
|
-
assignWsfeValue(
|
|
1062
|
-
voucher,
|
|
1063
|
-
"receiverVatConditionId",
|
|
1064
|
-
normalizeWsfeNumber(raw.CondicionIVAReceptorId)
|
|
1065
|
-
);
|
|
1066
|
-
assignWsfeValue(voucher, "totalAmount", normalizeWsfeNumber(raw.ImpTotal));
|
|
1067
|
-
assignWsfeValue(
|
|
1068
|
-
voucher,
|
|
1069
|
-
"nonTaxableAmount",
|
|
1070
|
-
normalizeWsfeNumber(raw.ImpTotConc)
|
|
1071
|
-
);
|
|
1072
|
-
assignWsfeValue(voucher, "netAmount", normalizeWsfeNumber(raw.ImpNeto));
|
|
1073
|
-
assignWsfeValue(voucher, "exemptAmount", normalizeWsfeNumber(raw.ImpOpEx));
|
|
1074
|
-
assignWsfeValue(voucher, "taxAmount", normalizeWsfeNumber(raw.ImpTrib));
|
|
1075
|
-
assignWsfeValue(voucher, "vatAmount", normalizeWsfeNumber(raw.ImpIVA));
|
|
1076
|
-
assignWsfeValue(voucher, "currencyId", normalizeWsfeString(raw.MonId));
|
|
1077
|
-
assignWsfeValue(voucher, "exchangeRate", normalizeWsfeNumber(raw.MonCotiz));
|
|
1078
|
-
assignWsfeValue(voucher, "result", normalizeWsfeString(raw.Resultado));
|
|
1079
|
-
assignWsfeValue(
|
|
1080
|
-
voucher,
|
|
1081
|
-
"cae",
|
|
1082
|
-
normalizeWsfeString(raw.CodAutorizacion ?? raw.CAE)
|
|
1083
|
-
);
|
|
1084
|
-
assignWsfeValue(
|
|
1085
|
-
voucher,
|
|
1086
|
-
"caeExpiry",
|
|
1087
|
-
normalizeWsfeString(raw.FchVto ?? raw.CAEFchVto)
|
|
1088
|
-
);
|
|
1089
|
-
return voucher;
|
|
1090
|
-
}
|
|
1091
|
-
function createWsfeAuth(representedTaxId, token, sign) {
|
|
1092
|
-
return {
|
|
1093
|
-
Token: token,
|
|
1094
|
-
Sign: sign,
|
|
1095
|
-
Cuit: Number.parseInt(String(representedTaxId), 10)
|
|
1096
|
-
};
|
|
1097
|
-
}
|
|
1098
|
-
function unwrapWsfeOperationEnvelope(operation, response) {
|
|
1099
|
-
const operationResponse = response[`${operation}Response`];
|
|
1100
|
-
const result = operationResponse?.[`${operation}Result`] ?? response[`${operation}Result`] ?? response;
|
|
1101
|
-
return result;
|
|
1102
|
-
}
|
|
1103
|
-
function throwForWsfeOperationErrors(operation, result) {
|
|
1104
|
-
const errors = extractWsfeGlobalIssues(result, operation);
|
|
1105
|
-
if (errors.length > 0) {
|
|
1106
|
-
throw createWsfeServiceError(operation, result, errors);
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
function normalizeWsfeDetailResponse(result) {
|
|
1110
|
-
const detailResponse = result.FeDetResp;
|
|
1111
|
-
const rawDetail = detailResponse?.FECAEDetResponse;
|
|
1112
|
-
if (Array.isArray(rawDetail)) {
|
|
1113
|
-
return rawDetail[0] ?? {};
|
|
1114
|
-
}
|
|
1115
|
-
return rawDetail ?? {};
|
|
1116
|
-
}
|
|
1117
|
-
function classifyWsfeAuthorization(result, voucherNumber) {
|
|
1118
|
-
const operation = "FECAESolicitar";
|
|
1119
|
-
const header = toWsfeRecord(result.FeCabResp) ?? {};
|
|
1120
|
-
const detail = normalizeWsfeDetailResponse(result);
|
|
1121
|
-
const headerResult = normalizeWsfeResult(header.Resultado);
|
|
1122
|
-
const detailResult = normalizeWsfeResult(detail.Resultado);
|
|
1123
|
-
const resultCode = detailResult ?? headerResult;
|
|
1124
|
-
const resultLevel = getWsfeResultLevel(headerResult, detailResult);
|
|
1125
|
-
const cae = normalizeWsfeString(detail.CAE);
|
|
1126
|
-
const caeExpiry = normalizeWsfeString(detail.CAEFchVto);
|
|
1127
|
-
const errors = extractWsfeGlobalIssues(result, operation, "header");
|
|
1128
|
-
const observations = extractWsfeObservations(
|
|
1129
|
-
detail,
|
|
1130
|
-
detailResult === "R" ? "business" : "observation"
|
|
1131
|
-
);
|
|
1132
|
-
const hasInfrastructureError = errors.some(
|
|
1133
|
-
(issue) => issue.category === "infrastructure"
|
|
1134
|
-
);
|
|
1135
|
-
const base = {
|
|
1136
|
-
service: "wsfe",
|
|
1137
|
-
operation,
|
|
1138
|
-
results: createWsfeResults(headerResult, detailResult),
|
|
1139
|
-
errors,
|
|
1140
|
-
observations,
|
|
1141
|
-
raw: result
|
|
1142
|
-
};
|
|
1143
|
-
const context = {
|
|
1144
|
-
base,
|
|
1145
|
-
headerResult,
|
|
1146
|
-
detailResult,
|
|
1147
|
-
resultCode,
|
|
1148
|
-
resultLevel,
|
|
1149
|
-
cae,
|
|
1150
|
-
caeExpiry
|
|
1151
|
-
};
|
|
1152
|
-
if (hasContradictoryWsfeResults(context)) {
|
|
1153
|
-
return createWsfeStructuredIndeterminate(context, "contradictory_response");
|
|
1154
|
-
}
|
|
1155
|
-
if (hasInfrastructureError) {
|
|
1156
|
-
return createWsfeStructuredIndeterminate(context, "incomplete_response");
|
|
1157
|
-
}
|
|
1158
|
-
if (isAuthorizedWsfeContext(context)) {
|
|
1159
|
-
return {
|
|
1160
|
-
...base,
|
|
1161
|
-
kind: "authorized",
|
|
1162
|
-
result: "A",
|
|
1163
|
-
resultLevel: "detail",
|
|
1164
|
-
cae: context.cae,
|
|
1165
|
-
caeExpiry: context.caeExpiry,
|
|
1166
|
-
voucherNumber
|
|
1167
|
-
};
|
|
1168
|
-
}
|
|
1169
|
-
if (isRejectedWsfeDetailContext(context)) {
|
|
1170
|
-
return {
|
|
1171
|
-
...base,
|
|
1172
|
-
kind: "rejected",
|
|
1173
|
-
result: "R",
|
|
1174
|
-
resultLevel: "detail"
|
|
1175
|
-
};
|
|
1176
|
-
}
|
|
1177
|
-
if (isRejectedWsfeHeaderContext(context)) {
|
|
1178
|
-
return {
|
|
1179
|
-
...base,
|
|
1180
|
-
kind: "rejected",
|
|
1181
|
-
result: "R",
|
|
1182
|
-
resultLevel: "header"
|
|
1183
|
-
};
|
|
1184
|
-
}
|
|
1185
|
-
return createWsfeStructuredIndeterminate(
|
|
1186
|
-
context,
|
|
1187
|
-
hasWsfeCaeContradiction(context) ? "contradictory_response" : "incomplete_response"
|
|
1188
|
-
);
|
|
1189
|
-
}
|
|
1190
|
-
function getWsfeResultLevel(headerResult, detailResult) {
|
|
1191
|
-
if (detailResult) {
|
|
1192
|
-
return "detail";
|
|
1193
|
-
}
|
|
1194
|
-
return headerResult ? "header" : void 0;
|
|
1195
|
-
}
|
|
1196
|
-
function hasContradictoryWsfeResults(context) {
|
|
1197
|
-
return Boolean(
|
|
1198
|
-
context.headerResult && context.detailResult && context.headerResult !== context.detailResult
|
|
1199
|
-
);
|
|
1200
|
-
}
|
|
1201
|
-
function isAuthorizedWsfeContext(context) {
|
|
1202
|
-
return Boolean(
|
|
1203
|
-
context.detailResult === "A" && context.headerResult !== "R" && context.base.errors.length === 0 && context.cae && context.caeExpiry
|
|
1204
|
-
);
|
|
1205
|
-
}
|
|
1206
|
-
function isRejectedWsfeDetailContext(context) {
|
|
1207
|
-
return context.detailResult === "R" && context.headerResult !== "A" && !context.cae;
|
|
1208
|
-
}
|
|
1209
|
-
function isRejectedWsfeHeaderContext(context) {
|
|
1210
|
-
return context.headerResult === "R" && context.detailResult === void 0 && !context.cae && context.base.errors.length > 0 && context.base.errors.every((issue) => issue.category === "business");
|
|
1211
|
-
}
|
|
1212
|
-
function hasWsfeCaeContradiction(context) {
|
|
1213
|
-
return (context.resultCode === "A" || context.resultCode === "R") && Boolean(context.cae);
|
|
1214
|
-
}
|
|
1215
|
-
function createWsfeStructuredIndeterminate(context, reason) {
|
|
1216
|
-
const outcome = {
|
|
1217
|
-
...context.base,
|
|
1218
|
-
kind: "indeterminate",
|
|
1219
|
-
reason
|
|
1220
|
-
};
|
|
1221
|
-
assignWsfeValue(outcome, "result", context.resultCode);
|
|
1222
|
-
assignWsfeValue(outcome, "resultLevel", context.resultLevel);
|
|
1223
|
-
assignWsfeValue(outcome, "cae", context.cae);
|
|
1224
|
-
assignWsfeValue(outcome, "caeExpiry", context.caeExpiry);
|
|
1225
|
-
return outcome;
|
|
1226
|
-
}
|
|
1227
|
-
function createWsfeResults(headerResult, detailResult) {
|
|
1228
|
-
const results = {};
|
|
1229
|
-
assignWsfeValue(results, "header", headerResult);
|
|
1230
|
-
assignWsfeValue(results, "detail", detailResult);
|
|
1231
|
-
return results;
|
|
1232
|
-
}
|
|
1233
|
-
function createWsfeIndeterminateOutcome(error) {
|
|
1234
|
-
return {
|
|
1235
|
-
kind: "indeterminate",
|
|
1236
|
-
service: "wsfe",
|
|
1237
|
-
operation: "FECAESolicitar",
|
|
1238
|
-
results: {},
|
|
1239
|
-
reason: getArcaIndeterminateReason(error),
|
|
1240
|
-
errors: [],
|
|
1241
|
-
observations: []
|
|
1242
|
-
};
|
|
1243
|
-
}
|
|
1244
|
-
function getArcaIndeterminateReason(error) {
|
|
1245
|
-
if (error instanceof ArcaTransportError) {
|
|
1246
|
-
return "transport_error";
|
|
1247
|
-
}
|
|
1248
|
-
if (error instanceof ArcaSoapFaultError) {
|
|
1249
|
-
return "soap_fault";
|
|
1250
|
-
}
|
|
1251
|
-
if (error instanceof ArcaInvalidSoapResponseError) {
|
|
1252
|
-
return "invalid_response";
|
|
1253
|
-
}
|
|
1254
|
-
return "unexpected_error";
|
|
1255
|
-
}
|
|
1256
|
-
function createWsfeOutcomeError(outcome) {
|
|
1257
|
-
const issues = [...outcome.errors, ...outcome.observations];
|
|
1258
|
-
const firstIssue = issues[0];
|
|
1259
|
-
const message = firstIssue ? formatWsfeIssue(firstIssue) : outcome.kind === "rejected" ? "WSFE rejected the voucher authorization" : outcome.result === "A" ? "WSFE did not return CAE authorization data" : "WSFE did not return conclusive voucher authorization data";
|
|
1260
|
-
return new ArcaServiceError(message, {
|
|
1261
|
-
service: "wsfe",
|
|
1262
|
-
operation: outcome.operation,
|
|
1263
|
-
...firstIssue?.code === void 0 ? {} : { serviceCode: firstIssue.code },
|
|
1264
|
-
...outcome.result === void 0 ? {} : { result: outcome.result },
|
|
1265
|
-
...outcome.resultLevel === void 0 ? {} : { resultLevel: outcome.resultLevel },
|
|
1266
|
-
results: outcome.results,
|
|
1267
|
-
...outcome.kind === "indeterminate" && outcome.cae ? { cae: outcome.cae } : {},
|
|
1268
|
-
issues,
|
|
1269
|
-
detail: outcome.raw
|
|
1270
|
-
});
|
|
1271
|
-
}
|
|
1272
|
-
function createWsfeServiceError(operation, result, issues) {
|
|
1273
|
-
const firstIssue = issues[0];
|
|
1274
|
-
return new ArcaServiceError(
|
|
1275
|
-
firstIssue ? formatWsfeIssue(firstIssue) : "WSFE returned a service error",
|
|
1276
|
-
{
|
|
1277
|
-
service: "wsfe",
|
|
1278
|
-
operation,
|
|
1279
|
-
...firstIssue?.code === void 0 ? {} : { serviceCode: firstIssue.code },
|
|
1280
|
-
issues,
|
|
1281
|
-
detail: result
|
|
1282
|
-
}
|
|
1283
|
-
);
|
|
1284
|
-
}
|
|
1285
|
-
function extractWsfeGlobalIssues(result, operation, resultLevel) {
|
|
1286
|
-
const errorsContainer = toWsfeRecord(result.Errors);
|
|
1287
|
-
return normalizeWsfeIssueEntries(errorsContainer?.Err).map((entry) => ({
|
|
1288
|
-
service: "wsfe",
|
|
1289
|
-
operation,
|
|
1290
|
-
source: "error",
|
|
1291
|
-
category: operation === "FECAESolicitar" && WSFE_AUTHORIZATION_INFRASTRUCTURE_CODES.has(entry.code ?? "") ? "infrastructure" : operation === "FECAESolicitar" ? "business" : "unknown",
|
|
1292
|
-
...entry.code === void 0 ? {} : { code: entry.code },
|
|
1293
|
-
message: entry.message,
|
|
1294
|
-
...resultLevel === void 0 ? {} : { resultLevel }
|
|
1295
|
-
}));
|
|
1296
|
-
}
|
|
1297
|
-
function extractWsfeObservations(detail, category) {
|
|
1298
|
-
const observationsContainer = toWsfeRecord(detail.Observaciones);
|
|
1299
|
-
return normalizeWsfeIssueEntries(observationsContainer?.Obs).map((entry) => ({
|
|
1300
|
-
service: "wsfe",
|
|
1301
|
-
operation: "FECAESolicitar",
|
|
1302
|
-
source: "observation",
|
|
1303
|
-
category,
|
|
1304
|
-
...entry.code === void 0 ? {} : { code: entry.code },
|
|
1305
|
-
message: entry.message,
|
|
1306
|
-
resultLevel: "detail"
|
|
1307
|
-
}));
|
|
1308
|
-
}
|
|
1309
|
-
function normalizeWsfeIssueEntries(rawErrors) {
|
|
1310
|
-
const entries = Array.isArray(rawErrors) ? rawErrors : rawErrors ? [rawErrors] : [];
|
|
1311
|
-
return entries.map((entry) => entry).map((entry) => {
|
|
1312
|
-
const code = entry.Code ?? entry.code;
|
|
1313
|
-
const message = entry.Msg ?? entry.msg ?? "Unknown WSFE error";
|
|
1314
|
-
return {
|
|
1315
|
-
...code === void 0 ? {} : { code: String(code) },
|
|
1316
|
-
message: String(message)
|
|
1317
|
-
};
|
|
1318
|
-
});
|
|
1319
|
-
}
|
|
1320
|
-
function formatWsfeIssue(issue) {
|
|
1321
|
-
return issue.code ? `(${issue.code}) ${issue.message}` : issue.message;
|
|
1322
|
-
}
|
|
1323
|
-
function normalizeWsfeResult(value) {
|
|
1324
|
-
if (typeof value !== "string") {
|
|
1325
|
-
return void 0;
|
|
1326
|
-
}
|
|
1327
|
-
const normalized = value.trim().toUpperCase();
|
|
1328
|
-
return normalized || void 0;
|
|
1329
|
-
}
|
|
1330
|
-
function normalizeWsfeString(value) {
|
|
1331
|
-
if (value === void 0 || value === null) {
|
|
1332
|
-
return void 0;
|
|
1333
|
-
}
|
|
1334
|
-
const normalized = String(value).trim();
|
|
1335
|
-
return normalized || void 0;
|
|
1336
|
-
}
|
|
1337
|
-
function normalizeWsfeNumber(value) {
|
|
1338
|
-
if (value === void 0 || value === null || value === "") {
|
|
1339
|
-
return void 0;
|
|
1340
|
-
}
|
|
1341
|
-
const normalized = Number(value);
|
|
1342
|
-
return Number.isFinite(normalized) ? normalized : void 0;
|
|
1343
|
-
}
|
|
1344
|
-
function assignWsfeValue(target, key, value) {
|
|
1345
|
-
if (value !== void 0) {
|
|
1346
|
-
target[key] = value;
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
function toWsfeRecord(value) {
|
|
1350
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
1351
|
-
}
|
|
1352
|
-
var WSFE_AUTHORIZATION_INFRASTRUCTURE_CODES = /* @__PURE__ */ new Set([
|
|
1353
|
-
"500",
|
|
1354
|
-
"501",
|
|
1355
|
-
"502",
|
|
1356
|
-
"600",
|
|
1357
|
-
"601"
|
|
1358
|
-
]);
|
|
1359
|
-
function getWsfeResultEntries(result, key) {
|
|
1360
|
-
const rawEntries = result.ResultGet?.[key];
|
|
1361
|
-
if (!rawEntries) {
|
|
1362
|
-
return [];
|
|
1363
|
-
}
|
|
1364
|
-
return (Array.isArray(rawEntries) ? rawEntries : [rawEntries]).map(
|
|
1365
|
-
(entry) => entry
|
|
1366
|
-
);
|
|
1367
|
-
}
|
|
1368
|
-
|
|
1369
|
-
// src/services/wsmtxca.ts
|
|
1370
|
-
function createWsmtxcaService(options) {
|
|
1371
|
-
async function executeWsmtxcaAuthenticatedOperation(operation, input, body = {}, retries) {
|
|
1372
|
-
const auth = await options.auth.login("wsmtxca", {
|
|
1373
|
-
representedTaxId: input.representedTaxId,
|
|
1374
|
-
forceRefresh: input.forceRefresh
|
|
1375
|
-
});
|
|
1376
|
-
const response = await options.soap.execute({
|
|
1377
|
-
service: "wsmtxca",
|
|
1378
|
-
operation,
|
|
1379
|
-
...retries === void 0 ? {} : { retries },
|
|
1380
|
-
bodyElementName: `${operation}Request`,
|
|
1381
|
-
bodyElementNamespaceMode: "prefix",
|
|
1382
|
-
body: {
|
|
1383
|
-
authRequest: createWsmtxcaAuth(
|
|
1384
|
-
input.representedTaxId ?? options.config.taxId,
|
|
1385
|
-
auth.token,
|
|
1386
|
-
auth.sign
|
|
1387
|
-
),
|
|
1388
|
-
...body
|
|
1389
|
-
}
|
|
1390
|
-
});
|
|
1391
|
-
return unwrapWsmtxcaOperationResponse(response.result, operation);
|
|
1392
|
-
}
|
|
1393
|
-
async function executeWsmtxcaAuthorization({
|
|
1394
|
-
representedTaxId,
|
|
1395
|
-
data,
|
|
1396
|
-
forceRefresh
|
|
1397
|
-
}) {
|
|
1398
|
-
try {
|
|
1399
|
-
const raw = await executeWsmtxcaAuthenticatedOperation(
|
|
1400
|
-
"autorizarComprobante",
|
|
1401
|
-
{ representedTaxId, forceRefresh },
|
|
1402
|
-
data,
|
|
1403
|
-
0
|
|
1404
|
-
);
|
|
1405
|
-
return { outcome: classifyWsmtxcaAuthorization(raw) };
|
|
1406
|
-
} catch (error) {
|
|
1407
|
-
return {
|
|
1408
|
-
outcome: createWsmtxcaIndeterminateOutcome(error),
|
|
1409
|
-
error
|
|
1410
|
-
};
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
async function authorizeVoucherOutcome(input) {
|
|
1414
|
-
return (await executeWsmtxcaAuthorization(input)).outcome;
|
|
1415
|
-
}
|
|
1416
|
-
async function authorizeVoucher(input) {
|
|
1417
|
-
const execution = await executeWsmtxcaAuthorization(input);
|
|
1418
|
-
if (execution.error) {
|
|
1419
|
-
throw execution.error;
|
|
1420
|
-
}
|
|
1421
|
-
if (execution.outcome.kind !== "authorized") {
|
|
1422
|
-
throw createWsmtxcaOutcomeError(execution.outcome);
|
|
1423
|
-
}
|
|
1424
|
-
const { outcome } = execution;
|
|
1425
|
-
return {
|
|
1426
|
-
cae: outcome.cae,
|
|
1427
|
-
...outcome.caeExpiry === void 0 ? {} : { caeExpiry: outcome.caeExpiry },
|
|
1428
|
-
voucherNumber: outcome.voucherNumber,
|
|
1429
|
-
messages: formatWsmtxcaIssues([
|
|
1430
|
-
...outcome.errors,
|
|
1431
|
-
...outcome.observations
|
|
1432
|
-
]),
|
|
1433
|
-
raw: outcome.raw ?? {}
|
|
1434
|
-
};
|
|
1435
|
-
}
|
|
1436
|
-
async function getLastAuthorizedVoucher({
|
|
1437
|
-
representedTaxId,
|
|
1438
|
-
voucherType,
|
|
1439
|
-
salesPoint,
|
|
1440
|
-
forceRefresh
|
|
1441
|
-
}) {
|
|
1442
|
-
const operation = "consultarUltimoComprobanteAutorizado";
|
|
1443
|
-
const raw = await executeWsmtxcaAuthenticatedOperation(
|
|
1444
|
-
operation,
|
|
1445
|
-
{ representedTaxId, forceRefresh },
|
|
1446
|
-
{
|
|
1447
|
-
consultaUltimoComprobanteAutorizadoRequest: {
|
|
1448
|
-
codigoTipoComprobante: voucherType,
|
|
1449
|
-
numeroPuntoVenta: salesPoint
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
);
|
|
1453
|
-
const errors = extractWsmtxcaIssues(raw, operation, "error");
|
|
1454
|
-
if (errors.length > 0 && errors.every((issue) => issue.code === "1502")) {
|
|
1455
|
-
return { voucherNumber: 0, raw };
|
|
1456
|
-
}
|
|
1457
|
-
if (errors.length > 0) {
|
|
1458
|
-
throw createWsmtxcaServiceError(operation, raw, errors);
|
|
1459
|
-
}
|
|
1460
|
-
return {
|
|
1461
|
-
voucherNumber: parseWsmtxcaVoucherNumber(
|
|
1462
|
-
raw.numeroComprobante ?? raw.cbteNro ?? raw.nroComprobante,
|
|
1463
|
-
"WSMTXCA did not return the last authorized voucher number",
|
|
1464
|
-
raw,
|
|
1465
|
-
true
|
|
1466
|
-
),
|
|
1467
|
-
raw
|
|
1468
|
-
};
|
|
1469
|
-
}
|
|
1470
|
-
async function getSalesPoints({
|
|
1471
|
-
representedTaxId,
|
|
1472
|
-
forceRefresh
|
|
1473
|
-
}) {
|
|
1474
|
-
const raw = await executeWsmtxcaAuthenticatedOperation(
|
|
1475
|
-
"consultarPuntosVenta",
|
|
1476
|
-
{ representedTaxId, forceRefresh }
|
|
1477
|
-
);
|
|
1478
|
-
const rawSalesPoints = toRecord(raw.arrayPuntosVenta)?.puntoVenta;
|
|
1479
|
-
const entries = Array.isArray(rawSalesPoints) ? rawSalesPoints : rawSalesPoints ? [rawSalesPoints] : [];
|
|
1480
|
-
const salesPoints = entries.flatMap((entry) => {
|
|
1481
|
-
const record = toRecord(entry);
|
|
1482
|
-
const number = parseOptionalPositiveInteger(record?.numeroPuntoVenta);
|
|
1483
|
-
if (number === void 0) {
|
|
1484
|
-
return [];
|
|
1485
|
-
}
|
|
1486
|
-
const deletedAt = normalizeWsmtxcaResponseDate(record?.fechaBaja);
|
|
1487
|
-
return [
|
|
1488
|
-
{
|
|
1489
|
-
number,
|
|
1490
|
-
blocked: String(record?.bloqueado ?? "N").toUpperCase() === "S",
|
|
1491
|
-
...deletedAt === void 0 ? {} : { deletedAt }
|
|
1492
|
-
}
|
|
1493
|
-
];
|
|
1494
|
-
});
|
|
1495
|
-
return { salesPoints, raw };
|
|
179
|
+
test: "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA13"
|
|
180
|
+
},
|
|
181
|
+
soapVersion: "1.1",
|
|
182
|
+
soapActionBase: "",
|
|
183
|
+
usesEmptySoapAction: true
|
|
1496
184
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
}) {
|
|
1504
|
-
const operation = "consultarComprobante";
|
|
1505
|
-
const raw = await executeWsmtxcaAuthenticatedOperation(
|
|
1506
|
-
operation,
|
|
1507
|
-
{ representedTaxId, forceRefresh },
|
|
1508
|
-
{
|
|
1509
|
-
consultaComprobanteRequest: {
|
|
1510
|
-
codigoTipoComprobante: voucherType,
|
|
1511
|
-
numeroPuntoVenta: salesPoint,
|
|
1512
|
-
numeroComprobante: voucherNumber
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
185
|
+
};
|
|
186
|
+
function getArcaServiceConfig(service) {
|
|
187
|
+
const serviceConfig = ARCA_SERVICE_CONFIG[service];
|
|
188
|
+
if (!serviceConfig) {
|
|
189
|
+
throw new ArcaConfigurationError(
|
|
190
|
+
`Unsupported ARCA service configuration: ${service}`
|
|
1515
191
|
);
|
|
1516
|
-
const errors = extractWsmtxcaIssues(raw, operation, "error");
|
|
1517
|
-
const observations = extractWsmtxcaIssues(raw, operation, "observation");
|
|
1518
|
-
if (errors.length > 0 && errors.every((issue) => issue.code === "1503")) {
|
|
1519
|
-
return {
|
|
1520
|
-
kind: "not_found",
|
|
1521
|
-
service: "wsmtxca",
|
|
1522
|
-
operation,
|
|
1523
|
-
errors,
|
|
1524
|
-
observations,
|
|
1525
|
-
raw
|
|
1526
|
-
};
|
|
1527
|
-
}
|
|
1528
|
-
if (errors.length > 0) {
|
|
1529
|
-
throw createWsmtxcaServiceError(operation, raw, errors);
|
|
1530
|
-
}
|
|
1531
|
-
const voucher = extractWsmtxcaVoucherPayload(raw);
|
|
1532
|
-
if (voucher === raw && !toRecord(raw.comprobante)) {
|
|
1533
|
-
throw new ArcaServiceError(
|
|
1534
|
-
"WSMTXCA did not return the voucher issue date",
|
|
1535
|
-
{
|
|
1536
|
-
service: "wsmtxca",
|
|
1537
|
-
operation,
|
|
1538
|
-
issues: observations,
|
|
1539
|
-
detail: raw
|
|
1540
|
-
}
|
|
1541
|
-
);
|
|
1542
|
-
}
|
|
1543
|
-
return {
|
|
1544
|
-
kind: "found",
|
|
1545
|
-
service: "wsmtxca",
|
|
1546
|
-
operation,
|
|
1547
|
-
voucher: mapWsmtxcaVoucherInfo(voucher),
|
|
1548
|
-
observations,
|
|
1549
|
-
raw
|
|
1550
|
-
};
|
|
1551
|
-
}
|
|
1552
|
-
async function getVoucher(input) {
|
|
1553
|
-
const lookup = await lookupVoucher(input);
|
|
1554
|
-
if (lookup.kind === "not_found") {
|
|
1555
|
-
throw createWsmtxcaServiceError(
|
|
1556
|
-
lookup.operation,
|
|
1557
|
-
lookup.raw,
|
|
1558
|
-
lookup.errors
|
|
1559
|
-
);
|
|
1560
|
-
}
|
|
1561
|
-
const invoiceDate = lookup.voucher.invoiceDate;
|
|
1562
|
-
if (!invoiceDate) {
|
|
1563
|
-
throw new ArcaServiceError(
|
|
1564
|
-
formatWsmtxcaIssues(lookup.observations)[0] ?? "WSMTXCA did not return the voucher issue date",
|
|
1565
|
-
{
|
|
1566
|
-
service: "wsmtxca",
|
|
1567
|
-
operation: lookup.operation,
|
|
1568
|
-
issues: lookup.observations,
|
|
1569
|
-
detail: lookup.raw
|
|
1570
|
-
}
|
|
1571
|
-
);
|
|
1572
|
-
}
|
|
1573
|
-
return {
|
|
1574
|
-
invoiceDate,
|
|
1575
|
-
voucher: lookup.voucher.raw,
|
|
1576
|
-
messages: formatWsmtxcaIssues(lookup.observations),
|
|
1577
|
-
raw: lookup.raw
|
|
1578
|
-
};
|
|
1579
192
|
}
|
|
1580
|
-
return
|
|
1581
|
-
authorizeVoucherOutcome,
|
|
1582
|
-
authorizeVoucher,
|
|
1583
|
-
getLastAuthorizedVoucher,
|
|
1584
|
-
getSalesPoints,
|
|
1585
|
-
lookupVoucher,
|
|
1586
|
-
getVoucher
|
|
1587
|
-
};
|
|
193
|
+
return serviceConfig;
|
|
1588
194
|
}
|
|
1589
|
-
function
|
|
195
|
+
function normalizeArcaClientConfig(config) {
|
|
196
|
+
const normalizedEnvironment = normalizeEnvironmentValue(String(config.environment)) ?? config.environment;
|
|
197
|
+
const normalizedLoggerLevel = normalizeLogLevelValue(config.logger?.level);
|
|
1590
198
|
return {
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
199
|
+
taxId: config.taxId.trim(),
|
|
200
|
+
certificatePem: config.certificatePem.trim(),
|
|
201
|
+
privateKeyPem: config.privateKeyPem.trim(),
|
|
202
|
+
environment: normalizedEnvironment,
|
|
203
|
+
timeout: config.timeout ?? DEFAULT_ARCA_TIMEOUT_MS,
|
|
204
|
+
retries: config.retries ?? DEFAULT_ARCA_RETRIES,
|
|
205
|
+
retryDelay: config.retryDelay ?? DEFAULT_ARCA_RETRY_DELAY_MS,
|
|
206
|
+
...config.logger === void 0 ? {} : {
|
|
207
|
+
logger: {
|
|
208
|
+
...config.logger,
|
|
209
|
+
...normalizedLoggerLevel === void 0 ? {} : { level: normalizedLoggerLevel }
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
...config.wsaaSessionStore === void 0 ? {} : { wsaaSessionStore: config.wsaaSessionStore }
|
|
1594
213
|
};
|
|
1595
214
|
}
|
|
1596
|
-
function
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
function unwrapWsmtxcaOperationResponse(response, operation) {
|
|
1600
|
-
const responseRecord = toRecord(response) ?? {};
|
|
1601
|
-
if (operation === "autorizarComprobante") {
|
|
1602
|
-
return toRecord(responseRecord.autorizarComprobanteResponse) ?? toRecord(responseRecord.autorizarComprobanteResult) ?? toRecord(responseRecord.comprobanteCAEResponse) ?? toRecord(responseRecord.comprobanteCAEReponse) ?? responseRecord;
|
|
1603
|
-
}
|
|
1604
|
-
if (operation === "consultarComprobante") {
|
|
1605
|
-
return toRecord(responseRecord.consultarComprobanteResponse) ?? toRecord(responseRecord.consultaComprobanteResponse) ?? toRecord(responseRecord.consultarComprobanteResult) ?? responseRecord;
|
|
1606
|
-
}
|
|
1607
|
-
if (operation === "consultarPuntosVenta") {
|
|
1608
|
-
return toRecord(responseRecord.consultarPuntosVentaResponse) ?? toRecord(responseRecord.consultarPuntosVentaResult) ?? responseRecord;
|
|
1609
|
-
}
|
|
1610
|
-
return toRecord(responseRecord.consultarUltimoComprobanteAutorizadoResponse) ?? toRecord(responseRecord.consultaUltimoComprobanteAutorizadoResponse) ?? toRecord(responseRecord.consultarUltimoComprobanteAutorizadoResult) ?? responseRecord;
|
|
1611
|
-
}
|
|
1612
|
-
function extractWsmtxcaAuthorizationPayload(raw) {
|
|
1613
|
-
return toRecord(raw.comprobanteResponse) ?? toRecord(raw.comprobanteCAEResponse) ?? toRecord(raw.comprobanteCAEReponse) ?? raw;
|
|
1614
|
-
}
|
|
1615
|
-
function extractWsmtxcaVoucherPayload(raw) {
|
|
1616
|
-
return toRecord(raw.comprobanteResponse) ?? toRecord(raw.comprobante) ?? toRecord(raw.cmp) ?? raw;
|
|
1617
|
-
}
|
|
1618
|
-
function classifyWsmtxcaAuthorization(raw) {
|
|
1619
|
-
const operation = "autorizarComprobante";
|
|
1620
|
-
const payload = extractWsmtxcaAuthorizationPayload(raw);
|
|
1621
|
-
const result = normalizeWsmtxcaResult(raw.resultado ?? payload.resultado);
|
|
1622
|
-
const cae = normalizeWsmtxcaString(
|
|
1623
|
-
payload.CAE ?? payload.codigoAutorizacion ?? raw.codigoAutorizacion
|
|
1624
|
-
);
|
|
1625
|
-
const caeExpiry = normalizeWsmtxcaResponseDate(
|
|
1626
|
-
payload.fechaVencimientoCAE ?? payload.fechaVencimiento ?? raw.fechaVencimiento
|
|
1627
|
-
);
|
|
1628
|
-
const voucherNumber = parseOptionalPositiveInteger(
|
|
1629
|
-
payload.numeroComprobante ?? raw.numeroComprobante
|
|
1630
|
-
);
|
|
1631
|
-
const errors = extractWsmtxcaIssues(raw, operation, "error");
|
|
1632
|
-
const observations = extractWsmtxcaIssues(raw, operation, "observation");
|
|
1633
|
-
const base = {
|
|
1634
|
-
service: "wsmtxca",
|
|
1635
|
-
operation,
|
|
1636
|
-
results: createWsmtxcaResults(result),
|
|
1637
|
-
errors,
|
|
1638
|
-
observations,
|
|
1639
|
-
raw
|
|
1640
|
-
};
|
|
1641
|
-
if ((result === "A" || result === "O") && cae && voucherNumber !== void 0 && errors.length === 0) {
|
|
1642
|
-
return {
|
|
1643
|
-
...base,
|
|
1644
|
-
kind: "authorized",
|
|
1645
|
-
result,
|
|
1646
|
-
resultLevel: "operation",
|
|
1647
|
-
cae,
|
|
1648
|
-
...caeExpiry === void 0 ? {} : { caeExpiry },
|
|
1649
|
-
voucherNumber
|
|
1650
|
-
};
|
|
215
|
+
function normalizeEnvironmentValue(value) {
|
|
216
|
+
if (!value) {
|
|
217
|
+
return void 0;
|
|
1651
218
|
}
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
kind: "rejected",
|
|
1656
|
-
result: "R",
|
|
1657
|
-
resultLevel: "operation"
|
|
1658
|
-
};
|
|
219
|
+
const normalized = value.trim().toLowerCase();
|
|
220
|
+
if (ARCA_ENVIRONMENTS.includes(normalized)) {
|
|
221
|
+
return normalized;
|
|
1659
222
|
}
|
|
1660
|
-
|
|
1661
|
-
...base,
|
|
1662
|
-
kind: "indeterminate",
|
|
1663
|
-
reason: result === "R" && Boolean(cae) || (result === "A" || result === "O") && Boolean(errors.length) ? "contradictory_response" : "incomplete_response",
|
|
1664
|
-
...result === void 0 ? {} : { result },
|
|
1665
|
-
...result === void 0 ? {} : { resultLevel: "operation" }
|
|
1666
|
-
};
|
|
1667
|
-
assignWsmtxcaValue(outcome, "cae", cae);
|
|
1668
|
-
assignWsmtxcaValue(outcome, "caeExpiry", caeExpiry);
|
|
1669
|
-
assignWsmtxcaValue(outcome, "voucherNumber", voucherNumber);
|
|
1670
|
-
return outcome;
|
|
223
|
+
return void 0;
|
|
1671
224
|
}
|
|
1672
|
-
function
|
|
1673
|
-
return
|
|
1674
|
-
kind: "indeterminate",
|
|
1675
|
-
service: "wsmtxca",
|
|
1676
|
-
operation: "autorizarComprobante",
|
|
1677
|
-
results: {},
|
|
1678
|
-
reason: getWsmtxcaIndeterminateReason(error),
|
|
1679
|
-
errors: [],
|
|
1680
|
-
observations: []
|
|
1681
|
-
};
|
|
225
|
+
function readEnv(env, variableName) {
|
|
226
|
+
return env[variableName]?.trim() || void 0;
|
|
1682
227
|
}
|
|
1683
|
-
function
|
|
1684
|
-
if (
|
|
1685
|
-
return
|
|
1686
|
-
}
|
|
1687
|
-
if (error instanceof ArcaSoapFaultError) {
|
|
1688
|
-
return "soap_fault";
|
|
228
|
+
function normalizeLogLevelValue(value) {
|
|
229
|
+
if (!value) {
|
|
230
|
+
return void 0;
|
|
1689
231
|
}
|
|
1690
|
-
|
|
1691
|
-
|
|
232
|
+
const normalized = value.trim().toLowerCase();
|
|
233
|
+
if (VALID_ARCA_LOG_LEVELS.includes(normalized)) {
|
|
234
|
+
return normalized;
|
|
1692
235
|
}
|
|
1693
|
-
return
|
|
236
|
+
return value;
|
|
1694
237
|
}
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
...outcome.result === void 0 ? {} : { result: outcome.result },
|
|
1706
|
-
...outcome.resultLevel === void 0 ? {} : { resultLevel: outcome.resultLevel },
|
|
1707
|
-
results: outcome.results,
|
|
1708
|
-
...outcome.kind === "indeterminate" && outcome.cae ? { cae: outcome.cae } : {},
|
|
1709
|
-
issues,
|
|
1710
|
-
detail: outcome.raw
|
|
238
|
+
|
|
239
|
+
// src/internal/logger.ts
|
|
240
|
+
var ARCA_LOG_LEVELS = ["debug", "info", "warn", "error"];
|
|
241
|
+
function createArcaLogger(config) {
|
|
242
|
+
const disabled = config?.disabled ?? false;
|
|
243
|
+
const level = resolveArcaLogLevel(config?.level);
|
|
244
|
+
const sink = config?.log ?? defaultArcaLog;
|
|
245
|
+
const log = (messageLevel, message, ...args) => {
|
|
246
|
+
if (disabled || !shouldLog(level, messageLevel)) {
|
|
247
|
+
return;
|
|
1711
248
|
}
|
|
1712
|
-
|
|
1713
|
-
}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
249
|
+
sink(messageLevel, message, ...args);
|
|
250
|
+
};
|
|
251
|
+
return {
|
|
252
|
+
disabled,
|
|
253
|
+
level,
|
|
254
|
+
log,
|
|
255
|
+
debug(message, ...args) {
|
|
256
|
+
log("debug", message, ...args);
|
|
257
|
+
},
|
|
258
|
+
info(message, ...args) {
|
|
259
|
+
log("info", message, ...args);
|
|
260
|
+
},
|
|
261
|
+
warn(message, ...args) {
|
|
262
|
+
log("warn", message, ...args);
|
|
263
|
+
},
|
|
264
|
+
error(message, ...args) {
|
|
265
|
+
log("error", message, ...args);
|
|
1729
266
|
}
|
|
1730
|
-
|
|
1731
|
-
}
|
|
1732
|
-
function extractWsmtxcaIssues(raw, operation, source) {
|
|
1733
|
-
const container = toRecord(
|
|
1734
|
-
source === "error" ? raw.arrayErrores : raw.arrayObservaciones
|
|
1735
|
-
);
|
|
1736
|
-
return normalizeWsmtxcaIssueEntries(container?.codigoDescripcion).map(
|
|
1737
|
-
(entry) => ({
|
|
1738
|
-
service: "wsmtxca",
|
|
1739
|
-
operation,
|
|
1740
|
-
source,
|
|
1741
|
-
category: source === "observation" ? "observation" : operation === "autorizarComprobante" ? "business" : "unknown",
|
|
1742
|
-
...entry.code === void 0 ? {} : { code: entry.code },
|
|
1743
|
-
message: entry.message,
|
|
1744
|
-
...operation === "autorizarComprobante" ? { resultLevel: "operation" } : {}
|
|
1745
|
-
})
|
|
1746
|
-
);
|
|
1747
|
-
}
|
|
1748
|
-
function normalizeWsmtxcaIssueEntries(value) {
|
|
1749
|
-
const entries = Array.isArray(value) ? value : value ? [value] : [];
|
|
1750
|
-
return entries.map((entry) => {
|
|
1751
|
-
const record = toRecord(entry) ?? {};
|
|
1752
|
-
const code = record.codigo;
|
|
1753
|
-
const description = record.descripcion;
|
|
1754
|
-
return {
|
|
1755
|
-
...code === void 0 || code === null ? {} : { code: String(code) },
|
|
1756
|
-
message: description === void 0 || description === null ? "Unknown WSMTXCA issue" : String(description)
|
|
1757
|
-
};
|
|
1758
|
-
});
|
|
1759
|
-
}
|
|
1760
|
-
function formatWsmtxcaIssues(issues) {
|
|
1761
|
-
return issues.map((issue) => {
|
|
1762
|
-
const prefix = issue.source === "error" ? "Error" : "Obs";
|
|
1763
|
-
return `${prefix}${issue.code ? ` ${issue.code}` : ""}: ${issue.message}`;
|
|
1764
|
-
});
|
|
1765
|
-
}
|
|
1766
|
-
function mapWsmtxcaVoucherInfo(raw) {
|
|
1767
|
-
const voucher = { raw };
|
|
1768
|
-
const invoiceDate = normalizeWsmtxcaResponseDate(
|
|
1769
|
-
raw.fechaEmision ?? raw.fecha ?? raw.CbteFch
|
|
1770
|
-
);
|
|
1771
|
-
const cae = normalizeWsmtxcaString(raw.codigoAutorizacion ?? raw.CAE);
|
|
1772
|
-
const caeExpiry = normalizeWsmtxcaResponseDate(
|
|
1773
|
-
raw.fechaVencimiento ?? raw.fechaVencimientoCAE
|
|
1774
|
-
);
|
|
1775
|
-
const vatAmount = sumWsmtxcaVatAmounts(raw.arraySubtotalesIVA);
|
|
1776
|
-
assignWsmtxcaValue(
|
|
1777
|
-
voucher,
|
|
1778
|
-
"voucherNumber",
|
|
1779
|
-
parseOptionalPositiveInteger(raw.numeroComprobante)
|
|
1780
|
-
);
|
|
1781
|
-
assignWsmtxcaValue(voucher, "invoiceDate", invoiceDate);
|
|
1782
|
-
assignWsmtxcaValue(
|
|
1783
|
-
voucher,
|
|
1784
|
-
"salesPoint",
|
|
1785
|
-
parseOptionalPositiveInteger(raw.numeroPuntoVenta)
|
|
1786
|
-
);
|
|
1787
|
-
assignWsmtxcaValue(
|
|
1788
|
-
voucher,
|
|
1789
|
-
"voucherType",
|
|
1790
|
-
parseOptionalPositiveInteger(raw.codigoTipoComprobante)
|
|
1791
|
-
);
|
|
1792
|
-
assignWsmtxcaValue(
|
|
1793
|
-
voucher,
|
|
1794
|
-
"concept",
|
|
1795
|
-
parseOptionalNumber(raw.codigoConcepto)
|
|
1796
|
-
);
|
|
1797
|
-
assignWsmtxcaValue(
|
|
1798
|
-
voucher,
|
|
1799
|
-
"documentType",
|
|
1800
|
-
parseOptionalNumber(raw.codigoTipoDocumento)
|
|
1801
|
-
);
|
|
1802
|
-
assignWsmtxcaValue(
|
|
1803
|
-
voucher,
|
|
1804
|
-
"documentNumber",
|
|
1805
|
-
normalizeWsmtxcaString(raw.numeroDocumento)
|
|
1806
|
-
);
|
|
1807
|
-
assignWsmtxcaValue(
|
|
1808
|
-
voucher,
|
|
1809
|
-
"receiverVatConditionId",
|
|
1810
|
-
parseOptionalNumber(raw.condicionIVAReceptor)
|
|
1811
|
-
);
|
|
1812
|
-
assignWsmtxcaValue(
|
|
1813
|
-
voucher,
|
|
1814
|
-
"totalAmount",
|
|
1815
|
-
parseOptionalNumber(raw.importeTotal)
|
|
1816
|
-
);
|
|
1817
|
-
assignWsmtxcaValue(
|
|
1818
|
-
voucher,
|
|
1819
|
-
"subtotalAmount",
|
|
1820
|
-
parseOptionalNumber(raw.importeSubtotal)
|
|
1821
|
-
);
|
|
1822
|
-
assignWsmtxcaValue(
|
|
1823
|
-
voucher,
|
|
1824
|
-
"taxableAmount",
|
|
1825
|
-
parseOptionalNumber(raw.importeGravado)
|
|
1826
|
-
);
|
|
1827
|
-
assignWsmtxcaValue(
|
|
1828
|
-
voucher,
|
|
1829
|
-
"nonTaxableAmount",
|
|
1830
|
-
parseOptionalNumber(raw.importeNoGravado)
|
|
1831
|
-
);
|
|
1832
|
-
assignWsmtxcaValue(
|
|
1833
|
-
voucher,
|
|
1834
|
-
"exemptAmount",
|
|
1835
|
-
parseOptionalNumber(raw.importeExento)
|
|
1836
|
-
);
|
|
1837
|
-
assignWsmtxcaValue(
|
|
1838
|
-
voucher,
|
|
1839
|
-
"taxAmount",
|
|
1840
|
-
parseOptionalNumber(raw.importeOtrosTributos)
|
|
1841
|
-
);
|
|
1842
|
-
assignWsmtxcaValue(voucher, "vatAmount", vatAmount);
|
|
1843
|
-
assignWsmtxcaValue(
|
|
1844
|
-
voucher,
|
|
1845
|
-
"currencyId",
|
|
1846
|
-
normalizeWsmtxcaString(raw.codigoMoneda)
|
|
1847
|
-
);
|
|
1848
|
-
assignWsmtxcaValue(
|
|
1849
|
-
voucher,
|
|
1850
|
-
"exchangeRate",
|
|
1851
|
-
parseOptionalNumber(raw.cotizacionMoneda)
|
|
1852
|
-
);
|
|
1853
|
-
assignWsmtxcaValue(voucher, "cae", cae);
|
|
1854
|
-
assignWsmtxcaValue(voucher, "caeExpiry", caeExpiry);
|
|
1855
|
-
return voucher;
|
|
1856
|
-
}
|
|
1857
|
-
function sumWsmtxcaVatAmounts(value) {
|
|
1858
|
-
const subtotals = toRecord(value)?.subtotalIVA;
|
|
1859
|
-
const entries = Array.isArray(subtotals) ? subtotals : subtotals ? [subtotals] : [];
|
|
1860
|
-
const amounts = entries.map((entry) => parseOptionalNumber(toRecord(entry)?.importe)).filter((amount) => amount !== void 0);
|
|
1861
|
-
return amounts.length > 0 ? amounts.reduce((total, amount) => total + amount, 0) : void 0;
|
|
1862
|
-
}
|
|
1863
|
-
function parseWsmtxcaVoucherNumber(value, message, detail, allowZero = false) {
|
|
1864
|
-
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
1865
|
-
if (!Number.isFinite(parsed) || (allowZero ? parsed < 0 : parsed <= 0)) {
|
|
1866
|
-
throw new ArcaServiceError(message, {
|
|
1867
|
-
service: "wsmtxca",
|
|
1868
|
-
detail
|
|
1869
|
-
});
|
|
1870
|
-
}
|
|
1871
|
-
return parsed;
|
|
1872
|
-
}
|
|
1873
|
-
function parseOptionalPositiveInteger(value) {
|
|
1874
|
-
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
1875
|
-
return Number.isFinite(parsed) && parsed > 0 ? parsed : void 0;
|
|
1876
|
-
}
|
|
1877
|
-
function parseOptionalNumber(value) {
|
|
1878
|
-
if (value === void 0 || value === null || value === "") {
|
|
1879
|
-
return void 0;
|
|
1880
|
-
}
|
|
1881
|
-
const parsed = Number(value);
|
|
1882
|
-
return Number.isFinite(parsed) ? parsed : void 0;
|
|
267
|
+
};
|
|
1883
268
|
}
|
|
1884
|
-
function
|
|
1885
|
-
if (
|
|
1886
|
-
return
|
|
269
|
+
function resolveArcaLogLevel(level) {
|
|
270
|
+
if (isArcaLogLevel(level)) {
|
|
271
|
+
return level;
|
|
1887
272
|
}
|
|
1888
|
-
const
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
function normalizeWsmtxcaString(value) {
|
|
1892
|
-
if (value === void 0 || value === null) {
|
|
1893
|
-
return void 0;
|
|
273
|
+
const envLevel = process.env.ARCA_LOG_LEVEL?.trim().toLowerCase();
|
|
274
|
+
if (isArcaLogLevel(envLevel)) {
|
|
275
|
+
return envLevel;
|
|
1894
276
|
}
|
|
1895
|
-
|
|
1896
|
-
return normalized || void 0;
|
|
277
|
+
return "warn";
|
|
1897
278
|
}
|
|
1898
|
-
function
|
|
1899
|
-
|
|
1900
|
-
target[key] = value;
|
|
1901
|
-
}
|
|
279
|
+
function shouldLog(threshold, messageLevel) {
|
|
280
|
+
return ARCA_LOG_LEVELS.indexOf(messageLevel) >= ARCA_LOG_LEVELS.indexOf(threshold);
|
|
1902
281
|
}
|
|
1903
|
-
function
|
|
1904
|
-
|
|
1905
|
-
return formatCompactDateToIso(value);
|
|
1906
|
-
}
|
|
1907
|
-
if (typeof value !== "string") {
|
|
1908
|
-
return void 0;
|
|
1909
|
-
}
|
|
1910
|
-
const trimmed = value.trim();
|
|
1911
|
-
if (!trimmed) {
|
|
1912
|
-
return void 0;
|
|
1913
|
-
}
|
|
1914
|
-
if (/^\d{8}$/.test(trimmed)) {
|
|
1915
|
-
return formatCompactDateToIso(Number.parseInt(trimmed, 10));
|
|
1916
|
-
}
|
|
1917
|
-
if (/^\d{4}-\d{2}-\d{2}/.test(trimmed)) {
|
|
1918
|
-
return trimmed.slice(0, 10);
|
|
1919
|
-
}
|
|
1920
|
-
return void 0;
|
|
282
|
+
function isArcaLogLevel(value) {
|
|
283
|
+
return ARCA_LOG_LEVELS.includes(value);
|
|
1921
284
|
}
|
|
1922
|
-
function
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
}
|
|
1926
|
-
const raw = String(dateValue);
|
|
1927
|
-
if (raw.length !== 8) {
|
|
1928
|
-
return void 0;
|
|
1929
|
-
}
|
|
1930
|
-
return `${raw.slice(0, 4)}-${raw.slice(4, 6)}-${raw.slice(6, 8)}`;
|
|
285
|
+
function defaultArcaLog(level, message, ...args) {
|
|
286
|
+
const method = level === "debug" ? console.debug : level === "info" ? console.info : level === "warn" ? console.warn : console.error;
|
|
287
|
+
method(message, ...args);
|
|
1931
288
|
}
|
|
1932
289
|
|
|
1933
290
|
// src/internal/http.ts
|
|
@@ -1974,7 +331,7 @@ async function postXmlWithMetadata({
|
|
|
1974
331
|
url,
|
|
1975
332
|
attempt,
|
|
1976
333
|
attempts: totalAttempts,
|
|
1977
|
-
error
|
|
334
|
+
...createSafeErrorDiagnostic(error)
|
|
1978
335
|
});
|
|
1979
336
|
throw error;
|
|
1980
337
|
}
|
|
@@ -1987,7 +344,7 @@ async function postXmlWithMetadata({
|
|
|
1987
344
|
url,
|
|
1988
345
|
attempt: nextAttempt,
|
|
1989
346
|
attempts: totalAttempts,
|
|
1990
|
-
error
|
|
347
|
+
...createSafeErrorDiagnostic(error)
|
|
1991
348
|
}
|
|
1992
349
|
);
|
|
1993
350
|
await delay(retryDelay);
|
|
@@ -2046,21 +403,18 @@ async function postXmlOnce({
|
|
|
2046
403
|
});
|
|
2047
404
|
response.on("error", (error) => {
|
|
2048
405
|
settleReject(
|
|
2049
|
-
new ArcaTransportError(
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
responseBody: getResponseBody()
|
|
2055
|
-
}
|
|
2056
|
-
)
|
|
406
|
+
new ArcaTransportError("ARCA HTTP response stream failed", {
|
|
407
|
+
cause: error,
|
|
408
|
+
statusCode: response.statusCode,
|
|
409
|
+
...createResponseBodyDiagnostic(getResponseBody())
|
|
410
|
+
})
|
|
2057
411
|
);
|
|
2058
412
|
});
|
|
2059
413
|
response.on("aborted", () => {
|
|
2060
414
|
settleReject(
|
|
2061
415
|
new ArcaTransportError("ARCA HTTP response was aborted", {
|
|
2062
416
|
statusCode: response.statusCode,
|
|
2063
|
-
|
|
417
|
+
...createResponseBodyDiagnostic(getResponseBody())
|
|
2064
418
|
})
|
|
2065
419
|
);
|
|
2066
420
|
});
|
|
@@ -2092,7 +446,7 @@ async function postXmlOnce({
|
|
|
2092
446
|
{
|
|
2093
447
|
statusCode,
|
|
2094
448
|
contentType: responseContentType,
|
|
2095
|
-
responseBody
|
|
449
|
+
...createResponseBodyDiagnostic(responseBody)
|
|
2096
450
|
}
|
|
2097
451
|
)
|
|
2098
452
|
);
|
|
@@ -2100,13 +454,20 @@ async function postXmlOnce({
|
|
|
2100
454
|
}
|
|
2101
455
|
);
|
|
2102
456
|
request.setTimeout(timeout, () => {
|
|
2103
|
-
|
|
2104
|
-
|
|
457
|
+
const timeoutCause = new Error(
|
|
458
|
+
`ARCA HTTP request timed out after ${timeout}ms`
|
|
459
|
+
);
|
|
460
|
+
settleReject(
|
|
461
|
+
new ArcaTransportError(
|
|
462
|
+
`ARCA HTTP request timed out after ${timeout}ms`,
|
|
463
|
+
{ cause: timeoutCause }
|
|
464
|
+
)
|
|
2105
465
|
);
|
|
466
|
+
request.destroy(timeoutCause);
|
|
2106
467
|
});
|
|
2107
468
|
request.on("error", (error) => {
|
|
2108
469
|
settleReject(
|
|
2109
|
-
new ArcaTransportError(
|
|
470
|
+
new ArcaTransportError("ARCA HTTP request failed", {
|
|
2110
471
|
cause: error
|
|
2111
472
|
})
|
|
2112
473
|
);
|
|
@@ -2174,7 +535,6 @@ function parseSoapBody(xml, context = {}) {
|
|
|
2174
535
|
throw createInvalidSoapResponseError(
|
|
2175
536
|
"Invalid SOAP response: XML parse failed",
|
|
2176
537
|
context,
|
|
2177
|
-
void 0,
|
|
2178
538
|
error instanceof Error ? error : void 0
|
|
2179
539
|
);
|
|
2180
540
|
}
|
|
@@ -2183,8 +543,7 @@ function parseSoapBody(xml, context = {}) {
|
|
|
2183
543
|
if (!body) {
|
|
2184
544
|
throw createInvalidSoapResponseError(
|
|
2185
545
|
"Invalid SOAP response: missing body",
|
|
2186
|
-
context
|
|
2187
|
-
parsed
|
|
546
|
+
context
|
|
2188
547
|
);
|
|
2189
548
|
}
|
|
2190
549
|
const fault = body.Fault;
|
|
@@ -2198,13 +557,12 @@ function getSingleBodyEntry(body, context = {}) {
|
|
|
2198
557
|
if (entries.length !== 1) {
|
|
2199
558
|
throw createInvalidSoapResponseError(
|
|
2200
559
|
`Invalid SOAP response: expected a single body entry, got ${entries.length}`,
|
|
2201
|
-
context
|
|
2202
|
-
body
|
|
560
|
+
context
|
|
2203
561
|
);
|
|
2204
562
|
}
|
|
2205
563
|
return entries[0];
|
|
2206
564
|
}
|
|
2207
|
-
function createInvalidSoapResponseError(message, context,
|
|
565
|
+
function createInvalidSoapResponseError(message, context, cause) {
|
|
2208
566
|
const responseBody = context.responseBody ?? "";
|
|
2209
567
|
return new ArcaInvalidSoapResponseError(message, {
|
|
2210
568
|
cause,
|
|
@@ -2213,20 +571,12 @@ function createInvalidSoapResponseError(message, context, parsedDetail, cause) {
|
|
|
2213
571
|
endpointUrl: context.endpointUrl,
|
|
2214
572
|
statusCode: context.statusCode,
|
|
2215
573
|
contentType: context.contentType,
|
|
2216
|
-
|
|
2217
|
-
responseBodyPreview: sanitizeSoapResponsePreview(
|
|
574
|
+
...createResponseBodyDiagnostic(
|
|
2218
575
|
responseBody,
|
|
2219
576
|
context.responseBodyPreviewLength
|
|
2220
|
-
)
|
|
2221
|
-
parsedDetail
|
|
577
|
+
)
|
|
2222
578
|
});
|
|
2223
579
|
}
|
|
2224
|
-
function sanitizeSoapResponsePreview(responseBody, maxLength = 4096) {
|
|
2225
|
-
return responseBody.replace(
|
|
2226
|
-
/<((?:[A-Za-z_][\w.-]*:)?(?:Token|Sign))\b([^>]*)>[\s\S]*?<\/\1>/gi,
|
|
2227
|
-
(_match, tagName, attributes) => `<${tagName}${attributes}>[REDACTED]</${tagName}>`
|
|
2228
|
-
).slice(0, maxLength);
|
|
2229
|
-
}
|
|
2230
580
|
function parseXmlDocument(xml) {
|
|
2231
581
|
return xmlParser.parse(xml);
|
|
2232
582
|
}
|
|
@@ -2244,8 +594,7 @@ function createSoapFaultError(fault) {
|
|
|
2244
594
|
const faultCode = typeof fault.faultcode === "string" ? fault.faultcode : getNestedString(fault, ["Code", "Value"]);
|
|
2245
595
|
const message = typeof fault.faultstring === "string" ? fault.faultstring : getNestedString(fault, ["Reason", "Text"]) ?? "ARCA SOAP fault response";
|
|
2246
596
|
return new ArcaSoapFaultError(message, {
|
|
2247
|
-
faultCode: faultCode ?? void 0
|
|
2248
|
-
detail: fault
|
|
597
|
+
faultCode: faultCode ?? void 0
|
|
2249
598
|
});
|
|
2250
599
|
}
|
|
2251
600
|
function getNestedString(value, path) {
|
|
@@ -2328,8 +677,7 @@ function createSoapTransport(options) {
|
|
|
2328
677
|
service: request.service,
|
|
2329
678
|
operation: request.operation,
|
|
2330
679
|
url,
|
|
2331
|
-
|
|
2332
|
-
error
|
|
680
|
+
...createSafeErrorDiagnostic(error)
|
|
2333
681
|
});
|
|
2334
682
|
}
|
|
2335
683
|
if (error instanceof ArcaInvalidSoapResponseError) {
|
|
@@ -2337,10 +685,7 @@ function createSoapTransport(options) {
|
|
|
2337
685
|
service: request.service,
|
|
2338
686
|
operation: request.operation,
|
|
2339
687
|
url,
|
|
2340
|
-
|
|
2341
|
-
contentType: error.contentType,
|
|
2342
|
-
responseBodyLength: error.responseBodyLength,
|
|
2343
|
-
error
|
|
688
|
+
...createSafeErrorDiagnostic(error)
|
|
2344
689
|
});
|
|
2345
690
|
}
|
|
2346
691
|
throw error;
|
|
@@ -2405,93 +750,128 @@ function isWsaaCredentialValid(credentials) {
|
|
|
2405
750
|
// src/wsaa/index.ts
|
|
2406
751
|
function createWsaaAuthModule(options) {
|
|
2407
752
|
const cache = /* @__PURE__ */ new Map();
|
|
2408
|
-
const
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
if (
|
|
2415
|
-
|
|
753
|
+
const ordinaryInFlight = /* @__PURE__ */ new Map();
|
|
754
|
+
const forcedInFlight = /* @__PURE__ */ new Map();
|
|
755
|
+
function trackLogin(target, cacheKey, login) {
|
|
756
|
+
const promise = login();
|
|
757
|
+
target.set(cacheKey, promise);
|
|
758
|
+
const cleanup = () => {
|
|
759
|
+
if (target.get(cacheKey) === promise) {
|
|
760
|
+
target.delete(cacheKey);
|
|
2416
761
|
}
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
762
|
+
};
|
|
763
|
+
promise.then(cleanup, cleanup);
|
|
764
|
+
return promise;
|
|
765
|
+
}
|
|
766
|
+
async function requestOrReuseWsaaCredentials(service, sessionKey, cacheKey, forceRefresh) {
|
|
767
|
+
const reuse = await getReusableCredentials({
|
|
768
|
+
config: options.config,
|
|
769
|
+
cache,
|
|
770
|
+
cacheKey,
|
|
771
|
+
sessionKey,
|
|
772
|
+
logger: options.logger,
|
|
773
|
+
service,
|
|
774
|
+
allowStore: !forceRefresh,
|
|
775
|
+
allowCache: !forceRefresh
|
|
776
|
+
});
|
|
777
|
+
if (reuse) {
|
|
778
|
+
return reuse;
|
|
779
|
+
}
|
|
780
|
+
const refresh = () => refreshWsaaCredentials({
|
|
781
|
+
config: options.config,
|
|
782
|
+
cache,
|
|
783
|
+
cacheKey,
|
|
784
|
+
sessionKey,
|
|
785
|
+
logger: options.logger,
|
|
786
|
+
service,
|
|
787
|
+
forceRefresh
|
|
788
|
+
});
|
|
789
|
+
if (options.config.wsaaSessionStore?.withLock) {
|
|
790
|
+
return await withWsaaSessionStoreLock(
|
|
791
|
+
options.config,
|
|
792
|
+
sessionKey,
|
|
793
|
+
service,
|
|
794
|
+
refresh
|
|
795
|
+
);
|
|
796
|
+
}
|
|
797
|
+
return await refresh();
|
|
798
|
+
}
|
|
799
|
+
async function performLogin(service, sessionKey, cacheKey, forceRefresh) {
|
|
800
|
+
try {
|
|
801
|
+
return await requestOrReuseWsaaCredentials(
|
|
802
|
+
service,
|
|
803
|
+
sessionKey,
|
|
804
|
+
cacheKey,
|
|
805
|
+
forceRefresh
|
|
806
|
+
);
|
|
807
|
+
} catch (error) {
|
|
808
|
+
if (error instanceof ArcaSoapFaultError && error.faultCode === "ns1:coe.alreadyAuthenticated") {
|
|
809
|
+
const recovered = await getReusableCredentials({
|
|
2432
810
|
config: options.config,
|
|
2433
811
|
cache,
|
|
2434
812
|
cacheKey,
|
|
2435
813
|
sessionKey,
|
|
2436
814
|
logger: options.logger,
|
|
2437
815
|
service,
|
|
2438
|
-
|
|
816
|
+
allowStore: true,
|
|
817
|
+
allowCache: true
|
|
2439
818
|
});
|
|
2440
|
-
if (
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
819
|
+
if (recovered) {
|
|
820
|
+
options.logger?.warn(
|
|
821
|
+
"Recovered WSAA coe.alreadyAuthenticated fault",
|
|
822
|
+
{
|
|
823
|
+
service,
|
|
824
|
+
faultCode: error.faultCode
|
|
825
|
+
}
|
|
2446
826
|
);
|
|
827
|
+
return recovered;
|
|
2447
828
|
}
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
} catch (error) {
|
|
2454
|
-
if (error instanceof ArcaSoapFaultError && error.faultCode === "ns1:coe.alreadyAuthenticated") {
|
|
2455
|
-
const recovered = await getReusableCredentials({
|
|
2456
|
-
config: options.config,
|
|
2457
|
-
cache,
|
|
2458
|
-
cacheKey,
|
|
2459
|
-
sessionKey,
|
|
2460
|
-
logger: options.logger,
|
|
2461
|
-
service,
|
|
2462
|
-
allowStore: true,
|
|
2463
|
-
allowCache: true
|
|
2464
|
-
});
|
|
2465
|
-
if (recovered) {
|
|
2466
|
-
options.logger?.warn(
|
|
2467
|
-
"Recovered WSAA coe.alreadyAuthenticated fault",
|
|
2468
|
-
{
|
|
2469
|
-
service,
|
|
2470
|
-
faultCode: error.faultCode
|
|
2471
|
-
}
|
|
2472
|
-
);
|
|
2473
|
-
return recovered;
|
|
2474
|
-
}
|
|
2475
|
-
if (!options.config.wsaaSessionStore) {
|
|
2476
|
-
throw new ArcaConfigurationError(
|
|
2477
|
-
"WSAA login failed because another process likely owns a valid TA. Configure a durable wsaaSessionStore for multi-process or serverless deployments.",
|
|
2478
|
-
{ cause: error }
|
|
2479
|
-
);
|
|
2480
|
-
}
|
|
829
|
+
if (!options.config.wsaaSessionStore) {
|
|
830
|
+
throw new ArcaConfigurationError(
|
|
831
|
+
"WSAA login failed because another process likely owns a valid TA. Configure a durable wsaaSessionStore for multi-process or serverless deployments.",
|
|
832
|
+
{ cause: error }
|
|
833
|
+
);
|
|
2481
834
|
}
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
835
|
+
}
|
|
836
|
+
if (error instanceof ArcaSoapFaultError) {
|
|
837
|
+
options.logger?.error("WSAA SOAP fault response", {
|
|
838
|
+
service,
|
|
839
|
+
operation: "loginCms",
|
|
840
|
+
url: ARCA_WSAA_CONFIG.endpoint[options.config.environment],
|
|
841
|
+
...createSafeErrorDiagnostic(error)
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
throw error;
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
return {
|
|
848
|
+
login(service, authOptions = {}) {
|
|
849
|
+
const sessionKey = buildWsaaSessionKey(options.config, service);
|
|
850
|
+
const cacheKey = serializeWsaaSessionKey(sessionKey);
|
|
851
|
+
if (authOptions.forceRefresh) {
|
|
852
|
+
const runningForced2 = forcedInFlight.get(cacheKey);
|
|
853
|
+
if (runningForced2) {
|
|
854
|
+
return runningForced2;
|
|
2490
855
|
}
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
856
|
+
const runningOrdinary2 = ordinaryInFlight.get(cacheKey);
|
|
857
|
+
return trackLogin(forcedInFlight, cacheKey, async () => {
|
|
858
|
+
await runningOrdinary2?.catch(() => void 0);
|
|
859
|
+
return await performLogin(service, sessionKey, cacheKey, true);
|
|
860
|
+
});
|
|
2494
861
|
}
|
|
862
|
+
const runningOrdinary = ordinaryInFlight.get(cacheKey);
|
|
863
|
+
if (runningOrdinary) {
|
|
864
|
+
return runningOrdinary;
|
|
865
|
+
}
|
|
866
|
+
const runningForced = forcedInFlight.get(cacheKey);
|
|
867
|
+
if (runningForced) {
|
|
868
|
+
return runningForced;
|
|
869
|
+
}
|
|
870
|
+
return trackLogin(
|
|
871
|
+
ordinaryInFlight,
|
|
872
|
+
cacheKey,
|
|
873
|
+
() => performLogin(service, sessionKey, cacheKey, false)
|
|
874
|
+
);
|
|
2495
875
|
}
|
|
2496
876
|
};
|
|
2497
877
|
}
|
|
@@ -2747,8 +1127,15 @@ function createArcaClient(config) {
|
|
|
2747
1127
|
const logger = createArcaLogger(normalizedConfig.logger);
|
|
2748
1128
|
const auth = createWsaaAuthModule({ config: normalizedConfig, logger });
|
|
2749
1129
|
const soap = createSoapTransport({ config: normalizedConfig, logger });
|
|
1130
|
+
const publicConfig = Object.freeze({
|
|
1131
|
+
taxId: normalizedConfig.taxId,
|
|
1132
|
+
environment: normalizedConfig.environment,
|
|
1133
|
+
timeout: normalizedConfig.timeout,
|
|
1134
|
+
retries: normalizedConfig.retries,
|
|
1135
|
+
retryDelay: normalizedConfig.retryDelay
|
|
1136
|
+
});
|
|
2750
1137
|
return {
|
|
2751
|
-
config:
|
|
1138
|
+
config: publicConfig,
|
|
2752
1139
|
wsfe: createWsfeService({ config: normalizedConfig, auth, soap }),
|
|
2753
1140
|
wsmtxca: createWsmtxcaService({ config: normalizedConfig, auth, soap }),
|
|
2754
1141
|
padron: createPadronService({ config: normalizedConfig, auth, soap })
|
|
@@ -2757,6 +1144,7 @@ function createArcaClient(config) {
|
|
|
2757
1144
|
export {
|
|
2758
1145
|
ARCA_ENVIRONMENTS,
|
|
2759
1146
|
ARCA_ENV_VARIABLES,
|
|
1147
|
+
ArcaAuthenticationError,
|
|
2760
1148
|
ArcaConfigurationError,
|
|
2761
1149
|
ArcaError,
|
|
2762
1150
|
ArcaInputError,
|
|
@@ -2765,12 +1153,15 @@ export {
|
|
|
2765
1153
|
ArcaSoapFaultError,
|
|
2766
1154
|
ArcaTransportError,
|
|
2767
1155
|
assertArcaClientConfig,
|
|
1156
|
+
buildFacturaB,
|
|
1157
|
+
buildFacturaC,
|
|
2768
1158
|
createArcaClient,
|
|
2769
1159
|
createArcaClientConfigFromEnv,
|
|
2770
1160
|
createMemoryWsaaSessionStore,
|
|
2771
1161
|
createPadronService,
|
|
2772
1162
|
createWsfeService,
|
|
2773
1163
|
createWsmtxcaService,
|
|
1164
|
+
isArcaAuthenticationError,
|
|
2774
1165
|
resolveArcaEnvironment
|
|
2775
1166
|
};
|
|
2776
1167
|
//# sourceMappingURL=index.mjs.map
|