diff --git a/pytrustnfe/ChaveNFe.py b/pytrustnfe/ChaveNFe.py deleted file mode 100644 index 53cee14..0000000 --- a/pytrustnfe/ChaveNFe.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# © 2016 Danimar Ribeiro, Trustcode -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - - -class ChaveNFe(object): - - def __init__(self, **kwargs): - self.cnpj = kwargs.pop('cnpj', '') - self.estado = kwargs.pop('estado', '') - self.emissao = kwargs.pop('emissao', '') - self.modelo = kwargs.pop('modelo', '') - self.serie = kwargs.pop('serie', '') - self.numero = kwargs.pop('numero', '') - self.tipo = kwargs.pop('tipo', '') - self.codigo = kwargs.pop('codigo', '') - - def validar(self): - assert self.cnpj != '', 'CNPJ necessário para criar chave NF-e' - assert self.estado != '', 'Estado necessário para criar chave NF-e' - assert self.emissao != '', 'Emissão necessário para criar chave NF-e' - assert self.modelo != '', 'Modelo necessário para criar chave NF-e' - assert self.serie != '', 'Série necessária para criar chave NF-e' - assert self.numero != '', 'Número necessário para criar chave NF-e' - assert self.tipo != '', 'Tipo necessário para criar chave NF-e' - assert self.codigo != '', 'Código necessário para criar chave NF-e' diff --git a/pytrustnfe/nfe/__init__.py b/pytrustnfe/nfe/__init__.py index 8d24ceb..89a430f 100644 --- a/pytrustnfe/nfe/__init__.py +++ b/pytrustnfe/nfe/__init__.py @@ -5,17 +5,77 @@ import os from lxml import etree -from .comunicacao import Comunicacao +from pytrustnfe.comunicacao import executar_consulta, Comunicacao from .assinatura import sign_xml, Assinatura from pytrustnfe import utils from pytrustnfe.xml import render_xml +from pytrustnfe.utils import CabecalhoSoap +def _build_header(**kwargs): + estado = kwargs['estado'] + return CabecalhoSoap({ 'estado': estado, 'soap_action': '' }) + + +def _send(certificado, method, **kwargs): + path = os.path.join(os.path.dirname(__file__), 'templates') + + xml = render_xml(path, '%s.xml' % method, **kwargs) + + pfx_path = certificado.save_pfx() + signer = Assinatura(pfx_path, certificado.password) + xml_signed = signer.assina_xml(xml, '') + + cabecalho = _build_header(**kwargs) + + return executar_consulta(certificado, cabecalho, xml_signed) + + + +def autorizar_nfe(certificado, **kwargs): # Assinar + _send(certificado, 'NfeAutorizacao', **kwargs) + +def retorno_autorizar_nfe(certificado, **kwargs): + _send(certificado, 'NfeRetAutorizacao', **kwargs) + +def recepcao_evento_cancelamento(certificado, **kwargs): # Assinar + _send(certificado, 'RecepcaoEventoCancelamento', **kwargs) + +def inutilizar_nfe(certificado, **kwargs): # Assinar + _send(certificado, 'NfeInutilizacao', **kwargs) + +def consultar_protocolo_nfe(certificado, **kwargs): + _send(certificado, 'NfeConsultaProtocolo', **kwargs) + +def nfe_status_servico(certificado, **kwargs): + _send(certificado, 'NfeStatusServico.', **kwargs) + +def consulta_cadastro(certificado, **kwargs): + _send(certificado, 'NfeConsultaCadastro.', **kwargs) + +def recepcao_evento_carta_correcao(certificado, **kwargs): # Assinar + _send(certificado, 'RecepcaoEventoCarta.', **kwargs) + +def recepcao_evento_manifesto(certificado, **kwargs): # Assinar + _send(certificado, 'RecepcaoEventoManifesto', **kwargs) + +def recepcao_evento_epec(certificado, **kwargs): # Assinar + _send(certificado, 'RecepcaoEventoEPEC', **kwargs) + +def consulta_nfe_destinada(certificado, **kwargs): + _send(certificado, 'NfeConsultaDest', **kwargs) + +def download_nfe(certificado, **kwargs): + _send(certificado, 'NfeDownloadNF', **kwargs) + + class NFe(Comunicacao): def __init__(self, cert, key): Comunicacao.__init__(self, cert, key) + + def consultar_cadastro(self, cadastro, estado): self.url = 'https://cad.sefazrs.rs.gov.br/ws/cadconsultacadastro/cadconsultacadastro2.asmx' self.metodo = 'NfeConsultaCadastro' diff --git a/pytrustnfe/nfe/comunicacao.py b/pytrustnfe/nfe/comunicacao.py index f767873..68db27c 100644 --- a/pytrustnfe/nfe/comunicacao.py +++ b/pytrustnfe/nfe/comunicacao.py @@ -15,6 +15,15 @@ common_namespaces = {'soap': 'http://www.w3.org/2003/05/soap-envelope'} soap_body_path = './soap:Envelope/soap:Body' soap_fault_path = './soap:Envelope/soap:Body/soap:Fault' +def executar_consulta(cerficado, cabecalho, xmlEnviar): + cert_path, key_path = self._preparar_temp_pem() + + client = HttpClient(self.url, cert_path, key_path) + soap_xml = self._soap_xml(xmlEnviar) + xml_retorno = client.post_xml(self.web_service, soap_xml) + + return sanitize_response(xml_retorno) + class Comunicacao(object): url = '' diff --git a/pytrustnfe/nfe/templates/NfeAutorizacao.xml b/pytrustnfe/nfe/templates/NfeAutorizacao.xml new file mode 100644 index 0000000..2ca11ad --- /dev/null +++ b/pytrustnfe/nfe/templates/NfeAutorizacao.xml @@ -0,0 +1,183 @@ + + {{ idLote }} + {{ indSinc }} + {% for NFe in NFes %} + + + + {% with ide = NFe.infNFe.ide %} + {{ ide.cUF }} + {{ ide.cNF }} + {{ ide.natOp }} + {{ ide.indPag }} + {{ ide.mod }} + {{ ide.serie }} + {{ ide.nNF }} + {{ ide.dhEmi }} + {{ ide.dhSaiEnt }} + {{ ide.tpNF }} + {{ ide.idDest }} + {{ ide.cMunFG }} + {{ ide.tpImp }} + {{ ide.tpEmis }} + {{ ide.cDV }} + {{ ide.tpAmb }} + {{ ide.finNFe }} + {{ ide.indFinal }} + {{ ide.indPres }} + {{ ide.procEmi }} + Odoo Brasil 9.0 + {% endwith %} + + + {% with emit = NFe.infNFe.emit %} + {% if emit.tipo == 'person' -%} + {{ emit.cnpj_cpf }} + {% endif %} + {% if emit.tipo == 'company' -%} + {{ emit.cnpj_cpf }} + {% endif %} + {{ emit.xNome }} + {{ emit.xFant }} + + {{ emit.enderEmit.xLgr }} + {{ emit.enderEmit.nro }} + {{ emit.enderEmit.xBairro }} + {{ emit.enderEmit.cMun }} + {{ emit.enderEmit.xMun }} + {{ emit.enderEmit.UF }} + {{ emit.enderEmit.CEP }} + {{ emit.enderEmit.cPais }} + {{ emit.enderEmit.xPais }} + {{ emit.enderEmit.fone }} + + {{ emit.IE }} + {{ emit.CRT }} + {% endwith %} + + + {% with dest = NFe.infNFe.dest %} + {% if dest.tipo == 'person' -%} + {{ dest.cnpj_cpf }} + {% endif %} + {% if dest.tipo == 'company' -%} + {{ dest.cnpj_cpf }} + {% endif %} + {{ dest.xNome }} + + {{ dest.enderDest.xLgr }} + {{ dest.enderDest.nro }} + {{ dest.enderDest.xBairro }} + {{ dest.enderDest.cMun }} + {{ dest.enderDest.xMun }} + {{ dest.enderDest.UF }} + {{ dest.enderDest.CEP }} + {{ dest.enderDest.cPais }} + {{ dest.enderDest.xPais }} + {{ dest.enderDest.fone }} + + {{ dest.indIEDest }} + {% if dest.IE != '' -%}{{ dest.IE }}{% endif %} + {% endwith %} + + {% for det in NFe.infNFe.detalhes %} + + + {% with prod = det.prod %} + {{ prod.cProd }} + {{ prod.cEAN }} + {{ prod.xProd }} + {{ prod.NCM }} + {{ prod.CFOP }} + {{ prod.uCom }} + {{ prod.qCom }} + {{ prod.vUnCom }} + {{ prod.vProd }} + {{ prod.cEANTrib }} + {{ prod.uTrib }} + {{ prod.qTrib }} + {{ prod.vUnTrib }} + {{ prod.indTot }} + {% endwith %} + + + {% with imposto = det.imposto %} + {{ imposto.vTotTrib }} + + + {{ imposto.ICMS.ICMS00.orig }} + {{ imposto.ICMS.ICMS00.CST }} + {{ imposto.ICMS.ICMS00.modBC }} + {{ imposto.ICMS.ICMS00.vBC }} + {{ imposto.ICMS.ICMS00.pICMS }} + {{ imposto.ICMS.ICMS00.vICMS }} + + + + {{ imposto.IPI.cEnq }} + + {{ imposto.IPI.IPITrib.CST }} + {{ imposto.IPI.IPITrib.vBC }} + {{ imposto.IPI.IPITrib.pIPI }} + {{ imposto.IPI.IPITrib.vIPI }} + + + + + {{ imposto.PIS.PISAliq.CST }} + {{ imposto.PIS.PISAliq.vBC }} + {{ imposto.PIS.PISAliq.pPIS }} + {{ imposto.PIS.PISAliq.vPIS }} + + + + + {{ imposto.COFINS.COFINSAliq.CST }} + {{ imposto.COFINS.COFINSAliq.vBC }} + {{ imposto.COFINS.COFINSAliq.pCOFINS }} + {{ imposto.COFINS.COFINSAliq.vCOFINS }} + + + {% endwith %} + + + {% endfor %} + + {% with total = NFe.infNFe.total %} + + {{ total.vBC }} + {{ total.vICMS }} + {{ total.vICMSDeson }} + {{ total.vBCST }} + {{ total.vST }} + {{ total.vProd }} + {{ total.vFrete }} + {{ total.vSeg }} + {{ total.vDesc }} + {{ total.vII }} + {{ total.vIPI }} + {{ total.vPIS }} + {{ total.vCOFINS }} + {{ total.vOutro }} + {{ total.vNF }} + {{ total.vTotTrib }} + + {% endwith %} + + + {{ NFe.infNFe.transp.modFrete }} + + + + 339/1 + 2016-06-02 + 8611.76 + + + + {{ NFe.infNFe.infAdic.infCpl }} + + + + {% endfor %} + diff --git a/pytrustnfe/nfe/templates/NfeConsultaCadastro.xml b/pytrustnfe/nfe/templates/NfeConsultaCadastro.xml new file mode 100644 index 0000000..bc1f9fb --- /dev/null +++ b/pytrustnfe/nfe/templates/NfeConsultaCadastro.xml @@ -0,0 +1,8 @@ + + + + CONS-CAD + {{ obj.estado }} + {{ obj.cnpj }} + + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/NfeConsultaDest.xml b/pytrustnfe/nfe/templates/NfeConsultaDest.xml new file mode 100644 index 0000000..0cd2082 --- /dev/null +++ b/pytrustnfe/nfe/templates/NfeConsultaDest.xml @@ -0,0 +1,8 @@ + + {{ obj.ambiente }} + CONSULTAR NFE DEST + {{ obj.cnpj }} + {{ obj.indicador_nfe }} + {{ obj.indicador_emissor }} + {{ obj.ultimo_nsu }} + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/NfeConsultaProtocolo.xml b/pytrustnfe/nfe/templates/NfeConsultaProtocolo.xml new file mode 100644 index 0000000..0156d9e --- /dev/null +++ b/pytrustnfe/nfe/templates/NfeConsultaProtocolo.xml @@ -0,0 +1,6 @@ + + + {{ obj.ambiente }} + CONSULTAR + {{ obj.chave_nfe }} + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/NfeDownloadNF.xml b/pytrustnfe/nfe/templates/NfeDownloadNF.xml new file mode 100644 index 0000000..70f837d --- /dev/null +++ b/pytrustnfe/nfe/templates/NfeDownloadNF.xml @@ -0,0 +1,6 @@ + + {{ obj.ambiente }} + DOWNLOAD NFE + {{ obj.cnpj }} + {{ obj.chave_nfe }} + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/NfeInutilizacao.xml b/pytrustnfe/nfe/templates/NfeInutilizacao.xml new file mode 100644 index 0000000..c655721 --- /dev/null +++ b/pytrustnfe/nfe/templates/NfeInutilizacao.xml @@ -0,0 +1,15 @@ + + + + {{ obj.ambiente }} + INUTILIZAR + {{ obj.estado }} + {{ obj.ano }} + {{ obj.cnpj }} + {{ obj.modelo }} + {{ obj.serie }} + {{ obj.numero_inicio}} + {{ obj.numero_fim }} + {{ obj.justificativa }} + + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/NfeRetAutorizacao.xml b/pytrustnfe/nfe/templates/NfeRetAutorizacao.xml new file mode 100644 index 0000000..d248162 --- /dev/null +++ b/pytrustnfe/nfe/templates/NfeRetAutorizacao.xml @@ -0,0 +1,5 @@ + + + {{ obj.ambiente }} + {{ obj.numero_recibo }} + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/NfeStatusServico.xml b/pytrustnfe/nfe/templates/NfeStatusServico.xml new file mode 100644 index 0000000..1d41a30 --- /dev/null +++ b/pytrustnfe/nfe/templates/NfeStatusServico.xml @@ -0,0 +1,6 @@ + + + {{ obj.ambiente }} + {{ obj.estado }} + STATUS + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/RecepcaoEventoCancelamento.xml b/pytrustnfe/nfe/templates/RecepcaoEventoCancelamento.xml new file mode 100644 index 0000000..91ed2a9 --- /dev/null +++ b/pytrustnfe/nfe/templates/RecepcaoEventoCancelamento.xml @@ -0,0 +1,20 @@ + + {{ obj.lote }} + + + {{ obj.orgao }} + {{ obj.ambiente }} + {{ obj.cnpj }} + {{ obj.chave_nfe }} + {{ obj.data_hora_evento }} + 110111 + {{ obj.numero_evento }} + 1.00 + + Cancelamento + {{ obj.protocolo }} + {{obj.justificativa }} + + + + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/RecepcaoEventoCarta.xml b/pytrustnfe/nfe/templates/RecepcaoEventoCarta.xml new file mode 100644 index 0000000..f409e4a --- /dev/null +++ b/pytrustnfe/nfe/templates/RecepcaoEventoCarta.xml @@ -0,0 +1,21 @@ + + + 00000001319901 + + + {{ obj.orgao }} + {{ obj.ambiente }} + {{ obj.cnpj }} + {{ obj.chave_nfe }} + {{} obj.data_hora_evento } + 110110 + {{ obj.sequencia }} + 1.00 + + Carta de Correção + {{ obj.correcao }} + A Carta de Correção é disciplinada pelo § 1º-A do art. 7º do Convênio S/N, de 15 de dezembro de 1970 e pode ser utilizada para regularização de erro ocorrido na emissão de documento fiscal, desde que o erro não esteja relacionado com: I - as variáveis que determinam o valor do imposto tais como: base de cálculo, alíquota, diferença de preço, quantidade, valor da operação ou da prestação; II - a correção de dados cadastrais que implique mudança do remetente ou do destinatário; III - a data de emissão ou de saída. + + + + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/RecepcaoEventoEPEC.xml b/pytrustnfe/nfe/templates/RecepcaoEventoEPEC.xml new file mode 100644 index 0000000..12a8478 --- /dev/null +++ b/pytrustnfe/nfe/templates/RecepcaoEventoEPEC.xml @@ -0,0 +1,31 @@ + + 00106151340701 + + + 91 + 2 + 10142785000190 + 35140810142785000190550010010615134079599952 + 2014-08-07T04:52:51-03:00 + 110140 + 1 + 1.00 + + EPEC + 35 + 1 + 1.26 + 2014-08-07T00:00:00-03:00 + 1 + 495171423115 + + SP + 00000000191 + 86.00 + 6.02 + 0 + + + + + \ No newline at end of file diff --git a/pytrustnfe/nfe/templates/RecepcaoEventoManifesto.xml b/pytrustnfe/nfe/templates/RecepcaoEventoManifesto.xml new file mode 100644 index 0000000..d9d18a3 --- /dev/null +++ b/pytrustnfe/nfe/templates/RecepcaoEventoManifesto.xml @@ -0,0 +1,18 @@ + + {{ obj.lote }} + + + {{ obj.orgao }} + {{ obj.ambiente }} + {{ obj.cnpj }} + {{ obj.chave_nfe }} + {{ obj.data_hora_evento }} + 210200 + {{ obj.sequencia }} + 1.00 + + Confirmacao da Operacao + + + + \ No newline at end of file diff --git a/pytrustnfe/utils.py b/pytrustnfe/utils.py index d6b5f4c..9abd251 100644 --- a/pytrustnfe/utils.py +++ b/pytrustnfe/utils.py @@ -5,6 +5,12 @@ from datetime import date, datetime +class CabecalhoSoap(object): + + def __init__(self, **kwargs): + self.estado = kwargs.pop('estado', '') + self.soap_action = kwargs.pop('soap_action', '') + class ChaveNFe(object): diff --git a/pytrustnfe/xml/consultar_cadastro.xml b/pytrustnfe/xml/consultar_cadastro.xml deleted file mode 100644 index e69de29..0000000