Jump to content

Promoção de Natal SAC Mensal

Contrate e ganhe 1 Kit agenda + Caneta
Saiba mais

LANÇAMENTO
Curso Completo - Dominando o ACBrMonitor

Conheça o Curso

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 12/10/2018 in all areas

  1. 16 points
    Olá pessoal! Temos o prazer de informar que mais um novo componente foi adicionado ao projeto: ACBrLCDPR. O ACBrLCDPR foi criado para facilitar a geração do LCDPR - Livro Caixa Digital do Produtor Rural. Esse componente segue a mesma ideia de outros componentes para geração de arquivos como ACBrSPEDFiscal, ACBrSPEDPISCOFINS, ACBrSEF2, etc... Com ele você pode gerar o arquivo sem se preocupar com o layout do arquivo. A sua preocupação será apenas com as informações que precisa aprensentar. Como é um componente novo, temos consciência de que alguns ajustes talvez sejam necessários. Todos podem ficar à vontade reportar problemas. Podem fazer isso por criar um novo tópico com ajustes e anexar nele. Crie o tópico no subfórum ACBrTXT -> Outros (ACBrLFD, ACBrSEF2, etc). Mas queremos agradecer ao @Willian Hübner que pôs a mão na massa e fez a doação do componente que serviu como base dessa versão. Queremos também aproveitar a oportunidade para agradecer aos nossos usuários SAC. Seu apoio nos ajuda a continuar avançando.
  2. 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.
  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. 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.
  5. 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).
  6. 7 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
  7. 7 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.
  8. 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
  9. 6 points
    Visulizar Arquivo Como agregar valor ao software com dados fiscais e gerenciais inteligentes Por: Marco Polo Viana Forneça informações fiscais e gerenciais que já estão no seu sistema e não são exploradas. Eles podem alertar os usuários preventivamente de riscos e cenários importantes Autor Daniel Simoes Enviado 24-09-2019 Categoria Dia do ACBr 2a edição  
  10. 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).
  11. 5 points

    Version 1.0.0

    51 downloads

    Veja o vídeo da Palestra Não sabe direito nem o que é um boleto e seu cliente está te apertando para colocar no sistema? Nunca ouviu falar nem de remessa, nem de retorno? Pode ficar tranquilo, o Bruto vai te guiar pelas noções desse mundo de boletos. OU, já fez tudo o que tinha que fazer, mas não sabe exatamente qual propriedade preencher pra gerar o valor que o banco pede na posição 130 a 135? O bruto vai te ensinar a dissecar os fontes do componente até as entranhas dele para descobrir tudo o que você necessita.
  12. 5 points
    07/10/2019 Ativadas as regras do QRCode em Produção e desativação da regra G234 Comunicamos que as regras de preenchimento do QRCode do CT-e passaram a ser obrigatórias no ambiente de produção desde as 09:00 de hoje (07/10). Também informamos que a regra de validação G234 (Rej. 786) que verifica a EC87 está suspensa na SVRS conforme definido em reunião do grupo técnico do CT-e realizada em BH no dia 01/10/2019. Regra G234 que esta suspensa, ou seja, não será validada pela SEFAZ: Se Tipo do CT-e= 0 (Normal), 3 (Substituição) ou 1 (Complemento de Valores) na Operação interestadual com Tipo de Serviço Normal, Destinatário não contribuinte (tag IE do destinatário não informada) e Tomador diferente de remetente e não contribuinte (indIEToma=9) Grupo de informações da partilha do ICMS com a UF de fim da prestação deve estar preenchido
  13. 5 points
    Bom dia a todos, Esse provedor esta fazendo a checagem de fora errada. Devemos gerar o XML do RPS, assinar e depois colocar dentro do grupo GerarNfseEnvio. A ideia é a mesma da NF-e, onde devemos gerar o XML da NF-e, assinar e depois colocar dentro do grupo enviNFe. Mas sabe como é, os caras querem ser diferentes, são os bam bam bam dos documentos fiscais eletrônicos. Mas como dizia o meu pai, eles são novos, daqui umas 10 semanas santa eles aprendem. Com a reforma tributaria que se Deus quiser vai sair, a nota fiscal de serviço vai ser unificada a nota fiscal de venda de produtos. Isso significa que vamos utilizar a NF-e para emitir as notas fiscais de serviço em todo o território nacional. Vai demorar um pouco, mas existe uma luz no fundo do túnel. E quando isso ocorrer vou ter o prazer de diz Bye Bye provedores.
  14. 5 points
    Bom dia @magnosystem Estamos implementando o registro de Boletos via WebServices incorporado ao componente ACBrBoleto, utilizando a mesma estrutura dos dados, inclusive já foi implementado para o Banco Caixa e está disponível na pasta Branches do Projeto no SVN. Mas seus fontes serão muito úteis para implementar o BB nos mesmos moldes, podemos utilizar o que você implementou. Obrigado!
  15. 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
  16. 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.
  17. 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.
  18. 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
  19. 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.
  20. 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.
  21. 5 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.
  22. 4 points
    há várias dessas linhas no seu Log... 07/12/2019 10:25:54 - Unable to open file "C:\acbr\entnfe.txt" 07/12/2019 10:25:57 - EFOpenError - Unable to open file "C:\acbr\entnfe.txt" isso não é normal... Provavelmente você está criando o arquivo de entrada diretamente... e não criando-o primeiro em um arquivo temporário... Veja o Fluxo, definido no manual: https://acbr.sourceforge.io/ACBrMonitor/ACBrMonitor.html
  23. 4 points
    Nao sou tao velhinho kkkkk basic, clipper, foxpro,
  24. 4 points
    Pessoal, Meu primeiro contato com programação também foi com um CP-500 isso em 1989 e depois um solution 16 boas lembranças
  25. 4 points
    Perfeito @Compusofts.. enviado para o SVN... Rev 18288
  26. 4 points
    Já, especialmente se todos os usuários acessam a mesma instância do seu executável. O ideal é que seu sistema seja instalado em cada usuário, cada um em uma pasta separada.
  27. 4 points
    Boa tarde Emilio, O seu XML esta errado. Você já esta incluindo nele o grupo <cteProc>, grupo este que só é incluído depois que a SEFAZ retorna o protocolo de autorização. A chave esta errada, você informa que o cCT é 229 mas na chave coloca 219. Outra coisa o valor cCT não pode ser igual a nCT no seu XML estão igual. Isso é o que notei logo quando abri ele. Eu no seu lugar seguiria os conselhos do Daniel. Em vez de ler as informações do banco de dados e gerar o XML, gere o arquivo INI e deixa o Monitor fazer o resto por você. Garanto que terá menos dor de cabeça.
  28. 4 points
    Chegamos a marca de 3 webservices distintos para Blumenau, agora SimplISS já pode pedir música no Fantástico. Eu já tenho empresas usando os outros dois webservices(wsblumenau e migracao) e agora vou ter no terceiro(wsblumenau1), porque ainda tenho problemas em 3 clientes referentes a assinatura. ou seja, pessoal se não der certo a emissão em um, bola pra frente e colocamos para enviar no próximo. Desde que não tenha o 4 webservice já estamos de bom tamanho;
  29. 4 points
    Olá pessoal, A SEFAZ-MS esta passando por instabilidade no processamento de CT-e, a recomendação é que os CT-e sejam enviados para a SVC-RS. Leia a noticia da SEFAZ-MS na integra. http://www.cte.ms.gov.br/instabilidade-do-ambiente-autorizador-do-ct-e-autorizar-via-svc-rs/ Favor atualizar todos os fontes de todas as pastas e reinstalar a suíte ACBr, pois foi necessário fazer um ajuste no código do componente conforme a recomendação da SEFAZ-MS. Lembre-se de que para enviar para o SVC é preciso fazer duas coisas: Primero configurar o componente: // (AC,AL,AP,AM,BA,CE,DF,ES,GO,MA,MT,MS,MG,PA,PB,PR,PE,PI,RJ,RN,RS,RO,RR,SC,SP,SE,TO); // (12,27,16,13,29,23,53,32,52,21,51,50,31,15,25,41,26,22,33,24,43,11,14,42,35,28,17); case rgTipoEmissao.ItemIndex of 0: ACBrCTe.Configuracoes.Geral.FormaEmissao := teNormal; 1: if ACBrCTe.Configuracoes.WebServices.UFCodigo in [14, 16, 26, 35, 50, 51] then ACBrCTe.Configuracoes.Geral.FormaEmissao := teSVCRS else ACBrCTe.Configuracoes.Geral.FormaEmissao := teSVCSP; end; Segundo alimentar corretamente o componente: // (AC,AL,AP,AM,BA,CE,DF,ES,GO,MA,MT,MS,MG,PA,PB,PR,PE,PI,RJ,RN,RS,RO,RR,SC,SP,SE,TO); // (12,27,16,13,29,23,53,32,52,21,51,50,31,15,25,41,26,22,33,24,43,11,14,42,35,28,17); case rgTipoEmissao.ItemIndex of 0: Ide.tpEmis := teNormal; 2: if ACBrCTe.Configuracoes.WebServices.UFCodigo in [14, 16, 26, 35, 50, 51] then Ide.tpEmis := teSVCRS else Ide.tpEmis := teSVCSP; end;
  30. 4 points
    Olha no supermecado "DIA" aqui de São José do Rio Pardo, eles imprimem um extrato dos produtos com os dados que voce queira e em seguida um CUPOM SAT SIMPLIFICADO. Ai nos dados dos produtos do extrato voce pode colocar mais informações do que o Layout do extrato com produtos É uma idéia que deve ser conferida, não conferi ainda por falta de tempo.
  31. 4 points
    Bom dia, Italo, MG está difícil demais, é uma verdadeira sacanagem com nós, principalmente em se tratando de NFCe, Já reportei ontem pra SEFAZ/MG, varias situações, mas nada de retornarem. Vamos aguardar pra ver o que resolvem. Tendo algum retorno da Sefaz, repasso a vocês. Grato a todos, Davidson
  32. 4 points
    Visulizar Arquivo Palestra de Abertura Explicação Geral Sobre o Evento. Visão Geral sobre o ACBr. Conheça funcionamento um Projeto de Código Aberto. Conheça a Equipe e o dia a dia de trabalho Saiba dos planos futuros do ACBr Veja o vídeo da Palestra Autor Daniel Simoes Enviado 24-09-2019 Categoria Dia do ACBr 2a edição  
  33. 4 points
    Foi enviada uma correção ao SVN favor baixar, recompilar e refazer os testes.
  34. 4 points
    Veja que a última chave no seu arquivo .ini não está formatada corretamente:
  35. 4 points
    Bom dia. Veja também nossa área relativa aos requisitos Fiscais por UF . Att.
  36. 4 points
    bom dia e possivel sim segue um link ai com algumas informacoes
  37. 4 points
    Boa tarde Milton, O que diz a NT (vou colocar em negrito o que considero importante): Sendo assim, a partir dessa Nota Técnica será possível um contribuinte cancelar uma NFC-e que foi emitida em duplicidade. Esse tipo de situação pode acontecer quando um contribuinte emite uma NFC-e (NFC-e 1), porém, por algum motivo, não obtém resposta, ficando pendente de retorno, e em seguida emite outra NFC-e (NFC-2), normalmente em contingência, para acobertar a operação. Depois é verificado que a “NFC-e 1” também foi autorizada, e sendo assim temos duas NFC-e acobertando a mesma operação. Acontecendo isso, o contribuinte poderá solicitar o cancelamento, no prazo não superior a 168 horas, da NFC-e emitida em duplicidade e que não acobertou a operação (NFC-e 1), tendo que referenciar a NFC-e que substituiu (NFC-2) aquela que está sendo cancelada. Resumindo: Foi emitida a NFC-e 1 segundo o tipo de emissão Normal ( 1 ) para acobertar a venda 1. Como o estabelecimento comercial não obter resposta da SEFAZ informado que a nota foi autorizada ou não, foi emitida uma a NFC-e 2 exatamente igual a anterior, mas segundo o tipo de emissão Contingência ( 9 ). Verificou-se depois que ambas as notas foram autorizadas, logo uma tem que ser cancelada dentro do prazo de 168 horas. Conforme o descrito a nota a ser cancelada é a NFC-e 1, vide rotina abaixo: ACBrNFe1.EventoNFe.Evento.Clear; with ACBrNFe1.EventoNFe.Evento.Add do begin infEvento.chNFe := ' Chave da NFC-e cujo tpEmis = 1 (Normal), portanto é a nota a ser cancelada '; infEvento.CNPJ := CNPJ; infEvento.dhEvento := now; infEvento.tpEvento := teCancSubst; infEvento.detEvento.xJust := ' Justificativa, minimo 15 e máximo 255 caracteres '; infEvento.detEvento.nProt := Protocolo; infEvento.detEvento.cOrgaoAutor := 35; // Código da UF do emitente da nota infEvento.detEvento.verAplic := '1.0'; infEvento.detEvento.chNFeRef := ' chave de acesso da NFC-e substituta, tpEmis = 9 (Contingência offline), portanto nota a prevalecer '; end; ACBrNFe1.EnviarEvento(StrToInt(idLote)); Espero ter ajudado.
  38. 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.
  39. 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.
  40. 4 points
    Boa tarde. O responsável técnico somente será aceito em produção em abril. Veja este tópico Att.
  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
    O gmail pode estar identificando o XML como corpo do e-mail. Se você usa o componente ACBrMail diretamente para envio veja se está informando o parâmetro Disposition, ele por padrão é adInline o que pode confundir o cliente de email. Caso use o método EnviarEmail do ACBrNFe ele já deve ir dessa forma.
  43. 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.
  44. 4 points
    Eu costumo ouvir musicas dos anos 80.
  45. 4 points
    Boa tarde @jamil Na última versão foi disponibilizado uma nova propriedade onde é possível editar a Fonte dos itens da NFCe, utilizando outro tipo de fonte, "Arial" por exemplo, pode melhorar o espaçamento da descrição dos itens, de forma que não fique cortando na lateral. Também foi adicionado os métodos para impressão de imagem .BPM via ESCPOS conforme citado acima pelo Daniel. Favor consultar a documentação atualizada do Monitor com os novos métodos e Tags. A última versão foi disponibilizada com instalador em RPM...
  46. 4 points
    Bom dia. O Santander trabalha com o Código de Transmissão também, verifique esta propriedade. Att.
  47. 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);
  48. 4 points
    Publicado legislação da nfce em Minas Gerais. Fonte D.O.U. Jornal de 15/12/2018 http://www.iof.mg.gov.br/index.php?/ultima-edicao.html caderno1_2018-12-15 4.pdf caderno1_2018-12-14 31.pdf
  49. 4 points
    serviço da Sefaz-BA normalizado.... Consultado normal as chaves de acesso atuais e chaves de acesso já autorizadas.
  50. 4 points
    Falta o encerramento do comando no final do arquivo:
×
×
  • Create New...