arca-sdk 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -37,7 +37,8 @@ __export(index_exports, {
37
37
  TipoComprobante: () => TipoComprobante,
38
38
  TipoDocumento: () => TipoDocumento,
39
39
  WsaaService: () => WsaaService,
40
- WsfeService: () => WsfeService
40
+ WsfeService: () => WsfeService,
41
+ generarUrlQR: () => generarUrlQR
41
42
  });
42
43
  module.exports = __toCommonJS(index_exports);
43
44
 
@@ -381,21 +382,32 @@ var TipoDocumento = /* @__PURE__ */ ((TipoDocumento2) => {
381
382
  })(TipoDocumento || {});
382
383
 
383
384
  // src/utils/calculations.ts
384
- function calcularSubtotal(items) {
385
+ function calcularSubtotal(items, incluyeIva = false) {
385
386
  return items.reduce((sum, item) => {
386
- return sum + item.cantidad * item.precioUnitario;
387
+ let precioNeto = item.precioUnitario;
388
+ if (incluyeIva && item.alicuotaIva) {
389
+ precioNeto = item.precioUnitario / (1 + item.alicuotaIva / 100);
390
+ }
391
+ return sum + item.cantidad * precioNeto;
387
392
  }, 0);
388
393
  }
389
- function calcularIVA(items) {
394
+ function calcularIVA(items, incluyeIva = false) {
390
395
  return items.reduce((sum, item) => {
391
- const subtotal = item.cantidad * item.precioUnitario;
392
396
  const alicuota = item.alicuotaIva || 0;
393
- return sum + subtotal * alicuota / 100;
397
+ let precioNeto = item.precioUnitario;
398
+ if (incluyeIva && alicuota) {
399
+ precioNeto = item.precioUnitario / (1 + alicuota / 100);
400
+ }
401
+ const subtotalNeto = item.cantidad * precioNeto;
402
+ return sum + subtotalNeto * alicuota / 100;
394
403
  }, 0);
395
404
  }
396
- function calcularTotal(items) {
397
- const subtotal = calcularSubtotal(items);
398
- const iva = calcularIVA(items);
405
+ function calcularTotal(items, incluyeIva = false) {
406
+ if (incluyeIva) {
407
+ return items.reduce((sum, item) => sum + item.cantidad * item.precioUnitario, 0);
408
+ }
409
+ const subtotal = calcularSubtotal(items, false);
410
+ const iva = calcularIVA(items, false);
399
411
  return subtotal + iva;
400
412
  }
401
413
  function redondear(valor) {
@@ -466,14 +478,16 @@ var WsfeService = class {
466
478
  */
467
479
  async emitirFacturaB(params) {
468
480
  this.validateItemsWithIVA(params.items);
469
- const ivaData = this.calcularIVAPorAlicuota(params.items);
481
+ const incluyeIva = params.incluyeIva || false;
482
+ const ivaData = this.calcularIVAPorAlicuota(params.items, incluyeIva);
470
483
  return this.emitirComprobante({
471
484
  tipo: 6 /* FACTURA_B */,
472
485
  concepto: params.concepto || 1 /* PRODUCTOS */,
473
486
  items: params.items,
474
487
  comprador: params.comprador,
475
488
  fecha: params.fecha,
476
- ivaData
489
+ ivaData,
490
+ incluyeIva
477
491
  });
478
492
  }
479
493
  /**
@@ -482,14 +496,16 @@ var WsfeService = class {
482
496
  */
483
497
  async emitirFacturaA(params) {
484
498
  this.validateItemsWithIVA(params.items);
485
- const ivaData = this.calcularIVAPorAlicuota(params.items);
499
+ const incluyeIva = params.incluyeIva || false;
500
+ const ivaData = this.calcularIVAPorAlicuota(params.items, incluyeIva);
486
501
  return this.emitirComprobante({
487
502
  tipo: 1 /* FACTURA_A */,
488
503
  concepto: params.concepto || 1 /* PRODUCTOS */,
489
504
  items: params.items,
490
505
  comprador: params.comprador,
491
506
  fecha: params.fecha,
492
- ivaData
507
+ ivaData,
508
+ incluyeIva
493
509
  });
494
510
  }
495
511
  /**
@@ -513,11 +529,15 @@ var WsfeService = class {
513
529
  * Calcula IVA agrupado por alícuota
514
530
  * ARCA requiere esto para Factura B/A
515
531
  */
516
- calcularIVAPorAlicuota(items) {
532
+ calcularIVAPorAlicuota(items, incluyeIva = false) {
517
533
  const porAlicuota = /* @__PURE__ */ new Map();
518
534
  items.forEach((item) => {
519
535
  const alicuota = item.alicuotaIva || 0;
520
- const base = item.cantidad * item.precioUnitario;
536
+ let precioNeto = item.precioUnitario;
537
+ if (incluyeIva && alicuota) {
538
+ precioNeto = item.precioUnitario / (1 + alicuota / 100);
539
+ }
540
+ const base = item.cantidad * precioNeto;
521
541
  const importe = base * alicuota / 100;
522
542
  const actual = porAlicuota.get(alicuota) || { base: 0, importe: 0 };
523
543
  porAlicuota.set(alicuota, {
@@ -558,9 +578,10 @@ var WsfeService = class {
558
578
  let subtotal = total;
559
579
  let iva = 0;
560
580
  if (request.items && request.items.length > 0) {
561
- subtotal = redondear(calcularSubtotal(request.items));
562
- iva = redondear(calcularIVA(request.items));
563
- total = redondear(calcularTotal(request.items));
581
+ const incluyeIva = request.incluyeIva || false;
582
+ subtotal = redondear(calcularSubtotal(request.items, incluyeIva));
583
+ iva = redondear(calcularIVA(request.items, incluyeIva));
584
+ total = redondear(calcularTotal(request.items, incluyeIva));
564
585
  }
565
586
  if (total <= 0) {
566
587
  throw new ArcaValidationError("El monto total debe ser mayor a 0");
@@ -756,6 +777,36 @@ var WsfeService = class {
756
777
  };
757
778
  }
758
779
  };
780
+
781
+ // src/utils/qr.ts
782
+ function generarUrlQR(caeResponse, cuitEmisor, total, comprador) {
783
+ const fDate = caeResponse.fecha;
784
+ const fechaFormat = fDate.length === 8 ? `${fDate.substring(0, 4)}-${fDate.substring(4, 6)}-${fDate.substring(6, 8)}` : fDate;
785
+ const docTipo = comprador?.tipoDocumento || 99 /* CONSUMIDOR_FINAL */;
786
+ const docNro = comprador?.nroDocumento ? parseInt(comprador.nroDocumento, 10) : 0;
787
+ const qrData = {
788
+ ver: 1,
789
+ // Versión estándar exigida por AFIP
790
+ fecha: fechaFormat,
791
+ cuit: parseInt(cuitEmisor, 10),
792
+ ptoVta: caeResponse.puntoVenta,
793
+ tipoCmp: caeResponse.tipoComprobante,
794
+ nroCmp: caeResponse.nroComprobante,
795
+ importe: parseFloat(total.toFixed(2)),
796
+ moneda: "PES",
797
+ // Por defecto PES (Pesos Argentinos)
798
+ ctz: 1,
799
+ // Cotización (siempre 1 para PES)
800
+ tipoDocRec: docTipo,
801
+ nroDocRec: docNro,
802
+ tipoCodAut: "E",
803
+ // 'E' para comprobantes electrónicos
804
+ codAut: parseInt(caeResponse.cae, 10)
805
+ };
806
+ const jsonString = JSON.stringify(qrData);
807
+ let base64 = typeof Buffer !== "undefined" ? Buffer.from(jsonString).toString("base64") : btoa(jsonString);
808
+ return `https://www.afip.gob.ar/fe/qr/?p=${base64}`;
809
+ }
759
810
  // Annotate the CommonJS export names for ESM import in node:
760
811
  0 && (module.exports = {
761
812
  ArcaAuthError,
@@ -765,5 +816,6 @@ var WsfeService = class {
765
816
  TipoComprobante,
766
817
  TipoDocumento,
767
818
  WsaaService,
768
- WsfeService
819
+ WsfeService,
820
+ generarUrlQR
769
821
  });
package/dist/index.d.cts CHANGED
@@ -192,6 +192,8 @@ interface EmitirFacturaRequest {
192
192
  baseImponible: number;
193
193
  importe: number;
194
194
  }[];
195
+ /** Indica si los preciosUnitarios de los items YA incluyen el IVA (Precio Final). Defecto: false */
196
+ incluyeIva?: boolean;
195
197
  /** Fecha del comprobante (default: hoy) */
196
198
  fecha?: Date;
197
199
  }
@@ -277,6 +279,7 @@ declare class WsfeService {
277
279
  comprador: Comprador;
278
280
  concepto?: Concepto;
279
281
  fecha?: Date;
282
+ incluyeIva?: boolean;
280
283
  }): Promise<CAEResponse>;
281
284
  /**
282
285
  * Emite una Factura A (RI a RI)
@@ -287,6 +290,7 @@ declare class WsfeService {
287
290
  comprador: Comprador;
288
291
  concepto?: Concepto;
289
292
  fecha?: Date;
293
+ incluyeIva?: boolean;
290
294
  }): Promise<CAEResponse>;
291
295
  /**
292
296
  * Valida que todos los items tengan alícuota IVA definida
@@ -323,4 +327,15 @@ declare class WsfeService {
323
327
  private parseCAEResponse;
324
328
  }
325
329
 
326
- export { ArcaAuthError, type ArcaConfig, ArcaError, ArcaValidationError, type CAEResponse, type Comprador, Concepto, type EmitirFacturaRequest, type Environment, type FacturaItem, type LoginTicket, TipoComprobante, TipoDocumento, type WsaaConfig, WsaaService, type WsfeConfig, WsfeService };
330
+ /**
331
+ * Genera la URL completa con el código QR para un comprobante emitido
332
+ *
333
+ * @param caeResponse Respuesta obtenida al emitir la factura (CAEResponse)
334
+ * @param cuitEmisor Tu CUIT (11 dígitos, sin guiones)
335
+ * @param total Importe total del comprobante
336
+ * @param comprador Datos del comprador (opcional, si no se pasa asume Consumidor Final)
337
+ * @returns La URL lista para embeber en un generador de QR
338
+ */
339
+ declare function generarUrlQR(caeResponse: CAEResponse, cuitEmisor: string, total: number, comprador?: Comprador): string;
340
+
341
+ export { ArcaAuthError, type ArcaConfig, ArcaError, ArcaValidationError, type CAEResponse, type Comprador, Concepto, type EmitirFacturaRequest, type Environment, type FacturaItem, type LoginTicket, TipoComprobante, TipoDocumento, type WsaaConfig, WsaaService, type WsfeConfig, WsfeService, generarUrlQR };
package/dist/index.d.ts CHANGED
@@ -192,6 +192,8 @@ interface EmitirFacturaRequest {
192
192
  baseImponible: number;
193
193
  importe: number;
194
194
  }[];
195
+ /** Indica si los preciosUnitarios de los items YA incluyen el IVA (Precio Final). Defecto: false */
196
+ incluyeIva?: boolean;
195
197
  /** Fecha del comprobante (default: hoy) */
196
198
  fecha?: Date;
197
199
  }
@@ -277,6 +279,7 @@ declare class WsfeService {
277
279
  comprador: Comprador;
278
280
  concepto?: Concepto;
279
281
  fecha?: Date;
282
+ incluyeIva?: boolean;
280
283
  }): Promise<CAEResponse>;
281
284
  /**
282
285
  * Emite una Factura A (RI a RI)
@@ -287,6 +290,7 @@ declare class WsfeService {
287
290
  comprador: Comprador;
288
291
  concepto?: Concepto;
289
292
  fecha?: Date;
293
+ incluyeIva?: boolean;
290
294
  }): Promise<CAEResponse>;
291
295
  /**
292
296
  * Valida que todos los items tengan alícuota IVA definida
@@ -323,4 +327,15 @@ declare class WsfeService {
323
327
  private parseCAEResponse;
324
328
  }
325
329
 
326
- export { ArcaAuthError, type ArcaConfig, ArcaError, ArcaValidationError, type CAEResponse, type Comprador, Concepto, type EmitirFacturaRequest, type Environment, type FacturaItem, type LoginTicket, TipoComprobante, TipoDocumento, type WsaaConfig, WsaaService, type WsfeConfig, WsfeService };
330
+ /**
331
+ * Genera la URL completa con el código QR para un comprobante emitido
332
+ *
333
+ * @param caeResponse Respuesta obtenida al emitir la factura (CAEResponse)
334
+ * @param cuitEmisor Tu CUIT (11 dígitos, sin guiones)
335
+ * @param total Importe total del comprobante
336
+ * @param comprador Datos del comprador (opcional, si no se pasa asume Consumidor Final)
337
+ * @returns La URL lista para embeber en un generador de QR
338
+ */
339
+ declare function generarUrlQR(caeResponse: CAEResponse, cuitEmisor: string, total: number, comprador?: Comprador): string;
340
+
341
+ export { ArcaAuthError, type ArcaConfig, ArcaError, ArcaValidationError, type CAEResponse, type Comprador, Concepto, type EmitirFacturaRequest, type Environment, type FacturaItem, type LoginTicket, TipoComprobante, TipoDocumento, type WsaaConfig, WsaaService, type WsfeConfig, WsfeService, generarUrlQR };
package/dist/index.js CHANGED
@@ -338,21 +338,32 @@ var TipoDocumento = /* @__PURE__ */ ((TipoDocumento2) => {
338
338
  })(TipoDocumento || {});
339
339
 
340
340
  // src/utils/calculations.ts
341
- function calcularSubtotal(items) {
341
+ function calcularSubtotal(items, incluyeIva = false) {
342
342
  return items.reduce((sum, item) => {
343
- return sum + item.cantidad * item.precioUnitario;
343
+ let precioNeto = item.precioUnitario;
344
+ if (incluyeIva && item.alicuotaIva) {
345
+ precioNeto = item.precioUnitario / (1 + item.alicuotaIva / 100);
346
+ }
347
+ return sum + item.cantidad * precioNeto;
344
348
  }, 0);
345
349
  }
346
- function calcularIVA(items) {
350
+ function calcularIVA(items, incluyeIva = false) {
347
351
  return items.reduce((sum, item) => {
348
- const subtotal = item.cantidad * item.precioUnitario;
349
352
  const alicuota = item.alicuotaIva || 0;
350
- return sum + subtotal * alicuota / 100;
353
+ let precioNeto = item.precioUnitario;
354
+ if (incluyeIva && alicuota) {
355
+ precioNeto = item.precioUnitario / (1 + alicuota / 100);
356
+ }
357
+ const subtotalNeto = item.cantidad * precioNeto;
358
+ return sum + subtotalNeto * alicuota / 100;
351
359
  }, 0);
352
360
  }
353
- function calcularTotal(items) {
354
- const subtotal = calcularSubtotal(items);
355
- const iva = calcularIVA(items);
361
+ function calcularTotal(items, incluyeIva = false) {
362
+ if (incluyeIva) {
363
+ return items.reduce((sum, item) => sum + item.cantidad * item.precioUnitario, 0);
364
+ }
365
+ const subtotal = calcularSubtotal(items, false);
366
+ const iva = calcularIVA(items, false);
356
367
  return subtotal + iva;
357
368
  }
358
369
  function redondear(valor) {
@@ -423,14 +434,16 @@ var WsfeService = class {
423
434
  */
424
435
  async emitirFacturaB(params) {
425
436
  this.validateItemsWithIVA(params.items);
426
- const ivaData = this.calcularIVAPorAlicuota(params.items);
437
+ const incluyeIva = params.incluyeIva || false;
438
+ const ivaData = this.calcularIVAPorAlicuota(params.items, incluyeIva);
427
439
  return this.emitirComprobante({
428
440
  tipo: 6 /* FACTURA_B */,
429
441
  concepto: params.concepto || 1 /* PRODUCTOS */,
430
442
  items: params.items,
431
443
  comprador: params.comprador,
432
444
  fecha: params.fecha,
433
- ivaData
445
+ ivaData,
446
+ incluyeIva
434
447
  });
435
448
  }
436
449
  /**
@@ -439,14 +452,16 @@ var WsfeService = class {
439
452
  */
440
453
  async emitirFacturaA(params) {
441
454
  this.validateItemsWithIVA(params.items);
442
- const ivaData = this.calcularIVAPorAlicuota(params.items);
455
+ const incluyeIva = params.incluyeIva || false;
456
+ const ivaData = this.calcularIVAPorAlicuota(params.items, incluyeIva);
443
457
  return this.emitirComprobante({
444
458
  tipo: 1 /* FACTURA_A */,
445
459
  concepto: params.concepto || 1 /* PRODUCTOS */,
446
460
  items: params.items,
447
461
  comprador: params.comprador,
448
462
  fecha: params.fecha,
449
- ivaData
463
+ ivaData,
464
+ incluyeIva
450
465
  });
451
466
  }
452
467
  /**
@@ -470,11 +485,15 @@ var WsfeService = class {
470
485
  * Calcula IVA agrupado por alícuota
471
486
  * ARCA requiere esto para Factura B/A
472
487
  */
473
- calcularIVAPorAlicuota(items) {
488
+ calcularIVAPorAlicuota(items, incluyeIva = false) {
474
489
  const porAlicuota = /* @__PURE__ */ new Map();
475
490
  items.forEach((item) => {
476
491
  const alicuota = item.alicuotaIva || 0;
477
- const base = item.cantidad * item.precioUnitario;
492
+ let precioNeto = item.precioUnitario;
493
+ if (incluyeIva && alicuota) {
494
+ precioNeto = item.precioUnitario / (1 + alicuota / 100);
495
+ }
496
+ const base = item.cantidad * precioNeto;
478
497
  const importe = base * alicuota / 100;
479
498
  const actual = porAlicuota.get(alicuota) || { base: 0, importe: 0 };
480
499
  porAlicuota.set(alicuota, {
@@ -515,9 +534,10 @@ var WsfeService = class {
515
534
  let subtotal = total;
516
535
  let iva = 0;
517
536
  if (request.items && request.items.length > 0) {
518
- subtotal = redondear(calcularSubtotal(request.items));
519
- iva = redondear(calcularIVA(request.items));
520
- total = redondear(calcularTotal(request.items));
537
+ const incluyeIva = request.incluyeIva || false;
538
+ subtotal = redondear(calcularSubtotal(request.items, incluyeIva));
539
+ iva = redondear(calcularIVA(request.items, incluyeIva));
540
+ total = redondear(calcularTotal(request.items, incluyeIva));
521
541
  }
522
542
  if (total <= 0) {
523
543
  throw new ArcaValidationError("El monto total debe ser mayor a 0");
@@ -713,6 +733,36 @@ var WsfeService = class {
713
733
  };
714
734
  }
715
735
  };
736
+
737
+ // src/utils/qr.ts
738
+ function generarUrlQR(caeResponse, cuitEmisor, total, comprador) {
739
+ const fDate = caeResponse.fecha;
740
+ const fechaFormat = fDate.length === 8 ? `${fDate.substring(0, 4)}-${fDate.substring(4, 6)}-${fDate.substring(6, 8)}` : fDate;
741
+ const docTipo = comprador?.tipoDocumento || 99 /* CONSUMIDOR_FINAL */;
742
+ const docNro = comprador?.nroDocumento ? parseInt(comprador.nroDocumento, 10) : 0;
743
+ const qrData = {
744
+ ver: 1,
745
+ // Versión estándar exigida por AFIP
746
+ fecha: fechaFormat,
747
+ cuit: parseInt(cuitEmisor, 10),
748
+ ptoVta: caeResponse.puntoVenta,
749
+ tipoCmp: caeResponse.tipoComprobante,
750
+ nroCmp: caeResponse.nroComprobante,
751
+ importe: parseFloat(total.toFixed(2)),
752
+ moneda: "PES",
753
+ // Por defecto PES (Pesos Argentinos)
754
+ ctz: 1,
755
+ // Cotización (siempre 1 para PES)
756
+ tipoDocRec: docTipo,
757
+ nroDocRec: docNro,
758
+ tipoCodAut: "E",
759
+ // 'E' para comprobantes electrónicos
760
+ codAut: parseInt(caeResponse.cae, 10)
761
+ };
762
+ const jsonString = JSON.stringify(qrData);
763
+ let base64 = typeof Buffer !== "undefined" ? Buffer.from(jsonString).toString("base64") : btoa(jsonString);
764
+ return `https://www.afip.gob.ar/fe/qr/?p=${base64}`;
765
+ }
716
766
  export {
717
767
  ArcaAuthError,
718
768
  ArcaError,
@@ -721,5 +771,6 @@ export {
721
771
  TipoComprobante,
722
772
  TipoDocumento,
723
773
  WsaaService,
724
- WsfeService
774
+ WsfeService,
775
+ generarUrlQR
725
776
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arca-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "SDK moderna en TypeScript para ARCA (ex-AFIP)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -8,9 +8,12 @@
8
8
  "types": "./dist/index.d.ts",
9
9
  "exports": {
10
10
  ".": {
11
- "types": "./dist/index.d.ts",
12
- "import": "./dist/index.mjs",
13
- "require": "./dist/index.js"
11
+ "types": {
12
+ "import": "./dist/index.d.ts",
13
+ "require": "./dist/index.d.cts"
14
+ },
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
14
17
  }
15
18
  },
16
19
  "files": [