domingo, 15 de novembro de 2009

Tutorial Homologação PAF-ECF Versão 01.03 – Parte 02 - Criação do Menu Fiscal

O menu fiscal é um dos mais importantes pontos de um sistema ECF dentro dos requisitos atuais de homologação. Nele é concentrado diversas informações referentes ao processamento dos dados do ECF e deve seguir em detalhes os padrões exigidos pela receita. A grande notícia é que para os desenvolvedores que utilizam as dll’s disponibilizadas pelos fabricantes de equipamentos fiscais, e que as dll’s realizam pelo menos 80% do trabalho pesado no processamento das informações cabendo ao desenvolvedor apenas encontrar o comando certo para criar este menu.

Nesta parte do tutorial vou estar postando os comando das dll’s referentes a cada opção do menu fiscal. Os comandos são referentes aos seguintes equipamentos: Bematech, Daruma, Epson, Elgin e Sweda.

O primeiro passo é elaborar a tela do menu fiscal. No meu caso criei uma tela parecida com a figura abaixo;




Observação: Os títulos de cada opção do menu fiscal deve ser idêntica a descrição solicitada no Roteiro de homologação. Pelo menos foi o que o avaliador me pediu quando realizei a homologação do meu aplicativo.

LX – Leitura X que é um comando básico de todo sistema de ECF.

Bematech - Bematech_FI_LeituraX;
Daruma - Daruma_FI_LeituraX;
Epson - EPSON_RelatorioFiscal_LeituraX;
Sweda - ECF_LeituraX;
Elgin - Elgin_LeituraX;

Não há parâmetros para esta opção;

LMFC – Leitura da memória fiscal Completa e LMFC – Leitura da memória fiscal Simplificada.

Neste requisito terá variações entre faixa de período e ou faixa de reduções-Z tanto para leitura da memória fiscal Completa como para leitura simplificada. E também deverá se impressora pela impressora fiscal ou gerada em arquivo texto. Segue os comandos:

Bematech
Bematech_FI_LeituraMemoriaFiscalDataMFD - Por período na impressora.
Bematech_FI_LeituraMemoriaFiscalSerialDataMFD - Por Período em arquivo.
Bematech_FI_LeituraMemoriaFiscalReducaoMFD - Por Redução na Impressora.
Bematech_FI_LeituraMemoriaFiscalSerialReducaoMFD - Por Redução em Arquivo.

Daruma
Daruma_FI_LeituraMemoriaFiscalData - Por Período na Impressora.
Daruma_FI_LeituraMemoriaFiscalSerialData - Por Período na Impressora.
Daruma_FI_LeituraMemoriaFiscalReducao - Por Redução na Impressora.
Daruma_FI_LeituraMemoriaFiscalSerialReducao - Por Redução em Arquivo.

Epson
EPSON_RelatorioFiscal_Leitura_MF - Por Período na Impressora.
EPSON_RelatorioFiscal_Leitura_MF - Por Período na Impressora.
EPSON_RelatorioFiscal_Leitura_MF - Por Redução na Impressora.
EPSON_RelatorioFiscal_Leitura_MF - Por Redução em Arquivo.

Sweda
ECF_LeituraMemoriaFiscalDataMFD - Por Período na Impressora.
ECF_LeituraMemoriaFiscalSerialDataMFD - Por Período na Impressora.
ECF_LeituraMemoriaFiscalReducaoMFD - Por Redução na Impressora.
ECF_LeituraMemoriaFiscalSerialReducaoMFD - Por Redução em Arquivo.

Elgin
Elgin_LeituraMemoriaFiscalData - Por Período na Impressora.
Elgin_LeituraMemoriaFiscalSerialData - Por Período na Impressora.
Elgin_LeituraMemoriaFiscalReducao - Por Redução na Impressora.
Elgin_LeituraMemoriaFiscalSerialReducao - Por Redução em Arquivo.

Espelho MFD – Como o próprio nome diz, este comando irá gerar um arquivo com o espelho de movimentações efetuadas pelo ECF. Também há variações neste comando que poderá ser por período de data ou numero de redução.

Bematech - Bematech_FI_DownloadMFD
Daruma - Daruma_FIMFD_DownloadDaMFD
Epson – EPSON_Obter_Dados_MF_MFD
Sweda – ECF_DownloadMFD
Elgin – Elgin_DownloadMFD

