def test_crear_pedido_certificado(): """Crea CSM para solicitar certificado.""" wsaa = WSAA() chk1 = wsaa.CrearClavePrivada() chk2 = wsaa.CrearPedidoCertificado() assert chk1 == True assert chk2 == True
def test_analizar_certificado(key_and_cert): """Test analizar datos en certificado.""" wsaa = WSAA() wsaa.AnalizarCertificado(key_and_cert[1]) assert wsaa.Identidad assert wsaa.Caducidad assert wsaa.Emisor
def _get_afip(): """Build and authenticate AFIP structure.""" # AFIP init wsaa = WSAA() wsfev1 = WSFEv1() # get access ticket (token y sign) certificate = settings.AFIP['auth_cert_path'] private_key = settings.AFIP['auth_key_path'] if not os.path.exists(certificate): raise ValueError( "Auth certificate can not be found (got {!r})".format(certificate)) if not os.path.exists(private_key): raise ValueError( "Auth key can not be found (got {!r})".format(private_key)) ta = wsaa.Autenticar("wsfe", certificate, private_key, wsdl=settings.AFIP['url_wsaa'], cache=CACHE, debug=True) wsfev1.Cuit = settings.AFIP['cuit'] wsfev1.SetTicketAcceso(ta) wsfev1.Conectar(CACHE, settings.AFIP['url_wsfev1']) return wsfev1
def datos_afip(request, cuit): from pyafipws.wsaa import WSAA from pyafipws.ws_sr_padron import WSSrPadronA4 empresa = empresa_actual(request) H**O = empresa.homologacion if H**O: WSDL = "https://wswhomo.afip.gov.ar/wsfev1/service.asmx?WSDL" WSAA_URL = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms" else: WSDL = "https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL" WSAA_URL = "https://wsaa.afip.gov.ar/ws/services/LoginCms" appserver_status = '' dbserver_status = '' authserver_status = '' #try: fecha = datetime.now().strftime("%Y%m%d") wsaa = WSAA() crt = empresa.fe_crt key = empresa.fe_key wsaa.Token, wsaa.Sign = _autenticar(request, crt=crt, key=key, cuit=cuit) #ta = wsaa.Autenticar("ws_sr_padron_a4",crt=crt,key=key,) padron = WSSrPadronA4() #padron.SetTicketAcceso(ta) padron.Cuit = empresa.cuit #padron.Conectar() ok = padron.Consultar(cuit) return padron
def __init__(self, privada, certificado, cuit): # instanciar el componente para factura electrónica mercado interno self.webservice = WSFEv1() self.webservice.LanzarExcepciones = True # datos de conexión (cambiar URL para producción) cache = None wsdl = AFIP_WSDL_URL proxy = "" wrapper = "" cacert = None # conectar try: self.webservice.Conectar(cache, wsdl, proxy, wrapper, cacert) except (ExpatError, ServerNotFoundError, SoapFault): raise AfipErrorRed("Error en la conexion inicial con la AFIP.") self.cert = certificado # archivos a tramitar previamente ante AFIP self.clave = privada self.wsaa_url = AFIP_WSAA_URL self.wsaa = WSAA() self.autenticar() self.webservice.Cuit = cuit
def authenticate(service, certificate, private_key, force=False, cache=CACHE, wsdl=WSAA_URL, proxy=PROXY, ): "Call AFIP Authentication webservice to get token & sign or error message" # import AFIP webservice authentication helper: from pyafipws.wsaa import WSAA # create AFIP webservice authentication helper instance: wsaa = WSAA() wsaa.LanzarExcepciones = True # raise python exceptions on any failure # make md5 hash of the parameter for caching... fn = "%s.xml" % hashlib.md5(service + certificate + private_key).hexdigest() if cache: fn = os.path.join(cache, fn) else: fn = os.path.join(wsaa.InstallDir, "cache", fn) try: # read the access ticket (if already authenticated) #import pdb #pdb.set_trace() if not os.path.exists(fn) or \ os.path.getmtime(fn)+(DEFAULT_TTL) < time.time(): # access ticket (TA) outdated, create new access request ticket (TRA) tra = wsaa.CreateTRA(service=service, ttl=DEFAULT_TTL) # cryptographically sing the access ticket cms = wsaa.SignTRA(tra, certificate, private_key) # connect to the webservice: wsaa.Conectar(cache, wsdl, proxy) # call the remote method ta = wsaa.LoginCMS(cms) if not ta: raise RuntimeError() # write the access ticket for further consumption open(fn, "w").write(ta) else: # get the access ticket from the previously written file ta = open(fn, "r").read() # analyze the access ticket xml and extract the relevant fields wsaa.AnalizarXml(xml=ta) token = wsaa.ObtenerTagXml("token") print "token", token sign = wsaa.ObtenerTagXml("sign") print "sign", sign err_msg = None except: print "sali x el except" token = sign = None if wsaa.Excepcion: # get the exception already parsed by the helper err_msg = wsaa.Excepcion else: # avoid encoding problem when reporting exceptions to the user: err_msg = traceback.format_exception_only(sys.exc_type, sys.exc_value)[0] if DEBUG: raise return {'token': token, 'sign': sign, 'err_msg': err_msg}
def auth(request): if 'dontusefix' in request.keywords: return z = request.module.__obj__ z.Cuit = CUIT wsaa = WSAA() ta = wsaa.Autenticar(request.module.__service__, CERT, PKEY) z.SetTicketAcceso(ta) z.Conectar(CACHE, request.module.__WSDL__) return z
def test_wsaa_sign_tra(key_and_cert): wsaa = WSAA() tra = wsaa.CreateTRA("wsfe") sign = wsaa.SignTRA(tra, key_and_cert[1], key_and_cert[0]) if not isinstance(sign, str): sign = sign.decode('utf-8') assert isinstance(sign, str) assert sign.startswith("MIIG+")
def authenticate(service, certificate, private_key, force=False, cache=CACHE, wsdl=WSAA_URL, proxy=PROXY, ): "Call AFIP Authentication webservice to get token & sign or error message" # import AFIP webservice authentication helper: from pyafipws.wsaa import WSAA # create AFIP webservice authentication helper instance: wsaa = WSAA() wsaa.LanzarExcepciones = True # raise python exceptions on any failure # make md5 hash of the parameter for caching... fn = "%s.xml" % hashlib.md5(service + certificate + private_key).hexdigest() if cache: fn = os.path.join(cache, fn) else: fn = os.path.join(wsaa.InstallDir, "cache", fn) try: # read the access ticket (if already authenticated) if not os.path.exists(fn) or \ os.path.getmtime(fn)+(DEFAULT_TTL) < time.time(): # access ticket (TA) outdated, create new access request ticket (TRA) tra = wsaa.CreateTRA(service=service, ttl=DEFAULT_TTL) # cryptographically sing the access ticket cms = wsaa.SignTRA(tra, certificate, private_key) # connect to the webservice: wsaa.Conectar(cache, wsdl, proxy) # call the remote method ta = wsaa.LoginCMS(cms) if not ta: raise RuntimeError() # write the access ticket for further consumption open(fn, "w").write(ta) else: # get the access ticket from the previously written file ta = open(fn, "r").read() # analyze the access ticket xml and extract the relevant fields wsaa.AnalizarXml(xml=ta) token = wsaa.ObtenerTagXml("token") sign = wsaa.ObtenerTagXml("sign") err_msg = None except: token = sign = None if wsaa.Excepcion: # get the exception already parsed by the helper err_msg = wsaa.Excepcion else: # avoid encoding problem when reporting exceptions to the user: err_msg = traceback.format_exception_only(sys.exc_type, sys.exc_value)[0] if DEBUG: raise return {'token': token, 'sign': sign, 'err_msg': err_msg}
def test_wsaa_create_tra(): wsaa = WSAA() tra = wsaa.CreateTRA(service="wsfe") # sanity checks: assert isinstance(tra, basestring) assert tra.startswith('<?xml version="1.0" encoding="UTF-8"?>' '<loginTicketRequest version="1.0">') assert "<uniqueId>" in tra assert "<expirationTime>" in tra assert "<generationTime>" in tra assert tra.endswith("<service>wsfe</service></loginTicketRequest>")
def test_wsaa_sign(): wsaa = WSAA() tra = '<?xml version="1.0" encoding="UTF-8"?><loginTicketRequest version="1.0"/>' # TODO: use certificate and private key as fixture / PEM text (not files) cms = wsaa.SignTRA(tra, "reingart.crt", "reingart.key") # TODO: return string if not isinstance(cms, str): cms = cms.decode("utf8") # sanity checks: assert isinstance(cms, str) out = base64.b64decode(cms) assert tra.encode("utf8") in out
def wscdc_(): wsc = ws ta = WSAA().Autenticar("wscdc", CERT, PKEY) wscdc.Cuit = CUIT wscdc.SetTicketAcceso(ta) wscdc.Conectar(CACHE, WSDL) return [wscdc, wsc]
def test_expirado(): """Revisar si el TA se encuentra vencido.""" wsaa = WSAA() #checking for expired certificate script_dir = os.path.dirname(__file__) file_path = os.path.join(script_dir, 'xml/expired_ta.xml') chk = wsaa.AnalizarXml(xml=open(file_path, "r").read()) chk2 = wsaa.Expirado() #checking for a valid certificate,i.e. which will #have expiration time 12 hrs(43200 secs) from generation fec = str(date("c", date("U") + 43200)) chk3 = wsaa.Expirado(fecha=fec) assert chk == True assert chk2 == True assert chk3 == False
def test_wsaa_sign_tra_inline(key_and_cert): wsaa = WSAA() tra = wsaa.CreateTRA("wsfe") sign = wsaa.SignTRA(tra, key_and_cert[1], key_and_cert[0]) sign_2 = wsaa.SignTRA(tra, open(key_and_cert[1]).read(), open(key_and_cert[0]).read()) if not isinstance(sign, str): sign = sign.decode('utf-8') if not isinstance(sign_2, str): sign_2 = sign_2.decode('utf-8') assert isinstance(sign, str) assert sign.startswith("MIIG+") assert isinstance(sign_2, str) assert sign_2.startswith("MIIG+")
def test_login_cms(key_and_cert): """comprobando si LoginCMS está funcionando correctamente""" wsaa = WSAA() tra = wsaa.CreateTRA(service="wsfe", ttl=DEFAULT_TTL) cms = wsaa.SignTRA(tra, key_and_cert[1], key_and_cert[0]) chk = wsaa.Conectar(cache=None, wsdl=WSDL, cacert=CACERT, proxy=None) ta_xml = wsaa.LoginCMS(cms) ta = SimpleXMLElement(ta_xml) if not isinstance(cms, str): cms = cms.decode('utf-8') assert isinstance(cms, str) assert cms.startswith('MIIG+') assert chk == True assert ta_xml.startswith( '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>') assert ta.credentials.token assert ta.credentials.sign assert "<source>" in ta_xml assert "<destination>" in ta_xml assert "<uniqueId>" in ta_xml assert "<expirationTime>" in ta_xml assert "<generationTime>" in ta_xml assert "<credentials>" in ta_xml assert "<token>" in ta_xml assert "<sign>" in ta_xml assert ta_xml.endswith("</loginTicketResponse>\n")
def get_wsfexv1(company=None, config=None): "return wsfexv1 object" if not company: company = get_company() company = set_afip_certs(company, config) URL_WSAA = "https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl" URL_WSFEXv1 = "https://wswhomo.afip.gov.ar/wsfexv1/service.asmx?WSDL" crt = get_filename('party_ar/tests/gcoop.crt') key = get_filename('party_ar/tests/gcoop.key') ta = WSAA().Autenticar('wsfex', crt, key, URL_WSAA, cacert=True) wsfexv1 = WSFEXv1() wsfexv1.LanzarExcepciones = True wsfexv1.SetTicketAcceso(ta) wsfexv1.Cuit = company.party.vat_number wsfexv1.Conectar(wsdl=URL_WSFEXv1, cacert=True) return wsfexv1
from pyafipws.wsaa import WSAA from pyafipws.wslpg import WSLPG import pysimplesoap.client print(pysimplesoap.client.__version__) #assert pysimplesoap.client.__version__ >= "1.08c" WSDL = "https://fwshomo.afip.gov.ar/wslpg/LpgService?wsdl" CUIT = 20267565393 CERT = "/home/reingart/pyafipws/reingart.crt" PRIVATEKEY = "/home/reingart/pyafipws/reingart.key" CACERT = "/home/reingart/pyafipws/afip_root_desa_ca.crt" CACHE = "/home/reingart/pyafipws/cache" # Autenticación: wsaa = WSAA() tra = wsaa.CreateTRA(service="wslpg") cms = wsaa.SignTRA(tra, CERT, PRIVATEKEY) wsaa.Conectar() wsaa.LoginCMS(cms) class TestIssues(unittest.TestCase): def setUp(self): sys.argv.append("--trace") # TODO: use logging self.wslpg = wslpg = WSLPG() wslpg.LanzarExcepciones = True wslpg.Conectar(url=WSDL, cacert=None, cache=CACHE) wslpg.Cuit = CUIT wslpg.Token = wsaa.Token wslpg.Sign = wsaa.Sign
class _Afip(object): ''' Clase que abstrae la emision de comprobantes electronicos en la afip. ''' def __init__(self, privada, certificado, cuit): # instanciar el componente para factura electrónica mercado interno self.webservice = WSFEv1() self.webservice.LanzarExcepciones = True # datos de conexión (cambiar URL para producción) cache = None wsdl = AFIP_WSDL_URL proxy = "" wrapper = "" cacert = None # conectar try: self.webservice.Conectar(cache, wsdl, proxy, wrapper, cacert) except (ExpatError, ServerNotFoundError, SoapFault): raise AfipErrorRed("Error en la conexion inicial con la AFIP.") self.cert = certificado # archivos a tramitar previamente ante AFIP self.clave = privada self.wsaa_url = AFIP_WSAA_URL self.wsaa = WSAA() self.autenticar() self.webservice.Cuit = cuit def autenticar(self): ''' Pide un ticket de acceso a la AFIP que sera usado en todas las requests. ''' try: self.ticket_autenticacion = self.wsaa.Autenticar( "wsfe", self.cert, self.clave, self.wsaa_url, cache=CACHE_PATH, debug=True) except SoapFault as e: raise AfipErrorRed("Error autenticando en la Afip: " + str(e)) if not self.ticket_autenticacion and self.wsaa.Excepcion: raise AfipError("Error WSAA: %s" % self.wsaa.Excepcion) # establecer credenciales (token y sign): self.webservice.SetTicketAcceso(self.ticket_autenticacion) @requiere_ticket def emitir_comprobante(self, comprobante_cedir, lineas): ''' Toma un comprobante nuestro y una lista de lineas, lo traduce al formato que usa la AFIP en su webservice y trata de emitirlo. En caso de exito, setea las propiedades faltantes del comprobante que son dependientes de la AFIP. En caso de error, levanta una excepcion. ''' nro = self.consultar_proximo_numero(comprobante_cedir.nro_terminal, comprobante_cedir.tipo_comprobante, comprobante_cedir.sub_tipo) fecha = comprobante_cedir.fecha_emision.strftime("%Y%m%d") # En estos tipos de comprobante en especifico, la AFIP te prohibe poner un campo fecha de vencimiento. fecha_vto = None if comprobante_cedir.tipo_comprobante.id in [ID_TIPO_COMPROBANTE_NOTA_DE_DEBITO_ELECTRONICA, ID_TIPO_COMPROBANTE_NOTA_DE_CREDITO_ELECTRONICA] else comprobante_cedir.fecha_vencimiento.strftime("%Y%m%d") imp_iva = sum([l.iva for l in lineas]) if comprobante_cedir.gravado.id == IVA_EXCENTO: imp_neto = Decimal("0.00") imp_op_ex = sum([l.importe_neto for l in lineas]) else: # importe neto gravado (todas las alicuotas) imp_neto = sum([l.importe_neto for l in lineas]) imp_op_ex = Decimal("0.00") # importe total operaciones exentas self.webservice.CrearFactura( concepto=2, # 2 es servicios, lo unico que hace el cedir. tipo_doc=comprobante_cedir.tipo_id_afip, nro_doc=comprobante_cedir.nro_id_afip, tipo_cbte=comprobante_cedir.codigo_afip, punto_vta=comprobante_cedir.nro_terminal, cbt_desde=nro, cbt_hasta=nro, imp_total=Decimal(comprobante_cedir.total_facturado).quantize(Decimal('.01'), ROUND_UP), imp_neto=Decimal(imp_neto).quantize(Decimal('.01'), ROUND_UP), imp_iva=Decimal(imp_iva).quantize(Decimal('.01'), ROUND_UP), imp_op_ex=Decimal(imp_op_ex).quantize(Decimal('.01'), ROUND_UP), fecha_cbte=fecha, # Estas fechas no cambian nunca, pero son requisito de la AFIP para el concepto=2 fecha_serv_desde=fecha, fecha_serv_hasta=fecha, fecha_venc_pago=fecha_vto) # Agregar el IVA if comprobante_cedir.gravado.id == IVA_10_5: self.webservice.AgregarIva( iva_id=4, base_imp=Decimal(imp_neto).quantize(Decimal('.01'), ROUND_UP), importe=Decimal(imp_iva).quantize(Decimal('.01'), ROUND_UP)) elif comprobante_cedir.gravado.id == IVA_21: self.webservice.AgregarIva( iva_id=5, base_imp=Decimal(imp_neto).quantize(Decimal('.01'), ROUND_UP), importe=Decimal(imp_iva).quantize(Decimal('.01'), ROUND_UP)) # Si hay comprobantes asociados, los agregamos. if comprobante_cedir.tipo_comprobante.id in [ ID_TIPO_COMPROBANTE_NOTA_DE_DEBITO, # Para comprobantes no electronicos puede no ser necesario pero se los deja por completitud ID_TIPO_COMPROBANTE_NOTA_DE_CREDITO, ID_TIPO_COMPROBANTE_NOTA_DE_DEBITO_ELECTRONICA, ID_TIPO_COMPROBANTE_NOTA_DE_CREDITO_ELECTRONICA] and comprobante_cedir.factura: comprobante_asociado = comprobante_cedir.factura self.webservice.AgregarCmpAsoc( tipo=comprobante_asociado.codigo_afip, pto_vta=comprobante_asociado.nro_terminal, nro=comprobante_asociado.numero, cuit=self.webservice.Cuit, # Cuit emisor. fecha=comprobante_asociado.fecha_emision.strftime("%Y%m%d") ) # Si es Factura de Credito Electronica, hayq eu agregar como opcional el CBU del Cedir # y el opcional Sistema de Circulacion Abierta if comprobante_cedir.tipo_comprobante.id in [ ID_TIPO_COMPROBANTE_FACTURA_CREDITO_ELECTRONICA]: self.webservice.AgregarOpcional(2101, "0150506102000109564632") self.webservice.AgregarOpcional(27, 'SCA') # Si es Nota de Debito/Credito Electronica, hay que agregar un opcional indicando que no es anulacion. # En principio, el Cedir nunca anula facturas. if comprobante_cedir.tipo_comprobante.id in [ ID_TIPO_COMPROBANTE_NOTA_DE_DEBITO_ELECTRONICA, ID_TIPO_COMPROBANTE_NOTA_DE_CREDITO_ELECTRONICA]: self.webservice.AgregarOpcional(22, "N") # llamar al webservice de AFIP para autorizar la factura y obtener CAE: try: self.webservice.CAESolicitar() except (ExpatError, ServerNotFoundError, SoapFault): raise AfipErrorRed("Error de red emitiendo el comprobante.") if self.webservice.Resultado == "R": # Si la AFIP nos rechaza el comprobante, lanzamos excepcion. raise AfipErrorValidacion(self.webservice.ErrMsg or self.webservice.Obs) if self.webservice.Resultado == "O": # Si hay observaciones (en self.webservice.Obs), deberiamos logearlas en la DB. pass comprobante_cedir.cae = self.webservice.CAE comprobante_cedir.numero = nro if self.webservice.Vencimiento: comprobante_cedir.vencimiento_cae = datetime.strptime(self.webservice.Vencimiento,'%Y%m%d').date() @requiere_ticket def consultar_comprobante(self, comprobante): ''' Consulta que informacion tiene la AFIP sobre un comprobante nuestro. Devuelve un diccionario con todos los datos. ''' codigo_afip_tipo = comprobante.codigo_afip nro_terminal = comprobante.nro_terminal cbte_nro = comprobante.numero self.webservice.CompConsultar(codigo_afip_tipo, nro_terminal, cbte_nro) # Todos estos datos se setean en el objeto afip cuando la llamada a ConsultarComprobante es exitosa. # Notar que si falla (comprobante invalido, conexion...) queda con valores viejos! return { "fecha": self.webservice.FechaCbte, "numero": self.webservice.CbteNro, "punto_venta": self.webservice.PuntoVenta, "vencimiento": self.webservice.Vencimiento, "importe_total": self.webservice.ImpTotal, "CAE": self.webservice.CAE, "emision_tipo": self.webservice.EmisionTipo } @requiere_ticket def consultar_proximo_numero(self, nro_terminal, tipo_comprobante, sub_tipo): codigo_afip = Comprobante(nro_terminal=nro_terminal, tipo_comprobante=tipo_comprobante, sub_tipo=sub_tipo).codigo_afip return int(self.webservice.CompUltimoAutorizado(codigo_afip, nro_terminal) or 0) + 1
def test_call_wsaa(key_and_cert): wsaa = WSAA() tra = wsaa.CreateTRA(service="wsfe", ttl=DEFAULT_TTL) cms = wsaa.SignTRA(tra, key_and_cert[1], key_and_cert[0]) assert call_wsaa(cms, WSDL)
def test_crear_clave_privada(): """Test crear clave RSA.""" wsaa = WSAA() chk = wsaa.CrearClavePrivada() assert chk == True
def facturar(registros): """Rutina para emitir facturas electrónicas en PDF c/CAE AFIP Argentina""" # inicialización AFIP: wsaa = WSAA() wsfev1 = WSFEv1() # obtener ticket de acceso (token y sign): ta = wsaa.Autenticar( "wsfe", CERT, PRIVATEKEY, wsdl=URL_WSAA, cache=CACHE, debug=True ) wsfev1.Cuit = CUIT wsfev1.SetTicketAcceso(ta) wsfev1.Conectar(CACHE, URL_WSFEv1) # inicialización PDF fepdf = FEPDF() fepdf.CargarFormato("factura.csv") fepdf.FmtCantidad = "0.2" fepdf.FmtPrecio = "0.2" fepdf.CUIT = CUIT for k, v in CONF_PDF.items(): fepdf.AgregarDato(k, v) if "h**o" in URL_WSAA: fepdf.AgregarCampo( "DEMO", "T", 120, 260, 0, 0, text="DEMOSTRACION", size=70, rotate=45, foreground=0x808080, priority=-1, ) fepdf.AgregarDato("motivos_obs", "Ejemplo Sin validez fiscal") # recorrer los registros a facturar, solicitar CAE y generar el PDF: for reg in registros: hoy = datetime.date.today().strftime("%Y%m%d") cbte = Comprobante( tipo_cbte=6, punto_vta=4000, fecha_cbte=hoy, cbte_nro=reg.get("nro"), tipo_doc=96, nro_doc=reg["dni"], nombre_cliente=reg["nombre"], # "Juan Perez" domicilio_cliente=reg["domicilio"], # "Balcarce 50" fecha_serv_desde=reg.get("periodo_desde"), fecha_serv_hasta=reg.get("periodo_hasta"), fecha_venc_pago=reg.get("venc_pago", hoy), ) cbte.agregar_item( ds=reg["descripcion"], qty=reg.get("cantidad", 1), precio=reg.get("precio", 0), tasa_iva=reg.get("tasa_iva", 21.0), ) ok = cbte.autorizar(wsfev1) nro = cbte.encabezado["cbte_nro"] print("Factura autorizada", nro, cbte.encabezado["cae"]) if "h**o" in URL_WSFEv1: cbte.encabezado["motivos_obs"] = "Ejemplo Sin validez fiscal" ok = cbte.generar_pdf(fepdf, "/tmp/factura_{}.pdf".format(nro)) print("PDF generado", ok)
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) #BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Especificar la ubicacion de los archivos certificado y claves CERTIFICADO = "FE/cjadeveloperPRO.crt" CLAVEPRIVADA = "FE/cjadeveloperPRO.key" # Servicios a acceder SERVICIO = "ws_sr_padron_a5" # Tiempo de vida en segundos TTL = 2400 PADRON_CUIT = "20267268038" #URL_homo = 'https://awshomo.afip.gov.ar/sr-padron/webservices/personaServiceA4?WSDL' URL = 'https://aws.afip.gov.ar/sr-padron/webservices/personaServiceA5?WSDL' wsaa = WSAA() ## Analizar certificado # wsaa.AnalizarCertificado(CERTIFICADO) # print wsaa.Identidad # print wsaa.Caducidad # print wsaa.Emisor # print wsaa.CertX509 # -------------------------------------------------------------- # Generar TA (TRA, CMS y Luego TA): Ver abajo. Usar Autenticar() # -------------------------------------------------------------- # # Generar un Ticket de Requerimiento de Acceso (TRA) # tra = wsaa.CreateTRA(SERVICIO, TTL) # # Generar el mensaje firmado (CMS) # cms = wsaa.SignTRA(tra, CERTIFICADO, CLAVEPRIVADA)
def obtener_cae(): # web service de factura electronica: wsfev1 = WSFEv1() wsfev1.LanzarExcepciones = True # obteniendo el TA para pruebas ta = WSAA().Autenticar("wsfe", "/home/rodrigo/pyafipws/staff.crt", "/home/rodrigo/pyafipws/staff.key", debug=True) wsfev1.SetTicketAcceso(ta) wsfev1.Cuit = "20267565393" ok = wsfev1.Conectar() tipo_cbte = 6 punto_vta = 4001 cbte_nro = long(wsfev1.CompUltimoAutorizado(tipo_cbte, punto_vta) or 0) fecha = datetime.datetime.now().strftime("%Y%m%d") concepto = 1 tipo_doc = 80 # 80: CUIT, 96: DNI nro_doc = "30500010912" # del cliente cbt_desde = cbte_nro + 1; cbt_hasta = cbte_nro + 1 imp_total = "222.00" imp_tot_conc = "0.00" imp_neto = "200.00" imp_iva = "21.00" imp_trib = "1.00" imp_op_ex = "0.00" fecha_cbte = fecha # Fechas del per�odo del servicio facturado y vencimiento de pago: if concepto > 1: fecha_venc_pago = fecha fecha_serv_desde = fecha fecha_serv_hasta = fecha else: fecha_venc_pago = fecha_serv_desde = fecha_serv_hasta = None moneda_id = 'PES' moneda_ctz = '1.000' wsfev1.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, cbt_desde, cbt_hasta , imp_total, imp_tot_conc, imp_neto, imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta, #-- moneda_id, moneda_ctz) # otros tributos: tributo_id = 99 desc = 'Impuesto Municipal Matanza' base_imp = None alic = None importe = 1 wsfev1.AgregarTributo(tributo_id, desc, base_imp, alic, importe) # subtotales por alicuota de IVA: iva_id = 3 # 0% base_imp = 100 # neto al 0% importe = 0 wsfev1.AgregarIva(iva_id, base_imp, importe) # subtotales por alicuota de IVA: iva_id = 5 # 21% base_imp = 100 # neto al 21% importe = 21 # iva liquidado al 21% wsfev1.AgregarIva(iva_id, base_imp, importe) wsfev1.CAESolicitar() print "Nro. Cbte. desde-hasta", wsfev1.CbtDesde, wsfev1.CbtHasta print "Resultado", wsfev1.Resultado print "Reproceso", wsfev1.Reproceso print "CAE", wsfev1.CAE print "Vencimiento", wsfev1.Vencimiento print "Observaciones", wsfev1.Obs session.cae = wsfev1.CAE response.view = "generic.html" return {"Nro. Cbte. desde-hasta": wsfev1.CbtDesde, "Resultado": wsfev1.Resultado, "Reproceso": wsfev1.Reproceso, "CAE": wsfev1.CAE, "Vencimiento": wsfev1.Vencimiento, "Observaciones": wsfev1.Obs, }
def Autenticar(self, *args, **kwargs): if 'service' in kwargs: service = kwargs['service'] else: service = 'wsfe' wsaa = WSAA() archivo = ubicacion_sistema() + service + '-ta.xml' try: file = open(archivo, "r") ta = file.read() file.close() except: ta = '' if ta == '': #si no existe el archivo se solicita un ticket solicitar = True else: ok = wsaa.AnalizarXml(ta) expiracion = wsaa.ObtenerTagXml("expirationTime") solicitar = wsaa.Expirado(expiracion) #si el ticket esta vencido se solicita uno nuevo logging.info("Fecha expiracion de ticket acceso {}".format(expiracion)) if solicitar: #Generar un Ticket de Requerimiento de Acceso(TRA) tra = wsaa.CreateTRA(service=service) logging.debug("Ticket de acceso {}".format(tra)) #Generar el mensaje firmado(CMS) if LeerIni(clave='h**o') == 'S':#homologacion cms = wsaa.SignTRA(tra, abspath(LeerIni(clave="cert_homo", key="WSAA")), abspath(LeerIni(clave="privatekey_homo", key="WSAA"))) ok = wsaa.Conectar("", LeerIni(clave='url_homo', key='WSAA')) # Homologación else: cacert = LeerIni('iniciosistema') + LeerIni(clave='cacert', key='WSFEv1') cms = wsaa.SignTRA(tra, LeerIni(clave="cert_prod", key="WSAA"), LeerIni(clave="privatekey_prod", key="WSAA")) ok = wsaa.Conectar("", LeerIni(clave='url_prod', key='WSAA'), cacert=cacert) #Produccion #Llamar al web service para autenticar ta = wsaa.LoginCMS(cms) #Grabo el ticket de acceso para poder reutilizarlo file = open(archivo, 'w') file.write(ta) file.close() # devuelvo el ticket de acceso return ta
def generate_invoices(records): """Generate the invoices in PDF using AFIP API resources.""" # AFIP init wsaa = WSAA() wsfev1 = WSFEv1() # get access ticket (token y sign) certificate = settings.AFIP['auth_cert_path'] private_key = settings.AFIP['auth_key_path'] if not os.path.exists(certificate): raise ValueError( "Auth certificate can not be found (got {!r})".format(certificate)) if not os.path.exists(private_key): raise ValueError( "Auth key can not be found (got {!r})".format(private_key)) ta = wsaa.Autenticar("wsfe", certificate, private_key, wsdl=settings.AFIP['url_wsaa'], cache=CACHE, debug=True) wsfev1.Cuit = settings.AFIP['cuit'] wsfev1.SetTicketAcceso(ta) wsfev1.Conectar(CACHE, settings.AFIP['url_wsfev1']) # init PDF builder fepdf = FEPDF() fepdf.CargarFormato("factura.csv") fepdf.FmtCantidad = "0.2" fepdf.FmtPrecio = "0.2" fepdf.CUIT = settings.AFIP['cuit'] for k, v in CONFIG_PDF.items(): fepdf.AgregarDato(k, v) # safeguard when using test webservice endpoints if "h**o" in settings.AFIP['url_wsaa']: fepdf.AgregarCampo("DEMO", 'T', 120, 260, 0, 0, text="DEMOSTRACION", size=70, rotate=45, foreground=0x808080, priority=-1) fepdf.AgregarDato("motivos_obs", "Ejemplo Sin Validez Fiscal") # get CAE for each record and generate corresponding PDF results = {} for record in records: invoice = MemberInvoice(document_number=record['dni'], fullname=record['fullname'], address=record['address'], city=record['city'], zip_code=record['zip_code'], province=record['province'], invoice_date=record['invoice_date'], invoice_number=record['invoice'], service_date_from=record['service_date_from'], service_date_to=record['service_date_to']) invoice.add_item(description=record['description'], quantity=record['quantity'], amount=record['amount'], comment=record['payment_comment']) authorized_ok = invoice.autorizar(wsfev1) invoice_number = invoice.header["cbte_nro"] print(" invoice generated: number={} CAE={} authorized={}".format( invoice_number, invoice.header["cae"], authorized_ok)) results[invoice_number] = {'invoice_ok': authorized_ok} if not authorized_ok: print("WARNING not auth") return # another safeguard if "h**o" in settings.AFIP['url_wsfev1']: invoice.header["motivos_obs"] = "Ejemplo Sin validez fiscal" # generate the PDF pdf_name = "FacturaPyArAC-{:04d}-{:08d}.pdf".format( settings.AFIP['selling_point'], invoice_number) pdf_path = os.path.join(PDF_PATH, pdf_name) invoice.generate_pdf(fepdf, pdf_path) print(" PDF generated {!r}".format(pdf_path)) results[invoice_number]['pdf_path'] = pdf_path return results
def obtener_cae(): from pyafipws.wsaa import WSAA from pyafipws.wsfev1 import WSFEv1 # web service de factura electronica: wsfev1 = WSFEv1() wsfev1.LanzarExcepciones = True # obteniendo el TA para pruebas ta = WSAA().Autenticar("wsfe", "/home/web2py/pyafipws/reingart.crt", "/home/web2py/pyafipws/reingart.key", debug=True) wsfev1.SetTicketAcceso(ta) wsfev1.Cuit = "20267565393" ok = wsfev1.Conectar() # obtengo el id de comprobante pasado por la URL desde la funcion facturar factura_id = int(request.args[0]) # obtengo el registro general del comprobante (encabezado y totales) reg = db(db.comprobante_afip.id==factura_id).select().first() tipo_cbte = reg.tipo_cbte punto_vta = reg.punto_vta cbte_nro = long(wsfev1.CompUltimoAutorizado(tipo_cbte, punto_vta) or 0) + 1 #fecha = reg.fecha_cbte.strftime("%Y%m%d") # formato AAAAMMDD fecha = datetime.datetime.now().strftime("%Y%m%d") concepto = reg.concepto tipo_doc = reg.tipo_doc # 80: CUIT, 96: DNI nro_doc = reg.nro_doc.replace("-", "") # del cliente, sin rayita cbt_desde = cbte_nro; cbt_hasta = cbte_nro imp_total = reg.imp_total imp_tot_conc = reg.imp_tot_conc imp_neto = reg.imp_neto imp_iva = reg.impto_liq imp_trib = "0.00" imp_op_ex = reg.imp_op_ex fecha_cbte = fecha # Fechas del per�odo del servicio facturado y vencimiento de pago: if concepto > 1: fecha_venc_pago = reg.fecha_venc_pago fecha_serv_desde = reg.fecha_serv_desde fecha_serv_hasta = reg.fecha_serv_desde else: fecha_venc_pago = fecha_serv_desde = fecha_serv_hasta = None moneda_id = "PES" moneda_ctz = "1.000" wsfev1.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte, punto_vta, cbt_desde, cbt_hasta , imp_total, imp_tot_conc, imp_neto, imp_iva, imp_trib, imp_op_ex, fecha_cbte, fecha_venc_pago, fecha_serv_desde, fecha_serv_hasta, #-- moneda_id, moneda_ctz) # subtotales por alicuota de IVA: iva_id = 5 # 21% base_imp = reg.imp_neto # neto al 21% importe = reg.impto_liq # iva liquidado al 21% wsfev1.AgregarIva(iva_id, base_imp, importe) try: wsfev1.CAESolicitar() except: print "uy le mandamos fruta!" #print "Nro. Cbte. desde-hasta", wsfev1.CbtDesde, wsfev1.CbtHasta #print "Resultado", wsfev1.Resultado #print "Reproceso", wsfev1.Reproceso #print "CAE", wsfev1.CAE #print "Vencimiento", wsfev1.Vencimiento #print "Observaciones", wsfev1.Obs # actualizamos la factura con la respuesta de AFIP db(db.comprobante_afip.id == factura_id).update( cae=wsfev1.CAE, fecha_cbte=fecha, cbte_nro=cbte_nro, fecha_vto=wsfev1.Vencimiento, ) if wsfev1.CAE: redirect(URL(f="generar_pdf", args=[factura_id])) response.view = "generic.html" return {"Nro. Cbte. desde-hasta": wsfev1.CbtDesde, "Resultado": wsfev1.Resultado, "Reproceso": wsfev1.Reproceso, "CAE": wsfev1.CAE, "Vencimiento": wsfev1.Vencimiento, "Observaciones": wsfev1.Obs, "XmlRequest": wsfev1.XmlRequest, "XmlResponse": wsfev1.XmlResponse, "ErrMsg": wsfev1.ErrMsg, }
def authenticate(self, service, certificate, private_key, force=False, cache="", wsdl="", proxy=""): """ Call AFIP Authentication webservice to get token & sign or error message """ # import AFIP webservice authentication helper: from pyafipws.wsaa import WSAA # create AFIP webservice authentication helper instance: wsaa = WSAA() # raise python exceptions on any failure wsaa.LanzarExcepciones = True # five hours DEFAULT_TTL = 60 * 60 * 5 # make md5 hash of the parameter for caching... fn = "%s.xml" % hashlib.md5( (service + certificate + private_key).encode('utf-8')).hexdigest() if cache: fn = os.path.join(cache, fn) else: fn = os.path.join(wsaa.InstallDir, "cache", fn) try: # read the access ticket (if already authenticated) if not os.path.exists(fn) or \ os.path.getmtime(fn) + (DEFAULT_TTL) < time.time(): # access ticket (TA) outdated, create new access request # ticket (TRA) tra = wsaa.CreateTRA(service=service, ttl=DEFAULT_TTL) # cryptographically sing the access ticket cms = wsaa.SignTRA(tra, certificate, private_key) # connect to the webservice: wsaa.Conectar(cache, wsdl, proxy) # call the remote method ta = wsaa.LoginCMS(cms) if not ta: raise RuntimeError() # write the access ticket for further consumption open(fn, "w").write(ta) else: # get the access ticket from the previously written file ta = open(fn, "r").read() # analyze the access ticket xml and extract the relevant fields wsaa.AnalizarXml(xml=ta) token = wsaa.ObtenerTagXml("token") sign = wsaa.ObtenerTagXml("sign") expirationTime = wsaa.ObtenerTagXml("expirationTime") generationTime = wsaa.ObtenerTagXml("generationTime") uniqueId = wsaa.ObtenerTagXml("uniqueId") except: token = sign = None if wsaa.Excepcion: # get the exception already parsed by the helper err_msg = wsaa.Excepcion else: # avoid encoding problem when reporting exceptions to the user: err_msg = traceback.format_exception_only( sys.exc_type, sys.exc_value)[0] raise UserError( _('Could not connect. This is the what we received: %s') % (err_msg)) return { 'uniqueid': uniqueId, 'generationtime': generationTime, 'expirationtime': expirationTime, 'token': token, 'sign': sign, }
def onClickBtnGenera(self): wsaa = WSAA() wsaa.CrearPedidoCertificado