diff --git a/README.md b/README.md index 9f96d31..e2a6e17 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Dependências: NFSe - Cidades atendidas --------------- +----------------------------- * **Paulistana** - São Paulo/SP * **Nota Carioca** - Rio de Janeiro/RJ * **Imperial** - Petrópolis/RH @@ -39,7 +39,7 @@ Implementar novos provedores de NFSe Exemplos de uso da NFe ---------------- +----------------------------- Consulta Cadastro por CNPJ: @@ -52,7 +52,102 @@ certificado = Certificado(certificado, 'senha_pfx') obj = {'cnpj': '12345678901234', 'estado': '42'} resposta = consulta_cadastro(certificado, obj=obj, ambiente=1, estado='42') ``` +Consulta Distribuição NF-e sem Validação de Esquema: +```python +from pytrustnfe.certificado import Certificado +from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe + +certificado = open("/path/certificado.pfx", "r").read() +certificado = Certificado(certificado, 'senha_pfx') + +# Gerando xml e enviado consulta por Ultimo NSU +response1 = consulta_distribuicao_nfe( + certificado, + ambiente=1, + estado='42', + modelo='55', + cnpj_cpf='12345678901234', + ultimo_nsu='123456789101213' +) + +# Gerando xml e enviado consulta por Chave +response2 = consulta_distribuicao_nfe( + certificado, + ambiente=1, + estado='42', + modelo='55', + cnpj_cpf='12345678901234', + chave_nfe='012345678901234567890123456789012345678912' +) + +# Gerando xml e enviado consulta por NSU +response3 = consulta_distribuicao_nfe( + certificado, + ambiente=1, + estado='42', + modelo='55', + cnpj_cpf='12345678901234', + nsu='123456789101213' +) +``` +Consulta Distribuição NF-e com Validação de Esquema: +```python +from pytrustnfe.certificado import Certificado +from pytrustnfe.nfe import consulta_distribuicao_nfe, xml_consulta_distribuicao_nfe +from pytrustnfe.xml.validate import valida_nfe, SCHEMA_DFE + +certificado = open("/path/certificado.pfx", "r").read() +certificado = Certificado(certificado, 'senha_pfx') + +# Gerando XML para Consulta por Ultimo NSU +xml1 = xml_consulta_distribuicao_nfe( + certificado, + ambiente=1, + estado='42', + cnpj_cpf='12345678901234', + ultimo_nsu='123456789101213' +) + +# Validando o XML com Esquema +if valida_nfe(xml1, SCHEMA_DFE): + Warning("Erro na validação do esquema") + +# Gerando XML para Consulta por Chave +xml2 = xml_consulta_distribuicao_nfe( + certificado, + ambiente=1, + estado='42', + cnpj_cpf='12345678901234', + chave_nfe='012345678901234567890123456789012345678912' +) + +# Validando o XML com Esquema +if valida_nfe(xml2, SCHEMA_DFE): + Warning("Erro na validação do esquema") + +# Gerando XML para Consulta por NSU +xml3 = xml_consulta_distribuicao_nfe( + certificado, + ambiente=1, + estado='42', + cnpj_cpf='12345678901234', + nsu='123456789101213' +) + +# Validando o XML com Esquema +if valida_nfe(xml3, SCHEMA_DFE): + Warning("Erro na validação do esquema") + +# Enviando xml de consulta para sefaz +response = consulta_distribuicao_nfe( + certificado, + ambiente=1, + estado='42', + modelo='55', + xml=xml1 +) +``` Exemplo de uso da NFSe Paulistana --------------------------------- diff --git a/pytrustnfe/Servidores.py b/pytrustnfe/Servidores.py index 273d28b..3442910 100644 --- a/pytrustnfe/Servidores.py +++ b/pytrustnfe/Servidores.py @@ -132,7 +132,7 @@ SVRS = { WS_NFE_RECEPCAO_EVENTO: 'ws/recepcaoevento/recepcaoevento4.asmx?wsdl', # noqa WS_NFE_AUTORIZACAO: 'ws/NfeAutorizacao/NFeAutorizacao4.asmx?wsdl', WS_NFE_RET_AUTORIZACAO: 'ws/NfeRetAutorizacao/NFeRetAutorizacao4.asmx?wsdl', # noqa - WS_NFE_CADASTRO: 'ws/cadconsultacadastro/cadconsultacadastro2.asmx?wsdl', # noqa + WS_NFE_CADASTRO: 'ws/cadconsultacadastro/cadconsultacadastro4.asmx?wsdl', # noqa }, AMBIENTE_HOMOLOGACAO: { 'servidor': 'nfe-homologacao.svrs.rs.gov.br', @@ -142,7 +142,7 @@ SVRS = { WS_NFE_RECEPCAO_EVENTO: 'ws/recepcaoevento/recepcaoevento4.asmx?wsdl', # noqa WS_NFE_AUTORIZACAO: 'ws/NfeAutorizacao/NFeAutorizacao4.asmx?wsdl', WS_NFE_RET_AUTORIZACAO: 'ws/NfeRetAutorizacao/NFeRetAutorizacao4.asmx?wsdl', # noqa - WS_NFE_CADASTRO: 'ws/cadconsultacadastro/cadconsultacadastro2.asmx?wsdl', # noqa + WS_NFE_CADASTRO: 'ws/cadconsultacadastro/cadconsultacadastro4.asmx?wsdl', # noqa } }, NFCE_MODELO: { @@ -268,23 +268,22 @@ UFAM = { }, NFCE_MODELO: { AMBIENTE_PRODUCAO: { - 'servidor': 'nfe.sefaz.am.gov.br', - WS_NFE_RECEPCAO_EVENTO: 'services2/services/RecepcaoEvento', - WS_NFE_AUTORIZACAO: 'services2/services/NfeAutorizacao', - WS_NFE_RET_AUTORIZACAO: 'services2/services/NfeRetAutorizacao', - WS_NFE_INUTILIZACAO: 'services2/services/NfeInutilizacao2', - WS_NFE_CONSULTA: 'services2/services/NfeConsulta2', - WS_NFE_SITUACAO: 'services2/services/NfeStatusServico2', - WS_NFE_CADASTRO: 'services2/services/cadconsultacadastro2', + 'servidor': 'nfce.sefaz.am.gov.br', + WS_NFE_RECEPCAO_EVENTO: 'nfce-services/services/RecepcaoEvento4?wsdl', + WS_NFE_AUTORIZACAO: 'nfce-services/services/NfeAutorizacao4?wsdl', + WS_NFE_RET_AUTORIZACAO: 'nfce-services/services/NfeRetAutorizacao4?wsdl', + WS_NFE_INUTILIZACAO: 'nfce-services/services/NfeInutilizacao4?wsdl', + WS_NFE_CONSULTA: 'nfce-services/services/NfeConsulta4?wsdl', + WS_NFE_SITUACAO: 'nfce-services/services/NfeStatusServico4?wsdl', }, AMBIENTE_HOMOLOGACAO: { 'servidor': 'homnfce.sefaz.am.gov.br', - WS_NFE_RECEPCAO_EVENTO: 'nfce-services-nac/services/RecepcaoEvento', - WS_NFE_AUTORIZACAO: 'nfce-services-nac/services/NfeAutorizacao', - WS_NFE_RET_AUTORIZACAO: 'nfce-services-nac/services/NfeRetAutorizacao', - WS_NFE_INUTILIZACAO: 'nfce-services-nac/services/NfeInutilizacao2', - WS_NFE_CONSULTA: 'nfce-services-nac/services/NfeConsulta2', - WS_NFE_SITUACAO: 'nfce-services-nac/services/NfeStatusServico2', + WS_NFE_RECEPCAO_EVENTO: 'nfce-services/services/RecepcaoEvento4?wsdl', + WS_NFE_AUTORIZACAO: 'nfce-services/services/NfeAutorizacao4?wsdl', + WS_NFE_RET_AUTORIZACAO: 'nfce-services/services/NfeRetAutorizacao4?wsdl', + WS_NFE_INUTILIZACAO: 'nfce-services/services/NfeInutilizacao4?wsdl', + WS_NFE_CONSULTA: 'nfce-services/services/NfeConsulta4?wsdl', + WS_NFE_SITUACAO: 'nfce-services/services/NfeStatusServico4?wsdl', WS_NFCE_QR_CODE: 'http://homnfce.sefaz.am.gov.br/nfceweb/consultarNFCe.jsp', } } @@ -482,27 +481,51 @@ UFMS = { } UFMG = { - AMBIENTE_PRODUCAO: { - 'servidor': 'nfe.fazenda.mg.gov.br', - WS_NFE_INUTILIZACAO: 'nfe2/services/NFeInutilizacao4?wsdl', - WS_NFE_CONSULTA: 'nfe2/services/NFeConsultaProtocolo4?wsdl', - WS_NFE_SITUACAO: 'nfe2/services/NFeStatusServico4?wsdl', - WS_NFE_RECEPCAO_EVENTO: 'nfe2/services/NFeRecepcaoEvento4?wsdl', - WS_NFE_AUTORIZACAO: 'nfe2/services/NFeAutorizacao4?wsdl', - WS_NFE_RET_AUTORIZACAO: 'nfe2/services/NFeRetAutorizacao4?wsdl', - WS_NFE_CADASTRO: 'nfe2/services/cadconsultacadastro2?wsdl', + NFE_MODELO: { + AMBIENTE_PRODUCAO: { + 'servidor': 'nfe.fazenda.mg.gov.br', + WS_NFE_INUTILIZACAO: 'nfe2/services/NFeInutilizacao4?wsdl', + WS_NFE_CONSULTA: 'nfe2/services/NFeConsultaProtocolo4?wsdl', + WS_NFE_SITUACAO: 'nfe2/services/NFeStatusServico4?wsdl', + WS_NFE_RECEPCAO_EVENTO: 'nfe2/services/NFeRecepcaoEvento4?wsdl', + WS_NFE_AUTORIZACAO: 'nfe2/services/NFeAutorizacao4?wsdl', + WS_NFE_RET_AUTORIZACAO: 'nfe2/services/NFeRetAutorizacao4?wsdl', + WS_NFE_CADASTRO: 'nfe2/services/CadConsultaCadastro4?wsdl', + }, + AMBIENTE_HOMOLOGACAO: { + 'servidor': 'hnfe.fazenda.mg.gov.br', + WS_NFE_INUTILIZACAO: 'nfe2/services/NFeInutilizacao4?wsdl', + WS_NFE_CONSULTA: 'nfe2/services/NFeConsultaProtocolo4?wsdl', + WS_NFE_SITUACAO: 'nfe2/services/NFeStatusServico4?wsdl', + WS_NFE_RECEPCAO_EVENTO: 'nfe2/services/NFeRecepcaoEvento4?wsdl', + WS_NFE_AUTORIZACAO: 'nfe2/services/NFeAutorizacao4?wsdl', + WS_NFE_RET_AUTORIZACAO: 'nfe2/services/NFeRetAutorizacao4?wsdl', + WS_NFE_CADASTRO: 'nfe2/services/CadConsultaCadastro4?wsdl', + }, + }, + NFCE_MODELO: { + AMBIENTE_PRODUCAO: { + 'servidor': 'nfce.fazenda.mg.gov.br', + WS_NFE_INUTILIZACAO: 'nfce/services/NFeInutilizacao4?wsdl', + WS_NFE_CONSULTA: 'nfce/services/NFeConsultaProtocolo4?wsdl', + WS_NFE_SITUACAO: 'nfce/services/NFeStatusServico4?wsdl', + WS_NFE_RECEPCAO_EVENTO: 'nfce/services/NFeRecepcaoEvento4?wsdl', + WS_NFE_AUTORIZACAO: 'nfce/services/NFeAutorizacao4?wsdl', + WS_NFE_RET_AUTORIZACAO: 'nfce/services/NFeRetAutorizacao4?wsdl', + WS_NFCE_QR_CODE: 'nfce.fazenda.mg.gov.br/portalnfce/sistema/qrcode.xhtml?' + }, + AMBIENTE_HOMOLOGACAO: { + 'servidor': 'hnfce.fazenda.mg.gov.br', + WS_NFE_INUTILIZACAO: 'nfce/services/NFeInutilizacao4?wsdl', + WS_NFE_CONSULTA: 'nfce/services/NFeConsultaProtocolo4?wsdl', + WS_NFE_SITUACAO: 'nfce/services/NFeStatusServico4?wsdl', + WS_NFE_RECEPCAO_EVENTO: 'nfce/services/NFeRecepcaoEvento4?wsdl', + WS_NFE_AUTORIZACAO: 'nfce/services/NFeAutorizacao4?wsdl', + WS_NFE_RET_AUTORIZACAO: 'nfce/services/NFeRetAutorizacao4?wsdl', + WS_NFCE_QR_CODE: 'nfce.fazenda.mg.gov.br/portalnfce/sistema/qrcode.xhtml?' + }, }, - AMBIENTE_HOMOLOGACAO: { - 'servidor': 'hnfe.fazenda.mg.gov.br', - WS_NFE_INUTILIZACAO: 'nfe2/services/NFeInutilizacao4?wsdl', - WS_NFE_CONSULTA: 'nfe2/services/NFeConsultaProtocolo4?wsdl', - WS_NFE_SITUACAO: 'nfe2/services/NFeStatusServico4?wsdl', - WS_NFE_RECEPCAO_EVENTO: 'nfe2/services/NFeRecepcaoEvento4?wsdl', - WS_NFE_AUTORIZACAO: 'nfe2/services/NFeAutorizacao4?wsdl', - WS_NFE_RET_AUTORIZACAO: 'nfe2/services/NFeRetAutorizacao4?wsdl', - WS_NFE_CADASTRO: 'nfe2/services/cadconsultacadastro2?wsdl', - } } UFPR = { @@ -653,24 +676,24 @@ UFSP = { NFCE_MODELO: { AMBIENTE_PRODUCAO: { 'servidor': 'nfce.fazenda.sp.gov.br', - WS_NFE_AUTORIZACAO: 'ws/nfeautorizacao.asmx', - WS_NFE_RET_AUTORIZACAO: 'ws/nferetautorizacao.asmx', - WS_NFE_INUTILIZACAO: 'ws/nfeinutilizacao2.asmx', - WS_NFE_CONSULTA: 'ws/nfeconsulta2.asmx', - WS_NFE_SITUACAO: 'ws/nfestatusservico2.asmx', + WS_NFE_AUTORIZACAO: 'ws/NFeAutorizacao4.asmx?wsdl', + WS_NFE_RET_AUTORIZACAO: 'ws/NFeRetAutorizacao4.asmx?wsdl', + WS_NFE_INUTILIZACAO: 'ws/NFeInutilizacao4.asmx?wsdl', + WS_NFE_CONSULTA: 'ws/NFeConsultaProtocolo4.asmx?wsdl', + WS_NFE_SITUACAO: 'ws/NFeStatusServico4.asmx?wsdl', WS_NFE_CADASTRO: 'ws/cadconsultacadastro2.asmx', - WS_NFE_RECEPCAO_EVENTO: 'ws/recepcaoevento.asmx', + WS_NFE_RECEPCAO_EVENTO: 'ws/NFeRecepcaoEvento4.asmx?wsdl', WS_NFCE_QR_CODE: '', }, AMBIENTE_HOMOLOGACAO: { 'servidor': 'homologacao.nfce.fazenda.sp.gov.br', - WS_NFE_AUTORIZACAO: 'ws/nfeautorizacao.asmx', - WS_NFE_RET_AUTORIZACAO: 'ws/nferetautorizacao.asmx', - WS_NFE_INUTILIZACAO: 'ws/nfeinutilizacao2.asmx', - WS_NFE_CONSULTA: 'ws/nfeconsulta2.asmx', - WS_NFE_SITUACAO: 'ws/nfestatusservico2.asmx', + WS_NFE_AUTORIZACAO: 'ws/NFeAutorizacao4.asmx?wsdl', + WS_NFE_RET_AUTORIZACAO: 'ws/NFeRetAutorizacao4.asmx?wsdl', + WS_NFE_INUTILIZACAO: 'ws/NFeInutilizacao4.asmx?wsdl', + WS_NFE_CONSULTA: 'ws/NFeConsultaProtocolo4.asmx?wsdl', + WS_NFE_SITUACAO: 'ws/NFeStatusServico4.asmx?wsdl', WS_NFE_CADASTRO: 'ws/cadconsultacadastro2.asmx', - WS_NFE_RECEPCAO_EVENTO: 'ws/recepcaoevento.asmx', + WS_NFE_RECEPCAO_EVENTO: 'ws/NFeRecepcaoEvento4.asmx?wsdl', WS_NFCE_QR_CODE: 'https://homologacao.nfce.fazenda.sp.gov.br/NFCEConsultaPublica/Paginas/ConstultaQRCode.aspx', } } diff --git a/pytrustnfe/nfe/__init__.py b/pytrustnfe/nfe/__init__.py index 8395f24..1a5b9c0 100644 --- a/pytrustnfe/nfe/__init__.py +++ b/pytrustnfe/nfe/__init__.py @@ -214,6 +214,22 @@ def xml_consulta_distribuicao_nfe(certificado, **kwargs): # Assinar return _render(certificado, 'NFeDistribuicaoDFe', False, **kwargs) +def consulta_distribuicao_nfe(certificado, **kwargs): + if "xml" not in kwargs: + kwargs['xml'] = xml_consulta_distribuicao_nfe(certificado, **kwargs) + return _send_v310(certificado, **kwargs) + + +def xml_download_nfe(certificado, **kwargs): # Assinar + return _render(certificado, 'NFeDistribuicaoDFe', False, **kwargs) + + +def download_nfe(certificado, **kwargs): + if "xml" not in kwargs: + kwargs['xml'] = xml_download_nfe(certificado, **kwargs) + return _send_v310(certificado, **kwargs) + + def _send_v310(certificado, **kwargs): xml_send = kwargs["xml"] base_url = localizar_url( @@ -243,19 +259,3 @@ def _send_v310(certificado, **kwargs): 'received_xml': response, 'object': obj.Body.nfeDistDFeInteresseResponse.nfeDistDFeInteresseResult } - - -def consulta_distribuicao_nfe(certificado, **kwargs): - if "xml" not in kwargs: - kwargs['xml'] = xml_consulta_distribuicao_nfe(certificado, **kwargs) - return _send_v310(certificado, **kwargs) - - -def xml_download_nfe(certificado, **kwargs): # Assinar - return _render(certificado, 'NFeDistribuicaoDFe', False, **kwargs) - - -def download_nfe(certificado, **kwargs): - if "xml" not in kwargs: - kwargs['xml'] = xml_download_nfe(certificado, **kwargs) - return _send_v310(certificado, **kwargs) diff --git a/pytrustnfe/nfe/danfce.py b/pytrustnfe/nfe/danfce.py index 7773798..9e64c24 100644 --- a/pytrustnfe/nfe/danfce.py +++ b/pytrustnfe/nfe/danfce.py @@ -122,16 +122,24 @@ class danfce(object): self._drawCenteredParagraph(cEnd) self.drawLine() - def danfce_information(self): - self.drawTitle( - "DANFE NFC-e - Documento Auxiliar da Nota Fiscal de", - 7, 'NimbusSanL-Bold') + def danfce_information(self, oXML=None): + el_ide = oXML.find(".//{http://www.portalfiscal.inf.br/nfe}ide") + tipo_emissao = tagtext(oNode=el_ide, cTag='tpEmis') + if tipo_emissao in ('5', '9'): + self.current_height -= 5 + self.drawTitle("EMITIDA EM CONTINGÊNCIA",9, 'NimbusSanL-Bold') + self.drawTitle("Pendente de autorização", 7, 'NimbusSanL-Bold') + self.drawLine() + else: + self.drawTitle( + "DANFE NFC-e - Documento Auxiliar da Nota Fiscal de", + 7, 'NimbusSanL-Bold') - self.drawTitle("Consumidor Eletrônica", 7, 'NimbusSanL-Bold') + self.drawTitle("Consumidor Eletrônica", 7, 'NimbusSanL-Bold') - self.drawString( - "NFC-e não permite aproveitamento de crédito de ICMS", True) - self.drawLine() + self.drawString( + "NFC-e não permite aproveitamento de crédito de ICMS", True) + self.drawLine() def produtos(self, oXML=None, el_det=None, oPaginator=None, list_desc=None, list_cod_prod=None): @@ -309,18 +317,26 @@ class danfce(object): dataSolicitacao = getdateUTC(tagtext(oNode=el_ide, cTag="dhEmi")) dataSolicitacao = dataSolicitacao[0] + " " + dataSolicitacao[1] - numProtocolo = tagtext(oNode=el_prot_nfe, cTag="nProt") + text = u"%s
%s
NFC-e nº%s Série %s %s
" % ( + frase_chave_acesso, cnpj_cpf, nNFC, serie, dataSolicitacao) - dataAutorizacao = getdateUTC(tagtext(oNode=el_prot_nfe, - cTag='dhRecbto')) - dataAutorizacao = dataAutorizacao[0] + " " + dataAutorizacao[1] + self._drawCenteredParagraph(text) + + tipo_emissao = tagtext(oNode=el_ide, cTag='tpEmis') + if tipo_emissao in ('5', '9'): + self.current_height -= 8 + self.drawTitle("EMITIDA EM CONTINGÊNCIA",9, 'NimbusSanL-Bold') + self.drawTitle("Pendente de autorização - Via Consumidor", 7, 'NimbusSanL-Bold') + else: + numProtocolo = tagtext(oNode=el_prot_nfe, cTag="nProt") - text = u"%s
%s
NFC-e nº%s Série %s %s
\ -Protocolo de autorização: %s
Data de autorização %s
\ -" % (frase_chave_acesso, cnpj_cpf, nNFC, serie, dataSolicitacao, - numProtocolo, dataAutorizacao) + dataAutorizacao = getdateUTC(tagtext(oNode=el_prot_nfe, + cTag='dhRecbto')) + dataAutorizacao = dataAutorizacao[0] + " " + dataAutorizacao[1] - self._drawCenteredParagraph(text) + text = "Protocolo de autorização: %s
Data de autorização %s
" % ( + numProtocolo, dataAutorizacao) + self._drawCenteredParagraph(text) self.draw_qr_code(qrcode) @@ -428,7 +444,7 @@ Protocolo de autorização: %s
Data de autorização %s
\ self.ide_emit(oXML=oXML) # self.destinatario(oXML=oXML) - self.danfce_information() + self.danfce_information(oXML=oXML) self.produtos(oXML=oXML, el_det=el_det, oPaginator=oPaginator[0], list_desc=list_desc, list_cod_prod=list_cod_prod) diff --git a/pytrustnfe/nfe/danfe.py b/pytrustnfe/nfe/danfe.py index 6bdaf1a..19287d9 100644 --- a/pytrustnfe/nfe/danfe.py +++ b/pytrustnfe/nfe/danfe.py @@ -170,9 +170,9 @@ class danfe(object): infAdProd = item.find( ".//{http://www.portalfiscal.inf.br/nfe}infAdProd") - list_ = wrap(tagtext(oNode=el_prod, cTag='xProd'), 56) + list_ = wrap(tagtext(oNode=el_prod, cTag='xProd'), 50) if infAdProd is not None: - list_.extend(wrap(infAdProd.text, 56)) + list_.extend(wrap(infAdProd.text, 50)) list_desc.append(list_) list_cProd = wrap(tagtext(oNode=el_prod, cTag='cProd'), 14) @@ -202,7 +202,9 @@ class danfe(object): self.adicionais(oXML=oXML, tamanho_diminuir=tamanho_ocupado) # Gera o restante das páginas do XML - while index <= nId: + while index < nId: + if index < 0: + index = index * -1 self.newpage() self.ide_emit(oXML=oXML, timezone=timezone) index = self.produtos( @@ -357,7 +359,7 @@ class danfe(object): self.canvas.restoreState() # Cancelado - if tagtext(oNode=elem_evento, cTag='cStat') == '135': + if tagtext(oNode=elem_evento, cTag='cStat') in ('135', '155'): self.canvas.saveState() self.canvas.rotate(45) self.canvas.setFont('NimbusSanL-Bold', 60) @@ -725,6 +727,7 @@ obsCont[@xCampo='NomeVendedor']") line_height = max(len(list_cod_prod[id]), len(list_desc[id])) line_height *= nStep if nLin + line_height > maxHeight: + id = id * -1 break item = el_det[id] @@ -759,9 +762,9 @@ obsCont[@xCampo='NomeVendedor']") tagtext(oNode=el_prod, cTag='vUnCom'))) self.stringRight(nMr - 50.5, nLin, format_number( tagtext(oNode=el_prod, cTag='vProd'))) - self.stringRight(nMr - 38.5, nLin, format_number(vBC)) - self.stringRight(nMr - 26.5, nLin, format_number(vICMS)) - self.stringRight(nMr - 7.5, nLin, format_number(pICMS)) + self.stringRight(nMr - 38.5, nLin, format_number(vBC or '0.00')) + self.stringRight(nMr - 26.5, nLin, format_number(vICMS or '0.00')) + self.stringRight(nMr - 7.5, nLin, format_number(pICMS or '0.00')) self.stringRight(nMr - 14.5, nLin, format_number(vIPI or '0.00')) self.stringRight(nMr - 0.5, nLin, format_number(pIPI or '0.00')) @@ -784,8 +787,6 @@ obsCont[@xCampo='NomeVendedor']") self.canvas.setStrokeColor(black) self.nlin += nH + 3 - if (index == max_index): - id += 1 return id def calculo_issqn(self, oXML=None): diff --git a/pytrustnfe/nfe/templates/NFeDistribuicaoDFe.xml b/pytrustnfe/nfe/templates/NFeDistribuicaoDFe.xml index cd3fc38..9762e86 100644 --- a/pytrustnfe/nfe/templates/NFeDistribuicaoDFe.xml +++ b/pytrustnfe/nfe/templates/NFeDistribuicaoDFe.xml @@ -8,4 +8,7 @@ {{ chave_nfe }} + + {{ nsu }} + diff --git a/pytrustnfe/nfe/templates/NfeAutorizacao.xml b/pytrustnfe/nfe/templates/NfeAutorizacao.xml index 15e6dbb..33ccd86 100644 --- a/pytrustnfe/nfe/templates/NfeAutorizacao.xml +++ b/pytrustnfe/nfe/templates/NfeAutorizacao.xml @@ -27,7 +27,7 @@ {{ ide.indFinal }} {{ ide.indPres }} {{ ide.procEmi }} - Odoo Brasil 10 + {{ ide.verProc }} {% if ide.NFref is defined -%} {% for ref in ide.NFref %} @@ -143,6 +143,7 @@ {{ NFe.infNFe.retirada.CNPJ }} {{ NFe.infNFe.retirada.CPF }} + {{ NFe.infNFe.retirada.xNome|normalize|escape }} {{ NFe.infNFe.retirada.xLgr|normalize|escape }} {{ NFe.infNFe.retirada.nro }} {{ NFe.infNFe.retirada.xCpl|normalize|escape }} @@ -150,12 +151,19 @@ {{ NFe.infNFe.retirada.cMun }} {{ NFe.infNFe.retirada.xMun|normalize }} {{ NFe.infNFe.retirada.UF }} + {{ NFe.infNFe.retirada.CEP }} + {{ NFe.infNFe.retirada.cPais }} + {{ NFe.infNFe.retirada.xPais|normalize|escape }} + {{ NFe.infNFe.retirada.fone }} + {{ NFe.infNFe.retirada.email }} + {{ NFe.infNFe.retirada.IE }} {% endif %} {% if NFe.infNFe.entrega is defined %} {{ NFe.infNFe.entrega.CNPJ }} {{ NFe.infNFe.entrega.CPF }} + {{ NFe.infNFe.entrega.xNome|normalize|escape }} {{ NFe.infNFe.entrega.xLgr|normalize|escape }} {{ NFe.infNFe.entrega.nro }} {{ NFe.infNFe.entrega.xCpl|normalize|escape }} @@ -163,6 +171,12 @@ {{ NFe.infNFe.entrega.cMun }} {{ NFe.infNFe.entrega.xMun }} {{ NFe.infNFe.entrega.UF }} + {{ NFe.infNFe.entrega.CEP }} + {{ NFe.infNFe.entrega.cPais }} + {{ NFe.infNFe.entrega.xPais|normalize|escape }} + {{ NFe.infNFe.entrega.fone }} + {{ NFe.infNFe.entrega.email }} + {{ NFe.infNFe.entrega.IE }} {% endif %} {% if NFe.infNFe.autXML %} @@ -260,6 +274,7 @@ {% for med in prod.med %} {{ med.cProdANVISA }} + {{ med.xMotivoIsencao }} {{ med.vPMC }} {% endfor %} @@ -368,6 +383,7 @@ {{ imposto.ICMS.CST }} {{ imposto.ICMS.vBCSTRet }} {{ imposto.ICMS.pST }} + {{ imposto.ICMS.vICMSSubstituto }} {{ imposto.ICMS.vICMSSTRet }} {{ imposto.ICMS.vBCFCPSTRet }} {{ imposto.ICMS.pFCPSTRet }} @@ -446,9 +462,18 @@ {{ imposto.ICMSST.orig }} {{ imposto.ICMSST.CST }} {{ imposto.ICMSST.vBCSTRet }} + {{ imposto.ICMSST.pST }} + {{ imposto.ICMSST.vICMSSubstituto }} {{ imposto.ICMSST.vICMSSTRet }} + {{ imposto.ICMSST.vBCFCPSTRet }} + {{ imposto.ICMSST.pFCPSTRet }} + {{ imposto.ICMSST.vFCPSTRet }} {{ imposto.ICMSST.vBCSTDest }} {{ imposto.ICMSST.vICMSSTDest }} + {{ imposto.ICMSST.pRedBCEfet }} + {{ imposto.ICMSST.vBCEfet }} + {{ imposto.ICMSST.pICMSEfet }} + {{ imposto.ICMSST.vICMSEfet }} {% endif %} {% if imposto.ICMS.CST == '101' -%} @@ -503,6 +528,7 @@ {{ imposto.ICMS.CST }} {{ imposto.ICMS.vBCSTRet }} {{ imposto.ICMS.pST }} + {{ imposto.ICMS.vICMSSubstituto }} {{ imposto.ICMS.vICMSSTRet }} {{ imposto.ICMS.vBCFCPSTRet }} {{ imposto.ICMS.pFCPSTRet }} @@ -576,7 +602,7 @@ {{ imposto.ISSQN.vOutro }} {{ imposto.ISSQN.vDescIncond }} {{ imposto.ISSQN.vDescCond }} - {{ imposto.ISSQN.vDeducao }} + {{ imposto.ISSQN.vISSRet }} {{ imposto.ISSQN.indISS }} {{ imposto.ISSQN.cServico }} {{ imposto.ISSQN.cMun }} @@ -859,6 +885,16 @@ {% endfor %} {% endif %} + {% if NFe.infNFe.infRespTec is defined %} + + {{ NFe.infNFe.infRespTec.CNPJ }} + {{ NFe.infNFe.infRespTec.xContato }} + {{ NFe.infNFe.infRespTec.email }} + {{ NFe.infNFe.infRespTec.fone }} + {{ NFe.infNFe.infRespTec.idCSRT }} + {{ NFe.infNFe.infRespTec.hashCSRT }} + + {% endif %} {% if NFe.infNFe.exporta is defined %} {{ NFe.infNFe.exporta.UFSaidaPais }} diff --git a/pytrustnfe/nfse/aparecida/__init__.py b/pytrustnfe/nfse/aparecida/__init__.py new file mode 100644 index 0000000..9e063ec --- /dev/null +++ b/pytrustnfe/nfse/aparecida/__init__.py @@ -0,0 +1,81 @@ +# © 2019 Danimar Ribeiro, Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import os +from requests import Session +from zeep import Client +from zeep.transports import Transport +from requests.packages.urllib3 import disable_warnings + +from pytrustnfe.xml import render_xml, sanitize_response +from pytrustnfe.certificado import extract_cert_and_key_from_pfx, save_cert_key +from pytrustnfe.nfe.assinatura import Assinatura + + +def _render(certificado, method, **kwargs): + path = os.path.join(os.path.dirname(__file__), 'templates') + xml_send = render_xml(path, '%s.xml' % method, True, **kwargs) + + reference = '' + signer = Assinatura(certificado.pfx, certificado.password) + xml_send = signer.assina_xml(xml_send, reference) + return xml_send + + +def _send(certificado, method, **kwargs): + base_url = '' + if kwargs['ambiente'] == 'producao': + base_url = 'https://aparecida.siltecnologia.com.br/tbw/services/Abrasf10?wsdl' + else: + base_url = 'https://aparecida.siltecnologia.com.br/tbwhomologacao/services/Abrasf10?wsdl' + + cert, key = extract_cert_and_key_from_pfx( + certificado.pfx, certificado.password) + cert, key = save_cert_key(cert, key) + + disable_warnings() + session = Session() + session.cert = (cert, key) + session.verify = False + transport = Transport(session=session) + + client = Client(base_url, transport=transport) + + xml_send = kwargs['xml'] + response = client.service[method](xml_send) + response, obj = sanitize_response(response) + return { + 'sent_xml': xml_send, + 'received_xml': response, + 'object': obj + } + + +def xml_recepcionar_lote_rps(certificado, **kwargs): + return _render(certificado, 'recepcionarLoteRps', **kwargs) + + +def recepcionar_lote_rps(certificado, **kwargs): + if "xml" not in kwargs: + kwargs['xml'] = xml_recepcionar_lote_rps(certificado, **kwargs) + return _send(certificado, 'recepcionarLoteRps', **kwargs) + + +def xml_consultar_lote_rps(certificado, **kwargs): + return _render(certificado, 'consultarLoteRps', **kwargs) + + +def consultar_lote_rps(certificado, **kwargs): + if "xml" not in kwargs: + kwargs['xml'] = xml_consultar_lote_rps(certificado, **kwargs) + return _send(certificado, 'consultarLoteRps', **kwargs) + + +def xml_cancelar_nfse(certificado, **kwargs): + return _render(certificado, 'cancelarNfse', **kwargs) + + +def cancelar_nfse(certificado, **kwargs): + if "xml" not in kwargs: + kwargs['xml'] = xml_cancelar_nfse(certificado, **kwargs) + return _send(certificado, 'cancelarNfse', **kwargs) diff --git a/pytrustnfe/nfse/aparecida/templates/Rps.xml b/pytrustnfe/nfse/aparecida/templates/Rps.xml new file mode 100644 index 0000000..d366389 --- /dev/null +++ b/pytrustnfe/nfse/aparecida/templates/Rps.xml @@ -0,0 +1,91 @@ + + + + {{ rps.numero }} + {{ rps.serie }} + {{ rps.tipo_rps }} + + {{ rps.data_emissao }} + {{ rps.natureza_operacao }} + {{ rps.regime_tributacao }} + {{ rps.optante_simples }} + {{ rps.incentivador_cultural }} + {{ rps.status }} + + {{ rps.numero_substituido }} + {{ rps.serie_substituido }} + {{ rps.tipo_substituido }} + + + + {{ rps.valor_servico }} + {{ rps.valor_deducao }} + {{ rps.valor_pis }} + {{ rps.valor_cofins }} + {{ rps.valor_inss }} + {{ rps.valor_ir }} + {{ rps.valor_csll }} + {{ rps.iss_retido }} + {{ rps.valor_iss }} + {{ rps.valor_iss_retido }} + {{ rps.outras_retencoes }} + {{ rps.base_calculo }} + {{ rps.aliquota_issqn }} + {{ rps.valor_liquido_nfse }} + {{ rps.desconto_incondicionado }} + {{ rps.desconto_condicionado }} + + {{ rps.codigo_servico }} + {{ rps.cnae_servico }} + {{ rps.codigo_tributacao_municipio }} + {{ rps.descricao }} + {{ rps.codigo_municipio }} + + + {{ rps.prestador.cnpj }} + {{ rps.prestador.inscricao_municipal }} + + + + + {% if rps.tomador.cnpj_cpf|length == 14 %} + {{ rps.tomador.cnpj_cpf }} + {% endif %} + {% if rps.tomador.cnpj_cpf|length == 11 %} + {{ rps.tomador.cnpj_cpf }} + {% endif %} + + {{ rps.tomador.inscricao_municipal }} + + {{ rps.tomador.razao_social }} + + {{ rps.tomador.logradouro }} + {{ rps.tomador.numero }} + {{ rps.tomador.complemento }} + {{ rps.tomador.bairro }} + {{ rps.tomador.cidade }} + {{ rps.tomador.uf }} + {{ rps.tomador.cep }} + + + {{ rps.tomador.telefone }} + {{ rps.tomador.email }} + + + {% if rps.intermediario is defined -%} + + {{ rps.intermediario.razao_social }} + + {{ rps.intermediario.cnpj }} + + {{ rps.intermediario.inscricao_municipal }} + + {% endif %} + {% if rps.construcao_civil is defined -%} + + {{ rps.construcao_civil.codigo_obra }} + {{ rps.construcao_civil.art }} + + {% endif %} + + diff --git a/pytrustnfe/nfse/aparecida/templates/cancelarNfse.xml b/pytrustnfe/nfse/aparecida/templates/cancelarNfse.xml new file mode 100644 index 0000000..f5ec25b --- /dev/null +++ b/pytrustnfe/nfse/aparecida/templates/cancelarNfse.xml @@ -0,0 +1,15 @@ + + + + + {{ cancelamento.numero_nfse }} + + {{ cancelamento.cnpj_prestador }} + + {{ cancelamento.inscricao_municipal }} + {{ cancelamento.cidade }} + + {{ cancelamento.codigo_cancelamento }} + + + diff --git a/pytrustnfe/nfse/aparecida/templates/consultarLoteRps.xml b/pytrustnfe/nfse/aparecida/templates/consultarLoteRps.xml new file mode 100644 index 0000000..7e4df96 --- /dev/null +++ b/pytrustnfe/nfse/aparecida/templates/consultarLoteRps.xml @@ -0,0 +1,7 @@ + + + {{ consulta.cnpj_prestador }} + {{ consulta.inscricao_municipal }} + + {{ consulta.protocolo }} + diff --git a/pytrustnfe/nfse/aparecida/templates/recepcionarLoteRps.xml b/pytrustnfe/nfse/aparecida/templates/recepcionarLoteRps.xml new file mode 100644 index 0000000..78dcaff --- /dev/null +++ b/pytrustnfe/nfse/aparecida/templates/recepcionarLoteRps.xml @@ -0,0 +1,13 @@ + + + {{ nfse.numero_lote }} + {{ nfse.cnpj_prestador }} + {{ nfse.inscricao_municipal }} + {{ nfse.lista_rps|length }} + + {% for rps in nfse.lista_rps -%} + {% include 'Rps.xml' %} + {% endfor %} + + + diff --git a/pytrustnfe/nfse/imperial/__init__.py b/pytrustnfe/nfse/imperial/__init__.py index 5795629..fba9f90 100644 --- a/pytrustnfe/nfse/imperial/__init__.py +++ b/pytrustnfe/nfse/imperial/__init__.py @@ -3,8 +3,11 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import os +import requests from lxml import etree -from pytrustnfe import HttpClient +from requests import Session +from zeep import Client +from zeep.transports import Transport from pytrustnfe.xml import render_xml, sanitize_response @@ -17,58 +20,41 @@ def _render(certificado, method, **kwargs): def _send(certificado, method, **kwargs): base_url = '' if kwargs['ambiente'] == 'producao': - base_url = 'https://nfe.etransparencia.com.br/rj.petropolis/webservice/aws_nfe.aspx' # noqa + base_url = 'https://petropolis.sigiss.com.br/petropolis/ws/sigiss_ws.php' # noqa else: - base_url = 'https://nfehomologacao.etransparencia.com.br/rj.petropolis/webservice/aws_nfe.aspx' # noqa - xml_send = kwargs["xml"] - path = os.path.join(os.path.dirname(__file__), 'templates') - soap = render_xml(path, 'SoapRequest.xml', False, soap_body=xml_send.decode()) - client = HttpClient(base_url) - response = client.post_soap(soap, 'NFeaction/AWS_NFE.%s' % method) - response, obj = sanitize_response(response) - return { - 'sent_xml': xml_send.decode(), - 'received_xml': response, - 'object': obj - } - - -def xml_processa_rps(certificado, **kwargs): - return _render(certificado, 'PROCESSARPS', **kwargs) - - -def processa_rps(certificado, **kwargs): - if "xml" not in kwargs: - kwargs['xml'] = xml_processa_rps(certificado, **kwargs) - return _send(certificado, 'PROCESSARPS', **kwargs) - + raise Exception('Não existe ambiente de homologação!') -def xml_consulta_protocolo(certificado, **kwargs): - return _render(certificado, 'CONSULTAPROTOCOLO', **kwargs) + xml_send = kwargs["xml"].decode('utf-8') + headers = { + 'SOAPAction': "urn:sigiss_ws#%s" % method, + 'Content-Type': 'text/xml; charset="utf-8"' + } + r = requests.post(base_url, data=xml_send, headers=headers) + response, obj = sanitize_response(r.text.strip()) -def consulta_protocolo(certificado, **kwargs): - if "xml" not in kwargs: - kwargs['xml'] = xml_consulta_protocolo(certificado, **kwargs) - return _send(certificado, 'CONSULTAPROTOCOLO', **kwargs) + return { + 'sent_xml': xml_send, + 'received_xml': response, + 'object': obj.Body + } -def xml_consulta_notas_protocolo(certificado, **kwargs): - return _render(certificado, 'CONSULTANOTASPROTOCOLO', **kwargs) +def xml_gerar_nota(certificado, **kwargs): + return _render(certificado, 'GerarNota', **kwargs) -def consulta_notas_protocolo(certificado, **kwargs): +def gerar_nota(certificado, **kwargs): if "xml" not in kwargs: - kwargs['xml'] = xml_consulta_notas_protocolo(certificado, **kwargs) - return _send(certificado, 'CONSULTANOTASPROTOCOLO', **kwargs) + kwargs['xml'] = xml_gerar_nota(certificado, **kwargs) + return _send(certificado, 'GerarNota', **kwargs) -def xml_cancelar_nfse(certificado, **kwargs): - return _render(certificado, 'CANCELANOTAELETRONICA', **kwargs) +def xml_cancelar_nota(certificado, **kwargs): + return _render(certificado, 'CancelarNota', **kwargs) -def cancelar_nfse(certificado, **kwargs): +def cancelar_nota(certificado, **kwargs): if "xml" not in kwargs: - kwargs['xml'] = xml_cancelar_nfse(certificado, **kwargs) - return _send(certificado, 'CANCELANOTAELETRONICA', **kwargs) - + kwargs['xml'] = xml_cancelar_nota(certificado, **kwargs) + return _send(certificado, 'CancelarNota', **kwargs) diff --git a/pytrustnfe/nfse/imperial/templates/CANCELANOTAELETRONICA.xml b/pytrustnfe/nfse/imperial/templates/CANCELANOTAELETRONICA.xml deleted file mode 100644 index 3afb262..0000000 --- a/pytrustnfe/nfse/imperial/templates/CANCELANOTAELETRONICA.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - {{ cancelamento.codigo_usuario }} - {{ cancelamento.codigo_contribuinte }} - - - {{ cancelamento.serie_nota }} - {{ cancelamento.numero_nota }} - {{ cancelamento.serie_rps }} - {{ cancelamento.numero_rps }} - {{ cancelamento.valor }} - {{ cancelamento.motivo }} - {{ cancelamento.cancelar_guia }} - - - diff --git a/pytrustnfe/nfse/imperial/templates/CONSULTANOTASPROTOCOLO.xml b/pytrustnfe/nfse/imperial/templates/CONSULTANOTASPROTOCOLO.xml deleted file mode 100644 index 30ea3d6..0000000 --- a/pytrustnfe/nfse/imperial/templates/CONSULTANOTASPROTOCOLO.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - {{ consulta.protocolo }} - - {{ consulta.codigo_usuario }} - {{ consulta.codigo_contribuinte }} - - - diff --git a/pytrustnfe/nfse/imperial/templates/CONSULTAPROTOCOLO.xml b/pytrustnfe/nfse/imperial/templates/CONSULTAPROTOCOLO.xml deleted file mode 100644 index 09765e5..0000000 --- a/pytrustnfe/nfse/imperial/templates/CONSULTAPROTOCOLO.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - {{ consulta.protocolo }} - - {{ consulta.codigo_usuario }} - {{ consulta.codigo_contribuinte }} - - - diff --git a/pytrustnfe/nfse/imperial/templates/CancelarNota.xml b/pytrustnfe/nfse/imperial/templates/CancelarNota.xml new file mode 100644 index 0000000..8edd597 --- /dev/null +++ b/pytrustnfe/nfse/imperial/templates/CancelarNota.xml @@ -0,0 +1,14 @@ + + + + + {{ cancelamento.ccm }} + {{ cancelamento.cnpj }} + {{ cancelamento.senha }} + {{ cancelamento.nota }} + {{ cancelamento.motivo }} + {{ cancelamento.email }} + + + + diff --git a/pytrustnfe/nfse/imperial/templates/GerarNota.xml b/pytrustnfe/nfse/imperial/templates/GerarNota.xml new file mode 100644 index 0000000..c0a09c4 --- /dev/null +++ b/pytrustnfe/nfse/imperial/templates/GerarNota.xml @@ -0,0 +1,43 @@ + + + + + {{ nfse.ccm }} + {{ nfse.cnpj }} + {{ nfse.senha }} + {{ nfse.crc }} + {{ nfse.crc_estado }} + {{ nfse.aliquota_simples }} + {{ nfse.id_sis_legado }} + {{ nfse.servico }} + {{ nfse.situacao }} + {{ nfse.valor }} + {{ nfse.base }} + {{ nfse.descricaoNF }} + {{ nfse.tomador_tipo }} + {{ nfse.tomador_cnpj }} + {{ nfse.tomador_email }} + {{ nfse.tomador_ie }} + {{ nfse.tomador_razao }} + {{ nfse.tomador_fantasia }} + {{ nfse.tomador_endereco }} + {{ nfse.tomador_endereco }} + {{ nfse.tomador_complemento }} + {{ nfse.tomador_bairro }} + {{ nfse.tomador_CEP }} + {{ nfse.tomador_cod_cidade }} + {{ nfse.tomador_fone }} + {{ nfse.tomador_ramal }} + {{ nfse.tomador_fax }} + {{ nfse.outro_municipio }} + {{ nfse.cod_outro_municipio }} + {{ nfse.retencao_iss }} + {{ nfse.pis }} + {{ nfse.cofins }} + {{ nfse.inss }} + {{ nfse.irrf }} + {{ nfse.csll }} + + + + diff --git a/pytrustnfe/nfse/imperial/templates/PROCESSARPS.xml b/pytrustnfe/nfse/imperial/templates/PROCESSARPS.xml deleted file mode 100644 index 3cfb27a..0000000 --- a/pytrustnfe/nfse/imperial/templates/PROCESSARPS.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - {{ nfse.codigo_usuario }} - {{ nfse.codigo_contribuinte }} - - - {{ nfse.ano }} - {{ nfse.mes }} - {{ nfse.cnpj_prestador }} - {{ nfse.data_emissao }} - {{ nfse.data_emissao }} - {{ nfse.tipo_tributacao }} - {{ nfse.data_adesao_simples }} - {{ nfse.aliquota_simples_isencao|comma }} - 2.00 - {% for rps in nfse.lista_rps -%} - - - - {{ rps.tipo_nfse }} - {{ rps.numero }} - {{ rps.serie }} - {{ rps.data_emissao }} - {{ rps.iss_retido }} - {{ rps.codigo_servico }} - {{ rps.descricao}} - {{ rps.valor_liquido_nfse|comma }} - {{ rps.valor_deducao|comma }} - {{ rps.discriminacao_deducao }} - {{ rps.base_calculo|comma }} - {{ rps.aliquota_issqn|comma }} - {{ rps.valor_iss|comma }} - {{ rps.valor_iss_retido|comma }} - {{ rps.tomador.cnpj_cpf }} - {{ rps.tomador.razao_social }} - {{ rps.tomador.tipo_logradouro }} - {{ rps.tomador.logradouro }} - {{ rps.tomador.numero }} - {{ rps.tomador.complemento }} - {{ rps.tomador.bairro }} - {{ rps.tomador.municipio }} - {{ rps.tomador.uf }} - {{ rps.tomador.cep }} - {{ rps.tomador.telefone }} - {{ rps.tomador.inscricao_municipal }} - {% if rps.local_prestacao == 'prestador' %} - {{ rps.prestador.tipo_logradouro }} - {{ rps.prestador.logradouro }} - {{ rps.prestador.numero }} - {{ rps.prestador.complemento }} - {{ rps.prestador.bairro }} - {{ rps.prestador.municipio }} - {{ rps.prestador.uf }} - {{ rps.prestador.cep }} - {% endif %} - {{ rps.tomador.email }} - {% for imposto in rps.impostos -%} - - - {{ imposto.sigla }} - {{ imposto.aliquota|comma }} - {{ imposto.valor|comma }} - - - {% endfor %} - - - {% endfor %} - - {{ nfse.lista_rps|length }} - {{ nfse.lista_rps|sum(attribute='valor_liquido_nfse')|comma }} - {{ nfse.lista_rps|sum(attribute='valor_iss')|comma }} - {{ nfse.lista_rps|sum(attribute='valor_deducao')|comma }} - {{ nfse.lista_rps|sum(attribute='valor_iss_retido')|comma }} - {{ nfse.quantidade_impostos }} - {{ nfse.valor_tributos|comma }} - - - - diff --git a/pytrustnfe/nfse/imperial/templates/SoapRequest.xml b/pytrustnfe/nfse/imperial/templates/SoapRequest.xml deleted file mode 100644 index e8b56b4..0000000 --- a/pytrustnfe/nfse/imperial/templates/SoapRequest.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - {{ soap_body }} - - diff --git a/pytrustnfe/nfse/simpliss/__init__.py b/pytrustnfe/nfse/simpliss/__init__.py index 62daa4a..b93bd2d 100644 --- a/pytrustnfe/nfse/simpliss/__init__.py +++ b/pytrustnfe/nfse/simpliss/__init__.py @@ -40,7 +40,7 @@ def _send(method, **kwargs): base_url = 'http://wshomologacao.simplissweb.com.br/nfseservice.svc' # noqa base_url = 'http://wshomologacao.simplissweb.com.br/nfseservice.svc' - xml_send = kwargs["xml"].replace('', '') + xml_send = kwargs["xml"] path = os.path.join(os.path.dirname(__file__), 'templates') soap = render_xml(path, 'SoapRequest.xml', False, soap_body=xml_send) diff --git a/pytrustnfe/urls.py b/pytrustnfe/urls.py index 25e65c1..3e8827d 100644 --- a/pytrustnfe/urls.py +++ b/pytrustnfe/urls.py @@ -39,6 +39,7 @@ URLS = { DF: 'http://www.fazenda.df.gov.br/nfce/qrcode?', GO: 'http://nfe.sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe?', MA: 'http://nfce.sefaz.ma.gov.br/portal/consultarNFCe.jsp?', + MG: 'https://nfce.fazenda.mg.gov.br/portalnfce/sistema/qrcode.xhtml?', MS: 'http://www.dfe.ms.gov.br/nfce/qrcode?', MT: 'http://www.sefaz.mt.gov.br/nfce/consultanfce?', PA: 'https://appnfc.sefa.pa.gov.br/portal/view/consultas/nfce/nfceForm.seam?', # noqa @@ -65,6 +66,7 @@ URLS = { GO: 'http://homolog.sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe?', MA: 'http://homologacao.sefaz.ma.gov.br/portal/consultarNFCe.jsp?', MS: 'http://www.dfe.ms.gov.br/nfce/qrcode?', + MG: 'https://nfce.fazenda.mg.gov.br/portalnfce/sistema/qrcode.xhtml?', MT: 'http://homologacao.sefaz.mt.gov.br/nfce/consultanfce?', PA: 'https://appnfc.sefa.pa.gov.br/portal-homologacao/view/consultas/nfce/nfceForm.seam?', # noqa PB: 'http://www.receita.pb.gov.br/nfcehom?', @@ -96,7 +98,7 @@ URLS_EXIBICAO = { MA: 'www.sefaz.ma.gov.br/nfce/consulta', MS: 'www.dfe.ms.gov.br/nfce/consulta', MT: 'www.sefaz.mt.gov.br/nfce/consulta', - MG: 'www.fazenda.mg.gov.br/nfce/consulta', + MG: 'http://nfce.fazenda.mg.gov.br/portalnfce', PA: 'www.sefa.pa.gov.br/nfce/consulta', PB: 'www.receita.pb.gov.br/nfce/consulta', PE: 'nfce.sefaz.pe.gov.br/nfce/consulta', @@ -124,7 +126,7 @@ URLS_EXIBICAO = { MA: 'www.sefaz.ma.gov.br/nfce/consulta', MS: 'www.dfe.ms.gov.br/nfce/consulta', MT: 'www.sefaz.mt.gov.br/nfce/consulta', - MG: 'www.fazenda.mg.gov.br/nfce/consulta', + MG: 'http://hnfce.fazenda.mg.gov.br/portalnfce', PA: 'www.sefa.pa.gov.br/nfce/consulta', PB: 'www.receita.pb.gov.br/nfcehom', PE: 'nfce.sefaz.pe.gov.br/nfce/consulta', diff --git a/pytrustnfe/xml/schemas/distDFeInt_v1.01.xsd b/pytrustnfe/xml/schemas/distDFeInt_v1.01.xsd new file mode 100644 index 0000000..5497aa7 --- /dev/null +++ b/pytrustnfe/xml/schemas/distDFeInt_v1.01.xsd @@ -0,0 +1,297 @@ + + + + + Tipo número sequencial único + + + + + + + + Tipo quantidade de NSU + + + + + + + + + Tipo Versão dos leiautes do Web Service NFeDistribuicaoDFe + + + + + + + + + Tipo Ambiente + + + + + + + + + + Tipo Código da UF da tabela do IBGE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tipo Código de orgão (UF da tabela do IBGE + 90 RFB) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tipo Número do CNPJ + + + + + + + + + + Tipo Número do CPF + + + + + + + + + + Tipo Versão do Aplicativo + + + + + + + + + Tipo Código da Mensagem enviada + + + + + + + + + + Tipo Motivo + + + + + + + + + Tipo string genérico + + + + + + + + + Tipo Chave da Nota Fiscal Eletrônica + + + + + + + + + + Tipo Número do Protocolo de Status + + + + + + + + + + Data e Hora, formato UTC (AAAA-MM-DDThh:mm:ssTZD, onde TZD = +hh:mm ou -hh:mm) + + + + + + + + + Tipo Inscrição Estadual do Emitente // alterado EM 24/10/08 para aceitar ISENTO + + + + + + + + + + Tipo Decimal com 15 dígitos, sendo 13 de corpo e 2 decimais + + + + + + + + + Schema de pedido de distribuição de DF-e de interesse + + + + + + + Identificação do Ambiente: + 1 - Produção + 2 - Homologação + + + + + + Código da UF do Autor + + + + + + CNPJ do interessado no DF-e + + + + + CPF do interessado no DF-e + + + + + + + Grupo para distribuir DF-e de interesse + + + + + + Último NSU recebido pelo ator. Caso seja informado com zero, ou com um NSU muito antigo, a consulta retornará unicamente as informações resumidas e documentos fiscais eletrônicos que tenham sido recepcionados pelo Ambiente Nacional nos últimos 3 meses. + + + + + + + + Grupo para consultar um DF-e a partir de um NSU específico + + + + + + Número Sequencial Único. Geralmente esta consulta será utilizada quando identificado pelo interessado um NSU faltante. O Web Service retornará o documento ou informará que o NSU não existe no Ambiente Nacional. Assim, esta consulta fechará a lacuna do NSU identificado como faltante. + + + + + + + + Grupo para consultar uma NF-e a partir da chave de acesso + + + + + + Chave de acesso da NF-e a ser consultada + + + + + + + + + + + diff --git a/pytrustnfe/xml/schemas/leiauteNFe_v4.00.xsd b/pytrustnfe/xml/schemas/leiauteNFe_v4.00.xsd index 8cde564..a643eb9 100755 --- a/pytrustnfe/xml/schemas/leiauteNFe_v4.00.xsd +++ b/pytrustnfe/xml/schemas/leiauteNFe_v4.00.xsd @@ -9,6 +9,8 @@ + + @@ -875,7 +877,8 @@ Formato ”CFOP9999”. - + + @@ -1268,10 +1271,10 @@ Formato ”CFOP9999”. - - - - + + + + @@ -1586,12 +1589,22 @@ N-NormalVIN - Utilizar o número do registro ANVISA -Obs.: Para medicamento isento de registro na ANVISA, utilizar o número da decisão que o isenta, como por exemplo o número da Resolução da Diretoria Colegiada da ANVISA (RDC). + Utilizar o número do registro ANVISA ou preencher com o literal “ISENTO”, no caso de medicamento isento de registro na ANVISA. - + + + + + + + Obs.: Para medicamento isento de registro na ANVISA, informar o número da decisão que o isenta, como por exemplo o número da Resolução da Diretoria Colegiada da ANVISA (RDC). + + + + + @@ -2355,9 +2368,8 @@ Informar o motivo da desoneração: - - - + + @@ -2504,7 +2516,12 @@ A exigência do preenchimento das informações do ICMS diferido fica à critér Aliquota suportada pelo consumidor final. - + + + Valor do ICMS Próprio do Substituto cobrado em operação anterior + + + Valor do ICMS ST retido anteriormente @@ -2527,10 +2544,8 @@ A exigência do preenchimento das informações do ICMS diferido fica à critér - - - - + + Percentual de redução da base de cálculo efetiva. @@ -3058,11 +3073,38 @@ Operação interestadual para consumidor final com partilha do ICMS devido na o Informar o valor da BC do ICMS ST retido na UF remetente + + + Aliquota suportada pelo consumidor final. + + + + + Valor do ICMS Próprio do Substituto cobrado em operação anterior + + Informar o valor do ICMS ST retido na UF remetente (iv2.0)) + + + + Informar o valor da Base de Cálculo do FCP retido anteriormente por ST. + + + + + Percentual relativo ao Fundo de Combate à Pobreza (FCP) retido por substituição tributária. + + + + + Valor do ICMS relativo ao Fundo de Combate à Pobreza (FCP) retido por substituição tributária. + + + Informar o valor da BC do ICMS ST da UF destino @@ -3073,6 +3115,28 @@ Operação interestadual para consumidor final com partilha do ICMS devido na o Informar o valor da BC do ICMS ST da UF destino (v2.0) + + + + Percentual de redução da base de cálculo efetiva. + + + + + Valor da base de cálculo efetiva. + + + + + Alíquota do ICMS efetivo. + + + + + Valor do ICMS efetivo. + + + @@ -3380,6 +3444,11 @@ Operação interestadual para consumidor final com partilha do ICMS devido na o Aliquota suportada pelo consumidor final. + + + Valor do ICMS próprio do substituto + + Valor do ICMS ST retido anteriormente (v2.0) @@ -3403,10 +3472,8 @@ Operação interestadual para consumidor final com partilha do ICMS devido na o - - - - + + Percentual de redução da base de cálculo efetiva. @@ -3427,8 +3494,7 @@ Operação interestadual para consumidor final com partilha do ICMS devido na o - - + @@ -4985,8 +5051,8 @@ Substituição Tributaria; - - + + @@ -5407,6 +5473,11 @@ concessório + + + Informações do Responsável Técnico pela emissão do DF-e + + @@ -5518,6 +5589,30 @@ concessório Descrição literal do status do serviço solicitado. + + + + Código da Mensagem. + + + + + + + + + + + Mensagem da SEFAZ para o emissor. + + + + + + + + + @@ -5967,6 +6062,17 @@ alterado para tamanho variavel 1-4. (NT2011/004) + + + Razão Social ou Nome do Expedidor/Recebedor + + + + + + + + Logradouro @@ -6032,6 +6138,136 @@ alterado para tamanho variavel 1-4. (NT2011/004) Sigla da UF + + + CEP + + + + + + + + + + + Código de Pais + + + + + + + + + + + Nome do país + + + + + + + + + + + Telefone, preencher com Código DDD + número do telefone , nas operações com exterior é permtido informar o código do país + código da localidade + número do telefone + + + + + + + + + + + Informar o e-mail do expedidor/Recebedor. O campo pode ser utilizado para informar o e-mail de recepção da NF-e indicada pelo expedidor + + + + + + + + + + + + Inscrição Estadual (v2.0) + + + + + + + Grupo de informações do responsável técnico pelo sistema de emissão de DF-e + + + + + CNPJ + + + + + Informar o nome da pessoa a ser contatada na empresa desenvolvedora do sistema utilizado na emissão do documento fiscal eletrônico. + + + + + + + + + + + Informar o e-mail da pessoa a ser contatada na empresa desenvolvedora do sistema. + + + + + + + + + + + + Informar o telefone da pessoa a ser contatada na empresa desenvolvedora do sistema. Preencher com o Código DDD + número do telefone. + + + + + + + + + + + + Identificador do CSRT utilizado para montar o hash do CSRT + + + + + + + + + + + O hashCSRT é o resultado da função hash (SHA-1 – Base64) do CSRT fornecido pelo fisco mais a Chave de Acesso da NFe. + + + + + + + + @@ -6124,6 +6360,7 @@ alterado para tamanho variavel 1-4. (NT2011/004) + @@ -6166,6 +6403,7 @@ alterado para tamanho variavel 1-4. (NT2011/004) + @@ -6239,6 +6477,7 @@ alterado para tamanho variavel 1-4. (NT2011/004) + @@ -6258,6 +6497,7 @@ alterado para tamanho variavel 1-4. (NT2011/004) + @@ -6295,6 +6535,7 @@ alterado para tamanho variavel 1-4. (NT2011/004) + diff --git a/pytrustnfe/xml/validate.py b/pytrustnfe/xml/validate.py index 3f672ba..01dd51e 100644 --- a/pytrustnfe/xml/validate.py +++ b/pytrustnfe/xml/validate.py @@ -8,11 +8,12 @@ from lxml import etree PATH = os.path.dirname(os.path.abspath(__file__)) SCHEMA = os.path.join(PATH, 'schemas/enviNFe_v4.00.xsd') +SCHEMA_DFE = os.path.join(PATH, 'schemas/distDFeInt_v1.01.xsd') -def valida_nfe(xml_nfe): +def valida_nfe(xml_nfe, schema=SCHEMA): nfe = etree.fromstring(xml_nfe) - esquema = etree.XMLSchema(etree.parse(SCHEMA)) + esquema = etree.XMLSchema(etree.parse(schema)) esquema.validate(nfe) erros = [x.message for x in esquema.error_log] return "\n".join(erros) diff --git a/setup.py b/setup.py index 51030a3..00299ec 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages -VERSION = "1.0.33.post3" +VERSION = "1.0.45" setup( @@ -39,12 +39,14 @@ later (LGPLv2+)', 'nfse/carioca/templates/*xml', 'nfse/bh/templates/*xml', 'nfse/mga/templates/*xml', + 'nfse/aparecida/templates/*xml', 'xml/schemas/*xsd', ]}, url='https://github.com/danimaribeiro/PyTrustNFe', license='LGPL-v2.1+', description='PyTrustNFe é uma biblioteca para envio de NF-e', long_description=open('README.md', 'r').read(), + long_description_content_type='text/markdown', install_requires=[ 'urllib3', 'xmlsec==1.3.3', # apt update;apt install libxmlsec1-dev pkg-config -y diff --git a/tests/test_servidores.py b/tests/test_servidores.py index a072f97..e83ac1a 100644 --- a/tests/test_servidores.py +++ b/tests/test_servidores.py @@ -21,7 +21,7 @@ url_rs = 'https://nfe.sefazrs.rs.gov.br/ws/NfeAutorizacao/NFeAutorizacao4.asmx?w url_cad_rs = 'https://cad.sefazrs.rs.gov.br/ws/cadconsultacadastro/cadconsultacadastro4.asmx?wsdl' url_cad_sc = 'https://cad.svrs.rs.gov.br/ws/cadconsultacadastro/cadconsulta\ -cadastro2.asmx?wsdl' +cadastro4.asmx?wsdl' class test_servidores(unittest.TestCase):