Painel de líderes
Conteúdo popular
Showing content with the highest reputation on 02-02-2019 em todas as áreas
-
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 Marca1 ponto
-
Bom dia, Fui informado que no dia 01/01/2019 já passa a vigorar a nova versão do Layout do sat, a 0.08 , e que existem novas validações nas tags IE e Cest. Já está disponível para atualização na ACBr? Realizando essas alterações será preciso atualizar o SB do equipamento?1 ponto
-
Bom dia a todos, Os componentes ACBrNFe, ACBrCTe e ACBrMDFe já estão preparados para gerar o grupo <infRespTec> = Informações do Responsável Técnico. Para quem emite NF-e favor ler a Nota Técnica 2018/005, já os emitentes de CT-e - Nota Técnica 2018/002 versão 1.01, e MDF-e - Nota Técnica 2018/002 versão 1.02 Essas NT estão disponíveis nos Portais de cada Documento Fiscal Eletrônico. Para quem esta com os fontes atualizados e reinstalados, ao selecionar o componente ACBrNFe ou ACBrCTe ou ACBrMDFe vai notar no Object Inspector em Configurações o grupo RespTec e dentro deste as propriedades idCSRT e CSRT. O grupo <infRespTec> contem as seguintes informações: CNPJ, Nome, e-mail, telefone, idCSRT e HashCSRT do Responsável Técnico. Sendo que as duas ultimas são geradas automaticamente se as propriedades idCSRT e CSRT forem informadas. Logo o que muda na aplicação: Configuração: Configuracoes.RespTec.idCSRT := <identicador do CSRT> Configuracoes.RespTec.CSRT := <Código de Segurança do Responsável Técnico> Tanto o ID quanto o código serão fornecidos futuramente pela SEFAZ, sendo assim devemos atribuir zero ao idCSRT e uma string vazia para CSRT, nesse primeiro momento. Rotina que alimenta o componente: // Dados do Responsável Técnico infRespTec.CNPJ := xCNPJ_RespTec; infRespTec.xContato := xContato_RespTec; // Nome do responsável técnico infRespTec.email := xEmail_RespTec; infRespTec.fone := xFone_RespTec; Como dito acima o idCSRT e HashCSRT são gerados automaticamente caso o idCSRT seja diferente de zero e CSRT diferente de uma string vazia. Observação: Tanto a configuração quanto a alimentação do componente é exatamente a mesma conforme o exemplo acima para a NF-e, CT-e e MDF-e. A geração desse grupo esta condicionada a cada UF, sendo assim uma UF poderá exigir e outra não, logo devemos ficar atento a legislação de cada UF.1 ponto
-
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).1 ponto
-
Boa tarde a todos, Vamos cortar mais algumas gorduras, chegou a vez da Consulta ao Recibo. Tanto a unit que gera o XML de consulta bem como a que lê o retorno foram generalizadas e agora se encontram dentro da pasta PCNComum. Como nem tudo são flores, ocorreu quebra de código, abaixo um exemplo de correção a ser feita em suas aplicações: for i := 0 to (ACBrNFe.WebServices.Retorno.NFeRetorno.ProtNFe.Count - 1) do begin sDataHora := DateTimeToStr(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtNFe.Items.dhRecbto); sProtocolo := ACBrNFe.WebServices.Retorno.NFeRetorno.ProtNFe.Items.nProt; sStat := IntToStr(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtNFe.Items.cStat); sMotivo := ACBrNFe.WebServices.Retorno.NFeRetorno.ProtNFe.Items.xMotivo; sNotaFiscal := Copy(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtNFe.Items.chNFe, 26, 3) + '.' + Copy(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtNFe.Items.chNFe, 29, 3) + '.' + Copy(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtNFe.Items.chNFe, 32, 3); MemoStatus.Lines.Add(' ' + sNotaFiscal + ' ' + sProtocolo + ' ' + sDataHora + ' ' + sStat + ' - ' + sMotivo); end; Alterar para: for i := 0 to (ACBrNFe.WebServices.Retorno.NFeRetorno.ProtDFe.Count - 1) do begin sDataHora := DateTimeToStr(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtDFe.Items.dhRecbto); sProtocolo := ACBrNFe.WebServices.Retorno.NFeRetorno.ProtDFe.Items.nProt; sStat := IntToStr(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtDFe.Items.cStat); sMotivo := ACBrNFe.WebServices.Retorno.NFeRetorno.ProtDFe.Items.xMotivo; sNotaFiscal := Copy(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtDFe.Items.chDFe, 26, 3) + '.' + Copy(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtDFe.Items.chDFe, 29, 3) + '.' + Copy(ACBrNFe.WebServices.Retorno.NFeRetorno.ProtDFe.Items.chDFe, 32, 3); MemoStatus.Lines.Add(' ' + sNotaFiscal + ' ' + sProtocolo + ' ' + sDataHora + ' ' + sStat + ' - ' + sMotivo); end; Notem que devemos trocar o ProtNFe por ProtDFe e chNFe por chDFe (não coloquei em negrito todos, mas acho que ficou claro).1 ponto
-
Esse tópico é para informar que o Refactoring das impressores DF-e foi concluído e enviado ao SVN na revisão 15983. Queremos lembrar que vai ser necessário reinstalar os pacotes e componentes, pois houveram alterações nas propriedades. Se você utiliza o ACBrInstall, não se preocupe. Ele já foi atualizado no SVN e daqui a pouco será já foi atualizado aqui na área de Downloads também. Se você não sabe do que se trata, veja esse tópico aqui: Nesse tópico são citados dois vídeos sobre o refactoring que recomendamos você assistir. Esse abaixo explica o refactoring: E esse mostra um exemplo de atualização de uma aplicação usando usando o exemplo do ACBrNFe: Deu bastante trabalho esse refactoring e fomos bem minuciosos. Mas pode ser que alguma coisa passou despercebido. Sugerimos que você atualize sua aplicação e comece os testes o quanto antes possível. Para complementar o disponibilizado antes, veja também essa tabela abaixo o nome de propriedades e métodos que mudaram. Note no entanto que há propriedades que são específicas de algumas classes e isso não foi alistado abaixo: Uma informação importante é que agora existe um componente específico para NFC-e em Fast Report. Se você vai trabalhar com NFC-e e imprimir usando o Fast Report, será necessário utilizar esse componente. Nele você encontrará as propriedades que são específicas para NFC-e. Agradecemos ao @BigWings pela ajuda no trabalho com esse componente. No mais, bom trabalho a todos.1 ponto
-
Já existe uma análise para a adequação, mas ainda não foi disponibilizado a atualização 0.08 para os SDKs. Lembrando que a versão 0.07 poderá ser usada por um bom tempo, e para o uso do layout 0.08 será necessário atualizar o SB do aparelho.1 ponto
-
Software básico e versão do layout do xml são questões diferentes. A SEFAZ ainda está processando os xmls na versão 0.06, mas a partir de janeiro não serão mais processados e isso pode acarretar o bloqueio do aparelho. Quanto ao software contábil é interessante entrar em contato com quem o fornece para obter mais detalhes, mas de antemão eu aconselho você a manter o software básico atualizado e gerar os xmls no layout atual, que é o 0.07.1 ponto
-
Bom dia @Diego Siervo Uma observação: No comando NFe.CriarNFe(), já está incluído internamente os comandos Assinar e Validar. Portanto ao usar o NFe.CriarNFe(), pode dispensar estes dois que comentei. Fica então: NFe.CriarNFe() Pegar retorno "OK" se foi criado o arquivo NFe.EnviarNFe() Pegar retorno do status. Aqui vc deve fazer o tratamento. Se receber status 105, por exemplo, significa que a nota ficou em processamento. A patir deste momento vc deve passar para o comando NFe.ConsultarNFe() até que receba o status 100 ou então uma rejeição para seguir a impressão ou alteração.1 ponto