Skip to content

Commit 38f7d8e

Browse files
committed
Update python3
1 parent 545ddce commit 38f7d8e

File tree

15 files changed

+1563
-34
lines changed

15 files changed

+1563
-34
lines changed

cot.pyw

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
4+
"Aplicativo Visual (Front-end) Remito Electrónico (COT) ARBA"
5+
6+
from __future__ import with_statement
7+
8+
__author__ = "Mariano Reingart ([email protected])"
9+
__copyright__ = "Copyright (C) 2013- Mariano Reingart"
10+
__license__ = "LGPL 3.0"
11+
12+
import datetime
13+
import decimal
14+
import time
15+
import os
16+
import fnmatch
17+
import shelve
18+
import sys
19+
20+
# importar gui2py (atajos)
21+
22+
import gui
23+
24+
# establecer la configuración regional por defecto:
25+
import wx, locale
26+
if sys.platform == "win32":
27+
locale.setlocale(locale.LC_ALL, 'Spanish_Argentina.1252')
28+
elif sys.platform == "linux2":
29+
locale.setlocale(locale.LC_ALL, 'es_AR.utf8')
30+
loc = wx.Locale(wx.LANGUAGE_DEFAULT, wx.LOCALE_LOAD_DEFAULT)
31+
32+
# importar el módulo principal de pyafipws para remito electrónico:
33+
34+
from cot import COT
35+
36+
# --- here goes your event handlers ---
37+
38+
39+
# --- gui2py designer generated code starts ---
40+
41+
with gui.Window(name='mywin', title=u'COT: Remito Electr\xf3nico ARBA',
42+
resizable=True, height='450px', left='180', top='24',
43+
width='550px', bgcolor=u'#E0E0E0', fgcolor=u'#4C4C4C',
44+
image='', ):
45+
gui.StatusBar(name='statusbar', )
46+
with gui.Panel(label=u'', name='panel', image='', ):
47+
gui.TextBox(name='usuario', left='299', top='10', width='105',
48+
value=u'20267565393', )
49+
gui.TextBox(name='clave', password=True, left='455', top='10',
50+
width='75', )
51+
gui.Line(name='line_25_556', height='3', left='24', top='390',
52+
width='499', )
53+
gui.Button(label=u'Salir', name='salir', left='440', top='394',
54+
width='85', onclick='import sys; sys.exit(0)', )
55+
gui.ComboBox(name=u'url',
56+
text=u'http://cot.test.arba.gov.ar/TransporteBienes/SeguridadCliente/presentarRemitos.do',
57+
height='29', left='79', top='42', width='250',
58+
bgcolor=u'#FFFFFF',
59+
data_selection=u'http://cot.test.arba.gov.ar/TransporteBienes/SeguridadCliente/presentarRemitos.do',
60+
fgcolor=u'#4C4C4C',
61+
items=[u'https://cot.arba.gov.ar/TransporteBienes/SeguridadCliente/presentarRemitos.do', u'http://cot.test.arba.gov.ar/TransporteBienes/SeguridadCliente/presentarRemitos.do'],
62+
selection=1,
63+
string_selection=u'http://cot.test.arba.gov.ar/TransporteBienes/SeguridadCliente/presentarRemitos.do', )
64+
gui.Label(name='lblTest_273_363', height='17', left='234', top='15',
65+
width='58', text=u'Usuario:', )
66+
gui.Label(name='lblTest_273', height='17', left='410', top='14',
67+
width='58', text=u'Clave:', )
68+
gui.Gauge(name='gauge', height='18', left='20', top='365',
69+
width='507', )
70+
gui.Label(id=228, name='lblTest_228', height='17', left='341',
71+
top='47', width='32', text=u'Carpeta:', )
72+
with gui.ListView(id=213, name=u'remitos', height='74', left='20',
73+
top='180', width='510', item_count=0, sort_column=0, ):
74+
gui.ListColumn(name=u'nro', text=u'N\xb0 \xdanico Remito',
75+
width=250, )
76+
gui.ListColumn(name=u'proc', text=u'Procesado', )
77+
with gui.ListView(name=u'archivos', height='99', left='21', top='77',
78+
width='509', item_count=0, sort_column=2, ):
79+
gui.ListColumn(name=u'txt', text='Archivo TXT', width=200, )
80+
gui.ListColumn(name=u'xml', text='Archivo XML', )
81+
gui.ListColumn(name=u'cuit', text='CUIT Empresa', )
82+
gui.ListColumn(name=u'nro', text=u'N\xb0 Comprobante', )
83+
gui.ListColumn(name=u'md5', text=u'C\xf3digo Integridad', )
84+
with gui.ListView(id=309, name=u'errores', height='99', left='20',
85+
top='259', width='510', item_count=0, sort_column=0, ):
86+
gui.ListColumn(name=u'codigo', text=u'C\xf3digo', width=100, )
87+
gui.ListColumn(name=u'descripcion', text=u'Descripci\xf3n Error',
88+
width=400, )
89+
gui.TextBox(id=488, mask='date', name='fecha',
90+
left='101', top='10', width='127', enabled=False,
91+
value=datetime.date(2014, 4, 5), )
92+
gui.CheckBox(label=u'Fecha:', name=u'filtrar_fecha', height='24',
93+
left='22', top='11', width='73',
94+
tooltip=u'filtrar por fecha', )
95+
gui.Label(id=2084, name='lblTest_228_2084', height='17', left='24',
96+
top='47', width='32', text=u'URL:', )
97+
gui.ComboBox(id=961, name=u'carpeta', text=u'datos', height='29',
98+
left='412', top='42', width='118', bgcolor=u'#FFFFFF',
99+
data_selection=u'datos', fgcolor=u'#4C4C4C',
100+
items=[u'datos', u'procesados'], selection=0,
101+
string_selection=u'datos', )
102+
gui.Button(label=u'Procesar', name=u'procesar', left='20', top='394',
103+
tooltip="Presentar el remito en ARBA",
104+
width='85', default=True, fgcolor=u'#4C4C4C', )
105+
gui.CheckBox(label=u'Auto:', name=u'auto', height='24',
106+
left='320', top='396', width='73', value=True,
107+
tooltip=u'procesar automaticamente', )
108+
gui.Button(label=u'Mover Procesados', name=u'mover', left='112',
109+
top='394', width='166', fgcolor=u'#4C4C4C', )
110+
111+
# --- gui2py designer generated code ends ---
112+
113+
# get a reference to the Top Level Window (used by designer / events handlers):
114+
mywin = gui.get("mywin")
115+
panel = mywin['panel']
116+
117+
# Manejo simple de claves:
118+
119+
passwd_db = shelve.open("passwd")
120+
121+
def getpass(username):
122+
password = passwd_db.get(str(username))
123+
if not password:
124+
password = gui.prompt(message=u"Ingrese contraseña",
125+
title="Usuario: %s" % username,
126+
password=True) or ""
127+
return password
128+
129+
def setpass(username, password):
130+
passwd_db[str(username)] = password
131+
132+
def grabar_clave(evt):
133+
setpass(panel['usuario'].value, panel['clave'].value)
134+
135+
# asignar controladores
136+
137+
cot = COT()
138+
139+
def listar_archivos(evt=None):
140+
print("listando...", datetime.datetime.now())
141+
# cargar listado de archivos a procesar (y su correspondiente respuesta):
142+
lv = panel['archivos']
143+
lv.clear()
144+
panel['remitos'].clear()
145+
panel['errores'].clear()
146+
# obtengo el fitlro de fecha (si esta habilitado):
147+
if panel['filtrar_fecha'].value:
148+
fecha = panel['fecha'].value.strftime("%Y%m%d")
149+
else:
150+
fecha = None
151+
carpeta = panel['carpeta'].text or "."
152+
for fn in os.listdir(carpeta):
153+
if fnmatch.fnmatch(fn, 'TB_???????????_*.txt'):
154+
# filtro por fecha (si esta tildado):
155+
# TB_20111111112_000000_20080124_000001.txt
156+
fecha_fn = fn[22:30]
157+
if fecha and fecha != fecha_fn:
158+
continue
159+
txt = fn
160+
xml = os.path.splitext(fn)[0] + ".xml"
161+
if not os.path.exists(os.path.join(carpeta, xml)):
162+
xml = ""
163+
elif panel['auto'].value:
164+
continue
165+
lv.items[fn] = {'txt': txt, 'xml': xml}
166+
167+
def procesar_archivos(evt=None):
168+
print("procesando...", datetime.datetime.now())
169+
# establezco la barra de progreso con la cantidad de archivos:
170+
panel['gauge'].max = len(panel['archivos'].items)
171+
# recorro los archivos a procesar:
172+
for i, item in enumerate(panel['archivos'].items):
173+
panel['gauge'].value = i + 1
174+
procesar_archivo(item, enviar=True)
175+
176+
if panel['auto'].value:
177+
mover_archivos()
178+
print("re-agendando...", datetime.datetime.now())
179+
gui.call_later(5000, listar_archivos)
180+
gui.call_later(10000, procesar_archivos)
181+
182+
183+
def cargar_archivo(evt):
184+
# obtengo y proceso el archivo seleccionado:
185+
item = evt.target.get_selected_items()[0]
186+
procesar_archivo(item)
187+
188+
def abrir_archivo(evt):
189+
# obtengo y proceso el archivo seleccionado:
190+
item = evt.target.get_selected_items()[0]
191+
fn = os.path.join(panel['carpeta'].text, item['txt'])
192+
try:
193+
os.startfile(fn)
194+
except AttributeError:
195+
os.system("""gedit "%s" """ % fn)
196+
197+
def procesar_archivo(item, enviar=False):
198+
"Enviar archivo a ARBA y analizar la respuesta"
199+
200+
# establezco credenciales:
201+
cuit = item['txt'][3:14]
202+
cot.Usuario = panel['usuario'].value = cuit
203+
cot.Password = panel['clave'].value = getpass(cuit)
204+
cot.Conectar(panel['url'].text, trace=True)
205+
206+
# obtengo la ruta al archivo de texto y xml
207+
carpeta = panel['carpeta'].text
208+
fn = os.path.join(carpeta, item['txt'])
209+
xml = item['xml']
210+
if xml:
211+
xml = os.path.join(carpeta, xml)
212+
elif not enviar:
213+
return
214+
215+
# llamada al webservice:
216+
cot.PresentarRemito(fn, testing=xml)
217+
218+
# grabo el xml devuelto:
219+
if not xml:
220+
xml = os.path.splitext(fn)[0] + ".xml"
221+
with open(xml, "w") as f:
222+
f.write(cot.XmlResponse)
223+
224+
if cot.Excepcion and enviar and not panel['auto'].value:
225+
gui.alert(cot.Traceback, cot.Excepcion)
226+
227+
if cot.TipoError and enviar and not panel['auto'].value:
228+
gui.alert(cot.MensajeError, "Error %s: %s" % (cot.TipoError, cot.CodigoError))
229+
230+
# actualizo los datos devueltos en el listado
231+
item['cuit'] = cot.CuitEmpresa
232+
item['nro'] = cot.NumeroComprobante
233+
item['md5'] = cot.CodigoIntegridad
234+
#assert item['txt'] == cot.NombreArchivo
235+
236+
# limpio, enumero y agrego los remitos para el archivo seleccionado:
237+
remitos = panel['remitos']
238+
item['remitos'] = []
239+
panel['errores'].items = []
240+
remitos.items = []
241+
i = 0
242+
while cot.LeerValidacionRemito():
243+
print "REMITO", i
244+
errores = []
245+
remito = {'nro': cot.NumeroUnico, 'proc': cot.Procesado,
246+
'errores': errores}
247+
remitos.items[i] = remito
248+
item['remitos'].append(remito)
249+
i += 1
250+
while cot.LeerErrorValidacion():
251+
print "Error Validacion:", "|", cot.CodigoError, "|", cot.MensajeError
252+
errores.append({'codigo': cot.CodigoError,
253+
'descripcion': cot.MensajeError})
254+
255+
def cargar_errores(evt):
256+
# obtengo el remito seleccionado:
257+
item = evt.target.get_selected_items()[0]
258+
# limpio, enumero y agrego los errores para el remito seleccionado:
259+
errores = panel['errores']
260+
errores.items = []
261+
for i, error in enumerate(item['errores']):
262+
print i, error
263+
errores.items[i] = error
264+
265+
def filtro_fecha(evt):
266+
panel['fecha'].enabled = evt.target.value
267+
listar_archivos()
268+
269+
270+
def mover_archivos(evt=None):
271+
carpeta = panel['carpeta'].text
272+
if carpeta != "datos" and evt:
273+
gui.alert("No se puede mover archivos de carpeta %s" % carpeta)
274+
275+
i = 0
276+
print panel['archivos'].items
277+
for item in panel['archivos'].items:
278+
procesado = all([remito.get('proc', 'NO') == 'SI'
279+
for remito in item.get('remitos', [])])
280+
if procesado and item.get('remitos'):
281+
for fn in (item['txt'], item['xml']):
282+
fn0 = os.path.join("datos", fn)
283+
fn1 = os.path.join("procesados", fn)
284+
try:
285+
os.rename(fn0, fn1)
286+
i += 1
287+
except Exception, e:
288+
gui.alert(unicode(e), "No se puede mover %s" % fn)
289+
if evt:
290+
gui.alert("Se movieron: %s archivos" % i)
291+
listar_archivos()
292+
293+
294+
panel['archivos'].onitemselected = cargar_archivo
295+
panel['archivos'].onmousedclick = abrir_archivo
296+
panel['remitos'].onitemselected = cargar_errores
297+
panel['filtrar_fecha'].onclick = filtro_fecha
298+
panel['fecha'].onchange = listar_archivos
299+
panel['carpeta'].onchange = listar_archivos
300+
panel['mover'].onclick = mover_archivos
301+
panel['procesar'].onclick = procesar_archivos
302+
panel['clave'].onchange = grabar_clave
303+
304+
305+
if __name__ == "__main__":
306+
mywin.show()
307+
mywin.title = u"%s - %s" % (mywin.title, cot.Version.decode("latin1"))
308+
mywin['statusbar'].text = ""
309+
listar_archivos()
310+
gui.main_loop()
311+
passwd_db.close()
312+

