Ir para conteúdo
  • Cadastre-se

dev botao

ABNTRoundTo e campo vItem


gustavozr
  • Este tópico foi criado há 856 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Bom dia, estou com uma situação estranha em relação ao arredondamento realizado pelo SAT. Eu envio a seguinte TAG de produto

      <prod>
        <cProd>717827</cProd>
        <cEAN>030471782701</cEAN>
        <xProd>PIMENTA BIQUINHO</xProd>
        <NCM>07096000</NCM>
        <CFOP>5102</CFOP>
        <uCom>UNI</uCom>
        <qCom>0.9950</qCom>
        <vUnCom>0.990</vUnCom>
        <indRegra>A</indRegra>
      </prod>

E o SAT me retorna 

      <prod>
        <cProd>717827</cProd>
        <cEAN>030471782701</cEAN>
        <xProd>PIMENTA BIQUINHO</xProd>
        <NCM>07096000</NCM>
        <CFOP>5102</CFOP>
        <uCom>UNI</uCom>
        <qCom>0.9950</qCom>
        <vUnCom>0.990</vUnCom>
        <vProd>0.98</vProd>
        <indRegra>A</indRegra>
        <vItem>0.98</vItem>
      </prod>

Ele está retornando o valor do item como R$ 0,98 , porém realizo o arredondamento da multiplicação entre qCom e vUnCom, através da função ABNTRoundTo da unit ACBrUtil, e o valor retornado é R$ 0,99. Até parece que o SAT está ignorando a regra de arredondamento 'A'. Alguém já pegou algum caso assim?

Link para o comentário
Compartilhar em outros sites

Fiz o teste com duas casa decimais, mas ocorre o mesmo problema. Tentei fazer um XML com 3 casa decimais na quantidade, mas ocorreu o erro 06010 ("Rejeição: Erro não identificado"), e quando voltei as 4 casas decimais, voltou a funcionar.

      <prod>
        <cProd>717827</cProd>
        <cEAN>030471782701</cEAN>
        <xProd>PIMENTA BIQUINHO</xProd>
        <NCM>07096000</NCM>
        <CFOP>5102</CFOP>
        <uCom>UNI</uCom>
        <qCom>0.9950</qCom>
        <vUnCom>0.99</vUnCom>
        <vProd>0.98</vProd>
        <indRegra>A</indRegra>
        <vItem>0.98</vItem>
      </prod>

se alguém tiver alguma luz, eu agradeceria. 

Link para o comentário
Compartilhar em outros sites

eu identifiquei o seguinte: 

No código abaixo o valor retornado será R$ 0,99 (diferente do SAT)

var
	currValorUnit : currency;
    currQtde : currency;
    currTotal : currency;
begin
	currValorUnit:=0.99;
    currQtde:=0.995;
    currTotal:=ACBrUtil.RoundABNT(currValorUnit * currQtde, 2);
end;

O valor final da variável currTotal será apresentado como 0.99, e como estava comparando pelo calculado pelo SAT, o valor não bate. Aparentemente, pelo que observei é porque a variável que a funcção RoundABNT recebe é um double, e o valor passado para a função é 0.98505.

 

Então implementei a situação de outra forma, conforme abaixo:

var
	currValorUnit : currency;
    currQtde : currency;
    currTotal : currency;
begin
	currValorUnit:=0.99;
    currQtde:=0.995;
    currTotal:=currValorUnit * currQtde;
    currTotal:=ACBrUtil.RoundABNT(currTotal, 2);
end;

Neste caso o valor de currTotal será 0.98 (R$ 0,98), assim como no retorno do SAT. O valor passado para a função RoundABNT neste caso, como é uma variável do tipo currency, será 0.9850. Pelo que observei com este teste, o SAT também faz cálculos com variáveis de até 4 casas decimais, como é o caso do currency do Delphi.

E o caso foi sanado desta forma.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Gustavozr, fiz um teste aqui na parte da manhã e só agora tive tempo de te responder, no meu SAT DIMEP para homologação ele calcula arredondando normalmente, R$ 0,99, não sei porquê o seu SAT não arredonda, em anexo o XML enviado e o XML retornado pelo SAT.

Sds,

Ricardo.

CFE15209.XML

AD35151161099008000141599000020400003236072953.xml

selo_equipe_acbr.pngRicardo Miquinioty
Ajude o Projeto ACBr crescer - Assine o SAC

Link para o comentário
Compartilhar em outros sites

