Jump to content
Fivewin Brasil

Problema com função Round(), vPIS e vCOFINS e Schema da NFe


rochinha

Recommended Posts

Amiguinhos,

Vinha eu caminhando saltitante pelo bosque dos cálculos de impostos quando num momento de envio do .XML fui barrado porque o calculo do total não batia.

O valor em questão é R$ 54,6312.

A função round() do Harbour que uso me retorna para 2 dígitos o valor de R$ 54,63.

No ACBr, eu jogo os valores todos com 4 dígitos pois ele se encarrega de cortar ou arredondar e também dá R$ 54,63.

Mas o SEFAZ, lobo maldito, insiste em assoprar o valor de R$ 54,64.

Pombas, eu sempre usei a técnica de arredondar de trás para frente caso encontrasse algum 5.

Mas segundo o https://pt.wikipedia.org/wiki/Arredondamento eu tô no bosque errado.

Tudo bem que meu Harbour é velhinho, mas...

	Harbour Compiler Alpha build 45.0 (Flex)
Copyright 1999-2005, http://www.harbour-project.org/
Link to comment
Share on other sites

#include "FiveWin.ch"
	#xtranslate round(<nVal>,<nDec>) => val(str(<nVal>,20,<nDec>))
	FUNCTION Test_Round()
 
   LOCAL nImp, qt, preco
 
   nImp      := 0.00
   qt        := 1.0001
   preco     := 54.6312
	   nImp := ( ROUND( qt, 2 ) ) * ( ROUND( preco, 2 ) )
 
   nImp := Round( Val( StrZero( preco * qt, 12, 2 ) ), 6 )
 
   ? ROUND( nImp, 2 )  // 54.64
	 
RETURN NIL

Link to comment
Share on other sites

Com ACBR, eu nada ÇAY...

#include "FiveWin.ch"
	#xtranslate round(<nVal>,<nDec>) => val(str(<nVal>,20,<nDec>))
	FUNCTION Test_Round()
 
   LOCAL nRound, nValor
 
   nRound      := 0.00
   nValor     := 54.6312 // + .01 ou:
	   nRound := Round( Val( StrZero( nValor, 12, 2 ) ), 4 ) + .01
 
   ? ROUND( nRound, 2 )  // 54.64
 
RETURN NIL


 

Link to comment
Share on other sites

Você faz assim?

Vp:=round(10.5678,2) :

 

ou em forma de variável, assim:  

vp1:=10.5678

vp2:=round(vp1,2)

??????

 

 

para calcular os impostos, faço assim:

vpis:=valor*0.065

vpis:=round(vpis,2)

 

outros exemplos, de como faço:

                      v3:=nvalor*2/100
                      v3:=round(v3,2)
                      :vFCPUFDest     :=v3
 

para calcular o valor do pis, na nfe:

                     :CST_Pis   := '01'   
                     :vBC_Pis   := nVALOR                                    // Valor da Base de Cálculo do PIS
                     :pPIS      := ARQ_LPN->POR_PIS                 // Alíquota do PIS (percentual)
                     vp:=nVALOR*ARQ_LPN->POR_PIS/100
                     vp:=ROUND(VP,2)
                     :vPIS      := vp  
                     t_pis:=t_pis+vp
                     t_pis:=round(t_pis,2)
 

 

 

Link to comment
Share on other sites

Amiguinhos,

mkyx

Uso a forma mais simples conforme voce apresentou

vpis:=valor*0.065

vpis:=round(vpis,2)

O valor R$ 54,6312 é o resultado da soma do cálculo de vPIS de vários itens em uma nota. Não é um valor direto ao qual irei impor cálculo.

A formula do kapiaba leva em consideração um item calculando diretamente sobre o valor. Não posso usar o método exposto pois ele está calculando apenas uma unidade e não valores variaveis. Da forma como está, posso corromper os cálculos.

Vou fazer um teste com um unico item e chegar ao valor de vPIS R$ 54,6312 e tentar a validação no SEFAZ para ver onde ele não valida.

Link to comment
Share on other sites

Amiguinhos,

fladimir

Verifiquei o fato de nas configurações do ACBr ter algo a ver com quantidade de digitos mas este campo em questão não se define pelas configurações do monitor, pois é padrão do layout que ele tenha 2 digitos. Este campo figura dentro do grupo totais

Fiz um teste com um único produto totalizando o mesmo valor de vPIS e passou.

Link to comment
Share on other sites

Então eu tinha escrito da possibilidade, mas depois li com mais calma e vi q vc definiu a quantidade de casas no ACBr.

O ACBr / Webservice do governo (não sei precisar qual, acredito q o Governo) permite até 0,004 de diferença em um item (pelo menos em testes no valor do IBPT por item) cheguei a este resultado, faça o seguinte, faça testes a nível de arquivo texto alimentado / alterando manualmente até chegar nos valores q vc verifica q vai passar depois ajusta no sistema.

Eu parei de trabalhar com Round nessa parte de calculos nos itens, faço os calculos e Trunco na 4 casa e mando bala e jogo a soma nas tags total, ai não tive mais problemas.

