Como já foi dito, o Sintegra pode ser resumido, como um arquivo de texto formatado segundo um padrão predefinido, onde cada linha do arquivo corresponde a um Registro, contendo vários campos, também predefinidos de acordo com o tipo de registro.
O que ainda não foi dito, é que a distribuição dos registros no
artigo magnético também deve seguir um padrão predefinido de apresentação. Este
padrão possui uma lógica de ordenação “inter-registros” e “intra-registros” como
será mostrado a seguir e resumido na Tabela 01.
Lógica de ordenação “Inter-Registros”
Esta é a lógica de ordenação dos registros entre si, que define qual a seqüência
de apresentação dos registros por tipos e subtipos de registros.
A lógica “inter-registros” define, por exemplo, que os registros 10 e 11 devem
ser sempre o primeiro e segundo registros do arquivo, e que os registros 90
devem ser sempre os últimos. Define também a ordem numérica ascendente de tipos
(ex.: 50, 51, 53, ...) e a ordem de apresentação dos subtipos de registros de um
mesmo tipo (ex.: 60M, 60A, 60D, ...).
Do ponto de vista da implementação, esta lógica de ordenação define no código
fonte do aplicativo, a seqüência de chamada das funções que irão gerar cada tipo
de registro. Sendo assim, a implementação das chamadas das funções deve seguir
uma lógica semelhante à mostrada na Listagem 01.
|
if sRegistro10(Err_Msg) then
//Chamada da função que gera o registro10
begin //Log de execução
Add_Log('1 Registro tipo 10 gerado com sucesso.', clgreen);
Total_Ok := Total_Ok + 1;
end
else
begin //Tratamento de erros
Add_Log('Erro durante criação do Registro tipo 10.' + #13 +
' Log de Erros: ' + #13 + Err_Msg, clred);
Total_Erro := Total_Erro + 1;
end;
if sRegistro11(Err_Msg) then
begin
Add_Log('1 Registro tipo 11 gerado com sucesso.', clgreen);
Total_Ok := Total_Ok + 1;
end
else
begin
Add_Log('Erro durante criação do Registro tipo 11.' + #13 +
' Log de Erros: ' + #13 + Err_Msg, clred);
Total_Erro := Total_Erro + 1;
end;
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;
... |
Listagem 01: Exemplo de chamadas de funções para geração do sintegra com
ordenação “inter-registros”
O código da Listagem 01 foi retirado do demo de implementação do Sintegra com a
Sintegra32dll.dll e demonstra a implementação da ordenação “inter-registros”.
Note que as chamadas às funções do tipo “sRegistroXX”, que fazem a geração dos
registros correspondentes, estão em ordem numérica crescente. Primeiro é feita a
chamada à função sRegistro10, depois sRegistro11, depois sRegistro50 e assim por
diante, conforme definido na Tabela 01.
O código completo do demo está disponível para download em
http://www.igara.com.br/produto.php?cod_produto=3
Lógica de ordenação “Intra-Registros”
Esta é a lógica de ordenação dos registros de mesmo tipo, que define os campos
de classificação utilizados para ordenar a seqüência de apresentação dos dados
referentes a um tipo de registro.
A lógica “intra-registros” define, por exemplo, que os registros tipo 50 devem
ser apresentados por ordem crescente de Data de Emissão na saída ou Data de
Recebimento na entrada dos documentos fiscais referentes aos registros tipo 50.
Define também que os registros tipo 54 e 56 devem ser classificados de acordo
com os campos CNPJ, SERIE, NUM_NF, NUM_ITEM segundo a ordem em que se apresentam
na Tabela 01.
Do ponto de vista da implementação, esta lógica de ordenação define no código
fonte do aplicativo, a cláusula “order by” utilizada no código SQL que faz a
seleção das informações do banco de dados que serão utilizadas para gerar os
registros correspondentes. Sendo assim, a implementação das chamadas das funções
deve seguir uma lógica semelhante à mostrada na Listagem 02.
|
…
with QrySintegra do
begin
Close;
UnPrepare;
SQL.Clear;
SQL.Add('SELECT * FROM nota_fiscal WHERE ');
SQL.Add('(datahora_emissao BETWEEN :datahora_ini AND :datahora_fim) AND
(');
SQL.Add('(modelo_nf = ''01'') OR');
SQL.Add('(modelo_nf = ''03'') OR');
SQL.Add('(modelo_nf = ''06'') OR');
SQL.Add('(modelo_nf = ''22''))');
SQL.Add('ORDER BY datahora’);
ParamByName('datahora_ini').asdatetime := DataHora_Inicial;
ParamByName('datahora_fim').asdatetime := DataHora_Final;
Prepare;
Open;
end;
…
if QrySintegra.RecordCount > 0 then
begin
while not QrySintegra.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 BD e
armazena numa string temporária
TempStr := Registro50(QrySintegra.Fields.FieldByName('cnpj_destinatario').AsString,
//CNPJ
QrySintegra.Fields.FieldByName('ie_destinatario').AsString,
//Insc_Est
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,
//Emitente
formatcurr('0.00', QrySintegra_D.Fields.FieldByName('subtotal').AsFloat),
//Valor_Total
formatcurr('0.00', QrySintegra_D.Fields.FieldByName('base_icms').AsFloat),
//Base_ICMS
formatcurr('0.00', QrySintegra_D.Fields.FieldByName('valor_icms').AsFloat),
//Valor_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),
//Aliquota
QrySintegra.Fields.FieldByName('situacao_nf').AsString //Situacao
);
…
end;
if not QrySintegra.EOF then
QrySintegra.Next;
end;
end;
QrySintegra.Close;
QrySintegra.UnPrepare;
... |
Listagem 02: Exemplo de chamadas de funções para geração do
sintegra com ordenação “intra-registros”
O código da Listagem 02 foi retirado do demo de implementação do
Sintegra com a Sintegra32dll.dll e demonstra a implementação da ordenação
“intra-registros”. Note a cláusula “order by” utilizada no código SQL que faz a
seleção das informações do banco de dados que serão utilizadas para gerar os
registros tipo 50. O comando SQL.Add('ORDER BY data’); define que os dados
selecionados pela Query devem ser ordenados por ordem crescente do campo Data
conforme definido na Tabela 01.
O código completo do demo está disponível para download em
http://www.igara.com.br/produto.php?cod_produto=3
Ordenação completa dos Registros
A Tabela 01 resume toda a apresentação dos registros conforme a ordenação
“inter-regitros” e “intra-regitros”. Ela se encontra disponível nos documentos
oficiais dos convênios do Sintegra, com exceção da coluna “Cláusula de Ordenação
SQL” que foi adicionada neste artigo para facilitar o entendimento das
implementações propostas neste e nos artigos futuros, que irão descrever em
detalhes a implementação de cada registro do Sintegra individualmente.
Na Tabela 01 a coluna “Registros” define a lógica de ordenação
“inter-registros”, a coluna “Campos de Classificação” define a lógica de
ordenação “intra-registros” e a coluna “Posição Campos” define a posição nos
registros onde se encontram os campos da coluna “Campos de Classificação”.
|
Registros |
Posição Campos |
Campos de Classificação |
Cláusula de Ordenação SQL |
|
10 |
- |
- |
1º registro |
|
11 |
- |
- |
2º registro |
|
50
51
53 |
31 a 38 |
Data |
Order by DATA; |
|
54 56 |
3 a 16
19 a 21
22 a 27
35 a 37 |
CNPJ
Série
Número
Número do Item |
Order by CNPJ, SERIE,
NUM_NF, NUM_ITEM; |
|
55 |
31 a 38 |
Data |
Order by DATA; |
|
60M
60A
60D
60I |
4 a 11
12 a 31 |
Data
Número de Série Fabricação |
Order by DATA, NUM_SERIE; |
|
60R |
4 a 9
10 a 23 |
Mês e Ano de emissão
Código do Produto ou Serviço |
Order by MÊS_ANO,
COD_PRODUTO; |
|
61 |
31 a 38 |
Data |
Order by DATA; |
|
61R |
10 a 23 |
Código do Produto |
Order by COD_PRODUTO; |
|
70
71 |
31 1 38 |
Data |
Order by DATA; |
|
74 |
3 a 10
11 a 24 |
Data
Código do Produto |
Order by DATA,
COD_PRODUTO; |
|
75 |
19 a 32 |
Código do Produto ou Serviço |
Order by COD_PRODUTO; |
|
76 |
52 a 59
37 a 46 |
Data
Número |
Order by DATA, NUM_NF; |
|
77 |
3 a 16
19 a 20
21 a 22
23 a 32
38 a 40 |
CNPJ
Série
Subsérie
Número
Número do Item |
Order by CNPJ, SERIE,
SUBSERIE, NUM_NF,
NUM_ITEM; |
|
85 |
14 a 21
03 a 13
95 a 102 |
Data da DDE
Número da DDE
Data Emissão NF exportação |
Order by DATA_DDE,
NUM_DDE,
DATA _NF_EXPORTACAO; |
|
86 |
15 a 22
03 a 14
59 a 66 |
Data de emissão do RE
Número do RE
Data de Emissão NF de remessa |
Order by DATA_RE, NUM_RE,
DATA_NF_REMESSA; |
|
90 |
- |
- |
Últimos registros |
Tabela 01: Tabela resumida de apresentação com ordenação
“inter-registros” e “intra-registros”
Por enquanto é só. Não perca a próxima edição quando iniciaremos os estudos a
respeito dos registros do Sintegra e veremos a geração do primeiro registro do
Sintegra, o Registro 10.
Este artigo foi baseado nas informações contidas nos
seguintes documentos disponíveis para download na internet:
Convênio ICMS 020 de 2000.doc, Convênio ICMS 31 de 1999.doc, CONVÊNIO ICMS 057
de 1995.doc, Convênio ICMS 069 de 2002.doc, CONVÊNIO ICMS 078 de 1997.doc,
Convênio ICMS 142 de 2002.doc, convenio_icms_018_de_2004.doc,
convenio_icms_019_de_2004.doc, convenio_icms_020_de_2004.doc, Decreto 11614 de
2004.doc, manualdoconvenio57-95 C 76-03.RTF
Victory Fernandes é Engenheiro Mestrando em Redes de computadores, e
desenvolvedor sócio da TKS Software - Soluções de Automação de Processos e
Softwares Dedicados e Administrador do projeto Sintegra32dll.dll (
www.sintegrafacil.com.br ). Pode ser contatado em
victory@igara.com.br,
ou através dos sites
www.igara.com.br -
www.victory.hpg.com.br
|