1 | ' Ejemplo de Uso de Interface COM con Web Service Factura Electrónica Mercado Interno AFIP |
---|
2 | ' Según RG2485 y RG2904 ArtÃculo 4 Opción B (sin detalle, Version 1) |
---|
3 | ' 2010 (C) Mariano Reingart <reingart@gmail.com> |
---|
4 | ' Licencia: GPLv3 |
---|
5 | |
---|
6 | Sub Main() |
---|
7 | Dim WSAA As Object, WSFEv1 As Object |
---|
8 | |
---|
9 | On Error GoTo ManejoError |
---|
10 | |
---|
11 | |
---|
12 | ' Una vez obtenido, se puede usar el mismo token y sign por 10 horas |
---|
13 | ' (este perÃodo se puede cambiar) |
---|
14 | ' revisar WSAA.Expirado() y en dicho caso tramitar nuevo TA |
---|
15 | |
---|
16 | ' Crear objeto interface Web Service de Factura Electrónica de Mercado Interno |
---|
17 | Set WSFEv1 = CreateObject("WSFEv1") |
---|
18 | Debug.Print WSFEv1.Version |
---|
19 | 'Debug.Print WSFEv1.InstallDir |
---|
20 | |
---|
21 | ' Setear tocken y sing de autorización (pasos previos) |
---|
22 | ''WSFEv1.Token = WSAA.Token |
---|
23 | ''WSFEv1.Sign = WSAA.Sign |
---|
24 | |
---|
25 | ' CUIT del emisor (debe estar registrado en la AFIP) |
---|
26 | WSFEv1.Cuit = "20267565393" |
---|
27 | |
---|
28 | ' deshabilito errores no manejados |
---|
29 | WSFEv1.LanzarExcepciones = False |
---|
30 | |
---|
31 | ' Conectar al Servicio Web de Facturación |
---|
32 | proxy = "" ' "usuario:clave@localhost:8000" |
---|
33 | wsdl = "https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL" |
---|
34 | cache = "" 'Path |
---|
35 | wrapper = "" ' libreria http (httplib2, urllib2, pycurl) |
---|
36 | |
---|
37 | ok = WSFEv1.Conectar(cache, wsdl, proxy, wrapper, cacert) ' homologación |
---|
38 | Debug.Print WSFEv1.Version |
---|
39 | ControlarExcepcion WSFEv1 |
---|
40 | |
---|
41 | ' mostrar bitácora de depuración: |
---|
42 | Debug.Print WSFEv1.DebugLog |
---|
43 | |
---|
44 | ' Llamo a un servicio nulo, para obtener el estado del servidor (opcional) |
---|
45 | WSFEv1.Dummy |
---|
46 | ControlarExcepcion WSFEv1 |
---|
47 | Debug.Print "appserver status", WSFEv1.AppServerStatus |
---|
48 | Debug.Print "dbserver status", WSFEv1.DbServerStatus |
---|
49 | Debug.Print "authserver status", WSFEv1.AuthServerStatus |
---|
50 | |
---|
51 | |
---|
52 | 'TipoCamioAfip = WSFEv1.ParamGetCotizacion("DOL", "20250403") |
---|
53 | Debug.Print WSFEv1.XmlRequest |
---|
54 | Debug.Print WSFEv1.XmlResponse |
---|
55 | MsgBox TipoCambioAfip |
---|
56 | |
---|
57 | cbte_nro = 0 ' no hay comprobantes emitidos |
---|
58 | fecha = Format(Date, "yyyymmdd") |
---|
59 | concepto = 1 |
---|
60 | tipo_doc = 80: nro_doc = "33693450239" |
---|
61 | cbte_nro = cbte_nro + 1 |
---|
62 | cbt_desde = cbte_nro: cbt_hasta = cbte_nro |
---|
63 | imp_total = "179.25": imp_tot_conc = "2.00": imp_neto = "150.00" |
---|
64 | imp_iva = "26.25": imp_trib = "1.00": imp_op_ex = "0.00" |
---|
65 | fecha_cbte = fecha: fecha_venc_pago = "" |
---|
66 | ' Fechas del perÃodo del servicio facturado (solo si concepto = 1?) |
---|
67 | fecha_serv_desde = "": fecha_serv_hasta = "" |
---|
68 | moneda_id = "PES": moneda_ctz = "1.000" |
---|
69 | |
---|
70 | ok = WSFEv1.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, _ |
---|
71 | cbt_desde, cbt_hasta, imp_total, imp_tot_conc, imp_neto, _ |
---|
72 | imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, _ |
---|
73 | fecha_serv_desde, fecha_serv_hasta, _ |
---|
74 | moneda_id, moneda_ctz) |
---|
75 | |
---|
76 | ' Agrego los comprobantes asociados: |
---|
77 | If False Then ' solo nc/nd |
---|
78 | tipo = 19 |
---|
79 | pto_vta = 2 |
---|
80 | nro = 1234 |
---|
81 | ok = WSFEv1.AgregarCmpAsoc(tipo, pto_vta, nro) |
---|
82 | End If |
---|
83 | |
---|
84 | ' Agrego impuestos varios |
---|
85 | id = 99 |
---|
86 | Desc = "Impuesto Municipal Matanza'" |
---|
87 | base_imp = "100.00" |
---|
88 | alic = "0.10" |
---|
89 | importe = "0.10" |
---|
90 | ok = WSFEv1.AgregarTributo(id, Desc, base_imp, alic, importe) |
---|
91 | |
---|
92 | ' Agrego impuestos varios |
---|
93 | id = 4 |
---|
94 | Desc = "Impuestos internos" |
---|
95 | base_imp = "100.00" |
---|
96 | alic = "0.40" |
---|
97 | importe = "0.40" |
---|
98 | ok = WSFEv1.AgregarTributo(id, Desc, base_imp, alic, importe) |
---|
99 | |
---|
100 | ' Agrego impuestos varios |
---|
101 | id = 1 |
---|
102 | Desc = "Impuesto nacional" |
---|
103 | base_imp = "50.00" |
---|
104 | alic = "1.00" |
---|
105 | importe = "0.50" |
---|
106 | ok = WSFEv1.AgregarTributo(id, Desc, base_imp, alic, importe) |
---|
107 | |
---|
108 | ' Agrego tasas de IVA |
---|
109 | id = 5 ' 21% |
---|
110 | base_imp = "100.00" |
---|
111 | importe = "21.00" |
---|
112 | ok = WSFEv1.AgregarIva(id, base_imp, importe) |
---|
113 | |
---|
114 | ' Agrego tasas de IVA al 0% (imp_tot_conc, solo para pruebas) |
---|
115 | id = 4 ' 10.5% |
---|
116 | base_imp = "50.00" |
---|
117 | importe = "5.25" |
---|
118 | ok = WSFEv1.AgregarIva(id, base_imp, importe) |
---|
119 | |
---|
120 | ' Agrego datos opcionales RG 3668 Impuesto al Valor Agregado - Art.12 ("presunci??e no vinculaci??on la actividad gravada", F.8001): |
---|
121 | If tipo_cbte = 1 Then ' solo para facturas A |
---|
122 | ok = WSFEv1.AgregarOpcional(5, "02") ' IVA Excepciones (01: Locador/Prestador, 02: Conferencias, 03: RG 74, 04: Bienes de cambio, 05: Ropa de trabajo, 06: Intermediario). |
---|
123 | ok = WSFEv1.AgregarOpcional(61, "80") ' Firmante Doc Tipo (80: CUIT, 96: DNI, etc.) |
---|
124 | ok = WSFEv1.AgregarOpcional(62, "20267565393") ' Firmante Doc Nro |
---|
125 | ok = WSFEv1.AgregarOpcional(7, "01") ' Car?er del Firmante (01: Titular, 02: Director/Presidente, 03: Apoderado, 04: Empleado) |
---|
126 | End If |
---|
127 | |
---|
128 | ' Habilito reprocesamiento automático (predeterminado): |
---|
129 | WSFEv1.Reprocesar = True |
---|
130 | |
---|
131 | ' Agrego RG 5616 |
---|
132 | ok = WSFEv1.EstablecerCampoFactura("cancela_misma_moneda_ext", "N") |
---|
133 | ok = WSFEv1.EstablecerCampoFactura("condicion_iva_receptor_id", "5") |
---|
134 | |
---|
135 | ' Solicito CAE: |
---|
136 | CAE = WSFEv1.CAESolicitar() |
---|
137 | ControlarExcepcion WSFEv1 |
---|
138 | |
---|
139 | Debug.Print "Resultado", WSFEv1.Resultado |
---|
140 | Debug.Print "CAE", WSFEv1.CAE |
---|
141 | |
---|
142 | Debug.Print "Numero de comprobante:", WSFEv1.CbteNro |
---|
143 | |
---|
144 | ' Imprimo pedido y respuesta XML para depuración (errores de formato) |
---|
145 | Debug.Print WSFEv1.XmlRequest |
---|
146 | Debug.Print WSFEv1.XmlResponse |
---|
147 | |
---|
148 | Debug.Print "Reprocesar:", WSFEv1.Reprocesar |
---|
149 | Debug.Print "Reproceso:", WSFEv1.Reproceso |
---|
150 | Debug.Print "CAE:", WSFEv1.CAE |
---|
151 | Debug.Print "EmisionTipo:", WSFEv1.EmisionTipo |
---|
152 | |
---|
153 | MsgBox "Resultado:" & WSFEv1.Resultado & " CAE: " & CAE & " Venc: " & WSFEv1.Vencimiento & " Obs: " & WSFEv1.obs & " Reproceso: " & WSFEv1.Reproceso, vbInformation + vbOKOnly |
---|
154 | |
---|
155 | ' Muestro los errores |
---|
156 | If WSFEv1.errmsg <> "" Then |
---|
157 | MsgBox WSFEv1.errmsg, vbExclamation, "Error" |
---|
158 | End If |
---|
159 | |
---|
160 | ' Muestro los eventos (mantenimiento programados y otros mensajes de la AFIP) |
---|
161 | For Each evento In WSFEv1.eventos: |
---|
162 | MsgBox evento, vbInformation, "Evento" |
---|
163 | Next |
---|
164 | |
---|
165 | ' Buscar la factura |
---|
166 | cae2 = WSFEv1.CompConsultar(tipo_cbte, punto_vta, cbte_nro) |
---|
167 | ControlarExcepcion WSFEv1 |
---|
168 | |
---|
169 | Debug.Print "Fecha Comprobante:", WSFEv1.FechaCbte |
---|
170 | Debug.Print "Fecha Vencimiento CAE", WSFEv1.Vencimiento |
---|
171 | Debug.Print "Importe Total:", WSFEv1.ImpTotal |
---|
172 | Debug.Print "Resultado:", WSFEv1.Resultado |
---|
173 | |
---|
174 | If WSFEv1.Version >= "1.12a" Then |
---|
175 | ok = WSFEv1.AnalizarXml("XmlResponse") |
---|
176 | If ok Then |
---|
177 | Debug.Print "CAE:", WSFEv1.ObtenerTagXml("CodAutorizacion"), WSFEv1.CAE |
---|
178 | Debug.Print "CbteFch:", WSFEv1.ObtenerTagXml("CbteFch"), WSFEv1.FechaCbte |
---|
179 | Debug.Print "Moneda:", WSFEv1.ObtenerTagXml("MonId") |
---|
180 | Debug.Print "Cotizacion:", WSFEv1.ObtenerTagXml("MonCotiz") |
---|
181 | Debug.Print "DocTIpo:", WSFEv1.ObtenerTagXml("DocTipo") |
---|
182 | Debug.Print "DocNro:", WSFEv1.ObtenerTagXml("DocNro") |
---|
183 | |
---|
184 | ' ejemplos con arreglos (primer elemento = 0): |
---|
185 | Debug.Print "Primer IVA (alci id):", WSFEv1.ObtenerTagXml("Iva", "AlicIva", 0, "Id") |
---|
186 | Debug.Print "Primer IVA (importe):", WSFEv1.ObtenerTagXml("Iva", "AlicIva", 0, "Importe") |
---|
187 | Debug.Print "Segundo IVA (alic id):", WSFEv1.ObtenerTagXml("Iva", "AlicIva", 1, "Id") |
---|
188 | Debug.Print "Segundo IVA (importe):", WSFEv1.ObtenerTagXml("Iva", "AlicIva", 1, "Importe") |
---|
189 | Debug.Print "Primer Tributo (ds):", WSFEv1.ObtenerTagXml("Tributos", "Tributo", 0, "Desc") |
---|
190 | Debug.Print "Primer Tributo (importe):", WSFEv1.ObtenerTagXml("Tributos", "Tributo", 0, "Importe") |
---|
191 | Debug.Print "Segundo Tributo (ds):", WSFEv1.ObtenerTagXml("Tributos", "Tributo", 1, "Desc") |
---|
192 | Debug.Print "Segundo Tributo (importe):", WSFEv1.ObtenerTagXml("Tributos", "Tributo", 1, "Importe") |
---|
193 | Debug.Print "Tercer Tributo (ds):", WSFEv1.ObtenerTagXml("Tributos", "Tributo", 2, "Desc") |
---|
194 | Debug.Print "Tercer Tributo (importe):", WSFEv1.ObtenerTagXml("Tributos", "Tributo", 2, "Importe") |
---|
195 | Else |
---|
196 | ' hubo error, muestro mensaje |
---|
197 | Debug.Print WSFEv1.Excepcion |
---|
198 | End If |
---|
199 | End If |
---|
200 | |
---|
201 | If CAE = "" Then |
---|
202 | ' hubo error, no comparo |
---|
203 | ElseIf CAE <> cae2 Then |
---|
204 | MsgBox "El CAE de la factura no concuerdan con el recuperado en la AFIP!: " & CAE & " vs " & cae2 |
---|
205 | Else |
---|
206 | MsgBox "El CAE de la factura concuerdan con el recuperado de la AFIP" |
---|
207 | End If |
---|
208 | |
---|
209 | Exit Sub |
---|
210 | ManejoError: |
---|
211 | ' Si hubo error (tradicional, no controlado): |
---|
212 | |
---|
213 | ' Depuración (grabar a un archivo los detalles del error) |
---|
214 | fd = FreeFile |
---|
215 | Open "c:\error.txt" For Append As fd |
---|
216 | If Not WSAA Is Nothing Then |
---|
217 | If WSAA.Version >= "1.02a" Then |
---|
218 | Print #fd, WSAA.Excepcion |
---|
219 | Print #fd, WSAA.Traceback |
---|
220 | Print #fd, WSAA.XmlRequest |
---|
221 | Print #fd, WSAA.XmlResponse |
---|
222 | ' guardo mensaje de error para mostrarlo: |
---|
223 | Excepcion = WSAA.Excepcion |
---|
224 | End If |
---|
225 | End If |
---|
226 | If Not WSFEv1 Is Nothing Then |
---|
227 | If WSFEv1.Version >= "1.10a" Then |
---|
228 | Print #fd, WSFEv1.Excepcion |
---|
229 | Print #fd, WSFEv1.Traceback |
---|
230 | Print #fd, WSFEv1.XmlRequest |
---|
231 | Print #fd, WSFEv1.XmlResponse |
---|
232 | Print #fd, WSFEv1.DebugLog() |
---|
233 | ' guardo mensaje de error para mostrarlo: |
---|
234 | Excepcion = WSFEv1.Excepcion |
---|
235 | End If |
---|
236 | End If |
---|
237 | Close fd |
---|
238 | |
---|
239 | Debug.Print Err.Description ' descripción error afip |
---|
240 | Debug.Print Err.Number - vbObjectError ' codigo error afip |
---|
241 | If Excepcion = "" Then ' si no tengo mensaje de excepcion |
---|
242 | Excepcion = Err.Description ' uso el error de VB |
---|
243 | End If |
---|
244 | |
---|
245 | ' Mostrar el mensaje de error |
---|
246 | Select Case MsgBox(Excepcion, vbCritical + vbRetryCancel, "Error:" & Err.Number - vbObjectError & " en " & Err.Source) |
---|
247 | Case vbRetry |
---|
248 | Debug.Assert False |
---|
249 | Resume |
---|
250 | Case vbCancel |
---|
251 | Debug.Print Err.Description |
---|
252 | End Select |
---|
253 | End Sub |
---|
254 | |
---|
255 | Sub ControlarExcepcion(obj As Object) |
---|
256 | ' Nueva funcion para verificar que no haya habido errores: |
---|
257 | On Error GoTo 0 |
---|
258 | If obj.Excepcion <> "" Then |
---|
259 | ' Depuración (grabar a un archivo los detalles del error) |
---|
260 | fd = FreeFile |
---|
261 | Open "c:\excepcion.txt" For Append As fd |
---|
262 | Print #fd, obj.Excepcion |
---|
263 | Print #fd, obj.Traceback |
---|
264 | Print #fd, obj.XmlRequest |
---|
265 | Print #fd, obj.XmlResponse |
---|
266 | Close fd |
---|
267 | MsgBox obj.Excepcion, vbExclamation, "Excepción" |
---|
268 | End |
---|
269 | End If |
---|
270 | End Sub |
---|