@ramiidv/arca-agro 0.1.0 → 0.3.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 +211 -179
- package/dist/arca-agro.d.ts +25 -140
- package/dist/arca-agro.d.ts.map +1 -1
- package/dist/arca-agro.js +69 -264
- package/dist/arca-agro.js.map +1 -1
- package/dist/constants.d.ts +34 -8
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +34 -11
- package/dist/constants.js.map +1 -1
- package/dist/context.d.ts +13 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -0
- package/dist/cpe-client.d.ts +95 -51
- package/dist/cpe-client.d.ts.map +1 -1
- package/dist/cpe-client.js +236 -228
- package/dist/cpe-client.js.map +1 -1
- package/dist/cpe-schemas.d.ts +76 -0
- package/dist/cpe-schemas.d.ts.map +1 -0
- package/dist/cpe-schemas.js +512 -0
- package/dist/cpe-schemas.js.map +1 -0
- package/dist/cpe-types.d.ts +599 -0
- package/dist/cpe-types.d.ts.map +1 -0
- package/dist/cpe-types.js +2 -0
- package/dist/cpe-types.js.map +1 -0
- package/dist/errors.d.ts +38 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +53 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -13
- package/dist/index.js.map +1 -1
- package/dist/lpg-client.d.ts +64 -43
- package/dist/lpg-client.d.ts.map +1 -1
- package/dist/lpg-client.js +215 -175
- package/dist/lpg-client.js.map +1 -1
- package/dist/lpg-schemas.d.ts +50 -0
- package/dist/lpg-schemas.d.ts.map +1 -0
- package/dist/lpg-schemas.js +478 -0
- package/dist/lpg-schemas.js.map +1 -0
- package/dist/lpg-types.d.ts +470 -0
- package/dist/lpg-types.d.ts.map +1 -0
- package/dist/lpg-types.js +2 -0
- package/dist/lpg-types.js.map +1 -0
- package/dist/schema.d.ts +90 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +301 -0
- package/dist/schema.js.map +1 -0
- package/dist/types.d.ts +33 -455
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +22 -43
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +31 -134
- package/dist/validation.js.map +1 -1
- package/llms.txt +78 -159
- package/package.json +7 -8
- package/dist/ctg-client.d.ts +0 -56
- package/dist/ctg-client.d.ts.map +0 -1
- package/dist/ctg-client.js +0 -214
- package/dist/ctg-client.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# @ramiidv/arca-agro
|
|
2
2
|
|
|
3
|
-
SDK para los servicios web agropecuarios de ARCA (ex AFIP), Argentina
|
|
3
|
+
SDK para los servicios web agropecuarios de ARCA (ex AFIP), Argentina:
|
|
4
4
|
|
|
5
|
-
- **WSCPE
|
|
6
|
-
- **
|
|
7
|
-
|
|
5
|
+
- **WSCPE**: Carta de Porte Electrónica (granos, automotor y ferroviaria). Reemplazó al CTG (RG 5017/2021).
|
|
6
|
+
- **WSLPG**: Liquidación Primaria de Granos y certificación primaria.
|
|
7
|
+
|
|
8
|
+
> **WSCTG ya no existe.** El Código de Trazabilidad de Granos fue derogado el 1/11/2021 y reemplazado por la Carta de Porte Electrónica; sus endpoints responden 404. Desde la versión 0.3.0 este paquete no lo incluye. El número de CTG ahora lo asigna WSCPE al autorizar la CPE (`cabecera.nroCTG`).
|
|
8
9
|
|
|
9
10
|
## Instalación
|
|
10
11
|
|
|
@@ -15,256 +16,287 @@ npm install @ramiidv/arca-agro @ramiidv/arca-common
|
|
|
15
16
|
## Requisitos
|
|
16
17
|
|
|
17
18
|
- Node.js >= 18
|
|
18
|
-
- Certificado digital y clave privada emitidos por ARCA
|
|
19
|
-
- Autorización en los servicios `wscpe`, `wsctg` y/o `wslpg` en WSAA
|
|
19
|
+
- Certificado digital y clave privada emitidos por ARCA, autorizados en WSAA para `wscpe` y/o `wslpg`.
|
|
20
20
|
|
|
21
21
|
## Inicio rápido
|
|
22
22
|
|
|
23
23
|
```ts
|
|
24
|
-
import { ArcaAgro } from '@ramiidv/arca-agro';
|
|
25
24
|
import fs from 'node:fs';
|
|
25
|
+
import { FileTicketStorage } from '@ramiidv/arca-common';
|
|
26
|
+
import { ArcaAgro, TIPO_CPE } from '@ramiidv/arca-agro';
|
|
26
27
|
|
|
27
28
|
const agro = new ArcaAgro({
|
|
28
|
-
cuit:
|
|
29
|
+
cuit: '20-12345678-6', // CUIT representada (se valida el dígito verificador)
|
|
29
30
|
cert: fs.readFileSync('cert.pem', 'utf-8'),
|
|
30
31
|
key: fs.readFileSync('key.pem', 'utf-8'),
|
|
31
32
|
production: false, // true para producción
|
|
33
|
+
ticketStorage: new FileTicketStorage('.arca-tickets'), // recomendado: persiste el TA entre reinicios
|
|
32
34
|
});
|
|
33
35
|
```
|
|
34
36
|
|
|
35
|
-
La autenticación WSAA
|
|
37
|
+
La autenticación WSAA es automática: el ticket se cachea y se renueva cuando vence.
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
Todos los métodos aceptan un último argumento opcional `{ signal }` (`AbortSignal`) para cancelar la llamada.
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
// Autorizar una carta de porte
|
|
41
|
-
const resultado = await agro.cpe.autorizarCPEAutomotor({
|
|
42
|
-
cuitTitularCartaPorte: 20123456789,
|
|
43
|
-
sucursal: 1,
|
|
44
|
-
nroOrden: 1,
|
|
45
|
-
codTipoCartaPorte: 1,
|
|
46
|
-
codGrano: 23, // soja
|
|
47
|
-
codLocalidadProcedencia: 10001,
|
|
48
|
-
codProvProcedencia: 1,
|
|
49
|
-
codLocalidadDestino: 20001,
|
|
50
|
-
codProvDestino: 12,
|
|
51
|
-
cuitDestino: 30111222333,
|
|
52
|
-
plantaDestino: 1,
|
|
53
|
-
pesoNeto: 30000,
|
|
54
|
-
pesoBruto: 32000,
|
|
55
|
-
pesoTara: 2000,
|
|
56
|
-
patente: 'ABC123',
|
|
57
|
-
cuitTransportista: 20999888777,
|
|
58
|
-
fechaEmision: '2026-03-31',
|
|
59
|
-
});
|
|
41
|
+
## WSCPE: Carta de Porte Electrónica
|
|
60
42
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
pesoNeto: 29800,
|
|
67
|
-
fechaArribo: '2026-04-01',
|
|
68
|
-
});
|
|
43
|
+
Los requests siguen el XSD oficial de WSCPE (mismos nombres y anidamiento). El SDK arma el XML en el orden del XSD, valida los datos antes de enviarlos y devuelve objetos tipados.
|
|
44
|
+
|
|
45
|
+
Tipos de carta de porte (`TIPO_CPE`): `74` automotor, `75` ferroviaria, `274` automotor flete corto.
|
|
46
|
+
|
|
47
|
+
### Autorizar una CPE automotor
|
|
69
48
|
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
49
|
+
```ts
|
|
50
|
+
const sucursal = 1;
|
|
51
|
+
const nroOrden = await agro.cpe.siguienteNroOrden(sucursal, TIPO_CPE.AUTOMOTOR);
|
|
52
|
+
|
|
53
|
+
const cpe = await agro.cpe.autorizarCPEAutomotor({
|
|
54
|
+
cabecera: { tipoCP: TIPO_CPE.AUTOMOTOR, cuitSolicitante: '20123456786', sucursal, nroOrden },
|
|
55
|
+
origen: { productor: { codProvincia: 1, codLocalidad: 10270 } }, // o { operador: { codProvincia, codLocalidad, planta } }
|
|
56
|
+
correspondeRetiroProductor: false,
|
|
57
|
+
esSolicitanteCampo: true,
|
|
58
|
+
datosCarga: { codGrano: 23, cosecha: 2526, pesoBruto: 42000, pesoTara: 12000 },
|
|
59
|
+
destino: { cuit: '30500011129', esDestinoCampo: false, codProvincia: 12, codLocalidad: 5244, planta: 1938 },
|
|
60
|
+
destinatario: { cuit: '30500011129' },
|
|
61
|
+
transporte: {
|
|
62
|
+
cuitTransportista: '20999888772',
|
|
63
|
+
dominio: ['AB123CD'],
|
|
64
|
+
fechaHoraPartida: new Date('2026-11-02T08:00:00-03:00'),
|
|
65
|
+
kmRecorrer: 250,
|
|
66
|
+
cuitChofer: '27300000008',
|
|
67
|
+
tarifa: 1500.5,
|
|
68
|
+
cuitPagadorFlete: '30712345671',
|
|
69
|
+
mercaderiaFumigada: false,
|
|
70
|
+
},
|
|
75
71
|
});
|
|
76
72
|
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
cpe.cabecera.nroCTG; // '010100012345' (string)
|
|
74
|
+
cpe.cabecera.estado; // 'AC'
|
|
75
|
+
cpe.pdf; // constancia en base64
|
|
76
|
+
```
|
|
80
77
|
|
|
81
|
-
|
|
82
|
-
const pdfBase64 = await agro.cpe.consultarConstanciaCPEPDF(12345);
|
|
78
|
+
> **`siguienteNroOrden` no es atómico.** Hace `consultarUltNroOrden + 1`: dos procesos que lo llamen a la vez obtienen el mismo número y ARCA rechaza la segunda autorización. Si emitís en paralelo para la misma sucursal y tipo, serializá las emisiones o llevá tu propio contador.
|
|
83
79
|
|
|
84
|
-
|
|
85
|
-
const nroOrden = await agro.cpe.siguienteNroOrden(1);
|
|
80
|
+
### Circuito automotor
|
|
86
81
|
|
|
87
|
-
|
|
88
|
-
const
|
|
82
|
+
```ts
|
|
83
|
+
const cartaPorte = { tipoCPE: TIPO_CPE.AUTOMOTOR, sucursal: 1, nroOrden: 15 };
|
|
84
|
+
|
|
85
|
+
await agro.cpe.confirmarArriboCPE({ cuitSolicitante, cartaPorte });
|
|
86
|
+
await agro.cpe.confirmacionDefinitivaCPEAutomotor({ cuitSolicitante, cartaPorte, pesoBrutoDescarga: 41900, pesoTaraDescarga: 12000 });
|
|
87
|
+
await agro.cpe.descargadoDestinoCPE({ cuitSolicitante, cartaPorte });
|
|
88
|
+
await agro.cpe.rechazoCPE({ cuitSolicitante, cartaPorte, rechazoMotivo: 2, rechazoObservaciones: 'Humedad' });
|
|
89
|
+
await agro.cpe.anularCPE({ cartaPorte, anulacionMotivo: 3, anulacionObservaciones: 'Error de carga' });
|
|
90
|
+
await agro.cpe.editarCPEAutomotor({ nroCTG, cuitDestinatario, cuitChofer, cuitTransportista, destino, pesoBruto, codGrano });
|
|
91
|
+
await agro.cpe.editarCPEConfirmadaAutomotor({ nroCTG, intervinientes: { cuitCorredorVentaPrimaria } });
|
|
92
|
+
await agro.cpe.nuevoDestinoDestinatarioCPEAutomotor({ cartaPorte, destino, transporte: { fechaHoraPartida, kmRecorrer } });
|
|
93
|
+
await agro.cpe.regresoOrigenCPEAutomotor({ cartaPorte, transporte: { fechaHoraPartida, kmRecorrer } });
|
|
94
|
+
await agro.cpe.desvioCPEAutomotor({ cuitSolicitante, cartaPorte, destino, transporte });
|
|
95
|
+
await agro.cpe.informarContingencia({ cartaPorte, contingencia: { concepto: 'C', descripcion: 'Desperfecto mecánico' } });
|
|
96
|
+
await agro.cpe.cerrarContingenciaCPE({ cartaPorte, concepto: 'A' });
|
|
97
|
+
|
|
98
|
+
const detalle = await agro.cpe.consultarCPEAutomotor({ nroCTG: '010100012345' }); // o { cartaPorte }
|
|
89
99
|
```
|
|
90
100
|
|
|
91
|
-
|
|
101
|
+
Las operaciones que modifican una CPE devuelven `CPEResultado` (`{ cabecera?, pdf?, metadata? }`).
|
|
92
102
|
|
|
93
|
-
|
|
94
|
-
// Solicitar un CTG
|
|
95
|
-
const ctg = await agro.ctg.solicitarCTGInicial({
|
|
96
|
-
nroCartaPorte: 67890,
|
|
97
|
-
codEspecie: 23,
|
|
98
|
-
cuitDestino: 30111222333,
|
|
99
|
-
cuitDestinatario: 30111222333,
|
|
100
|
-
codLocalidadOrigen: 10001,
|
|
101
|
-
codLocalidadDestino: 20001,
|
|
102
|
-
codCosecha: 2526,
|
|
103
|
-
pesoNeto: 30000,
|
|
104
|
-
});
|
|
103
|
+
### Circuito ferroviario
|
|
105
104
|
|
|
106
|
-
|
|
107
|
-
await agro.ctg.confirmarArribo({
|
|
108
|
-
nroCTG: ctg.nroCTG!,
|
|
109
|
-
nroCartaPorte: 67890,
|
|
110
|
-
cuitDestino: 30111222333,
|
|
111
|
-
pesoNeto: 29800,
|
|
112
|
-
fechaArribo: '2026-04-01',
|
|
113
|
-
});
|
|
105
|
+
`autorizarCPEFerroviaria`, `consultarCPEFerroviaria`, `editarCPEFerroviaria`, `editarCPEConfirmadaFerroviaria`, `confirmacionDefinitivaCPEFerroviaria`, `nuevoDestinoDestinatarioCPEFerroviaria`, `regresoOrigenCPEFerroviaria`, `desvioCPEFerroviaria` y `consultaCPEFerroviariaPorNroOperativo`.
|
|
114
106
|
|
|
115
|
-
|
|
116
|
-
const ctgs = await agro.ctg.consultarCTG({
|
|
117
|
-
fechaDesde: '2026-03-01',
|
|
118
|
-
fechaHasta: '2026-03-31',
|
|
119
|
-
});
|
|
107
|
+
### Consultas y paramétricas
|
|
120
108
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
109
|
+
```ts
|
|
110
|
+
await agro.cpe.consultarUltNroOrden(1, TIPO_CPE.AUTOMOTOR); // número; si ARCA no lo devuelve, lanza
|
|
111
|
+
await agro.cpe.consultarCPEPorDestino({ planta: 1938, fechaPartidaDesde: '2026-11-01', fechaPartidaHasta: '2026-11-07' });
|
|
112
|
+
await agro.cpe.consultarCPEPPendientesDeResolucion({ perfil: 'D', planta: 1938 });
|
|
113
|
+
await agro.cpe.consultarProvincias();
|
|
114
|
+
await agro.cpe.consultarLocalidadesPorProvincia(12);
|
|
115
|
+
await agro.cpe.consultarTiposGrano();
|
|
116
|
+
await agro.cpe.consultarPlantas('30500011129');
|
|
117
|
+
await agro.cpe.consultarLocalidadesProductor('20123456786');
|
|
118
|
+
await agro.cpe.consultarCategoriasSemillas();
|
|
119
|
+
await agro.cpe.consultarVariedadesSemillas(23);
|
|
120
|
+
await agro.cpe.dummy();
|
|
121
|
+
```
|
|
126
122
|
|
|
127
|
-
|
|
128
|
-
await agro.ctg.rechazarCTG({ nroCTG: 123, nroCartaPorte: 456, codMotivo: 1 });
|
|
129
|
-
await agro.ctg.anularCTG({ nroCTG: 123, nroCartaPorte: 456, codMotivo: 2 });
|
|
123
|
+
Las listas sin resultados devuelven `[]`; si ARCA devuelve errores, se lanza `ArcaAgroServiceError` (nunca una lista vacía).
|
|
130
124
|
|
|
131
|
-
|
|
132
|
-
const activos = await agro.ctg.obtenerCTGActivos();
|
|
125
|
+
### No soportado en WSCPE
|
|
133
126
|
|
|
134
|
-
|
|
135
|
-
const pdf = await agro.ctg.consultarConstanciaCTGPDF(12345);
|
|
127
|
+
El circuito de **derivados granarios** (CPE DG, tipos 284-287: `autorizarCPEAutomotorDG`, `autorizarCPEFerroviariaDG`, `autorizarCPEDuctosDG`, `autorizarCPEEmisionDestinoDG`, etc.), `consultarCPEDuctos`, `consultarRenspa`, `consultarDomiciliosPorCUIT` y las paramétricas de DG (`consultarTiposEmbalaje`, `consultarUnidadesMedida`, `consultarDerivadosGranarios`, `consultarPlantasDG`) todavía no están implementados.
|
|
136
128
|
|
|
137
|
-
|
|
138
|
-
const status = await agro.ctg.dummy();
|
|
139
|
-
```
|
|
129
|
+
## WSLPG: Liquidación Primaria de Granos
|
|
140
130
|
|
|
141
|
-
|
|
131
|
+
`liquidacion` sigue `LpgLiquidacionBaseType` del XSD; `deducciones`, `retenciones` y `percepciones` van como hermanos (arrays).
|
|
142
132
|
|
|
143
133
|
```ts
|
|
144
|
-
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
134
|
+
const ptoEmision = 1;
|
|
135
|
+
const nroOrden = (await agro.lpg.liquidacionUltimoNroOrdenConsultar(ptoEmision)) + 1;
|
|
136
|
+
|
|
137
|
+
const { autorizacion, eventos } = await agro.lpg.liquidacionAutorizar({
|
|
138
|
+
liquidacion: {
|
|
139
|
+
ptoEmision,
|
|
140
|
+
nroOrden,
|
|
141
|
+
cuitComprador: '20123456786',
|
|
142
|
+
nroActComprador: 40,
|
|
143
|
+
nroIngBrutoComprador: 901234567,
|
|
144
|
+
codTipoOperacion: '1',
|
|
145
|
+
codPuerto: 14,
|
|
146
|
+
codGrano: 31,
|
|
147
|
+
cuitVendedor: '30712345671',
|
|
148
|
+
nroIngBrutoVendedor: 900123,
|
|
149
|
+
liquidaCorredor: 'N',
|
|
150
|
+
fechaPrecioOperacion: '2026-10-30',
|
|
151
|
+
precioRefTn: 250000,
|
|
152
|
+
precioFleteTn: 0,
|
|
153
|
+
campaniaPPal: 2526,
|
|
154
|
+
codLocalidadProcedencia: 3,
|
|
155
|
+
codProvProcedencia: 1,
|
|
156
|
+
pesoNetoSinCertificado: 30000,
|
|
157
|
+
},
|
|
158
|
+
deducciones: [{ codigoConcepto: 'CO', comisionGastosAdm: 1.5, alicuotaIva: 21 }],
|
|
159
|
+
retenciones: [{ codigoConcepto: 'RG', baseCalculo: 7500000, alicuota: 2 }],
|
|
151
160
|
});
|
|
152
161
|
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
fechaHasta: '2026-03-31',
|
|
157
|
-
});
|
|
162
|
+
autorizacion.coe; // '330100012345' (string)
|
|
163
|
+
autorizacion.totalNetoAPagar; // number
|
|
164
|
+
```
|
|
158
165
|
|
|
159
|
-
|
|
160
|
-
await agro.lpg.liquidacionAnular(1, 100);
|
|
166
|
+
Los códigos de actividad, operación, puerto, grano, deducción y retención salen de las paramétricas.
|
|
161
167
|
|
|
162
|
-
|
|
168
|
+
```ts
|
|
169
|
+
await agro.lpg.liquidacionXCoeConsultar(coe, { pdf: true }); // { liquidacion, autorizacion, pdf, eventos }
|
|
170
|
+
await agro.lpg.liquidacionXNroOrdenConsultar(ptoEmision, nroOrden);
|
|
171
|
+
await agro.lpg.liquidacionAnular(coe); // { coe, resultado, pdf?, eventos }
|
|
163
172
|
await agro.lpg.liquidacionAjustarUnificado({
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
tipoAjuste: 'credito',
|
|
167
|
-
liquidacion: { pesoNeto: 29500 },
|
|
173
|
+
ajusteBase: { ptoEmision, nroOrden, coeAjustado: coe, codLocalidad: 3, codProv: 1 },
|
|
174
|
+
ajusteDebito: { diferenciaPesoNeto: 0, diferenciaPrecioOperacion: 1000, diferenciaPrecioFleteTn: 0 },
|
|
168
175
|
});
|
|
169
176
|
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
+
// Certificación primaria
|
|
178
|
+
await agro.lpg.cgConsultarUltimoNroOrden(ptoEmision);
|
|
179
|
+
await agro.lpg.cgAutorizar({ cabecera: { ... }, primaria: { ... } }); // o retiroTransferencia / preexistente
|
|
180
|
+
await agro.lpg.cgSolicitarAnulacion(coe);
|
|
181
|
+
await agro.lpg.cgConfirmarAnulacion(coe, { pdf: true });
|
|
182
|
+
|
|
183
|
+
// Paramétricas
|
|
184
|
+
await agro.lpg.tipoGranoConsultar();
|
|
185
|
+
await agro.lpg.puertoConsultar();
|
|
186
|
+
await agro.lpg.provinciasConsultar();
|
|
187
|
+
await agro.lpg.localidadXProvinciaConsultar(1);
|
|
188
|
+
await agro.lpg.tipoActividadConsultar();
|
|
189
|
+
await agro.lpg.tipoActividadRepresentadoConsultar();
|
|
190
|
+
await agro.lpg.tipoOperacionXActividadConsultar(40);
|
|
191
|
+
await agro.lpg.tipoDeduccionConsultar();
|
|
192
|
+
await agro.lpg.tipoRetencionConsultar();
|
|
193
|
+
await agro.lpg.tipoCertificadoDepositoConsultar();
|
|
194
|
+
await agro.lpg.codigoGradoReferenciaConsultar();
|
|
195
|
+
await agro.lpg.codigoGradoEntregadoXTipoGranoConsultar(2);
|
|
196
|
+
await agro.lpg.campaniasConsultar();
|
|
197
|
+
await agro.lpg.dummy();
|
|
198
|
+
```
|
|
177
199
|
|
|
178
|
-
|
|
179
|
-
await agro.lpg.certificacionAnular(1, cert.nroCertificacion!);
|
|
200
|
+
### No soportado en WSLPG
|
|
180
201
|
|
|
181
|
-
|
|
182
|
-
const granos = await agro.lpg.consultarParametros('tipoGranoConsultar');
|
|
202
|
+
Liquidación secundaria (`lsg*`), anticipos (`lpgAutorizarAnticipo`, `lpgCancelarAnticipo`), anulación contra documento, ajuste por contrato (`liquidacionAjustarContrato`, `asociarLiquidacionAContrato`, `*PorContratoConsultar`, `ajusteXCoeConsultar`, `ajusteXNroOrdenConsultar`) y el resto de las operaciones de certificación (`cgBuscarCtg`, `cgBuscarCertConSaldoDisponible`, `cgConsultarXCoe`, `cgConsultarXNroOrden`, `cgInformarCalidad`).
|
|
183
203
|
|
|
184
|
-
|
|
185
|
-
const status = await agro.lpg.dummy();
|
|
186
|
-
```
|
|
204
|
+
## Errores
|
|
187
205
|
|
|
188
|
-
|
|
206
|
+
| Error | Cuándo |
|
|
207
|
+
|-------|--------|
|
|
208
|
+
| `ArcaValidationError` | Datos inválidos, antes de llamar a ARCA: campo obligatorio faltante, campo desconocido, CUIT con dígito verificador incorrecto, `NaN`/`Infinity`, rangos y largos del XSD, fechas. `details[]` trae cada campo con su ruta (ej: `transporte.dominio[0]`). |
|
|
209
|
+
| `ArcaAgroServiceError` (extiende `ArcaServiceError`) | ARCA rechazó la operación: `errores.error[]` (y en WSLPG también `erroresFormato.error[]`). `errors[]`, `service`, `method` y `response` (el nodo completo devuelto). |
|
|
210
|
+
| `ArcaSoapError` | Red, timeout, HTTP o SOAP Fault. `uncertain` indica si ARCA pudo haber procesado el request. |
|
|
211
|
+
| `ArcaAgroResponseError` | La respuesta no trae un dato imprescindible (ej: `nroCTG` al autorizar, `coe` al liquidar, `nroOrden` al consultar el último). `uncertain` es `true` en emisiones. |
|
|
212
|
+
| `ArcaAuthError` / `ArcaTicketVigenteError` | Errores de WSAA. |
|
|
189
213
|
|
|
190
|
-
|
|
191
|
-
const status = await agro.serverStatus();
|
|
192
|
-
// { cpe: { appserver, dbserver, authserver }, ctg: { ... }, lpg: { ... } }
|
|
193
|
-
```
|
|
214
|
+
Los montos se redondean a los decimales del XSD (`fractionDigits`). Las fechas `xsd:date` aceptan `Date` o `AAAAMMDD`/`AAAA-MM-DD`; las `xsd:dateTime` aceptan `Date` (se envía en hora de Argentina, `-03:00`) o un string ISO-8601.
|
|
194
215
|
|
|
195
|
-
|
|
216
|
+
En las respuestas, los campos `xs:string` (ej: `codigo` de las paramétricas) son `string`, los IDs largos (`nroCTG`, `coe`) son `string`, los CUIT y montos son `number`.
|
|
196
217
|
|
|
197
|
-
|
|
218
|
+
## Emisiones y reintentos
|
|
198
219
|
|
|
199
|
-
|
|
200
|
-
import { CpeClient, CtgClient, LpgClient } from '@ramiidv/arca-agro';
|
|
201
|
-
import { WsaaClient } from '@ramiidv/arca-common';
|
|
220
|
+
Las operaciones que crean o modifican algo en ARCA **nunca se reintentan**:
|
|
202
221
|
|
|
203
|
-
|
|
204
|
-
|
|
222
|
+
- WSCPE: `autorizarCPEAutomotor`, `autorizarCPEFerroviaria`, `confirmarArriboCPE`, `confirmacionDefinitivaCPE*`, `descargadoDestinoCPE`, `rechazoCPE`, `anularCPE`, `editarCPE*`, `nuevoDestinoDestinatarioCPE*`, `regresoOrigenCPE*`, `desvioCPE*`, `informarContingencia`, `cerrarContingenciaCPE`.
|
|
223
|
+
- WSLPG: `liquidacionAutorizar`, `liquidacionAnular`, `liquidacionAjustarUnificado`, `cgAutorizar`, `cgSolicitarAnulacion`, `cgConfirmarAnulacion`.
|
|
205
224
|
|
|
206
|
-
|
|
207
|
-
const auth = { Token: ticket.token, Sign: ticket.sign, Cuit: 20123456789 };
|
|
225
|
+
Las consultas se reintentan ante errores transitorios (`retries`, default 1).
|
|
208
226
|
|
|
209
|
-
|
|
210
|
-
```
|
|
227
|
+
### Recuperar una emisión incierta
|
|
211
228
|
|
|
212
|
-
|
|
229
|
+
Si una emisión falla con `error.uncertain === true` (timeout, conexión cortada, HTTP 5xx, SOAP Fault, respuesta incompleta), ARCA pudo haberla procesado. **No reintentes a ciegas**: consultá primero.
|
|
230
|
+
|
|
231
|
+
- **CPE** (manual WSCPE §1.3): `consultarUltNroOrden(sucursal, tipoCPE)`. Si es `>=` al `nroOrden` que enviaste, la CPE se autorizó: obtenela con `consultarCPEAutomotor({ cartaPorte: { tipoCPE, sucursal, nroOrden } })` (o `consultarCPEFerroviaria`). Si no, reintentá con el mismo `nroOrden`. Para las demás operaciones, consultá la CPE y mirá `cabecera.estado`.
|
|
232
|
+
- **Liquidación**: `liquidacionUltimoNroOrdenConsultar(ptoEmision)` y `liquidacionXNroOrdenConsultar(ptoEmision, nroOrden)`. Para anulaciones y ajustes, `liquidacionXCoeConsultar(coe)` y mirá `autorizacion.estado`.
|
|
233
|
+
- **Certificación**: `cgConsultarUltimoNroOrden(ptoEmision)`.
|
|
213
234
|
|
|
214
235
|
```ts
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
236
|
+
try {
|
|
237
|
+
return await agro.cpe.autorizarCPEAutomotor(params);
|
|
238
|
+
} catch (e) {
|
|
239
|
+
if (!((e instanceof ArcaSoapError || e instanceof ArcaAgroResponseError) && e.uncertain)) throw e;
|
|
240
|
+
const { tipoCP, sucursal, nroOrden } = params.cabecera;
|
|
241
|
+
if ((await agro.cpe.consultarUltNroOrden(sucursal, tipoCP)) >= nroOrden) {
|
|
242
|
+
return agro.cpe.consultarCPEAutomotor({ cartaPorte: { tipoCPE: tipoCP, sucursal, nroOrden } });
|
|
243
|
+
}
|
|
244
|
+
return agro.cpe.autorizarCPEAutomotor(params); // no se emitió
|
|
245
|
+
}
|
|
219
246
|
```
|
|
220
247
|
|
|
221
|
-
##
|
|
248
|
+
## Estado de los servicios
|
|
222
249
|
|
|
223
250
|
```ts
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
ArcaServiceError,
|
|
228
|
-
} from '@ramiidv/arca-agro';
|
|
251
|
+
const estado = await agro.serverStatus();
|
|
252
|
+
// { cpe: { ok: true, status: { appserver, dbserver, authserver } }, lpg: { ok: false, error } }
|
|
253
|
+
```
|
|
229
254
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
} else if (error instanceof ArcaAuthError) {
|
|
240
|
-
// Error de autenticación WSAA
|
|
241
|
-
console.error('Error auth:', error.message);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
255
|
+
Usa `Promise.allSettled`: la caída de un servicio no oculta el estado del otro.
|
|
256
|
+
|
|
257
|
+
## Eventos
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
agro.on('auth:login', (e) => console.log(`Login ${e.service}`));
|
|
261
|
+
agro.on('request:end', (e) => console.log(`${e.method} en ${e.durationMs}ms`));
|
|
262
|
+
agro.on('request:retry', (e) => console.warn(`Reintento #${e.attempt}`));
|
|
263
|
+
agro.on('request:error', (e) => console.error(`Error en ${e.method}`));
|
|
244
264
|
```
|
|
245
265
|
|
|
266
|
+
También se puede pasar `onEvent` en la configuración. Los errores de los handlers se ignoran.
|
|
267
|
+
|
|
246
268
|
## Configuración
|
|
247
269
|
|
|
270
|
+
`ArcaAgroConfig` extiende `ArcaBaseConfig` de `@ramiidv/arca-common`.
|
|
271
|
+
|
|
248
272
|
| Opción | Tipo | Default | Descripción |
|
|
249
273
|
|--------|------|---------|-------------|
|
|
250
|
-
| `cuit` | `number` | **requerido** | CUIT
|
|
251
|
-
| `cert` | `string` | **requerido** | Certificado
|
|
252
|
-
| `
|
|
253
|
-
| `
|
|
254
|
-
| `
|
|
255
|
-
| `requestTimeoutMs` | `number` | `30000` | Timeout para requests HTTP (ms) |
|
|
256
|
-
| `retries` | `number` | `1` | Reintentos en errores transitorios |
|
|
274
|
+
| `cuit` | `number \| string` | **requerido** | CUIT representada (con o sin guiones) |
|
|
275
|
+
| `cert` / `key` | `string` | **requerido** | Certificado y clave privada PEM |
|
|
276
|
+
| `production` | `boolean` | `false` | Entorno de producción |
|
|
277
|
+
| `timeout` | `number` | `30000` | Timeout HTTP (ms) |
|
|
278
|
+
| `retries` | `number` | `1` | Reintentos de consultas (las emisiones nunca se reintentan) |
|
|
257
279
|
| `retryDelayMs` | `number` | `1000` | Delay base entre reintentos (ms) |
|
|
258
|
-
| `
|
|
280
|
+
| `tokenTTLMinutes` | `number` | `720` | Vida del ticket WSAA |
|
|
281
|
+
| `ticketStorage` | `TicketStorage` | memoria | Persistencia del ticket WSAA (recomendado en producción) |
|
|
282
|
+
| `clockOffsetMs` / `autoClockSkew` | | `0` / `true` | Desfase de reloj con ARCA |
|
|
283
|
+
| `loginErrorCooldownMs` | `number` | `60000` | Espera tras un login WSAA fallido |
|
|
284
|
+
| `fetch` | `typeof fetch` | global | `fetch` propio (proxy, tests) |
|
|
285
|
+
| `legacyTls` | `'auto' \| 'never' \| 'always'` | `'auto'` | Transporte TLS legacy |
|
|
286
|
+
| `endpoints` | `{ cpe?, lpg?, wsaa? }` | oficiales | Endpoints propios |
|
|
287
|
+
| `onEvent` | `function` | | Callback de eventos |
|
|
288
|
+
|
|
289
|
+
`clearAuthCache()` (async) invalida los tickets de WSCPE y WSLPG.
|
|
259
290
|
|
|
260
291
|
## Endpoints
|
|
261
292
|
|
|
262
293
|
| Servicio | Homologación | Producción |
|
|
263
294
|
|----------|-------------|------------|
|
|
264
|
-
| WSCPE | `https://
|
|
265
|
-
| WSCTG | `https://fwshomo.afip.gov.ar/wsctg/services/CTGService_v4.0` | `https://serviciosjava.afip.gob.ar/wsctg/services/CTGService_v4.0` |
|
|
295
|
+
| WSCPE | `https://cpea-ws-qaext.afip.gob.ar/wscpe/services/soap` | `https://cpea-ws.afip.gob.ar/wscpe/services/soap` |
|
|
266
296
|
| WSLPG | `https://fwshomo.afip.gov.ar/wslpg/LpgService` | `https://serviciosjava.afip.gob.ar/wslpg/LpgService` |
|
|
267
297
|
|
|
298
|
+
Namespaces: WSCPE `https://serviciosjava.afip.gob.ar/wscpe/`, WSLPG `http://serviciosjava.afip.gob.ar/wslpg/`.
|
|
299
|
+
|
|
268
300
|
## Licencia
|
|
269
301
|
|
|
270
302
|
MIT
|