facturas 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/errors.d.ts +16 -1
- package/dist/errors.mjs +14 -0
- package/dist/errors.mjs.map +1 -1
- package/dist/fiscal-evidence-DbbFH74x.d.ts +69 -0
- package/dist/{index-CqXVyU0E.d.ts → index-3fdgJ3c2.d.ts} +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.mjs +919 -265
- package/dist/index.mjs.map +1 -1
- package/dist/padron.d.ts +2 -2
- package/dist/padron.mjs.map +1 -1
- package/dist/{types-CKKe1Oo4.d.ts → types-Cup-oevW.d.ts} +2 -0
- package/dist/types.d.ts +1 -1
- package/dist/wsfe.d.ts +32 -3
- package/dist/wsfe.mjs +477 -108
- package/dist/wsfe.mjs.map +1 -1
- package/dist/wsmtxca.d.ts +64 -8
- package/dist/wsmtxca.mjs +543 -156
- package/dist/wsmtxca.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -68,10 +68,24 @@ var ArcaInvalidSoapResponseError = class extends ArcaError {
|
|
|
68
68
|
var ArcaServiceError = class extends ArcaError {
|
|
69
69
|
name = "ArcaServiceError";
|
|
70
70
|
serviceCode;
|
|
71
|
+
service;
|
|
72
|
+
operation;
|
|
73
|
+
result;
|
|
74
|
+
resultLevel;
|
|
75
|
+
results;
|
|
76
|
+
cae;
|
|
77
|
+
issues;
|
|
71
78
|
detail;
|
|
72
79
|
constructor(message, options) {
|
|
73
80
|
super(message, "ARCA_SERVICE_ERROR", options);
|
|
74
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;
|
|
75
89
|
this.detail = options?.detail;
|
|
76
90
|
}
|
|
77
91
|
};
|
|
@@ -432,7 +446,7 @@ async function executePadronOperation(options, service, operation, body) {
|
|
|
432
446
|
|
|
433
447
|
// src/services/wsfe.ts
|
|
434
448
|
function createWsfeService(options) {
|
|
435
|
-
async function
|
|
449
|
+
async function executeWsfeAuthenticatedRawOperation(operation, input, body = {}, retries) {
|
|
436
450
|
const auth = await options.auth.login("wsfe", {
|
|
437
451
|
representedTaxId: input.representedTaxId,
|
|
438
452
|
forceRefresh: input.forceRefresh
|
|
@@ -440,6 +454,7 @@ function createWsfeService(options) {
|
|
|
440
454
|
const response = await options.soap.execute({
|
|
441
455
|
service: "wsfe",
|
|
442
456
|
operation,
|
|
457
|
+
...retries === void 0 ? {} : { retries },
|
|
443
458
|
body: {
|
|
444
459
|
Auth: createWsfeAuth(
|
|
445
460
|
input.representedTaxId ?? options.config.taxId,
|
|
@@ -449,7 +464,16 @@ function createWsfeService(options) {
|
|
|
449
464
|
...body
|
|
450
465
|
}
|
|
451
466
|
});
|
|
452
|
-
return
|
|
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;
|
|
453
477
|
}
|
|
454
478
|
async function executeWsfeOperation(operation, body = {}) {
|
|
455
479
|
const response = await options.soap.execute({
|
|
@@ -457,7 +481,9 @@ function createWsfeService(options) {
|
|
|
457
481
|
operation,
|
|
458
482
|
body
|
|
459
483
|
});
|
|
460
|
-
|
|
484
|
+
const result = unwrapWsfeOperationEnvelope(operation, response.result);
|
|
485
|
+
throwForWsfeOperationErrors(operation, result);
|
|
486
|
+
return result;
|
|
461
487
|
}
|
|
462
488
|
async function getNextVoucherNumber({
|
|
463
489
|
representedTaxId,
|
|
@@ -499,55 +525,148 @@ function createWsfeService(options) {
|
|
|
499
525
|
forceRefresh
|
|
500
526
|
});
|
|
501
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
|
+
}
|
|
502
542
|
async function authorizeNormalizedVoucher({
|
|
503
543
|
representedTaxId,
|
|
504
544
|
data: normalizedInput,
|
|
505
545
|
voucherNumber,
|
|
506
546
|
forceRefresh
|
|
507
547
|
}) {
|
|
508
|
-
const
|
|
509
|
-
const auth = await options.auth.login("wsfe", {
|
|
548
|
+
const execution = await executeWsfeAuthorization({
|
|
510
549
|
representedTaxId,
|
|
550
|
+
data: normalizedInput,
|
|
551
|
+
voucherNumber,
|
|
511
552
|
forceRefresh
|
|
512
553
|
});
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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
|
+
}
|
|
530
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
|
|
531
634
|
}
|
|
532
635
|
}
|
|
533
|
-
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
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,
|
|
540
656
|
detail: result
|
|
541
657
|
});
|
|
542
658
|
}
|
|
543
659
|
return {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
660
|
+
kind: "found",
|
|
661
|
+
service: "wsfe",
|
|
662
|
+
operation,
|
|
663
|
+
voucher: mapWsfeVoucherInfo(raw),
|
|
664
|
+
observations: [],
|
|
547
665
|
raw: result
|
|
548
666
|
};
|
|
549
667
|
}
|
|
550
668
|
return {
|
|
669
|
+
authorizeVoucherOutcome,
|
|
551
670
|
authorizeVoucher,
|
|
552
671
|
async createNextVoucher({ representedTaxId, data, forceRefresh }) {
|
|
553
672
|
const normalizedInput = normalizeWsfeVoucherInput(data);
|
|
@@ -659,33 +778,11 @@ function createWsfeService(options) {
|
|
|
659
778
|
const raw = result.ResultGet ?? {};
|
|
660
779
|
return mapWsfeQuotation(raw);
|
|
661
780
|
},
|
|
662
|
-
async getVoucherInfo({
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
forceRefresh
|
|
668
|
-
}) {
|
|
669
|
-
const result = await executeWsfeAuthenticatedOperation(
|
|
670
|
-
"FECompConsultar",
|
|
671
|
-
{
|
|
672
|
-
representedTaxId,
|
|
673
|
-
forceRefresh
|
|
674
|
-
},
|
|
675
|
-
{
|
|
676
|
-
FeCompConsReq: {
|
|
677
|
-
CbteNro: number,
|
|
678
|
-
PtoVta: salesPoint,
|
|
679
|
-
CbteTipo: voucherType
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
);
|
|
683
|
-
const raw = result.ResultGet ?? null;
|
|
684
|
-
if (!raw) {
|
|
685
|
-
return null;
|
|
686
|
-
}
|
|
687
|
-
return mapWsfeVoucherInfo(raw);
|
|
688
|
-
}
|
|
781
|
+
async getVoucherInfo(input) {
|
|
782
|
+
const lookup = await lookupVoucher(input);
|
|
783
|
+
return lookup.kind === "found" ? lookup.voucher : null;
|
|
784
|
+
},
|
|
785
|
+
lookupVoucher
|
|
689
786
|
};
|
|
690
787
|
}
|
|
691
788
|
function mapWsfeVoucherInput(input, voucherNumber) {
|
|
@@ -951,17 +1048,45 @@ function mapWsfeQuotation(raw) {
|
|
|
951
1048
|
};
|
|
952
1049
|
}
|
|
953
1050
|
function mapWsfeVoucherInfo(raw) {
|
|
954
|
-
|
|
1051
|
+
const voucher = {
|
|
955
1052
|
voucherNumber: Number(raw.CbteDesde ?? raw.CbteHasta ?? 0),
|
|
956
|
-
...raw.CbteFch === void 0 ? {} : { voucherDate: String(raw.CbteFch) },
|
|
957
|
-
...raw.PtoVta === void 0 ? {} : { salesPoint: Number(raw.PtoVta) },
|
|
958
|
-
...raw.CbteTipo === void 0 ? {} : { voucherType: Number(raw.CbteTipo) },
|
|
959
|
-
...raw.ImpTotal === void 0 ? {} : { totalAmount: Number(raw.ImpTotal) },
|
|
960
|
-
...raw.Resultado === void 0 ? {} : { result: String(raw.Resultado) },
|
|
961
|
-
...raw.CAE === void 0 ? {} : { cae: String(raw.CAE) },
|
|
962
|
-
...raw.CAEFchVto === void 0 ? {} : { caeExpiry: String(raw.CAEFchVto) },
|
|
963
1053
|
raw
|
|
964
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;
|
|
965
1090
|
}
|
|
966
1091
|
function createWsfeAuth(representedTaxId, token, sign) {
|
|
967
1092
|
return {
|
|
@@ -970,47 +1095,16 @@ function createWsfeAuth(representedTaxId, token, sign) {
|
|
|
970
1095
|
Cuit: Number.parseInt(String(representedTaxId), 10)
|
|
971
1096
|
};
|
|
972
1097
|
}
|
|
973
|
-
function
|
|
1098
|
+
function unwrapWsfeOperationEnvelope(operation, response) {
|
|
974
1099
|
const operationResponse = response[`${operation}Response`];
|
|
975
1100
|
const result = operationResponse?.[`${operation}Result`] ?? response[`${operation}Result`] ?? response;
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
const observationsContainer = detailResponse.Observaciones;
|
|
981
|
-
const observations = normalizeWsfeErrors(observationsContainer?.Obs);
|
|
982
|
-
if (observations.length > 0) {
|
|
983
|
-
const firstObservation = observations[0];
|
|
984
|
-
if (!firstObservation) {
|
|
985
|
-
throw new ArcaServiceError(
|
|
986
|
-
"WSFE returned an empty observation list",
|
|
987
|
-
{
|
|
988
|
-
detail: result
|
|
989
|
-
}
|
|
990
|
-
);
|
|
991
|
-
}
|
|
992
|
-
throw new ArcaServiceError(firstObservation.message, {
|
|
993
|
-
serviceCode: firstObservation.code,
|
|
994
|
-
detail: result
|
|
995
|
-
});
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
const errorsContainer = result.Errors;
|
|
1000
|
-
const errors = normalizeWsfeErrors(errorsContainer?.Err);
|
|
1101
|
+
return result;
|
|
1102
|
+
}
|
|
1103
|
+
function throwForWsfeOperationErrors(operation, result) {
|
|
1104
|
+
const errors = extractWsfeGlobalIssues(result, operation);
|
|
1001
1105
|
if (errors.length > 0) {
|
|
1002
|
-
|
|
1003
|
-
if (!firstError) {
|
|
1004
|
-
throw new ArcaServiceError("WSFE returned an empty error list", {
|
|
1005
|
-
detail: result
|
|
1006
|
-
});
|
|
1007
|
-
}
|
|
1008
|
-
throw new ArcaServiceError(firstError.message, {
|
|
1009
|
-
serviceCode: firstError.code,
|
|
1010
|
-
detail: result
|
|
1011
|
-
});
|
|
1106
|
+
throw createWsfeServiceError(operation, result, errors);
|
|
1012
1107
|
}
|
|
1013
|
-
return result;
|
|
1014
1108
|
}
|
|
1015
1109
|
function normalizeWsfeDetailResponse(result) {
|
|
1016
1110
|
const detailResponse = result.FeDetResp;
|
|
@@ -1020,17 +1114,248 @@ function normalizeWsfeDetailResponse(result) {
|
|
|
1020
1114
|
}
|
|
1021
1115
|
return rawDetail ?? {};
|
|
1022
1116
|
}
|
|
1023
|
-
function
|
|
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) {
|
|
1024
1310
|
const entries = Array.isArray(rawErrors) ? rawErrors : rawErrors ? [rawErrors] : [];
|
|
1025
1311
|
return entries.map((entry) => entry).map((entry) => {
|
|
1026
|
-
const code = entry.Code ?? entry.code
|
|
1312
|
+
const code = entry.Code ?? entry.code;
|
|
1027
1313
|
const message = entry.Msg ?? entry.msg ?? "Unknown WSFE error";
|
|
1028
1314
|
return {
|
|
1029
|
-
code: String(code),
|
|
1030
|
-
message:
|
|
1315
|
+
...code === void 0 ? {} : { code: String(code) },
|
|
1316
|
+
message: String(message)
|
|
1031
1317
|
};
|
|
1032
1318
|
});
|
|
1033
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
|
+
]);
|
|
1034
1359
|
function getWsfeResultEntries(result, key) {
|
|
1035
1360
|
const rawEntries = result.ResultGet?.[key];
|
|
1036
1361
|
if (!rawEntries) {
|
|
@@ -1043,145 +1368,222 @@ function getWsfeResultEntries(result, key) {
|
|
|
1043
1368
|
|
|
1044
1369
|
// src/services/wsmtxca.ts
|
|
1045
1370
|
function createWsmtxcaService(options) {
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
}
|
|
1065
|
-
});
|
|
1066
|
-
const raw = unwrapWsmtxcaOperationResponse(
|
|
1067
|
-
response.result,
|
|
1068
|
-
"autorizarComprobante"
|
|
1069
|
-
);
|
|
1070
|
-
const authorizationPayload = extractWsmtxcaAuthorizationPayload(raw);
|
|
1071
|
-
const messages = extractWsmtxcaMessages(raw);
|
|
1072
|
-
const resultado = raw.resultado ?? authorizationPayload.resultado;
|
|
1073
|
-
const caeValue = authorizationPayload.CAE ?? authorizationPayload.codigoAutorizacion ?? raw.codigoAutorizacion;
|
|
1074
|
-
if (resultado === "R" || caeValue == null) {
|
|
1075
|
-
throw new ArcaServiceError(
|
|
1076
|
-
messages.join(" | ") || "WSMTXCA rejected the voucher authorization",
|
|
1077
|
-
{ detail: raw }
|
|
1078
|
-
);
|
|
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
|
|
1079
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) {
|
|
1080
1407
|
return {
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
authorizationPayload.fechaVencimientoCAE ?? authorizationPayload.fechaVencimiento ?? raw.fechaVencimiento
|
|
1084
|
-
),
|
|
1085
|
-
voucherNumber: parseWsmtxcaVoucherNumber(
|
|
1086
|
-
authorizationPayload.numeroComprobante ?? raw.numeroComprobante,
|
|
1087
|
-
"WSMTXCA did not return the authorized voucher number",
|
|
1088
|
-
raw
|
|
1089
|
-
),
|
|
1090
|
-
messages,
|
|
1091
|
-
raw
|
|
1408
|
+
outcome: createWsmtxcaIndeterminateOutcome(error),
|
|
1409
|
+
error
|
|
1092
1410
|
};
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
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
|
|
1119
1450
|
}
|
|
1120
|
-
}
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
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 };
|
|
1496
|
+
}
|
|
1497
|
+
async function lookupVoucher({
|
|
1498
|
+
representedTaxId,
|
|
1499
|
+
voucherType,
|
|
1500
|
+
salesPoint,
|
|
1501
|
+
voucherNumber,
|
|
1502
|
+
forceRefresh
|
|
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
|
+
}
|
|
1515
|
+
);
|
|
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")) {
|
|
1125
1519
|
return {
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1520
|
+
kind: "not_found",
|
|
1521
|
+
service: "wsmtxca",
|
|
1522
|
+
operation,
|
|
1523
|
+
errors,
|
|
1524
|
+
observations,
|
|
1131
1525
|
raw
|
|
1132
1526
|
};
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
service: "wsmtxca",
|
|
1147
|
-
operation: "consultarComprobante",
|
|
1148
|
-
bodyElementName: "consultarComprobanteRequest",
|
|
1149
|
-
bodyElementNamespaceMode: "prefix",
|
|
1150
|
-
body: {
|
|
1151
|
-
authRequest: createWsmtxcaAuth(
|
|
1152
|
-
representedTaxId ?? options.config.taxId,
|
|
1153
|
-
auth.token,
|
|
1154
|
-
auth.sign
|
|
1155
|
-
),
|
|
1156
|
-
consultaComprobanteRequest: {
|
|
1157
|
-
codigoTipoComprobante: voucherType,
|
|
1158
|
-
numeroPuntoVenta: salesPoint,
|
|
1159
|
-
numeroComprobante: voucherNumber
|
|
1160
|
-
}
|
|
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
|
|
1161
1540
|
}
|
|
1162
|
-
});
|
|
1163
|
-
const raw = unwrapWsmtxcaOperationResponse(
|
|
1164
|
-
response.result,
|
|
1165
|
-
"consultarComprobante"
|
|
1166
1541
|
);
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
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
|
+
}
|
|
1171
1571
|
);
|
|
1172
|
-
if (!invoiceDate) {
|
|
1173
|
-
throw new ArcaServiceError(
|
|
1174
|
-
messages[0] ?? "WSMTXCA did not return the voucher issue date",
|
|
1175
|
-
{ detail: raw }
|
|
1176
|
-
);
|
|
1177
|
-
}
|
|
1178
|
-
return {
|
|
1179
|
-
invoiceDate,
|
|
1180
|
-
voucher,
|
|
1181
|
-
messages,
|
|
1182
|
-
raw
|
|
1183
|
-
};
|
|
1184
1572
|
}
|
|
1573
|
+
return {
|
|
1574
|
+
invoiceDate,
|
|
1575
|
+
voucher: lookup.voucher.raw,
|
|
1576
|
+
messages: formatWsmtxcaIssues(lookup.observations),
|
|
1577
|
+
raw: lookup.raw
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
return {
|
|
1581
|
+
authorizeVoucherOutcome,
|
|
1582
|
+
authorizeVoucher,
|
|
1583
|
+
getLastAuthorizedVoucher,
|
|
1584
|
+
getSalesPoints,
|
|
1585
|
+
lookupVoucher,
|
|
1586
|
+
getVoucher
|
|
1185
1587
|
};
|
|
1186
1588
|
}
|
|
1187
1589
|
function createWsmtxcaAuth(representedTaxId, token, sign) {
|
|
@@ -1192,7 +1594,7 @@ function createWsmtxcaAuth(representedTaxId, token, sign) {
|
|
|
1192
1594
|
};
|
|
1193
1595
|
}
|
|
1194
1596
|
function toRecord(value) {
|
|
1195
|
-
return value && typeof value === "object" ? value : void 0;
|
|
1597
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
1196
1598
|
}
|
|
1197
1599
|
function unwrapWsmtxcaOperationResponse(response, operation) {
|
|
1198
1600
|
const responseRecord = toRecord(response) ?? {};
|
|
@@ -1202,6 +1604,9 @@ function unwrapWsmtxcaOperationResponse(response, operation) {
|
|
|
1202
1604
|
if (operation === "consultarComprobante") {
|
|
1203
1605
|
return toRecord(responseRecord.consultarComprobanteResponse) ?? toRecord(responseRecord.consultaComprobanteResponse) ?? toRecord(responseRecord.consultarComprobanteResult) ?? responseRecord;
|
|
1204
1606
|
}
|
|
1607
|
+
if (operation === "consultarPuntosVenta") {
|
|
1608
|
+
return toRecord(responseRecord.consultarPuntosVentaResponse) ?? toRecord(responseRecord.consultarPuntosVentaResult) ?? responseRecord;
|
|
1609
|
+
}
|
|
1205
1610
|
return toRecord(responseRecord.consultarUltimoComprobanteAutorizadoResponse) ?? toRecord(responseRecord.consultaUltimoComprobanteAutorizadoResponse) ?? toRecord(responseRecord.consultarUltimoComprobanteAutorizadoResult) ?? responseRecord;
|
|
1206
1611
|
}
|
|
1207
1612
|
function extractWsmtxcaAuthorizationPayload(raw) {
|
|
@@ -1210,42 +1615,291 @@ function extractWsmtxcaAuthorizationPayload(raw) {
|
|
|
1210
1615
|
function extractWsmtxcaVoucherPayload(raw) {
|
|
1211
1616
|
return toRecord(raw.comprobanteResponse) ?? toRecord(raw.comprobante) ?? toRecord(raw.cmp) ?? raw;
|
|
1212
1617
|
}
|
|
1213
|
-
function
|
|
1214
|
-
const
|
|
1215
|
-
const
|
|
1216
|
-
const
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
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
|
+
};
|
|
1651
|
+
}
|
|
1652
|
+
if (result === "R" && !cae && errors.length > 0) {
|
|
1653
|
+
return {
|
|
1654
|
+
...base,
|
|
1655
|
+
kind: "rejected",
|
|
1656
|
+
result: "R",
|
|
1657
|
+
resultLevel: "operation"
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
const outcome = {
|
|
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;
|
|
1671
|
+
}
|
|
1672
|
+
function createWsmtxcaIndeterminateOutcome(error) {
|
|
1673
|
+
return {
|
|
1674
|
+
kind: "indeterminate",
|
|
1675
|
+
service: "wsmtxca",
|
|
1676
|
+
operation: "autorizarComprobante",
|
|
1677
|
+
results: {},
|
|
1678
|
+
reason: getWsmtxcaIndeterminateReason(error),
|
|
1679
|
+
errors: [],
|
|
1680
|
+
observations: []
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1683
|
+
function getWsmtxcaIndeterminateReason(error) {
|
|
1684
|
+
if (error instanceof ArcaTransportError) {
|
|
1685
|
+
return "transport_error";
|
|
1686
|
+
}
|
|
1687
|
+
if (error instanceof ArcaSoapFaultError) {
|
|
1688
|
+
return "soap_fault";
|
|
1689
|
+
}
|
|
1690
|
+
if (error instanceof ArcaInvalidSoapResponseError) {
|
|
1691
|
+
return "invalid_response";
|
|
1692
|
+
}
|
|
1693
|
+
return "unexpected_error";
|
|
1694
|
+
}
|
|
1695
|
+
function createWsmtxcaOutcomeError(outcome) {
|
|
1696
|
+
const issues = [...outcome.errors, ...outcome.observations];
|
|
1697
|
+
const messages = formatWsmtxcaIssues(issues);
|
|
1698
|
+
const firstIssue = issues[0];
|
|
1699
|
+
return new ArcaServiceError(
|
|
1700
|
+
messages.join(" | ") || (outcome.kind === "rejected" ? "WSMTXCA rejected the voucher authorization" : "WSMTXCA did not return conclusive voucher authorization data"),
|
|
1701
|
+
{
|
|
1702
|
+
service: "wsmtxca",
|
|
1703
|
+
operation: outcome.operation,
|
|
1704
|
+
...firstIssue?.code === void 0 ? {} : { serviceCode: firstIssue.code },
|
|
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
|
|
1222
1711
|
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1712
|
+
);
|
|
1713
|
+
}
|
|
1714
|
+
function createWsmtxcaResults(operationResult) {
|
|
1715
|
+
const results = {};
|
|
1716
|
+
assignWsmtxcaValue(results, "operation", operationResult);
|
|
1717
|
+
return results;
|
|
1718
|
+
}
|
|
1719
|
+
function createWsmtxcaServiceError(operation, raw, issues) {
|
|
1720
|
+
const firstIssue = issues[0];
|
|
1721
|
+
return new ArcaServiceError(
|
|
1722
|
+
formatWsmtxcaIssues(issues).join(" | ") || "WSMTXCA returned a service error",
|
|
1723
|
+
{
|
|
1724
|
+
service: "wsmtxca",
|
|
1725
|
+
operation,
|
|
1726
|
+
...firstIssue?.code === void 0 ? {} : { serviceCode: firstIssue.code },
|
|
1727
|
+
issues,
|
|
1728
|
+
detail: raw
|
|
1225
1729
|
}
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
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
|
+
};
|
|
1232
1758
|
});
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
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)
|
|
1239
1821
|
);
|
|
1240
|
-
|
|
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;
|
|
1241
1856
|
}
|
|
1242
|
-
function
|
|
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) {
|
|
1243
1864
|
const parsed = Number.parseInt(String(value ?? ""), 10);
|
|
1244
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
1245
|
-
throw new ArcaServiceError(message, {
|
|
1865
|
+
if (!Number.isFinite(parsed) || (allowZero ? parsed < 0 : parsed <= 0)) {
|
|
1866
|
+
throw new ArcaServiceError(message, {
|
|
1867
|
+
service: "wsmtxca",
|
|
1868
|
+
detail
|
|
1869
|
+
});
|
|
1246
1870
|
}
|
|
1247
1871
|
return parsed;
|
|
1248
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;
|
|
1883
|
+
}
|
|
1884
|
+
function normalizeWsmtxcaResult(value) {
|
|
1885
|
+
if (typeof value !== "string") {
|
|
1886
|
+
return void 0;
|
|
1887
|
+
}
|
|
1888
|
+
const normalized = value.trim().toUpperCase();
|
|
1889
|
+
return normalized || void 0;
|
|
1890
|
+
}
|
|
1891
|
+
function normalizeWsmtxcaString(value) {
|
|
1892
|
+
if (value === void 0 || value === null) {
|
|
1893
|
+
return void 0;
|
|
1894
|
+
}
|
|
1895
|
+
const normalized = String(value).trim();
|
|
1896
|
+
return normalized || void 0;
|
|
1897
|
+
}
|
|
1898
|
+
function assignWsmtxcaValue(target, key, value) {
|
|
1899
|
+
if (value !== void 0) {
|
|
1900
|
+
target[key] = value;
|
|
1901
|
+
}
|
|
1902
|
+
}
|
|
1249
1903
|
function normalizeWsmtxcaResponseDate(value) {
|
|
1250
1904
|
if (typeof value === "number" && Number.isInteger(value)) {
|
|
1251
1905
|
return formatCompactDateToIso(value);
|
|
@@ -1638,7 +2292,7 @@ function createSoapTransport(options) {
|
|
|
1638
2292
|
soapAction: serviceConfig.soapVersion === "1.1" ? soapAction : void 0,
|
|
1639
2293
|
useLegacyTlsSecurityLevel0: options.config.environment === "production" && serviceConfig.useLegacyTlsSecurityLevel0 === true,
|
|
1640
2294
|
timeout: options.config.timeout,
|
|
1641
|
-
retries: options.config.retries,
|
|
2295
|
+
retries: request.retries ?? options.config.retries,
|
|
1642
2296
|
retryDelay: options.config.retryDelay,
|
|
1643
2297
|
logger: options.logger,
|
|
1644
2298
|
service: request.service,
|