PyNFe icon indicating copy to clipboard operation
PyNFe copied to clipboard

Valor de troco "Nan"

Open miguelsousawdt opened this issue 8 months ago • 1 comments

Boa tarde,

Estou a emitir NFC-e em ambiente de homolog com pagamento à vista em dinheiro. Consigo consultar no site de homolog da fazenda. Contudo não consigo informar corretamente o troco quando ele não existe (= 0.00).

Tentei omitir o campo valor_troco e tentei com valor a 0. No entanto no website da fazenda fica mostrando Nan. Reparei que na serialização o valor é removido pois no xml de envio não está presente quando é 0

nota_fiscal = NotaFiscal( ... "valor_troco": 0 )

Image

Qual a maneira correta de enviar troco 0 num pagamento a dinheiro ?

pynfe/processamento/serializacao.py (1397)

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, False, 2, 2)

        if retorna_string:
            return etree.tostring(pag, encoding="unicode", pretty_print=False)
        else:
            return pag

pynfe/utils/xml_writer.py (31)

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(Decimal(value or '0')):
        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

pynfe/utils/init.py (196)

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, Decimal)) and value == Decimal(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

Dando uma olhada rápida aí, mesmo enviando o valor_troco a 0, o is_empty vai retornar True e ele não será adicionado. Eu não sei se é esse o processo correto, mas na página web do documento, o campo Troco vem como NaN

miguelsousawdt avatar Apr 30 '25 17:04 miguelsousawdt

Isso é um problema no próprio site da fazenda... Está interpretando o Nulo/Zero como Not a Number (NaN), não tem a ver com a biblioteca, pois a gente só serializa no formato que o WSDL disponibiliza, e se ele aceitou juntamente com o servidor da SEFAZ, é por que estava correto.

felps-dev avatar May 03 '25 07:05 felps-dev