Arq. MFD – Este comando não é suportado pelas DLL’s. Então seguindo orientação do Roteiro apenas coloquei a mensagem “Função Não suportada pelo modelo do ECF utilizado!!!”.

Nas Opções que seguintes do menu fiscal (Tab. Prod, Estoque, Movimento por ECF, Meios de Pagto., DAV Emitidos, Trans. Mesas, Mesas Abertas), deverá ser extraídos dados da base de dados do sistema e gerado arquivos textos ou relatórios gerenciais impressos pela impressora fiscal. Os arquivos gerados deverão segui um layout pré-determinado pela receita que você encontrará no seguinte link:

http://www.fazenda.gov.br/confaz/confaz/atos/atos_cotepe/2008/ac006_08.htm

Estes arquivos deverão ser assinados digitalmente, e validados pelo aplicativo eECF. Leia mais sobre este assunto no link.

http://delphiwork.blogspot.com/2009/07/assinatura-digital-ead-paf-ecf.html

Para emissão dos Relatórios Gerenciais com os respectivos dados solicitados em cada uma das opções deverá usar os seguintes comandos:

Abertura do Gerencial:
Bematech – Não é necessário comando para abertura, ao enviar primeira linha será aberto o gerencial.
Daruma – Daruma_FI_AbreRelatorioGerencial.
Epson – EPSON_NaoFiscal_Abrir_Relatorio_Gerencial.
Sweda – ECF_AbreRelatorioGerencial.
Elgin – Elgin_AbreRelatorioGerencial.

Imprmir Linha no relatório gerencial:
Bematech – Bematech_FI_UsaComprovanteNaoFiscalVinculadoTEF.
Daruma – Daruma_FI_UsaComprovanteNaoFiscalVinculado.
Epson – EPSON_NaoFiscal_Imprimir_LinhaEX.
Sweda – ECF_UsaComprovanteNaoFiscalVinculado.
Elgin – Elgin_UsaComprovanteNaoFiscalVinculado.

Fechar relatório gerencial:
Bematech – Bematech_FI_FechaRelatorioGerencial.
Daruma – Daruma_FI_FechaRelatorioGerencial.
Epson – EPSON_NaoFiscal_Fechar_Relatorio_Gerencial.
Sweda – ECF_FechaRelatorioGerencial.
Elgin – Elgin_FechaRelatorioGerencial.

Observações:
Antes de ir a um agente credenciado pela receita para realizar a certificação, efetue todos os teste detalhadamente em laboratório, observe bem as entrelinhas, revise os layout’s gerados pela aplicação, valide a assinatura EAD. Pois tudo isso será observado criteriosamente pelo examinador, e como terá um alto custo para realização da certificação quanto menos tempo se perde acertando detalhes e melhor.
Quando for para a certificação, será necessário levar as declarações exigidas e também alguns envelopes para lacrar o cd com os fontes.

Qualquer dúvida que tiver, efetuei um comentário. Terei o maior prazer e estar ajudando.

segunda-feira, 2 de novembro de 2009

Tutorial Homologação PAF-ECF Versão 01.03 - Parte 01

Olá!!!

Nos últimos dias tenho visto em alguns foruns de programação um assunto cada vez mais frequente, “Dúvidas no processo de Homologação de aplicações PAF-ECF”. E Tendo em vista a experiência que adiquiri passando por esse processo por duas vezes, resolvi elaborar esse tópico em meu blog dando as coordenadas para que esta iniciando os procedimentos.
A primeira mão parace ser uma tarefa bastante ardua, mas terminado o processo vimus que não é nenhum bicho de sete cabeças.
Mas sem mais delongas vamos dar inicio ao tutorial.

O primeiro passo é fazer o download dos manuais e roteiros de homologação que serão usados para homologar o aplicativo.

No link abaixo você poderá baixar uma cópia do manual de desenvolvimento do aplicativo. Nele tem detalhado todos os requisitos necessários e legislação relacionado do aplicativo PAF-ECF.

http://www.fazenda.mg.gov.br/empresas/ecf/manuais/manu_des.pdf

Neste outro link você irá baixar o roteiro de homologação que será usado pelo orgão credenciado da receita.

http://www.fazenda.mg.gov.br/empresas/ecf/manuais/rafpaf.pdf

