Painel de líderes
Conteúdo popular
Showing content with the highest reputation on 21-02-2019 em Posts
-
Sempre acreditei que a informação deve ser algo democrático e acessível... Pensando nisso, tornei pública a nossa área de Base de Conhecimentos Nela você encontrará excelentes artigos, escritos pelos nossos experientes Consultores, e que tornarão o uso dos os componentes ACBr algo mais simples e funcional... Espero que gostem... e fiquem a vontade para sugerir novos artigos...5 pontos
-
Olá pessoal, Já está no SVN, uma nova classe de Impressora para o componente ACBrPosPrinter, com o intuito de suportar as impressoras da Marca Italiana CUSTOM A Custom chegou no Brasil, através da compra da Nitere... então você poderá achar drivers e especificações dessa impressora, no site da Nitere O Site da própria Custom Itália, é mais completo: http://custom4u.it mas para utilizá-lo você deve fazer um Cadastro (gratuito) e conhecer o "part number" dos equipamentos Para descobrir o "Part Number", entre no site comercial da Custom, como por exemplo, a página da Q3X repare nos números em negrito no final da página... Copie esses números (911FF...) e cole no Edit principal, da página de Drivers da Custom .... (confuso não ?) Muito em breve, devemos fazer um relatório de testes, da Q3X, e disponibilizá-lo na área de equipamentos testados. A Custom usa um protocolo próprio, semelhante ao Epson Esc/Pos, mas não idêntico... Ele é chamado de CustomPos, por esse motivo, você deve configurar o ACBrPosPrinter usando o novo modelo: ACBrPosPrinter1.Modelo := ppCustomPos (A Unit ACBrEscCustomPos.pas, implementa a classe TACBrEscCustomPos) ATENÇÃO: Não use o comando de programação de Logo Tipo do ACBrPosPrinter, com essa Impressora... Notamos um sério Bug no Firmware da versão 3.04... o comando de programação de Logotipo, compatível com o modelo Epson Esc/Pos (ppEscPosEpson), pode danificar o Software Básico desse equipamento... Na classe "TACBrEscCustomPos", esses comandos serão ignorados (sem efeito)... porém se você se comunicar com essa impressora, usando a classe TACBrEscPosEpson, e tentar Programar um logotipo, poderá danificar o seu equipamento. Já notificamos o fabricante desse problema, e estamos trabalhando em uma solução em conjunto...4 pontos
-
Com os fontes atualizados do ACBr, está tudo funcionando. Está ocorrendo o erro 12002 TimeOut. Para solucionar, coloque um timeout de 35 segundos. Está bem lento o retorno da SEFAZ/MG e eles já reconheceram o problema.3 pontos
-
Eles são templates do Fast Report. Como você tinha mencionado um deles, achamos que estava utilizando o Fast Report.2 pontos
-
2 pontos
-
Boa tarde Adilson, O programa exemplo não esta configurado? Outra coisa, esse XML que você anexou se refere ao RPS e não a NFS-e. Para imprimir o DANFSE devemos carregar o XML da NFS-e.2 pontos
-
Boa tarde Vamos verificar a possibilidade de adicionar uma propriedade para definir isso... Pois simplesmente alterar, sem ter uma definição de versão, vai dar diferença no calculo de juros para quem utiliza o layout anterior, visto que a maioria ainda está aceitando o layout antigo...2 pontos
-
Bom dia. Parece que foi problemas com provedor , por que la eu troquei o dns do computador para o do Google e reiniciaram o moldem e funcionou. Vlw2 pontos
-
Boa ! Notei que ao realizar uma venda com acréscimo o Acréscimo sobre SubTotal está sendo impresso com sinal de negativo - . Fiz a correção no .pas e estou enviando para vocês. Valeu ! ACBrSATExtratoESCPOS.pas2 pontos
-
2 pontos
-
Bom dia, Wesley Silva. Veja o tópico abaixo:2 pontos
-
A chave de Acesso é o código de identificação do estabelecimento junto a SEFAZ CE, porém até o momento eles disponibilizaram uma única chave para todas as ativações do ambiente de produção : 25CFE38D-3B92-46C0-91CA-CFF751A82D3D A Chave de Requisição é para cada equipamento TEF ou POS que tenha no cliente, no cadastro dos equipamentos TEF/POS eu tenho o campo CHAVE_REQ, como eu uso o Firebird estou utilizando uma "trigger befere insert" que preenche o campo com o comando uuid_to_char(gen_uuid()), ele gera a chave no cadastro e a chave nunca se repete, ela irá funcionar como um ID que identifica o equipamento no estabelecimento. Mas fica aberto pra vc gerar sua própria GUID porém ela tem que ser única para identificar o equipamento na interface ENVIARPAGAMENTO. A Assinatura do AC vc pode ver o exemplo na pasta \ACBr-Trunk2\Projetos\ACBrSatSign\Delphi2 pontos
-
2 pontos
-
Boa noite! Veja no help online: https://acbr.sourceforge.io/ACBrMonitor/NFEDistribuicaoDFe.html Caso necessite de mais informações, procure por DistribuicaoDFe na pesquisa. Existem vários tópicos tratando do assunto.2 pontos
-
2 pontos
-
2 pontos
-
A Secretaria da Fazenda do Estado do Ceará anunciou no dia 15/02/2019 a disponibilização de uma nova versão do Driver MFE que permite a comunicação direta entre o Aplicativo Comercial e o MFE sem o Integrador Fiscal. Esta alteração visa agilizar o processo de venda, diminuindo o tempo necessário para autorização do CF-e. Para quem utiliza o componente ACBrSAT, o uso da nova versão do Driver MFE sem o Integrador Fiscal acontece quase que de forma transparente. Atualize o Driver MFE para versão 01.05.01 ou superior e configure as seguintes propriedades no ACBrSAT ACBrSAT1.Modelo := satDinamico_stdcall; ACBrSAT1.NomeDLL := 'C:\Arquivos de Programas (x86)\SEFAZ-CE\Driver MFE\Biblioteca de funções\mfe.dll'; //Pasta de Instalação do Driver MFE. Lembrando que a SEFAZ ainda exige que o Integrador deve permanecer instalado na máquina. Para mais informações sobre como usar o MFE sem o Integrador Fiscal, veja https://www.djpdv.com.br/como-usar-o-mfe-sem-o-integrador-fiscal/1 ponto
-
Boa tarde Pessoal, Primeiro foi o CT-e e o MDF-e a ter o seu layout alterado para contemplar um novo grupo: <infRespTec> Informações do Responsável Técnico, agora esta chegando a vez da NF-e. Os 3 componentes já estão preparados para gerar esse grupo. Alguns desenvolvedores já estão gerando o grupo <infRespTec> para o CT-e e MDF-e, tanto em homologação quanto em produção. No caso da NF-e as datas previstas são: para o ambiente de homologação é 25/02/2019 e para produção é 29/04/2019 alterado para 03/06/2019 (conforme consta na versão 1.30 da NT 2018/005). Quero deixar claro que essas datas se referem ao prazo para que as SEFAZ finalizem a implementação em seus webservices, portanto somente a partir dessas datas é que poderemos enviar o XML da NF-e com esse grupo. Portanto, a partir do dia 25/02/2019 teremos um prazo de 3 meses para realizar os testes em ambiente de homologação. Outra coisa importante a ser dita é que esse grupo é opcional, mas vai ficar a critério de cada UF torna-lo obrigatório ou não. Quais são as informações que compõe esse grupo? O grupo <infRespTec> é composto pelos campos: CNPJ da empresa que desenvolveu o software, xContato é o nome da pessoa responsável pelo software, email e fone dessa pessoa ou da empresa. Caso você opte por gerar esse grupo independente da UF exigir ou não, as 4 informações acima deveram constar. Como dito acima os componentes ACBrNFe, ACBrCTe e ACBrMDFe já estão preparados para gerar o grupo <infRespTec>, para que isso ocorra basta acrescentar na sua rotina que alimenta o componente com os dados que vão fazer parte do XML as seguintes linhas... O exemplo abaixo é para a NF-e: with ACBrNFe.NotasFiscais.Add.NFe do begin (...) infRespTec.CNPJ := xCNPJ_RespTec; // CNPJ da Empresa infRespTec.xContato := xContato_RespTec; // Nome do Contato infRespTec.email := xEmail_RespTec; // email do Contato ou Empresa infRespTec.fone := xFone_RespTec; // fone do Contato ou Empresa end; As linhas em negrito acima são exatamente iguais para o CT-e e MDF-e. Nas Notas Técnicas da NF-e, CT-e e MDF-e que se refere a esse grupo tempos ainda mais dois campos: idCSRT e hashCSRT que vão ficar para uma segunda etapa. O CSRT - Código de Segurança do Responsável Técnico, trata-se de um código alfa numérico que será fornecido pela SEFAZ através de uma página própria ou por um webservice, conforme consta na Nota Técnica. Sendo assim, enquanto a SEFAZ não criar essa página ou webservice não temos como solicitar o CSRT e portanto não podemos incluir no XML o idCSRT que é um numero sequencial e o hashCSRT que é o resultado do hash (SHA1 - Base64) da concatenação do CSRT mais a chave do documento. Os componentes já possuem no rol de configurações, as propriedades idCSRT (Integer) e CSRT (String), nessa primeira etapa devemos atribuir o valor zero a idCSRT e uma string vazia para o CSRT, para que os campos: idCSRT e hashCSRT não sejam gerados. Os valores padrões estabelecidos pelo componente são: idCSRT = 0 e CSRT = '' (string vazia). Reforço que o preenchimento dessas propriedades só devem ser feitas a partir do momento que a SEFAZ lhe fornecer o idCSRT e o CSRT. Vamos supor que as UF: x, y e z venham a exigir o grupo <infRespTec> e criem uma pagina ou webservice para fornecer o CSRT, caso você tenha clientes usando ou seu software para emitir NF-e ou CT-e ou MDF-e será necessário solicitar o CSRT em cada uma das UF. Resumindo o CSRT fornecido pela UF x só é valida para os seus clientes dessa UF que usam o seu software. Quais são as UF que vão exigir o grupo <infRespTec> não sabemos, logo devemos ficar atentos. A minha sugestão é que o seu software gere esse grupo independente da UF exigir ou não, pois o dia que ela resolver exigir você não vai precisar fazer nada, pois já consta no XML o grupo. A questão agora é quanto ao CSRT, como dito anteriormente, vai ficar para uma segunda etapa visto que, se faz necessário a SEFAZ criar a página ou webservice. O meu conselho é que no seu software na tela de configuração tenha os campos: idCSRT e CSRT para que você possa informa-los assim que obter. Detalhe importante, os campos idCSRT e hashCSRT só serão gerados no XML e de forma automática dentro do grupo <infRespTec> a partir do momento que as propriedades de configuração: idCSRT e CSRT passarem a ter valores validos. O texto ficou longo, mas espero ter passado todas as informações necessárias para que vocês possam fazer as alterações em seus softwares e desta forma ficarem em conformidade com as nas Notas Técnicas. Para quem não leu as NT, por favor leiam. NT 2018/005 versão 1.20 - Alteração do layout da NF-e https://sourceforge.net/p/acbr/code/HEAD/tree/tools/DFe/NFe/NT/2018/ NT 2018/002 versão 1.01 - Alteração do layout do CT-e https://sourceforge.net/p/acbr/code/HEAD/tree/tools/DFe/CTe/NT/2018/ NT 2018/002 versão 1.02 - Alteração do layout do MDF-e https://sourceforge.net/p/acbr/code/HEAD/tree/tools/DFe/MDFe/NT/2018/1 ponto
-
Boa tarde. Notei que seu código está um pouco divergente do svn em outros itens e também que a variável cTipoBoleto está sem uso, queira por favor atualizar e anexar novamente os arquivos. Att.1 ponto
-
Obrigado por reportar. Fechando. Para novas dúvidas, criar um novo tópico.1 ponto
-
Boa tarde, aroncaio. Veja o tópico abaixo:1 ponto
-
Você tentou abrir o link que postei acima no pc do cliente com o gmail dele logado e liberou acesso de fora ? Aqui quanto vou configurar email em clientes, eu abro o link direto no pc dele, tem que ser assim, pq ai o sistema consegue enviar. no seu se ja fez vai funcionar, mais apenas no seu pc.1 ponto
-
Bom dia Foi autorizada primeira NFSe em ambiente de homologação do Projeto de NFse Nacional (Com o CNPJ da Tecnospeed). https://preprod.nfse.fazenda.gov.br/API/SefinNacional/DANFSe?ChaveAcesso=41152001208187168000160000000000000019022880089526 Noticia Boa1 ponto
-
Obrigado por reportar. Fechando. Para novas dúvidas, criar um novo tópico.1 ponto
-
Para dúvidas sobre esse assunto, favor criar um Novo Tópico em: https://www.projetoacbr.com.br/forum/forum/66-mfe-módulo-fiscal-eletrônico/1 ponto
-
Mas creio que a ideia é justamente enviar a venda, sem passar pelo Integrador, correto ? Veja esse tópico: Para dúvidas sobre esse assunto, favor criar um Novo Tópico em: https://www.projetoacbr.com.br/forum/forum/66-mfe-módulo-fiscal-eletrônico/1 ponto
-
Faça teste usando o demo do ACBrNFSe e caso o problema ocorra nele informe o passo a passo para que possamos reproduzir.1 ponto
-
1 ponto
-
1 ponto
-
1 ponto
-
Joia. Que bom que resolveu. Não sei se entendi direito, mas não deveria haver diferença das respostas do método no modo Debug e Release. Se for isso que estiver acontecendo, acho que seria bom verificar um pouco mais.1 ponto
-
@EMBarbosa Encontrei o problema. Era nesse ponto: { busca informações da aliquota caso seja T ou S } AliqICMS := DMACBr.ECF.AchaICMSAliquota(vAliqCur); Nesse ponto eu mando o componente procurar a alíquota tributável (T ou S), para saber se ela existe antes de tentar registrar o item. Se o método retornar o objeto, significa que encontrou a alíquota, aí continuo com o restante do processo. Caso não encontre, o método retornava um nil. Com isso aviso ao usuário e paro o restante do processo. Eu implementei para tratar as tributações do tipo T e S. As demais tributações não fiscais (FF, II, NN...) o componente retorna nil no modo Debug. No modo Release, agora ele retorna o objeto. Foi isso que causou o problema. Sempre retornava nil independentemente de ser Debug ou Release, mas agora isso não acontece. Para resolver, coloquei alguns tratamentos a mais na minha codificação. Obs.: não tem vinculo com qualquer modelo de ecf.1 ponto
-
Realmente se o ECF não retorna o ACK, não há como saber se o comando foi corretamente interpretado... Verifique se é possível diminuir a velocidade da porta Serial nesse ECF... isso poderia tornar a comunicação de dados um pouco mais segura1 ponto
-
1 ponto
-
ola, aconteceu o mesmo em alguns clientes, todos usavam o Gmail. Mas depois de uma analisada, é um problema na visualização de emails pelo Gmail, ele tem um campo no email "Visualizar email completo" ali esta o email correto, na pré-visualizacao ele tenta identificar o xml e coloca ele no corpo do e-mail, se clicar no link sugerido abre o email corretamente.1 ponto
-
1 ponto
-
1 ponto
-
@plenustech Com ACBr da forma que esta hoje você não consegue compilar nativamente para dispositivos mobile, já se consegue para Firemonkey Win32 e 64; Ha um esforço gigante da equipe em melhorar o código, inclusive com grandes refactores em vários componentes no intuito de tornar-lo mais abrangente inclusive para outras linguagens de programação. Mas nesse seu caso em especifico eu recomendo você indicar a seu cliente o uso de um notebook com sistema win32; Agora se realmente a ideia é usar apenas o mobile é bem provável que se consiga com algum investimento construir essa aplicação.1 ponto
-
Me parece que a geração do CNAB400 para esse banco ainda não foi validada. No tópico onde foi anexada a contribuição que foi enviada ao repositório não menciona a implementação do CNAB400, e comparando os códigos fontes está quase idêntico ao CNAB400 do Banco do Brasil. Se você quiser fazer as modificações necessárias de acordo com o manual do banco, basta abrir o arquivo ACBrBancoCredisis.pas e implementar/corrigir os métodos GerarRegistroHeader400 (header), GerarRegistroTransacao400 (detalhe e opcional) e GerarRegistroTrailler400 (trailler). Ou usar CNAB240 para a geração que aparentemente foi validada.1 ponto
-
Vejam esse excelente artigo, escrito pelo @Italo Jurisato Junior, para nossa área de Base de Conhecimentos1 ponto
-
Ítalo, No ambiente de produção obtive êxito e enviar e gerar a NFSe. Não obtive ainda retorno do provedor sobre o ambiente de homologação. Muito obrigado.1 ponto
-
Exatamente a ECF do ato cotepe é 9 digitos tanto o COO quanto CCF1 ponto
-
Obrigado por reportar. Fechando. Para novas dúvidas, criar um novo tópico.1 ponto
-
Boa tarde. Alguns vídeos são de acesso exclusivo aos assinante do SAC ACBr, verifique se não é o caso...porém o demo é importante também. Att.1 ponto
-
Boa tarde. Se certifique de estar enviando na propriedade NossoNumero somente os dígitos que realmente se referem a esta informação. Att.1 ponto
-
Desculpe BigWings, o problema era interno mesmo, houve uma alteração na nossa função e acabou encadeando o problema. Fui negligente em postar o problema sem ter analisados todos os pontos. Pode desconsiderar o tópico ou até excluí-lo pois não tem relevância. Obrigado pela atenção.1 ponto
-
Boa tarde. Anexe também o XML. Att.1 ponto
-
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.1 ponto
-
Boa tarde. Caso opte por permanecer no CNAB400 basta passar para a propriedade Instrucao1 o codigo desejado. Att.,1 ponto
-
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.1 ponto