Tutorial PAF-ECF Versão 0103 – Gerando arquivo de Movimento por ECF
Dicas sobre geração do arquivo de "Movimento por ECF" exigido no processo de criação do Menu Fiscal.
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 em branco. E as demais informações uso das tabelas do banco de dados.
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 // Elgin
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
Para este registro eu tenho uma tabela vinculada a de dados dos cupons fiscais que gravo as formas de pagamentos utilizadas em cada cupom e valores referentes a cada forma de pagamento. Sendo assim ficou fácil para gerar o registro, bastando para mim buscar os dados no período referente e gravar no arquivo como registro R07.
Artigos relacionados
-
DevCast
-
Artigo
-
Artigo
-
DevCast
-
DevCast