ejemplos/remito_electronico_harina.vbs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'
22
' Ejemplo de Uso de Interfaz PyAfipWs para Windows Script Host
33
' (Visual Basic / Visual Fox y lenguages con soporte ActiveX simil OCX)
4-
' con Web Service Autenticación / Remito Electrónico Harina AFIP
4+
' con Web Service Autenticaci�n / Remito Electr�nico Harina AFIP
55
' 2018(C) Mariano Reingart <[email protected]>
66
' Licencia: GPLv3
77
' Requerimientos: scripts wsaa.py y wsfev1.py registrados (ver instaladores)
@@ -10,12 +10,12 @@
1010
' http://www.sistemasagiles.com.ar/trac/wiki/PyAfipWs
1111
' http://www.sistemasagiles.com.ar/trac/wiki/ManualPyAfipWs
1212

13-
' Crear el objeto WSAA (Web Service de Autenticación y Autorización) AFIP
13+
' Crear el objeto WSAA (Web Service de Autenticaci�n y Autorizaci�n) AFIP
1414
Set WSAA = Wscript.CreateObject("WSAA")
1515
Wscript.Echo "InstallDir", WSAA.InstallDir, WSAA.Version
1616

1717
' Solicitar Ticket de Acceso
18-
wsdl = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms" ' Homologación!
18+
wsdl = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms" ' Homologaci�n!
1919
scriptdir = CreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName)
2020
proxy = "" ' en caso de ser necesario: "usuario:clave@servidor:puerto"
2121
wrapper = "" ' usar "pycurl" como transporte alternativo en caso de inconvenientes con SSL
@@ -41,7 +41,7 @@ wsdl = "https://fwshomo.afip.gov.ar/wsremharina/RemHarinaService?wsdl"
4141
timeout = 30 ' tiempo de espera predeterminado
4242
WSRemHarina.Conectar cache, wsdl, proxy, wrapper, cacert, timeout
4343

