@lapyme/arca 0.1.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/dist/wsfe.js ADDED
@@ -0,0 +1,340 @@
1
+ // src/errors.ts
2
+ var ArcaError = class extends Error {
3
+ code;
4
+ name = "ArcaError";
5
+ constructor(message, code = "ARCA_ERROR", options) {
6
+ super(message, options);
7
+ this.code = code;
8
+ }
9
+ };
10
+ var ArcaServiceError = class extends ArcaError {
11
+ name = "ArcaServiceError";
12
+ serviceCode;
13
+ detail;
14
+ constructor(message, options) {
15
+ super(message, "ARCA_SERVICE_ERROR", options);
16
+ this.serviceCode = options?.serviceCode;
17
+ this.detail = options?.detail;
18
+ }
19
+ };
20
+
21
+ // src/services/wsfe.ts
22
+ function createWsfeService(options) {
23
+ async function getLastVoucher({
24
+ representedTaxId,
25
+ salesPoint,
26
+ voucherType,
27
+ forceAuthRefresh
28
+ }) {
29
+ const auth = await options.auth.login("wsfe", {
30
+ representedTaxId,
31
+ forceRefresh: forceAuthRefresh
32
+ });
33
+ const response = await options.soap.execute({
34
+ service: "wsfe",
35
+ operation: "FECompUltimoAutorizado",
36
+ body: {
37
+ Auth: createWsfeAuth(
38
+ representedTaxId ?? options.config.taxId,
39
+ auth.token,
40
+ auth.sign
41
+ ),
42
+ PtoVta: salesPoint,
43
+ CbteTipo: voucherType
44
+ }
45
+ });
46
+ const result = unwrapWsfeOperationResult(
47
+ "FECompUltimoAutorizado",
48
+ response.result
49
+ );
50
+ return Number(result.CbteNro ?? 0) + 1;
51
+ }
52
+ return {
53
+ async createNextVoucher({ representedTaxId, data }) {
54
+ const voucherNumber = await getLastVoucher({
55
+ representedTaxId,
56
+ salesPoint: data.salesPoint,
57
+ voucherType: data.voucherType
58
+ });
59
+ const requestData = mapWsfeVoucherInput(data, voucherNumber);
60
+ const auth = await options.auth.login("wsfe", { representedTaxId });
61
+ const response = await options.soap.execute({
62
+ service: "wsfe",
63
+ operation: "FECAESolicitar",
64
+ body: {
65
+ Auth: createWsfeAuth(
66
+ representedTaxId ?? options.config.taxId,
67
+ auth.token,
68
+ auth.sign
69
+ ),
70
+ FeCAEReq: {
71
+ FeCabReq: {
72
+ CantReg: 1,
73
+ PtoVta: data.salesPoint,
74
+ CbteTipo: data.voucherType
75
+ },
76
+ FeDetReq: {
77
+ FECAEDetRequest: requestData
78
+ }
79
+ }
80
+ }
81
+ });
82
+ const result = unwrapWsfeOperationResult(
83
+ "FECAESolicitar",
84
+ response.result
85
+ );
86
+ const detailResponse = normalizeWsfeDetailResponse(result);
87
+ const cae = detailResponse.CAE;
88
+ const caeExpiry = detailResponse.CAEFchVto;
89
+ if (typeof cae !== "string" || typeof caeExpiry !== "string") {
90
+ throw new ArcaServiceError(
91
+ "WSFE did not return CAE authorization data",
92
+ { detail: result }
93
+ );
94
+ }
95
+ return {
96
+ cae,
97
+ caeExpiry: String(caeExpiry),
98
+ voucherNumber,
99
+ raw: result
100
+ };
101
+ },
102
+ getLastVoucher,
103
+ async getSalesPoints({ representedTaxId, forceAuthRefresh }) {
104
+ const auth = await options.auth.login("wsfe", {
105
+ representedTaxId,
106
+ forceRefresh: forceAuthRefresh
107
+ });
108
+ const response = await options.soap.execute({
109
+ service: "wsfe",
110
+ operation: "FEParamGetPtosVenta",
111
+ body: {
112
+ Auth: createWsfeAuth(
113
+ representedTaxId ?? options.config.taxId,
114
+ auth.token,
115
+ auth.sign
116
+ )
117
+ }
118
+ });
119
+ const result = unwrapWsfeOperationResult(
120
+ "FEParamGetPtosVenta",
121
+ response.result
122
+ );
123
+ const resultGet = result.ResultGet;
124
+ const rawPoints = resultGet?.PtoVenta;
125
+ if (!rawPoints) {
126
+ return [];
127
+ }
128
+ const entries = Array.isArray(rawPoints) ? rawPoints : [rawPoints];
129
+ return entries.map(mapWsfeSalesPoint);
130
+ },
131
+ async getVoucherInfo({
132
+ representedTaxId,
133
+ number,
134
+ salesPoint,
135
+ voucherType
136
+ }) {
137
+ const auth = await options.auth.login("wsfe", { representedTaxId });
138
+ const response = await options.soap.execute({
139
+ service: "wsfe",
140
+ operation: "FECompConsultar",
141
+ body: {
142
+ Auth: createWsfeAuth(
143
+ representedTaxId ?? options.config.taxId,
144
+ auth.token,
145
+ auth.sign
146
+ ),
147
+ FeCompConsReq: {
148
+ CbteNro: number,
149
+ PtoVta: salesPoint,
150
+ CbteTipo: voucherType
151
+ }
152
+ }
153
+ });
154
+ const result = unwrapWsfeOperationResult(
155
+ "FECompConsultar",
156
+ response.result
157
+ );
158
+ const raw = result.ResultGet ?? null;
159
+ if (!raw) {
160
+ return null;
161
+ }
162
+ return mapWsfeVoucherInfo(raw);
163
+ }
164
+ };
165
+ }
166
+ function mapWsfeVoucherInput(input, voucherNumber) {
167
+ const data = {
168
+ Concepto: input.concept,
169
+ DocTipo: input.documentType,
170
+ DocNro: input.documentNumber,
171
+ CbteDesde: voucherNumber,
172
+ CbteHasta: voucherNumber,
173
+ CbteFch: input.voucherDate,
174
+ ImpTotal: input.totalAmount,
175
+ ImpTotConc: input.nonTaxableAmount,
176
+ ImpNeto: input.netAmount,
177
+ ImpOpEx: input.exemptAmount,
178
+ ImpTrib: input.taxAmount,
179
+ ImpIVA: input.vatAmount,
180
+ MonId: input.currencyId,
181
+ MonCotiz: input.exchangeRate,
182
+ PtoVta: input.salesPoint,
183
+ CbteTipo: input.voucherType
184
+ };
185
+ if (input.receiverVatConditionId !== void 0) {
186
+ data.CondicionIVAReceptorId = input.receiverVatConditionId;
187
+ }
188
+ if (input.serviceStartDate !== void 0) {
189
+ data.FchServDesde = input.serviceStartDate;
190
+ }
191
+ if (input.serviceEndDate !== void 0) {
192
+ data.FchServHasta = input.serviceEndDate;
193
+ }
194
+ if (input.paymentDueDate !== void 0) {
195
+ data.FchVtoPago = input.paymentDueDate;
196
+ }
197
+ if (input.associatedVouchers) {
198
+ data.CbtesAsoc = {
199
+ CbteAsoc: input.associatedVouchers.map((v) => ({
200
+ Tipo: v.type,
201
+ PtoVta: v.salesPoint,
202
+ Nro: v.number,
203
+ ...v.taxId !== void 0 ? { Cuit: v.taxId } : {},
204
+ ...v.voucherDate !== void 0 ? { CbteFch: v.voucherDate } : {}
205
+ }))
206
+ };
207
+ }
208
+ if (input.taxes) {
209
+ data.Tributos = {
210
+ Tributo: input.taxes.map((t) => ({
211
+ Id: t.id,
212
+ ...t.description !== void 0 ? { Desc: t.description } : {},
213
+ BaseImp: t.baseAmount,
214
+ Alic: t.rate,
215
+ Importe: t.amount
216
+ }))
217
+ };
218
+ }
219
+ if (input.vatRates) {
220
+ data.Iva = {
221
+ AlicIva: input.vatRates.map((v) => ({
222
+ Id: v.id,
223
+ BaseImp: v.baseAmount,
224
+ Importe: v.amount
225
+ }))
226
+ };
227
+ }
228
+ if (input.optionalFields) {
229
+ data.Opcionales = {
230
+ Opcional: input.optionalFields.map((o) => ({
231
+ Id: o.id,
232
+ Valor: o.value
233
+ }))
234
+ };
235
+ }
236
+ if (input.buyers) {
237
+ data.Compradores = {
238
+ Comprador: input.buyers.map((b) => ({
239
+ DocTipo: b.documentType,
240
+ DocNro: b.documentNumber,
241
+ Porcentaje: b.percentage
242
+ }))
243
+ };
244
+ }
245
+ return data;
246
+ }
247
+ function mapWsfeSalesPoint(raw) {
248
+ const record = raw;
249
+ return {
250
+ number: Number(record.Nro ?? 0),
251
+ ...record.EmisionTipo !== void 0 ? { emissionType: String(record.EmisionTipo) } : {},
252
+ ...record.Bloqueado !== void 0 ? { blocked: String(record.Bloqueado) } : {},
253
+ ...record.FchBaja !== void 0 ? { deletedSince: String(record.FchBaja) } : {}
254
+ };
255
+ }
256
+ function mapWsfeVoucherInfo(raw) {
257
+ return {
258
+ voucherNumber: Number(raw.CbteDesde ?? raw.CbteHasta ?? 0),
259
+ ...raw.CbteFch !== void 0 ? { voucherDate: String(raw.CbteFch) } : {},
260
+ ...raw.PtoVta !== void 0 ? { salesPoint: Number(raw.PtoVta) } : {},
261
+ ...raw.CbteTipo !== void 0 ? { voucherType: Number(raw.CbteTipo) } : {},
262
+ ...raw.ImpTotal !== void 0 ? { totalAmount: Number(raw.ImpTotal) } : {},
263
+ ...raw.Resultado !== void 0 ? { result: String(raw.Resultado) } : {},
264
+ ...raw.CAE !== void 0 ? { cae: String(raw.CAE) } : {},
265
+ ...raw.CAEFchVto !== void 0 ? { caeExpiry: String(raw.CAEFchVto) } : {},
266
+ raw
267
+ };
268
+ }
269
+ function createWsfeAuth(representedTaxId, token, sign) {
270
+ return {
271
+ Token: token,
272
+ Sign: sign,
273
+ Cuit: Number.parseInt(String(representedTaxId), 10)
274
+ };
275
+ }
276
+ function unwrapWsfeOperationResult(operation, response) {
277
+ const operationResponse = response[`${operation}Response`];
278
+ const result = operationResponse?.[`${operation}Result`] ?? response[`${operation}Result`] ?? response;
279
+ if (operation === "FECAESolicitar") {
280
+ const detailResponse = normalizeWsfeDetailResponse(result);
281
+ const resultCode = detailResponse.Resultado;
282
+ if (resultCode && resultCode !== "A") {
283
+ const observationsContainer = detailResponse.Observaciones;
284
+ const observations = normalizeWsfeErrors(observationsContainer?.Obs);
285
+ if (observations.length > 0) {
286
+ const firstObservation = observations[0];
287
+ if (!firstObservation) {
288
+ throw new ArcaServiceError(
289
+ "WSFE returned an empty observation list",
290
+ {
291
+ detail: result
292
+ }
293
+ );
294
+ }
295
+ throw new ArcaServiceError(firstObservation.message, {
296
+ serviceCode: firstObservation.code,
297
+ detail: result
298
+ });
299
+ }
300
+ }
301
+ }
302
+ const errorsContainer = result.Errors;
303
+ const errors = normalizeWsfeErrors(errorsContainer?.Err);
304
+ if (errors.length > 0) {
305
+ const firstError = errors[0];
306
+ if (!firstError) {
307
+ throw new ArcaServiceError("WSFE returned an empty error list", {
308
+ detail: result
309
+ });
310
+ }
311
+ throw new ArcaServiceError(firstError.message, {
312
+ serviceCode: firstError.code,
313
+ detail: result
314
+ });
315
+ }
316
+ return result;
317
+ }
318
+ function normalizeWsfeDetailResponse(result) {
319
+ const detailResponse = result.FeDetResp;
320
+ const rawDetail = detailResponse?.FECAEDetResponse;
321
+ if (Array.isArray(rawDetail)) {
322
+ return rawDetail[0] ?? {};
323
+ }
324
+ return rawDetail ?? {};
325
+ }
326
+ function normalizeWsfeErrors(rawErrors) {
327
+ const entries = Array.isArray(rawErrors) ? rawErrors : rawErrors ? [rawErrors] : [];
328
+ return entries.map((entry) => entry).map((entry) => {
329
+ const code = entry.Code ?? entry.code ?? "N/A";
330
+ const message = entry.Msg ?? entry.msg ?? "Unknown WSFE error";
331
+ return {
332
+ code: String(code),
333
+ message: `(${String(code)}) ${String(message)}`
334
+ };
335
+ });
336
+ }
337
+ export {
338
+ createWsfeService
339
+ };
340
+ //# sourceMappingURL=wsfe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/services/wsfe.ts"],"sourcesContent":["/** Base error class for all ARCA-related errors. */\nexport class ArcaError extends Error {\n readonly code: string;\n override readonly name: string = \"ArcaError\";\n\n constructor(message: string, code = \"ARCA_ERROR\", options?: ErrorOptions) {\n super(message, options);\n this.code = code;\n }\n}\n\n/** Thrown when the ARCA client configuration is missing or invalid. */\nexport class ArcaConfigurationError extends ArcaError {\n override readonly name: string = \"ArcaConfigurationError\";\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"ARCA_CONFIGURATION_ERROR\", options);\n }\n}\n\nclass ArcaNotImplementedError extends ArcaError {\n override readonly name: string = \"ArcaNotImplementedError\";\n\n constructor(message: string, options?: ErrorOptions) {\n super(message, \"ARCA_NOT_IMPLEMENTED\", options);\n }\n}\n\n/** Thrown when an HTTP request to an ARCA endpoint fails at the transport level. */\nexport class ArcaTransportError extends ArcaError {\n override readonly name: string = \"ArcaTransportError\";\n readonly statusCode?: number;\n readonly responseBody?: string;\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n statusCode?: number;\n responseBody?: string;\n }\n ) {\n super(message, \"ARCA_TRANSPORT_ERROR\", options);\n this.statusCode = options?.statusCode;\n this.responseBody = options?.responseBody;\n }\n}\n\n/** Thrown when the SOAP response contains a Fault element. */\nexport class ArcaSoapFaultError extends ArcaError {\n override readonly name: string = \"ArcaSoapFaultError\";\n readonly faultCode?: string;\n readonly detail?: unknown;\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n faultCode?: string;\n detail?: unknown;\n }\n ) {\n super(message, \"ARCA_SOAP_FAULT\", options);\n this.faultCode = options?.faultCode;\n this.detail = options?.detail;\n }\n}\n\n/** Thrown when an ARCA service (WSFE, WSMTXCA, Padron) returns a domain-level error. */\nexport class ArcaServiceError extends ArcaError {\n override readonly name: string = \"ArcaServiceError\";\n readonly serviceCode?: string | number;\n readonly detail?: unknown;\n\n constructor(\n message: string,\n options?: ErrorOptions & {\n serviceCode?: string | number;\n detail?: unknown;\n }\n ) {\n super(message, \"ARCA_SERVICE_ERROR\", options);\n this.serviceCode = options?.serviceCode;\n this.detail = options?.detail;\n }\n}\n","import { ArcaServiceError } from \"../errors\";\nimport type { SoapTransport } from \"../soap\";\nimport type { ArcaClientConfig } from \"../internal/types\";\nimport type { WsaaAuthModule } from \"../wsaa\";\n\n/** An associated voucher referenced by a WSFE invoice request. */\nexport type WsfeAssociatedVoucher = {\n type: number;\n salesPoint: number;\n number: number;\n taxId?: string;\n voucherDate?: string;\n};\n\n/** A tax (tributo) item in a WSFE invoice request. */\nexport type WsfeTax = {\n id: number;\n description?: string;\n baseAmount: number;\n rate: number;\n amount: number;\n};\n\n/** A VAT rate (alícuota IVA) item in a WSFE invoice request. */\nexport type WsfeVatRate = {\n id: number;\n baseAmount: number;\n amount: number;\n};\n\n/** An optional field (campo opcional) in a WSFE invoice request. */\nexport type WsfeOptionalField = {\n id: string;\n value: string;\n};\n\n/** A buyer (comprador) in a WSFE invoice request. */\nexport type WsfeBuyer = {\n documentType: number;\n documentNumber: number;\n percentage: number;\n};\n\n/** Input data for creating a new WSFE voucher via {@link WsfeService.createNextVoucher}. */\nexport type WsfeVoucherInput = {\n salesPoint: number;\n voucherType: number;\n concept: number;\n documentType: number;\n documentNumber: number;\n receiverVatConditionId?: number;\n voucherDate: string;\n totalAmount: number;\n nonTaxableAmount: number;\n netAmount: number;\n exemptAmount: number;\n taxAmount: number;\n vatAmount: number;\n currencyId: string;\n exchangeRate: number;\n serviceStartDate?: string;\n serviceEndDate?: string;\n paymentDueDate?: string;\n associatedVouchers?: WsfeAssociatedVoucher[];\n taxes?: WsfeTax[];\n vatRates?: WsfeVatRate[];\n optionalFields?: WsfeOptionalField[];\n buyers?: WsfeBuyer[];\n};\n\n/** Result of a successful WSFE voucher authorization. */\nexport type WsfeAuthorizationResult = {\n cae: string;\n caeExpiry: string;\n voucherNumber: number;\n raw: Record<string, unknown>;\n};\n\n/** A point-of-sale entry returned by {@link WsfeService.getSalesPoints}. */\nexport type WsfeSalesPoint = {\n number: number;\n emissionType?: string;\n blocked?: string;\n deletedSince?: string;\n};\n\n/** Voucher details returned by {@link WsfeService.getVoucherInfo}. */\nexport type WsfeVoucherInfo = {\n voucherNumber: number;\n voucherDate?: string;\n salesPoint?: number;\n voucherType?: number;\n totalAmount?: number;\n result?: string;\n cae?: string;\n caeExpiry?: string;\n raw: Record<string, unknown>;\n};\n\n/** WSFE electronic invoicing service. */\nexport type WsfeService = {\n /** Authorizes a new voucher by fetching the next number and requesting a CAE. */\n createNextVoucher(input: {\n representedTaxId?: number | string;\n data: WsfeVoucherInput;\n }): Promise<WsfeAuthorizationResult>;\n /** Returns the next available voucher number for the given sales point and type. */\n getLastVoucher(input: {\n representedTaxId?: number | string;\n salesPoint: number;\n voucherType: number;\n forceAuthRefresh?: boolean;\n }): Promise<number>;\n /** Lists all configured points of sale for the taxpayer. */\n getSalesPoints(input: {\n representedTaxId?: number | string;\n forceAuthRefresh?: boolean;\n }): Promise<WsfeSalesPoint[]>;\n /** Retrieves details for a specific voucher. Returns `null` if not found. */\n getVoucherInfo(input: {\n representedTaxId?: number | string;\n number: number;\n salesPoint: number;\n voucherType: number;\n }): Promise<WsfeVoucherInfo | null>;\n};\n\nexport type CreateWsfeServiceOptions = {\n config: ArcaClientConfig;\n auth: WsaaAuthModule;\n soap: SoapTransport;\n};\n\n/** Creates a WSFE service instance wired with authentication and SOAP transport. */\nexport function createWsfeService(\n options: CreateWsfeServiceOptions\n): WsfeService {\n async function getLastVoucher({\n representedTaxId,\n salesPoint,\n voucherType,\n forceAuthRefresh,\n }: {\n representedTaxId?: number | string;\n salesPoint: number;\n voucherType: number;\n forceAuthRefresh?: boolean;\n }) {\n const auth = await options.auth.login(\"wsfe\", {\n representedTaxId,\n forceRefresh: forceAuthRefresh,\n });\n const response = await options.soap.execute<\n Record<string, unknown>,\n Record<string, unknown>\n >({\n service: \"wsfe\",\n operation: \"FECompUltimoAutorizado\",\n body: {\n Auth: createWsfeAuth(\n representedTaxId ?? options.config.taxId,\n auth.token,\n auth.sign\n ),\n PtoVta: salesPoint,\n CbteTipo: voucherType,\n },\n });\n const result = unwrapWsfeOperationResult(\n \"FECompUltimoAutorizado\",\n response.result\n );\n return Number(result.CbteNro ?? 0) + 1;\n }\n\n return {\n async createNextVoucher({ representedTaxId, data }) {\n const voucherNumber = await getLastVoucher({\n representedTaxId,\n salesPoint: data.salesPoint,\n voucherType: data.voucherType,\n });\n\n const requestData = mapWsfeVoucherInput(data, voucherNumber);\n\n const auth = await options.auth.login(\"wsfe\", { representedTaxId });\n const response = await options.soap.execute<\n Record<string, unknown>,\n Record<string, unknown>\n >({\n service: \"wsfe\",\n operation: \"FECAESolicitar\",\n body: {\n Auth: createWsfeAuth(\n representedTaxId ?? options.config.taxId,\n auth.token,\n auth.sign\n ),\n FeCAEReq: {\n FeCabReq: {\n CantReg: 1,\n PtoVta: data.salesPoint,\n CbteTipo: data.voucherType,\n },\n FeDetReq: {\n FECAEDetRequest: requestData,\n },\n },\n },\n });\n\n const result = unwrapWsfeOperationResult(\n \"FECAESolicitar\",\n response.result\n );\n const detailResponse = normalizeWsfeDetailResponse(result);\n const cae = detailResponse.CAE;\n const caeExpiry = detailResponse.CAEFchVto;\n\n if (typeof cae !== \"string\" || typeof caeExpiry !== \"string\") {\n throw new ArcaServiceError(\n \"WSFE did not return CAE authorization data\",\n { detail: result }\n );\n }\n\n return {\n cae,\n caeExpiry: String(caeExpiry),\n voucherNumber,\n raw: result,\n };\n },\n getLastVoucher,\n async getSalesPoints({ representedTaxId, forceAuthRefresh }) {\n const auth = await options.auth.login(\"wsfe\", {\n representedTaxId,\n forceRefresh: forceAuthRefresh,\n });\n const response = await options.soap.execute<\n Record<string, unknown>,\n Record<string, unknown>\n >({\n service: \"wsfe\",\n operation: \"FEParamGetPtosVenta\",\n body: {\n Auth: createWsfeAuth(\n representedTaxId ?? options.config.taxId,\n auth.token,\n auth.sign\n ),\n },\n });\n const result = unwrapWsfeOperationResult(\n \"FEParamGetPtosVenta\",\n response.result\n );\n const resultGet = result.ResultGet as Record<string, unknown> | undefined;\n const rawPoints = resultGet?.PtoVenta;\n if (!rawPoints) {\n return [];\n }\n const entries = Array.isArray(rawPoints) ? rawPoints : [rawPoints];\n return entries.map(mapWsfeSalesPoint);\n },\n async getVoucherInfo({\n representedTaxId,\n number,\n salesPoint,\n voucherType,\n }) {\n const auth = await options.auth.login(\"wsfe\", { representedTaxId });\n const response = await options.soap.execute<\n Record<string, unknown>,\n Record<string, unknown>\n >({\n service: \"wsfe\",\n operation: \"FECompConsultar\",\n body: {\n Auth: createWsfeAuth(\n representedTaxId ?? options.config.taxId,\n auth.token,\n auth.sign\n ),\n FeCompConsReq: {\n CbteNro: number,\n PtoVta: salesPoint,\n CbteTipo: voucherType,\n },\n },\n });\n const result = unwrapWsfeOperationResult(\n \"FECompConsultar\",\n response.result\n );\n const raw = (result.ResultGet as Record<string, unknown> | null) ?? null;\n if (!raw) {\n return null;\n }\n return mapWsfeVoucherInfo(raw);\n },\n };\n}\n\nfunction mapWsfeVoucherInput(\n input: WsfeVoucherInput,\n voucherNumber: number\n): Record<string, unknown> {\n const data: Record<string, unknown> = {\n Concepto: input.concept,\n DocTipo: input.documentType,\n DocNro: input.documentNumber,\n CbteDesde: voucherNumber,\n CbteHasta: voucherNumber,\n CbteFch: input.voucherDate,\n ImpTotal: input.totalAmount,\n ImpTotConc: input.nonTaxableAmount,\n ImpNeto: input.netAmount,\n ImpOpEx: input.exemptAmount,\n ImpTrib: input.taxAmount,\n ImpIVA: input.vatAmount,\n MonId: input.currencyId,\n MonCotiz: input.exchangeRate,\n PtoVta: input.salesPoint,\n CbteTipo: input.voucherType,\n };\n\n if (input.receiverVatConditionId !== undefined) {\n data.CondicionIVAReceptorId = input.receiverVatConditionId;\n }\n\n if (input.serviceStartDate !== undefined) {\n data.FchServDesde = input.serviceStartDate;\n }\n if (input.serviceEndDate !== undefined) {\n data.FchServHasta = input.serviceEndDate;\n }\n if (input.paymentDueDate !== undefined) {\n data.FchVtoPago = input.paymentDueDate;\n }\n\n if (input.associatedVouchers) {\n data.CbtesAsoc = {\n CbteAsoc: input.associatedVouchers.map((v) => ({\n Tipo: v.type,\n PtoVta: v.salesPoint,\n Nro: v.number,\n ...(v.taxId !== undefined ? { Cuit: v.taxId } : {}),\n ...(v.voucherDate !== undefined ? { CbteFch: v.voucherDate } : {}),\n })),\n };\n }\n\n if (input.taxes) {\n data.Tributos = {\n Tributo: input.taxes.map((t) => ({\n Id: t.id,\n ...(t.description !== undefined ? { Desc: t.description } : {}),\n BaseImp: t.baseAmount,\n Alic: t.rate,\n Importe: t.amount,\n })),\n };\n }\n\n if (input.vatRates) {\n data.Iva = {\n AlicIva: input.vatRates.map((v) => ({\n Id: v.id,\n BaseImp: v.baseAmount,\n Importe: v.amount,\n })),\n };\n }\n\n if (input.optionalFields) {\n data.Opcionales = {\n Opcional: input.optionalFields.map((o) => ({\n Id: o.id,\n Valor: o.value,\n })),\n };\n }\n\n if (input.buyers) {\n data.Compradores = {\n Comprador: input.buyers.map((b) => ({\n DocTipo: b.documentType,\n DocNro: b.documentNumber,\n Porcentaje: b.percentage,\n })),\n };\n }\n\n return data;\n}\n\nfunction mapWsfeSalesPoint(raw: unknown): WsfeSalesPoint {\n const record = raw as Record<string, unknown>;\n return {\n number: Number(record.Nro ?? 0),\n ...(record.EmisionTipo !== undefined\n ? { emissionType: String(record.EmisionTipo) }\n : {}),\n ...(record.Bloqueado !== undefined\n ? { blocked: String(record.Bloqueado) }\n : {}),\n ...(record.FchBaja !== undefined\n ? { deletedSince: String(record.FchBaja) }\n : {}),\n };\n}\n\nfunction mapWsfeVoucherInfo(raw: Record<string, unknown>): WsfeVoucherInfo {\n return {\n voucherNumber: Number(raw.CbteDesde ?? raw.CbteHasta ?? 0),\n ...(raw.CbteFch !== undefined ? { voucherDate: String(raw.CbteFch) } : {}),\n ...(raw.PtoVta !== undefined ? { salesPoint: Number(raw.PtoVta) } : {}),\n ...(raw.CbteTipo !== undefined\n ? { voucherType: Number(raw.CbteTipo) }\n : {}),\n ...(raw.ImpTotal !== undefined\n ? { totalAmount: Number(raw.ImpTotal) }\n : {}),\n ...(raw.Resultado !== undefined ? { result: String(raw.Resultado) } : {}),\n ...(raw.CAE !== undefined ? { cae: String(raw.CAE) } : {}),\n ...(raw.CAEFchVto !== undefined\n ? { caeExpiry: String(raw.CAEFchVto) }\n : {}),\n raw,\n };\n}\n\nfunction createWsfeAuth(\n representedTaxId: number | string,\n token: string,\n sign: string\n) {\n return {\n Token: token,\n Sign: sign,\n Cuit: Number.parseInt(String(representedTaxId), 10),\n };\n}\n\nfunction unwrapWsfeOperationResult(\n operation: string,\n response: Record<string, unknown>\n) {\n const operationResponse = response[`${operation}Response`] as\n | Record<string, unknown>\n | undefined;\n const result = (operationResponse?.[`${operation}Result`] ??\n response[`${operation}Result`] ??\n response) as Record<string, unknown>;\n\n if (operation === \"FECAESolicitar\") {\n const detailResponse = normalizeWsfeDetailResponse(result);\n const resultCode = detailResponse.Resultado;\n if (resultCode && resultCode !== \"A\") {\n const observationsContainer = detailResponse.Observaciones as\n | Record<string, unknown>\n | undefined;\n const observations = normalizeWsfeErrors(observationsContainer?.Obs);\n if (observations.length > 0) {\n const firstObservation = observations[0];\n if (!firstObservation) {\n throw new ArcaServiceError(\n \"WSFE returned an empty observation list\",\n {\n detail: result,\n }\n );\n }\n throw new ArcaServiceError(firstObservation.message, {\n serviceCode: firstObservation.code,\n detail: result,\n });\n }\n }\n }\n\n const errorsContainer = result.Errors as Record<string, unknown> | undefined;\n const errors = normalizeWsfeErrors(errorsContainer?.Err);\n if (errors.length > 0) {\n const firstError = errors[0];\n if (!firstError) {\n throw new ArcaServiceError(\"WSFE returned an empty error list\", {\n detail: result,\n });\n }\n throw new ArcaServiceError(firstError.message, {\n serviceCode: firstError.code,\n detail: result,\n });\n }\n\n return result;\n}\n\nfunction normalizeWsfeDetailResponse(result: Record<string, unknown>) {\n const detailResponse = result.FeDetResp as\n | Record<string, unknown>\n | undefined;\n const rawDetail = detailResponse?.FECAEDetResponse;\n\n if (Array.isArray(rawDetail)) {\n return (rawDetail[0] as Record<string, unknown>) ?? {};\n }\n\n return (rawDetail as Record<string, unknown> | undefined) ?? {};\n}\n\nfunction normalizeWsfeErrors(rawErrors: unknown) {\n const entries = Array.isArray(rawErrors)\n ? rawErrors\n : rawErrors\n ? [rawErrors]\n : [];\n\n return entries\n .map((entry) => entry as Record<string, unknown>)\n .map((entry) => {\n const code = entry.Code ?? entry.code ?? \"N/A\";\n const message = entry.Msg ?? entry.msg ?? \"Unknown WSFE error\";\n return {\n code: String(code),\n message: `(${String(code)}) ${String(message)}`,\n };\n });\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,53 @@
1
+ import { W as WsaaAuthModule, S as SoapTransport } from './index-vWZOjFDO.js';
2
+ import { e as ArcaRepresentedTaxId, A as ArcaClientConfig } from './types-DWsYue4B.js';
3
+
4
+ /** Result of a successful WSMTXCA voucher authorization. */
5
+ type WsmtxcaAuthorizationResult = {
6
+ cae: string;
7
+ caeExpiry?: string;
8
+ voucherNumber: number;
9
+ messages: string[];
10
+ raw: Record<string, unknown>;
11
+ };
12
+ /** Result of querying the last authorized voucher number. */
13
+ type WsmtxcaLastAuthorizedVoucherResult = {
14
+ voucherNumber: number;
15
+ raw: Record<string, unknown>;
16
+ };
17
+ /** Result of looking up a specific WSMTXCA voucher. */
18
+ type WsmtxcaVoucherLookupResult = {
19
+ invoiceDate: string;
20
+ voucher: Record<string, unknown>;
21
+ messages: string[];
22
+ raw: Record<string, unknown>;
23
+ };
24
+ /** WSMTXCA electronic invoicing service (Factura de Crédito Electrónica). */
25
+ type WsmtxcaService = {
26
+ /** Authorizes a voucher and returns the CAE. */
27
+ authorizeVoucher(input: {
28
+ representedTaxId?: ArcaRepresentedTaxId;
29
+ data: Record<string, unknown>;
30
+ }): Promise<WsmtxcaAuthorizationResult>;
31
+ /** Returns the last authorized voucher number for the given sales point and type. */
32
+ getLastAuthorizedVoucher(input: {
33
+ representedTaxId?: ArcaRepresentedTaxId;
34
+ voucherType: number;
35
+ salesPoint: number;
36
+ }): Promise<WsmtxcaLastAuthorizedVoucherResult>;
37
+ /** Retrieves details for a specific voucher. */
38
+ getVoucher(input: {
39
+ representedTaxId?: ArcaRepresentedTaxId;
40
+ voucherType: number;
41
+ salesPoint: number;
42
+ voucherNumber: number;
43
+ }): Promise<WsmtxcaVoucherLookupResult>;
44
+ };
45
+ type CreateWsmtxcaServiceOptions = {
46
+ config: ArcaClientConfig;
47
+ auth: WsaaAuthModule;
48
+ soap: SoapTransport;
49
+ };
50
+ /** Creates a WSMTXCA service instance wired with authentication and SOAP transport. */
51
+ declare function createWsmtxcaService(options: CreateWsmtxcaServiceOptions): WsmtxcaService;
52
+
53
+ export { type CreateWsmtxcaServiceOptions, type WsmtxcaAuthorizationResult, type WsmtxcaLastAuthorizedVoucherResult, type WsmtxcaService, type WsmtxcaVoucherLookupResult, createWsmtxcaService };
@@ -0,0 +1,247 @@
1
+ // src/errors.ts
2
+ var ArcaError = class extends Error {
3
+ code;
4
+ name = "ArcaError";
5
+ constructor(message, code = "ARCA_ERROR", options) {
6
+ super(message, options);
7
+ this.code = code;
8
+ }
9
+ };
10
+ var ArcaServiceError = class extends ArcaError {
11
+ name = "ArcaServiceError";
12
+ serviceCode;
13
+ detail;
14
+ constructor(message, options) {
15
+ super(message, "ARCA_SERVICE_ERROR", options);
16
+ this.serviceCode = options?.serviceCode;
17
+ this.detail = options?.detail;
18
+ }
19
+ };
20
+
21
+ // src/services/wsmtxca.ts
22
+ function createWsmtxcaService(options) {
23
+ return {
24
+ async authorizeVoucher({ representedTaxId, data }) {
25
+ const auth = await options.auth.login("wsmtxca", { representedTaxId });
26
+ const response = await options.soap.execute({
27
+ service: "wsmtxca",
28
+ operation: "autorizarComprobante",
29
+ bodyElementName: "autorizarComprobanteRequest",
30
+ bodyElementNamespaceMode: "prefix",
31
+ body: {
32
+ authRequest: createWsmtxcaAuth(
33
+ representedTaxId ?? options.config.taxId,
34
+ auth.token,
35
+ auth.sign
36
+ ),
37
+ ...data
38
+ }
39
+ });
40
+ const raw = unwrapWsmtxcaOperationResponse(
41
+ response.result,
42
+ "autorizarComprobante"
43
+ );
44
+ const authorizationPayload = extractWsmtxcaAuthorizationPayload(raw);
45
+ const messages = extractWsmtxcaMessages(raw);
46
+ const resultado = raw.resultado ?? authorizationPayload.resultado;
47
+ const caeValue = authorizationPayload.CAE ?? authorizationPayload.codigoAutorizacion ?? raw.codigoAutorizacion;
48
+ if (resultado === "R" || caeValue == null) {
49
+ throw new ArcaServiceError(
50
+ messages.join(" | ") || "WSMTXCA rejected the voucher authorization",
51
+ { detail: raw }
52
+ );
53
+ }
54
+ return {
55
+ cae: String(caeValue),
56
+ caeExpiry: normalizeWsmtxcaResponseDate(
57
+ authorizationPayload.fechaVencimientoCAE ?? authorizationPayload.fechaVencimiento ?? raw.fechaVencimiento
58
+ ),
59
+ voucherNumber: parseWsmtxcaVoucherNumber(
60
+ authorizationPayload.numeroComprobante ?? raw.numeroComprobante,
61
+ "WSMTXCA did not return the authorized voucher number",
62
+ raw
63
+ ),
64
+ messages,
65
+ raw
66
+ };
67
+ },
68
+ async getLastAuthorizedVoucher({
69
+ representedTaxId,
70
+ voucherType,
71
+ salesPoint
72
+ }) {
73
+ const auth = await options.auth.login("wsmtxca", { representedTaxId });
74
+ const response = await options.soap.execute({
75
+ service: "wsmtxca",
76
+ operation: "consultarUltimoComprobanteAutorizado",
77
+ bodyElementName: "consultarUltimoComprobanteAutorizadoRequest",
78
+ bodyElementNamespaceMode: "prefix",
79
+ body: {
80
+ authRequest: createWsmtxcaAuth(
81
+ representedTaxId ?? options.config.taxId,
82
+ auth.token,
83
+ auth.sign
84
+ ),
85
+ consultaUltimoComprobanteAutorizadoRequest: {
86
+ codigoTipoComprobante: voucherType,
87
+ numeroPuntoVenta: salesPoint
88
+ }
89
+ }
90
+ });
91
+ const raw = unwrapWsmtxcaOperationResponse(
92
+ response.result,
93
+ "consultarUltimoComprobanteAutorizado"
94
+ );
95
+ return {
96
+ voucherNumber: parseWsmtxcaVoucherNumber(
97
+ raw.numeroComprobante ?? raw.cbteNro ?? raw.nroComprobante,
98
+ extractWsmtxcaMessages(raw).join(" | ") || "WSMTXCA did not return the last authorized voucher number",
99
+ raw
100
+ ),
101
+ raw
102
+ };
103
+ },
104
+ async getVoucher({
105
+ representedTaxId,
106
+ voucherType,
107
+ salesPoint,
108
+ voucherNumber
109
+ }) {
110
+ const auth = await options.auth.login("wsmtxca", { representedTaxId });
111
+ const response = await options.soap.execute({
112
+ service: "wsmtxca",
113
+ operation: "consultarComprobante",
114
+ bodyElementName: "consultarComprobanteRequest",
115
+ bodyElementNamespaceMode: "prefix",
116
+ body: {
117
+ authRequest: createWsmtxcaAuth(
118
+ representedTaxId ?? options.config.taxId,
119
+ auth.token,
120
+ auth.sign
121
+ ),
122
+ consultaComprobanteRequest: {
123
+ codigoTipoComprobante: voucherType,
124
+ numeroPuntoVenta: salesPoint,
125
+ numeroComprobante: voucherNumber
126
+ }
127
+ }
128
+ });
129
+ const raw = unwrapWsmtxcaOperationResponse(
130
+ response.result,
131
+ "consultarComprobante"
132
+ );
133
+ const voucher = extractWsmtxcaVoucherPayload(raw);
134
+ const messages = extractWsmtxcaMessages(raw);
135
+ const invoiceDate = normalizeWsmtxcaResponseDate(
136
+ voucher.fechaEmision ?? voucher.fecha ?? voucher.CbteFch
137
+ );
138
+ if (!invoiceDate) {
139
+ throw new ArcaServiceError(
140
+ messages[0] ?? "WSMTXCA did not return the voucher issue date",
141
+ { detail: raw }
142
+ );
143
+ }
144
+ return {
145
+ invoiceDate,
146
+ voucher,
147
+ messages,
148
+ raw
149
+ };
150
+ }
151
+ };
152
+ }
153
+ function createWsmtxcaAuth(representedTaxId, token, sign) {
154
+ return {
155
+ token,
156
+ sign,
157
+ cuitRepresentada: Number.parseInt(String(representedTaxId), 10)
158
+ };
159
+ }
160
+ function toRecord(value) {
161
+ return value && typeof value === "object" ? value : void 0;
162
+ }
163
+ function unwrapWsmtxcaOperationResponse(response, operation) {
164
+ const responseRecord = toRecord(response) ?? {};
165
+ if (operation === "autorizarComprobante") {
166
+ return toRecord(responseRecord.autorizarComprobanteResponse) ?? toRecord(responseRecord.autorizarComprobanteResult) ?? toRecord(responseRecord.comprobanteCAEResponse) ?? toRecord(responseRecord.comprobanteCAEReponse) ?? responseRecord;
167
+ }
168
+ if (operation === "consultarComprobante") {
169
+ return toRecord(responseRecord.consultarComprobanteResponse) ?? toRecord(responseRecord.consultaComprobanteResponse) ?? toRecord(responseRecord.consultarComprobanteResult) ?? responseRecord;
170
+ }
171
+ return toRecord(responseRecord.consultarUltimoComprobanteAutorizadoResponse) ?? toRecord(responseRecord.consultaUltimoComprobanteAutorizadoResponse) ?? toRecord(responseRecord.consultarUltimoComprobanteAutorizadoResult) ?? responseRecord;
172
+ }
173
+ function extractWsmtxcaAuthorizationPayload(raw) {
174
+ return toRecord(raw.comprobanteResponse) ?? toRecord(raw.comprobanteCAEResponse) ?? toRecord(raw.comprobanteCAEReponse) ?? raw;
175
+ }
176
+ function extractWsmtxcaVoucherPayload(raw) {
177
+ return toRecord(raw.comprobanteResponse) ?? toRecord(raw.comprobante) ?? toRecord(raw.cmp) ?? raw;
178
+ }
179
+ function extractWsmtxcaMessages(raw) {
180
+ const rawErrors = raw.arrayErrores;
181
+ const rawObservations = raw.arrayObservaciones;
182
+ const toEntries = (value) => {
183
+ if (!value) {
184
+ return [];
185
+ }
186
+ if (Array.isArray(value)) {
187
+ return value;
188
+ }
189
+ if (typeof value === "object") {
190
+ return [value];
191
+ }
192
+ return [];
193
+ };
194
+ const errors = toEntries(rawErrors?.codigoDescripcion).map((entry) => {
195
+ const code = entry.codigo == null ? "N/A" : String(entry.codigo);
196
+ const description = entry.descripcion == null ? "Unknown WSMTXCA error" : String(entry.descripcion);
197
+ return `Error ${code}: ${description}`;
198
+ });
199
+ const observations = toEntries(rawObservations?.codigoDescripcion).map(
200
+ (entry) => {
201
+ const code = entry.codigo == null ? "N/A" : String(entry.codigo);
202
+ const description = entry.descripcion == null ? "" : String(entry.descripcion);
203
+ return `Obs ${code}: ${description}`.trim();
204
+ }
205
+ );
206
+ return [...errors, ...observations];
207
+ }
208
+ function parseWsmtxcaVoucherNumber(value, message, detail) {
209
+ const parsed = Number.parseInt(String(value ?? ""), 10);
210
+ if (!Number.isFinite(parsed) || parsed <= 0) {
211
+ throw new ArcaServiceError(message, { detail });
212
+ }
213
+ return parsed;
214
+ }
215
+ function normalizeWsmtxcaResponseDate(value) {
216
+ if (typeof value === "number" && Number.isInteger(value)) {
217
+ return formatCompactDateToIso(value);
218
+ }
219
+ if (typeof value !== "string") {
220
+ return void 0;
221
+ }
222
+ const trimmed = value.trim();
223
+ if (!trimmed) {
224
+ return void 0;
225
+ }
226
+ if (/^\d{8}$/.test(trimmed)) {
227
+ return formatCompactDateToIso(Number.parseInt(trimmed, 10));
228
+ }
229
+ if (/^\d{4}-\d{2}-\d{2}/.test(trimmed)) {
230
+ return trimmed.slice(0, 10);
231
+ }
232
+ return void 0;
233
+ }
234
+ function formatCompactDateToIso(dateValue) {
235
+ if (!dateValue) {
236
+ return void 0;
237
+ }
238
+ const raw = String(dateValue);
239
+ if (raw.length !== 8) {
240
+ return void 0;
241
+ }
242
+ return `${raw.slice(0, 4)}-${raw.slice(4, 6)}-${raw.slice(6, 8)}`;
243
+ }
244
+ export {
245
+ createWsmtxcaService
246
+ };
247
+ //# sourceMappingURL=wsmtxca.js.map