def wsfe_get_status(self, cr, uid, ids, conn_id, context=None): """ AFIP Description: Método Dummy para verificación de funcionamiento de infraestructura (FEDummy) """ conn_obj = self.pool.get('wsafip.connection') r = {} for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFE. if srv.code != 'wsfe': continue conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if nescesary. try: _logger.debug('Query AFIP Web service status') srvclient = Client(srv.url+'?WSDL', transport=HttpsTransport()) response = srvclient.service.FEDummy() except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error %i: %s') % (e[0], e[1])) r[srv.id] = (response.AuthServer, response.AppServer, response.DbServer) return r
def wsfe_get_last_invoice_number(self, cr, uid, ids, conn_id, ptoVta, cbteTipo, context=None): """ Get last ID number from AFIP AFIP Description: Recuperador de ultimo valor de comprobante registrado (FECompUltimoAutorizado) """ conn_obj = self.pool.get('wsafip.connection') r = {} for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFE. if srv.code != 'wsfe': continue # Take the connection conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() if conn.state not in ['connected', 'clockshifted']: r[srv.id] = False continue try: _logger.info('Take last invoice number from AFIP Web service ' '(pto vta: %s, cbte tipo: %s)' % (ptoVta, cbteTipo)) srvclient = Client(srv.url + '?WSDL', transport=HttpsTransport()) response = srvclient.service.FECompUltimoAutorizado( Auth=conn.get_auth(), PtoVta=ptoVta, CbteTipo=cbteTipo) except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv( _(u'AFIP Web service error'), _(u'System return error %i: %s\n' u'Pueda que esté intente realizar esta ' u'operación desde el servidor de ' u'homologación. Intente desde el ' u'servidor de producción.') % (e[0], e[1])) if hasattr(response, 'Errors'): for e in response.Errors.Err: _logger.error('AFIP Web service error!: (%i) %s' % (e.Code, e.Msg)) r[srv.id] = False else: r[srv.id] = int(response.CbteNro) return r
def wsfe_update_tax(self, cr, uid, ids, conn_id, context=None): """ Update taxes. This function must be called from connection model. AFIP Description: Recuperador de valores referenciales de códigos de Tipos de Tributos (FEParamGetTiposTributos) """ conn_obj = self.pool.get('wsafip.connection') for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFE. if srv.code != 'wsfe': continue # Take the connection, continue if connected or clockshifted conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if nescesary. if conn.state not in [ 'connected', 'clockshifted' ]: continue _escape_ = lambda s: s.replace('%', '%%') try: _logger.info('Updating currency from AFIP Web service') srvclient = Client(srv.url+'?WSDL', transport=HttpsTransport()) response = srvclient.service.FEParamGetTiposTributos(Auth=conn.get_auth()) # Take list of taxes tax_list = [ { 'afip_code': c.Id, 'name': c.Desc } for c in response.ResultGet.TributoTipo ] # Take IVA codes response = srvclient.service.FEParamGetTiposIva(Auth=conn.get_auth()) tax_list.extend([ { 'afip_code': c.Id, 'name': "%s" % _escape_(c.Desc) } for c in response.ResultGet.IvaTipo ]) except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error %i: %s') % (e[0], e[1])) tax_code_obj = self.pool.get('account.tax.code') for tc in tax_list: tax_code_ids = tax_code_obj.search(cr, uid, [('name','ilike', tc['name'])]) _logger.debug("Tax '%s' match with %s" % (tc['name'], tax_code_ids)) if tax_code_ids: w = dict(tc) del w['name'] tax_code_obj.write(cr, uid, tax_code_ids, w) return True
def wsfe_update_afip_concept_type(self, cr, uid, ids, conn_id, context=None): """ Update concepts class. AFIP Description: Recuperador de valores referenciales de códigos de Tipos de Conceptos (FEParamGetTiposConcepto) """ conn_obj = self.pool.get('wsafip.connection') for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFE. if srv.code != 'wsfe': continue # Take the connection, continue if connected or clockshifted conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() if conn.state not in ['connected', 'clockshifted']: continue # Build request auth = conn.get_auth() try: _logger.debug('Updating concept class from AFIP Web service') srvclient = Client(srv.url + '?WSDL', transport=HttpsTransport()) response = srvclient.service.FEParamGetTiposConcepto(Auth=auth) # Take list of concept type concepttype_list = [{ 'afip_code': ct.Id, 'name': ct.Desc, 'active': ct.FchHasta in [None, 'NULL'] } for ct in response.ResultGet.ConceptoTipo] except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv( _(u'AFIP Web service error'), _(u'System return error %i: %s') % (e[0], e[1])) _update(self.pool, cr, uid, 'afip.concept_type', concepttype_list, can_create=True, domain=[('afip_code', '!=', 0)]) return
def wsfex_get_cae(self, cr, uid, ids, conn_id, invoice_request, context=None): """ Get CAE. AFIP Description: Autoriza un comprobante, devolviendo su CAE correspondiente (FEXAuthorize) """ conn_obj = self.pool.get('wsafip.connection') r = {} for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFEX. if srv.code != 'wsfex': continue # Take the connection conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if necessary. if conn.state not in [ 'connected', 'clockshifted' ]: continue _logger.info('Get CAE from AFIP Web service') try: srvclient = Client(srv.url+'?WSDL', transport=HttpsTransport()) first = invoice_request.keys()[0] response = srvclient.service.FEXAuthorize(Auth=conn.get_auth(), Cmp = [dict([(k,v) for k,v in req.iteritems()]) for req in invoice_request.itervalues()] ) except WebFault as e: #~ import pdb; pdb.set_trace() _logger.error('WebFault Error!: %s' % (e)) raise osv.except_osv(_(u'WebFault Error!'), _(u'Error: %s') % (e)) except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error %i: %s') % (e[0], e[1])) for resp in response.FEXAuthorizeResult.FEXResultAuth: if resp.Resultado == 'R': # Existe Error! _logger.error('Rejected invoice: %s' % (resp,)) r[int(resp.Id)]={ 'Eventos': [ (o.EventCode, unicode(o.EventMsg)) for o in response.FEXAuthorizeResult.FEXEvents ] if hasattr(response.FEXAuthorizeResult, 'FEXEvents') else [], 'Errores': [ (e.ErrCode, unicode(e.ErrMsg)) for e in response.FEXAuthorizeResult.FEXErr ] if hasattr(response.FEXAuthorizeResult, 'FEXErr') else [], } else: # Todo bien! r[int(resp.Id)]={ 'CAE': resp.Cae, 'CAEFchVto': resp.Fch_venc_Cae, } return r
def wsfe_update_document_type(self, cr, uid, ids, conn_id, context=None): """ Update document type. This function must be called from connection model. Recuperador de valores referenciales de códigos de Tipos de Documentos (FEParamGetTiposDoc) """ conn_obj = self.pool.get('wsafip.connection') for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFE. if srv.code != 'wsfe': continue # Take the connection, continue if connected or clockshifted conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() if conn.state not in ['connected', 'clockshifted']: continue try: _logger.info('Updating document types from AFIP Web service') srvclient = Client(srv.url + '?WSDL', transport=HttpsTransport()) response = srvclient.service.FEParamGetTiposDoc( Auth=conn.get_auth()) # Take list of document types doctype_list = [{ 'afip_code': c.Id, 'name': c.Desc, 'code': c.Desc, 'active': c.FchHasta in [None, 'NULL'] } for c in response.ResultGet.DocTipo] except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv( _(u'AFIP Web service error'), _(u'System return error %i: %s') % (e[0], e[1])) _update(self.pool, cr, uid, 'afip.document_type', doctype_list, can_create=True, domain=[]) return True
def wsfe_update_journal_class(self, cr, uid, ids, conn_id, context=None): """ Update journal class. AFIP Description: Recuperador de valores referenciales de códigos de Tipos de comprobante (FEParamGetTiposCbte) """ journal_obj = self.pool.get('afip.journal_class') conn_obj = self.pool.get('wsafip.connection') for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFE. if srv.code != 'wsfe': continue # Take the connection, continue if connected or clockshifted conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if nescesary. if conn.state not in ['connected', 'clockshifted']: continue try: _logger.info('Updating journal class from AFIP Web service') srvclient = Client(srv.url + '?WSDL', transport=HttpsTransport()) response = srvclient.service.FEParamGetTiposCbte( Auth=conn.get_auth()) # Take list of journal class journalclass_list = [{ 'afip_code': c.Id, 'name': c.Desc, 'active': c.FchHasta in [None, 'NULL'] } for c in response.ResultGet.CbteTipo] except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv( _(u'AFIP Web service error'), _(u'System return error %i: %s') % (e[0], e[1])) _update(self.pool, cr, uid, 'afip.journal_class', journalclass_list, can_create=False, domain=[('afip_code', '!=', 0)]) return
def wsfex_check_permissions(client, token, sign, cuit, id_permiso, dst_merc): """ Check shipment/destination country permissions from AFIP AFIP Description: Verifica la existencia de la permiso/pais de destinación de embarque ingresado (FEXCheck_Permiso) """ conn_obj = self.pool.get('wsafip.connection') r={} for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFEX. if srv.code != 'wsfex': continue # Take the connection conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if necessary. if conn.state not in [ 'connected', 'clockshifted' ]: r[srv.id] = False continue try: _logger.info('Check shipment/destination country permissions from AFIP Web service') srvclient = Client(srv.url+'?WSDL', transport=HttpsTransport()) response = srvclient.service.FEXCheck_Permiso(Auth=conn.get_auth(), ID_Permiso=id_permiso, Dst_merc=dst_merc) except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error %i: %s\n' u'Pueda que esté intente realizar esta operación' u'desde el servidor de homologación.' u'Intente desde el servidor de producción.') % (e[0], e[1])) if hasattr(response, 'Errors'): for e in response.Errors.Err: code = e.Code _logger.error('AFIP Web service error!: (%i) %s' % (e.Code, e.Msg)) r[srv.id] = False else: r[srv.id] = str(response.FEXCheck_PermisoResult.FEXResultGet.Status) return r
def wsfex_update_languages(self, cr, uid, ids, conn_id, context=None): """ Updates the list of available Languages. AFIP Description: Recupera el listado de los idiomas y sus codigos utilizables en servicio de autorizacion (FEXGetPARAM_Idiomas) """ conn_obj = self.pool.get('wsafip.connection') for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFEX. if srv.code != 'wsfex': continue # Take the connection, continue if connected or clockshifted conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if necessary. if conn.state not in [ 'connected', 'clockshifted' ]: continue # Build request try: _logger.debug('Updating list of Languages from AFIP Web service') srvclient = Client(srv.url+'?WSDL', transport=HttpsTransport()) response = srvclient.service.FEXGetPARAM_Idiomas(Auth=conn.get_auth()) # Take list of available languages languages_list = [ {'afip_lang_id': res.Idi_Id, 'language_name': res.Idi_Ds } for res in response.FEXResultGet.ClsFEXResponse_Idi ] except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error %i: %s') % (e[0], e[1])) _update(self.pool, cr, uid, 'afip.fex_language', languages_list, can_create=True ) return
def wsfex_get_last_id(self, cr, uid, ids, conn_id, context=None): """ Get Last ID number from AFIP. AFIP Description: Recupera el ultimo ID y su fecha (FEXGetLast_ID) """ conn_obj = self.pool.get('wsafip.connection') for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFEX. if srv.code != 'wsfex': continue # Take the connection conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if necessary. if conn.state not in [ 'connected', 'clockshifted' ]: r[srv.id] = False continue try: _logger.info('Take last invoice number from AFIP Web service') srvclient = Client(srv.url+'?WSDL', transport=HttpsTransport()) response = srvclient.service.FEXGetLast_ID(Auth=conn.get_auth()) except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error %i: %s\n' u'Pueda que esté intente realizar esta operación' u'desde el servidor de homologación.' u'Intente desde el servidor de producción.') % (e[0], e[1])) if hasattr(response, 'Errors'): for e in response.Errors.Err: code = e.Code _logger.error('AFIP Web service error!: (%i) %s' % (e.Code, e.Msg)) r[srv.id] = False else: r[srv.id] = int(response.FEXGetLast_IDResult.FEXResultGet.Id) return r
def wsfex_update_uom(self, cr, uid, ids, conn_id, context=None): """ Update UoM. This function must be called from connection model. AFIP Description: Recupera el listado de las unidades de medida y su codigo utilizables en servicio de autorizacion (FEXGetPARAM_UMed) """ conn_obj = self.pool.get('wsafip.connection') for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFEX. if srv.code != 'wsfex': continue # Take the connection, continue if connected or clockshifted conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if necessary. if conn.state not in [ 'connected', 'clockshifted' ]: continue try: _logger.info('Updating UoM from AFIP Web service') srvclient = Client(srv.url+'?WSDL', transport=HttpsTransport()) response = srvclient.service.FEXGetPARAM_UMed(Auth=conn.get_auth()) # Take list of UoM available uom_list = [ { 'afip_code': c.Umed_Id, 'name': c.Umed_Ds } for c in response.FEXResultGet.ClsFEXResponse_UMed ] except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error %i: %s') % (e[0], e[1])) _update(self.pool, cr, uid, 'product.uom', uom_list, can_create=True ) return True
def wsfe_query_invoice(self, cr, uid, ids, conn_id, cbteTipo, cbteNro, ptoVta, context=None): """ Query for invoice stored by AFIP Web service. AFIP Description: Método para consultar Comprobantes Emitidos y su código (FECompConsultar) """ conn_obj = self.pool.get('wsafip.connection') r = {} for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFE. if srv.code != 'wsfe': continue # Take the connection conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if nescesary. try: _logger.info('Query for invoice stored by AFIP Web service') srvclient = Client(srv.url+'?WSDL', transport=HttpsTransport()) response = srvclient.service.FECompConsultar(Auth=conn.get_auth(), FeCompConsReq={ 'CbteTipo': cbteTipo, 'CbteNro': cbteNro, 'PtoVta': ptoVta, }) except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error %i: %s\n' u'Pueda que esté intente realizar esta operación' u'desde el servidor de homologación.' u'Intente desde el servidor de producción.') % (e[0], e[1])) if hasattr(response, 'Errors'): for e in response.Errors.Err: code = e.Code _logger.error('AFIP Web service error!: (%i) %s' % (e.Code, e.Msg)) r[srv.id] = False else: r[srv.id] = { 'Concepto': response.ResultGet.Concepto, 'DocTipo': response.ResultGet.DocTipo, 'DocNro': response.ResultGet.DocNro, 'CbteDesde': response.ResultGet.CbteDesde, 'CbteHasta': response.ResultGet.CbteHasta, 'CbteFch': response.ResultGet.CbteFch, 'ImpTotal': response.ResultGet.ImpTotal, 'ImpTotConc': response.ResultGet.ImpTotConc, 'ImpNeto': response.ResultGet.ImpNeto, 'ImpOpEx': response.ResultGet.ImpOpEx, 'ImpTrib': response.ResultGet.ImpTrib, 'ImpIVA': response.ResultGet.ImpIVA, 'FchServDesde': response.ResultGet.FchServDesde, 'FchServHasta': response.ResultGet.FchServHasta, 'FchVtoPago': response.ResultGet.FchVtoPago, 'MonId': response.ResultGet.MonId, 'MonCotiz': response.ResultGet.MonCotiz, 'Resultado': response.ResultGet.Resultado, 'CodAutorizacion': response.ResultGet.CodAutorizacion, 'EmisionTipo': response.ResultGet.EmisionTipo, 'FchVto': response.ResultGet.FchVto, 'FchProceso': response.ResultGet.FchProceso, 'PtoVta': response.ResultGet.PtoVta, 'CbteTipo': response.ResultGet.CbteTipo, } return r
def wsfe_get_cae(self, cr, uid, ids, conn_id, invoice_request, context=None): """ Get CAE. AFIP Description: Método de autorización de comprobantes electrónicos por CAE (FECAESolicitar) """ conn_obj = self.pool.get('wsafip.connection') r = {} for srv in self.browse(cr, uid, ids, context=context): # Ignore servers without code WSFE. if srv.code != 'wsfe': continue # Take the connection conn = conn_obj.browse(cr, uid, conn_id, context=context) conn.login() # Login if nescesary. if conn.state not in [ 'connected', 'clockshifted' ]: continue _logger.info('Get CAE from AFIP Web service') auth = conn.get_auth() try: srvclient = Client(srv.url+'?WSDL', transport=HttpsTransport()) first = invoice_request.keys()[0] response = srvclient.service.FECAESolicitar(Auth=auth, FeCAEReq = [{ 'FeCabReq':{ 'CantReg': len(invoice_request), 'PtoVta': invoice_request[first]['PtoVta'], 'CbteTipo': invoice_request[first]['CbteTipo'], }, 'FeDetReq': [ { 'FECAEDetRequest': dict( [ (k, v) for k,v in req.iteritems() if k not in ['CantReg', 'PtoVta', 'CbteTipo'] ] ) } for req in invoice_request.itervalues() ], }] ) except WebFault as e: _logger.error('AFIP Web service error!: %s' % (e[0])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error: %s') % e[0]) except Exception as e: _logger.error('AFIP Web service error!: (%i) %s' % (e[0], e[1])) raise osv.except_osv(_(u'AFIP Web service error'), _(u'System return error %i: %s') % (e[0], e[1])) soapRequest = [{ 'FeCabReq':{ 'CantReg': len(invoice_request), 'PtoVta': invoice_request[first]['PtoVta'], 'CbteTipo': invoice_request[first]['CbteTipo'],}, 'FeDetReq': [{ 'FECAEDetRequest': dict([ (k, v) for k,v in req.iteritems() if k not in ['CantReg', 'PtoVta', 'CbteTipo'] ] ) } for req in invoice_request.itervalues()], }] try: common_error = [ (e.Code, unicode(e.Msg)) for e in response.Errors[0] ] if response.FeCabResp.Resultado in ["P", "R"] and hasattr(response, 'Errors') else [] else: import pdb; pdb.set_trace() _logger.error('Request error: %s' % (common_error,)) for resp in response.FeDetResp.FECAEDetResponse: if resp.Resultado == 'R': # Existe Error! _logger.error('Invoice error: %s' % (resp,)) r[int(resp.CbteDesde)]={ 'CbteDesde': resp.CbteDesde, 'CbteHasta': resp.CbteHasta, 'Observaciones': [ (o.Code, unicode(o.Msg)) for o in resp.Observaciones.Obs ] if hasattr(resp,'Observaciones') else [], 'Errores': common_error + [ (e.Code, unicode(e.Msg)) for e in response.Errors.Err ] if hasattr(response, 'Errors') else [], } else: # Todo bien! r[int(resp.CbteDesde)]={ 'CbteDesde': resp.CbteDesde, 'CbteHasta': resp.CbteHasta, 'CAE': resp.CAE, 'CAEFchVto': resp.CAEFchVto, 'Request': soapRequest, 'Response': response, }