Nesta versão do PAF-ECF é necessário a criação de um menu fiscal que deverá gravar várias informações em arquivos eletrônicos no formato .TXT. Neste arquivos deverá conter uma assinatura digital EAD que será validada pelo aplicativo eECFc. Sendo assim, é extremamente aconselhavél que você faça essa validação em todos os arquivos antes de ir para o processo de homologação nos orgãos credenciados pela receita. Segue abaixo o link para baixar o aplicativo.

http://www.fazenda.mg.gov.br/empresas/ecf/informacoes/eecfc.htm

Para gerar a assinatura digital EAD, é necessário o uso de DLL de terceiros, bom, pelo menos foi o meio mais fácil que encontrei. No link abaixo eu dou um exemplo da função que uso em meu aplicativo. Confere lá.

http://delphiwork.blogspot.com/2009/07/assinatura-digital-ead-paf-ecf.html

Em uma das funções exigidas no menu fiscal, será necessário na criação do nome do arquivo eletrônico no formato .TXT, que seja identificado o equipamento ECF pelo código nacional. Esse código foi criado pela receita e poderá se encontrado na tabela que se encontra no link abaixo:

http://www.fazenda.mg.gov.br/empresas/ecf/informacoes/TABNCIEE_por_marca.pdf

Observação: Para os desenvolvedores que utilizam equipamentos Daruma, entre em contato com o suporte técnico do fabricante da mesmo que eles disponibilizam um link com um tutorial de todos os comando necessários para desenvolver o menu fiscal.

Nesta primeira parte do tutorial passei todos os link’s necessários para iniciar o desenvolvimento de uma aplicação PAF-ECF. Na segunda parte estarei passando alguns detalhes importantes para desenvolvimento do Menu Fiscal. Até lá!!!




quarta-feira, 29 de julho de 2009

Problemas com separador de casas decimais

Tendo em vista que muitos programadores tem problemas com a conversão de dados de string para float e vice-versa, quando há necessidade de trabalhar com a configuração do windows no simbolo decimal com ponto ao invês de virgula, resolvi compartilhar uma função que uso em meus projetos para resolver esse problema.




Nesta função é vasculhado todos os componentes TEdit's do formulario ativo e caso o usuário tenha digitado uma virgula (,), o caracter é alterado para ponto automáticamente.

Segue a função:

procedure AlterVirgulaPonto(auxForm:TForm;var Key: Char);
var i : Integer;
begin
for i := 0 to auxForm.ComponentCount -1 do
begin
if auxForm.Components[i] is TEdit then
begin
with auxForm do
begin
if key in [',','.'] then
key := decimalseparator;
end;
end;
end;
end;

Após criado a função, basta chama-la no evento OnKeyPress do formulario.

Até a próxima...

sexta-feira, 24 de julho de 2009

Assinatura Digital EAD PAF-ECF

Ola pessoal!!!

Após algum tempo estou voltando a postar novas informações sobre um assunto muito discutido em alguns fóruns de programação. A assinatura digital EAD usada em aplicativos PAF-ECF para atender a nova legislação.

Neste post vou colocar a disposição o exemplo da função que estou usando em meu aplicativo para gerar essa assinatura EAD.

Observações:
Essa função que estou usando foi adquirida em um fórum disponibilizada por um membro e adaptada em meu aplicativo. Todo credito pelo desenvolvimento deve ser atribuído ao mesmo.

Essa assinatura é realizada apenas usando a DLL Libeay32.dll e a unit Libeay32.pas.




Vamos lá:

O primeiro passo é fazer o download da DLL e da Unit necessários para o funcionamento da função em questão.

Clique nos links a seguir para efetuar tal download:

http://www.disi.unige.it/person/FerranteM/delphiopenssl/libeay32.pas

http://www.dll-files.com/dllindex/dll-files.shtml?libeay32

Depois adcione a unit Libeay32.pas ao seu projeto.

Copie os códigos abaixo e faça as adaptações necessárias no seu projeto.

// função para gerar a assinatura EAD
function TECF.AssinaArquivo(fArquivo: String): Boolean;
var aAssinatura : String;
strList : TStringList;
begin
aAssinatura := Sign_RSA_MD5(ExtractFilePath(Application.ExeName)+'avisnet.pem',fArquivo);
// Assina Arquivo
strList := TStringList.Create;
strList.LoadFromFile(fArquivo);
strList.SaveToFile(fArquivo);
// strList.Add('EAD10'+copy(aAssinatura,1,254));
strList.Add('EAD'+aAssinatura);
strList.SaveToFile(fArquivo);
strList.Free;

end;



