Ir para conteúdo
  • Cadastre-se

amarildolacerda

Membros
  • Total de ítens

    186
  • Registro em

  • Última visita

1 Seguidor

Contact Methods

  • Website URL
    wbagestao.com.br

Últimos Visitantes

O bloco dos últimos visitantes está desativado e não está sendo visualizado por outros usuários.

amarildolacerda's Achievements

Community Regular

Community Regular (8/14)

  • First Post
  • Collaborator Rare
  • Week One Done
  • One Month Later
  • One Year In

Recent Badges

37

Reputação

  1. Alteração para enviar QRCode versao 2.00 function TACBrNFe.AjustarVersaoQRCode(AVersaoQRCode: TpcnVersaoQrCode; AVersaoXML: TpcnVersaoDF): TpcnVersaoQrCode; begin if (AVersaoXML <= ve310) then Result := veqr000 else // ve400 ou superior Result := TpcnVersaoQrCode(max(Integer(AVersaoQRCode), Integer(veqr200))); { TODO: codigo original esta versao 100 do qrcode } end;
  2. 1. Alguma situações o Integrador devolve uma resposta de Erro por conta de formatação com Erro no pacote de requisição - não há nenhum ponto para recuperar este e erro, já que o código esta esperando um erro de resposta da operação e não de erro no pacato de requisição. // pegar erro de validação do dado no envio do pacote ao integrador - Amarildo Lacerda Erro := LerTagXML(RespostaIntegrador, 'Erro', True); if Erro <> '' then DoException(Erro); 2. Constatamos um número muito elevado de situações que o "Integrador" não devolve a resposta da operação após ter capturado a XML de requisição... Fluxo: 1) aplicação gera o XML de requisição; 2) o integrador pega o XML; .... não devolve nenhum retorno e entra em "timeout"; Para avaliar a questão estamos testando a possibilidade de reenviar o mesmo pacote com os mesmos dados. Estamos ainda para avaliar se isto poderá gerar duplicidade do mesmo dado no MFE (não tenho resposta segura ainda); Como estamos fazendo isto: - incluído um contador de insucesso ao obter a resposta; - a cada insucesso incrementa o contador; - depois de um número de insucessos, gera novamente o arquivo com os mesmos dados. <code> unit ACBrIntegrador; .... function TComandoIntegrador.EnviaComando(numeroSessao: Integer; Nome, Comando: String; TimeOutComando: Integer = 0): String; var LocTimeOut, ActualTime, TimeToRetry: TDateTime; NomeArquivoXml, RespostaIntegrador: String; ATimeout: Integer; function CriarXml(NomeArquivo, Comando: String): String; var NomeArquivoTmp, NomeArquivoXml: String; begin NomeArquivoTmp := ChangeFileExt(NomeArquivo, '.tmp'); FOwner.DoLog('Criando arquivo: ' + NomeArquivoTmp); WriteToFile(NomeArquivoTmp, Comando); if not FileExists(NomeArquivoTmp) then DoException('Erro ao criar o arquivo: ' + NomeArquivoTmp); NomeArquivoXml := ChangeFileExt(NomeArquivoTmp, '.xml'); FOwner.DoLog('Renomeando arquivo: ' + NomeArquivoTmp + ' para: ' + NomeArquivoXml); if not RenameFile(NomeArquivoTmp, NomeArquivoXml) then DoException('Erro ao renomear o arquivo: ' + NomeArquivoTmp + ' para: ' + NomeArquivoXml); Result := NomeArquivoXml; end; var Erro: string; conta: Integer; begin Result := ''; Clear; conta := 0; // NomeArquivoXml := CriarXml(FPastaInput + LowerCase(Nome) + '-' + // IntToStr(numeroSessao), Comando); NomeArquivoXml := CriarXml(FPastaInput + LowerCase(Nome) + '-' + IntToStr(numeroSessao) + '-' + FormatDateTime('HHNNSS', ActualTime), Comando); // somente para debug --- remover // seria interessante ter um evento para gravar o conteúdo enviado - WriteToFile(ChangeFileExt(NomeArquivoXml, '.env'), Comando); ActualTime := Now; TimeToRetry := IncSecond(ActualTime, 3); if (TimeOutComando > 0) then ATimeout := TimeOutComando else ATimeout := FTimeout; if (ATimeout <= 0) then ATimeout := 100; LocTimeOut := IncSecond(ActualTime, ATimeout); RespostaIntegrador := AguardaArqResposta(numeroSessao); while EstaVazio(RespostaIntegrador) and (ActualTime < LocTimeOut) do begin Sleep(150); RespostaIntegrador := AguardaArqResposta(numeroSessao); ActualTime := Now; if ActualTime > TimeToRetry then // Caso arquivo ainda não tenha sido consumido após 5 segundos, recria o arquivo begin // se tentou e não retornou nenhum dado... renenviar inc(conta); TimeToRetry := IncSecond(ActualTime, 3); if (FilesExists(NomeArquivoXml)) or (conta > 2) then begin try FOwner.DoLog('Apagando arquivo não processado: ' + NomeArquivoXml); DeleteFile(NomeArquivoXml); except end; NomeArquivoXml := CriarXml(FPastaInput + LowerCase(Nome) + '-' + IntToStr(numeroSessao) + '-' + FormatDateTime('HHNNSS', ActualTime), Comando); conta := 0; end; end; end; /// somente para debug - remover /// remove o arquivo gerado para DEBUG... houve sucesso if (not EstaVazio(RespostaIntegrador)) and FileExists(debug) then DeleteFile(debug); if FilesExists(NomeArquivoXml) then // Apaga arquivo não tratado pelo Integrador begin FOwner.DoLog('Apagando arquivo: ' + NomeArquivoXml); DeleteFile(NomeArquivoXml); end; if EstaVazio(RespostaIntegrador) then begin FErroTimeout := True; DoException('Sem Resposta do Integrador'); end; // pegar erro de validação do dado no envio do pacote ao integrador - Amarildo Lacerda Erro := LerTagXML(RespostaIntegrador, 'Erro', True); if Erro <> '' then DoException(Erro); FOwner.DoLog('RespostaIntegrador: ' + RespostaIntegrador); FResposta := RespostaIntegrador; FIntegradorResposta.LerResposta(RespostaIntegrador); Result := PegaResposta(RespostaIntegrador); end; </code>
  3. Alterado o comando de impressão de cheque que não estava imprimindo a palavra "centavos" no extenso do cheque. ACBrECFEpson.pas
  4. A implementação para checar se a porta é uma DLL não estava funcionando (não reconhecia DLL1). Alterado para: else if (pos(copy(UPorta,1,3),'USB|DLL') > 0) then /// Amarildo Lacerda: correção Result := dtHook ACBrDevice.pas
  5. - Segue o código da ESC Toshiba que estou usando em produção. ACBrSerial_ESC_Toshiba.rar - Documentação oficial para a impressora Toshiba 4610ProgrammersGuide.rar
  6. Olá Daniel, Sabe se temos a chave CHV_CFE (a chave eletronica) do ECF TM800/TM900 da epson (Convênio 09/09 ) ?
  7. Vou olhar qual o impacto se utilizar TACBrPosComandos
  8. Conclusão para portar a impressora da Toshiba PosPrinter Classe: TACBrEscToshiba. Algumas alterações que foram necessárias: 1) a impressora não pode receber #13#10 - precisa ser substuido por #13 (estava gerando um salto adicional de linha). Para completar esta imprementação foi preciso implementar um novo evento em: TACBrPosPrinter property OnTratarImprimir : TACBrTagOnTraduzirTag read FOnTratarImprimir write SetOnTratarImprimir; o evento irá receber a string para impressão e substuir o #13#10 por #13 (na classe: TACBrEscToshiba) no create será atribuido o evento para que a substituição seja feita. constructor TACBrEscToshiba.Create(AOwner: TACBrPosPrinter); begin inherited Create(AOwner); AOwner.OnTratarImprimir := DoTratarImprimir; ..... 2) Reintroduzi a TACBrEscPosChequeClass = class na TACBrPosPrinter Este código que suporte a impressão de cheque já estava integrado. Nas últimas atualizações ele foi removido. 3) implementado a impressão de cheque na Toshiba - Layout dos cheque é o mesmo fornecedo pelo fabricante. 4) anexo o PDF com os codigo EscPOS de comandos para a impressora ( esgotou espaço - vou subir em outro POST) . ACBrPosPrinter.pas ACBrEscPosChequeToshiba.pas ACBrEscToshiba.pas checkLayouts.xml
  9. - se observar o código... toda vez que chama o cheque... ele reprograma o cheque para o indice 01.... ou seja, o indice sempre é o mesmo com novas posições de impressão.
  10. Eu deve ter perdido alguma coisa... Estou procurando onde pegar a Chave CFe do cupom no ECF da Epson T800F e não estou conseguindo localizar. Na DLL, a Epson indicou a função: EPSON_ESC_ECF_Obter_Chave_Busca_CFE Temos em algum lugar esta informação ? (motivo: no SPED C465 ele exige "CHV_CFE - Chave cupom fiscal eletrônico")
  11. http://www.fazenda.sp.gov.br/sat/downloads/Especificacao_SAT_v_ER_2_19_07.pdf 1- Desconto sobre subtotal deverá ser rateado proporcionalmen te ao valor de cada item, já considerado o desconto ou acréscimo sobre item; 2- Diferença entre o valor do desconto sobre subtotal e a soma dos seus rateios deve ser Especificação Técnica de Requisitos - SAT - Direitos Reservados - Versão ER 2.19.07 de 18/05/2016 72 alocada ao rateio de maior valor
  12. A versão 0.06 do SAT não tratou corretamente a questão do arredondamento do rateio de desconto de subtotal para os itens resultando em valor diferente quando do somatório dos rateios dos itens em relação ao valor de desconto no total. Na versão 0.07, isto foi resolvido da seguitne forma... depois de fazer o rateio ajusta-se a diferença no item de maior valor. Pensando nisto, fiz alterações que permitam replicar a mesma coisa para a versão 0.06 1) incluido novo evento no ACBrECFVirtualSAT - QuandoFechaCupom 2) no evento QuandoFecharCupom - implementado... procedure TConectorSATEletronico.DoQuandoFechaCupom(CFe: TCFe); var vDescTotal: double; var i, iMax: integer; vMax: double; fator: double; vDescItem: double; vDescAcum: double; vProd: double; vItem:double; function RoundECF(valor:Double):double; begin result := FServer.ECFVirtual.ECFVirtualClass.RoundECF(valor); // usa o tipo de arredondamento configurado no ECFVirtual; end; begin inherited; // na versao 0.06 o arredondamento esta com diferença de arredondamento. // tentativa de correção do arredondamento, fazendo rateio pelos itens. vDescTotal := CFe.Total.DescAcrEntr.vDescSubtot; if (vDescTotal > 0) and (FloatToString( CFe.infCFe.versaoDadosEnt) = FloatToString(0.06)) then begin iMax := 0; vDescAcum := 0; vProd := 0; for i := 0 to CFe.Det.count - 1 do begin vItem := RoundECF( CFe.Det.Items.Prod.qCom * CFe.Det.Items.Prod.vUnCom); vProd := vProd + vItem; end; if vProd > 0 then begin fator := vDescTotal / vProd; for i := 0 to CFe.Det.count - 1 do begin vItem := RoundECF( CFe.Det.Items.Prod.qCom * CFe.Det.Items.Prod.vUnCom); if vItem > vMax then begin iMax := i; vMax := vItem; // guarda o item de maior valor -- conforme determinou a norma tecnica para a versao 0.07 end; vDescItem := RoundECF(vItem * fator); CFe.Det.Items.Prod.VDesc := CFe.Det.Items.Prod.VDesc + vDescItem; vDescAcum := vDescAcum + vDescItem; end; // ajusta a diferença CFe.Det.Items[iMax].Prod.VDesc := CFe.Det.Items[iMax].Prod.VDesc + (vDescTotal - vDescAcum); CFe.Total.DescAcrEntr.vDescSubtot := 0; end; end; end; ACBrECFVirtualSAT.pas
  13. No ACBrECFVirtual.pas -> quando inicializa os totalizadores são instânciados na sequência FF, II e NN - (base 0 -> 0, 1 , 2.... Quando chama o TotalNaoTributado -> estava pegando na posição 1... deveria ser 2 No TotalIsento -> estava pegando na posição 2... deveria ser 1 Alterado para acertar o local onde pega os totalizadores e mantido a sequência FF, II, NN ACBrECFVirtual.pas
  14. Fazendo aniversário.... o problema voltou.... Ou Seja, Não estava resolvido.... O problema ocorre quando a maquina é um windows 10... em particular com EPSON USB emulando serial.
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.