Ricardo, pelo que entendi, todos os SATs trabalham com o arredondamento NBR, a diferença é o tipo de variável ponto-flutuante que cada um está utilizando. Pois tanto 0,98 quanto 0,99 estão corretos dependendo de qual a precisão da variável de ponto-flutuante que você está utilizando. Realizei os testes com as marcas Sweda e Gertec, vou ver outros SATs para ver o que ocorre, e informo aqui no mesmo post.

 

Sds.

Gustavo

Link para o comentário
Compartilhar em outros sites

Boa tarde a todos, realizei os testes, e como havia previsto, os resultados diferem, embora pelo que analisei o cálculo está correto, apenas a precisão do ponto-flutuante na hora do cálculo varia. No caso os SATs Sweda e Gertec retornaram R$ 0,98 e o SAT Tanca retornou R$ 0,99.

Dados enviados:

      <prod>
        <cProd>717827</cProd>
        <cEAN>10304717827019</cEAN>
        <xProd>Pp PIMENTA BIQUINHO*</xProd>
        <NCM>07096000</NCM>
        <CFOP>5102</CFOP>
        <uCom>UNI</uCom>
        <qCom>0.9950</qCom>
        <vUnCom>0.990</vUnCom>
        <indRegra>A</indRegra>
      </prod>

Retorno Sweda (R$ 0,98)

      <prod>
        <cProd>717827</cProd>
        <cEAN>10304717827019</cEAN>
        <xProd>Pp PIMENTA BIQUINHO*</xProd>
        <NCM>07096000</NCM>
        <CFOP>5102</CFOP>
        <uCom>UNI</uCom>
        <qCom>0.9950</qCom>
        <vUnCom>0.990</vUnCom>
        <vProd>0.98</vProd>
        <indRegra>A</indRegra>
        <vItem>0.98</vItem>
      </prod>

Retorno Gertec (R$ 0,98)

      <prod>
        <cProd>717827</cProd>
        <cEAN>10304717827019</cEAN>
        <xProd>Pp PIMENTA BIQUINHO*</xProd>
        <NCM>07096000</NCM>
        <CFOP>5102</CFOP>
        <uCom>UNI</uCom>
        <qCom>0.9950</qCom>
        <vUnCom>0.990</vUnCom>
        <vProd>0.98</vProd>
        <indRegra>A</indRegra>
        <vItem>0.98</vItem>
      </prod>

Retorno Tanca (R$ 0,99)

      <prod>
        <cProd>717827</cProd>
        <cEAN>10304717827019</cEAN>
        <xProd>Pp PIMENTA BIQUINHO*</xProd>
        <NCM>07096000</NCM>
        <CFOP>5102</CFOP>
        <uCom>UNI</uCom>
        <qCom>0.9950</qCom>
        <vUnCom>0.990</vUnCom>
        <vProd>0.99</vProd>
        <indRegra>A</indRegra>
        <vItem>0.99</vItem>
        <vRatDesc>0.00</vRatDesc>
        <vRatAcr>0.00</vRatAcr>
      </prod>

 

Agora terei que trabalhar para prever todas as situações.

Obrigado a ajuda de todos.

 

Sds.

Gustavo

Link para o comentário
Compartilhar em outros sites

Ricardo, eu realizei os teste com 2 e com 3 casas decimais, o resultado final é independente disto, o cálculo aparentemente está ligado diretamente com a quantidade de casas decimais prevista dentro do SAT.

Talvez se você fizer um teste com equipamentos Sweda ou Gertec você alcance os mesmos resultados que eu consegui.

Sds.

Gustavo

Editado por gustavozr
Link para o comentário
Compartilhar em outros sites

  • Fabricantes

Prezados, bom dia!

 

Como um retorno por parte dos fabricantes, represento a marca Tanca, em nossa visão o arredondamento correto é 0,99.

A solução dada pelo Gustavo é muito inteligente, porém resolve a questão para o aplicativo comercial e infelizmente o cupom é rejeitado na Retaguarda.

O acesso a retaguarda é algo que só o fabricante consegue ver nos kits de desenvolvimento, portanto ele não teria como saber.

Fizemos dois testes aqui, um com o SAT retornando 0,99 (correto) e no outro alteramos o Software Básico do SAT retornando 0,98 (errado).

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Usando versão original (arredondamento: 0.99)
<prod>
    <cProd>717827</cProd>
    <cEAN>10304717827019</cEAN>
    <xProd>PIMENTA BIQUINHO</xProd>
    <NCM>07096000</NCM>
    <CFOP>5102</CFOP>
    <uCom>UNI</uCom>
    <qCom>0.9950</qCom>
    <vUnCom>0.990</vUnCom>
    <vProd>0.99</vProd>
    <indRegra>A</indRegra>
    <vItem>0.99</vItem>
    <vRatDesc>0.00</vRatDesc>
    <vRatAcr>0.00</vRatAcr>