Link to comment
Share on other sites

Amiguinhos,

Baseado em uma NT que o JoseQuintas apresentou no PCToledo e na função que o kapiaba apresentou, mas não explicou o porque de um tal 0,01 é que pude entender que se tratava de um fator de arredondamento.

O problema que este fator de arredondamento, como dito na NT, serve para arredondar para mais ou para menos o valor afim de se adequar as regras do SEFAZ.

Nossos sistemas não são dotados de inteligencia artificial(ainda) para decidir que momento usar um ou outro método, além daqueles que programamos.

Partindo deste pressuposto elaborei uma função para testar as regras conforne ABNT.

Arredondando a 2 algarismos decimais deveremos ter em atenção o terceiro e quarto decimal. Assim, conforme as regras anteriores:

O número 12,6529 seria arredondado para 12,65 (aqui fica 12.65, uma vez que 29 é inferior a 50, então não se modifica)
O número 12,86512 seria arredondado para 12,87 (aqui fica 12.87, uma vez que 512 é superior a 500, então incrementa-se uma unidade)
O número 12,744623 seria arredondado para 12,74 (aqui fica 12.74, uma vez que 4623 é inferior a 5000, então não se modifica)
O número 12,8752 seria arredondado para 12,88
O número 12,8150 seria arredondado para 12,82 (aqui fica 12.82, uma vez que os algarismos seguintes é igual a 50, então incrementa-se uma unidade)
O número 12,80050 seria arredondado para 12,80 (aqui fica 12.80, uma vez que 050 e menor que 500)
O numero 13,4666..., se fossemos arredondar à parte inteira, será sempre arredondado para 13, pois 4666... sempre será menor que 5000... (Se fizermos o arredondamento número a número, teríamos : 13,4666... ? 13,47 ? 13,5 ? 14, porém, isso seria afirmar que 13,4666... está mais próximo de 14 do que está de 13, que não é verdade. Portanto, não devemos arredondar o número já previamente arredondado!!!)

FUNCTION ABNTROUND( R_VALOR )
   R_VALOR_INT := INT( R_VALOR )
   R_VALOR_DEC := ROUND( DEC( R_VALOR ), 2 )
   R_VALOR_RND := R_VALOR_DEC - DEC( R_VALOR )
   IF     R_VALOR_RND >= .0050 .AND. R_VALOR_RND < .00499
          R_VALOR_DEC := R_VALOR_DEC + 1
   ELSEIF R_VALOR_RND >= .00500 .AND. R_VALOR_RND < .004999
          R_VALOR_DEC := R_VALOR_DEC + 1
   ELSEIF R_VALOR_RND >= .005000 .AND. R_VALOR_RND < .0049999
          R_VALOR_DEC := R_VALOR_DEC + 1
   ENDIF
   RETURN R_VALOR_INT + R_VALOR_DEC

Com esta função consegui fazer os valores serem calculados baterem com ABNT com excessão do 12,8150 que não arredondou, mesmo porque fiz a função rapidamente.

Nela também o meu valor não se alterou.

Usando a função do kapiaba os valores bateram com excessão do 12,744623 que arredondou para 12,75 e do 12,80050 que arredondou para 12,81 e do meu valor que foi de 53,6312 para 53,64.

Resumindo:

Para efeitos do fisco, diferenças para cima são aceitas.

Observação:

Não encontrei referencia a função trunk() e quando pesquisei sobre a função dec() ou Decimals vi que só a tenho pois a mesma esta criada em minhas funções.

Em tempos, vou passar a usar a função conforme o cálculo que o kapiaba apresentou.

Esta mensagem esta sendo reverberada nos foruns aos quais coloquei em pauta.

Link to comment
Share on other sites

Amiguinhos,

A função que mais chegou perto do resultado ABNT foi esta:

#xtranslate round(<nVal>,<nDec>) => val(str(<nVal>,20,<nDec>))
	FUNCTION KROUND( preco )
   LOCAL nImp := 0.00, qt := 1.0001
   nImp := round( Val( StrZero( preco * qt, 12, 2 ) ), 6 )
   RETURN round( nImp, 2 )


 

Link to comment
Share on other sites

Amigos...

Sempre usei desta forma e nunca tive problemas, mesmo porque é permitido a diferença de até R$ 0,01 nos cálculos.

Qtde. := 1.7356 

Valor := R$ 3,4540

Total := round(1.7356 x 3,454,9)

Total := round(Total,15,2)

Resultado = R$ 5,99

Abrs

Link to comment
Share on other sites

Perfeito Tranka:

#include "FiveWin.ch"
	#xtranslate round(<nVal>,<nDec>) => val(str(<nVal>,20,<nDec>))
	FUNCTION Test_Round()
 
   LOCAL nImp, qt, preco
 
   nImp      := 0.00
   qt        := 1.7356
   preco     := 3.4540
	   nImp := Round( Val( StrZero( preco * qt, 12, 2 ) ), 6 )
 
   ? ROUND( nImp, 2 )  // Resultado = R$ 5,9947624
	 
RETURN NIL

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...