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