Jump to content

2 Dia do ACBr

Visite Stands dos Patrocinadores
Control iD, CS Devices, Elgin, Gertec, Bematech, Jetway, PlugMobile, Epson, Custom e Sweda
Inscreva-se

Nova Loja Oficial
loja.projetoacbr.com.br
Ajude o projeto a crescer, com estilo

Comprar

Balança SM100 performance surpreendente

Tecnologia Japonesa   Teclado e Visor resistentes a água
Consumo inteligente de etiquetas   Baixo custo de manutenção
Comunicação Ethernet e WIFI independentes

Saiba mais

Impressora de Etiquetas ELGIN - L42 PRO

Protocolos PPLA, PPLB, ZPL, EPL (automático)
Porta USB padrão Opcionais: Ethernet, Serial, Paralela
Sensor de Etiquetas Móvel Garantia de 18 meses

Saiba mais

Leaderboard


Popular Content

Showing content with the highest reputation since 06/23/2018 in all areas

  1. 16 points
    Foto por David Siglin em Unsplash. Olá pessoal, É bom quando encontramos uma ferramenta que facilita ou melhora nosso trabalho, não? Todos devem ter notado que ultimamente temos enviado vários commits ao SVN de remoção de warnings e hints, muitas vezes mencionando a ferramenta FixInsight. Para quem não conhece, essa ferramenta faz uma análise do seu código e aponta possíveis erros e sugere otimizações. Ela é uma ferramenta muito boa, tanto que foi comprada pela TMS e se tornou TMS FixInsight. Já tem um tempo que conheço a ferramenta e sempre tive o desejo de rodá-la em todo o código do ACBr. Mas devido ao tempo não tinha sido possível. Depois de um incentivo (valeu @Waldir Paim), eu resolvi baixar a versão trial e fazer isso. E que bom que fiz. Gostaríamos de compartilhar com vocês algumas coisas que encontramos no nosso código com a ajuda dessa ferramenta. Encontrando pequenos problemas num código gigante Vamos começar por um código que estava no ACBrValidador. Vejam esse código, onde a função ValidarCEP de baixo chama a função ValidarCEP de cima, e tente encontrar um problema: function ValidarCEP(const ACEP, AUF: String): String; begin Result := ValidarDocumento( docCEP, ACEP, AUF); end; function ValidarCEP(const ACEP: Integer; AUF: String): String; begin ValidarCEP( FormatarCEP(ACEP), AUF ); end; Conseguiu ver o problema? Essa função nunca retornaria que um CEP é inválido se você passasse o CEP como inteiro. Precisava de um “Result := ” no início. Simples? Nem tanto quando lembramos do tamanho do projeto ACBr. Temos mais de 200 componentes e mais de 779 mil linhas de código, contribuídos por dezenas ou talvez centenas de programadores, embora a nossa equipe de commiters seja realmente pequena. Só a unit ACBrValidador.pas em questão tem atualmente cerca de 2070 linhas. Não fica muito mais fácil quando uma ferramenta aponta pra você? [FixInsight Warning] ACBrValidador.pas(294): W521 Return value of function 'ValidarCEP' might be undefined Vamos a outro exemplo no pacote ACBrSerial, componente ACBrECF: [FixInsight Warning] ACBrECFDaruma.pas(4638): W503 Assignment right hand side is equal to its left hand side Veja o código (só a parte interessante): else if StrToIntDef(fsNumVersao, -1) >= 345 then begin RetCmd := EnviaComando( ESC + #240 ); RetCmd := Copy(RetCmd, 92, Length(RetCmd)); RetCmd := RetCmd; //<--- Viu aqui??? for A := 0 to fpAliquotas.Count-1 do begin fpAliquotas[A].Total := RoundTo( StrToFloatDef(Copy(RetCmd,(A*14)+1,14),0) / 100, -2 ); end; end; end; Uma linha que não faz absolutamente nada a não ser gastar espaço, memória e CPU. Uma linha desnecessária a menos no código. E você consegue encontrar um no seu aplicativo código que nunca será executado? Ainda no mesmo pacote, veja esse exemplo:  [FixInsight Warning] ACBrECFDataRegis.pas(1838): W509 Unreachable code Nesse código: if (fsArqPrgBcoTXT <> '') and (not FileExists( fsArqPrgBcoTXT )) then begin Msg := ACBrStr( 'Arquivo '+fsArqPrgBcoTXT+' não encontrado. '+ 'Valores padrões serão utilizados.' ) ; raise EACBrECFErro.Create( Msg ); fsArqPrgBcoTXT := '' ; //Essa linha nunca vai ser executada porque tem um raise acima. end ; Mais uma vez, tente imaginar procurar esse problema num projeto tão grande. Não é facilmente percebido se você não tiver olhos treinados e estiver procurando problemas. Vamos a outro exemplo ainda no componente ACBrECF:  [FixInsight Warning] ACBrECFEscECF.pas(1222): W517 Variable 'CHK' hides a class field, method or property Veja esse código: procedure TACBrECFEscECFResposta.SetResposta(const AValue: AnsiString); Var Soma, I, F, LenCmd : Integer ; CHK : Byte ; begin O problema desse código é que ele confunde uma variável local (CHK) com uma propriedade da classe (TACBrECFEscECFResposta.CHK). É preciso analisar todo código em cada lugar que isso acontece para ter certeza quando você está se referindo a propriedade e quando é a variável. Imagine se você confunde uma com a outra. Uma hora você pensa que sua variável está recebendo valores estranhos. Outra hora você pensa que sua propriedade não está sendo atualizada. Nesse caso específico, a variável foi renomeada para vCHK evitando a confusão com a propriedade CHK. O importante é que quando você for ler o código, não precise ficar pensando “Isso aqui é uma variável ou uma propriedade?”. Veja outro exemplo, agora no ACBrSMS: [FixInsight Warning] ACBrSMSClass.pas(192): W511 Object 'ListaSMS' created in TRY block begin try Self.Clear; if not FileExists(APath) then raise EACBrSMSException.CreateFmt('Arquivo "%s" não encontrado.', [APath]); ListaSMS := TStringList.Create; ListaSMS.LoadFromFile(APath); if ListaSMS.Count = 0 then Exit; //(bla bla bla...) finally FreeAndNil(ListaSMS); end; Não é apropriado esse código. O correto é mover a criação do objeto para fora do try..finally. Pense bem, se o objeto não for construído, você não quer que ele seja destruído. A mensagem ajudou a perceber também que esse bloco poderia ser escrito de outra maneira. Aquele raise não precisava estar dentro do try..finally. Evitando problemas futuros Rodando no pacote ACBrOpenSSL tivemos a seguinte mensagem no componente ACBrEAD: [FixInsight Optimization] ACBrEAD.pas(268): O804 Method parameter 'AChavePublicaOpenSSL' is declared but never used Quer dizer, parâmetro ‘AchavePublicaOpenSSL’ declarado mas não utilizado. Veja abaixo a a parte importante da função: function TACBrEAD.ConverteChavePublicaParaOpenSSH( const AChavePublicaOpenSSL: String): String; Var Buffer, Modulo, Expoente: AnsiString; {...} begin // https://www.netmeister.org/blog/ssh2pkcs8.html CalcularModuloeExpoente(Modulo, Expoente); Buffer := EncodeBufferSSH('ssh-rsa') + EncodeHexaSSH(Expoente) + EncodeHexaSSH('00'+Modulo); Result := 'ssh-rsa '+ EncodeBase64(Buffer); end; É estranho esse método ConverteChavePublicaParaOpenSSH não utilizar o parâmetro da chavePública. Qualquer pessoa que visse o método e tentasse chamar passando a chave pública não teria o resultado desejado. Analisando o código melhor vemos que o componente lê a chave pública por meio do método “LerChavePublica”. Nesse caso o correto seria remover o parâmetro para que não haja nenhuma confusão. E essa mensagem no TACBrBALToledo2090: [FixInsight Warning] ACBrBALToledo2090.pas(107): W508 Variable is assigned twice successively if (Length(wStrListDados[1]) = 16) then wDecimais := 1000; {APENAS BLOCO PROCESSADO} wResposta := wStrListDados[1]; //<---- sobreposto pela linha seguinte wResposta := Copy(wStrListDados[1], 5, 7); if (Length(wResposta) <= 0) then Exit; Veja que os dados de uma linha é sobreposta pela outra. O compilador nunca daria um aviso sobre isso. Mais dois exemplos de mensagens e o código a seguir: [FixInsight Warning] ACBrEscEpsonP2.pas(97): W514 Loop iterator could be out of range (missing -1?) [FixInsight Warning] ACBrEscEpsonP2.pas(100): W514 Loop iterator could be out of range (missing -1?) For I := 0 to Length(cTAGS_BARRAS) do TagsNaoSuportadas.Add( cTAGS_BARRAS[I] ); For I := 0 to Length(cTAGS_ALINHAMENTO) do TagsNaoSuportadas.Add( cTAGS_ALINHAMENTO[I] ); Essa eu não sei como não foi detectada antes. Por algum motivo não está sendo emitida a mensagem estouro quando o valor de I chega a 16 no primeiro caso e 3 no segundo. Encontrando erros gerados por Ctrl+C..Ctrl+V No pacote ACBrPAF veja a mensagem gerada: [FixInsight Optimization] ACBrPAF_T_Class.pas(137): O804 Method parameter 'ACampo2' is declared but never used function OrdenarT2(const ACampo1, ACampo2: Pointer): Integer; var Campo1, Campo2: String; begin Campo1 := FormatDateTime('YYYYMMDD', TRegistroT2(ACampo1).DT_MOV) + TRegistroT2(ACampo1).TP_DOCTO + TRegistroT2(ACampo1).SERIE + TRegistroT2(ACampo1).NUM_ECF; Campo2 := FormatDateTime('YYYYMMDD', TRegistroT2(ACampo1).DT_MOV) + TRegistroT2(ACampo1).TP_DOCTO + TRegistroT2(ACampo1).SERIE + TRegistroT2(ACampo1).NUM_ECF; Result := AnsiCompareText(Campo1, Campo2); end; Essa função é utilizada para ordenar os registros T2 do PAF. Mas veja que ela compara o registro “ACampo1” com ele mesmo. Suspeita: Ctrl+C e Ctrl+V... Quem nunca??... Outra situação diferente, mas relacionada com ordenação apareceu no ACBrSintegra. Na verdade 4 situações no ACBrSintegra, semelhantes entre si. Vou mostrar apenas uma, mas dessa vez a mensagem do FixInsight fica pra depois. Vamos a um jogo dos sete erros entre os ifs e else no código abaixo: function Sort60A(Item1, Item2: Pointer): Integer; var witem1, witem2 : TRegistro60A; begin witem1 := TRegistro60A(Item1); witem2 := TRegistro60A(Item2); if witem1.Emissao>witem2.Emissao then begin if witem1.NumSerie>witem2.NumSerie then Result:=1 else if witem1.NumSerie=witem2.NumSerie then Result:=0 else Result:=-1; end else if witem1.Emissao = witem2.Emissao then begin if witem1.NumSerie>witem2.NumSerie then Result:=1 else if witem1.NumSerie=witem2.NumSerie then Result:=0 else Result:=-1; end else begin if witem1.NumSerie>witem2.NumSerie then Result:=1 else if witem1.NumSerie=witem2.NumSerie then Result:=0 else Result:=-1; end; end; Conseguiu encontrar os erros? Bem, se você procurou diferenças, não deve ter encontrado nada. E não existe mesmo. Veja a mensagem da ferramenta: [FixInsight Warning] ACBrSintegra.pas(3410): W507 THEN statement is equal to ELSE statement São dois if e um else pra fazer a mesma coisa... A correção foi remover o IFs e ELSE.  Agora vamos ao pacote ACBrSPED. Depois de remover muitos e muitos parâmetros desnecessários apontados pelo FixInsight, veja esse código: function CodAjToStr(const AValue: TACBrCodAj): string; begin if AValue = codAjAcaoJudicial then Result := '01' else if AValue = codAjAcaoJudicial then Result := '02' else if AValue = codAjLegTributaria then Result := '03' else if AValue = codAjEspRTI then Result := '04' else if AValue = codAjOutrasSituacaoes then Result := '05' else if AValue = codAjEstorno then Result := '06'; end; A mensagem é a seguinte: [FixInsight Warning] ACBrEPCBlocos.pas(2071): W512 Odd ELSE-IF condition (review lines 2071 and 2073) Viu lá? Os dois primeiros ifs estão comparando AValue com o mesmo valor, "codAjAcaoJudicial". O segundo deveria ser "codAjProAdministrativo". Provavelmente mais um Ctrl+C..Ctrl+V. Mensagens para otimização de código Nem todas as mensagens geradas são de erros. Algumas são mensagens de otimização. Muitos dos commits que temos feito estão relacionados a uma mensagem como estas abaixo: [FixInsight Optimization] ACBrSATClass.pas(776): O801 CONST missing for unmodified string parameter 'CNPJvalue' [FixInsight Optimization] ACBrSATClass.pas(776): O801 CONST missing for unmodified string parameter 'assinaturaCNPJs' Ela pode ser gerada numa função como essa: function TACBrSATClass.AssociarAssinatura( CNPJvalue, assinaturaCNPJs : AnsiString) : String ; begin ...// um código que não altera nenhum dos parâmetros citados end; Essas mensagens estão dizendo que os parâmetros 'CNPJvalue' e ‘assinaturaCNPJs’ do tipo string não estão sendo alterados dentro da função a que eles pertencem. Nesse caso é bem provável que os parâmetros devessem ter um prefixo CONST na sua declaração, como abaixo: function TACBrSATClass.AssociarAssinatura(const CNPJvalue, assinaturaCNPJs : AnsiString) : String ; begin ...// um código que não altera nenhum dos parâmetros citados end; Não vou entrar em muitos detalhes sobre isso, mas usar CONST tem alguns benefícios, principalmente em caso de strings: A execução é mais rápida, porque o compilador pode otimizar o código. No caso de strings, não tem contagem de referências; O compilador garante que você não vai alterar os parâmetros passados gerando um efeito colateral indesejado em quem chamou as funções; O código fica mais legível, porque você pode ler que a intenção é não alterar o parâmetro passado; Como os parâmetros são imutáveis, pode tornar o código mais ThreadSafe; Se quer saber um pouco mais sobre isso, recomendo os seguintes links: All hail the “const” parameters! Is the use of ‘const’ dogmatic or rational? Concluindo... Bom pessoal, ainda temos bastante pra fazer. Contudo, queremos dizer que o FixInsight tem nos ajudado melhorar nosso código. Ficamos tão satisfeitos que entramos em contato com a TMS e eles generosamente nos cederam uma licença da versão Pro pra continuar nosso trabalho. Muito obrigado TMS. Agora, se você quer nossa opinião, essa é uma ferramenta altamente recomendada e está disponível pra toda versão do Delphi a partir do Delphi 2006. Se você tem alguma dúvida, baixe a versão trial e comece agora mesmo a usar no seu código. A versão trial limita as mensagens a 5 por units e funciona por 30 dias. Mas é o suficiente pra se perceber como é muito útil, como aconteceu com a gente. Quer um passo a passo em como utilizá-la? Veja o próximo post logo abaixo.
  2. 15 points
    Boa tarde a todos! Gostaria de parabenizar o trabalho e a dedicação de toda a equipe, patrocinadores e empresas envolvidas, foi uma grande oportunidade e privilegio participar com todos vocês...Pena que foi só um dia!? Agradeço a todos que estiveram envolvidos nesse grande projeto. Essa equipe é sensacional:
  3. 13 points
    O que é o ACBrPosPrinter e Esc/Pos ? Para quem ainda não conhece, o ACBrPosPrinter é o nosso componente para acesso a Impressoras de Bobinas, Não fiscais... Essas impressoras, denominadas Impressoras POS (Point of Sale), contemplam uma linguagem de impressão de linha, interna, onde podemos realizar tarefas como: Modificar os atributos de impressão Imprimir códigos de barras 1D e 2D (QRCode) Acionar dispositivos ligados a Impressora, como Gaveta de Dinheiro, Guilhotina Ler status da Impressora (Tampa aberta, pouco ou sem papel, etc) No mercado brasileiro, há vários modelos, que contemplam várias linguagens, como por exemplo: EscPos, EscBema, EscDaruma, etc... As linguagens são chamadas de "Esc", pois os comandos geralmente iniciam com o caractere não imprimível, ESC ou #27... Exemplo: se enviarmos para a Impressora a String: chr(27) + 'E' + chr(01), ligaremos o modo Negrito A grande maioria dos fabricantes, procurou seguir o padrão Epson, que é a marca mundialmente líder nesse segmento, e a sua linguagem Epson Esc/Pos... O componente ACBrPosPrinter suporta a grande maioria das linguagens e modelos existentes no mercado brasileiro... mas nem todos os recursos, estão disponíveis em todas as linguagens... Usar o ACBrPosPrinter é extremamente simples, e não requer o conhecimento de Esc/Pos... Através de suas Tags, você pode construir ricos relatórios, com várias formatações de fontes, alinhamento, Imagens, códigos de barra e QRCode... A título de Exemplo, usamos o próprio componente ACBrPosPrinter, para criar o Extrato do SAT, Unit ACBrSATExtratoESCPOS.pas e o DANFCe, unit ACBrNFeDANFeESCPOS.pas Se você usa o ACBrMonitorPLUS, poderá acessar o ACBrPosPrinter pelo objeto ESCPOS... Veja no manual: https://acbr.sourceforge.io/ACBrMonitor/ESCPOSImprimirTags.html Você pode baixar um Demo compilado do ACBrPosPrinter em: Você pode baixar uma Apresentação sobre o ACBrPosPrinter em: Se você não programa em ObjectPascal (Delphi/Lazarus), pode baixar a biblioteca (DLL) ACBrLibPosPrinter em: https://www.projetoacbr.com.br/forum/files/category/35-acbrlibposprinter/ Sobre a Impressão de Imagens no ACBrPosPrinter A muito tempo eu sentia falta dos seguintes recursos, no componente ACBrPosPrinter Impressão de Imagens Gravação e manipulação de Logos na memória da Impressora... Agora isso já é possível... Após muita pesquisa, e com a ajuda de vários outros artigos que encontrei na Internet (veja referência nos fontes), consegui implementar a Impressão de Imagens no modo "Raster Image"... Devido a característica desses equipamentos, apenas a impressão de Imagens monocromáticas é suportada. Existem vários sites de conversão de Imagem, para BMP Monocromático, on-line, como por exemplo: https://online-converting.com/image/convert2bmp/ Novos métodos no componente ACBrPosPrinter procedure ImprimirImagemStream(ABMPStream: TStream); // Permite Imprimir uma Imagem, no formato BMP Monocromático, de um Stream procedure ImprimirImagemArquivo(ArquivoBMP: String); // Carrega e imprime uma Imagem de um Arquivo. Em aplicações visuais (não console) será usado o Objeto TPicture, que permite carregar vários formatos de Imagem, podendo ser Colorida ou em Escala de cinza. A Imagem será convertida para BMP Monocromática. Entretanto, procure sempre usar Imagens BMP Moncromáticas, para evitar processamento desnecessário procedure ImprimirImagemRasterStr(const ARasterStr: AnsiString; AWidth, AHeight: Integer); // Imprime uma Imagem a partir de uma String no formato "Raster Image" (veja abaixo) procedure ImprimirLogo(AKC1: Integer = -1; AKC2: Integer = -1; AFatorX: Integer = -1; AFatorY: Integer = -1); // Imprime um Logo préviamente gravado na memória da Impressora. Se os parâmetros não foram informados, serão usados os valores de ACBrPosPrinter.ConfigLogo procedure GravarLogoStream(ABMPStream: TStream; AKC1: Integer = -1; AKC2: Integer = -1); // Grava uma Imagem de Logo, no formato BMP Monocromático, a partir de um Stream, nas posições informadas. Se os parâmetros não foram informados, serão usados os valores de ACBrPosPrinter.ConfigLogo procedure GravarLogoArquivo(ArquivoBMP: String; AKC1: Integer = -1; AKC2: Integer = -1); // Grava uma Imagem de Logo, a partir de um arquivo em Disco, nas posições informadas. Se os parâmetros não foram informados, serão usados os valores de ACBrPosPrinter.ConfigLogo procedure ApagarLogo(AKC1: Integer = -1; AKC2: Integer = -1); // Remove um Logo da memória da Impressora. Se os parâmetros não foram informados, serão usados os valores de ACBrPosPrinter.ConfigLogo Nova Tag de Bloco <bmp> - Imprime Imagem BMP monocromática. Conteúdo pode ser: Path da Imagem, Stream em Base64 ou AscII Art (0 e 1) Veja alguns exemplos de uso: Inicializa </zera>, define o alinhamento no centro </ce>, e efetua a impressão da Imagem em disco, no Path "C:\temp\acbrmono.bmp" </zera></ce><bmp>C:\temp\acbrmono.bmp</bmp> Imprimir uma Imagem de BMP Mono, codificada em Base64 <bmp> Qk3eDQAAAAAAAD4AAAAoAAAA+gAAAG0AAAABAAEAAAAAAKANAAAAAAAAAAAAAAIAAAAAAAAAAAAAAP///wD/////////////////////////////////////////wP/////////////////////////////////////////A/////////////////////////////////////////8D/////////////////////////////////////////wP4AAAAAAAAAAAAAAA8A8AAAAAAAAAAAAAAAAAAAAD/A/AAAAAAAAAAAAAAADwD4AAAAAAAAAAAAAAAAAAAAD8D4AAAAAAAAAAAAAAAPAHwAAAAAAAAAAAAAAAAAAAAHwOAAAAAAAAAAAAAAAA8APgAAAAAAAAAgAAAAAAAAAAHAwAAAAAAAAAAAAAAADwAfAAAAAAAAAcAAAAAAAAAAAcDAAAAAAAAAAAAAAAAPAA+AAAAAAAAfgAAAAAAAAAAAwIAAAAAAAAAAAAADgAQAB8AAAAAAAH+AAAAAAAAAAABAgAAAAAAAAAAAAACAAAABAAAAAAAAAAAAAAAAAAAAAEAAAAAADDvjnnNn489ngHw4zM+cPM/MD8w7PO4AAAAAAAAAAAAMN+e/c2fn7+/A/nzMz9x+z8wP7Hd27gAAAAAAAAAAAA/2ZnNzZ2YO7ODGxszf3ODOzAxsdx7uAAAAAAAAAAAABmZmc3Nj7gfs4cDGzN/c4MfMDO4ffu4AAAAAAAAAAAAH5mYzd2BmYOzBwObuzNzmxMwPzgdg7gAAAAAAAAAAAAfGb55+5+fHx4HAfP/Pn3zHzAzvvz7uAAAAAAAAAAAAA8AGAAAAAAAAAO4AAAAAAAAMDOAAAA4AAAAAAIAAAAADwAIAAAAAB4AA/AAAMAAAwAwPwAAA7gAAAABAgAAAAAAAAAAAAAAADwA4A+H/4AADwAAAAAAAAAAAAEDAAAAAAAAAAAAAAAAPAAAB//4AAAfAAAAAAAAAAAAAwOAAAAAAAAAAAAAAAA8AAAD/8AAAB4AAAAAAAAAAAAHA8AAAAAAAAAAAAAAADwAAAH/AAAAHAAAAAAAAAAAAA8D4AAAAAAAAAAAAAAAPAAAAPAAAAA4AAAAAAAAAAAAHwP4AAAAAAAAAAAAAAA8AAAAAAAAAHgAAAAAAAAAAAB/A/////////////////////////////////////////8D/////////////////////////////////////////wP/////////////////////////////////////////A/////////////////////////////////////////8D///////gAP///Af////gA//////+Af//4B///////wP///+AAeAB4AB4D+AAB/ADwAAAAf+B4AHgH///////A////4AA4AHgAHgfgAAB+APAAAAAH8HgAeAf//////8D////wADgAeAAeD4AAAB8A8AAAAAHweAB4B///////wP////AAPABwABw+AAAAB4DwAAAAAHx4AHgH///////A////+AA///AAPD4AAAAHwPAAAAAAPHgAeAf//////8D////4AB//8AA4eAAAAAHg8AAAAAAeeAB4B///////wP////wAH//wAHj4AAAAAeDwAAAAAB54AHgH///////A/////AAf/+AAePAAAAAA8PAAAAAADngAeAf//////8D////8AAAAAADx4AAAAAD48AAAAAAPeAB4D///////wP////wAAAAAAPHAAAAAAHjwAAAAAA94AHgP///////A/////gAAAAAA48AAP8AAOPAAP/gAB3gAeA///////8D////+AAAAAADjwAB/4AA48AA//AAH+AB4D///////wP////8AAAAAAe+AAP/wADzwAD/+AAf4AHgf///////A/////wAAAAAB/4AB8PgAPPAAOf4AB/gAeB///////8D/////AAAAAAP/AAHgfAAc8AA7zgAH+AB4H///////wP////+AAAAAA/8AA8A8AP7wAD/+AAd4AHg////////A/////4AAAAAD5wADgBwH/vAAP/4AD3gAeD///////8D/////wAH/AAePAAOAHB/+8AA//AAPeAA4P///////wP/////AAf8ABw8AA4Af/8DwAD/gAA54ADg////////A/////8AB/gAPDwAHgB//APAAAAAAHngAPH///////8D/////4AH+AA8PAAeAD+AA8AAAAAA+eAAf////////wP/////gAf4ADw8AB4APgADwAAAAAHx4AB/////////A/////+AA/gAf7wAHgAwAAPAAAAAA+HgAH////////8D/////8AD8AB//AAeAAAAA8AAAAAfweAAHP///////wP/////wAHwAH/8AB4AAAADwAAAAB+B4AAAf///////A//////gAfAA8fwAHgA4AAPAAAAAB8HgAAA///////8D/////+AB4ADwPAAOAH+AA8AAAAADweAAAD///////wP/////4ADgAeA8AA4Af/gDwAAAAAHh4AAAP///////A//////wAMAB4BwADgB//+PAAP/AAPHgAgAf//////8D//////AAwAHAHAAPAHP/+8AA/+AA8eACAB///////wP/////+ADAA8AcAAfx8A/7wAD/4ADx4AMAD///////A//////4AEADgB4AB//gAPPAAODgAHHgA4AP//////8D//////gAQAOAHgAD/+AA88AA8+AAeeADwB///////wP//////AAAB4AOAAH/gADjwAD/4AB5////////////A//////8AAAHgA8AAP8AAOPAAP/gAHn///////////8D//////wAAA8ABwAAAAAB48AA/wAAef///////////wP//////gAADwAHgAAAAAPDwAAAAABwAAH/////////A//////+AAAOAAOAAAAAA8PAAAAAAPAAAf////////8D//////8AAB4AA+AAAAAHg8AAAAAA8AAD/////////wP//////wAAHgAB4AAAAA8DwAAAAADgAAf/////////A///////AAA8AAD4AAAAHwPAAAAAA/AAD/////////8D//////8AADwAAPgAAAA+A8AAAAAD+AAP/////////wP//////4AAPAAAfgAAAHwDwAAAAAf4AB//////////A///////gAA4AAAfgAAB+APAAAAAHzwAP/////////8D///////AAHgAAA/gAAfwA8AAAAD/PgA//////////wP/////////8AAAB////8AD//////wfAH//////////A//////////wAAAB////gAP//////88A//////////8D//////////gAAAB///4AB////////4H//////////wP//////////AAAAAP/wAAHgAAAAB//w///////////A//////////+AAAAAAHAAA8AAAAAAf/n//////////8D//////////8AAAAAAcAAHwAAAAAAB////////////wP//////////4AAAAABwAAeAAAAAAAAf///////////A///////////wAAAAAHAADwAAAAAAAA///////////8D///////////gAAAAAcAAeAAAAAAAAH///////////wP///////////AAAAABwAD4AAAAAAAA////////////A////////////AAAAAHAAeAAAAAAAAH///////////8D///////////8AAAAAeAD4AAAAAAAA////////////wP///////////4AAAAB4APAAAAAAAAH////////////A////////////4AAAAHgB4AAAAAAAB////////////8D////////////wAAAAeAPAAAAAAAAP////////////wP////////////wAAAB4B8AAAAAAAD/////////////A/////////////gAAAHgHgAAAAAAAf////////////8D/////////////AAAAOA8AAAAAAAD/////////////wP/////////////AAAA4HwAAAAAAA//////////////A//////////////AAADgeAAAAAAAP/////////////8D//////////////AAAPHwAAAAAAD//////////////wP//////////////AAA8eAAAAAAA///////////////A///////////////AADz4AAAAAAH//////////////8D///////////////AAPeAAAAAAD///////////////wP///////////////gA/4AAAAAA////////////////A////////////////wD/AAAAAA////////////////8D////////////////wH4AAAAAP////////////////wP////////////////4fAAAAAH/////////////////A//////////////////8AAAAP/////////////////8D//////////////////8AAA///////////////////wP/////////////////////////////////////////A/////////////////////////////////////////8D/////////////////////////////////////////wA== </bmp> Imprimir uma Imagem, baseado em ASCII ART Na Unit ACBrImage.pas, do pacote ACBrComum, é onde a mágica acontece... essa Unit implementa os seguintes métodos function IsPCX(S: TStream; CheckIsMono: Boolean = True): Boolean; // Retorna True se o Stream contém uma Imagem em PCX function IsBMP(S: TStream; CheckIsMono: Boolean = True): Boolean; // Retorna True se o Stream contém uma Imagem em BMP procedure RasterStrToAscII(const ARasterStr: AnsiString; AWidth: Integer; InvertImg: Boolean; AscIIArtLines: TStrings); // Converte uma String codificada em "Raster Image", para ASCII ART procedure AscIIToRasterStr(AscIIArtLines: TStrings; out AWidth: Integer; out AHeight: Integer; out ARasterStr: AnsiString); // Converte uma String codificada em ASCII ART para "Raster Image" procedure BMPMonoToRasterStr(ABMPStream: TStream; InvertImg: Boolean; out AWidth: Integer; out AHeight: Integer; out ARasterStr: AnsiString); // Converte uma Imagem no formato BMP Monocromático, gravada em um Stream, para uma String codificada em "Raster Image" procedure RasterStrToBMPMono(ARasterStr: AnsiString; AWidth: Integer; InvertImg: Boolean; ABMPStream: TStream); // Converte uma String codificada e "Raster Image", para uma Imagem no formato BMP Monocromático, gravando-a em um Stream {$IfNDef NOGUI} procedure BitmapToRasterStr(ABmpSrc: TBitmap; InvertImg: Boolean; out AWidth: Integer; out AHeight: Integer; out ARasterStr: AnsiString; LuminosityThreshold: Byte = C_LUMINOSITY_THRESHOLD); // Apenas disponível se a aplicação não for console. converte uma Imagem de um TBitMap, para uma String codificada e "Raster Image" {$EndIf} Use a força, leia os fontes Não deixe de estudar os fontes do Projeto Demo, PosPrinterTeste, na pasta: \ACBr\Exemplos\ACBrSerial\ACBrPosPrinter\Delphi Nesse projeto há vários exemplos de como Imprimir Imagens, e manipular Logotipos, usando as Tags e Métodos do componente ACBrPosPrinter O que é o modo "Raster Image" ? O Modo Raster é um fluxo de Bytes que representam os Pixels da Imagem... https://pt.wikipedia.org/wiki/Raster Exemplo: Imagine a Seguinte imagem, de 16 x 16 Pixels... Se fôssemos representá-la em ASCII ART, teríamos: 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 1010101010101010 Para transformá-la em Raster, agrupamos os Bits, em Bytes (8 bits)... portanto a primeira linha ficaria: Em Binário: 10101010 + 10101010 Em Hexa: AA + AA Em Decimal: 170 + 170 Então a String em Raster Image, da Imagem acima seria o equivalente a: #170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170+#170 Para imprimir uma String em Raster, é fundamental sabermos qual a largura em Pixels, da imagem A Epson disponibiliza utilitário, para converter imagens para o formato Raster: Epson BmpToRaster (o estudo do conteúdo do arquivo gerado por esse Utilitário, foi essencial na implementação dos métodos de ACBrImage)
  4. 13 points
    Olá pessoal, Na postagem "Como obter o XML do Fornecedor" mostrei o uso do método DistribuicaoDFePorChaveNFe, nessa nova postagem vou mostrar mais dois métodos: DistribuicaoDFePorUltNSU e DistribuicaoDFePorNSU. Vamos a sintaxe, que por sinal é semelhante ao do DistribuicaoDFePorChaveNFe. DistribuicaoDFePorUltNSU( <código da UF do destinatário>, <CNPJ do destinatário>, <numero do ultimo NSU> ) DistribuicaoDFePorNSU( <código da UF do destinatário>, <CNPJ do destinatário>, <numero do NSU> ) Primeiramente vamos entender o que vem a ser esse tal de NSU. NSU - numero sequencial único, é um numero atribuído pelo Ambiente Nacional ao documento ora compartilhado pelas SEFAZ-Autorizadora. Exemplo: o emitente da nota é do Estado de São Paulo, logo a nota é enviada para a SEFAZ-SP esta por sua vez vai compartilhar com o Ambiente Nacional as notas que foram autorizadas, o Ambiente Nacional por sua vez atribui um NSU para cada nota que receber. Na verdade o Ambiente Nacional gera um resumo da nota e atribui o NSU a esse resumo primeiramente e não a nota propriamente dita. Um NSU só será atribuído a nota quando o destinatário enviar o evento de Manifestação do Destinatário. Lembre-se o NSU da nota será um numero diferente do NSU do resumo dela, e por ser gerado após o envio do evento de Manifestação do Destinatário, podemos concluir que o NSU da nota é maior que o NSU do resumo. Vamos agora entender como funciona os dois métodos mencionados acima. O método DistribuicaoDFePorNSU é o mais simples de entender, pois este simplesmente baixa o documento que possui o NSU informado. Note que usei o termo documento, pois o webservice DistribuicaoDFe pode retornar os seguintes tipos de documentos: Resumo de Nota, Nota Completa, Resumo de Evento e Evento Completo. Se o NSU informado no método DistribuicaoDFePorNSU for o NSU de um resumo, o que teremos como retorno será o XML do resumo e não o XML da Nota. Por outro lado o método DistribuicaoDFePorUltNSU nos retorna uma lista com até 50 documentos, cujos NSU são superiores ao NSU informado. Exemplo: DistribuicaoDFePorUltNSU( 35, 12345678000123, 450 ) ===> 450 é o valor do Ultimo NSU. Ao executar o método, como dito anteriormente poderá nos retornar uma lista com até 50 documentos, pois bem suponha que retorne 50, os NSU desse documentos retornados serão, 451, 452, 453, ...., 498, 499, 500. Lembre-se que nessa lista podemos ter Resumos de Notas, Notas Completas, Resumo de Eventos e Eventos Completos. Através de uma propriedade chamada Schema nos traz a informação do tipo de documento retornado. Temos também outras duas propriedades muito importantes, são elas: UltNSU e MaxNSU. A propriedade UltNSU nos informa o numero do NSU referente ao ultimo documento da lista, já a propriedade MaxNSU nos informar o maior NSU existente no Ambiente Nacional. Continuando o exemplo acima, vamos supor que após a execução os valores de UltNSU e MaxNSU são respectivamente 500 e 750. Era de se esperar mesmo que o valor de ultNSU seja 500 pois informamos 450 e foi retornado 50 documentos, logo o NSU do ultimo é 500. A próxima vez que formos executar o DistribuicaoDFePorUltNSU devemos informar o valor 500, para que ele retorne os documentos a partir de 501 que é o próximo da lista. E devemos repetir o procedimento até que o valor de ultNSU seja igual a maxNSU, desta forma vamos ter baixado todos os documentos disponibilizados pelo Ambiente Nacional. Lembre-se que o valor de MaxNSU tende sempre a crescer a medida que novas notas forem emitidas e compartilhadas com o Ambiente Nacional e a medida que o destinatário for enviando o evento de Manifestação do Destinatário. Entre uma execução e outra do DistribuicaoDFePorUltNSU você pode realizar a manifestação referente a cada resumo de nota obtido, ou seja, enviar o evento de Manifestação do Destinatário. Desta forma a medida que você vai avançando na lista o Ambiente Nacional já vai liberando a Nota Completa (notas manifestadas) e disponibilizando ela na lista. O DistribuicaoDFe não serve apenas para que possamos obter o XML do fornecedor, mas também descobrirmos se existe alguma empresa emitindo notas contra o nosso CNPJ sem no nosso consentimento. Você descobre isso através do DistribuicaoDFePorUltNSU e pode avisar a SEFAZ enviando o evento de Manifestação do Destinatário: Desconhecimento da Operação. Esse evento diz a SEFAZ que você não comprou desse fornecedor. Para saber mais sobre Manifestação do Destinatário vide a Nota Técnica 2012/002 versão 1.02 e para saber mais sobre o Distribuição DFe vide a Nota Técnica 2014/002 versão 1.02b, ambas estão disponíveis no Portal Nacional da NF-e.
  5. 12 points
    Olá a todos, Para quem não sabe nas configurações do componente ACBrNFe, temos dentro do grupo Arquivos um subgrupo chamado DownloadNFe, que contem as propriedades PathDownload e SepararPorNome. Através dessas duas propriedades definimos o caminho onde os XML retornados pelo método DistribuicaoDFe vão ser salvos e se desejamos separar por nome ou não. A primeira alteração realizada foi a migração da definição dessas propriedades de configuração da unit ACBrNFeConfiguracoes para ACBrDFeConfiguracoes. A motivação para essa mudança é que a definição dessas propriedades também se encontravam nas units ACBrCTeConfiguracoes, ACBrMDFeConfiguracores e ACBrBPeConfiguracoes, agora temos em apenas um lugar, ou seja, na unit ACBrDFeConfiguracoes. Com essa mudança temos uma redução de código e caso futuramente tenhamos alguma correção ou melhoria, elas serão feitas em apenas um lugar, desta forma agilizando o tempo de manutenção do código. Como nem tudo são flores, quem tem em seu código as linhas para configurar o Download deverá fazer a seguinte alteração para que a aplicação seja compilada com sucesso (exemplo no caso da NF-e): Antes: ACBrNFe.Configuracoes.Arquivos.DownloadNFe.PathDownload Alteração: ACBrNFe.Configuracoes.Arquivos.DownloadDFe.PathDownload Falando em melhoria, antes tínhamos uma função chamada GetPathDownload que tem como finalidade gerar o Path final onde será gravado os XML referentes aos Resumos de Notas e Notas Completas. Agora além da função citada acima temos também a função GetPathDownloadEvento que tem como finalidade gerar o Path final onde será gravado os XML referentes aos Resumos de Eventos e Eventos Completos. O que motivou a criar essa nova função é que antes o DistribuicaoDFe ao salvar os XML referentes aos eventos estava usando o mesmo Path dos eventos enviados, ou seja, estava misturando os eventos enviados com os eventos baixados pelo DistribuicaoDFe. Resumindo, a primeira alteração visou a redução de código nos componentes ACBrNFe, ACBrCTe, ACBrMDFe e ACBrBPe e a segunda visou organização dos XML baixados pelo método DistribuicaoDFe. Qualquer duvida ou problemas, favor postar no fórum.
  6. 10 points
    Pessoal É com grande alegria que venho agradecer o meu presente por ter sido o primeiro a fazer a inscrição E parabenizar a todos pelo evento
  7. 9 points
    Bom dia a todos, Foi feito uma generalização nas Units: pcnConsCad, pcnRetConsCad, pcnConsStatServ, pcnRetConsStatServ, pcnDistDFeInt e pcnRetDistDFeInt. A motivação é porque elas aparecem de forma repetidas com nomes diferentes nos fontes dos componentes ACBrNFe, ACBrCTe, ACBrMDFe e ACBrBPe. A generalização e migração para a pasta PCNComum faz com que tenhamos mais controle das correções e melhorias, sem falar na redução de código. Infelizmente ao generalizar o pcnRetDistDFeInt ocorreu uma quebra de código, pois se fez necessário alterar o nome de uma classe e de algumas propriedades publicas. Para quem usa o DistribuicaoDFe será necessários fazer alguns ajustes no código da aplicação. Trocar os resNFe por resDFe e chNFe por chDFe (para quem baixa as Notas). Trocar os resCTe por resDFe e chCTe por chDFe (para quem baixa os Conhecimentos). Trocar os resMDFe por resDFe e chMDFe por chDFe (para quem baixa os Manifestos).
  8. 9 points
    Estão todos de parabéns, foi um ótimo evento e estaremos no próximo com certeza! Palestras esclarecedores e uma fonte enorme de promovermos o contato profissional! A única dúvida que ficou no ar é quem é @BigWings kkkkkk
  9. 8 points
    É com muita satisfação que recebemos a ELGIN, como patrocinadora do Dia do ACBr... Participe do Dia do ACBr e conheça os produtos e a equipe técnica da ELGIN... Conheça a Plataforma Fiscal Elgin, que será lançada no Evento
  10. 8 points
  11. 7 points
    Olá Pessoal, Muitos tem interesse em obter o XML do fornecedor para facilitar a entrada dos materiais no Estoque, Contas a Pagar, etc. Segundo a legislação, quem emite uma NF-e tem por obrigação legal de disponibilizar o XML assinado e com o protocolo de autorização ao destinatário da mercadoria, assim que a SEFAZ autorizar a nota. Essa disponibilização pode ser feita por e-mail, ou seja, o emitente envia para o destinatário o XML via e-mail. Sabemos que isso nem sempre ocorre, por 2 motivos: 1. No cadastro do destinatário não consta o endereço de e-mail; 2. A aplicação do emitente não possui esse recurso ou esta desativado. Mas temos uma alternativa. Com certeza o DANFE foi impresso e entregue junto com a mercadoria. De posse do DANFE temos a chave e com ela podemos primeiramente enviar o evento de Manifestação do Destinatário. Temos duas situações: 1. Se as mercadorias foram entregues conforme o combinado, devemos enviar o evento: Confirmação da Operação (Código: 210200); 2. Se algo estiver errado e alguma mercadoria esta errada, quebrada, ...., devemos enviar o evento: Operação não Realizada (Código: 210240), neste evento se faz necessário informar uma justificativa. Após manifestar todas as notas, podemos obter o XML através do método: DistribuicaoDFePorChaveNFe, esse método possui 3 parâmetros, sendo eles: Código da UF do Destinatário, CNPJ do Destinatário e a Chave da NF-e previamente manifestada. Conclui-se que devemos executar o método acima para cada nota manifestada. Informação importante, tanto a Manifestação do Destinatário quanto o Distribuição DF-e, são atendidos pelo Ambiente Nacional, portanto não tem nada haver com a SEFAZ-Autorizadora do emitente da nota ou do destinatário da mercadoria. Se algo falhar nesse processo, a "culpa" é do Ambiente Nacional.
  12. 7 points
    Sim, pensei nisso... alias essa foi a decisão mais difícil... Há prós e contras... fazer um evento desse porte em SP é no mínimo 4x mais caro... (porém é bem mais rápido de vender) No fim, os fatores decisivos, para escolher o Interior, foram: O (terrível) transito de SP, e as espaçosas acomodações do Parque Tecnológico de Sorocaba
  13. 7 points
    Olá pessoal. Temos novidades na área das impressões dos DF-e. Com o objetivo de facilitar o trabalho e reduzir a duplicação de código, estamos promovendo um refactoring nas classes de impressões de DF-e. Essas alterações ainda não foram enviadas ao SVN, mas queremos avisar com antecedência para que todos possam se preparar. Fizemos um vídeo para explicar os objetivos e as principais alterações. Você pode acessar aqui: Mas... se você não é muito fã de vídeos, vou resumir os principais pontos nesse tópico. Os objetivos desse refactoring são: Diminuir código duplicado; Padronizar os componentes de impressão; Isso vai simplificar o trabalho com componentes diferentes; Minimiza a necessidade de aprender vários detalhes diferentes; Melhor organização de código; Mais fácil pra você ler, entender e debugar o código; Lançar base para melhorias futuras; Podemos resumir a principal diferença como: Agora há classes para padronizar o comportamento mesmo em componentes de impressão diferentes. Na nova estrutura os componentes de impressão herdam da classe base TACBrDFeReport (unit ACBrDFeReport.pas) que se encontra no pacote ACBrDFeComum. Esta classe visa englobar todas as propriedades e/ou métodos que são usados por todas as impressões DFe. Por exemplo: PathPDF, CasasDecimais, etc.. Se assemelha a esse organograma: Veja algumas propriedades que foram alteradas, removidas ou mudaram de nome: Essas são as modificações principais. Podem haver outras, mas acreditamos que são menores e darão menos dor de cabeça. A previsão é enviar ao SVN antes do Dia do ACBr. Assim que enviarmos ao SVN vou postar uma nova mensagem aqui.
  14. 7 points
    Gostaria de deixar registrado meus agradecimentos a todos que colaboram com esse projeto, principalmente por solucionar situacoes criticas (Software-houve - Cliente ) do qual me sinto segunro em sempre usar esse pacote maravilhoso (acbrmonitorplus) integrador show de bola. Obrigado a todos mais uma vez
  15. 6 points
    Opa! Não entendi muito bem sua pergunta. Mas vamos lá... Caso queira baixar notas fiscais emitidas CONTRA o CNPJ do seu cliente. Deve-se utilizar o método de DistribuicaoDFe. (Aqui uma explicação, e aqui um exemplo prático) Observação 1: você consegue baixar um resumo das notas fiscais para que seja possível você realizar o manifesto. Após o evento de manifestação o Ambiente Nacional disponibiliza o XML da nota em questão. Observação 2: O Ambiente Nacional disponibiliza o resumo/DFe apenas se o seu cliente for o Destinatário, Transportadora ou o CNPJ estiver na tag <AutXML>. Caso queira RECUPERAR um ou mais XML EMITIDO pelo seu cliente. Deve-se alimentar o componente com os dados da venda/nota, assinar e consultar. (Aqui um exemplo prático) Observação 1: Não é muito indicado ficar fazendo isso. Já que na lei diz que o contribuinte é obrigado guardar o XML do documento fiscal. Observação 2: Caso você tenha o XML assinado, você pode carregar o XML e executar o método Consultar apenas... Dessa forma o XML será atualizado com o protocolo. Observação 3: O único método oficial pela SEFAZ é realizar o download do documento fiscal diretamente pelo portal, utilizando o certificado digital. Sites como Arquivei lite fornece um XML válido porém sem validade jurídica já que a assinatura não é a do emitente.
  16. 6 points
    Boa tarde a todos, Vocês devem ter notado que os componentes mencionados ao configurar para o ambiente de teste devemos atribuir o valor taHomologacao a propriedade de configuração: Ambiente. Mas ao alimentar qualquer evento o valor atribuído ao campo tpAmb tem que ser taProducaoRestrita que nada mais é do que um ambiente de teste, ou seja, homologação. Não me perguntem porque os responsáveis pelo e-Social e Reinf resolveram chamar o ambiente de teste de Produção Restrita em vez de Homologação. É sabido que o tipo de ambiente informado na configuração tem que ser o mesmo ao alimentar os dados do evento, para facilitar a vida resolvi remover o campo tpAmb. Isso vai fazer com que ao compilar a sua aplicação após a atualização dos fontes da suíte ACBr vai ocorrer erros de compilação, apontando para o campo tpAmb e acusando o mesmo de não existir. Como proceder? Simples, remova a linha da sua aplicação que contem o campo tpAmb nas rotinas que alimentam os eventos. A geração da tag <tpAmb> vai conter o valor atribuído ao configurar o componente. Se o valor de Ambiente = taProducao a tag receberá o valor 1, por outro lado se for igual a taHomologacao receberá o valor 2 que é o mesmo valor de taProducaoRestrita. Com essa alteração nos componentes ACBreSocial e ACBrReinf nunca mais vai ocorrer de um evento ser rejeitado pelo fato do tipo de ambiente informado no XML ser diferente do ambiente para o qual foi enviado. O envio dessa alteração para o repositório ocorra amanhã (29/03/2019).
  17. 6 points
    Bom dia, ALA. Sugiro assinar o SAC para que você possa ter acesso a todo o conteúdo do Dia do ACBr, documentos, vídeos, download e muito mais! Lembrando que você pode assinar um mês, sem cobranças futuras! É uma boa oportunidade e uma grande fonte de conhecimento... Para contratar o SAC, veja esse link: https://www.projetoacbr.com.br/forum/sac/sobre/
  18. 6 points
    https://www.embarcadero.com/products/rad-studio/whats-new-in-10-3-rio Lembrando que o Delphi Communitty Edition também é atualizado. basta usar o mesmo instalador.
  19. 6 points
    Ola.. Galera.. Seguindo a Recomendaçao do icaro.. vamos la. Já fui um Cara forte e fraco, ja´foi o Doutor Hass, e ja fui tambem Mestre Jedi. Atualmente sou o Senhor dos Windevs. e Porque isso. Eu sempre postei videos, aulas, ha muitos anos,tenho muitos blogs, e videos. mas a 3 e meio conheci o windev, e paixao a primeira vista. quando eu estava aprendendo, eu ja fazia video, e virou o sucesso que é hoje. Ja dava aula em cursinho em 88, e posso dizer que ja consegui fazer muitos virarem programadores, e ganham seu dinheiro hoje. e ate hoje faço isso. Posso dizer que depois que me for , ficarei na eternidade. Atualmente preciso chegar a 1000 inscritos , e ja estou com 824. Se quizerem se inscrever no canal vamos la.. convido a todos. Canal Youtube: Amarildo Matos
  20. 6 points
    Nessa página do Portal, temos um bom índice de como achar, Info, Manual e Download do MonitorPLUS https://www.projetoacbr.com.br/acbr-monitor-plus/
  21. 5 points
    Bom dia pessoal, Com a versão 3.00a do CT-e temos um novo evento chamado Comprovante de Entrega. Esse evento é emitido pela própria transportadora e não pelo destinatário da mercadoria. Nesse evento temos um campo obrigatório chamado hashEntrega, cuja descrição: Hash (SHA1) no formato Base64 resultante da concatenação: Chave de acesso do CT-e + Base64 da imagem capturada da entrega (Exemplo: imagem capturada da assinatura eletrônica, digital do recebedor, foto, etc) Nota 1: A critério do autor deste evento, este campo pode ser utilizado como índice para acesso as informações do Comprovante de entrega. Nota 2: A SEFAZ não tem nenhum controle sobre a informação deste campo. Observação: 28 caracteres são representados no schema como 20 bytes do tipo base64Binary. Nesse primeiro momento o componente não esta calculado o hash ficando a cargo da aplicação do desenvolvedor, pois vamos verificar a possibilidade de implementar. Para quem utiliza o ACBrMonitor abaixo segue um exemplo de como montar o arquivo INI do evento de Comprovante de Entrega: [EVENTO] idLote=1 [EVENTO001] chCTe= chave do CT-e cOrgao= Codigo da UF CNPJ= CNPJ do emitente dhEvento=25/07/2019 10:30:00 tpEvento=110180 nSeqEvento=1 nProt= numero do protocolo de autorização do CT-e dhEntrega=24/07/2019 17:30:00 nDoc= Documento de identificação da pessoa que recebeu a entrega xNome= Nome da pessoa que recebeu a entrega latitude= Latitude do ponto da entrega (detectado pelo equipamento do transportador, exemplo: PDA, tablet, celular) longitude= Longitude do ponto da entrega (detectado pelo equipamento do transportador, exemplo: PDA, tablet, celular) hashEntrega= Hash (SHA1) no formato Base64 resultante da concatenação: Chave de acesso do CT-e + Base64 da imagem capturada da entrega (Exemplo: imagem capturada da assinatura eletrônica, digital do recebedor, foto, etc) dhHashEntrega= Data e hora da geração do hash da entrega ; xxxx pode variar de 0001 até 2000 [infEntregaxxxx] chNFe= chave da NF-e da mercadoria que foi entregue Para quem utiliza o componente, abaixo temos um exemplo de como enviar o evento em questão: ACBrCTe1.EventoCTe.Evento.Clear; with ACBrCTe1.EventoCTe.Evento.New do begin infEvento.chCTe := ChaveCTe; infEvento.CNPJ := CNPJEmitente; infEvento.dhEvento := now; infEvento.tpEvento := teComprEntrega; infEvento.nSeqEvento := 1; infEvento.detEvento.nProt := nProtocoloAutorizacao; infEvento.detEvento.dhEntrega := datahoraEntrega; infEvento.detEvento.nDoc := NumeroDocumento; infEvento.detEvento.xNome := NomedoRecebedor; infEvento.detEvento.latitude := fLatitude; infEvento.detEvento.longitude := fLongitude; infEvento.detEvento.hashEntrega := hashdaEntrega; infEvento.detEvento.dhHashEntrega := datahhoradoHashEntrega; InfEvento.detEvento.infEntrega.Clear; // o bloco abaixo poderá se repetir por até 2000 vezes with InfEvento.detEvento.infEntrega.New do chNFe := ChaveNFe; end; ACBrCTe1.EnviarEvento( 1 ); // 1 = Numero do Lote
  22. 5 points
    Boa tarde, Remova o percurso, quando a UF de inicio faz divisa com a UF de fim não se deve informar o percurso. Detalhe, quanto informar o percurso, devemos colocar somente as UFs entre a de inicio e fim, por exemplo: UFIni = SP UFFim = RS ==> Percurso: PR; SC
  23. 5 points
    Bom dia a todos, Na pasta: ...\Exemplos\ACBrDFe\Schemas\CTe temos os schemas: cteTiposBasico_v3.00.xsd cteTiposBasico_v3.00_Homologacao.xsd O schema cteTiposBasico_v3.00_Homologacao contempla as mudanças ocorridas na estrutura do XML do CT-e na versão 3.00a, já o outro não contempla. Até o dia 25/08/2019 devemos usar o arquivo cteTiposBasico_v3.00 em nossos clientes uma vez que eles estão emitindo os CT-e em produção. Para aqueles que desejam realizar os testes no ambiente de Homologação deverão seguir os passos abaixo: rename cteTiposBasico_v3.00.xsd cteTiposBasico_v3.00_Producao.xsd rename cteTiposBasico_v3.00_Homologacao.xsd cteTiposBasico_v3.00.xsd A partir do dia 26/08/2019 deveremos enviar para os nossos clientes o arquivo cteTiposBasico_v3.00_Homologacao renomeado para cteTiposBasico_v3.00 Isso se a SEFAZ comprir com as datas publicadas.
  24. 5 points
    De forma semelhante ao material disponibilizado pela SEFAZ-MG, a SEFAZ-SP também publicou em seu portal a relação das regras de validação facultativas a UF da NT 2019.001 as quais a mesma exigirá. Clique aqui para visualizar a tabela publicada no portal da SEFAZ-SP.
  25. 5 points
    Boa tarde! Enquanto aguardamos o teu arquivo, aproveito para alerta-lo sobre o CST do IPI. No XML que você postou a operação é de saída e você colocou código CST de IPI como de entrada. Aproveite e corrija isto também, pois poderá ter alguma complicação mais tarde ou receber um email da SEFAZ, já que agora eles estão solicitando as informações do grupo técnico Teu XML: A partir de 01/04/2010 os contribuintes do IPI deverão utilizar a seguinte Tabela de CST/IPI: SAÍDAS 50 – Saída Tributada 51 – Saída Tributável com Alíquota Zero 52 – Saída Isenta 53 – Saída Não Tributada 54 – Saída Imune 55 – Saída com Suspensão 99 – Outras Saídas ENTRADAS 00 – Entrada com Recuperação de Crédito 01 – Entrada Tributada com Alíquota Zero 02 – Entrada Isenta 03 – Entrada Não Tributada 04 – Entrada Imune 05 – Entrada com Suspensão 49 – Outras Entradas
  26. 5 points
    Bom dia Sergio, o interessante é você consultar um analista contábil pra te ajudar nesse quesito, ele saberá (ou ao menos deveria) responder todos seus questionamentos acerca do assunto com maior exatidão. Há várias regras e situações diferentes para cada empresa, então fica complicado lhe passar como são feitos os cálculos sendo que pode resultar em problemas futuros, ao menos em minha opinião, não é mesmo? Abraço
  27. 5 points
    E quando terceiros prestam serviço de manutenção? Quem é o responsável técnico? Dúvidas assim podem surgir quando fixamos na mente mais a ideia de um "representante da classe de programação" perante a lei do que na ideia de um responsável pelo sistema. Talvez isso aconteça porque o termo usado é "responsável técnico". Logo nos vem a mente um engenheiro responsável pela obra e tal... Mas veja bem, a ideia do responsável técnico, é ter uma "pessoa" para quem a Sefaz vai mandar um e-mail quando quiser falar sobre o software emissor do DF-e. Como dito antes, suponha que o software emissor tentou retransmitir a mesma NF-e com erros no XML, por 70.000 vezes... ou seja, mesmo recebendo o erro de rejeição por XML inválido, a aplicação ficou em algum Loop, tentando retransmitir o mesmo XML que já sabia era rejeitado, isso por 70 mil vezes. Nesse caso, quem a SEFAZ deveria contatar? Pensar nesses termos, nos ajuda a entender o motivo das tags Responsável Técnico e assim saber como preencher. Vamos a dois exemplos, com base nas perguntas desse link: Imagine uma microempresa, distribuidora de produtos de limpeza, que para emitir a notas fiscais, paga a um programador fazer as alterações nos fontes de um sistema emissor. Esse programador é pessoa física. Como fica esta situação? Não se engane. A resposta depende mais do tipo do vínculo entre eles e menos de o programador ser uma pessoa física. A questão que deve ser respondida é: Quem é o responsável pelo software? Quem a SEFAZ deve contatar caso queira falar sobre o sistema? Isso vai depender de cada caso e talvez de cada UF. Responder algumas perguntas podem ajudar a resolver a questão: Atualmente, o sistema é da ME distribuidora de produtos de limpeza? O programador é chamado como um terceirizado ou mesmo como funcionário temporário da empresa, não tendo de fato vínculo com o sistema? Por exemplo, ele pode ser substituído por outro programador? (Note, não importa aqui o conhecimento interno do sistema...) Se a resposta a essas perguntas for sim então, a menos que algo diferente esteja em contrato, o responsável técnico é a empresa distribuidora de produtos de limpeza.  Ela contrata outra pessoa para dar manutenção mas, ainda assim, ela é responsável, porque o sistema é dela. No PAF-ECF, chamávamos isso de "sistema próprio". Quer dizer próprio da empresa. Não é um sistema que ela aluga. Caso alguma resposta para as perguntas for não, então, provavelmente, o responsável técnico é o programador. Será necessário verificar com a UF como ele deve ser informado já que ele não tem CNPJ. No caso da empresa ter uma pessoa que saiba programação e faça estas alterações mas não é programador registrado e sim diretor ou gerente ADM, como fica? Nesse caso, sem dúvida, o responsável técnico é a própria empresa. Ela tem um sistema próprio, desenvolvido internamente para emitir os DF-e. Não importa se quem faz as alterações é um programador ou o contínuo da empresa. O importante é quem é responsável perante a SEFAZ e, nesse caso, é claro que a SEFAZ não vai querer saber quem deu manutenção no sistema. Quando ela precisar falar com um responsável, ela vai querer contatar diretamente a empresa. Afinal de contas, se a empresa não quisesse isso ela teria contratado um sistema de alguém ao invés de permitir um funcionário (ou sobrinho do dono) criar o sistema.
  28. 5 points
    Pesquisando sobre esse erro, encontrei um tópico que indica que um problema no logo poderia gerar especificamente este erro. Sendo assim, queira por favor atualizar e verificar se as alterações propostas hoje corrigem o problema do logo e também esse.
  29. 5 points
    Um ótimo evento, com certeza só tende a crescer. Foi uma experiência legal, com um ótimo Networking.
  30. 5 points
    Alguns membros do Fórum estão recebendo e-mail indicando um cupom, permitindo desconto nas inscrições do Dia do ACBr. Isso é verdade ! O melhor é que agora você pode ter acesso a esse desconto diferenciado. Para os "de longe" e os "de muito longe" podemos avaliar descontos melhores. Fale conosco pelo [email protected] Agora você ainda não decidiu, seja rápido, pois esse cupom tem quantidade limitada e curto período de validade. Acesse o formulário de inscrição e aplique o código [email protected] no campo indicado conforme abaixo:
  31. 5 points
    Questão: "NT 2018.002 - idCSRT do responsavel técnico pelo aplicativo emissor. Onde adquirir esse codigo?" Resposta SEFAZ/MG em 18/09/2018:
  32. 5 points
  33. 5 points
    Porque nem o Padre Quevedo conseguiria usar a versão 4.00 sem receber um TimeOut Tá bom ACBr, pode me enviar meu boné, por favor?
  34. 5 points
    Ok, acho que foi falha de interpretação da minha parte... Eu pessoalmente acho que a Elgin derrapou no final, em não atuar de forma mais conclusiva nas doações das impressoras... Mas em nenhum momento a Elgin disse que não irá cumprir com o prometido... As impressoras estão sendo entregues, e as falhas estão sendo tratadas... Todos os canais para tratar as falhas, estão abertos, inclusive eu mesmo me dispus a ajudar, nesse mesmo tópico... Em tempo... não faço parte da Elgin, e não recebi nada pelas palestras... mas como o convite partiu do ACBr, eu me sinto no direito de interceder pelos usuários do ACBr... Mas não é muito legal, vir fazer propaganda de fabricante B, sendo que quem promoveu as palestras e distribuiu os brindes, foi o fabricante A... (todo o evento foi gratuito) Convide o fabricante B, para fazer o mesmo que o Fabricante A fez... pode ser em outro estado... 4 palestras e aproximadamente 300 impressoras doadas...
  35. 4 points
    Veja que a última chave no seu arquivo .ini não está formatada corretamente:
  36. 4 points
    Veja como está carregando o XML para o componente NotasFiscais.LoadFromFile(<xml>, True) <--- com True pode dar o erro Experimente colocar NotasFiscais.LoadFromFile(xml) que já passa False como parâmetro
  37. 4 points
    Boa tarde a todos, Hoje recebi um e-mail da SEFAZ-RS: A emissão de NF-e segue sempre 2 regulamentações: a legislação tributária, e as especificações técnicas. A utilização das séries 890 a 899 na emissão em contingência está prevista na legislação tributária, no dispositivo que vocês mencionaram. Porém, até o momento o CONFAZ não publicou nenhuma Nota Técnica com as especificações para a utilização dessas séries. Por isso, a utilização dessas séries ainda não foi implementada. Ela será implementada assim que o CONFAZ publicar uma Nota Técnica com as especificações. Há uma proposta de alterar os efeitos do Ajuste 13/18 para março de 2020, no que tange a séries específicas, no âmbito do CONFAZ. O assunto ainda está sendo discutido pelos grupos nacionais, buscando a melhor solução com menos impacto para as empresas e para os Fiscos.
  38. 4 points
    Boa tarde, Muito obrigado pela postagem. Já se encontra disponível no repositório tanto a atualização dos schemas bem como do componente que visa atender a Nota Técnica em questão. Favor atualizar todos os fontes de todas as pastas. Reinstalar a suíte ACBr usando o ACBrInstall_Trunk2 deixando marcado a opção para apagar os arquivos antigos.
  39. 4 points
    Boa tarde. O responsável técnico somente será aceito em produção em abril. Veja este tópico Att.
  40. 4 points
    Bom dia. Obrigada pelas informações pessoal, caso obtenham retorno de outras UFs, podem continuar nos atualizando. Segue link do tópico explicativo criado pelo @Italo Jurisato Junior, oque também contem as respostas de algumas SEFAZ. Att. A dúvida é se não será exigido todo o grupo Responsável Tecnico ou se somente não exigirão o IDCSRT (estamos tentando obter esta informação também)
  41. 4 points
    Sim o recomendado é trocar por isso é colocado o "deprecated", já para ir avisando as pessoas que o método não é o mais recomendado.
  42. 4 points
    Bom dia, Veja também esse vídeo, é importante para realizar as configurações iniciais e tem um arquivo .ini com os dados da NFe em Anexo.
  43. 4 points
    Eu costumo ouvir musicas dos anos 80.
  44. 4 points
    RESOLVIDO! Verifiquei os fontes do método e nele tem o parâmetro aDisposition : TMailAttachmentDisposition. Por padrão ele está setado para "adInline". Pelo que entendi, ele tenta incorporar no Body o conteúdo. Mudei para adAttachment e resolveu o problema. FMail.AddAttachment(ArquivoXML, '', adAttachment);
  45. 4 points
    serviço da Sefaz-BA normalizado.... Consultado normal as chaves de acesso atuais e chaves de acesso já autorizadas.
  46. 4 points
    Falta o encerramento do comando no final do arquivo:
  47. 4 points
    Exatamente, por aqui também. Não tem um natal que programadores e suporte não passam com esse tipo de "evento" criado pelo governo, kkkk
  48. 4 points
    O erro é típico de versão do OpenSSL antiga, que ainda não suporta TLS1.2 Pegue (todas) as DLLs da pasta "\ACBr\DLLs\OpenSSL\1.0.2.13\x86", e copie na mesma pasta do seu .EXE
  49. 4 points
    Tenta assim: var I: integer; begin ACBrNFe1.SSL.ListaCertificados.Clear; ACBrNFe1.SSL.LerCertificadosStore; For I := 0 to ACBrNFe1.SSL.ListaCertificados.Count-1 do begin LOG.Lines.Add('Encontrado!'); LOG.Lines.Add(ACBrMDFe1.SSL.ListaCertificados[I].CNPJ); end; end;
  50. 4 points
    Bom dia Altamiro, Primeiramente peço que procure anexar o arquivo e não colocar o seu conteúdo como parte do texto da postagem. Esse erro de validação esta ocorrendo porque você colocou no seu arquivo INI as seções: [infNFxxx] e [infNFexxx] sendo que só pode existir apenas uma delas. Em um CT-e podemos colocar "n" seções infNFe ou infNF mas não podem aparecer ambas as seções. Essas seções contem informações referente ao nota emitida pelo remetente da mercadoria. Você concorda que o remetente ou emitiu uma NF-e ou uma NF (comum de papel)? Resumindo em um arquivo INI só pode existir a sesção InfNFe ou só a infNF, ambas já mais.
×
×
  • Create New...