// função que retorna a assinatura digital EAD usando a DLL
function TECF.Sign_RSA_MD5(chave_privada, arquivo_assinar: string): string;
var Len: cardinal;
mdctx: EVP_MD_CTX;
inbuf, outbuf: array [0..1023] of char;
key: pEVP_PKEY;
a : pEVP_PKEY;
keyfile: pBIO;
oArquivo : TStringList;
begin
if FileExists(chave_privada) = false then
begin
raise Exception.Create('Arquivo da chave privada não foi encontrado.');
end;
if FileExists(arquivo_assinar) = false then
begin
raise Exception.Create('Arquivo para ser assinado não foi encontrado.');
end;
a := nil;
OpenSSL_add_all_algorithms; //
OpenSSL_add_all_ciphers; // InitOpenSSL
OpenSSL_add_all_digests; //
ERR_load_crypto_strings; //
try
keyfile := BIO_new(BIO_s_file());
BIO_read_filename(keyfile, PChar(chave_privada));
key := PEM_read_bio_PrivateKey(keyfile, a, nil, nil);
if key = nil then
begin
raise Exception.Create('Não foi possível ler a chave privada.');
end;
oArquivo := TStringList.Create;
oArquivo.LoadFromFile(arquivo_assinar);
// StrPCopy(inbuf,oArquivo.Text);
// oArquivo.Free;
EVP_SignInit(@mdctx, EVP_md5());
EVP_SignUpdate(@mdctx, pChar(oArquivo.Text), StrLen(pchar(oArquivo.Text)));
// EVP_SignUpdate(@mdctx, @inbuf, StrLen(inbuf));
EVP_SignFinal(@mdctx, @outbuf, Len, key);
BinToHex(outbuf, inbuf,Len);
inbuf[2*Len]:=#0;
oArquivo.Free;
Result := inbuf;
finally
EVP_cleanup; // FreeOpenSSL
end;

end;



Caso tenha efetuado corretamente os procedimentos esta pronto a rotina para assinar digitalmente um arquivo.

Basta agora compilar o projeto, selecionar um arquivo no formato TXT e enviar o comando para executar a rotina. Depois é só conferir a assinatura com o aplicativo eECFc.exe 3.0.12.0.

Qualque dúvida, post um comentário, terei prazer em tirar as dúvidas.

sábado, 13 de junho de 2009

Ola!!!

Este é meu primeiro post em blog's e confesso não ter experências no assunto.
Estou criando este blog com intuito de passar algumas experiências adquiridas e também estar trocando ideias com outros programadores em delphi, essa poderosa ferramenta para desenvolvimento.
Com a chegada do Embarcadeiro acredito que muitos programadores que usavam ou ainda usam o delphi 7, "que foi uma das versões mais usadas ao longo dos tempos", estão migrando suas aplicações para esta nova versão da IDE ou buscando conhecimento na mesma para tal procedimento, e eu também me encontro neste time.
No momento estou realizando estudos sobre o assunto e espero em breve estar postando informações úteis sobre o assunto.

No momento deixarei aqui uma Unit como exemplo para aqueles que usam o DBX do delphi 7 para conectar ao banco de dados firebird. Nessa rotina é criado os arquivos "dbxdrivers.ini" e "dbxconnections.ini" quando ocorrer um erro na conexão com o banco

unit uFrmConfigConexao;


interface

uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IniFiles, uFrmPadrao, DB, DBClient, StdCtrls, Mask, DBCtrls, Buttons;

