diff --git a/pynfe/entidades/notafiscal.py b/pynfe/entidades/notafiscal.py index 62db290..8af29f7 100644 --- a/pynfe/entidades/notafiscal.py +++ b/pynfe/entidades/notafiscal.py @@ -58,8 +58,8 @@ class NotaFiscal(Entidade): # - Forma de pagamento (obrigatorio - seleciona de lista) - NF_FORMAS_PAGAMENTO forma_pagamento = int() - # - Tipo de pagamento - # 01=Dinheiro 02=Cheque 03=Cartão de Crédito 04=Cartão de Débito 05=Crédito Loja 10=Vale Alimentação 11=Vale Refeição 12=Vale Presente 13=Vale Combustível 99=Outros + # - Tipo de pagamento + # 01=Dinheiro 02=Cheque 03=Cartão de Crédito 04=Cartão de Débito 05=Crédito Loja 10=Vale Alimentação 11=Vale Refeição 12=Vale Presente 13=Vale Combustível 99=Outros tipo_pagamento = int() # - Forma de emissao (obrigatorio - seleciona de lista) - NF_FORMAS_EMISSAO @@ -398,7 +398,7 @@ class NotaFiscal(Entidade): self.dv_codigo_numerico_aleatorio = '0' return '0' self.dv_codigo_numerico_aleatorio = str(11 - remainder) - return str(self.dv_codigo_numerico_aleatorio) + return str(self.dv_codigo_numerico_aleatorio) @property # @memoize @@ -906,9 +906,7 @@ class NotaFiscalEntregaRetirada(Entidade): endereco_telefone = str() class NotaFiscalServico(Entidade): - - # Empresa que implementa o webservice - autorizador = str() # betha + # id do rps identificador = str() # tag competencia @@ -934,4 +932,3 @@ class NotaFiscalServico(Entidade): def __str__(self): return ' '.join([str(self.identificador)]) - diff --git a/pynfe/processamento/autorizador_nfse.py b/pynfe/processamento/autorizador_nfse.py index 8fea396..8390b96 100644 --- a/pynfe/processamento/autorizador_nfse.py +++ b/pynfe/processamento/autorizador_nfse.py @@ -1,6 +1,8 @@ +import ipdb from pyxb import BIND from importlib import import_module - +# import pynfe.utils.nfse.ginfes.servico_enviar_lote_rps_envio_v03 as servico_enviar_lote_rps_envio_v03 +# import pynfe.utils.nfse.ginfes._tipos as _tipos class InterfaceAutorizador(): #TODO Colocar raise Exception Not Implemented nos metodos @@ -10,9 +12,6 @@ class InterfaceAutorizador(): def cancelar(self): pass - def serializar_lote_sincrono(self): - pass - class SerializacaoBetha(InterfaceAutorizador): def __init__(self): @@ -243,9 +242,11 @@ class SerializacaoBetha(InterfaceAutorizador): class SerializacaoGinfes(InterfaceAutorizador): def __init__(self): # importa - global _tipos, servico_consultar_nfse_envio_v03, cabecalho_v03 + global _tipos, servico_consultar_nfse_envio_v03 + global servico_enviar_lote_rps_envio_v03, cabecalho_v03 _tipos = import_module('pynfe.utils.nfse.ginfes._tipos') servico_consultar_nfse_envio_v03 = import_module('pynfe.utils.nfse.ginfes.servico_consultar_nfse_envio_v03') + servico_enviar_lote_rps_envio_v03 = import_module('pynfe.utils.nfse.ginfes.servico_enviar_lote_rps_envio_v03') cabecalho_v03 = import_module('pynfe.utils.nfse.ginfes.cabecalho_v03') def consultar_rps(self, nfse): @@ -290,9 +291,85 @@ class SerializacaoGinfes(InterfaceAutorizador): return consulta.toxml(element_name='ns1:ConsultarNfseEnvio') + def serializar_lote_assincrono(self, nfse): + "Serializa lote de envio, baseado no servico_enviar_lote_rps_envio_v03.xsd" + + servico = _tipos.tcDadosServico() + valores_servico = _tipos.tcValores() + valores_servico.ValorServicos = nfse.servico.valor_servico + valores_servico.IssRetido = nfse.servico.iss_retido + + servico.Valores = valores_servico + servico.ItemListaServico = nfse.servico.item_lista + ## dois campos opcionais aqui no meio se der errado # TODO retirar + servico.Discriminacao = nfse.servico.discriminacao + servico.CodigoMunicipio = nfse.servico.codigo_municipio + + # endereco tomador + endereco_tomador = _tipos.tcEndereco() + endereco_tomador.Endereco = nfse.cliente.endereco_logradouro + endereco_tomador.Numero = nfse.cliente.endereco_numero + endereco_tomador.Bairro = nfse.cliente.endereco_bairro + endereco_tomador.CodigoMunicipio = nfse.cliente.endereco_cod_municipio + endereco_tomador.Uf = nfse.cliente.endereco_uf + endereco_tomador.Cep = nfse.cliente.endereco_cep + # identificacao Tomador + id_tomador = _tipos.tcIdentificacaoTomador() + id_tomador.CpfCnpj = nfse.cliente.numero_documento + if nfse.cliente.inscricao_municipal: + id_tomador.InscricaoMunicipal = nfse.cliente.inscricao_municipal + # Tomador + tomador = _tipos.tcDadosTomador() + tomador.IdentificacaoTomador = id_tomador + tomador.RazaoSocial = nfse.cliente.razao_social + tomador.Endereco = endereco_tomador + + # Prestador + id_prestador = _tipos.tcIdentificacaoPrestador() + id_prestador.Cnpj = nfse.emitente.cnpj + id_prestador.InscricaoMunicipal = nfse.emitente.inscricao_municipal + + # identificacao rps + id_rps = _tipos.tcIdentificacaoRps() + id_rps.Numero = nfse.identificador + id_rps.Serie = nfse.serie + id_rps.Tipo = nfse.tipo + # inf rps + inf_rps = _tipos.tcInfRps() + inf_rps.IdentificacaoRps = id_rps + inf_rps.DataEmissao = nfse.data_emissao.strftime('%Y-%m-%dT%H:%M:%S') + inf_rps.NaturezaOperacao = 1 # tributacao no municipio + inf_rps.RegimeEspecialTributacao = None # opcional + inf_rps.OptanteSimplesNacional = nfse.simples + inf_rps.IncentivadorCultural = 2 # Nao + inf_rps.Status = 1 + inf_rps.RpsSubstituido = None # opcional + inf_rps.Servico = servico + inf_rps.Prestador = id_prestador + inf_rps.Tomador = tomador + inf_rps.IntermediarioServico = None # opcional + inf_rps.ConstrucaoCivil = None # opcional + inf_rps.Id = nfse.identificador + + rps = _tipos.tcRps() + rps.InfRps = inf_rps + + lote = _tipos.tcLoteRps() + lote.NumeroLote = 1 + lote.Id = 1 + lote.Cnpj = nfse.emitente.cnpj + lote.InscricaoMunicipal = nfse.emitente.inscricao_municipal + lote.QuantidadeRps = 1 + lote.ListaRps = BIND() + lote.ListaRps.append(rps) + + enviarLote = servico_enviar_lote_rps_envio_v03.EnviarLoteRpsEnvio() + enviarLote.LoteRps = lote + return enviarLote.toxml("UTF-8", element_name='ns1:EnviarLoteRpsEnvio') + def cabecalho(self): # info cabecalho = cabecalho_v03.cabecalho() cabecalho.versao = '3' cabecalho.versaoDados = '3' - return cabecalho.toxml(element_name='cabecalho') \ No newline at end of file + return cabecalho.toxml(element_name='cabecalho') diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 5bf1e03..758909e 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -601,6 +601,13 @@ class SerializacaoNfse(object): else: raise Exception('Este método só esta implementado no autorizador Betha.') + def gerar_lote(self, nfse): + if self.autorizador.lower() == 'ginfes': + from pynfe.processamento.autorizador_nfse import SerializacaoGinfes + return SerializacaoGinfes().serializar_lote_assincrono(nfse) + else: + raise Exception('Este método só esta implementado no autorizador ginfes.') + def consultar_nfse(self, emitente, numero=None, inicio=None, fim=None): if self.autorizador.lower() == 'ginfes': from pynfe.processamento.autorizador_nfse import SerializacaoGinfes diff --git a/pynfe/utils/nfse/ginfes/servico_enviar_lote_rps_envio_v03.py b/pynfe/utils/nfse/ginfes/servico_enviar_lote_rps_envio_v03.py index a74af2d..ab48ff5 100644 --- a/pynfe/utils/nfse/ginfes/servico_enviar_lote_rps_envio_v03.py +++ b/pynfe/utils/nfse/ginfes/servico_enviar_lote_rps_envio_v03.py @@ -24,8 +24,8 @@ if pyxb.__version__ != _PyXBVersion: raise pyxb.PyXBVersionError(_PyXBVersion) # Import bindings for namespaces imported into schema -import _tipos as _ImportedBinding__tipos -import _dsig as _ImportedBinding__dsig +from pynfe.utils.nfse.ginfes import _tipos as _ImportedBinding__tipos +from pynfe.utils.nfse.ginfes import _dsig as _ImportedBinding__dsig import pyxb.binding.datatypes # NOTE: All namespace declarations are reserved within the binding @@ -88,18 +88,18 @@ class CTD_ANON (pyxb.binding.basis.complexTypeDefinition): _ElementMap = {} _AttributeMap = {} # Base type is pyxb.binding.datatypes.anyType - + # Element {http://www.ginfes.com.br/servico_enviar_lote_rps_envio_v03.xsd}LoteRps uses Python identifier LoteRps __LoteRps = pyxb.binding.content.ElementDeclaration(pyxb.namespace.ExpandedName(Namespace, 'LoteRps'), 'LoteRps', '__httpwww_ginfes_com_brservico_enviar_lote_rps_envio_v03_xsd_CTD_ANON_httpwww_ginfes_com_brservico_enviar_lote_rps_envio_v03_xsdLoteRps', False, pyxb.utils.utility.Location('/home/leonardo/Downloads/xsd ginfes/servico_enviar_lote_rps_envio_v03.xsd', 9, 4), ) - + LoteRps = property(__LoteRps.value, __LoteRps.set, None, None) - + # Element {http://www.w3.org/2000/09/xmldsig#}Signature uses Python identifier Signature __Signature = pyxb.binding.content.ElementDeclaration(pyxb.namespace.ExpandedName(_Namespace_dsig, 'Signature'), 'Signature', '__httpwww_ginfes_com_brservico_enviar_lote_rps_envio_v03_xsd_CTD_ANON_httpwww_w3_org200009xmldsigSignature', False, pyxb.utils.utility.Location('/home/leonardo/Downloads/xsd ginfes/xmldsig-core-schema20020212_v03.xsd', 41, 0), ) - + Signature = property(__Signature.value, __Signature.set, None, None) _ElementMap.update({ @@ -107,7 +107,7 @@ class CTD_ANON (pyxb.binding.basis.complexTypeDefinition): __Signature.name() : __Signature }) _AttributeMap.update({ - + }) @@ -150,4 +150,3 @@ def _BuildAutomaton (): st_1._set_transitionSet(transitions) return fac.Automaton(states, counters, False, containing_state=None) CTD_ANON._Automaton = _BuildAutomaton() -