-
Notifications
You must be signed in to change notification settings - Fork 21
/
consultas.py
339 lines (309 loc) · 16.2 KB
/
consultas.py
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
#!/usr/bin/python
# -*- coding: utf-8 -*-
"Aplicativo Factura Electronica Libre"
from __future__ import with_statement # for python 2.5 compatibility
__author__ = "Mariano Reingart ([email protected])"
__copyright__ = "Copyright (C) 2015- Mariano Reingart"
__license__ = "GPL 3.0+"
__version__ = "0.7c"
# Documentación: http://www.sistemasagiles.com.ar/trac/wiki/PyFactura
import calendar
import datetime
import decimal
import os
import time
import traceback
import sys
from ConfigParser import SafeConfigParser
import gui # import gui2py package (shortcuts)
from pyafipws.padron import PadronAFIP
from pyafipws.sired import SIRED
from pyafipws.wsaa import WSAA
from pyafipws.wsfev1 import WSFEv1
from pyafipws.pyfepdf import FEPDF
from pyafipws.pyemail import PyEmail
# set default locale to handle correctly numeric format (maskedit):
import wx, locale
if sys.platform == "win32":
locale.setlocale(locale.LC_ALL, 'Spanish_Argentina.1252')
elif sys.platform == "linux2":
locale.setlocale(locale.LC_ALL, 'es_AR.utf8')
loc = wx.Locale(wx.LANGUAGE_DEFAULT, wx.LOCALE_LOAD_DEFAULT)
CONFIG_FILE = "rece.ini"
HOMO = WSAA.HOMO or WSFEv1.HOMO
import datos
# --- here go your event handlers ---
def on_tipo_doc_change(evt):
ctrl = evt.target
value = ""
if ctrl.value == 80:
mask = '##-########-#'
elif ctrl.value == 99:
mask = '#'
value = "0"
#on_nro_doc_change(evt)
else:
mask = '########'
panel['criterios']['nro_doc'].mask = mask
panel['criterios']['nro_doc'].value = value
def buscar(evt, fn=SIRED().Consultar):
listado = mywin['panel']['listado']
listado.items.clear()
# obtengo criterio de busqueda:
tipo_doc = panel['criterios']['tipo_doc'].value
nro_doc = panel['criterios']['nro_doc'].value.replace("-", "").strip()
nro_doc = int(nro_doc) if nro_doc else None
nombre_cliente = panel['criterios']['nombre_cliente'].value
tipo_cbte = panel['criterios']['tipo_cbte'].value
pto_vta = panel['criterios']['pto_vta'].value
nro_cbte_desde = panel['criterios']['nro_cbte_desde'].value
nro_cbte_hasta = panel['criterios']['nro_cbte_hasta'].value
fecha_cbte_hasta = panel['criterios']['fecha_cbte_hasta'].value
fecha_cbte_desde = panel['criterios']['fecha_cbte_desde'].value
cae = panel['criterios']['cae'].value
aceptado = panel['criterios']['aceptado'].value
# utilizar la funcion para obtener los comprobantes (desde SIRED/WSFEv1)
kwargs = dict(tipo_cbte=tipo_cbte, punto_vta=pto_vta,
cbte_desde=nro_cbte_desde, cbte_hasta=nro_cbte_hasta)
for reg in fn(**kwargs):
# convertir a fecha el formato de AFIP
if not isinstance(reg['fecha_cbte'], datetime.date):
reg['fecha_cbte'] = datetime.datetime.strptime(reg['fecha_cbte'], "%Y%m%d").date()
# aplico filtros
if aceptado and reg['resultado'] != 'A':
continue
if nro_doc and (reg['nro_doc'] != nro_doc or reg['tipo_doc'] != tipo_doc):
print "filtrado por nro_doc", tipo_doc, nro_doc
continue
if nombre_cliente and not reg['nombre_cliente'].lower().startswith(nombre_cliente.lower()):
print "filtrado por nombre"
continue
if tipo_cbte and reg['tipo_cbte'] != tipo_cbte:
print "filtrado por tipo_cbte"
continue
if pto_vta and reg['punto_vta'] != pto_vta:
print "filtrado por punto_vta", pto_vta, reg['punto_vta']
continue
if nro_cbte_desde and not reg['cbte_nro'] >= nro_cbte_desde:
print "filtrado por cbte_nro_desde", nro_cbte_desde, reg['cbte_nro']
continue
if nro_cbte_hasta and not reg['cbte_nro'] <= nro_cbte_hasta:
print "filtrado por cbte_nro_hasta", nro_cbte_hasta, reg['cbte_nro']
continue
if fecha_cbte_desde and not reg['fecha_cbte'] >= fecha_cbte_desde:
print "filtrado por fecha_cbte_desde", fecha_cbte_desde, reg['fecha_cbte']
continue
if fecha_cbte_hasta and not reg['fecha_cbte'] <= fecha_cbte_hasta:
print "filtrado por fecha_cbte_hasta", fecha_cbte_hasta, reg['fecha_cbte']
continue
if cae and reg['cae'] != cae:
print "filtrado por cae", cae, reg['cae']
continue
# agrego el registro al listado:
for it in reg.get('ivas', reg.get('iva', [])):
reg['imp_iva_%d' % it['iva_id']] = it['importe']
listado.items[reg['id']] = reg
def exportar(evt):
from pyafipws.formatos.formato_csv import desaplanar, aplanar, escribir
# adapto los datos al formato de pyrece:
items = [item.copy() for item in listado.items]
for item in items:
item['cbt_numero'] = item['cbte_nro']
item['fecha_cbte'] = item['fecha_cbte'].strftime("%Y%m%d")
if not 'tributos' in items:
item['tributos'] = []
if not 'ivas' in items:
item['ivas'] = []
filas1 = aplanar(items)
print filas1
# elejir nombre de archivo:
result = gui.save_file(title='Guardar', filename="facturas-exportar.csv",
wildcard='|'.join(["Archivos CSV (*.csv)|*.csv"]))
if result:
filename = result[0]
escribir(filas1, filename)
def reporte(evt):
# elejir nombre de archivo:
result = gui.save_file(title='Guardar', filename="facturas-reporte.html",
wildcard='|'.join(["Archivos HTML (*.html)|*.html"]))
if result:
filename = result[0]
f = open(filename, "w")
f.write("<HTML><BODY><TABLE>\n")
f.write("<TR>\n")
for col in listado:
f.write("<TH>%s</TH>\n" % col.text)
f.write("</TR>\n")
for it in listado.items:
f.write("<TR>")
for col in listado:
if it[col.name] is None:
v = ""
elif callable(col.represent):
v = col.represent(it[col.name])
elif col.represent:
v = col.represent % it[col.name]
else:
v = it[col.name]
if isinstance(v, unicode):
v = v.encode("latin1", "ignore")
f.write("<TD>%s</TD>" % v)
f.write("</TR>\n")
f.write("</TR></TABLE></BODY></HTML>\n")
f.close()
# --- gui2py designer generated code starts ---
with gui.Window(name='consultas',
title=u'Aplicativo Facturaci\xf3n Electr\xf3nica',
resizable=True, height='636px', left='181', top='52',
width='794px', image='', ):
with gui.MenuBar(name='menubar_83_155', ):
with gui.Menu(name='menu_114', ):
gui.MenuItemSeparator(name='menuitemseparator_130', )
gui.StatusBar(name='statusbar_15_91',
text=u'Servicio Web Factura Electr\xf3nica mercado interno (WSFEv1)', )
with gui.Panel(label=u'', name='panel', image='', ):
gui.Image(name='image_507_571', height='36', left='17', top='545',
width='238', filename='sistemas-agiles.png', )
gui.Image(name='image_33_540', height='50', left='665', top='532',
width='100', filename='logo-pyafipws.png', )
with gui.ListView(name='listado', height='353', left='7', top='168',
width='775', item_count=0, sort_column=-1, ):
gui.ListColumn(name=u'tipo_cbte', text='Tipo Cbte')
gui.ListColumn(name=u'punto_vta', text='Punto Venta',
represent="%s", width=50, align="right")
gui.ListColumn(name=u'cbte_nro', text='Nro Cbte',
represent="%s", align="right")
gui.ListColumn(name=u'fecha_cbte', text='Fecha Cbte',
align="center")
gui.ListColumn(name=u'tipo_doc', text='Tipo Doc', width=50)
gui.ListColumn(name=u'nro_doc', text='Nro Doc', width=100,
represent="%s", align="right")
gui.ListColumn(name=u'nombre_cliente', text='Cliente', width=150)
gui.ListColumn(name=u'id_impositivo', text='Cond. IVA', width=50,
represent="%s", align="left")
gui.ListColumn(name=u'imp_total', text='Total', width=100,
represent=lambda x: locale.format("%.2f", x), align="right")
gui.ListColumn(name=u'imp_op_ex', text='Exento', width=100,
represent=lambda x: locale.format("%.2f", x), align="right")
gui.ListColumn(name=u'imp_tot_conc', text='No Gravado', width=100,
represent=lambda x: locale.format("%.2f", x), align="right")
gui.ListColumn(name=u'imp_neto', text='Neto', width=100,
represent=lambda x: locale.format("%.2f", x), align="right")
gui.ListColumn(name=u'imp_iva_4', text='IVA 10.5%', width=100,
represent=lambda x: locale.format("%.2f", x), align="right")
gui.ListColumn(name=u'imp_iva_5', text='IVA 21%', width=100,
represent=lambda x: locale.format("%.2f", x), align="right")
gui.ListColumn(name=u'imp_iva_6', text='IVA 27%', width=100,
represent=lambda x: locale.format("%.2f", x), align="right")
gui.ListColumn(name=u'imp_trib', text='Tributos', width=100,
represent=lambda x: locale.format("%.2f", x), align="right")
gui.ListColumn(name=u'fecha_vto', text='Vto. CAE', align="left",
represent=lambda x: str(x) if x else "")
gui.ListColumn(name=u'cae', text='CAE', width=50, align="right",
represent=lambda x: str(x) if x else "")
gui.Button(label=u'Recuperar', name=u'recuperar', left='205', top='542',
width='80', default=True)
gui.Button(label=u'Buscar', name=u'buscar', left='295', top='542',
width='75', default=True, onclick=buscar)
gui.Label(name='label_22_147', left='12', top='144',
text=u'Resultados:', )
with gui.Panel(label=u'Criterios de B\xfasqueda:', name='criterios',
height='135', left='6', top='9', width='778',
bgcolor=u'#F9F9F8', fgcolor=u'#4C4C4C', image='', ):
gui.Label(name='label_182_163', height='21', left='16', top='31',
width='38', text=u'Cliente:', )
gui.ComboBox(name='tipo_doc', text=u'CF', left='75', top='23',
width='78', onchange=on_tipo_doc_change,
items=[u'CUIT', u'DNI', u'CF', u'Pasaporte'],
selection=3, value=u'CF', )
gui.TextBox(mask='##-########-#', name='nro_doc', left='164',
top='24', width='110', text=u'20-26756539-3',
value=u'20-26756539-3', )
gui.Label(name='label_268_164', height='31', left='295', top='28',
width='61', text=u'Nombre:', )
gui.TextBox(name='nombre_cliente', left='367', top='23',
width='240', value=u'Mariano Reingart', )
gui.Label(name='label_24_16', height='17', left='12', top='64',
width='146', text=u'Tipo Comprobante:', )
gui.ComboBox(name=u'tipo_cbte', left='151', top='58', width='170',
items=[u'Factura A', u'Factura B', u'Factura C', ], )
gui.Label(name='label_356_21_178', height='17', left='262',
top='96', width='20', text=u'Hasta:', )
gui.TextBox(mask='####', name=u'pto_vta', alignment='right',
left='365', top='59', width='47', value=99, )
gui.Label(name='label_356_21_155', height='17', left='15',
top='96', width='60', text=u'Fecha:', )
gui.Label(id=2293, name='label_356_21_178_2293', height='17',
left='329', top='64', width='29', text=u'P.V.:', )
gui.Label(id=2591, name='label_356_21_178_2591', height='17',
left='72', top='96', width='47', text=u'Desde:', )
gui.TextBox(id=2794, mask='date', name=u'fecha_cbte_hasta',
height='29', left='308', top='91', width='122',
bgcolor=u'#F2F1F0', fgcolor=u'#4C4C4C',
value=datetime.date(2014, 5, 27), )
gui.TextBox(id=290, mask='date', name=u'fecha_cbte_desde',
height='29', left='131', top='91', width='122',
bgcolor=u'#F2F1F0', fgcolor=u'#4C4C4C',
value=datetime.date(2014, 5, 27), )
gui.TextBox(id=2361, mask='########', name=u'nro_cbte_hasta',
alignment='right', height='27', left='654', top='59',
width='92', bgcolor=u'#FFFFFF', fgcolor=u'#000000',
value=12345678, )
gui.TextBox(mask='########', name=u'nro_cbte_desde',
alignment='right', height='27', left='481', top='59',
width='92', bgcolor=u'#FFFFFF', fgcolor=u'#000000',
value=12345678, )
gui.Label(name='label_26_372_2499_2861', height='17', left='439',
top='98', width='39', text=u'CAE:', )
gui.TextBox(name='cae', left='480', top='93', width='153',
text=u'123456789012345',
tooltip=u'CAE o c\xf3digo de barras',
value=u'123456789012345', )
gui.CheckBox(label=u'Aprobado', name=u'aceptado', height='24',
left='655', top='94', width='114', value=True, )
gui.Label(id=1243, name='label_356_21_178_2591_1243', height='17',
left='423', top='63', width='47', text=u'Desde:', )
gui.Label(id=1343, name='label_356_21_178_1343', height='17',
left='593', top='64', width='44', text=u'Hasta:', )
gui.Button(label=u'Cargar', name=u'cargar', left='379', top='542',
width='73', fgcolor=u'#4C4C4C', )
gui.Button(label=u'Exportar', name=u'exportar', left='458', top='542',
width='75', fgcolor=u'#4C4C4C', onclick=exportar)
gui.Button(id=188, label=u'Reporte', name=u'reporte', left='542',
top='542', width='75', fgcolor=u'#4C4C4C', onclick=reporte)
# --- gui2py designer generated code ends ---
# obtener referencia a la ventana principal:
mywin = gui.get("consultas")
panel = mywin['panel']
listado = panel['listado']
def main(callback=None, recuperar_fn=None):
global mywin, panel, listado
# limpiar valores del diseñador:
panel['criterios']['tipo_doc'].items = datos.TIPO_DOC_MAP
panel['criterios']['tipo_doc'].value = 80 # CUIT
panel['criterios']['nro_doc'].value = None
panel['criterios']['nombre_cliente'].value = ""
panel['criterios']['tipo_cbte'].items = datos.TIPO_CBTE_MAP
panel['criterios']['tipo_cbte'].value = None
panel['criterios']['pto_vta'].value = None
panel['criterios']['nro_cbte_desde'].value = None
panel['criterios']['nro_cbte_hasta'].value = None
# utilizar el mes actual (dia inicio y finalización):
hoy = datetime.date.today()
r = calendar.monthrange(hoy.year, hoy.month)
desde = datetime.date(hoy.year, hoy.month, r[0] + 1)
hasta = datetime.date(hoy.year, hoy.month, r[1])
panel['criterios']['fecha_cbte_hasta'].value = hasta
panel['criterios']['fecha_cbte_desde'].value = desde
panel['criterios']['cae'].value = ""
# mostrar la representación más amigable de los códigos de AFIP
listado['tipo_doc'].represent = lambda x: datos.TIPO_DOC_MAP[x]
listado['tipo_cbte'].represent = lambda x: datos.TIPO_CBTE_MAP[x]
listado['fecha_cbte'].represent = lambda x: x.strftime("%x")
if callback:
panel['cargar'].onclick = lambda evt: callback(listado.get_selected_items()[0])
panel['recuperar'].onclick = lambda evt: buscar(evt, recuperar_fn)
mywin.show()
if __name__ == "__main__":
main()
gui.main_loop()