type
TFrmConfigConexao = class(TFrmPadrao)
CdsConfig: TClientDataSet;
CdsConfigPATHBANCO: TStringField;
CdsConfigNOMEUSU: TStringField;
CdsConfigSENHAUSU: TStringField;
GroupBox1: TGroupBox;
DataConfig: TDataSource;
Label1: TLabel;
DbPath: TDBEdit;
Label2: TLabel;
DbUsuario: TDBEdit;
Label3: TLabel;
DbSenha: TDBEdit;
OpenDialog1: TOpenDialog;
SpeedButton1: TSpeedButton;
CdsConfigDRIVER: TStringField;
DbDriver: TDBComboBox;
Label4: TLabel;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
procedure FormCreate(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure OpenDialog1CanClose(Sender: TObject; var CanClose: Boolean);
procedure DbDriverKeyPress(Sender: TObject; var Key: Char);
procedure FormShow(Sender: TObject); procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
sConfig1,sConfig2 : TIniFile;
sNomeArq1,
sNomeArq2 : string;
function LeDbxConectionsINI:Boolean;
function GravaDbxConectionsINI:Boolean; public { Public declarations } end;

var FrmConfigConexao: TFrmConfigConexao;

implementation

Uses uLibrary;

{$R *.dfm}

{ TFrmConfigConexao }
function TFrmConfigConexao.GravaDbxConectionsINI: Boolean;
begin
// dbxconection.ini
sConfig1 := TIniFile.Create(sNomeArq1);

sConfig1.WriteString('WorkCom','DriverName',CdsConfigDRIVER.AsString); sConfig1.WriteInteger('WorkCom','BlobSize',1);
sConfig1.WriteString('WorkCom','CommitRetain','False');
sConfig1.WriteString('WorkCom','Database',CdsConfigPATHBANCO.AsString);
sConfig1.WriteString('WorkCom','ErrorResourceFile','');
sConfig1.WriteInteger('WorkCom','LocaleCode',0000);
sConfig1.WriteString('WorkCom','Password',CdsConfigSENHAUSU.AsString);
sConfig1.WriteString('WorkCom','RoleName','RoleName');
sConfig1.WriteString('WorkCom','ServerCharSet','');
sConfig1.WriteInteger('WorkCom','SQLDialect',3);
sConfig1.WriteString('WorkCom','Interbase TransIsolation','ReadCommited'); sConfig1.WriteString('WorkCom','User_Name',CdsConfigNOMEUSU.AsString); sConfig1.WriteString('WorkCom','WaitOnLocks','True'); sConfig1.Free;

// drivers.ini
sConfig2 := TIniFile.Create(sNomeArq2);
sConfig2.WriteString('UIB FireBird15','GetDriverFunc','getSQLDriverINTERBASE'); sConfig2.WriteString('UIB FireBird15','LibraryName','dbexpUIBfire15.dll'); sConfig2.WriteString('UIB FireBird15','VendorLib','fbclient.dll');
sConfig2.WriteInteger('UIB FireBird15','BlobSize',-1);
sConfig2.WriteString('UIB FireBird15','CommitRetain','False');
sConfig2.WriteString('UIB FireBird15','Database',CdsConfigPATHBANCO.AsString); sConfig2.WriteString('UIB FireBird15','ErrorResourceFile','');
sConfig2.WriteInteger('UIB FireBird15','LocaleCode',0000);
sConfig2.WriteString('UIB FireBird15','Password',CdsConfigSENHAUSU.AsString); sConfig2.WriteString('UIB FireBird15','RoleName','RoleName');
sConfig2.WriteString('UIB FireBird15','ServerCharSet','');
sConfig2.WriteInteger('UIB FireBird15','SQLDialect',3);
sConfig2.WriteString('UIB FireBird15','Interbase TransIsolation','ReadCommited'); sConfig2.WriteString('UIB FireBird15','User_Name',CdsConfigNOMEUSU.AsString); sConfig2.WriteString('UIB FireBird15','WaitOnLocks','True'); sConfig2.Free;
end;

function TFrmConfigConexao.LeDbxConectionsINI: Boolean;
begin
// exclui arquivos existentes
if FileExists(sNomeArq1) then
DeleteFile(sNomeArq1);
if FileExists(sNomeArq2) then
DeleteFile(sNomeArq2);
end;

procedure TFrmConfigConexao.FormCreate(Sender: TObject);
begin
inherited;
sNomeArq1 := ExtractFilePath(Application.ExeName)+'dbxconnections.ini';
sNomeArq2 := ExtractFilePath(Application.ExeName)+'dbxdrivers.ini';
if not CdsConfig.Active then
CdsConfig.CreateDataSet; CdsConfig.EmptyDataSet;
end;

procedure TFrmConfigConexao.SpeedButton1Click(Sender: TObject);
begin
inherited;
OpenDialog1.Execute;
end;

procedure TFrmConfigConexao.OpenDialog1CanClose(Sender: TObject; var CanClose: Boolean);
begin
inherited;
CdsConfigPATHBANCO.AsString := OpenDialog1.FileName;
end;

procedure TFrmConfigConexao.FormShow(Sender: TObject);
begin
inherited;
LeDbxConectionsINI;
end;

procedure TFrmConfigConexao.BitBtn1Click(Sender: TObject);
begin
inherited;
GravaDbxConectionsINI;
end;

end.