facturas 0.6.1 → 0.7.1

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