44-
' Consultar último comprobante autorizado en AFIP
44+
' Consultar �ltimo comprobante autorizado en AFIP
4545
tipo_comprobante = 993
4646
punto_emision = 1
4747
ult = 1
@@ -62,7 +62,7 @@ If ult = 0 Then
6262
if WSRemHarina.Excepcion <> "" Then Wscript.Echo WSRemHarina.Excepcion, "Excepcion:"
6363
End If
6464

65-
' Calculo el próximo número de comprobante:
65+
' Calculo el pr�ximo n�mero de comprobante:
6666
If ult = "" Then
6767
nro_remito = 0 ' no hay comprobantes emitidos
6868
Else
@@ -150,12 +150,12 @@ ok = WSRemHarina.AgregarMercaderia(orden, cod_tipo, cod_tipo_emb, cantidad_emb,
150150
' WSRemHarina.AgregarContingencias(tipo=1, observacion="anulacion")
151151

152152
' Solicito CodRemito:
153-
id_req = Int(DateDiff("s","24-Sep-23 00:00:00", Now)) ' usar un numero interno único / clave primaria (id_remito)
153+
id_req = Int(DateDiff("s","24-Sep-23 00:00:00", Now)) ' usar un numero interno �nico / clave primaria (id_remito)
154154
archivo = "qr.png"
155155
ok = WSRemHarina.GenerarRemito(id_req, archivo)
156156

157157
If not ok Then
158-
' Imprimo pedido y respuesta XML para depuración (errores de formato)
158+
' Imprimo pedido y respuesta XML para depuraci�n (errores de formato)
159159
Wscript.Echo "Traceback", WSRemHarina.Traceback
160160
Wscript.Echo "XmlResponse", WSRemHarina.XmlResponse
161161
Wscript.Echo "XmlRequest", WSRemHarina.XmlRequest

formatos/formato_txt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@
108108
("codigo", 30, A),
109109
("qty", (12, 2), I),
110110
("umed", 2, N),
111-
("precio", (12, 3), I),
111+
("precio", (15, 3), I),
112112
("importe", (14, 3), I),
113113
("iva_id", 5, N),
114114
("ds", 4000, A),
@@ -118,7 +118,7 @@
118118
("imp_iva", 15, I),
119119
("despacho", 20, A),
120120
("u_mtx", 10, N),
121-
("cod_mtx", 30, N),
121+
("cod_mtx", 30, A),
122122
("dato_a", 15, A),
123123
("dato_b", 15, A),
124124
("dato_c", 15, A),

pyfepdf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
from past.utils import old_div
2727

2828
__author__ = "Mariano Reingart <[email protected]>"
29-
__copyright__ = "Copyright (C) 2011-2021 Mariano Reingart"
29+
__copyright__ = "Copyright (C) 2011-2025 Mariano Reingart"
3030
__license__ = "LGPL-3.0-or-later"
31-
__version__ = "3.11c"
31+
__version__ = "3.12c"
3232

3333
DEBUG = False
3434
HOMO = False

0 commit comments

Comments
 (0)