rochinha Posted May 9, 2017 Report Share Posted May 9, 2017 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/ Quote Link to comment Share on other sites More sharing options...
mkyx Posted May 9, 2017 Report Share Posted May 9, 2017 nunca tive esse problemas, mas acho que você deverá mudar a forma como você processa os cálculos. Quote Link to comment Share on other sites More sharing options...
kapiaba Posted May 9, 2017 Report Share Posted May 9, 2017 #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 Quote Link to comment Share on other sites More sharing options...
rochinha Posted May 9, 2017 Author Report Share Posted May 9, 2017 Amiguinhos, mkyx A forma que eu uso é a de jogar o valor dentro da função round(), simples e pura, não tem firula. kapiaba Como você chegou até esta formula? e que valor 1.0001 é este? qual a base para usá-lo. Quote Link to comment Share on other sites More sharing options...
kapiaba Posted May 9, 2017 Report Share Posted May 9, 2017 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 Quote Link to comment Share on other sites More sharing options...
mkyx Posted May 9, 2017 Report Share Posted May 9, 2017 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) Quote Link to comment Share on other sites More sharing options...
rochinha Posted May 9, 2017 Author Report Share Posted May 9, 2017 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. Quote Link to comment Share on other sites More sharing options...
rochinha Posted May 9, 2017 Author Report Share Posted May 9, 2017 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. Quote Link to comment Share on other sites More sharing options...
fladimir Posted May 9, 2017 Report Share Posted May 9, 2017 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. Quote Link to comment Share on other sites More sharing options...
rochinha Posted May 9, 2017 Author Report Share Posted May 9, 2017 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. Quote Link to comment Share on other sites More sharing options...
rochinha Posted May 10, 2017 Author Report Share Posted May 10, 2017 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 ) kapiaba 1 Quote Link to comment Share on other sites More sharing options...
kapiaba Posted May 10, 2017 Report Share Posted May 10, 2017 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. Mas vocêe meu caro amigo, é DOTADO de super inteligência, então... kkkkkkkkkkkkkkkkk, abs. rochinha 1 Quote Link to comment Share on other sites More sharing options...
Valdir Posted May 10, 2017 Report Share Posted May 10, 2017 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 Quote Link to comment Share on other sites More sharing options...
kapiaba Posted May 10, 2017 Report Share Posted May 10, 2017 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 Valdir 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.