Painel de líderes
Conteúdo popular
Showing content with the highest reputation on 04-02-2019 em todas as áreas
-
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.5 pontos
-
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...4 pontos
-
Olá pessoal, Introduzi no componente ACBrPosPrinter, um novo mecanismo de acesso a Impressora Agora poderemos acessar algumas impressoras, usando a Sintaxe: ACBrPosPrinter1.Porta := 'DLL:MARCA'; Onde MARCA, será o nome da Marca do Fabricante da Impressora... Até o momento, temos suporte para as marcas "ELGIN", e "EPSON" A ideia por traz dessa nova sintaxe de Porta, é permitir usar a DLL/SO do Fabricante, para Imprimir diretamente na Impressora... Ok.. o ACBrPosPrinter, já conseguia acessar impressoras Não Fiscais, pela Porta USB, usando a Sintaxe "RAW:" ACBrPosPrinter1.Porta := 'RAW:Nome da Impressora no Windows'; Mas então porque desenvolvemos essa nova forma de acesso ? A nova sintaxe "DLL:", tem algumas vantagens, em relação a sintaxe "RAW:" Não depende da instalação do Driver de Spool da Impressora.. (note porém, que em alguns casos, o Driver de Spool não pode estar instalado, pois ele bloqueia o acesso a USB) Podemos Ler Informações da Impressora (o que não é possível no modo RAW) Entretanto, como foi dito antes, dependemos de DLL exclusiva do fabricante, para o acesso a Impressora pela USB... Quais são essas DLLs ? Para onde eu devo copiá-las ? Vejamos como foi descrito no ACBrSerial-change-Log.txt Creio que isso responde as duas perguntas, correto ? Você pode encontrar as DLLs no nosso SVN, na pasta: \ACBr\DLLs\PosPrinter, ou ainda pela Web: http://svn.code.sf.net/p/acbr/code/trunk2/DLLs/PosPrinter/ Você pode ainda baixar uma versão do Demo PosPrinterTeste, atualizada, compilado em Lazarus/FPC no link abaixo: Como funciona essa nova técnica ? Quem faz todo acesso as Portas suportadas pelo ACBr, é um subcomponente chamado ACBrDevice, e há um bom tempo, esse componente já possui uma possibilidade de Integração por Hooks O que é Hook ? https://pt.wikipedia.org/wiki/Hooking A ideia por trás dos Hooks, é instalar ganchos, em eventos, que nos permitam interceptar algumas ações e chamadas... Veja esse trecho de código FDevice.HookAtivar := PosPrinterHookAtivar; FDevice.HookDesativar := PosPrinterHookDesativar; FDevice.HookEnviaString := PosPrinterHookEnviaString; FDevice.HookLeString := PosPrinterHookLeString; Aqui instruímos o subcomponente ACBrDevice, a chamar nossos eventos, quando ele precisar "Ativar", "Desativar" uma porta e também quando ele for "EnviarString" e "LeString", de uma determinada porta... Então no interior do componente ACBrPosPrinter, implementamos os eventos indicados acima (PosPrinterHookAtivar, PosPrinterHookDesativar, etc) ... Com isso, o ACBrDevice executará um código nosso, ao invés do que ele normalmente executaria... Veja que dentro dos eventos de ativação e desativação usamos uma Classe de Hook (leia mais abaixo) procedure TACBrPosPrinter.PosPrinterHookAtivar(const APort: String; Params: String); begin if Assigned(FHook) then FHook.Open(APort); end; procedure TACBrPosPrinter.PosPrinterHookDesativar(const APort: String); begin if Assigned(FHook) then FHook.Close; end; FHook por sua vez, é uma variável interna ao ACBrPosPrinter, que contem uma Classe de Hook (TACBrPosPrinterHook), e implementa os comandos necessários, para transmitir essas ações, a DLL do fabricante... Veja o exemplo abaixo, como fica a implementação dos Hooks de Ativar e Desativar, da ELGIN... observe que chamamos métodos Externos, da DLL da Elgin, como: "PrtPortOpenW" e "PrtPortClose" procedure TElginUSBPrinter.Open(const APort: String); var errorNo: Integer; begin if Connected then Exit; inherited Open(APort); try errorNo := xPrtPortOpenW(FPrinter, WideString(fpPort)); // <------- A Q U I ------- if (errorNo <> E_SUCCESS) then raise Exception.CreateFmt(CERROR_OPEN, [fpPort, fpPrinterName]); except fpConnected := False; fpPort := ''; raise; end; end; procedure TElginUSBPrinter.Close; var errorNo: Integer; begin if not Connected then Exit; errorNo := xPrtPortClose(FPrinter); // <------- A Q U I ------- if (errorNo <> E_SUCCESS) then raise Exception.CreateFmt(CERROR_CLOSE, [fpPort, fpPrinterName]); inherited Close; end; Com isso, conseguimos usar a DLL do Fabricante, para estabelecer um túnel entre o ACBrPosPrinter e o equipamento... Como posso implementar um Hook para um novo modelo ? Os Primeiros passos, são verificar: Se o Fabricante disponibiliza uma DLL para acesso direto ao equipamento (sem depender do Spooler) Se há nessa DLL, um método que nos permita Escrever e Ler Dados da Porta USB Ou seja, não precisamos de métodos de alto nível, que façam a formatação de caracteres, ou manipulem a impressora... Pois continua sendo o ACBrPosPrinter, quem montará toda a Sintaxe de comandos a serem enviados para a Impressora, usando a linguagem Esc/Pos... e igualmente, será o ACBrPosPrinter que fará a leitura de respostas, quando for necessário... Na DLL da Elgin, temos um ótimo exemplo de método para isso... function PrtDirectIO(printer:Pointer; // Ponteiro com a Impressora instanciada por PrtPrinterCreatorW writeData:PByte; // Buffer com dados a serem enviados writeNum:integer; // Número de Bytes em "writeData" (tamanho do Buffer) readData:PByte; // Ponteiro com o Retorno a ser Lido (Buffer de saída) readNum:integer; // Numero de bytes disponíveis para escrita em "readData" (tamanho disponível no Buffer de Saída) preadedNum:PInteger // Número de bytes realmente escritos em "readData" ): Integer; cdecl; // Status de retorno E_SUCCESS = 0; Tendo isso em mãos, podemos criar uma cópia de uma das Units já existentes, como por exemplo a Unit ACBrEscPosHookElginDLL.pas, e implementar o suporte usando a nova DLL, e efetuar os ajustes referente a nova Marca3 pontos
-
Instalando o FixInsight para utilizar no seu projeto Para utilizar o TMS FixInsight no seu projeto, primeiro faça o download da versão trial no site oficial. O FixInsight está disponível para todas as versões do Delphi a partir do Delphi 2006. A versão pro possui linha de comando, permitindo você executar a ferramenta mesmo quando o Delphi não está aberto. Isso permite você integrar com seu sistema de Build ou sistema de integração contínua. A instalação é muito simples, bastando escolher em qual versão do Delphi você quer instalar. Após a instalação as seguintes entradas vão aparecer no menu Project: E também no "Project Manager" (clique com botão direito no projeto): A entrada "FixInsight Settings..." configura a ferramenta e pode habilitar ou desabilitar as mensagens geradas. Ela abre uma tela como essa: Na imagem acima você pode observar que a mensagem "C101 Method '%s' is too long (%d lines)" está selecionada e permite a configuração de quantas linhas para você um método, function ou procedure não deve exceder. Dá pra ver também que as mensagens C102 e C103 estão desabilitadas e assim não geram avisos. A entrada "Run FixInsight for unit1.pas" executa a ferramenta para a unit aberta atualmente (neste caso Unit1.pas). A entrada "Run FixInsight" executa a ferramenta no projeto atual inteiro. Rodando o FixInsight no seu projeto Como mencionado, é por meio da entrada 'Run FixInsight" que você executa a ferramenta no seu projeto. Então basta abrir o seu projeto e executar por meio do menu Project -> Run FixInsight. Ele vai ser executado e abrir uma aba na janela de mensagens como na imagem abaixo. Dois cliques te jogam na unit e linha relacionada a mensagem: Agora é com você. Você analisa a mensagem o código e verifica se algo pode ser feito.3 pontos
-
3 pontos
-
Obrigado Juliana Era o código de transmissão mas uma obs.: no Help do ACBrMonitor estava escrito CodigoTransmissao e o Correto é CodTransmissao Muito Obrigado a todos3 pontos
-
O VFormats.ShortDateFormat que postei inicialmente está errado. O correto é VFormats.ShortTimeFormat. Bom dia, Consegui uma solução. O problema ocorria porque GetLocaleFormatSettings(LOCALE_USER_DEFAULT, VFormats) traz sempre todo o texto em minúsculo. Aí não tem como avaliar se está configurado para 12 horas (hh:mm) ou para 24 horas (HH:MM). A solução é ler diretamente no registro. Deixo a função para quem sabe ajudar outros. class function TFuncPubl.GetHoraCurtaFormat : String; Var VReg : Tregistry; begin //não pode usar o GetLocaleFormatSettings( aqui pqe essa função retorna sempre tudo em minúsculo. Aí sempre daria erro. result := 'HH:MM'; //para se der erro retornar o correto do GFIL. VReg := TRegistry.Create; try VReg.RootKey := HKEY_CURRENT_USER; VReg.OpenKey('Control Panel\International', false); result := VReg.ReadString('sShortTime'); finally FreeAndNil(VReg); end; end; Tópico resolvido. Obrigado.3 pontos
-
Bom dia. O Santander trabalha com o Código de Transmissão também, verifique esta propriedade. Att.3 pontos
-
Ou seja, você deve querer ligar a Balança ao PC, e ler o peso diretamente na sua aplicação, correto ? Se SIM, essa balança, em conjunto com o componente ACBrBAL, atenderia a sua necessidade https://www.automacaototal.com.br/balancas/balanca-computadora-dp-152 pontos
-
Boa tarde Só acessando o Sistema Retaguarda SAT e baixando os lotes de lá https://satsp.fazenda.sp.gov.br/COMSAT/ Aconselho você salvar os XMLs também no banco de dados...2 pontos
-
Boa Tarde, Só para avisar, essa semana já vou finalizar a atualização do 2240. Assim que eu finalizar e realizar os testes, postarei os fontes aqui. Obrigado!2 pontos
-
Boa tarde, Muito obrigado pela colaboração, ainda hoje estarei enviando para o repositório.2 pontos
-
Boa tarde Lucas, Ainda hoje estarei enviando para o repositório.2 pontos
-
2 pontos
-
Boa tarde, Não temos nada relacionado a este item em andamento, infelizmente temos o mesmo cenário discutido nos posts anteriores. Att.2 pontos
-
Boa Tarde Seguindo o padrão dos métodos de Envio de e-mail dos DF-es já existentes, adicionamos o parâmetro para envio de e-mail com "ReplayTo"" em todos os métodos. Favor verificar a sintaxe na documentação e realizar os testes com a ultima versão. NFe.EnviarEmail(cEmailDestino,cArqXML,cEnviaPDF,[cAssunto],[cEmailsCopias],[cAnexos],[cReplayTo])2 pontos
-
Boa tarde Existe uma propriedade no componente para não imprimir a Mensagem de Tributos, vamos disponibilizar essa opção no ACBrMonitor... Estará disponível na próxima versão semanal. Porém, note que no seu XML 50190209428584000175650010000110931000110934-nfe.xml não tem a tag <vTotTrib> por isso não sai a informação automática do componente detalhando os impostos no Rodapé. Neste caso NÃO deve ser informado também em o total de impostos em "Inf.Adicionais".2 pontos
-
2 pontos
-
Bom dia pessoal, A SEFAZ-CE por meio da instrução Normativa 08 de 31/01/2019 prorrogou os prazos finais de 31/07/2019 para para 30/09/2019, dando assim um tempo maior para que as empresas possam se adequar. Também foi alterado de 18 para 24 meses a permissão de uso de ECFs os quais tenham sido adquiridos ou tido sua autorização de uso pela SEFAZ CE até 31/12/2018. Link para Instrução Normativa 69 de 28/12/2018 a qual estabelecia o prazo de 31/07/2019 (para consulta dos CNAEs obrigados) http://imagens.seplag.ce.gov.br/PDF/20190114/do20190114p05.pdf#page=61 Link para Instrução Normativa 08 de 31/01/2019 com as alterações http://imagens.seplag.ce.gov.br/PDF/20190201/do20190201p01.pdf Links para o calendário do ACBr Att.2 pontos
-
2 pontos
-
2 pontos
-
bom dia.. chegou a Baixar o Demo do acbr? 51141270401700010965001000000004000000004-ped-inu.xml2 pontos
-
2 pontos
-
Bom dia.. Se tiver duvida, entre no site do sefaz, e consulte a nota, para ver a situação. Nos aqui com nosso erpMatos, todo processo que é feito , é adicionado no nosso banco de dados, para saber o que foi feito, entao sugiro, entao fazer isso sim..2 pontos
-
Realmente era falha de programação, ao forçar antes da consulta funcionou, Obrigado with ACBrNFe1.Configuracoes.WebServices do begin UF := 'SP'; End;2 pontos
-
Consegui! Depois de desinstalar e instalar várias vezes deu certo. Repeti o mesmo processo e pela última vez funcionou tudo. Valeu.2 pontos
-
Verifique se você está enviado para a UF correta; caso necessário force a UF, setando antes de executar a consulta2 pontos
-
1 ponto
-
Boa tarde. Recomendo que faça o processo em duas operações distintas, numa você realiza a geração dos PDFs e na segunda gera a remessa com todos os titulos. Att.1 ponto
-
Boa tarde. Caso opte por permanecer no CNAB400 basta passar para a propriedade Instrucao1 o codigo desejado. Att.,1 ponto
-
Boa tarde Souza, Se você puder fazer as alterações, ficaremos gratos, pois toda ajuda é bem vinda.1 ponto
-
Boa tarde Roberto, Através do programa exemplo do componente ACBrNFSe você consegue o arquivo desejado.1 ponto
-
Notei um erro no seu arquivo na Tag [itensRemun]. O Contador de registro deve ficar da seguinte forma: [itensRemun010011001] [itensRemun010011002] ... Ajustando isso o arquivo gerou corretamente...1 ponto
-
Boa tarde Fábio, Atualizei o arquivo INI do provedor e o Cidades.ini Favor atualizar os fontes e faça novos testes.1 ponto
-
Bom dia, Professor. Só completando o que o nosso colega Amarildo de Matos passou, aconselho você baixar e ler a Nota Técnica 2014/002 versão 1.02b que trata sobre o Distribuição DFe. Em seguida, baixe e leia a Nota Técnica 2012/002 versão 1.02 que trata sobre Manifestação do Destinatário. Você pode utilizar o demo na pasta exemplos para realização dos testes. Lembrando que existe vários tópicos sobre o assunto, basta realizar uma pesquisa.1 ponto
-
1 ponto
-
Bom dia, smarcuss. Acredito que a rotina atual de gerarPDF não tem essa funcionalidade. Pois a funcionalidade de agrupar e gerar apenas um PDF a partir do preview, faz parte da rotina do gerador de relatório.1 ponto
-
Obrigado por reportar. Fechando. Para novas dúvidas, criar um novo tópico.1 ponto
-
Obrigado por reportar. Fechando. Para novas dúvidas, criar um novo tópico.1 ponto
-
Obrigado por reportar. Fechando. Para novas dúvidas, criar um novo tópico.1 ponto
-
1 ponto
-
Realmente, usando essa configuração deu certo "LT_TLSv1_2", valeu por compartilhar, estava insistindo no WinCrypt, por isso dava tanto erro de TimeOut.1 ponto
-
O teste que pode ser feito para verificar as configurações é o envio de um email, não sei se teria outra forma. Favor refaça este teste com a DLL anexa, estamos fazendo modificações na inicialização da lib, reporte caso o erro persista. Este erro não ocorreu nos testes, favor baixar fontes e testar novamente. Ajustado UI, o campo onde diz Mensagem HTML, na verdade se trata do Texto Alternativo, que é exibido apenas quando o HTML não pode ser exibido. O HTML quando enviado deve ser colocado no campo "Mensagem Texto" Desde já agradecemos por testar e reportar! Correções na demo no SVN Rev.: [16466] Cdecl.zip1 ponto
-
Olá @Tiago Tarifa Munhoz Muito obrigado por me ajudar a solucionar esse problema. Agora vou ver com o pessoal da control id o que poderá ser feito.1 ponto
-
@Antonio Rufino , o problema está na versão 2.1.5 do firmware, o seja, o mais recente que se encontra no site da Control-iD. A Print-iD que temos estava na versão 1.2.5. Ela imprimiu os acentos corretamente. Foi fazer a atualização e o problema que você descreveu aconteceu exatamente comigo. Aos que não realizaram a atualização, recomendo não fazê-la se o firmware que se encontra no site for o 2.1.5. Aos que desejam saber qual a versão do firmware na impressora, basta imprimir um autoteste. No tópico citado pelo @Daniel Simoes (acima), ilustra como realizá-lo. Fiz um comparativo do antes(esquerda) e depois da atualização:1 ponto
-
1 ponto
-
boa tarde amigo para empresa do simples nacional nao gera base de icms nem coloca percentual caso necessite gerar base use csosn 900 voce ta usando 102 esse csosn nao gera base .1 ponto
-
Bom dia Lucas, Favor testar com a unit em anexo. pcnNFeR.pas1 ponto
-
Bom dia Darlana, A URL montada pelo componente: https://porteirinhamg.webiss.com.br/ws/nfse.asmx é valida. Favor entrar em contato com o provedor, pode ser que se faça necessário um cadastro para que o contribuinte possa emitir a nota via webservice.1 ponto
-
Bom dia, Conforme instituído pela Instrução Normativa 69/2018 publicada no DOE CE em 14/01/19, a partir de 01/02/2019 para os CNAES a seguir, não serão mais concedidas autorizações de uso e nem permitidas intervenções técnicas em ECF, com exceção dos ECFs adquiridos até 31/01/2019. a) 4711-3/01 Comércio varejista de mercadorias em geral, com predominância de produtos alimentícios - hipermercados; b) 4711-3/02 Comércio varejista de mercadorias em geral, com predominância de produtos alimentícios - supermercados; c) 4712-1/00 Comércio varejista de mercadorias em geral, com predominância de produtos alimentícios - minimercados, mercearias e armazéns; d) 4713-0/01 Lojas de departamentos ou magazines; e) 4713-0/02 Lojas de variedades, exceto lojas de departamentos ou magazines; f) 4713-0/03 Lojas duty free de aeroportos internacionais; g) 4721-1/02 Padaria e confeitaria com predominância de revenda; h) 4721-1/03 Comércio varejista de laticínios e frios; i) 4721-1/04 Comércio varejista de doces, balas, bombons e semelhantes; j) 4722-9/01 Comércio varejista de carnes – açougues; k) 4722-9/02 Peixaria; l) 4723-7/00 Comércio varejista de bebidas; m) 4724-5/00 Comércio varejista de hortifrutigranjeiros; n) 4729-6/01 Tabacaria; o) 4729-6/02 Comércio varejista de mercadorias em lojas de conveniência; p) 4729-6/99 Comércio varejista de produtos alimentícios em geral ou especializado em produtos alimentícios não especificados anteriormente; q) 4761-0/01Comércio varejista de livros; r) 4761-0/02 Comércio varejista de jornais e revistas; s) 4761-0/03 Comércio varejista de artigos de papelaria; t) 4762-8/00 Comércio varejista de discos, CDs, DVDs e fitas; u) 4784-9/00 Comércio varejista de gás liquefeito de petróleo (GLP); v) 4785-7/01 Comércio varejista de antiguidades; w) 4785-7/99 Comércio varejista de outros artigos usados; x) 4789-0/01 Comércio varejista de suvenires, bijuterias e artesanatos; y) 4789-0/02 Comércio varejista de plantas e flores naturais; z) 4789-0/03 Comércio varejista de objetos de arte; z.1) 4789-0/04 Comércio varejista de animais vivos e de artigos e alimentos para animais de estimação; z.2) 4789-0/05 Comércio varejista de produtos saneantes domissanitários; z.3) 4789-0/06 Comércio varejista de fogos de artifício e artigos pirotécnicos; z.4) 4789-0/07 Comércio varejista de equipamentos para escritório; z.5) 4789-0/08 Comércio varejista de artigos fotográficos e para filmagem; z.6) 4789-0/09 Comércio varejista de armas e munições; z.7) 4789-0/99 Comércio varejista de outros produtos não especificados anteriormente Fonte: http://imagens.seplag.ce.gov.br/PDF/20190114/do20190114p05.pdf#page=611 ponto