-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathAFIP.cpp
484 lines (425 loc) · 19.8 KB
/
AFIP.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
//---------------------------------------------------------------------------
#pragma hdrstop
#include "AFIP.h"
#include "auxiliar.h"
#define HOMO
//---------------------------------------------------------------------------
#pragma package(smart_init)
#ifdef HOMO
AnsiString URL_WSAA = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl";
AnsiString URL_WSFEv1 = "https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL";
AnsiString URL_WSSrPadronA5 = "https://awshomo.afip.gov.ar/sr-padron/webservices/personaServicioA5?wsdl";
#else
AnsiString URL_WSAA = "https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl";
AnsiString URL_WSFEv1 = "https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL";
AnsiString URL_WSSrPadronA5 = "https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA5?wsdl";
#endif
//---------------------------------------------------------------------------
static inline Variant VWS(AnsiString s)
{
return Variant(WideString(s));
}
//---------------------------------------------------------------------------
static inline Variant VWS(int s)
{
return Variant(WideString(s));
}
//---------------------------------------------------------------------------
static inline Variant VWS(double s)
{
return Variant(WideString(s));
}
//---------------------------------------------------------------------------
Item::Item(int qty, AnsiString ds, double precio, double importe)
{
Item::qty = qty;
Item::ds = ds;
Item::precio = precio;
Item::importe = importe;
}
//---------------------------------------------------------------------------
AFIP::AFIP(AnsiString fichcert, AnsiString fichclave)
{
AnsiString error = "No se puede conectar con el componente ";
try
{
// Crear objeto interface Web Service Autenticación y Autorización
WSAA = Variant::CreateObject("WSAA");
}
catch (...)
{
throw EAFIP(error + "WSAA");
}
try
{
// Crear objeto interface Web Service de Factura Electrónica de Mercado Interno
WSFEv1 = Variant::CreateObject("WSFEv1");
}
catch (...)
{
throw EAFIP(error + "WSFEv1");
}
try
{
// Crear objeto interface para generación de F.E. en PDF
PyFEPDF = Variant::CreateObject("PyFEPDF");
}
catch (...)
{
throw EAFIP(error + "PyFEPDF");
}
try
{
// Crear objeto interface para Padron AFIP
WSSrPadronA5 = Variant::CreateObject("WSSrPadronA5");
}
catch (...)
{
throw EAFIP(error + "WSSrPadronA5");
}
// Deshabilito excepciones para WSAA y WSFEv1
WSAA.OlePropertySet("LanzarExcepciones", false);
WSFEv1.OlePropertySet("LanzarExcepciones", false);
WSSrPadronA5.OlePropertySet("LanzarExcepciones", false);
AFIP::fichcert = fichcert;
AFIP::fichclave = fichclave;
}
//---------------------------------------------------------------------------
void AFIP::AutorizarComprobante(FE &fe)
{
AnsiString excepcion;
AnsiString cae_comp;
Variant eventos;
// Llamo al web service para autenticar
WSAA.OleFunction("Autenticar",
VWS("wsfe"), // servicio a acceder
VWS(fichcert), // certificado firmado por la afip
VWS(fichclave), // clave privada usada para crear el certificado
VWS(URL_WSAA)); // url WSAA
excepcion = WSAA.OlePropertyGet("Excepcion");
if (! excepcion.IsEmpty())
{
throw EAFIP("Autentificar:\n" + excepcion);
}
// Seteo token y sing de autorización
WSFEv1.OlePropertySet("Token", WSAA.OlePropertyGet("Token"));
WSFEv1.OlePropertySet("Sign", WSAA.OlePropertyGet("Sign"));
// Seteo CUIT del emisor
WSFEv1.OlePropertySet("Cuit", VWS(SinGuiones(cuit)));
// Conecto al Servicio Web de Facturación
WSFEv1.OleFunction("Conectar",
VWS(""), // cache
VWS(URL_WSFEv1)); // url WSFEv1
excepcion = WSFEv1.OlePropertyGet("Excepcion");
if (! excepcion.IsEmpty())
{
throw EAFIP("Conectar:\n" + excepcion);
}
// Verifico el estado de los servidores
WSFEv1.OleFunction("Dummy");
if (WSFEv1.OlePropertyGet("AppServerStatus") != VWS("OK") ||
WSFEv1.OlePropertyGet("DbServerStatus") != VWS("OK") ||
WSFEv1.OlePropertyGet("AuthServerStatus") != VWS("OK"))
{
throw EAFIP("Aparentemente uno de los servidores está fuera de servicio");
}
// Obtengo el número del último comprobante
fe.cbte_nro = WSFEv1.OleFunction("CompUltimoAutorizado",
fe.tipo_cbte,
punto_vta);
excepcion = WSFEv1.OlePropertyGet("Excepcion");
if (! excepcion.IsEmpty())
{
throw EAFIP("CompUltimoAutorizado:\n" + excepcion);
}
// Número del próximo comprobante
fe.cbte_nro++;
// Establezco los valores de la factura
WSFEv1.OleFunction("CrearFactura",
VWS(1), // concepto (1: Producto)
VWS(80), // tipo_doc (80: CUIT)
VWS(SinGuiones(fe.nro_doc)), // nro_doc
VWS(fe.tipo_cbte), // tipo_cbte
VWS(punto_vta), // punto_vta
VWS(fe.cbte_nro), // cbt_desde
VWS(fe.cbte_nro), // cbt_hasta
VWS(fe.imp_total), // imp_total
VWS("0.00"), // imp_tot_conc
VWS(fe.imp_neto), // imp_neto
VWS(fe.imp_iva), // imp_iva
VWS("0.00"), // imp_trib
VWS("0.00"), // imp_op_ex
VWS(fe.fecha_cbte.FormatString("yyyymmdd")), // fecha_cbte
VWS(""), // fecha_venc_pago
VWS(""), // fecha_serv_desde
VWS(""), // fecha_serv_hasta
VWS("PES"), // moneda_id
VWS("1.000")); // moneda_ctz
// Agrego tasa de IVA
WSFEv1.OleFunction("AgregarIva",
VWS(5), // iva_id (5: 21%)
VWS(fe.imp_neto), // base_imp
VWS(fe.imp_iva)); // importe
// Si es NC o ND agrego comprobante asociado
if (fe.tipo_cbte == 2 ||
fe.tipo_cbte == 3 ||
fe.tipo_cbte == 7 ||
fe.tipo_cbte == 8)
{
WSFEv1.OleFunction("AgregarCmpAsoc",
VWS(fe.tipo_cbte_asoc),
VWS(punto_vta),
VWS(fe.cbte_nro_asoc));
}
// Solicito CAE, y guardo pedido y respuesta XML
WSFEv1.OleFunction("CAESolicitar");
excepcion = WSFEv1.OlePropertyGet("Excepcion");
fichlog.open("AFIP_XML.log", ofstream::out | ofstream::app);
fichlog << "***** " << Date().FormatString("dd/mm/yyyy").c_str()
<< " - " << Time().FormatString("hh:nn").c_str() << " *****"
<< endl << endl << "XmlRequest:" << endl
<< AnsiString(WSFEv1.OlePropertyGet("XmlRequest")).c_str()
<< endl << endl << "XmlResponse:" << endl
<< AnsiString(WSFEv1.OlePropertyGet("XmlResponse")).c_str()
<< endl << endl << endl;
fichlog.close();
if (! excepcion.IsEmpty())
{
throw EAFIP("CAESolicitar: " + excepcion);
}
fe.cae = WSFEv1.OlePropertyGet("cae");
fe.obs_afip = WSFEv1.OlePropertyGet("obs");
if (fe.cae == "" || WSFEv1.OlePropertyGet("Resultado") != VWS("A"))
{
throw EAFIP("*** LA OPERACIÓN NO FUE APROBADA ***\n\n" + fe.obs_afip);
}
fe.vto_cae = StringToDate(WSFEv1.OlePropertyGet("Vencimiento"));
// Guardo los eventos (mantenimiento programados y otros mensajes de la AFIP)
eventos = WSFEv1.OlePropertyGet("eventos");
fe.eventos.clear();
for (int c = eventos.ArrayLowBound(); c <= eventos.ArrayHighBound(); c++)
{
ficheventos.open("AFIP_eventos.log", ofstream::out | ofstream::app);
ficheventos << "[" << Date().FormatString("dd/mm/yyyy").c_str()
<< " - " << Time().FormatString("hh:nn").c_str()
<< "] " << AnsiString(eventos.GetElement(c)).c_str()
<< endl;
ficheventos.close();
fe.eventos.push_back(AnsiString(eventos.GetElement(c)));
}
// Realizo comprobaciones adicionales
cae_comp = WSFEv1.OleFunction("CompConsultar", fe.tipo_cbte, punto_vta, fe.cbte_nro);
excepcion = WSFEv1.OlePropertyGet("Excepcion");
if (! excepcion.IsEmpty())
{
throw EAFIPAdv("El comprobante fue autorizado pero no pudo ser recuperado. "
"Si este problema se vuelve a repetir por favor informarlo "
"al programador.");
}
if (fe.cae != cae_comp)
{
throw EAFIPAdv("El comprobante fue autorizado pero se encontró una inconsistencia. "
"Si este problema se vuelve a repetir por favor informarlo "
"al programador.");
}
}
//---------------------------------------------------------------------------
void AFIP::GenerarPDF(FE &fe, AnsiString fichpdf)
{
AnsiString excepcion;
// CUIT del emisor (necesario para el código de barras)
PyFEPDF.OlePropertySet("CUIT", VWS(SinGuiones(cuit)));
// Establezco formatos (cantidad de decimales)
PyFEPDF.OlePropertySet("FmtCantidad", VWS("0.0"));
PyFEPDF.OlePropertySet("FmtPrecio", VWS("0.2"));
// Creo la factura (internamente en la interfaz)
PyFEPDF.OleFunction("CrearFactura",
VWS(1), // concepto (1: Producto)
VWS(80), // tipo_doc (80: CUIT)
VWS(SinGuiones(fe.nro_doc)), // nro_doc
VWS(fe.tipo_cbte), // tipo_cbte
VWS(punto_vta), // punto_vta
VWS(fe.cbte_nro), // cbte_nro
VWS(fe.imp_total), // imp_total
VWS("0.00"), // imp_tot_conc
VWS(fe.imp_neto), // imp_neto
VWS(fe.imp_iva), // imp_iva
VWS("0.00"), // imp_trib
VWS("0.00"), // imp_op_ex
VWS(fe.fecha_cbte.FormatString("yyyymmdd")), // fecha_cbte
VWS(""), // fecha_venc_pago
VWS(""), // fecha_serv_desde
VWS(""), // fecha_serv_hasta
VWS("PES"), // moneda_id
VWS("1.000"), // moneda_ctz
VWS(fe.cae), // cae
VWS(fe.vto_cae.FormatString("yyyymmdd")), // fecha_vto_cae
VWS(fe.id_impositivo), // id_impositivo
VWS(fe.nombre_cliente), // nombre_cliente
VWS(fe.domicilio_cliente), // domicilio_cliente
VWS(""), // pais_dst_cmp
VWS(""), // obs_comerciales
VWS(fe.obs_generales), // obs_generales
VWS("Contado"), // forma_pago
VWS(""), // incoterms
VWS(""), // idioma_cbte
VWS(fe.obs_afip)); // motivos_obs
// Datos de la empresa
PyFEPDF.OleFunction("AgregarDato",
VWS("logo"),
VWS(GetCurrentDir() + "\\plantillas\\logo.png"));
PyFEPDF.OleFunction("AgregarDato",
VWS("MEMBRETE2"),
VWS("742 de Evergreen Terrace"));
PyFEPDF.OleFunction("AgregarDato",
VWS("MEMBRETE3"),
VWS("Springfield"));
PyFEPDF.OleFunction("AgregarDato",
VWS("IVA"),
VWS("IVA Responsable Inscripto"));
PyFEPDF.OleFunction("AgregarDato",
VWS("CUIT"),
VWS("CUIT: " + cuit));
PyFEPDF.OleFunction("AgregarDato",
VWS("IIBB"),
VWS("Ing. Brutos: 123-456789-0"));
PyFEPDF.OleFunction("AgregarDato",
VWS("Inicio"),
VWS("Inicio de Actividad: 01/09/2012"));
// Más datos del cliente
PyFEPDF.OleFunction("EstablecerParametro",
VWS("localidad_cliente"),
VWS(fe.localidad_cliente));
PyFEPDF.OleFunction("EstablecerParametro",
VWS("provincia_cliente"),
VWS(fe.provincia_cliente));
// Blanqueo elementos que no quiero que se vean
vector<AnsiString> items;
vector<AnsiString>::const_iterator it;
items.push_back("Pedido.L");
items.push_back("Remito.L");
items.push_back("VencimientoL");
items.push_back("Item.Codigo");
items.push_back("Item.Bonificacion");
items.push_back("Item.AlicuotaIVA");
items.push_back("descuento.L");
items.push_back("descuento");
items.push_back("NGRA.L");
items.push_back("imp_tot_conc");
items.push_back("EXENTO.L");
items.push_back("imp_op_ex");
items.push_back("custom-tit-transporte");
//items.push_back("NETO.L");
//items.push_back("NETO");
for (it = items.begin(); it != items.end(); it++)
{
PyFEPDF.OleFunction("EstablecerParametro",
VWS(*it),
VWS(""));
}
// Numero de control
PyFEPDF.OleFunction("EstablecerParametro",
VWS("Pagina"),
VWS(AnsiString("Nro Ctrl: ") + fe.nro_ctrl));
// Items de la factura
for (unsigned c = 0; c < fe.items.size(); c++)
{
PyFEPDF.OleFunction("AgregarDetalleItem",
VWS(""), // u_mtx
VWS(""), // cod_mtx
VWS(""), // codigo
VWS(fe.items[c].ds), // ds
VWS(fe.items[c].qty), // qty
VWS(7), // umed (7: unidades)
VWS(fe.items[c].precio), // precio
VWS(""), // bonif
VWS(1), // iva_id (1: No gravado)
VWS(""), // imp_iva
VWS(fe.items[c].importe), // importe
VWS("")); // despacho
}
// Descuento
if (fe.desc > 0)
{
AnsiString ds = "Descuento: " + AnsiString(fe.desc) + "%";
PyFEPDF.OleFunction("AgregarDetalleItem",
VWS(""), // u_mtx
VWS(""), // cod_mtx
VWS(""), // codigo
VWS(ds), // ds
VWS(""), // qty
VWS(0), // umed (0: sin unidad)
VWS(""), // precio
VWS(""), // bonif
VWS(1), // iva_id (1: No gravado)
VWS(""), // imp_iva
VWS(- fe.imp_desc), // importe
VWS("")); // despacho
}
// IVA
if (fe.imp_iva != 0)
{
PyFEPDF.OleFunction("AgregarIva",
VWS(5), // iva_id (5: 21%)
VWS(fe.imp_neto), // base_imp
VWS(fe.imp_iva)); // importe
}
// Cargo el formato desde el archivo CSV
PyFEPDF.OleFunction("CargarFormato",
VWS(GetCurrentDir() + "\\plantillas\\factura.csv"));
// Creo plantilla para esta factura (papel A4 vertical)
PyFEPDF.OleFunction("CrearPlantilla",
VWS("A4"), // papel (A4, letter o legal)
VWS("portrait")); // orientacion (portrait o landscape)
// Proceso la plantilla
PyFEPDF.OleFunction("ProcesarPlantilla",
VWS(2), // num_copias
VWS(24), // lineas_max
VWS("izq")); // qty_pos
// Genero el PDF
PyFEPDF.OleFunction("GenerarPDF", VWS(fichpdf));
}
//---------------------------------------------------------------------------
AnsiString AFIP::ObtenerDenominacion(AnsiString cuit)
{
AnsiString excepcion;
Variant ta;
AnsiString denominacion;
// Llamo al web service para autenticar
ta = WSAA.OleFunction("Autenticar",
VWS("ws_sr_padron_a5"), // servicio a acceder
VWS(fichcert), // certificado firmado por la afip
VWS(fichclave), // clave privada usada para crear el certificado
VWS(URL_WSAA)); // url WSAA
excepcion = WSAA.OlePropertyGet("Excepcion");
if (! excepcion.IsEmpty())
{
throw EAFIP("WSSrPadronA5.Autentificar:\n" + excepcion);
}
// Seteo ticket acceso
WSSrPadronA5.OleFunction("SetTicketAcceso", ta);
// Seteo CUIT del consultor
WSSrPadronA5.OlePropertySet("Cuit", VWS(SinGuiones(AFIP::cuit)));
// Conecto al Servicio Web de Padrón A5
WSSrPadronA5.OleFunction("Conectar",
VWS(""), // cache
VWS(URL_WSSrPadronA5)); // url WSSrPadronA5
excepcion = WSSrPadronA5.OlePropertyGet("Excepcion");
if (! excepcion.IsEmpty())
{
throw EAFIP("WSSrPadronA5.Conectar:\n" + excepcion);
}
// Obtengo la denominación del CUIT
WSSrPadronA5.OleFunction("Consultar", VWS(SinGuiones(cuit)));
excepcion = WSSrPadronA5.OlePropertyGet("Excepcion");
if (! excepcion.IsEmpty())
{
throw EAFIP("WSSrPadronA5.Consultar:\n" + excepcion);
}
denominacion = WSSrPadronA5.OlePropertyGet("denominacion");
if (denominacion.IsEmpty()) { // por si retorna una cadena vacía
throw EAFIP("Error al consultar el CUIT en el padrón de la AFIP");
}
return denominacion;
}
//---------------------------------------------------------------------------