Valor de troco "Nan"
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 )
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
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.