</prod>

050302.JPG

 

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Usando versão para teste (arredondamento:0.98)
<prod>
    <cProd>717827</cProd>
    <cEAN>10304717827019</cEAN>
    <xProd>PIMENTA BIQUINHO</xProd>
    <NCM>07096000</NCM>
    <CFOP>5102</CFOP>
    <uCom>UNI</uCom>
    <qCom>0.9950</qCom>
    <vUnCom>0.990</vUnCom>
    <vProd>0.98</vProd>
    <indRegra>A</indRegra>
    <vItem>0.98</vItem>
    <vRatDesc>0.00</vRatDesc>
    <vRatAcr>0.00</vRatAcr>
</prod>

050303.JPG

 

 

Qualquer duvida estou a disposição.
Att

Cristiano Abbud

 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Fundadores

O que ocorre, é que:

   0.99 x 0.995 = 0,98505,  e pelas Regras da ABNT, quando o número a ser eliminado é igual a 5 deve-se primeiro observar se o seu antecessor é impar, se for, já soma-se 1 na casa de arredondamento.  Porém no nosso caso, temos 8, então observa-se uma segunda regra...Se houve algum "resto, após a casa a arredondar, então soma-se1 na casa a arredondar... (esse é o nosso caso)

No caso de dúvida, façam a mesma venda no emulador de ECF, (que permita arredondamento e 3 decimais na QTD). Os ECF sempre usaram a regra de arredondamento da ABNT

 


IMPRESSORA FISCAL BEMATECH MP-4200 TH FI
      APENAS PARA DESENVOLVIMENTO
            SEM VALOR FISCAL
CNPJ: 82.373.077/0001-71 IM: ISENTO
------------------------------------------------
11/11/2015 12:35:10  CCF:000000008 COO:000000019
CUPOM FISCAL
ITEM CÓDIGO DESCRIÇÃO QTD. UN. VL UNIT(R$) ST VL ITEM(R$)
------------------------------------------------
001 111222333 TESTE DE PRODUTO 0,995 UNX0,990 N1           0,99

 

Se usarmos uma variável do Tipo 'Currency', para receber o valor da conta, o que ocorre é que o "Delphi", elimina as dizimas após a quarta casa... Veja esse tópico

portanto:

var
  currValorUnit, currQtde, currTotal: Currency;
begin
  currValorUnit :=0.99;
  currQtde :=0.995;
  currTotal := currValorUnit * currQtde;    
  // 0.99 x 0.995 = 0,98505, porém "currTotal" é um currency, que somente usa 4 casas decimais, portanto será: 0,9850

Nesse caso, o RoundABNT(currTotal, 2) será igual a  0.98, pois não haverá "resto" apos a casa a ser arredondada (0.9850)

  • Curtir 2
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

  • 5 meses depois ...
  • Membros Pro

