From defbf8d32f183f2c76b2a35d1b6da95180bfc7a4 Mon Sep 17 00:00:00 2001 From: Roberto Godinho Date: Wed, 20 Dec 2023 11:45:34 -0300 Subject: [PATCH 1/6] =?UTF-8?q?ADD:=20metodos=20de=20formata=C3=A7=C3=A3o?= =?UTF-8?q?=20de=20Decimais=20ADD:=20`xml=5Fwriter.py`=20-=20responsavel?= =?UTF-8?q?=20por=20gerar=20as=20TAG's=20do=20XML=20ADD:=20Adicionado=20li?= =?UTF-8?q?sta=20de=20`pagamentos`=20=C3=A0=20classe=20NotaFiscal,=20remov?= =?UTF-8?q?ido=20campo=20`tipo=5Fpagamento`=20ADD:=20Serializa=C3=A7=C3=A3?= =?UTF-8?q?o=20do=20grupo=20de=20pagamentos=20TEST:=20`test=5Fnfce=5Fseria?= =?UTF-8?q?lizacao.py`=20-=20adicionado=20valida=C3=A7=C3=A3o=20do=20total?= =?UTF-8?q?=20pago.=20(vPag-vTroco=20=3D=20vNF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit issue: #317 --- pynfe/entidades/notafiscal.py | 50 ++++++++----- pynfe/processamento/serializacao.py | 72 +++++++++--------- pynfe/utils/__init__.py | 65 ++++++++++++++++ pynfe/utils/xml_writer.py | 82 +++++++++++++++++++++ tests/test_nfce_serializacao.py | 15 +++- tests/test_nfce_serializacao_sem_cliente.py | 4 +- tests/test_nfce_serializacao_somente_cpf.py | 4 +- tests/test_nfe_serializacao_csosn_101.py | 4 +- tests/test_nfe_serializacao_csosn_102.py | 3 +- tests/test_nfe_serializacao_csosn_103.py | 3 +- tests/test_nfe_serializacao_csosn_201.py | 4 +- tests/test_nfe_serializacao_csosn_202.py | 6 +- tests/test_nfe_serializacao_csosn_203.py | 3 +- tests/test_nfe_serializacao_csosn_300.py | 3 +- tests/test_nfe_serializacao_csosn_400.py | 3 +- tests/test_nfe_serializacao_csosn_500.py | 3 +- tests/test_nfe_serializacao_csosn_900.py | 3 +- tests/test_nfe_serializacao_cst_00.py | 3 +- tests/test_nfe_serializacao_cst_10.py | 3 +- tests/test_nfe_serializacao_cst_20.py | 3 +- tests/test_nfe_serializacao_cst_30.py | 3 +- tests/test_nfe_serializacao_cst_40.py | 3 +- tests/test_nfe_serializacao_cst_41.py | 3 +- tests/test_nfe_serializacao_cst_50.py | 3 +- tests/test_nfe_serializacao_cst_51.py | 3 +- tests/test_nfe_serializacao_cst_60.py | 3 +- tests/test_nfe_serializacao_cst_70.py | 10 ++- tests/test_nfe_serializacao_cst_90.py | 17 ++++- tests/test_nfe_serializacao_geral.py | 19 ++++- tests/test_nfe_serializacao_ii_di_ipi.py | 10 ++- 30 files changed, 329 insertions(+), 81 deletions(-) create mode 100644 pynfe/utils/xml_writer.py diff --git a/pynfe/entidades/notafiscal.py b/pynfe/entidades/notafiscal.py index 0e07869b..ecd5ed08 100644 --- a/pynfe/entidades/notafiscal.py +++ b/pynfe/entidades/notafiscal.py @@ -55,26 +55,6 @@ class NotaFiscal(Entidade): # Removido na NF-e 4.00 # forma_pagamento = int() - # - Tipo de pagamento - """ - Obrigatório o preenchimento do Grupo Informações de Pagamento para NF-e e NFC-e. - Para as notas com finalidade de Ajuste ou Devolução o campo Forma de Pagamento - deve ser preenchido com 90=Sem 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 - 14=Duplicata Mercantil - 90= Sem pagamento - 99=Outros - """ - tipo_pagamento = int() - # - Forma de emissao (obrigatorio - seleciona de lista) - NF_FORMAS_EMISSAO forma_emissao = str() @@ -381,6 +361,11 @@ class NotaFiscal(Entidade): # - Processo Referenciado (lista 1 para * / ManyToManyField) processos_referenciados = None + # - pagamentos + pagamentos = list() + # valor do troco + valor_troco = Decimal() + def __init__(self, *args, **kwargs): self.autorizados_baixar_xml = [] self.notas_fiscais_referenciadas = [] @@ -390,12 +375,19 @@ def __init__(self, *args, **kwargs): self.observacoes_contribuinte = [] self.processos_referenciados = [] self.responsavel_tecnico = [] + self.pagamentos = [] super(NotaFiscal, self).__init__(*args, **kwargs) def __str__(self): return " ".join([str(self.modelo), self.serie, self.numero_nf]) + def adicionar_pagamento(self, **kwargs): + """Adiciona uma instancia de Responsavel Tecnico""" + obj = NotaFiscalPagamentos(**kwargs) + self.pagamentos.append(obj) + return obj + def adicionar_autorizados_baixar_xml(self, **kwargs): obj = AutorizadosBaixarXML(**kwargs) self.autorizados_baixar_xml.append(obj) @@ -1165,3 +1157,21 @@ class NotaFiscalResponsavelTecnico(Entidade): class AutorizadosBaixarXML(Entidade): CPFCNPJ = str() + +class NotaFiscalPagamentos(Entidade): + # forma de pagamento flag: FORMAS_PAGAMENTO + t_pag = str() + # descrição da forma de pagametno + x_pag = str() + # valor + v_pag = Decimal() + # tipo de integracao: '', '1' integrado, '2' - não integrado + tp_integra = str() + # CNPJ da Credenciadora de cartão de crédito e/ou débito + cnpj = str() + # Bandeira da operadora de cartão de crédito e/ou débito flag: BANDEIRA_CARTAO + t_band = int() + # Número de autorização da operação cartão de crédito e/ou débito + c_aut = str() + # Indicador da Forma de Pagamento: 0=à Vista, 1=à Prazo + ind_pag = int() diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 34dd8549..56dd81c8 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -22,6 +22,7 @@ VERSAO_QRCODE, ) from pynfe.utils.webservices import MDFE, NFCE +import pynfe.utils.xml_writer as xmlw class Serializacao(object): @@ -1330,6 +1331,36 @@ def _serializar_responsavel_tecnico( else: return raiz + def _serializar_pagamentos(self, pagamentos: list(), finalidade_emissao='', valor_troco = 0.00, retorna_string=True): + pag = etree.Element('pag') + if (finalidade_emissao in [3, 4]): + detpag = etree.SubElement(pag, "detPag") + etree.SubElement(detpag, "tPag").text = "90" + etree.SubElement(detpag, "vPag").text = "{:.2f}".format(0) + else: + for item in pagamentos: + det = etree.Element("detPag") + xmlw.write_txt(det, "indPag", item.ind_pag, False) + xmlw.write_txt(det, "tPag", item.t_pag, True) + xmlw.write_txt(det, 'xPag', item.x_pag, False) + xmlw.write_float(det, 'vPag', item.v_pag, True, 2, 2) + if item.tp_integra: + card = etree.SubElement(det, "card") + xmlw.write_txt(card, "tpIntegra", item.tp_integra, True) + xmlw.write_txt(card, "CNPJ", item.cnpj, False) + xmlw.write_txt(card, "tBand", item.t_band, False) + xmlw.write_txt(card, "cAut", item.c_aut, False) + pag.append(det) + + # troco + + xmlw.write_float(pag, 'vTroco', valor_troco, True, 2, 2) + + if retorna_string: + return etree.tostring(pag, encoding="unicode", pretty_print=False) + else: + return pag + def _serializar_nota_fiscal( self, nota_fiscal, tag_raiz="infNFe", retorna_string=True ): @@ -1699,39 +1730,14 @@ def _serializar_nota_fiscal( """ Obrigatório o preenchimento do Grupo Informações de Pagamento para NF-e e NFC-e. Para as notas com finalidade de Ajuste ou Devolução o campo Forma de Pagamento deve ser preenchido com 90=Sem Pagamento. """ - pag = etree.SubElement(raiz, "pag") - detpag = etree.SubElement(pag, "detPag") - if ( - str(nota_fiscal.finalidade_emissao) == "3" - or str(nota_fiscal.finalidade_emissao) == "4" - ): - etree.SubElement(detpag, "tPag").text = "90" - etree.SubElement(detpag, "vPag").text = "{:.2f}".format(0) - else: - etree.SubElement(detpag, "tPag").text = str( - nota_fiscal.tipo_pagamento - ).zfill(2) - etree.SubElement(detpag, "vPag").text = "{:.2f}".format( - nota_fiscal.totais_icms_total_nota - ) - if nota_fiscal.tipo_pagamento == 3 or nota_fiscal.tipo_pagamento == 4: - cartao = etree.SubElement(detpag, "card") - """ Tipo de Integração do processo de pagamento com - o sistema de automação da empresa: - 1=Pagamento integrado com o sistema de automação da empresa - 2= Pagamento não integrado com o sistema de automação da empresa - """ - etree.SubElement(cartao, "tpIntegra").text = "2" - # etree.SubElement(cartao, 'CNPJ').text = '' - # # Informar o CNPJ da Credenciadora de cartão de crédito / débito - # etree.SubElement(cartao, 'tBand').text = '' - # # 01=Visa 02=Mastercard 03=American Express 04=Sorocred - # 05=Diners Club 06=Elo 07=Hipercard 08=Aura 09=Caba 99=Outros - # etree.SubElement(cartao, 'cAut').text = '' - # # Identifica o número da autorização da transação da operação - # com cartão de crédito e/ou débito - # troco - # etree.SubElement(pag, 'vTroco').text = str('') + raiz.append( + self._serializar_pagamentos( + pagamentos=nota_fiscal.pagamentos, + finalidade_emissao=nota_fiscal.finalidade_emissao, + valor_troco=nota_fiscal.valor_troco, + retorna_string=False + ) + ) # Informações adicionais if ( diff --git a/pynfe/utils/__init__.py b/pynfe/utils/__init__.py index b831c361..6dda9341 100644 --- a/pynfe/utils/__init__.py +++ b/pynfe/utils/__init__.py @@ -4,6 +4,7 @@ import os from unicodedata import normalize from signxml import XMLSigner +from typing import Literal try: from lxml import etree # noqa: F401 @@ -178,3 +179,67 @@ def __init__(self, method, signature_algorithm, digest_algorithm, c14n_algorithm def check_deprecated_methods(self): pass + +def is_empty(value): + """ + Verifica se um valor está vazio. + + Parameters: + - value: O valor a ser verificado. + + Returns: + - True se o valor estiver vazio, False caso contrário. + """ + if value is None: + return True + elif isinstance(value, (int, float)) and value == 0: + # Verifica se o valor numérico é igual a zero. + return True + elif isinstance(value, str) and not value.strip(): + # Verifica se a string está vazia ou contém apenas espaços em branco. + return True + elif isinstance(value, (list, tuple, dict)) and not value: + # Verifica se a lista, tupla ou dicionário está vazio. + return True + else: + return False + + +def truncar_valor(float_number: float, decimal_places: int, suprimir_zeros: bool = False): + multiplier = 10**decimal_places + result = str(int(float_number * multiplier) / multiplier) + if suprimir_zeros: + result = result.rstrip("0").rstrip(".") + return result + + +def arredondar_valor(value: float, decimal_places: int, suprimir_zeros: bool = False): + f = f"%.{decimal_places}f" + result = f % value + if suprimir_zeros: + result = result.rstrip("0").rstrip(".") + return result + + +def ajustar_valor( + value: float | None, decimal_places: int = 2, min_decimal_places: int = 2, tipo: Literal["ROUND", "TRUNC"] = "ROUND", decimal_separator: str = "." +): + value = 0 if value is None else value + + formated_value: str = "0" + supress_zeros = min_decimal_places < decimal_places + + if tipo == "ROUND": + formated_value = arredondar_valor(value, decimal_places, supress_zeros) + else: + formated_value = truncar_valor(value, decimal_places, supress_zeros) + + pi, sep, dec = list(formated_value.partition(".")) + + # preenche com zeros a direita até a quantidade minima + if min_decimal_places: + dec = dec.ljust(min_decimal_places, "0") + # se não tem decimais não haverá separator + sep = decimal_separator if dec else "" + + return f"{pi}{sep}{dec}".replace(".", decimal_separator) \ No newline at end of file diff --git a/pynfe/utils/xml_writer.py b/pynfe/utils/xml_writer.py new file mode 100644 index 00000000..e16802f6 --- /dev/null +++ b/pynfe/utils/xml_writer.py @@ -0,0 +1,82 @@ +from lxml import etree +from decimal import Decimal +from . import ajustar_valor, is_empty +from typing import Literal, Any + +__MIN_LEN_ERROR = 'Tamanho do campo {} é menor que o mímino permitido "{}"' +__MAX_LEN_ERROR = 'Tamanho do campo {} é maior que o mímino permitido "{}"' + +def write_txt(root: etree.ElementTree, tag_name, value: str, required: bool, min_len=0, max_len=0): + """ + :param root: XML root + :param tag_name: Nome da TAG a ser escrita (str) + :param value: Valor a ser escrito na TAG (str) + :param min_len: comprimento minimo + :param max-len: comprimento maximo + :param required: Se `True` e esta vazio, escreve a TAG vazia, do contrario não precisa gerar a TAG + """ + tag_value = str(value).strip() + + # retorna sem gerar nada se a TAG não é obrigatoria + if is_empty(tag_value) and not required: + return + + if len(tag_value) < min_len: + raise Exception(__MIN_LEN_ERROR.format(len(tag_value), min_len)) + if max_len > 0 and len(tag_value) > max_len: + raise Exception(__MAX_LEN_ERROR.format(len(tag_value), max_len)) + + etree.SubElement(root, tag_name).text = tag_value + +def write_float(root: etree.ElementTree, tag_name: str, value: Decimal, required: bool, decimal_places = 2, min_decimals = 0, iat: Literal["ROUND", "TRUNC"]="ROUND"): + """ + :param root: XML root + :param tag_name: Nome da TAG a ser escrita (str) + :param value: Valor a ser escrito na TAG (str) + :param decimal_places: casas decimais + :param min_decimals: numero minimo de casas decimais + :param required: Se `True` e esta vazio, escreve a TAG vazia, do contrario não precisa gerar a TAG (considera 0 como vazio) + :param iat: indice de arredondamento/truncamento (default: ROUND) + """ + + # retorna sem gerar nada se a TAG não é obrigatoria + if is_empty(value): + if not required: + return + raise Exception(f"{tag_name} - Valor requerido e não informado") + + tag_value = ajustar_valor( + value=value.__float__(), + decimal_places=decimal_places, + min_decimal_places=min_decimals, + tipo=iat + ) + + etree.SubElement(root, tag_name).text = tag_value + +def write_int(root: etree.ElementTree, tag_name: str, value: int, required: bool): + """ + :param root: XML root + :param tag_name: Nome da TAG a ser escrita (str) + :param value: Valor a ser escrito na TAG (str) + :param required: Se `True` e esta vazio, escreve a TAG vazia, do contrario não precisa gerar a TAG (considera 0 como vazio) + :param zero_is_empty: se `True` e o valor for zero será tratado como vazio + """ + + # retorna sem gerar nada se a TAG não é obrigatoria + if is_empty(value): + if not required: + return + raise Exception(f"{tag_name} - Valor requerido e não informado") + + etree.SubElement(root, tag_name).text = int(value) + + +def write_tag(root: etree.ElementTree, tag_name: str, value: Any, required: bool): + # retorna sem gerar nada se a TAG não é obrigatoria + if is_empty(value): + if not required: + return + raise Exception(f"{tag_name} - Valor requerido e não informado") + + etree.SubElement(root, tag_name).text = str(value) diff --git a/tests/test_nfce_serializacao.py b/tests/test_nfce_serializacao.py index d586d7fd..6fde3b5e 100644 --- a/tests/test_nfce_serializacao.py +++ b/tests/test_nfce_serializacao.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # *-* encoding: utf8 *-* - +from lxml import etree import datetime import unittest from decimal import Decimal @@ -92,7 +92,6 @@ def preenche_notafiscal_produto(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=65, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -110,6 +109,7 @@ def preenche_notafiscal_produto(self): transporte_modalidade_frete=1, informacoes_adicionais_interesse_fisco="Mensagem complementar", totais_tributos_aproximado=Decimal("1.01"), + valor_troco=Decimal('3.24674500'), ) self.notafiscal.adicionar_produto_servico( @@ -150,6 +150,8 @@ def preenche_notafiscal_produto(self): fone="11912341234", ) + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=120.25, ind_pag=0) + def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) return serializador.exportar() @@ -491,6 +493,14 @@ def total_e_produto_test(self): "//ns:total/ns:ICMSTot/ns:vTotTrib", namespaces=self.ns )[0].text + vTroco = self.xml_assinado.xpath( + "//ns:pag/ns:vTroco", namespaces=self.ns + )[0].text + + vPag = self.xml_assinado.xpath( + "//ns:pag/ns:detPag/ns:vPag", namespaces=self.ns + )[0].text + self.assertEqual(vBC, "0.00") self.assertEqual(vICMS, "0.00") self.assertEqual(vICMSDeson, "0.00") @@ -511,6 +521,7 @@ def total_e_produto_test(self): self.assertEqual(vOutro, "0.00") self.assertEqual(vNF, "117.00") self.assertEqual(vTotTrib, "1.01") + self.assertEqual(Decimal(vPag) - Decimal(vTroco), Decimal(vNF)) def test_notafiscal_produto_cst00(self): # Preenche as classes do pynfe diff --git a/tests/test_nfce_serializacao_sem_cliente.py b/tests/test_nfce_serializacao_sem_cliente.py index c8e024d9..f0ea115f 100644 --- a/tests/test_nfce_serializacao_sem_cliente.py +++ b/tests/test_nfce_serializacao_sem_cliente.py @@ -75,7 +75,6 @@ def preenche_notafiscal_produto(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=65, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -93,6 +92,7 @@ def preenche_notafiscal_produto(self): transporte_modalidade_frete=1, informacoes_adicionais_interesse_fisco="Mensagem complementar", totais_tributos_aproximado=Decimal("1.01"), + valor_troco=Decimal('3.00'), ) self.notafiscal.adicionar_produto_servico( @@ -133,6 +133,8 @@ def preenche_notafiscal_produto(self): fone="11912341234", ) + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=120.00, ind_pag=0) + def serializa_nfe(self): serializador = SerializacaoXML( fonte_dados=_fonte_dados, homologacao=self.homologacao, so_cpf=True diff --git a/tests/test_nfce_serializacao_somente_cpf.py b/tests/test_nfce_serializacao_somente_cpf.py index c673d47a..69f24485 100644 --- a/tests/test_nfce_serializacao_somente_cpf.py +++ b/tests/test_nfce_serializacao_somente_cpf.py @@ -84,7 +84,6 @@ def preenche_notafiscal_produto(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=65, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -102,6 +101,7 @@ def preenche_notafiscal_produto(self): transporte_modalidade_frete=1, informacoes_adicionais_interesse_fisco="Mensagem complementar", totais_tributos_aproximado=Decimal("1.01"), + valor_troco=Decimal('3.00'), ) self.notafiscal.adicionar_produto_servico( @@ -142,6 +142,8 @@ def preenche_notafiscal_produto(self): fone="11912341234", ) + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=120.00, ind_pag=0) + def serializa_nfe(self): serializador = SerializacaoXML( fonte_dados=_fonte_dados, homologacao=self.homologacao, so_cpf=True diff --git a/tests/test_nfe_serializacao_csosn_101.py b/tests/test_nfe_serializacao_csosn_101.py index 28af1a36..c725933e 100644 --- a/tests/test_nfe_serializacao_csosn_101.py +++ b/tests/test_nfe_serializacao_csosn_101.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn101(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -168,6 +167,9 @@ def preenche_notafiscal_produto_csosn101(self): fone="11912341234", ) + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) + + def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) return serializador.exportar() diff --git a/tests/test_nfe_serializacao_csosn_102.py b/tests/test_nfe_serializacao_csosn_102.py index 056ef63a..f912ca49 100644 --- a/tests/test_nfe_serializacao_csosn_102.py +++ b/tests/test_nfe_serializacao_csosn_102.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn102(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -166,6 +165,8 @@ def preenche_notafiscal_produto_csosn102(self): fone="11912341234", ) + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) + def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) return serializador.exportar() diff --git a/tests/test_nfe_serializacao_csosn_103.py b/tests/test_nfe_serializacao_csosn_103.py index d5c4d8d2..dbe35e51 100644 --- a/tests/test_nfe_serializacao_csosn_103.py +++ b/tests/test_nfe_serializacao_csosn_103.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn102(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -166,6 +165,8 @@ def preenche_notafiscal_produto_csosn102(self): fone="11912341234", ) + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) + def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) return serializador.exportar() diff --git a/tests/test_nfe_serializacao_csosn_201.py b/tests/test_nfe_serializacao_csosn_201.py index cd225674..619d4530 100644 --- a/tests/test_nfe_serializacao_csosn_201.py +++ b/tests/test_nfe_serializacao_csosn_201.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn201(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -164,6 +163,9 @@ def preenche_notafiscal_produto_csosn201(self): pdevol=Decimal("0.00"), ) + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=118.17, ind_pag=0) + + def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) return serializador.exportar() diff --git a/tests/test_nfe_serializacao_csosn_202.py b/tests/test_nfe_serializacao_csosn_202.py index 40fee4d1..0ccabb16 100644 --- a/tests/test_nfe_serializacao_csosn_202.py +++ b/tests/test_nfe_serializacao_csosn_202.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn202(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -113,6 +112,7 @@ def preenche_notafiscal_produto_csosn202(self): transporte_modalidade_frete=1, informacoes_adicionais_interesse_fisco="Mensagem complementar", totais_tributos_aproximado=Decimal("21.06"), + valor_troco=Decimal('1.83') ) self.notafiscal.adicionar_produto_servico( @@ -157,9 +157,11 @@ def preenche_notafiscal_produto_csosn202(self): nfci="12345678-AAAA-FFFF-1234-000000000000", informacoes_adicionais="Informações adicionais", ipi_valor_ipi_dev=Decimal("0.00"), - pdevol=Decimal("0.00"), + pdevol=Decimal("0.00") ) + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=120.00, ind_pag=0) + def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) return serializador.exportar() diff --git a/tests/test_nfe_serializacao_csosn_203.py b/tests/test_nfe_serializacao_csosn_203.py index c0a8f25f..ace55588 100644 --- a/tests/test_nfe_serializacao_csosn_203.py +++ b/tests/test_nfe_serializacao_csosn_203.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn203(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -159,6 +158,8 @@ def preenche_notafiscal_produto_csosn203(self): ipi_valor_ipi_dev=Decimal("0.00"), pdevol=Decimal("0.00"), ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=118.17, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_csosn_300.py b/tests/test_nfe_serializacao_csosn_300.py index 879c4459..e2cb8b4c 100644 --- a/tests/test_nfe_serializacao_csosn_300.py +++ b/tests/test_nfe_serializacao_csosn_300.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn300(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -165,6 +164,8 @@ def preenche_notafiscal_produto_csosn300(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_csosn_400.py b/tests/test_nfe_serializacao_csosn_400.py index ac89295e..ce469e18 100644 --- a/tests/test_nfe_serializacao_csosn_400.py +++ b/tests/test_nfe_serializacao_csosn_400.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn400(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -165,6 +164,8 @@ def preenche_notafiscal_produto_csosn400(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_csosn_500.py b/tests/test_nfe_serializacao_csosn_500.py index 0cf04874..c0fe14e5 100644 --- a/tests/test_nfe_serializacao_csosn_500.py +++ b/tests/test_nfe_serializacao_csosn_500.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn500(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -165,6 +164,8 @@ def preenche_notafiscal_produto_csosn500(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_csosn_900.py b/tests/test_nfe_serializacao_csosn_900.py index a3f4c840..3a0f8967 100644 --- a/tests/test_nfe_serializacao_csosn_900.py +++ b/tests/test_nfe_serializacao_csosn_900.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_csosn900(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -167,6 +166,8 @@ def preenche_notafiscal_produto_csosn900(self): ipi_valor_ipi_dev=Decimal("0.00"), pdevol=Decimal("0.00"), ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=119.34, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_00.py b/tests/test_nfe_serializacao_cst_00.py index f91fb589..e7981d8f 100644 --- a/tests/test_nfe_serializacao_cst_00.py +++ b/tests/test_nfe_serializacao_cst_00.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst00(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -150,6 +149,8 @@ def preenche_notafiscal_produto_cst00(self): ipi_valor_ipi_dev=Decimal("10.00"), pdevol=Decimal("1.00"), ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=127.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_10.py b/tests/test_nfe_serializacao_cst_10.py index 9b176f2d..05940657 100644 --- a/tests/test_nfe_serializacao_cst_10.py +++ b/tests/test_nfe_serializacao_cst_10.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst10(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -163,6 +162,8 @@ def preenche_notafiscal_produto_cst10(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_20.py b/tests/test_nfe_serializacao_cst_20.py index c4a48e39..3b99d8b7 100644 --- a/tests/test_nfe_serializacao_cst_20.py +++ b/tests/test_nfe_serializacao_cst_20.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst20(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -163,6 +162,8 @@ def preenche_notafiscal_produto_cst20(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_30.py b/tests/test_nfe_serializacao_cst_30.py index 6bb562be..a9f20112 100644 --- a/tests/test_nfe_serializacao_cst_30.py +++ b/tests/test_nfe_serializacao_cst_30.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst30(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -169,6 +168,8 @@ def preenche_notafiscal_produto_cst30(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_40.py b/tests/test_nfe_serializacao_cst_40.py index 386f9d29..99a6af2b 100644 --- a/tests/test_nfe_serializacao_cst_40.py +++ b/tests/test_nfe_serializacao_cst_40.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst40(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -158,6 +157,8 @@ def preenche_notafiscal_produto_cst40(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=107.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_41.py b/tests/test_nfe_serializacao_cst_41.py index e736eaab..0fb01b16 100644 --- a/tests/test_nfe_serializacao_cst_41.py +++ b/tests/test_nfe_serializacao_cst_41.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst41(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -158,6 +157,8 @@ def preenche_notafiscal_produto_cst41(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=107.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_50.py b/tests/test_nfe_serializacao_cst_50.py index 9f0f7690..625fd03a 100644 --- a/tests/test_nfe_serializacao_cst_50.py +++ b/tests/test_nfe_serializacao_cst_50.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst50(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -158,6 +157,8 @@ def preenche_notafiscal_produto_cst50(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=107.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_51.py b/tests/test_nfe_serializacao_cst_51.py index e22026af..8fa02505 100644 --- a/tests/test_nfe_serializacao_cst_51.py +++ b/tests/test_nfe_serializacao_cst_51.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst51(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -156,6 +155,8 @@ def preenche_notafiscal_produto_cst51(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_60.py b/tests/test_nfe_serializacao_cst_60.py index 8b6f803e..bdcf8407 100644 --- a/tests/test_nfe_serializacao_cst_60.py +++ b/tests/test_nfe_serializacao_cst_60.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst60(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -156,6 +155,8 @@ def preenche_notafiscal_produto_cst60(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento(t_pag="01", x_pag="Dinheiro", v_pag=117.00, ind_pag=0) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_70.py b/tests/test_nfe_serializacao_cst_70.py index 3320b276..ffe984a8 100644 --- a/tests/test_nfe_serializacao_cst_70.py +++ b/tests/test_nfe_serializacao_cst_70.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst70(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -173,6 +172,15 @@ def preenche_notafiscal_produto_cst70(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento( + t_pag="03", + x_pag="Cartao Credito", + v_pag=118.46, + ind_pag=0, + tp_integra="2", + t_band="99", + ) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_cst_90.py b/tests/test_nfe_serializacao_cst_90.py index 878b7c23..3d74ff3f 100644 --- a/tests/test_nfe_serializacao_cst_90.py +++ b/tests/test_nfe_serializacao_cst_90.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst90(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -178,6 +177,22 @@ def preenche_notafiscal_produto_cst90(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento( + t_pag="01", + x_pag="Dinheiro", + v_pag=17.00, + ind_pag=0, + ) + + self.notafiscal.adicionar_pagamento( + t_pag="03", + x_pag="Cartao Credito", + v_pag=100.00, + ind_pag=0, + tp_integra="2", + t_band="99", + ) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_geral.py b/tests/test_nfe_serializacao_geral.py index c372b117..abd624be 100644 --- a/tests/test_nfe_serializacao_geral.py +++ b/tests/test_nfe_serializacao_geral.py @@ -95,7 +95,6 @@ def preenche_notafiscal_produto_cst00(self): uf="PR", natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie="1", numero_nf="111", # Número do Documento Fiscal. @@ -163,6 +162,24 @@ def preenche_notafiscal_produto_cst00(self): email="pynfe@pynfe.io", fone="11912341234", ) + + self.notafiscal.adicionar_pagamento( + t_pag="03", + x_pag="Cartao Credito", + v_pag=117.00, + ind_pag=0, + tp_integra="2", + t_band="99", + ) + + self.notafiscal.adicionar_pagamento( + t_pag="03", + x_pag="Cartao Credito", + v_pag=117.00, + ind_pag=0, + tp_integra="2", + t_band="99", + ) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) diff --git a/tests/test_nfe_serializacao_ii_di_ipi.py b/tests/test_nfe_serializacao_ii_di_ipi.py index 8c9e033e..54fe205d 100644 --- a/tests/test_nfe_serializacao_ii_di_ipi.py +++ b/tests/test_nfe_serializacao_ii_di_ipi.py @@ -102,7 +102,6 @@ def preenche_notafiscal_produto_cst00(self): uf='PR', natureza_operacao='VENDA', # venda, compra, transferência, devolução, etc forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros. - tipo_pagamento=1, modelo=55, # 55=NF-e; 65=NFC-e serie='1', numero_nf='111', # Número do Documento Fiscal. @@ -200,6 +199,15 @@ def preenche_notafiscal_produto_cst00(self): imposto_importacao_valor=Decimal('0.00'), imposto_importacao_valor_iof=Decimal('1.11'), ) + + self.notafiscal.adicionar_pagamento( + t_pag="03", + x_pag="Cartao Credito", + v_pag=118.70, + ind_pag=0, + tp_integra="2", + t_band="99", + ) def serializa_nfe(self): serializador = SerializacaoXML(_fonte_dados, homologacao=self.homologacao) From 7a7e218f47837224c0744f60223a50a3a912245d Mon Sep 17 00:00:00 2001 From: Roberto Godinho Date: Wed, 20 Dec 2023 11:55:34 -0300 Subject: [PATCH 2/6] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 11179d1f..af4f1e7c 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,5 @@ target/ db.* TODO* + +venv \ No newline at end of file From a95e0a1d74a1e53bb73e5d1053271bcac162b858 Mon Sep 17 00:00:00 2001 From: Roberto Godinho Date: Wed, 20 Dec 2023 12:02:43 -0300 Subject: [PATCH 3/6] Update test_nfce_serializacao.py REFACTORY: remove unused import --- tests/test_nfce_serializacao.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_nfce_serializacao.py b/tests/test_nfce_serializacao.py index 6fde3b5e..c37cd06f 100644 --- a/tests/test_nfce_serializacao.py +++ b/tests/test_nfce_serializacao.py @@ -1,6 +1,5 @@ #!/usr/bin/env python # *-* encoding: utf8 *-* -from lxml import etree import datetime import unittest from decimal import Decimal From 9369ce718dafe216e9311cc54591e8fc08744701 Mon Sep 17 00:00:00 2001 From: Roberto Godinho Date: Wed, 20 Dec 2023 12:14:40 -0300 Subject: [PATCH 4/6] Update __init__.py REFACTORY: python 3.8 e 3.9 compatibility, remove unsupported operator --- pynfe/utils/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pynfe/utils/__init__.py b/pynfe/utils/__init__.py index 6dda9341..4fd75fc5 100644 --- a/pynfe/utils/__init__.py +++ b/pynfe/utils/__init__.py @@ -222,7 +222,7 @@ def arredondar_valor(value: float, decimal_places: int, suprimir_zeros: bool = F def ajustar_valor( - value: float | None, decimal_places: int = 2, min_decimal_places: int = 2, tipo: Literal["ROUND", "TRUNC"] = "ROUND", decimal_separator: str = "." + value: float, decimal_places: int = 2, min_decimal_places: int = 2, tipo: Literal["ROUND", "TRUNC"] = "ROUND", decimal_separator: str = "." ): value = 0 if value is None else value From 87e652a02c48a60c47296cbede712fe9d50494cb Mon Sep 17 00:00:00 2001 From: Roberto Godinho Date: Wed, 20 Dec 2023 14:23:41 -0300 Subject: [PATCH 5/6] ADD: adicionado flags de FORMAS_PAGAMENTO e BANDEIRA_CARTAO --- pynfe/utils/flags.py | 48 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/pynfe/utils/flags.py b/pynfe/utils/flags.py index fb41de2a..fe9b3449 100644 --- a/pynfe/utils/flags.py +++ b/pynfe/utils/flags.py @@ -601,3 +601,51 @@ "AN": "91", "EX": "99", } + +BANDEIRA_CARTAO = ( + ("01", "Visa"), + ("02", "MasterCard"), + ("03", "AmericanExpress"), + ("04", "Sorocred"), + ("05", "DinersClub"), + ("06", "Elo"), + ("07", "Hipercard"), + ("08", "Aura"), + ("09", "Cabal"), + ("10", "Alelo"), + ("11", "BanesCard"), + ("12", "CalCard"), + ("13", "Credz"), + ("14", "Discover"), + ("15", "GoodCard"), + ("16", "GrenCard"), + ("17", "Hiper"), + ("18", "JcB"), + ("19", "Mais"), + ("20", "MaxVan"), + ("21", "Policard"), + ("22", "RedeCompras"), + ("23", "Sodexo"), + ("24", "ValeCard"), + ("25", "Verocheque"), + ("26", "VR"), + ("27", "Ticket"), + ("99", "Outros"), +) + +FORMAS_PAGAMENTO = ( + ("01", "Dinheiro"), + ("02", "Cheque"), + ("03", "Cartao Credito"), + ("04", "Cartao Debito"), + ("05", "Credito Loja"), + ("10", "Vale Alimentacao"), + ("11", "Vale Refeicao"), + ("12", "Vale Presente"), + ("13", "Vale Combustivel"), + ("14", "Duplicata Mercantil"), + ("15", "Boleto Bancario"), + ("17", "Pagamento Instantaneo"), + ("90", "Sem Pagamento"), + ("99", "Outro"), +) From 0a376a69a862b18532feae0b10fbe8c1f1d9b1da Mon Sep 17 00:00:00 2001 From: Roberto Godinho Date: Wed, 20 Dec 2023 15:52:55 -0300 Subject: [PATCH 6/6] FIX: `valor_troco`corrigido para permitir valor zerado --- pynfe/processamento/serializacao.py | 3 +-- pynfe/utils/__init__.py | 3 ++- pynfe/utils/xml_writer.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pynfe/processamento/serializacao.py b/pynfe/processamento/serializacao.py index 56dd81c8..0045ffc7 100644 --- a/pynfe/processamento/serializacao.py +++ b/pynfe/processamento/serializacao.py @@ -1353,8 +1353,7 @@ def _serializar_pagamentos(self, pagamentos: list(), finalidade_emissao='', valo pag.append(det) # troco - - xmlw.write_float(pag, 'vTroco', valor_troco, True, 2, 2) + xmlw.write_float(pag, 'vTroco', valor_troco, False, 2, 2) if retorna_string: return etree.tostring(pag, encoding="unicode", pretty_print=False) diff --git a/pynfe/utils/__init__.py b/pynfe/utils/__init__.py index 4fd75fc5..8f53eb04 100644 --- a/pynfe/utils/__init__.py +++ b/pynfe/utils/__init__.py @@ -5,6 +5,7 @@ from unicodedata import normalize from signxml import XMLSigner from typing import Literal +from decimal import Decimal try: from lxml import etree # noqa: F401 @@ -192,7 +193,7 @@ def is_empty(value): """ if value is None: return True - elif isinstance(value, (int, float)) and value == 0: + elif isinstance(value, (int, float, Decimal)) and value == Decimal(0): # Verifica se o valor numérico é igual a zero. return True elif isinstance(value, str) and not value.strip(): diff --git a/pynfe/utils/xml_writer.py b/pynfe/utils/xml_writer.py index e16802f6..d16e67d1 100644 --- a/pynfe/utils/xml_writer.py +++ b/pynfe/utils/xml_writer.py @@ -40,7 +40,7 @@ def write_float(root: etree.ElementTree, tag_name: str, value: Decimal, required """ # retorna sem gerar nada se a TAG não é obrigatoria - if is_empty(value): + if is_empty(Decimal(value or '0')): if not required: return raise Exception(f"{tag_name} - Valor requerido e não informado")