Nos últimos dias tenho recebido muitos emails solicitando informações sobre a geração do arquivo de “Movimento por ECF” referente ao requisito XXV do roteiro de análise funcional versão 1.3. Sendo assim resolvi complementar o tutorial anterior com este artigo, informando à forma que desenvolvi esta funcionalidade em meu aplicativo.
Este arquivo deverá ser criado em conformidade com o leiaute e com as especificações estabelecidas no
Anexo VI do Ato Cotepe/ICMS 06/08.
São exigidas as seguintes informações conforme os registros
R01,R02,R03,R04,R05,R06,R07 e no final a assinatura digital EAD.
Registro R01
É referente à identificação da impressora fiscal, do usuário da impressora, que é para quem esta registrada a mesma, e identificação da empresa desenvolvedora do aplicativo PAF-ECF. Neste registro eu coleto as informações da impressora através dos seguintes comandos:
Numero de Serie da Impressora:
Bematech_FI_NumeroSerie
Daruma_FI_NumeroSerie
EPSON_Obter_Dados_Impressora
ECF_NumeroSerie
Elgin_NumeroSerie
Marca, Modelo e Tipo da impressora:
Bematech_FI_MarcaModeloTipoImpressoraMFD
Daruma_FIMFD_RetornaInformacao('78',MFAdicional);
Daruma_FIMFD_RetornaInformacao('79',TipoECF);
Daruma_FIMFD_RetornaInformacao('80',MarcaECF);
Daruma_FIMFD_RetornaInformacao('81',ModeloECF);
Versão da DLL:
Bematech_FI_VersaoDll
Daruma_FI_RetornarVersaoDLL
EPSON_Obter_Versao_DLL
ECF_VersaoDll
Elgin_VersaoFirmware
Os campos Data e Hora da instalação, uso preencher com
espaços
Registro R02 e R03
Estas informações eu uso gravar em tabelas do banco de dados diariamente, até mesmo porque é destas tabelas que retiro informações para gerar o sintegra. Para preencher os dados desta tabela, podem-se usar diversos comandos da DLL para capturar os dados necessários. Mas eu prefiro usar apenas os comando para que a DLL gere o arquivo de retorno com informações dos registros 60M e 60A e gravo os dados na tabela a partir destes arquivos.
Para gerar o registro 60M:
Bematech_FI_RelatorioTipo60Mestre()
Daruma_FI_RelatorioTipo60Mestre()
ECF_RelatorioTipo60Mestre()
Elgin_RelatorioTipo60Mestre()
Para gerar o registro 60A:
Bematech_FI_RelatorioTipo60Analitico()
Daruma_FI_RelatorioTipo60Analitico()
ECF_RelatorioTipo60Analitico()
Elgin_RelatorioTipo60Analitico()
No caso de equipamentos ECF da Epson são necessário usar os diversos comandos capturando as informações necessárias em variáveis e depois gravar no banco de dados:
EPSON_Obter_Dados_Jornada( pchar( sDados ) )
EPSON_Obter_Contadores( pchar( sContadores ) )
EPSON_Obter_Total_Bruto( pchar( sVendaBruta ) )
EPSON_Obter_Venda_Bruta( pchar( sVBatual ), pchar( sVBanterior ) )
EPSON_Obter_Dados_Impressora( aDadosImpressora )
EPSON_Obter_Tabela_Aliquotas( pchar( sAliquotas ) )
EPSON_Obter_Total_Cancelado( pchar( sCancelado ) )
EPSON_Obter_Total_Descontos( pchar( sTotalDescontos ) )
EPSON_Obter_Total_Acrescimos( pchar( sAcrescimos ) )
EPSON_Obter_GT(pChar(sGrandeTotal))
Feito esses procedimentos, basta selecionar na tabela os dados do período desejado para gerar os registros R02 e R03.
Registros R04 e R05
Estes registros são dados referentes aos cupons emitidos pelo ECF. Neste caso também devem ser gravados estes dados em tabelas do banco de dados, apenas tomando o cuidado de gravar os contadores da impressora, respectivamente referentes aos cupons. Sendo assim no momento de gerar os registros R04 e R05, também deverá apenas capturar os dados do banco referente ao período desejado para gravar os mesmo.
Observações:
É importante lembrar que os registros deverão ser organizados em seqüência, sendo:
Forma Correta |
Forma Errada |
R01 R02 R02 R02 R03 R03 R03 R03 R03 R04 R04 R04 R05 R05 R05 R06 R06 R06 R07 R07 |
R01 R02 R03 R03 R02 R03 R03 R03 R04 R05 R05 R05 R04 R05 R05 R05 R05 R06 R06 R07 |
Registro R06
Para obter os dados deste registro, eu criei uma tabela no banco de dados onde gravo informações de todos os documentos emitidos pelo ECF, e criei uma função para facilitar a gravação destes dados. Segue abaixo a estrutura da tabela criada e a função desenvolvida em linguagem de programação Delphi, para gravar os dados na tabela.
CREATE
TABLE DOCEMITIDOSECF (
ID
INTEGER NOT NULL,
COO INTEGER,
GNF INTEGER,
GRG INTEGER,
CDC INTEGER,
DENOMINICAO VARCHAR(2),
DATEMI
TIMESTAMP,
HOREMI
TIMESTAMP,
CODEMP
VARCHAR(3),
CAIXA VARCHAR(3)
);
function
GravaDadosDocECF(fDenomina: String): Boolean;
var Query :
TSQlQuery;
begin
Result := true;
try
// obtem contadores
ObterContadoresImpressora;
Query := TSqlQuery.Create(nil);
try
Query.SQLConnection := ConexaoBancoDados;
Query.Close;
Query.Sql.Add('insert into docemitidosecf(ID,COO,GNF,GRG,CDC,DENOMINICAO,DATEMI,HOREMI,CODEMP,CAIXA)');
Query.Sql.Add('values(:pID,:pCOO,:pGNF,:pGRG,:pCDC,:pDENOMINICAO,:pDATEMI,:pHOREMI,:pCODEMP,:pCAIXA)');
Query.Params.ParamByName('pID').AsInteger := DtmAutoInc.AutoIncremental('DOCEMITIDOSECF','ID','Integer');;
Query.Params.ParamByName('pCOO').AsInteger := COO;
Query.Params.ParamByName('pGNF').AsInteger := GNF;
Query.Params.ParamByName('pGRG').AsInteger := GRG;
Query.Params.ParamByName('pCDC').AsInteger := CDC;
Query.Params.ParamByName('pDENOMINICAO').AsString := fDenomina;
Query.Params.ParamByName('pDATEMI').AsDate := Data;
Query.Params.ParamByName('pHOREMI').AsTime := Hora;
Query.Params.ParamByName('pCODEMP').AsString := _CodEmp;
Query.Params.ParamByName('pCODEMP').AsString := Armazena_NumeroDoCaixa;
Query.ExecSQL(False);
finally
Query.Close;
Query.Free;
end;
except
Result := false;
end;
end;
function
ObterContadoresImpressora: Boolean;
var aux :
string;
begin
Result := true;
try
if TipoImpressora = 1 then // bematech
begin
// COO
aux := Space(6);
Bematech_Retorno := Bematech_FI_NumeroCupom(aux);
Bematech_Analisa_Retorno(0,false);
if Bematech_Retorno = 1 then
COO := StrToInt(aux);
// GNF
aux := Space(6);
Bematech_Retorno := Bematech_FI_NumeroOperacoesNaoFiscais(aux);
Bematech_Analisa_Retorno(0,false);
if Bematech_Retorno = 1 then
GNF := StrToInt(aux);
// GRG
aux := Space(6);
Bematech_Retorno := Bematech_FI_ContadorRelatoriosGerenciaisMFD(aux);
Bematech_Analisa_Retorno(0,false);
if Bematech_Retorno = 1 then
GRG := StrToInt(aux);
// CDC
aux := Space(4);
Bematech_Retorno := Bematech_FI_ContadorComprovantesCreditoMFD(aux);
Bematech_Analisa_Retorno(0,false);
if Bematech_Retorno = 1 then
CDC := StrToInt(aux);
// CCF
aux := Space(6);
Bematech_Retorno := Bematech_FI_ContadorCupomFiscalMFD(aux);
Bematech_Analisa_Retorno(0,false);
if Bematech_Retorno = 1 then
CCF := StrToInt(aux);
end;
if TipoImpressora = 2 then // Daruma
begin
// Outros
aux := Space(66);
Daruma_Retorno := Daruma_FIMFD_RetornaInformacao('21',aux);
if Daruma_Retorno = 1 then
begin
COO := StrToInt(Copy(aux,01,6));
GNF := StrToInt(Copy(aux,13,6));
CCF := StrToInt(Copy(aux,25,6));
GRG := StrToInt(Copy(aux,43,6));
end;
// CDC
aux := Space(4);
Daruma_Retorno := Daruma_FIMFD_RetornaInformacao('45',aux);
if Daruma_Retorno = 1 then
CDC := StrToInt(aux);
end;
if TipoImpressora = 3 then // Epson
begin
aux := Space(84);
Epson_Retorno := EPSON_Obter_Contadores(pchar(aux));
if Epson_Retorno = 0 then
begin
COO := StrToInt(Copy(aux,01,6));
GNF := StrToInt(Copy(aux,19,6));
GRG := StrToInt(Copy(aux,37,6));
CDC := StrToInt(Copy(aux,25,6));
CCF := StrToInt(Copy(aux,43,6));
end;
end;
if TipoImpressora = 4 then // Sweda
begin
// COO
aux := Space(6);
Sweda_Retorno := ECF_NumeroCupom(aux);
Sweda_Analisa_Retorno(0,false);
if Sweda_retorno = 1 then
COO := StrToInt(aux);
// GNF
aux := Space(6);
Sweda_Retorno := ECF_NumeroOperacoesNaoFiscais(aux);
Sweda_Analisa_Retorno(0,false);
if Sweda_retorno = 1 then
GNF := StrToInt(aux);
// GRG
aux := Space(6);
Sweda_Retorno := ECF_ContadorRelatoriosGerenciaisMFD(aux);
Sweda_Analisa_Retorno(0,false);
if Sweda_retorno = 1 then
GRG := StrToInt(aux);
// CDC
aux := Space(4);
Sweda_Retorno := ECF_ContadorComprovantesCreditoMFD(aux);
Sweda_Analisa_Retorno(0,false);
if Sweda_retorno = 1 then
CDC := StrToInt(aux);
// CCF
aux := Space(6);
Sweda_Retorno := ECF_ContadorCupomFiscalMFD(aux);
Sweda_Analisa_Retorno(0,false);
if Sweda_retorno = 1 then
CCF := StrToInt(aux);
end;
if TipoImpressora = 5 then //
begin
// COO
aux := Space(6);
Elgin_Retorno := Elgin_NumeroCupom(aux);
Elgin_Analisa_Retorno(0,false);
if Elgin_Retorno = 1 then
COO := StrToInt(aux);
// GNF
aux := Space(6);
Elgin_Retorno := Elgin_NumeroOperacoesNaoFiscais(aux);
Elgin_Analisa_Retorno(0,false);
if Elgin_Retorno = 1 then
GNF := StrToInt(aux);
// GRG
aux := Space(6);
Elgin_Retorno := Elgin_ContadorRelatoriosGerenciaisMFD(aux);
Elgin_Analisa_Retorno(0,false);
if Elgin_Retorno = 1 then
GRG := StrToInt(aux);
// CDC
aux := Space(4);
Elgin_Retorno := Elgin_ContadorComprovantesCreditoMFD(aux);
Elgin_Analisa_Retorno(0,false);
if Elgin_Retorno = 1 then
CDC := StrToInt(aux);
// CCF
aux := Space(6);
Elgin_Retorno := Elgin_ContadorCupomFiscalMFD(aux);
Elgin_Analisa_Retorno(0,false);
if Elgin_Retorno = 1 then
CCF := StrToInt(aux);
end;
except
Result := false;
MessageDlg('Erro ao capturar contadores!!!', mtWarning, [mbOK], 0);
end;
end;
Registro R07