Pessoal, boa tarde, sei que o fórum está um pouco antigo, mas ainda no mesmo assunto de arredondamento, hoje me deparei com um retorno da função RoundABNT(... que segundo o pessoal da DIMEP, está errado.

Exemplo de um valor calculado entre a quantidade x Vr.Unitário

1 x 4,885 = 4,88 Correto segundo a DIMEP

Utilizando a função RoundABNT(4.885, 2) = 4,89 (Errado segundo a DIMEP)

Orientações passadas pela DIMEP.

Quando a terceira casa decimal for Inferior a 5, a segunda decimal, é mantida sem alteração: 1,333333 para 1,33     

Quando a terceira casa decimal for Superior a 5 ou Igual a 5 seguido de pelo menos 1 algarismo diferente de zero,  a segunda decimal, é aumentada de 1 unidade: 1,666666 para 1,67 2,345001 para 2,35

Quando a terceira casa decimal for igual a  5 seguido de zeros, a segunda decimal, é arredondada para o algarismo “par” mais próximo: 4,555000 para 4,56 4,885000 para 4,88     

 

Realizei o teste no SAT da DIMEP e calculou no XML = 4,88.

Alguém tem alguma solução, onde tem uma função correta que realiza o cálculo igual o SAT da DIMEP?  
 

 

 

Link para o comentário
Compartilhar em outros sites

  • Fundadores

Rodou os testes unitários da ACBrDiversos ??

Fiz o teste em ACBrComumTesteCase... em Delphi XE7 e Lazaus... em ambos os casos... o RoundABNT retorna 4.88

  dblValorUnit := 4.885;
  dblQtde := 1;
  dblTotal := dblValorUnit * dblQtde;
  CheckEquals( 4.88, RoundABNT(dblTotal, 2), 0.00001);

 

  • Curtir 1
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

Daniel a função que você usou eu achei ela na internet, esta tem um terceiro parâmetro que é o Delta = 0.00001 que ao ser enviado retorna correto, porém no ACBrUtil.pas que tenho aqui nos fontes do ACBr tem a mesma função sem o terceiro parâmetro Delta que dá errado, para solução eu copiei a função que tem o terceiro parâmetro e colei no fonte do meu sistema com nome diferente e estou usando ela. Funcionou!!

Link para o comentário
Compartilhar em outros sites

  • Fundadores

É aconselhado manter seus fontes idênticos ao do ACBr...

O delta é necessário se você usa float... O Delphi tem uma dificuldade enorme de compara floats, ( não percebo esse problema no Lazarus)

Se vc trabalha com no máximo 4 casas decimais, use Currency

Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

Link para o comentário
Compartilhar em outros sites

  • Membros Pro

//Declaração

function RoundABNT(const AValue: Double; const Digits: SmallInt; const Delta: Double = 0.00001): Double;

 

//Função

function TdmPaf.RoundABNT(const AValue: Double; const Digits: SmallInt; const Delta: Double): Double;
var
  Pow, FracValue, PowValue: Extended;
  RestPart: Double;
  IntCalc, FracCalc, LastNumber, IntValue: Int64;
  Negativo: Boolean;
begin
  Negativo := (AValue < 0);

  Pow := intpower(10, abs(Digits));
  PowValue := abs(AValue) / 10;
  IntValue := trunc(PowValue);
  FracValue := frac(PowValue);

  PowValue := SimpleRoundTo(FracValue * 10 * Pow, -9); // SimpleRoundTo elimina dizimas ;
  IntCalc := trunc(PowValue);
  FracCalc := trunc(frac(PowValue) * 100);

  if (FracCalc > 50) then
    Inc(IntCalc)

  else if (FracCalc = 50) then
  begin
    LastNumber := round(frac(IntCalc / 10) * 10);

    if odd(LastNumber) then
      Inc(IntCalc)
    else
    begin
      RestPart := frac(PowValue * 10);

      if RestPart > Delta then
        Inc(IntCalc);
    end;
  end;

  Result := ((IntValue * 10) + (IntCalc / Pow));
  if Negativo then
    Result := -Result;
end;

 

Link para o comentário
Compartilhar em outros sites

Daniel, vou checar, posso estar tumultuando por ser meio burrinho, mas tentei abntround entre outras, e quando o cupom tem muitas incidências de produtos de fracionados, da falha de dizima e da rejeição no SAT.

Nos ECF quando raramente acontecia eu lia o subtotal e concertava o valor do item, no sat, nao dá.

 

Obrigado.

Link para o comentário
Compartilhar em outros sites

  • 6 anos depois...
  • Membros Pro
Em 18/04/2016 at 18:44, Daniel Simoes disse:

Há alguma diferença dessa implementação e da existente em ACBrUtil ??

Daniel, boa tarde, estou tendo esse problema para produtos que são vendidos fracionados por peso, essa ACBrUtil tem a versão para utilizar no .Net? Onde está o download dela, sou membro Pro.

Link para o comentário
Compartilhar em outros sites

  • Moderadores
18 minutos atrás, Gustavo.Vicente disse:

Daniel, boa tarde, estou tendo esse problema para produtos que são vendidos fracionados por peso, essa ACBrUtil tem a versão para utilizar no .Net? Onde está o download dela, sou membro Pro.

Boa tarde.

não lembro se foi colocado em dll para ser usado. mas basicamente tu pode pegar a função e converter para acredito eu C# ou até mesmo pegar na internet pois é o Round usando fielmente as regras da ABNT

Consultor SAC ACBr Juliomar Marchetti
 

Projeto ACBr

skype: juliomar
telegram: juliomar
e-mail: [email protected]
http://www.juliomarmarchetti.com.br
MVP_NewLogo_100x100_Transparent-02.png
 

 

Link para o comentário
Compartilhar em outros sites

  • Este tópico foi criado há 856 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.

The popup will be closed in 10 segundos...