def test_save_pfx(self): pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read() pfx = Certificado(pfx_source, '123') path = pfx.save_pfx() saved = open(path, 'r').read() self.assertEqual(pfx_source, saved, 'Arquivo pfx salvo não bate com arquivo lido')
def test_save_pfx(self): pfx_source = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() pfx = Certificado(pfx_source, "123") path = pfx.save_pfx() saved = open(path, "rb").read() self.assertEqual( pfx_source, saved, "Arquivo pfx salvo não bate com arquivo lido" )
def consulta_cnpj_prefeitura(self): self.ensure_one() company = self.company_id or self.env.user.company_id if not company.nfe_a1_file: raise UserError('Atenção!', 'Certificado não configurado') if not company.nfe_a1_password: raise UserError('Atenção!', 'Senha do Certificado não configurado') if not company.cnpj_cpf: raise UserError('Atenção!', 'CNPJ da empresa não configurado') if not self.cnpj_cpf: raise UserError('Atenção!', 'CNPJ do cliente não preenchido') pfx_stream = base64.b64decode(company.nfe_a1_file) certificado = Certificado(pfx_stream, company.nfe_a1_password) consulta = { 'cnpj_remetente': re.sub('[^0-9]', '', company.cnpj_cpf), 'cnpj_contribuinte': re.sub('[^0-9]', '', self.cnpj_cpf) } result = consulta_cnpj(certificado, consulta=consulta) if result['object'].Cabecalho.Sucesso: if "Alerta" in dir(result['object']): message = "%s - %s" % (result['object'].Alerta.Codigo, result['object'].Alerta.Descricao) raise UserError('Atenção', message) message = u"Emitente com inscrição: %s\nEmite NFe: %s" % ( result['object'].Detalhe.InscricaoMunicipal, u'Sim' if result['object'].Detalhe.EmiteNFe else u'Não') raise UserError('Resultado da Consulta', message) else: message = "%s - %s" % (result['object'].Erro.Codigo, result['object'].Erro.Descricao) raise UserError('Atenção', message)
def action_post_validate(self): super(InvoiceEletronic, self).action_post_validate() if self.model not in ('55', '65'): return chave_dict = { 'cnpj': re.sub('[^0-9]', '', self.company_id.cnpj_cpf), 'estado': self.company_id.state_id.ibge_code, 'emissao': self.data_emissao[2:4] + self.data_emissao[5:7], 'modelo': self.model, 'numero': self.numero, 'serie': self.serie.code.zfill(3), 'tipo': int(self.tipo_emissao), 'codigo': "%08d" % self.numero_controle } self.chave_nfe = gerar_chave(ChaveNFe(**chave_dict)) cert = self.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) nfe_values = self._prepare_eletronic_invoice_values() lote = self._prepare_lote(self.id, nfe_values) xml_enviar = xml_autorizar_nfe(certificado, **lote) mensagens_erro = valida_nfe(xml_enviar) if mensagens_erro: raise UserError(mensagens_erro) self.xml_to_send = base64.encodestring(xml_enviar.encode('utf-8')) self.xml_to_send_name = 'nfse-enviar-%s.xml' % self.numero
def cancel_api(certificate, password, vals): cert_pfx = base64.decodestring(certificate) certificado = Certificado(cert_pfx, password) canc = { 'motivo': vals['justificativa'], 'aedf': vals['aedf'], 'numero': vals['numero'], 'codigo_verificacao': vals['protocolo_nfe'], } resposta = cancelar_nota( certificado, cancelamento=canc, ambiente=vals['ambiente'], client_id=vals['client_id'], secret_id=vals['client_secret'], username=vals['inscricao_municipal'], password=vals['user_password'] ) retorno = resposta['object'] msg_cancelada = 'A Nota Fiscal já está com a situação cancelada.' if resposta['status_code'] == 200 or retorno.message == msg_cancelada: return { 'code': 200, 'message': 'Nota Fiscal Cancelada', } else: return { 'code': 400, 'api_code': resposta['status_code'], 'message': retorno.message, }
def send_api(certificate, password, list_rps): cert_pfx = base64.decodestring(certificate) certificado = Certificado(cert_pfx, password) vals = list_rps[0] vals = _convert_values(vals) recebe_lote = processar_nota( certificado, rps=vals, ambiente=vals['ambiente'], client_id=vals['client_id'], secret_id=vals['client_secret'], username=vals['emissor']['inscricao_municipal'], password=vals['user_password']) retorno = recebe_lote['object'] if "codigoVerificacao" in dir(retorno): return { 'code': 201, 'entity': { 'protocolo_nfe': retorno.codigoVerificacao, 'numero_nfe': retorno.numeroSerie, }, 'xml': recebe_lote['received_xml'], } else: return { 'code': 400, 'api_code': recebe_lote['status_code'], 'message': retorno.message, }
def cancel_api(certificate, password, vals): cert_pfx = base64.decodestring(certificate) certificado = Certificado(cert_pfx, password) canc = { 'numero_nfse': vals['numero'], 'cnpj_prestador': vals['cnpj_cpf'], 'inscricao_municipal': vals['inscricao_municipal'], 'cidade': vals['codigo_municipio'], } resposta = cancelar_nfse(certificado, cancelamento=canc, ambiente=vals['ambiente'], client_id=vals['client_id'], secret_id=vals['client_secret'], username=vals['inscricao_municipal'], password=vals['user_password']) retorno = resposta['object'] if "RetCancelamento" in dir(retorno): return { 'code': 200, 'message': 'Nota Fiscal Cancelada', 'xml': resposta['received_xml'].split( "<?xml version='1.0' encoding='UTF-8'?>")[1].encode('utf - 8') } else: erro_retorno = retorno.ListaMensagemRetorno.MensagemRetorno return { 'code': 400, 'api_code': erro_retorno.Codigo, 'message': erro_retorno.Mensagem, }
def cancel_nfse(self): if self.city_code == '50308': # São Paulo pfx_stream = base64.b64decode(self.certificate) certificado = Certificado(pfx_stream, self.password) company = self.invoice_id.company_id canc = { 'cnpj_remetente': re.sub('[^0-9]', '', company.cnpj_cpf), 'inscricao_municipal': re.sub('[^0-9]', '', company.inscr_mun), 'numero_nfse': self.invoice_id.internal_number, 'codigo_verificacao': self.invoice_id.verify_code, 'assinatura': '%s%s' % (re.sub('[^0-9]', '', company.inscr_mun), self.invoice_id.internal_number.zfill(12)) } resposta = cancelamento_nfe(certificado, cancelamento=canc) status = self._create_status(resposta, 'cancelamento') return status return super(BaseNfse, self).cancel_nfse()
def action_check_nfse_status(self): if self.model != '001': raise UserError( 'A consulta de situação serve apenas para São Paulo') cert = self.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) company = self.company_id consulta = { 'cnpj_remetente': re.sub('[^0-9]', '', company.cnpj_cpf), 'inscricao_municipal': re.sub('[^0-9]', '', company.inscr_mun), 'numero_rps': self.numero, 'serie_rps': self.serie.code or '', } resposta = consulta_nfe(certificado, consulta=consulta) retorno = resposta['object'] if retorno.Cabecalho.Sucesso and "NFe" in dir(retorno): self.state = 'done' self.codigo_retorno = '100' self.mensagem_retorno = \ 'Nota Fiscal Paulistana emitida com sucesso' self.verify_code = retorno.NFe.ChaveNFe.CodigoVerificacao self.numero_nfse = retorno.NFe.ChaveNFe.NumeroNFe else: msg = '%s - %s' % (retorno.Alerta.Codigo, retorno.Alerta.Descricao) raise UserError(msg)
def cancel_api(certificate, password, vals): cert_pfx = base64.decodestring(certificate) certificado = Certificado(cert_pfx, password) canc = { 'cnpj_remetente': vals['cnpj_cpf'], 'inscricao_municipal': vals['inscricao_municipal'], 'numero_nfse': vals['numero'], 'codigo_verificacao': vals['protocolo_nfe'], 'assinatura': '%s%012d' % ( vals['inscricao_municipal'], vals['numero'], ) } if vals['ambiente'] == 'homologacao': return { 'code': 200, 'message': 'Nota Fiscal Cancelada', } resposta = cancelamento_nfe(certificado, cancelamento=canc) retorno = resposta['object'] if retorno.Cabecalho.Sucesso: return { 'code': 200, 'message': 'Nota Fiscal Cancelada', } else: return { 'code': 400, 'api_code': retorno.Erro.Codigo, 'message': retorno.Erro.Descricao, }
def action_cancel_document(self, context=None, justificativa=None): if self.model not in ('013'): return super(InvoiceEletronic, self).action_cancel_document( justificativa=justificativa) if not justificativa: return { 'name': 'Cancelamento NFe', 'type': 'ir.actions.act_window', 'res_model': 'wizard.cancel.nfse', 'view_type': 'form', 'view_mode': 'form', 'target': 'new', 'context': { 'default_edoc_id': self.id } } cert = self.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) company = self.company_id city_prestador = self.company_id.partner_id.city_id canc = { 'cnpj_prestador': re.sub('[^0-9]', '', company.cnpj_cpf), 'inscricao_municipal': re.sub('[^0-9]', '', company.inscr_mun), 'cidade': '%s%s' % (city_prestador.state_id.ibge_code, city_prestador.ibge_code), 'numero_nfse': self.numero_nfse, 'codigo_cancelamento': '1', # Erro na emissão } cancel = cancelar_nfse( certificado, cancelamento=canc, ambiente=self.ambiente) retorno = cancel['object'] if "Cancelamento" in dir(retorno): self.state = 'cancel' self.codigo_retorno = '100' self.mensagem_retorno = u'Nota Fiscal de Serviço Cancelada' else: # E79 - Nota já está cancelada if retorno.ListaMensagemRetorno.MensagemRetorno.Codigo != 'E79': mensagem = "%s - %s" % ( retorno.ListaMensagemRetorno.MensagemRetorno.Codigo, retorno.ListaMensagemRetorno.MensagemRetorno.Mensagem ) raise UserError(mensagem) self.state = 'cancel' self.codigo_retorno = '100' self.mensagem_retorno = u'Nota Fiscal de Serviço Cancelada' self.env['invoice.eletronic.event'].create({ 'code': self.codigo_retorno, 'name': self.mensagem_retorno, 'invoice_eletronic_id': self.id, }) self._create_attachment('canc', self, cancel['sent_xml']) self._create_attachment('canc-ret', self, cancel['received_xml'])
def action_send_eletronic_invoice(self): super(InvoiceEletronic, self).action_send_eletronic_invoice() if self.model == '001' and self.state not in ('done', 'cancel'): self.state = 'error' _logger.info('Sending NFS-e Paulistana (%s) %s' % ( self.numero, self.partner_id.name)) nfse_values = self._prepare_eletronic_invoice_values() cert = self.company_id.with_context( {'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado( cert_pfx, self.company_id.nfe_a1_password) if self.ambiente == 'producao': resposta = envio_lote_rps(certificado, nfse=nfse_values) else: resposta = teste_envio_lote_rps( certificado, nfse=nfse_values) retorno = resposta['object'] if retorno.Cabecalho.Sucesso: self.write({ 'state': 'done', 'codigo_retorno': '100', 'mensagem_retorno': 'Nota Paulistana emitida com sucesso', }) # Apenas producão tem essa tag if self.ambiente == 'producao': self.verify_code = \ retorno.ChaveNFeRPS.ChaveNFe.CodigoVerificacao self.numero_nfse = retorno.ChaveNFeRPS.ChaveNFe \ .NumeroNFe for inv_line in self.invoice_id.invoice_line_ids: if inv_line.product_id.fiscal_type == 'service': inv_line.write( {'state': 'transmitido', 'numero_nfse': self.numero_nfse}) else: self.write({ 'codigo_retorno': retorno.Erro.Codigo, 'mensagem_retorno': retorno.Erro.Descricao, }) self.notify_user() self.env['invoice.eletronic.event'].create({ 'code': self.codigo_retorno, 'name': self.mensagem_retorno, 'invoice_eletronic_id': self.id, }) self._create_attachment( 'nfse-envio', self, resposta['sent_xml']) self._create_attachment( 'nfse-ret', self, resposta['received_xml']) _logger.info('NFS-e Paulistana (%s) finished with status %s' % ( self.numero, self.codigo_retorno))
def action_cancel_document(self, context=None, justificativa=None): if self.model not in ('012'): return super( InvoiceEletronic, self).action_cancel_document(justificativa=justificativa) if not justificativa: return { 'name': 'Cancelamento NFe', 'type': 'ir.actions.act_window', 'res_model': 'wizard.cancel.nfse', 'view_type': 'form', 'view_mode': 'form', 'target': 'new', 'context': { 'default_edoc_id': self.id } } cert = self.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) company = self.company_id canc = { 'motivo': justificativa, 'aedf': re.sub('[^0-9]', '', company.aedf), 'numero': self.numero_nfse, 'codigo_verificacao': self.verify_code, } resposta = cancelar_nota(certificado, cancelamento=canc, ambiente=self.ambiente, client_id=self.company_id.client_id, secret_id=self.company_id.client_secret, username=self.company_id.inscr_mun, password=self.company_id.user_password) retorno = resposta['object'] msg_cancelada = 'A Nota Fiscal já está com a situação cancelada.' if resposta['status_code'] == 200 or retorno.message == msg_cancelada: self.state = 'cancel' self.codigo_retorno = '100' self.mensagem_retorno = 'Nota Fiscal Cancelada' else: self.codigo_retorno = resposta['status_code'] self.mensagem_retorno = retorno.message self.env['invoice.eletronic.event'].create({ 'code': self.codigo_retorno, 'name': self.mensagem_retorno, 'invoice_eletronic_id': self.id, }) self._create_attachment('canc', self, resposta['sent_xml']) self._create_attachment('canc-ret', self, resposta['received_xml'].decode('utf-8'))
def action_cancel_document(self, context=None, justificativa=None): if self.model not in ('001'): return super( InvoiceEletronic, self).action_cancel_document(justificativa=justificativa) _logger.info('Cancelling NFS-e Paulistana (%s)' % self.numero) cert = self.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) if self.ambiente == 'homologacao' or \ self.company_id.tipo_ambiente_nfse == 'homologacao': self.state = 'cancel' self.codigo_retorno = '100' self.mensagem_retorno = 'Nota Fiscal Paulistana Cancelada' return company = self.company_id canc = { 'cnpj_remetente': re.sub('[^0-9]', '', company.cnpj_cpf), 'inscricao_municipal': re.sub('[^0-9]', '', company.inscr_mun), 'numero_nfse': self.numero_nfse, 'codigo_verificacao': self.verify_code, 'assinatura': '%s%s' % (re.sub('[^0-9]', '', company.inscr_mun), self.numero_nfse.zfill(12)) } resposta = cancelamento_nfe(certificado, cancelamento=canc) retorno = resposta['object'] if retorno.Cabecalho.Sucesso: self.write({ 'state': 'cancel', 'codigo_retorno': '100', 'mensagem_retorno': 'Nota Fiscal Paulistana Cancelada', }) else: self.write({ 'codigo_retorno': retorno.Erro.Codigo, 'mensagem_retorno': retorno.Erro.Descricao, }) self.env['invoice.eletronic.event'].create({ 'code': self.codigo_retorno, 'name': self.mensagem_retorno, 'invoice_eletronic_id': self.id, }) self._create_attachment('canc', self, resposta['sent_xml']) self._create_attachment('canc-ret', self, resposta['received_xml']) _logger.info('Cancelling NFS-e (%s) was finished with status %s' % (self.numero, self.codigo_retorno))
def test_envio_nfse(self): pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read() pfx = Certificado(pfx_source, '123456') rps = [ { 'assinatura': '123', 'serie': '1', 'numero': '1', 'data_emissao': '2016-08-29', 'codigo_atividade': '07498', 'total_servicos': '2.00', 'total_deducoes': '3.00', 'prestador': { 'inscricao_municipal': '123456' }, 'tomador': { 'tipo_cpfcnpj': '1', 'cpf_cnpj': '12345678923256', 'inscricao_municipal': '123456', 'razao_social': 'Trustcode', 'tipo_logradouro': '1', 'logradouro': 'Vinicius de Moraes, 42', 'numero': '42', 'bairro': 'Corrego', 'cidade': 'Floripa', 'uf': 'SC', 'cep': '88037240', }, 'codigo_atividade': '07498', 'aliquota_atividade': '5.00', 'descricao': 'Venda de servico' } ] nfse = { 'cpf_cnpj': '12345678901234', 'data_inicio': '2016-08-29', 'data_fim': '2016-08-29', 'lista_rps': rps } path = os.path.join(os.path.dirname(__file__), 'XMLs') xml_return = open(os.path.join( path, 'paulistana_resultado.xml'), 'r').read() with mock.patch('pytrustnfe.nfse.paulistana.get_authenticated_client') as client: retorno = mock.MagicMock() client.return_value = retorno retorno.service.EnvioLoteRPS.return_value = xml_return retorno = envio_lote_rps(pfx, nfse=nfse) self.assertEqual(retorno['received_xml'], xml_return) self.assertEqual(retorno['object'].Cabecalho.Sucesso, True) self.assertEqual( retorno['object'].ChaveNFeRPS.ChaveNFe.NumeroNFe, 446) self.assertEqual( retorno['object'].ChaveNFeRPS.ChaveRPS.NumeroRPS, 6)
def action_check_sefaz(self): if self.cnpj_cpf and self.state_id: if self.state_id.code == 'AL': raise UserError(u'Alagoas não possui consulta de cadastro') company = self.env.user.company_id if not company.nfe_a1_file and not company.nfe_a1_password: raise UserError(u'Configurar o certificado e senha na empresa') cert = company.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, company.nfe_a1_password) cnpj = re.sub('[^0-9]', '', self.cnpj_cpf) obj = {'cnpj': cnpj, 'estado': self.state_id.code} resposta = consulta_cadastro(certificado, obj=obj, ambiente=1, estado=self.state_id.ibge_code) obj = resposta['object'] if "Body" in dir(obj) and \ "consultaCadastro2Result" in dir(obj.Body): info = obj.Body.consultaCadastro2Result.retConsCad.infCons if info.cStat == 111 or info.cStat == 112: if not self.inscr_est: self.inscr_est = info.infCad.IE if not self.cnpj_cpf: self.cnpj_cpf = info.infCad.IE def get_value(obj, prop): if prop not in dir(obj): return None return getattr(obj, prop) self.legal_name = get_value(info.infCad, 'xNome') if "ender" not in dir(info.infCad): return cep = get_value(info.infCad.ender, 'CEP') or '' self.zip = str(cep).zfill(8) if cep else '' self.street = get_value(info.infCad.ender, 'xLgr') self.number = get_value(info.infCad.ender, 'nro') self.street2 = get_value(info.infCad.ender, 'xCpl') self.district = get_value(info.infCad.ender, 'xBairro') cMun = get_value(info.infCad.ender, 'cMun') xMun = get_value(info.infCad.ender, 'xMun') city = None if cMun: city = self.env['res.state.city'].search( [('ibge_code', '=', str(cMun)[2:]), ('state_id', '=', self.state_id.id)]) if not city and xMun: city = self.env['res.state.city'].search( [('name', 'ilike', xMun), ('state_id', '=', self.state_id.id)]) if city: self.city_id = city.id else: msg = "%s - %s" % (info.cStat, info.xMotivo) raise UserError(msg) else: raise UserError(u'Preencha o estado e o CNPJ para pesquisar')
def test_consulta_situacao_lote(self): pfx_source = open("/home/danimar/Downloads/machado.pfx", "rb").read() pfx = Certificado(pfx_source, "123456789") dados = {"ambiente": "homologacao"} retorno = consultar_situacao_lote(pfx, consulta=dados, ambiente="homologacao") self.assertNotEqual(retorno["received_xml"], "") self.assertEqual(retorno["object"].Cabecalho.Sucesso, True)
def test_consulta_situacao_lote(self): pfx_source = open('/home/danimar/Downloads/machado.pfx', 'rb').read() pfx = Certificado(pfx_source, '123456789') dados = {'ambiente': 'homologacao'} retorno = consultar_situacao_lote(pfx, consulta=dados, ambiente='homologacao') self.assertNotEqual(retorno['received_xml'], '') self.assertEqual(retorno['object'].Cabecalho.Sucesso, True)
def _prepare_xml_dfe_query(self): lote = self._prepare_dfe_query_values() cert = self.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) xml_enviar = xml_consulta_distribuicao_nfe(certificado, **lote) xml_to_send = base64.encodestring(xml_enviar.encode('utf-8')) return xml_to_send
def manifestar_nfe(self): #certificado = open("/path/certificado.pfx", "r").read() #certificado = Certificado(certificado, 'senha_pfx') import pudb pu.db fatura = self.env['account.invoice'].browse( self._context.get('invoice_id')) cert = fatura.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, fatura.company_id.nfe_a1_password) obj = { 'manifesto.cnpj_empresa': re.sub("[^0-9]", "", fatura.company_id.cnpj_cpf or ''), 'estado': '35', 'ambiente': 1, 'manifesto.chave_nfe': '35180563910657000106550010000054201000054204', } #'ultimo_nsu':'000000000008023', #valida_xml = xml_consulta_distribuicao_nfe(certificado, **obj) #erro_xml = self.validar(valida_xml) #resposta = consulta_distribuicao_nfe(certificado, obj=obj, ambiente=2, estado='35', ultNSU= '000000000000008') #resposta = consulta_distribuicao_nfe(certificado, **obj) resposta = download_nfe(certificado, **obj) data = resposta['received_xml'] #self.eletronic_doc_id._create_attachment( # 'cce_ret', self.eletronic_doc_id, resposta['received_xml']) file_name = 'xxxx.xml' self.env['ir.attachment'].create({ 'name': file_name, 'datas': base64.b64encode(data.encode()), 'datas_fname': file_name, 'description': u'', 'res_model': 'account.invoice', 'res_id': fatura.id }) print(resposta) print(resposta['received_xml'])
def action_post_validate(self): super(InvoiceEletronic, self).action_post_validate() if self.model not in ('008'): return cert = self.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) nfse_values = self._prepare_eletronic_invoice_values() xml_enviar = xml_gerar_nfse(certificado, nfse=nfse_values) self.xml_to_send = base64.encodestring(xml_enviar) self.xml_to_send_name = 'nfse-enviar-%s.xml' % self.numero
def send_sefaz(self): company = self.env.user.company_id ambiente = company.tipo_ambiente estado = company.state_id.ibge_code obj = self._prepare_obj(company=company, estado=estado, ambiente=ambiente) cert = company.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, company.nfe_a1_password) resposta = inutilizar_nfe(certificado, obj=obj, estado=estado, ambiente=int(ambiente)) self._handle_resposta(resposta=resposta)
def test_nfse_signature(self): pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read() pfx = Certificado(pfx_source, '123456') nfse = self._get_nfse() path = os.path.join(os.path.dirname(__file__), 'XMLs') xml_sent = open(os.path.join(path, 'paulistana_signature.xml'), 'r').read() with mock.patch('pytrustnfe.nfse.paulistana.get_authenticated_client' ) as client: retorno = mock.MagicMock() client.return_value = retorno retorno.service.EnvioLoteRPS.return_value = '<xml></xml>' retorno = envio_lote_rps(pfx, nfse=nfse) self.assertEqual(retorno['sent_xml'], xml_sent)
def check_nfse_by_lote(self): if self.city_code == '50308': # São Paulo pfx_stream = base64.b64decode(self.certificate) certificado = Certificado(pfx_stream, self.password) company = self.invoice_id.company_id consulta = { 'cnpj_remetente': re.sub('[^0-9]', '', company.cnpj_cpf), 'lote': self.invoice_id.lote_nfse, 'inscricao_municipal': re.sub('[^0-9]', '', company.inscr_mun) } resposta = consulta_lote(certificado, consulta=consulta) status = self._create_status(resposta, 'consulta_lote') return status return super(BaseNfse, self).check_nfse_by_lote()
def action_get_status(self): cert = self.company_id.with_context({ 'bin_size': False }).l10n_br_certificate cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.l10n_br_cert_password) consulta = { 'estado': self.company_id.state_id.l10n_br_ibge_code, 'ambiente': 2 if self.ambiente == 'homologacao' else 1, 'modelo': '55' if self.model == 'nfe' else '65', 'obj': { 'chave_nfe': self.chave_nfe, 'ambiente': 2 if self.ambiente == 'homologacao' else 1, } } resp = consultar_protocolo_nfe(certificado, **consulta) retorno_consulta = resp['object'].getchildren()[0] if retorno_consulta.cStat == 101: self.state = 'cancel' self.codigo_retorno = retorno_consulta.cStat self.mensagem_retorno = retorno_consulta.xMotivo resp['received_xml'] = etree.tostring(retorno_consulta, encoding=str) # self.env['invoice.eletronic.event'].create({ # 'code': self.codigo_retorno, # 'name': self.mensagem_retorno, # 'eletronic_document_id': self.id, # }) self._create_attachment('canc', self, resp['sent_xml']) self._create_attachment('canc-ret', self, resp['received_xml']) nfe_processada = base64.decodestring(self.nfe_processada) nfe_proc_cancel = gerar_nfeproc_cancel( nfe_processada, resp['received_xml'].encode()) if nfe_proc_cancel: self.sudo().write({ 'nfe_processada': base64.encodestring(nfe_proc_cancel), }) else: message = "%s - %s" % (retorno_consulta.cStat, retorno_consulta.xMotivo) raise UserError(message)
def test_cancelamento_nfse_ok(self): pfx_source = open(os.path.join(self.caminho, 'teste.pfx'), 'r').read() pfx = Certificado(pfx_source, '123456') cancelamento = self._get_cancelamento() path = os.path.join(os.path.dirname(__file__), 'XMLs') xml_return = open(os.path.join( path, 'paulistana_canc_ok.xml'), 'r').read() with mock.patch('pytrustnfe.nfse.paulistana.get_authenticated_client') as client: retorno = mock.MagicMock() client.return_value = retorno retorno.service.CancelamentoNFe.return_value = xml_return retorno = cancelamento_nfe(pfx, cancelamento=cancelamento) self.assertEqual(retorno['received_xml'], xml_return) self.assertEqual(retorno['object'].Cabecalho.Sucesso, True)
def action_post_validate(self): super(InvoiceEletronic, self).action_post_validate() if self.model not in ('55', '65'): return chave_dict = { 'cnpj': re.sub('[^0-9]', '', self.company_id.cnpj_cpf), 'estado': self.company_id.state_id.ibge_code, 'emissao': self.data_emissao[2:4] + self.data_emissao[5:7], 'modelo': self.model, 'numero': self.numero, 'serie': self.serie.code.zfill(3), 'tipo': int(self.tipo_emissao), 'codigo': "%08d" % self.numero_controle } self.chave_nfe = gerar_chave(ChaveNFe(**chave_dict)) cert = self.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) nfe_values = self._prepare_eletronic_invoice_values() lote = self._prepare_lote(self.id, nfe_values) xml_enviar = xml_autorizar_nfe(certificado, **lote) # _logger.info("============================xml_enviar before===========================%s", xml_enviar) # xml_enviar1 = xml_enviar.split('<dest>')[0] # xml_enviar2 = xml_enviar.split('<dest>')[1] # if self.ind_dest == '3': # xml_enviar = xml_enviar1+'<dest><idEstrangeiro>'+re.sub('[^0-9]', '', self.partner_id.cnpj_cpf or '')+'</idEstrangeiro>'+xml_enviar2 if self.partner_id.cnpj_cpf else xml_enviar1+'<dest><idEstrangeiro/>'+xml_enviar2 # _logger.info("========================xml_enviar after===========================%s", xml_enviar) mensagens_erro = valida_nfe(xml_enviar) _logger.info( "========================mensagens_erro===========================%s", mensagens_erro) if mensagens_erro: raise UserError(mensagens_erro) self.xml_to_send = base64.encodestring(xml_enviar.encode('utf-8')) self.xml_to_send_name = 'nfse-enviar-%s.xml' % self.numero _logger.info( "========================self.xml_to_send_name===========================%s", self.xml_to_send_name)
def action_send_eletronic_invoice(self): super(InvoiceEletronic, self).action_send_eletronic_invoice() if self.model == '001': self.state = 'error' nfse_values = self._prepare_eletronic_invoice_values() cert = self.company_id.with_context({ 'bin_size': False }).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) if self.ambiente == 'producao': resposta = envio_lote_rps(certificado, nfse=nfse_values) else: resposta = teste_envio_lote_rps(certificado, nfse=nfse_values) retorno = resposta['object'] if retorno.Cabecalho.Sucesso: self.state = 'done' self.codigo_retorno = '100' self.mensagem_retorno = \ 'Nota Fiscal Paulistana emitida com sucesso' if self.ambiente == 'producao': # Apenas producão tem essa tag self.verify_code = \ retorno.ChaveNFeRPS.ChaveNFe.CodigoVerificacao self.numero_nfse = retorno.ChaveNFeRPS.ChaveNFe.NumeroNFe else: self.codigo_retorno = retorno.Erro.Codigo self.mensagem_retorno = retorno.Erro.Descricao self.env['invoice.eletronic.event'].create({ 'code': self.codigo_retorno, 'name': self.mensagem_retorno, 'invoice_eletronic_id': self.id, }) self._create_attachment('nfse-envio', self, resposta['sent_xml']) self._create_attachment('nfse-ret', self, resposta['received_xml'])
def action_send_eletronic_invoice(self): super(InvoiceEletronic, self).action_send_eletronic_invoice() if self.model != '014' or self.state in ('done', 'cancel'): return self.state = 'error' xml_to_send = base64.decodestring(self.xml_to_send) cert = self.company_id.with_context({'bin_size': False}).nfe_a1_file cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) enviar_nfse = gerar_nfse(certificado, xml=xml_to_send, ambiente=self.ambiente) retorno = enviar_nfse['object'] if "ListaNfse" in dir(retorno): self.state = 'done' self.codigo_retorno = '100' self.mensagem_retorno = 'NFSe emitida com sucesso' self.verify_code = \ retorno.ListaNfse.CompNfse.Nfse.InfNfse.CodigoVerificacao.text self.numero_nfse = retorno.ListaNfse.CompNfse.Nfse.InfNfse.Numero else: msg = None if "ListaMensagemRetorno" in dir(retorno): msg = retorno.ListaMensagemRetorno.MensagemRetorno else: msg = retorno.ListaMensagemRetornoLote.MensagemRetorno self.codigo_retorno = msg.Codigo self.mensagem_retorno = msg.Mensagem self.env['invoice.eletronic.event'].create({ 'code': self.codigo_retorno, 'name': self.mensagem_retorno, 'invoice_eletronic_id': self.id, }) self._create_attachment('nfse-envio', self, enviar_nfse['sent_xml']) self._create_attachment('nfse-ret', self, enviar_nfse['received_xml'])
def test_cancelamento_nfse_ok(self): pfx_source = open(os.path.join(self.caminho, "teste.pfx"), "rb").read() pfx = Certificado(pfx_source, "123456") cancelamento = self._get_cancelamento() path = os.path.join(os.path.dirname(__file__), "XMLs") xml_return = open(os.path.join(path, "paulistana_canc_ok.xml"), "r").read() with mock.patch("pytrustnfe.nfse.paulistana.get_authenticated_client" ) as client: retorno = mock.MagicMock() client.return_value = retorno retorno.service.CancelamentoNFe.return_value = xml_return retorno = cancelamento_nfe(pfx, cancelamento=cancelamento) self.assertEqual(retorno["received_xml"], xml_return) self.assertEqual(retorno["object"].Cabecalho.Sucesso, True)