From cba6d22fcb533f3af3b352f781d39d8b8d2c442f Mon Sep 17 00:00:00 2001 From: Rodolfo Leyes Date: Wed, 29 Dec 2021 06:44:34 -0300 Subject: [PATCH] Commit inicial funcional --- .gitignore | 1 + README.md | 3 + afip/__init__.py | 0 afip/comprobantes/__init__.py | 0 afip/comprobantes/facturador.py | 237 ++++++++++++++++++++++++++++++++ facturar.py | 26 ++++ input_template.csv | 3 + start.sh | 1 + 8 files changed, 271 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 afip/__init__.py create mode 100644 afip/comprobantes/__init__.py create mode 100644 afip/comprobantes/facturador.py create mode 100644 facturar.py create mode 100644 input_template.csv create mode 100755 start.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e99e36 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.pyc \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce31733 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# README + +Download geckodriver package for example geckodriver-v0.30.0-linux32.tar.gz and uncompress on this same dir \ No newline at end of file diff --git a/afip/__init__.py b/afip/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/afip/comprobantes/__init__.py b/afip/comprobantes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/afip/comprobantes/facturador.py b/afip/comprobantes/facturador.py new file mode 100644 index 0000000..3278bd1 --- /dev/null +++ b/afip/comprobantes/facturador.py @@ -0,0 +1,237 @@ +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.common.keys import Keys +from selenium.webdriver.support.select import Select +from selenium.webdriver.firefox.firefox_profile import FirefoxProfile +import time +import sys + +class MyComprobantesAfip: + + def __init__(self, + cuit, + password, + nombre_empresa, + descargar_comprobante=True, + confirmar_manualmente=True, + directorio_comprobantes="./", + tiempo_espera_confirmacion_automatica=5 + ): + self.cuit = cuit + self.password = password + self.nombre_empresa = nombre_empresa + self.descargar_comprobante=descargar_comprobante + self.confirmar_manualmente=confirmar_manualmente + self.directorio_comprobantes=directorio_comprobantes + self.tiempo_espera_confirmacion_automatica=tiempo_espera_confirmacion_automatica + + def esperar(self,secs=10): + for remaining in range(secs, 0, -1): + sys.stdout.write("\r") + sys.stdout.write("quedan {:2d} segundos..".format(remaining)) + sys.stdout.flush() + time.sleep(1) + sys.stdout.write("\rOk! \n") + + def inicializar_browser(self): + print("Inicializando Navegador...") + profile = FirefoxProfile() + profile.set_preference("browser.download.panel.shown", False) + profile.set_preference("browser.download.manager.showWhenStarting", False) + profile.set_preference("browser.download.manager.alertOnEXEOpen", False) + profile.set_preference("browser.download.manager.focusWhenStarting", False) + profile.set_preference("browser.download.manager.useWindow", False) + profile.set_preference("browser.download.manager.showAlertOnComplete", False) + profile.set_preference("browser.download.manager.closeWhenDone", False) + + # profile.set_preference("browser.helperApps.neverAsk.openFile","text/csv,application/vnd.ms-excel,application/pdf") + profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "text/csv,application/vnd.ms-excel,application/pdf") + profile.set_preference("browser.download.folderList", 2) + profile.set_preference("browser.download.dir", self.directorio_comprobantes) + profile.set_preference("browser.helperApps.alwaysAsk.force", False) + + self.browser = webdriver.Firefox(firefox_profile=profile) + self.browser.implicitly_wait(10) + + def login(self): + self.inicializar_browser() + print("Ingresando a AFIP...") + self.browser.get('https://auth.afip.gob.ar/contribuyente_/login.xhtml') + assert 'Acceso con Clave Fiscal - AFIP' in self.browser.title + elem = self.browser.find_element(By.NAME, 'F1:username') + elem.send_keys(self.cuit + Keys.RETURN) + elem = self.browser.find_element(By.NAME, 'F1:password') + elem.send_keys(self.password + Keys.RETURN) + time.sleep(5) + assert 'Mi Portal - Clave Fiscal' in self.browser.title + print("Ingresando a Aplicativo Generacion de Comprobantes...") + elem = self.browser.find_element(By.CSS_SELECTOR, "[title='rcel']") + elem.click() + time.sleep(4) + + self.browser.switch_to.window(self.browser.window_handles[-1]) + time.sleep(2) + self.seleccionarEmpresa(self.nombre_empresa) + + def seleccionarEmpresa(self, nombre_empresa): + assert 'RCEL' in self.browser.title + print("Seleccionando empresa...") + elem = self.browser.find_element(By.CSS_SELECTOR, "[value='"+ nombre_empresa +"']") + elem.click() + print("Ingresando a generar nuevo comprobante...") + elem = self.browser.find_element(By.ID, "btn_gen_cmp") + elem.click() + time.sleep(4) + + def cerrar(self): + print("Finalizando...") + self.browser.quit() + + def menu_principal(self): + self.browser.get("https://serviciosjava2.afip.gob.ar/rcel/jsp/menu_ppal.jsp") + + def generar_comprobante(self, punto_de_venta=1, + tipo_comprobante=0, + fecha_comprobante="26/12/2021", + id_concepto=2, + fecha_desde="26/12/2021", + fecha_hasta="26/12/2021", + vencimiento_pago="26/12/2021", + referencia="", + id_iva_receptor="5", + forma_de_pago="", + concepto="", + precio="" + ): + assert 'RCEL' in self.browser.title + + print("Iniciando generacion de nuevo comprobante...") + # assert "Puntos de Ventas y Tipos de Comprobantes habilitados para impre" in self.browser.current_url + + ## PRIMERA PAGINA + + print("Seleccionando punto de venta y tipo de comprobante...") + ### Punto de venta + elem = self.browser.find_element(By.ID, "puntodeventa") + select_object = Select(elem) + # Comienza con 1 porque el 0 es vacio + select_object.select_by_index(punto_de_venta) + + time.sleep(2) + ### Tipo de comprobante (0 es factura) + elem = self.browser.find_element(By.ID, "universocomprobante") + select_object = Select(elem) + # 0 es factura + select_object.select_by_index(tipo_comprobante) + time.sleep(2) + + elem = self.browser.find_element(By.CSS_SELECTOR, "[value='Continuar >']") + elem.click() + + ## SEGUNDA PAGINA + + ### Fecha de Comprobante + elem = self.browser.find_element(By.ID, "fc") + elem.clear() + elem.send_keys(fecha_comprobante) + + ### Concepto + elem = self.browser.find_element(By.ID, "idconcepto") + select_object = Select(elem) + # 1 - Productos + # 2 - Servicios + # 3 - Productos y Servicios + select_object.select_by_index(id_concepto) + + time.sleep(2) + + ### Fecha desde + elem = self.browser.find_element(By.ID, "fsd") + elem.clear() + elem.send_keys(fecha_desde) + + ### Fecha hasta + elem = self.browser.find_element(By.ID, "fsh") + elem.clear() + elem.send_keys(fecha_hasta) + + ### Fecha de pago + elem = self.browser.find_element(By.ID, "vencimientopago") + elem.clear() + elem.send_keys(vencimiento_pago) + + ### Referencia + elem = self.browser.find_element(By.ID, "refComEmisor") + elem.clear() + elem.send_keys(referencia) + + elem = self.browser.find_element(By.CSS_SELECTOR, "[value='Continuar >']") + elem.click() + + ## TERCERA PAGINA + elem = self.browser.find_element(By.ID, "idivareceptor") + select_object = Select(elem) + # + # + # + # + # + # + # + # + # + # + # + # + select_object.select_by_value(id_iva_receptor) + + time.sleep(2) + ### Otra forma de pago + # TODO: Mejorar esta parte estamos seleccionando otro + elem = self.browser.find_element(By.ID, "formadepago7") + elem.click() + + elem = self.browser.find_element(By.CSS_SELECTOR, "[value='Continuar >']") + elem.click() + + ## CUARTA PAGINA + elem = self.browser.find_element(By.ID, "detalle_descripcion1") + elem.send_keys(concepto) + + elem = self.browser.find_element(By.ID, "detalle_precio1") + elem.send_keys(precio) + + elem = self.browser.find_element(By.CSS_SELECTOR, "[value='Continuar >']") + elem.click() + + self.confirmar_comprobante() + + def confirmar_comprobante(self): + menu_principal_button = self.browser.find_element(By.CSS_SELECTOR, "[value='Menú Principal']") + boton_generar = self.browser.find_element(By.ID, "btngenerar") + + confirmado=False + confirmar="N" + if self.confirmar_manualmente: + confirmar=input('Confirmar comprobante? (Y/N):') + else: + print("Si no quiere continuar cancele la ejecucion") + self.esperar(self.tiempo_espera_confirmacion_automatica) + confirmar="Y" + + if confirmar=="Y": + boton_generar.click() + time.sleep(2) + # TODO: Capturar el "Comprobante Generado" + dialogo_confirmacion = self.browser.switch_to.alert + dialogo_confirmacion.accept() + time.sleep(2) + + confirmado = True + + if confirmado and self.descargar_comprobante: + boton_imprimir = self.browser.find_element(By.CSS_SELECTOR, "[value='Imprimir...']") + boton_imprimir.click() + menu_principal_button.click() + elem = self.browser.find_element(By.ID, "btn_gen_cmp") + elem.click() \ No newline at end of file diff --git a/facturar.py b/facturar.py new file mode 100644 index 0000000..e51b4b2 --- /dev/null +++ b/facturar.py @@ -0,0 +1,26 @@ +import csv +from afip.comprobantes.facturador import MyComprobantesAfip + +cuit = "" +password = "" +nombre_empresa = "" + +filename = "input.csv" +with open(filename, newline='') as csvfile: + reader = csv.DictReader(csvfile) + afip = MyComprobantesAfip(cuit, password, nombre_empresa, confirmar_manualmente=False) + afip.login() + fila = 1 + for row in reader: + print(f'Informacion de la fila: {fila} -> {row}') + afip.generar_comprobante(fecha_comprobante=row["fecha_comprobante"], + id_concepto=2, + fecha_desde=row["fecha_desde"], + fecha_hasta=row["fecha_hasta"], + vencimiento_pago=row["fecha_comprobante"], + referencia=row["referencia"], + concepto=row["concepto"], + precio=row["monto"] + ) + fila = fila + 1 + afip.cerrar() diff --git a/input_template.csv b/input_template.csv new file mode 100644 index 0000000..c4eff20 --- /dev/null +++ b/input_template.csv @@ -0,0 +1,3 @@ +fecha_comprobante,fecha_desde,fecha_hasta,referencia,concepto,monto +21/12/2021,01/05/2021,31/05/2021,5-002,Mantenimiento/Soporte de infraestructura informatica,12000 + diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..5618f25 --- /dev/null +++ b/start.sh @@ -0,0 +1 @@ +PATH=$PATH:./ python facturar.py