Skip to content

Commit 7a239bc

Browse files
authored
Serializacao: Fixando 2 casas decimais para vNF e vProd (#354)
1 parent 2123b75 commit 7a239bc

File tree

2 files changed

+175
-2
lines changed

2 files changed

+175
-2
lines changed

pynfe/processamento/serializacao.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,7 @@ def _serializar_nota_fiscal(
16621662
if nota_fiscal.totais_icms_v_icms_mono_ret:
16631663
etree.SubElement(icms_total, "vICMSMonoRet").text = "{:.2f}".format(nota_fiscal.totais_icms_v_icms_mono_ret)
16641664

1665-
etree.SubElement(icms_total, "vProd").text = str(
1665+
etree.SubElement(icms_total, "vProd").text = "{:.2f}".format(
16661666
nota_fiscal.totais_icms_total_produtos_e_servicos
16671667
)
16681668
etree.SubElement(icms_total, "vFrete").text = "{:.2f}".format(
@@ -1695,7 +1695,7 @@ def _serializar_nota_fiscal(
16951695
etree.SubElement(icms_total, "vOutro").text = "{:.2f}".format(
16961696
nota_fiscal.totais_icms_outras_despesas_acessorias
16971697
)
1698-
etree.SubElement(icms_total, "vNF").text = str(
1698+
etree.SubElement(icms_total, "vNF").text = "{:.2f}".format(
16991699
nota_fiscal.totais_icms_total_nota
17001700
)
17011701
if nota_fiscal.totais_tributos_aproximado:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#!/usr/bin/env python
2+
# *-* encoding: utf8 *-*
3+
4+
import datetime
5+
import unittest
6+
from decimal import Decimal
7+
8+
from pynfe.entidades.emitente import Emitente
9+
from pynfe.entidades.fonte_dados import _fonte_dados
10+
from pynfe.entidades.notafiscal import NotaFiscal
11+
from pynfe.processamento.assinatura import AssinaturaA1
12+
from pynfe.processamento.serializacao import SerializacaoXML
13+
from pynfe.processamento.validacao import Validacao
14+
from pynfe.utils.flags import (
15+
CODIGO_BRASIL,
16+
NAMESPACE_NFE,
17+
NAMESPACE_SIG,
18+
XSD_FOLDER_NFE,
19+
XSD_NFE,
20+
XSD_NFE_PROCESSADA,
21+
)
22+
23+
24+
class SerializacaoNFeTestCase(unittest.TestCase):
25+
"""
26+
Imprimir o XML completo:
27+
print(etree.tostring(self.xml_assinado))
28+
29+
"""
30+
31+
def setUp(self):
32+
self.certificado = "./tests/certificado.pfx"
33+
self.senha = bytes("123456", "utf-8")
34+
self.uf = "pr"
35+
self.homologacao = True
36+
37+
self.ns = {"ns": NAMESPACE_NFE}
38+
self.ns_sig = {"ns": NAMESPACE_SIG}
39+
40+
self.validacao = Validacao()
41+
self.xsd_procNFe = self.validacao.get_xsd(
42+
xsd_file=XSD_NFE_PROCESSADA, xsd_folder=XSD_FOLDER_NFE
43+
)
44+
self.xsd_nfe = self.validacao.get_xsd(
45+
xsd_file=XSD_NFE, xsd_folder=XSD_FOLDER_NFE
46+
)
47+
48+
def preenche_emitente(self):
49+
self.emitente = Emitente(
50+
razao_social="NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL",
51+
nome_fantasia="Nome Fantasia da Empresa",
52+
cnpj="99999999000199", # cnpj apenas números
53+
codigo_de_regime_tributario="3", # 1 para simples nacional ou 3 para normal
54+
inscricao_estadual="9999999999", # numero de IE da empresa
55+
inscricao_municipal="12345",
56+
cnae_fiscal="9999999", # cnae apenas números
57+
endereco_logradouro="Rua da Paz",
58+
endereco_numero="666",
59+
endereco_bairro="Sossego",
60+
endereco_municipio="Paranavaí",
61+
endereco_uf="PR",
62+
endereco_cep="87704000",
63+
endereco_pais=CODIGO_BRASIL,
64+
)
65+
return self.emitente
66+
67+
def preenche_notafiscal_produto(self, valorUnitario, quantidade, valorTotal):
68+
utc = datetime.timezone.utc
69+
data_emissao = datetime.datetime(2021, 1, 14, 12, 0, 0, tzinfo=utc)
70+
data_saida_entrada = datetime.datetime(2021, 1, 14, 13, 10, 20, tzinfo=utc)
71+
72+
self.notafiscal = NotaFiscal(
73+
emitente=self.emitente,
74+
cliente=None,
75+
uf="PR",
76+
natureza_operacao="VENDA", # venda, compra, transferência, devolução, etc
77+
forma_pagamento=0, # 0=Pagamento à vista; 1=Pagamento a prazo; 2=Outros.
78+
tipo_pagamento=1,
79+
modelo=65, # 55=NF-e; 65=NFC-e
80+
serie="1",
81+
numero_nf="111", # Número do Documento Fiscal.
82+
data_emissao=data_emissao,
83+
data_saida_entrada=data_saida_entrada,
84+
tipo_documento=1, # 0=entrada; 1=saida
85+
municipio="4118402", # Código IBGE do Município
86+
tipo_impressao_danfe=1, # 1=DANFE normal
87+
forma_emissao="1", # 1=Emissão normal (não em contingência);
88+
cliente_final=1, # 0=Normal;1=Consumidor final;
89+
indicador_destino=1,
90+
indicador_presencial=1,
91+
finalidade_emissao="1", # 1=NF-e normal
92+
processo_emissao="0", # 0=Emissão de NF-e com aplicativo do contribuinte;
93+
transporte_modalidade_frete=1,
94+
informacoes_adicionais_interesse_fisco="Mensagem complementar",
95+
totais_tributos_aproximado=Decimal("1.01"),
96+
valor_troco=Decimal('3.00'),
97+
)
98+
99+
self.notafiscal.adicionar_produto_servico(
100+
codigo="000328", # id do produto
101+
descricao="Produto teste",
102+
ncm="99999999",
103+
# cest='0100100', # NT2015/003
104+
ean="1234567890121",
105+
cfop="5102",
106+
unidade_comercial="UN",
107+
quantidade_comercial=Decimal(quantidade),
108+
valor_unitario_comercial=Decimal(valorUnitario),
109+
valor_total_bruto=Decimal(valorTotal),
110+
unidade_tributavel="UN",
111+
quantidade_tributavel=Decimal(quantidade),
112+
valor_unitario_tributavel=Decimal(valorUnitario),
113+
ean_tributavel="SEM GTIN",
114+
ind_total=1,
115+
icms_modalidade="00",
116+
icms_origem=0,
117+
icms_csosn="",
118+
pis_modalidade="51",
119+
cofins_modalidade="51",
120+
pis_valor_base_calculo=Decimal("0.00"),
121+
pis_aliquota_percentual=Decimal("0.00"),
122+
pis_valor=Decimal("0.00"),
123+
cofins_valor_base_calculo=Decimal("0.00"),
124+
cofins_aliquota_percentual=Decimal("0.00"),
125+
cofins_valor=Decimal("0.00"),
126+
valor_tributos_aprox="1.01",
127+
)
128+
129+
def serializa_nfe(self):
130+
serializador = SerializacaoXML(
131+
fonte_dados=_fonte_dados, homologacao=self.homologacao, so_cpf=True
132+
)
133+
return serializador.exportar()
134+
135+
def assina_xml(self):
136+
a1 = AssinaturaA1(self.certificado, self.senha)
137+
return a1.assinar(self.xml)
138+
139+
def validacao_com_xsd_do_xml_gerado_sem_processar(self):
140+
self.validacao.validar_etree(
141+
xml_doc=self.xml_assinado, xsd_file=self.xsd_nfe, use_assert=True
142+
)
143+
144+
def total_test(self, valorEsperado):
145+
vProd = self.xml_assinado.xpath(
146+
"//ns:total/ns:ICMSTot/ns:vProd", namespaces=self.ns
147+
)[0].text
148+
149+
vNF = self.xml_assinado.xpath(
150+
"//ns:total/ns:ICMSTot/ns:vNF", namespaces=self.ns
151+
)[0].text
152+
153+
self.assertEqual(vProd, valorEsperado)
154+
self.assertEqual(vNF, valorEsperado)
155+
156+
def test_notafiscal_produto_com_vnf_e_vprod_com_duas_casas_decimais(self):
157+
valorUnitario = 9.67
158+
quantidade = 12
159+
valorTotal = 116.03999999999999
160+
valorEsperado = "116.04"
161+
# Preenche as classes do pynfe
162+
self.emitente = self.preenche_emitente()
163+
self.notafiscal = self.preenche_notafiscal_produto(valorUnitario, quantidade, valorTotal)
164+
165+
# Serializa e assina o XML
166+
self.xml = self.serializa_nfe()
167+
self.xml_assinado = self.assina_xml()
168+
169+
self.assertEqual(valorUnitario * quantidade, valorTotal)
170+
self.total_test(valorEsperado)
171+
172+
if __name__ == "__main__":
173+
unittest.main()

0 commit comments

Comments
 (0)