TadaSoftware / PyNFe

Projeto de biblioteca para fazer interface com o webservice de Nota Fiscal eletrônica para Python, disponível sob LGPL.
http://groups.google.com/group/pynfe
Other
423 stars 173 forks source link

Gerar o grupo de informações de Cobrança <cob></cobr> #350

Open asjsandro opened 3 months ago

asjsandro commented 3 months ago

Não estou conseguindo gerar o grupo de informçaões de cobrança da Nota fiscal (Parcelas).

Exemplo do grupo de tags que precisa conter no XML image

Já tentei de várias formas mas não consigo gerar as informações do grupo de tags

emitente = Emitente(
            razao_social='EMITENTE TESTE',
            nome_fantasia='TESTE EMITENTE',
            cnpj='99999999999999',           # cnpj apenas números
            codigo_de_regime_tributario='1', # 1 para simples nacional ou 3 para normal
            inscricao_estadual='999999999', # numero de IE da empresa
            inscricao_municipal='',
            cnae_fiscal='9999999',           # cnae apenas números
            endereco_logradouro='RUA A ',
            endereco_numero='121',
            endereco_bairro='ENDEREÇO TESTE',
            endereco_municipio='SALVADOR',
            endereco_uf='BA',
            endereco_cep='42000000',
            endereco_pais=CODIGO_BRASIL
            )

            #dados do Cliente:
            cliente = Cliente(
            razao_social='NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL',
            tipo_documento = 'CNPJ', #dadosCliente[0]['tipo_documento'], 
            email = 'email@email.com.br', 
            numero_documento = dadosCliente[0]['numero_documento'], 
            indicador_ie = '1',
            inscricao_estadual = '99999999',
            endereco_logradouro = 'ENDERECO TESTE', 
            endereco_numero = '999',  
            endereco_complemento = 'Complemento Endereço',
            endereco_bairro = 'Salvador, 
            endereco_municipio = 'Bahia', 
            endereco_uf = 'BA', 
            endereco_cep = '42000000', 
            endereco_pais = CODIGO_BRASIL,
            endereco_telefone = '7199999999'
            )
            parcelas = retParcelamentoNota(numeroNfe,registroAtual, registroFinal)

            dadosNfe = retornaDadosNfe(registroAtual, registroFinal)

            # Dados da NFE
            nota_fiscal = NotaFiscal(
            emitente=emitente,
            cliente=cliente,
            uf=uf.upper(),
            natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc
            forma_pagamento=2,  # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros.
            tipo_pagamento=14,
            modelo=55,                 # 55=NF-e; 65=NFC-e
            serie='1',
            numero_nf = numeroNfe,           # Número do Documento Fiscal.
            data_emissao=datetime.now(),
            data_saida_entrada=datetime.now(),
            tipo_documento=1,          # 0=entrada; 1=saida
            municipio='2905701',       # Código IBGE do Município 
            tipo_impressao_danfe=1,    # 0=Sem geração de DANFE;1=DANFE normal, Retrato;2=DANFE normal Paisagem;3=DANFE Simplificado;4=DANFE NFC-e;
            forma_emissao='1',         # 1=Emissão normal (não em contingência);
            cliente_final=1,           # 0=Normal;1=Consumidor final;
            indicador_destino=1,
            indicador_presencial=1,
            finalidade_emissao='1',    # 1=NF-e normal;2=NF-e complementar;3=NF-e de ajuste;4=Devolução de mercadoria.
            processo_emissao='0',      #0=Emissão de NF-e com aplicativo do contribuinte;
            transporte_modalidade_frete=1,
            informacoes_adicionais_interesse_fisco='NF-e Venda Loja Lirios FSA para Armazem Cosméticos',
            totais_tributos_aproximado=Decimal("{:.2f}".format(dadosNfe[0]['totais_tributos_aproximado'])),
            pagamentos=[1,2]
            )

            # Preenchendo os Itens da nFE
            qtdItem = 0
            itens = retItensNotaFiscal(registroAtual, registroFinal)

            for item in itens:
                nota_fiscal.adicionar_produto_servico(
                    codigo=item['Controle'],         #'2034',                           # id do produto
                    descricao=item['Descricao'],    #'LAPIS PRETO COM APONTADOR COD. 2034 VIVAI  PC/ COM 12',
                    ncm=item['CodIpi'],             #'33049100',
                    #cest='0100100',                # NT2015/003
                    cfop='5102',
                    unidade_comercial=item['unidade'],                          #'UN',
                    ean = item['EAN'] ,          #'7899956862304',
                    ean_tributavel=item['ean_tributavel'],                      #'7899956862304',
                    quantidade_comercial=Decimal("{:.2f}".format(item['Quantidade'])), #Decimal('12'),        # 12 unidades
                    valor_unitario_comercial=Decimal("{:.2f}".format(item['Vlr Unitario'])), # Decimal('9.75'),  # preço unitário
                    valor_total_bruto=Decimal("{:.2f}".format(item['Total'])), #Decimal('117.00'),       # preço total
                    unidade_tributavel=item['unidade'],#'UN',
                    quantidade_tributavel=Decimal("{:.2f}".format(item['Quantidade'])), #Decimal('12'),
                    valor_unitario_tributavel=Decimal("{:.2f}".format(item['Vlr Unitario'])), #Decimal('9.75'),
                    ind_total=1,
                    # numero_pedido='12345',                   # xPed
                    # numero_item='123456',                    # nItemPed
                    icms_modalidade='102',
                    icms_origem=item['icms_origem'],                                    #0,
                    icms_csosn=item['CST'],                                             #'400',
                    pis_modalidade=item['pis_modalidade'],                              #'07',
                    cofins_modalidade=item['cofins_modalidade'],                        #'07',
                    valor_tributos_aprox=Decimal("{:.2f}".format(item['Total']))        #'21.06'
                    )
                qtdItem += 1

            # Preenchendo os dados de Resp. Técnico do sistema
            nota_fiscal.adicionar_responsavel_tecnico(
            cnpj='47672512000168',
            contato='Asjsandro',
            email='asjsandro@gmail.com',
            fone='71999081709'
            )

            #Preenchendo a tag de Parcelas 
            nota_fiscal.adicionar_duplicata(
                numero = str(parcelas[0]['Doc/Pedido']).zfill(10),
                data_vencimento = parcelas[0]['Doc/Pedido'],
                valor = Decimal("{:.2f}".format(parcelas[0]['Doc/Pedido']))
            )

            nota_fiscal.adicionar_pagamento(
                t_pag = '15',
                x_pag = 'BOLETO BANCARIO',
                v_pag = Decimal("{:.2f}".format(parcelas[0]['Valor R$'])),
                tp_integra = '2',
                ind_pag = 1
            )
            # Preenchendo a tag de Auroziradores para baixar o XML
            autxml_lista = ['13937073000156',#SEFAZ-BA
                            '47672512000168', #Emitente
                            '92683886500'] #Destinatário

            for index, item in enumerate(autxml_lista, 1):
                nota_fiscal.adicionar_autorizados_baixar_xml(CPFCNPJ=item)

            # serialização
            serializador = SerializacaoXML(_fonte_dados, homologacao=homologacao)
            nfe = serializador.exportar()

            # assinatura
            a1 = AssinaturaA1(certificado, senha)
            xml = a1.assinar(nfe)
            conSefaz = ComunicacaoSefaz(uf, certificado, senha, homologacao)
            envio = conSefaz.autorizacao(modelo='nfe', nota_fiscal=xml, ind_sinc=0) #retorna uma tupla com o código do retorno (0,1) o numero do recibo e o XML Enviado

             # Obtendo o retorno do envio da NFE para a Sefaz.
            if envio[0] == 0:
                print(f'NF-e: {numeroNfe} Enviada com Sucesso Sucesso!')
                print('Aguardando 20s para consultar a NFe na Sefaz')
                print(f'Numero do Recibo/Protocolo: {envio[1]}')

                # Contagem Regressiva de 20s
                for contagem in range(20,0,-1):
                    print(f"\b\b\b{contagem}", end="", flush=True)
                    time.sleep(1)
                print('')

                response = conSefaz.consulta_recibo(modelo='nfe', numero=envio[1]) # nfe ou nfce
                infProt = response.text
                ns = {'ns':NAMESPACE_NFE}

                retRecibo = etree.fromstring(response.text.encode('utf-8')) # SEFAZ SP utilizar envio.content
                statusLote = retRecibo[0][0].xpath('ns:retConsReciNFe/ns:cStat', namespaces=ns)[0].text
                motivoLote = retRecibo[0][0].xpath('ns:retConsReciNFe/ns:xMotivo', namespaces=ns)[0].text

                if statusLote == '104':
                    print(f'Lote Processado!')
                    print(80 * '-')
                    print('Status Lote: ', statusLote)
                    print('Motivo Lote: ', motivoLote)
                    print(80 * '-')

                    chNFe = retRecibo[0][0].xpath('ns:retConsReciNFe/ns:protNFe/ns:infProt/ns:chNFe', namespaces=ns)[0].text
                    statusNfe = retRecibo[0][0].xpath('ns:retConsReciNFe/ns:protNFe/ns:infProt/ns:cStat', namespaces=ns)[0].text
                    prot_nfe = retRecibo[0][0].xpath('ns:retConsReciNFe/ns:protNFe/ns:infProt/ns:nProt', namespaces=ns)[0].text
                    xMotivo_nfe = retRecibo[0][0].xpath('ns:retConsReciNFe/ns:protNFe/ns:infProt/ns:xMotivo', namespaces=ns)[0].text
                    if statusNfe == '100':
                        print(f'Nota fiscal Autorizada')
                        print(80 * '-')
                        print('Status NFe: ', statusNfe)
                        print('Motivo: ', xMotivo_nfe)
                        print('Protocolo: ', prot_nfe)
                        print('Chave Nfe: ', chNFe)
                        print(80 * '-')
                        infnfe = etree.tostring(envio[2])
                        raiz = etree.Element('nfeProc', xmlns=NAMESPACE_NFE, versao=VERSAO_PADRAO)
                        aut = infProt[infProt.find('<protNFe'):infProt.find('</protNFe>') + 10]
                        raiz.append(etree.fromstring(infnfe))
                        raiz.append(etree.fromstring(aut))
                        xxx = etree.tostring(raiz)
                        xxx = xxx.decode("utf-8")
                        tree = ET.XML(etree.tostring(envio[2]))
                        filename = datetime.now().strftime(f"Nfe-{numeroNfe}_AUTORIZADA_%d%m%Y"+"-"+"%H%M%S")+'.xml'
                        folder = r'./xmls/'
                        with open(folder + filename, "wb") as f:
                            print('Salvando arquivo XML no diretório /xmls/')
                            f.write(str(xxx).encode())
                            print(f'Arquivo: {filename} salvo com Sucesso! - {qtdItem} Itens')
                    else:
                        print(80 * '-')
                        print(f'NFe REJEITADA!!!')
                        print('Status NFe: ', statusNfe)
                        print('Motivo: ', xMotivo_nfe)
                        print('Protocolo: ', prot_nfe)
                        print('Chave Nfe: ', chNFe)
                        print(80 * '-')
                        infnfe = etree.tostring(envio[2])
                        raiz = etree.Element('nfeProc', xmlns=NAMESPACE_NFE, versao=VERSAO_PADRAO)
                        aut = infProt[infProt.find('<protNFe'):infProt.find('</protNFe>') + 10]
                        raiz.append(etree.fromstring(infnfe))
                        raiz.append(etree.fromstring(aut))
                        xxx = etree.tostring(raiz)
                        xxx = xxx.decode("utf-8")
                        tree = ET.XML(etree.tostring(envio[2]))
                        filename = datetime.now().strftime(f"Nfe-{numeroNfe}_REJEITADA_%d%m%Y"+"-"+"%H%M%S")+'.xml'
                        folder = r'./xmls/'
                        with open(folder + filename, "wb") as f:
                            print('Salvando arquivo XML no diretório /xmls/')
                            f.write(str(xxx).encode())
                            print(f'Arquivo: {filename} salvo com Sucesso! - {qtdItem} Itens')
                        (80 * '-')
                else:
                    print(80 * '-')
                    print(f'Nfe: {numeroNfe} NÃO AUTORIZADA!')
                    infnfe = etree.tostring(envio[2])
                    raiz = etree.Element('nfeProc', xmlns=NAMESPACE_NFE, versao=VERSAO_PADRAO)
                    aut = retRecibo[retRecibo.find('<protNFe'):retRecibo.find('</protNFe>') + 10]
                    raiz.append(etree.fromstring(infnfe))
                    raiz.append(etree.fromstring(aut))
                    xxx = etree.tostring(raiz)
                    xxx = xxx.decode("utf-8")
                    tree = ET.XML(etree.tostring(envio[2]))
                    filename = datetime.now().strftime(f"Nfe-{numeroNfe}- NAO_AUTORIZADA_%d%m%Y"+"-"+"%H%M%S")+'.xml'
                    folder = r'./xmls/'
                    with open(folder + filename, "wb") as f:
                        print('Salvando arquivo XML no diretório /xmls/')
                        f.write(str(xxx).encode())
                        print(f'Arquivo: {filename} salvo com Sucesso! - {qtdItem} Itens')
                    print(80 * '-')
            else:
                print('-' * 80)
                print(f'Nfe: {numeroNfe} não processada')
                print('Erro no Envio!!!')
                print(envio[1].text) # resposta
                print('Retorno:')
                print(etree.tostring(envio[2], encoding="unicode")) # nfe
                print('-' * 80)

            registroAtual += registroPorVez
            registroFinal += registroPorVez
            numeroNfe += 1
            input('Press Any key for continue!')
        else:
            print('Notas geradas com sucesso!')
            print('Programa Finalizado!!!!!')
G3nilson commented 1 month ago

Também estou com este problema, conseguiu resolver @asjsandro?

leogregianin commented 1 week ago

É necessário implementar o grupo de informações de cobrança com faturas e duplicatas.

felps-dev commented 5 days ago

Temos os métodos mas infelizmente ainda não foi implementado a serialização dos grupos no serializacao.py