diff --git a/br_nfe/models/invoice_eletronic.py b/br_nfe/models/invoice_eletronic.py index f7971dbc7..58db763cc 100644 --- a/br_nfe/models/invoice_eletronic.py +++ b/br_nfe/models/invoice_eletronic.py @@ -20,6 +20,7 @@ from pytrustnfe.nfe import xml_autorizar_nfe from pytrustnfe.nfe import retorno_autorizar_nfe from pytrustnfe.nfe import recepcao_evento_cancelamento + from pytrustnfe.nfe import consultar_protocolo_nfe from pytrustnfe.certificado import Certificado from pytrustnfe.utils import ChaveNFe, gerar_chave, gerar_nfeproc from pytrustnfe.nfe.danfe import danfe @@ -888,40 +889,61 @@ def action_cancel_document(self, context=None, justificativa=None): cert_pfx = base64.decodestring(cert) certificado = Certificado(cert_pfx, self.company_id.nfe_a1_password) - id_canc = "ID110111%s%02d" % (self.chave_nfe, self.sequencial_evento) - cancelamento = { - 'idLote': self.id, + consulta = { 'estado': self.company_id.state_id.ibge_code, 'ambiente': 2 if self.ambiente == 'homologacao' else 1, - 'eventos': [{ - 'Id': id_canc, - 'cOrgao': self.company_id.state_id.ibge_code, - 'tpAmb': 2 if self.ambiente == 'homologacao' else 1, - 'CNPJ': re.sub('[^0-9]', '', self.company_id.cnpj_cpf), - 'chNFe': self.chave_nfe, - 'dhEvento': datetime.utcnow().strftime( - '%Y-%m-%dT%H:%M:%S-00:00'), - 'nSeqEvento': self.sequencial_evento, - 'nProt': self.protocolo_nfe, - 'xJust': justificativa - }], - 'modelo': self.model, + 'chave_nfe': self.chave_nfe, } - resp = recepcao_evento_cancelamento(certificado, **cancelamento) - resposta = resp['object'].Body.nfeRecepcaoEventoResult.retEnvEvento - if resposta.cStat == 128 and \ - resposta.retEvento.infEvento.cStat in (135, 136, 155): + + resp = consultar_protocolo_nfe(certificado, **consulta) + + retorno_consulta = \ + resp['object'].Body.nfeConsultaNF2Result.retConsSitNFe + + if retorno_consulta.cStat == 101: self.state = 'cancel' - self.codigo_retorno = resposta.retEvento.infEvento.cStat - self.mensagem_retorno = resposta.retEvento.infEvento.xMotivo + self.codigo_retorno = retorno_consulta.cStat + self.mensagem_retorno = retorno_consulta.xMotivo self.sequencial_evento += 1 + resp['received_xml'] = etree.tostring(retorno_consulta.retCancNFe) + resp['sent_xml'] = etree.tostring(retorno_consulta.procEventoNFe) else: - if resposta.cStat == 128: + id_canc = "ID110111%s%02d" % ( + self.chave_nfe, self.sequencial_evento) + cancelamento = { + 'idLote': self.id, + 'estado': self.company_id.state_id.ibge_code, + 'ambiente': 2 if self.ambiente == 'homologacao' else 1, + 'eventos': [{ + 'Id': id_canc, + 'cOrgao': self.company_id.state_id.ibge_code, + 'tpAmb': 2 if self.ambiente == 'homologacao' else 1, + 'CNPJ': re.sub('[^0-9]', '', self.company_id.cnpj_cpf), + 'chNFe': self.chave_nfe, + 'dhEvento': datetime.utcnow().strftime( + '%Y-%m-%dT%H:%M:%S-00:00'), + 'nSeqEvento': self.sequencial_evento, + 'nProt': self.protocolo_nfe, + 'xJust': justificativa + }], + 'modelo': self.model, + } + resp = recepcao_evento_cancelamento(certificado, **cancelamento) + resposta = resp['object'].Body.nfeRecepcaoEventoResult.retEnvEvento + if resposta.cStat == 128 and \ + resposta.retEvento.infEvento.cStat in (135, 136, 155): + self.state = 'cancel' self.codigo_retorno = resposta.retEvento.infEvento.cStat self.mensagem_retorno = resposta.retEvento.infEvento.xMotivo + self.sequencial_evento += 1 else: - self.codigo_retorno = resposta.cStat - self.mensagem_retorno = resposta.xMotivo + if resposta.cStat == 128: + self.codigo_retorno = resposta.retEvento.infEvento.cStat + self.mensagem_retorno = \ + resposta.retEvento.infEvento.xMotivo + else: + self.codigo_retorno = resposta.cStat + self.mensagem_retorno = resposta.xMotivo self.env['invoice.eletronic.event'].create({ 'code': self.codigo_retorno, diff --git a/br_nfe/tests/test_nfe.py b/br_nfe/tests/test_nfe.py index 5e1b9fe73..127bd4a72 100644 --- a/br_nfe/tests/test_nfe.py +++ b/br_nfe/tests/test_nfe.py @@ -430,7 +430,8 @@ def test_nfe_with_concept_error(self, autorizar, ret_autorizar, validar): @patch('odoo.addons.br_nfe.models.invoice_eletronic.valida_nfe') @patch('odoo.addons.br_nfe.models.invoice_eletronic.recepcao_evento_cancelamento') # noqa - def test_nfe_cancelamento_ok(self, cancelar, validar): + @patch('odoo.addons.br_nfe.models.invoice_eletronic.consultar_protocolo_nfe') # noqa + def test_nfe_cancelamento_ok(self, consulta, cancelar, validar): validar.return_value = '' for invoice in self.invoices: # Confirmando a fatura deve gerar um documento eletrĂ´nico @@ -446,6 +447,17 @@ def test_nfe_cancelamento_ok(self, cancelar, validar): 'received_xml': xml_recebido } + # Consulta realizada + xml_recebido = open(os.path.join( + self.caminho, 'xml/consulta.xml'), 'r').read() + resp_consulta = sanitize_response(xml_recebido) + + consulta.return_value = { + 'object': resp_consulta[1], + 'sent_xml': '', + 'received_xml': xml_recebido + } + invoice_eletronic = self.env['invoice.eletronic'].search( [('invoice_id', '=', invoice.id)]) invoice_eletronic.action_cancel_document( diff --git a/br_nfe/tests/xml/consulta.xml b/br_nfe/tests/xml/consulta.xml new file mode 100644 index 000000000..8bbd1620d --- /dev/null +++ b/br_nfe/tests/xml/consulta.xml @@ -0,0 +1,39 @@ + + + + 53 + 3.10 + + + + + + 2 + SVRS201710241713 + 100 + Autorizado o uso da NF-e + 53 + 2018-03-19T17:02:12-03:00 + 53180301929144000190550010000000111425608529 + + + 2 + SVRS201803141609 + 53180301929144000190550010000000111425608529 + 2018-03-19T15:53:13-03:00 + 353180000120999 + R+4GfYd0MKpxbaLk0hRG30BD5oc= + 100 + Autorizado o uso da NF-e + + + + + + \ No newline at end of file