From c2e2d1ed467e831b7223a0cabe4a3daf7a757ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A1bio=20Luna?= Date: Thu, 14 Dec 2017 16:15:03 -0200 Subject: [PATCH] [WIP] Implementa NFS-e Campinas --- pytrustnfe/nfse/campinas/__init__.py | 80 +++++++++++ .../nfse/campinas/templates/ConsultaSeqRps.xsd | 30 +++++ .../nfse/campinas/templates/ConsultarLote.xml | 10 ++ .../nfse/campinas/templates/ConsultarLote.xsd | 46 +++++++ pytrustnfe/nfse/campinas/templates/cancelar.xml | 18 +++ pytrustnfe/nfse/campinas/templates/cancelar.xsd | 55 ++++++++ .../nfse/campinas/templates/consulta_notas.xml | 11 ++ .../nfse/campinas/templates/consulta_notas.xsd | 88 ++++++++++++ .../nfse/campinas/templates/consultarNFSeRps.xml | 19 +++ .../nfse/campinas/templates/consultarNFSeRps.xsd | 55 ++++++++ pytrustnfe/nfse/campinas/templates/enviar.xml | 108 +++++++++++++++ pytrustnfe/nfse/campinas/templates/enviar.xsd | 149 +++++++++++++++++++++ pytrustnfe/nfse/campinas/templates/soap_header.xml | 12 ++ 13 files changed, 681 insertions(+) create mode 100644 pytrustnfe/nfse/campinas/__init__.py create mode 100644 pytrustnfe/nfse/campinas/templates/ConsultaSeqRps.xsd create mode 100644 pytrustnfe/nfse/campinas/templates/ConsultarLote.xml create mode 100644 pytrustnfe/nfse/campinas/templates/ConsultarLote.xsd create mode 100644 pytrustnfe/nfse/campinas/templates/cancelar.xml create mode 100644 pytrustnfe/nfse/campinas/templates/cancelar.xsd create mode 100644 pytrustnfe/nfse/campinas/templates/consulta_notas.xml create mode 100644 pytrustnfe/nfse/campinas/templates/consulta_notas.xsd create mode 100644 pytrustnfe/nfse/campinas/templates/consultarNFSeRps.xml create mode 100644 pytrustnfe/nfse/campinas/templates/consultarNFSeRps.xsd create mode 100644 pytrustnfe/nfse/campinas/templates/enviar.xml create mode 100644 pytrustnfe/nfse/campinas/templates/enviar.xsd create mode 100644 pytrustnfe/nfse/campinas/templates/soap_header.xml diff --git a/pytrustnfe/nfse/campinas/__init__.py b/pytrustnfe/nfse/campinas/__init__.py new file mode 100644 index 0000000..ff5ef02 --- /dev/null +++ b/pytrustnfe/nfse/campinas/__init__.py @@ -0,0 +1,80 @@ +# -*- encoding: utf-8 -*- +# © 2017 Fábio Luna, Trustcode +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +import os +import suds +from lxml import etree +from pytrustnfe.xml import render_xml, sanitize_response +from pytrustnfe.nfse.assinatura import Assinatura +from pytrustnfe import HttpClient + + +def _render_xml(certificado, method, **kwargs): + path = os.path.join(os.path.dirname(__file__), 'templates') + xml_send = render_xml(path, '%s.xml' % method, True, **kwargs) + xml_send = etree.tostring(xml_send) + + return xml_send + + +def _validate(method, xml): + path = os.path.join(os.path.dirname(__file__), 'templates') + schema = os.path.join(path, '%s.xsd' % method) + + nfe = etree.fromstring(xml) + esquema = etree.XMLSchema(etree.parse(schema)) + esquema.validate(nfe) + erros = [x.message for x in esquema.error_log] + return erros + + +def _send(certificado, method, **kwargs): + url = 'http://issdigital.campinas.sp.gov.br/WsNFe2/LoteRps.jws?wsdl' # noqa + + path = os.path.join(os.path.dirname(__file__), 'templates') + + if method == "testeEnviar": + xml_send = render_xml(path, 'testeEnviar', **kwargs) + else: + xml_send = render_xml(path, '%s.xml' % method, False) + client = HttpClient(url) + + pfx_path = certificado.save_pfx() + signer = Assinatura(pfx_path, certificado.password) + xml_signed = signer.assina_xml(xml_send, '') + + try: + response = getattr(client.service, method)(xml_signed) + response, obj = sanitize_response(response) + except suds.WebFault as e: + return { + 'sent_xml': xml_send, + 'received_xml': e.fault.faultstring, + 'object': None + } + + return { + 'sent_xml': xml_send, + 'received_xml': response, + 'object': obj + } + + +def enviar(certificado, **kwargs): + if kwargs['ambiente'] == 'producao': + return _send(certificado, 'enviar', **kwargs) + else: + return _send(certificado, 'testeEnviar', **kwargs) + + +def cancelar(certificado, ** kwargs): + return _send(certificado, 'cancelar', **kwargs) + + +def consulta_lote(certificado, **kwargs): + return _send(certificado, 'ConsultarLote', **kwargs) + + +def consultar_lote_rps(certificado, **kwarg): + return _send(certificado, 'consultarNFSeRps', **kwarg) diff --git a/pytrustnfe/nfse/campinas/templates/ConsultaSeqRps.xsd b/pytrustnfe/nfse/campinas/templates/ConsultaSeqRps.xsd new file mode 100644 index 0000000..94491a7 --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/ConsultaSeqRps.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pytrustnfe/nfse/campinas/templates/ConsultarLote.xml b/pytrustnfe/nfse/campinas/templates/ConsultarLote.xml new file mode 100644 index 0000000..24afc5d --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/ConsultarLote.xml @@ -0,0 +1,10 @@ + + + {{ consulta.cidade }} + {{ consulta.cpf_cnpj }} + 1 + {{ consulta.lote }} + + \ No newline at end of file diff --git a/pytrustnfe/nfse/campinas/templates/ConsultarLote.xsd b/pytrustnfe/nfse/campinas/templates/ConsultarLote.xsd new file mode 100644 index 0000000..068756f --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/ConsultarLote.xsd @@ -0,0 +1,46 @@ + + + + + + Schema utilizado para REQUISIçÂO de Consulta de Lote de RPS. + Este Schema XML é utilizado pelos Prestadores de serviços para consultarem Lote de RPS emitidos por eles. + + + + + + Cabeçalho do pedido. + + + + + + Informe o Codigo da Cidade. + + + + + Informe o CPF/CNPJ do Remetente autorizado a transmitir a mensagem XML. + + + + + Informe a Versão do Schema XML utilizado. + + + + + Informe o Número do Lote a ser consultado. + + + + + + + + + diff --git a/pytrustnfe/nfse/campinas/templates/cancelar.xml b/pytrustnfe/nfse/campinas/templates/cancelar.xml new file mode 100644 index 0000000..d72086b --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/cancelar.xml @@ -0,0 +1,18 @@ + + + {{ cancelamento.cidade }} + {{ cancelamento.cpf_cnpj }} + true + 1 + + + + {{ cancelamento.inscricao_municipal }} + {{ cancelamento.nota_id }} + {{ cancelamento.assinatura }} + {{ cancelamento.motivo }} + + + diff --git a/pytrustnfe/nfse/campinas/templates/cancelar.xsd b/pytrustnfe/nfse/campinas/templates/cancelar.xsd new file mode 100644 index 0000000..09f1938 --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/cancelar.xsd @@ -0,0 +1,55 @@ + + + + + + + + Schema utilizado para Cancelamento de NFSe. + Este Schema XML é utilizado pelos Prestadores de serviços cancelarem NFSe emitidas por eles. + + + + + + Cabeçalho do pedido. + + + + + + Informe o Codigo da Cidade. + + + + + Informe o CPF/CNPJ do Remetente autorizado a transmitir a mensagem XML. + + + + + Informe se as NF-e a serem canceladas farão parte de uma mesma transação. True - As NF-e só serão canceladas se não ocorrer nenhum evento de erro durante o processamento de todo o lote; False - As NF-e aptas a serem canceladas serão canceladas, mesmo que ocorram eventos de erro durante processamento do cancelamento de outras NF-e deste lote. + + + + + Informe a Versão do Schema XML utilizado. + + + + + + + + Detalhe do pedido de cancelamento de NFSe. Cada detalhe deverá conter a Chave de uma NFSe e sua respectiva assinatura de cancelamento. + + + + + + + diff --git a/pytrustnfe/nfse/campinas/templates/consulta_notas.xml b/pytrustnfe/nfse/campinas/templates/consulta_notas.xml new file mode 100644 index 0000000..4a666d0 --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/consulta_notas.xml @@ -0,0 +1,11 @@ + + +{{ consulta.cidade }} +{{ consulta.cpf_cnpj }} +{{ consulta.inscricao_municipal }} +{{ consulta.data_inicio }} +{{ consulta.data_final }} +{{ consulta.nota_inicial }} +1 + + \ No newline at end of file diff --git a/pytrustnfe/nfse/campinas/templates/consulta_notas.xsd b/pytrustnfe/nfse/campinas/templates/consulta_notas.xsd new file mode 100644 index 0000000..5784eb8 --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/consulta_notas.xsd @@ -0,0 +1,88 @@ + + + + + + + Schema utilizado para REQUISIÇAO de consultas + de notas que foram enviadas por lote de RPS. + Este Schema XML é utilizado pelos prestadores + de serviços para consultas de notas que foram enviadas por lote de + RPS. + + + + + + Cabeçalho do pedido. + + + + + + Informe o Codigo da Cidade. + + + + + + Informe o CPF/CNPJ do Remetente + autorizado a transmitir a mensagem XML. + + + + + Informe a Inscrição Municipal do + Prestador + + + + + Informe a data de início do período + transmitido (AAAA-MM-DD). + + + + + Informe a data final do período + transmitido (AAAA-MM-DD). + + + + + Numero da nota inicial da consulta. Ou + seja a consulta ira retornar as notas no periodo, onde o + numero da nota seja maior ou igual a esse numero. O retorno + não pode ultrapassar 500Kb. Caso não tenha o numero da nota, + passar o valor Zero, será retornado as notas geradas no + periodo até o limite de 500kb. + + + + + Informe a Versão. + + + + + + + + + + + + + diff --git a/pytrustnfe/nfse/campinas/templates/consultarNFSeRps.xml b/pytrustnfe/nfse/campinas/templates/consultarNFSeRps.xml new file mode 100644 index 0000000..6535559 --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/consultarNFSeRps.xml @@ -0,0 +1,19 @@ + + + {{ consulta.cidade }} + {{ consulta.cpf_cnpj }} + true + 1 + + + + + {{ consulta.inscricao_municipal }} + {{ consulta.rps_id }} + {{ consulta.serie_prestacao }} + + + + diff --git a/pytrustnfe/nfse/campinas/templates/consultarNFSeRps.xsd b/pytrustnfe/nfse/campinas/templates/consultarNFSeRps.xsd new file mode 100644 index 0000000..c0e83bf --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/consultarNFSeRps.xsd @@ -0,0 +1,55 @@ + + + + + + + + Schema utilizado para Consulta de NFSe. + Este Schema XML é utilizado pelos Prestadores de serviços consultarem NFSe emitidas por eles. + + + + + + Cabeçalho do pedido. + + + + + + Informe o Codigo da Cidade. + + + + + Informe o CPF/CNPJ do Remetente autorizado a transmitir a mensagem XML. + + + + + Informe se as NF-e a serem consultadas farão parte de uma mesma transação. Informe sempre True. + + + + + Informe a Versão do Schema XML utilizado. + + + + + + + + Detalhe do pedido de consulta de NFSe. Cada detalhe deverá conter a Chave de uma NFSe e sua respectiva assinatura de consulta. + + + + + + + diff --git a/pytrustnfe/nfse/campinas/templates/enviar.xml b/pytrustnfe/nfse/campinas/templates/enviar.xml new file mode 100644 index 0000000..7e4b178 --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/enviar.xml @@ -0,0 +1,108 @@ + + + {{ nfse.cidade }} + {{ nfse.cpf_cnpj }} + {{ nfse.remetente }} + {{ nfse.transacao }} + {{ nfse.data_inicio|format_date }} + {{ nfse.data_fim|format_date }} + {{ nfse.total_rps }} + {{ nfse.total_servicos }} + {{ nfse.total_deducoes }} + 1 + WS + + + {% for rps in nfse.lista_rps -%} + + {{ rps.assinatura }} + {{ rps.prestador.inscricao_municipal }} + + {{ rps.prestador.razao_social }} + RPS + {{ rps.serie }} + {{ rps.numero }} + {{ rps.data_emissao|format_datetime }} + + {{ rps.situacao }} + + 0 + 0 + 1900-01-01 + {{ rps.serie_prestacao }} + {{ rps.tomador.inscricao_municipal }} + {{ rps.tomador.cpf_cnpj }} + {{ rps.tomador.razao_social }} + + {{ rps.tomador.tipo_logradouro }} + + {{ rps.tomador.logradouro }} + {{ rps.tomador.numero }} + + {{ rps.tomador.tipo_bairro }} + {{ rps.tomador.bairro }} + {{ rps.tomador.cidade }} + {{ rps.tomador.cidade_descricao }} + + {{ rps.tomador.cep }} + {{ rps.tomador.email }} + {{ rps.codigo_atividade }} + {{ rps.aliquota_atividade }} + {{ rps.tipo_recolhimento }} + {{ rps.municipio_prestacao }} + + {{ rps.municipio_descricao_prestacao }} + + {{ rps.operacao }} + {{ rps.tributacao }} + {{ rps.valor_pis }} + {{ rps.valor_cofins }} + {{ rps.valor_inss }} + {{ rps.valor_ir }} + {{ rps.valor_csll }} + {{ rps.aliquota_pis }} + {{ rps.aliquota_cofins }} + {{ rps.aliquota_inss }} + {{ rps.aliquota_ir }} + {{ rps.aliquota_csll }} + {{ rps.descricao }} + {{ rps.prestador.ddd }} + {{ rps.prestador.telefone }} + {{ rps.tomador.ddd }} + {{ rps.tomador.telefone }} + {{ rps.motivo_cancelamento }} + {% if rps.deducoes|count > 0 %} + + {% for deducao in rps.deducoes -%} + + {{ deducao.por }} + {{ deducao.tipo }} + {{ deducao.cnpj_referencia }} + {{ deducao.nf_referencia }} + {{ deducao.valor_referencia }} + {{ deducao.percentual_deduzir }} + {{ deducao.valor_deduzir }} + + {% endfor %} + + {% endif %} + {% if rps.deducoes|count == 0 %} + + {% endif %} + + {% for item in rps.itens -%} + + {{ item.descricao }} + {{ item.quantidade }} + {{ item.valor_unitario }} + {{ item.valor_total }} + S + + {% endfor %} + + + {% endfor %} + + diff --git a/pytrustnfe/nfse/campinas/templates/enviar.xsd b/pytrustnfe/nfse/campinas/templates/enviar.xsd new file mode 100644 index 0000000..fedce41 --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/enviar.xsd @@ -0,0 +1,149 @@ + + + + + + Schema utilizado para envio de lote de RPS. + Este Schema XML é utilizado pelos prestadores + de serviços para substituição em lote de RPS por NFS-e. + + + + + + + Cabeçalho do Lote. + + + + + + Informe o Codigo da Cidade no Padrão SIAFI. + + + + + + + CNPJ do contribuinte ou CPF do Responsável Legal autorizado a entregar o lote. + + + + + + + Informe o Nome do Contribuinte ou do Responsável Legal + + + + + + + Informe se os RPS a serem + substituídos por + NF-e farão + parte de uma mesma transação. + True - Os RPS só serão + substituídos por NF-e se não + ocorrer nenhum evento de erro + durante o processamento de todo + o lote; False - Os RPS válidos + serão substituídos por NF-e, + mesmo que ocorram eventos de + erro durante processamento de + outros RPS deste lote. Por definição + estão sendo aceitos apenas lotes com RPS válidos, + o lote é + recusado caso haja algum RPS inválido. + + + + + + + Informe a data de início do + período + transmitido + (AAAA-MM-DD). + + + + + + + Informe a data final do período + transmitido + (AAAA-MM-DD). + + + + + + + Informe o total de RPS contidos + na mensagem + XML. OBS: O xml não pode ultrapassar o tamanho maximo de 500kb. + + + + + + + Informe o valor total dos + serviços prestados + dos RPS + contidos na mensagem XML. + + + + + + + Informe o valor total das + deduções dos RPS + contidos na + mensagem XML. + + + + + + + Informe a Versão do Schema XML + utilizado. + + + + + + Informe o Método de Envio + + + + + Versão da DLL de envio de lote. Não é necessário informar esse campo caso não utilize a DLL. + + + + + + + + + + Informe os RPS a serem substituidos por + NF-e. + + + + + + + diff --git a/pytrustnfe/nfse/campinas/templates/soap_header.xml b/pytrustnfe/nfse/campinas/templates/soap_header.xml new file mode 100644 index 0000000..e9d1dd2 --- /dev/null +++ b/pytrustnfe/nfse/campinas/templates/soap_header.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file