Business - Automação Comercial
SIntegra: Abordagem Completa – Implementanto o Sintegra
Continuando a nossa série de artigos sobre o Sintegra, iremos agora abordar a implementação do arquivo propriamente dita.
por Victory FernandesContinuando a nossa série de artigos sobre o Sintegra, iremos agora abordar a implementação do arquivo propriamente dita. Através dos 2 demos que acompanham o artigo, é demonstrada a geração de todos os registros do sintegra, e a geração dos principais registros do sintegra descritos no artigo anterior a partir de dados contidos em um banco de dados Interbase 6.01 (Freeware).
Visão geral da Implementação
Como o Sintegra se baseia em uma série de informações fornecidas pelo usuário do sistema gerencial em questão, e como estas informações devem ser cuidadosamente tratadas antes de serem enviadas para o banco de dados do sistema e por fim utilizadas na geração do arquivo de texto, sob pena de recusa do arquivo gerado por parte do Programa Validador, foi desenvolvida a SIntegra32Dll.dll, como uma solução que visa facilitar e agilizar o processo de tratamento destas informações, uma vez que seus usuários podem abstrair a camada de geração dos registros e validação das informações, se preocupando apenas em fazer as chamadas à dll passando os parâmetros necessários para a criação do registro.
É importante lembrar que o arquivo do sintegra será gerado referente a um período anterior, com base em informações que já foram adicionadas a um banco de dados e que devem ser coerentes com o sintegra. Então, a Sintegra32dll.dll deve ser usada na verdade em dois momentos, a exemplo:
- Momento A: Em um sistema de controle de notas fiscais com Sintegra, as entradas e saídas das notas devem ser feitas levando em consideração que o banco de dados gerado será usado para geração do arquivo magnético, assim, logo após o preenchimento de cada nota fiscal, o sistema deve antes de tudo chamar a dll para os registros correspondentes e testar se houve erro, salvando as informações no banco de dados, caso nenhum problema seja encontrado.
- Momento B: No momento da geração do arquivo magnético propriamente dita, o sistema deve ler as informações do banco de dados e fazer as chamadas às funções da dll de acordo com o registros desejados.
Figura 01: Processo de Implementação do Sintegra
Na Figura 01 vemos os passos envolvidos na implementação do sintegra que são descritos a seguir. Os passos em vermelho são aqueles que devem ser implementados no sistema gerencial e os passos em verde podem ser abstraídos a partir da utilização da Sintegra32dll.dll.
1. Tabelas e Campos de acordo com o Sintegra: Todas as tabelas do sistema gerencial em questão devem estar formatadas de acordo com os campos dos registros do sintegra, observando-se tipos de campo (numérico ou alfanumérico) e tamanho máximo dos mesmos.
2. Telas de Cadastro de Dados do Sintegra: As telas do sistema gerencial devem estar de acordo com o banco de dados e, as necessidades do sintegra. Atenção principalmente para as telas de Vendas, Entrada de Nota Fiscal e Saída de Nota Fiscal que normalmente precisam ser revistas sendo necessário fazer pelo menos pequenas alterações não previstas até então. Atenção também para telas de Cadastro de Informante (Registro 10 e 11), Cadastro de Redução Z (Registros 60), Cadastro de GNRE (Registro 55) e etc que precisam ser criadas para satisfazer a geração de alguns registros específicos do Sintegra.
3. Validação das Informações + Tratamento de Erros: Para garantir o máximo de integridade e o mínimo de imprevistos no momento da geração do arquivo, é aconselhável que os dados passem pela camada de validação de informações antes de ir para o banco de dados. Assim, no momento da geração, você garante que os dados do banco estão consistentes.
4. Seleção das informações do Período: Esta é a tela de geração do arquivo propriamente dito, e nela deve haver uma implementação de seleção das informações a serem utilizadas para a geração do arquivo, normalmente feita através de Querys no banco de dados, aplicando à Select os filtros referentes ao período das informações, tipo de registros, bem como ordenação dos campos (order by) e agrupamentos (group by) caso necessário.
5. Chamadas para as Geração dos registros: As informações retornadas pelo banco de dados serão então passadas como parâmetros para as chamadas de geração dos registros sob a forma de loops nas Querys de seleção. As funções de geração dos registros, executam novamente o procedimento de validação das informações (Passo 6) e por fim, caso não seja encontrado erro nas informações transmitidas, executa a Composição dos Registros, colocando os parâmetros passados sob a forma descrita na legislação do sintegra.
Pronto! Uma vez de posse do retorno das funções de geração do registros, contendo os registros devidamente formatados, tudo o que o software gerencial tem a fazer é colocar a linha formatada em um arquivo .txt. Implementando o Sintegra com a SIntegra32Dll.dll
A Sintegra32dll.dll vem acompanhada de 2 demos que exemplificam sua utilização nos dois momentos descritos anteriormente. Para o Momento A há o demo sem utilização de banco de dados, onde são mostradas chamadas a todas as funções presentes na dll. Através de cliques nos botões respectivos você pode fazer os testes de cada função separadamente, como mostra a Figura 02.
Figura 02: Demo sem banco de dados. Chamadas a todas as funções disponíveis na Sintegra32dll.dll através do clique nos botões respectivos
No demo da Figura 02, para criação da linha do registro 50 descrita anteriormente, a chamada à função da dll no botão Registro 50 é feita como mostrado:
var Form1: TForm1; implementation Function Registro50(CNPJ, Insc_Est, Data_Emissao_Recebimento, UF, Modelo, Serie, Nro, CFOP, Emitente, Valor_Total, Base_ICMS, Valor_ICMS, Isenta, Outras, Aliquota, Situacao: ShortString): ShortString; stdcall; external "SIntegra32Dll.DLL"; procedure TForm1.Button3Click(Sender: TObject); var TempStr: String; begin //Registro50 - Registro de Total de Nota Fiscal TempStr := Registro50("23.859.507/0001-09", //CNPJ "7.075.793.310.062", //Insc_Est "21/06/95", //Data_Emissao_Recebimento "BA", //UF, "1", //Modelo "1", //Serie "501306", //Nro "5111", //CFOP "P", //Emitente "518,19", //Valor_Total "518,19", //Base_ICMS "36,27", //Valor_ICMS "", //Isenta "0,00", //Outras "7,00", //Aliquota "N" //Situacao ); if TempStr[1] <> "-" then Memo1.Lines.Add(TempStr) //Adiciona no Memo o Registro 50 formatado else ShowMessage(Copy(TempStr, 6, Length(TempStr))); //Mostra a mensagem de erro recebida end;
Para o Momento B há o demo com utilização de banco de dados, onde são mostradas chamadas aos principais registros do sintegra descritos anteriormente, sendo que as chamadas às funções da dll são feitas passando-se como parâmetros os valores contidos em um banco de dados Interbase, refletindo o exato comportamento que deve ser implementado pelo desenvolvedor quando na adaptação do seu sistema, incluindo as funções de tratamento de erros, log de erros na tela e criação do arquivo de texto.
A tela principal do demo com banco de dados é mostrada na Figura 03, e sua implementação será mostrada em detalhes neste artigo.
Figura 03: Demo com banco de dados. Chamadas a partir de um banco de dados Interbase às principais funções de registro do Sintegra disponíveis na Sintegra32dll.dll.
A principal funcionalidade do demo está implementada no botão Gerar Sintegra. Após o usuário preencher corretamente as informações da caixa superior sobre a Natureza das Operações, Finalidade do Arquivo, path do arquivo de saída .txt e período sobre o qual as informações devem ser geradas, e uma vez pressionado o botão Gerar Sintegra o programa segue o seguinte algoritmo:
- Verifica se o arquivo de saída já existe e se existir exclue o arquivo existente.
- Inicia o uso da Sintegra32dll.dll a partir de uma chamada à função Inicia_Sintegra.
- Realiza a chamada a uma determinada função de registro, que faz uma Query no banco de dados respectivo buscando pelas informações necessárias à geração do registro dentro do período desejado e na ordem de apresentação definida (order by).
- Realiza um loop na Query fazendo chamadas à Sintegra32dll.dll passando como parâmetros os resultados retornados pela Query, e armazenando em uma variável temporária a string retornada pela dll.
- Realiza a chamada a uma função de tratamento de erro passando como parâmetro a string temporária armazenada anteriormente, com o objetivo de verificar se a string contém descrição de erro ou o registro esperado devidamente formatado.
- Caso a string temporária contenha erro, é efetuado o log completo do erro na caixa de texto; caso contrário o registro devidamente formatado é adicionado ao arquivo de texto .txt.
- Repete-se os passos 2, 3, 4, 5 e 6 para todos os registros do Sintegra que se deseja gerar, tendo em vista características específicas do informante, como por exemplo se ele é ou não contribuinte do IPI (deve-se gerar registro 51), se ele é ou não Substituto Tributário (deve-se gerar registro 53). Tais informações devem ser armazenadas em uma tabela a ser preenchida previamente pelo usuário.
Vamos agora mostrar passo a passo a implementação do algoritmo descrito anteriormente para a confecção do registro 50 já apresentado nas situações anteriores.
No passo 1, executa-se a verificação se o arquivo de saída já existe e se existir exclue o arquivo existente.
if fileexists(edit1.Text) then begin Add_Log("Arquivo de saída existente excluído: " + edit1.Text, clred); deletefile(edit1.Text); end;No passo 2, faz-se a chamada a função Inicia_Sintegra.
Inicia_Sintegra;
No passo 3, realiza-se a chamada à uma determinada função de registro, que faz uma Query no banco de dados respectivo buscando pelas informações necessárias à geração do registro dentro do período desejado e na ordem de apresentação definida (order by).
//Geração de Registro50 quanto a Saída de Nota Fiscal //Executa a seleção dos registros no banco de dados with QrySintegra do begin Close; UnPrepare; SQL.Clear; SQL.Add("SELECT * FROM pedidos WHERE "); SQL.Add("(datahora_emissao BETWEEN :datahora_ini AND :datahora_fim) AND ("); SQL.Add("(modelo_nf = ""01"") OR"); SQL.Add("(modelo_nf = ""1A"") OR"); SQL.Add("(modelo_nf = ""03"") OR"); SQL.Add("(modelo_nf = ""06"") OR"); SQL.Add("(modelo_nf = ""22""))"); SQL.Add("ORDER BY datahora_emissao"); ParamByName("datahora_ini").asdatetime := DataHora_Inicial; ParamByName("datahora_fim").asdatetime := DataHora_Final; Prepare; Open; end;
No passo 4, realiza-se um loop na Query fazendo chamadas à Sintegra32dll.dll passando como parâmetros os resultados retornados pela Query, e armazenando em uma variável temporária a string retornada pela dll.
if QrySintegra.RecordCount> 0 then begin while not QrySintegra.EOF do begin while not QrySintegra_D.EOF do begin num_nf := QrySintegra.Fields.FieldByName("num_nf").AsString; num_nf := trim(copy(num_nf, length(num_nf) - 6, length(num_nf))); //Faz a chamada da dll passando as informações do banco de dados e armazena numa string temporária TempStr := Registro50(QrySintegra.Fields.FieldByName("cnpj_destinatario").AsString, //CNPJ QrySintegra.Fields.FieldByName("ie_destinatario").AsString, //IE datetostr(QrySintegra.Fields.FieldByName("datahora_emissao").AsDateTime), //Data QrySintegra.Fields.FieldByName("uf_destinatario").AsString, //UF, QrySintegra.Fields.FieldByName("modelo_nf").AsString, //Modelo QrySintegra.Fields.FieldByName("serie_nf").AsString, //Serie num_nf, //Nro QrySintegra.Fields.FieldByName("cfop").AsString, //CFOP QrySintegra.Fields.FieldByName("emitente_nf").AsString, //Emitent formatcurr("0.00", QrySintegra_D.Fields.FieldByName("subtotal").AsFloat), //V_Total formatcurr("0.00", QrySintegra_D.Fields.FieldByName("base_icms").AsFloat), //B_ICMS formatcurr("0.00", QrySintegra_D.Fields.FieldByName("valor_icms").AsFloat), //V_ICMS formatcurr("0.00", QrySintegra.FieldByName("valor_isento_icms").AsFloat), //Isenta formatcurr("0.00", QrySintegra.FieldByName("outras_despesas").AsFloat), //Outras formatcurr("0.00", QrySintegra_D.Fields.FieldByName("aliquota_icms").AsFloat), //Aliquot QrySintegra.Fields.FieldByName("situacao_nf").AsString //Situac );
Nos passos 5 e 6, realiza-se a chamada a uma função de tratamento de erro passando como parâmetro a string temporária armazenada anteriormente, como o objetivo de verificar se a string contém descrição de erro ou o registro devidamente formatado. Caso a string temporária contenha erro, é efetuado o log completo do erro na caixa de texto, caso contrário o registro devidamente formatado é adicionado ao arquivo de texto .txt.
//Executa o tratamento da string temporária testando se houve erro //Caso haja erro, executa o log das informações inconsistentes no RichEdit if not Trata_SIntegra_Str(TempStr) then begin qnt_erro := qnt_erro + 1; Result := False; Err_Msg := Err_Msg + #13 + " Cod_Pedidos: " + QrySintegra.Fields.FieldByName("cod_pedidos").AsString + #13 + " CNPJ: " + QrySintegra.Fields.FieldByName("cnpj_destinatario").AsString + #13 + " IE: " + QrySintegra.Fields.FieldByName("ie_destinatario").AsString + #13 + " Emissao: " + datetostr(QrySintegra.Fields.FieldByName("datahora_emissao").AsDateTime) + #13 + " UF: " + QrySintegra.Fields.FieldByName("uf_destinatario").AsString + #13 + " Modelo: " + QrySintegra.Fields.FieldByName("modelo_nf").AsString + #13 + " Serie: " + QrySintegra.Fields.FieldByName("serie_nf").AsString + #13 + " Nro: " + num_nf + #13 + " CFOP: " + QrySintegra.Fields.FieldByName("cfop").AsString + #13 + " Emitente: " + QrySintegra.Fields.FieldByName("emitente_nf").AsString + #13 + " Valor_Total: " + QrySintegra_D.Fields.FieldByName("subtotal").AsString + #13 + " Base ICMS: " + QrySintegra_D.Fields.FieldByName("base_icms").AsString + #13 + " Valor ICMS: " + QrySintegra_D.Fields.FieldByName("valor_icms").AsString + #13 + " Isenta: " + QrySintegra.FieldByName("valor_isento_icms").AsString + #13 + " Outras: " + QrySintegra.FieldByName("outras_despesas").AsString + #13 + " Aliquota: " + floattostr(QrySintegra_D.Fields.FieldByName("aliquota_icms").AsFloat * 100) + #13 + " Situacao: " + QrySintegra.Fields.FieldByName("situacao_nf").AsString; end;
No passo 7, repete-se, os passos 2, 3, 4, 5 e 6 para todos os registros do Sintegra que se deseja gerar, tendo em vista características específicas do informante, como por exemplo se ele é ou não contribuinte do IPI (deve-se gerar registro 51), se ele é ou não Substituto Tributário (deve-se gerar registro 53). Assim o código para chamada e geração dos registros 10, 11, e 50 no botão Gerar Sintegra ficariam como segue:
procedure TSIntegra_ListFrm.BitBtn1Click(Sender: TObject); begin DataHora_Inicial := StartOfTheMonth(Datetimepicker1.DateTime); DataHora_Final := EndOfTheMonth(Datetimepicker1.DateTime); if fileexists(edit1.Text) then begin Add_Log("Arquivo de saída existente excluído: " + edit1.Text, clred); deletefile(edit1.Text); end; Inicia_Sintegra; if sRegistro10(Err_Msg) then Add_Log("1 Registro tipo 10 gerado com sucesso.", clgreen); else Add_Log("Erro durante criação do Registro tipo 10." + #13 + " Log de Erros: " + #13 + Err_Msg, clred); if sRegistro11(Err_Msg) then Add_Log("1 Registro tipo 11 gerado com sucesso.", clgreen); else Add_Log("Erro durante criação do Registro tipo 11." + #13 + " Log de Erros: " + #13 + Err_Msg, clred); if sRegistro50(Err_Msg, Qnt_Ok, Qnt_Erro) then begin if Qnt_Ok> 0 then Add_Log(inttostr(Qnt_Ok) + " Registro(s) tipo 50 gerado(s) com sucesso.", clgreen) end else begin if Qnt_Ok> 0 then Add_Log(inttostr(Qnt_Ok) + " Registro(s) tipo 50 gerado(s) com sucesso.", clgreen); Add_Log(inttostr(Qnt_Erro) + " Registro(s) tipo 50 não gerado(s) por Erro" + #13 + " Log de Erros: " + Err_Msg, clred); end;
Onde as funções sRegistro10, sRegistro11 e sRegistro50 executam internamente as funcionalidades descritas nos passos 3, 4, 5 e 6, para suas respectivas tabelas do banco de dados.
O arquivo de saída para o mês de 02/2004 gerado pelo demo, para os valores default que acompanham o banco de dados do mesmo é gerado sem erros e aceito pelo validador sem críticas e o resultado para a chamada do Registro 50 é mostrado de forma resumida a seguir, nele podemos visualizar os registros 10, 11 e 50 conforme a formatação do Sintegra, lembrando apenas que no caso do arquivo .txt o mesmo se apresenta sem quebra de linhas, sendo cada linha um registro.
103426113100014426858614 TKS Comercio e Servicos de TelefoniSalvador BA00037118182004020120040229331 11Rua Casemiro Quiroga Loja D 00236Centro Comercial do ImImbui 41720050Gilmar Gomes Fernandes 000003711818 501470129600018202014120 20040202BA01 0016651101T000000015530400000015530400000000000000000000000000000000000000001700N
Conclusão
Com este artigo, cobrimos os conceitos gerais acerca da implementação do sintegra, estruturação básica do sistema gerencial e o fluxograma de procedimentos a serem seguidos para a geração arquivo. Tendo sido demonstrado a partir do exemplo do registro 50 a forma geral de implementação, geração e tratamento de erros de um registro do sintegra a partir de informações contidas em um banco de dados Interbase.
No próximo artigo da série será descrito todo o processo de validação, visualização e transmissão do arquivo gerado, abordando as ferramentas oficiais disponíveis relacionadas ao tema.
- DarumaFramework.SO no LinuxAutomação Comercial
- Palavra de status da impressora na DarumaFrameworkAutomação Comercial
- TEF – Comprovante de Crédito ou DébitoAutomação Comercial
- Comunicar com equipamentos Daruma em linguagens 16bits e DOSAutomação Comercial
- Verificando Redução Z nas Impressoras DarumaAutomação Comercial