unit ConfigImportacaoExportacao;
                                                                                                   
interface

uses
  Windows, system.UItypes, IB_Access,  Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TelaComum,  DB, DBClient, ImgList, ExtCtrls, StdCtrls, Buttons,
  IB_Components, Grids, DBGrids, IB_Grid, System.ImageList;

type
  TfrmConfigExportacao = class(TfrmTelaComum)
    cdsTabelasDisponiveis: TClientDataSet;
    dsrTabelasDisponiveis: TDataSource;
    DBGrid1: TDBGrid;
    Label1: TLabel;
    qrListaTodasTb: TIB_Query;
    dsrTabelaImportacao: TIB_DataSource;
    IB_Grid1: TIB_Grid;
    btnInsereTodos: TBitBtn;
    btnInsere: TBitBtn;
    btnRemoveTodos: TBitBtn;
    btnRemove: TBitBtn;
    qrDependencia: TIB_Query;
    Label2: TLabel;
    lblInfTabDispomiveis: TLabel;
    lblInfTabExport: TLabel;
    edtpesquisaDisponivel: TEdit;
    edtPesquisaSelecionada: TEdit;
    procedure FormCreate(Sender: TObject);
    function  VerificaDependenciaTabela(Indice:Integer ;tabela :string ) : Boolean ;
    procedure btnInsereClick(Sender: TObject);
    procedure AtualizaTela;
    procedure btnRemoveClick(Sender: TObject);
    procedure btnInsereTodosClick(Sender: TObject);
    procedure btnRemoveTodosClick(Sender: TObject);
    procedure edtpesquisaDisponivelChange(Sender: TObject);
    procedure edtPesquisaSelecionadaChange(Sender: TObject);
    procedure BtCancelarClick(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmConfigExportacao: TfrmConfigExportacao;

implementation

uses DataModulo;

{$R *.dfm}
function  TfrmConfigExportacao.VerificaDependenciaTabela(Indice:Integer ;tabela :string ) : Boolean ;
var qrTabela : TIB_Query;
begin
   { ==================================================
       Verifica as tabelas que sao necessarias estar preenchidas antes da
       tabela passada como paramentro, ou seja, Verifica a dependencia das tabelas;

       Para manter a integridade esta Function é recursiva. Vericando desta forma todos os nives
       de dependencia das tabelas

       EX: Importando a tabela "Itens_da_nota"
          A tabela "Itens_da_nota" depende da tabela "Notas_Fiscais"
          A tabela "Notas_Fiscais" depende da tabela "Usuario"
          A tabela usuario depende da tabela Funcionarios

          Para nao ocorrer erro de Chave Estrangeira a importacao deve ser feita na seguinte ordem
          Funcionario -> usuario -> Notas_Fiscais -> Itens_da_nota

       Note que a tebela a ser importada era a Itens_da_nota mas ela depende de outras tabelas para ser cadastrada
   ====================================================}

   //============= Para cada chamada um componente é criado, o indice garante que nao vai haver 2 componentes com o mesmo nome =============
   //============= A consulta retorna se a tabela passada como paramentro possui chaves estrangeiras =============

   Indice := Indice +1;
   qrTabela              := TIB_Query.Create(Self);
   qrTabela.Name         := 'qrDinamica'+ IntToStr(Indice );
   qrTabela.IB_Connection:= Dados.IB_Conexao;
   qrTabela.SQL.Add(qrDependencia.SQL.Text);
   qrTabela.ParamByName('VARTABELA').Value := tabela;
   qrTabela.Open;

   Application.ProcessMessages;

   if qrTabela.IsEmpty then
   begin
      //========= se a tabela nao possuir chave estrangeira verifica se ela ja esta inserida na lista de ordenacao
      if not Dados.qrTabelasExportacao.Locate('NOME_TABELA',TABELA,[]) then
      begin
         Dados.qrTabelasExportacao.Insert;
         Dados.qrTabelasExportacao.FieldByName('NOME_TABELA').Value := tabela;
         Dados.qrTabelasExportacao.Post;
      end;
      Result := True;
      qrTabela.Destroy;
      Exit;
   end;

   //============= Depois de realizar as verificacoes de dependecia da tabela que deseja importar ela colocada na ista de ordencao =============
   if not Dados.qrTabelasExportacao.Locate('NOME_TABELA',TABELA,[]) then
   begin
      Dados.qrTabelasExportacao.Insert;
      Dados.qrTabelasExportacao.FieldByName('NOME_TABELA').Value := tabela;
      Dados.qrTabelasExportacao.Post;
   end;

    { ==============================================
       se a tabela depende de outra tabela verifica se essa outra tabela possui dependencia
       Somente acontece a chamada recursiva se essa outra tabela nao estiver na lista de ordenacao
   ==============================================}
   qrTabela.First;
   while not qrTabela.Eof do
   begin
      if not Dados.qrTabelasExportacao.Locate('NOME_TABELA',qrTabela.FieldByName('NOME_TABELA').AsString,[]) then
      begin
         VerificaDependenciaTabela(Indice, qrTabela.FieldByName('NOME_TABELA').AsString );
      end;
      qrTabela.Next
   end;

   Result := True;
   qrTabela.Destroy;
end;


procedure TfrmConfigExportacao.FormCreate(Sender: TObject);
begin
  inherited;
   Dados.qrTabelasExportacao.Open;
   qrListaTodasTb.Open;
   cdsTabelasDisponiveis.Close;
   cdsTabelasDisponiveis.CreateDataSet;
   qrListaTodasTb.First;
   while not qrListaTodasTb.Eof do
   begin
      cdsTabelasDisponiveis.Insert;
      cdsTabelasDisponiveis.FieldByName('NOME_TABELA').Value := qrListaTodasTb.FieldByName('NOME_TABELA').AsString;
      cdsTabelasDisponiveis.Post;
      qrListaTodasTb.Next;
      Application.ProcessMessages;
   end;

   AtualizaTela;
end;

procedure TfrmConfigExportacao.btnInsereClick(Sender: TObject);
begin
  inherited;
   if cdsTabelasDisponiveis.IsEmpty then
   begin
      MessageDlg('Não existe tabelas disponiveis para inserir', mtWarning, [mbOK], 0);
      Exit;
   end;

   //============= Verifica se a tabela possui  dependencias =============
   qrDependencia.Close;
   qrDependencia.ParamByName('VARtabela').AsString  := cdsTabelasDisponiveis.FieldByName('NOME_TABELA').AsString;
   qrDependencia.Open;

   if not qrDependencia.IsEmpty then
   begin
      MessageDlg('Esta tabela necessita de dados previamente cadastrados '+#13+#10+'em outras tabelas do banco de dados.'+#13+#10+'Para garantir a integridade dos dados todas as tabelas'+#13+#10+'diretamente relacionadas serão adcionadas na lsita de seleção', mtWarning, [mbOK], 0);
      VerificaDependenciaTabela(0,cdsTabelasDisponiveis.FieldByName('NOME_TABELA').AsString);
      AtualizaTela;
      Exit;
   end;

   Dados.qrTabelasExportacao.Insert;
   Dados.qrTabelasExportacao.FieldByName('NOME_TABELA').Value := cdsTabelasDisponiveis.FieldByName('NOME_TABELA').Value;
   Dados.qrTabelasExportacao.Post;

   AtualizaTela;
end;

procedure TfrmConfigExportacao.AtualizaTela;
begin
   Dados.qrTabelasExportacao.First;
   while not Dados.qrTabelasExportacao.Eof do
   begin
      if cdsTabelasDisponiveis.Locate('NOME_TABELA', Dados.qrTabelasExportacao.fieldbyname('NOME_TABELA').AsString , [] ) then
         cdsTabelasDisponiveis.Delete;
      Dados.qrTabelasExportacao.Next;
   end;

   lblInfTabDispomiveis.Caption := IntToStr(cdsTabelasDisponiveis.RecordCount);
   lblInfTabExport.Caption := IntToStr(Dados.qrTabelasExportacao.RecordCount);
end;

procedure TfrmConfigExportacao.btnRemoveClick(Sender: TObject);
begin
  inherited;
   if Dados.qrTabelasExportacao.IsEmpty then
   begin
      MessageDlg('Não existe tabelas disponiveis para inserir', mtWarning, [mbOK], 0);
      Exit;
   end;

   cdsTabelasDisponiveis.Insert;
   cdsTabelasDisponiveis.FieldByName('NOME_TABELA').Value := Dados.qrTabelasExportacao.FieldByName('NOME_TABELA').AsString;
   cdsTabelasDisponiveis.Post;
   Dados.qrTabelasExportacao.Delete;
end;

procedure TfrmConfigExportacao.btnInsereTodosClick(Sender: TObject);
begin
  inherited;
   cdsTabelasDisponiveis.First;
   while not cdsTabelasDisponiveis.Eof  do
   begin
     Dados.qrTabelasExportacao.Insert;
     Dados.qrTabelasExportacao.FieldByName('NOME_TABELA').Value := cdsTabelasDisponiveis.FieldByName('NOME_TABELA').Value;
     Dados.qrTabelasExportacao.Post;
     cdsTabelasDisponiveis.Next;
   end;

   AtualizaTela;
end;

procedure TfrmConfigExportacao.btnRemoveTodosClick(Sender: TObject);
begin
  inherited;
   Dados.qrTabelasExportacao.First;
   while not Dados.qrTabelasExportacao.Eof  do
   begin
      cdsTabelasDisponiveis.Insert;
      cdsTabelasDisponiveis.FieldByName('NOME_TABELA').Value := Dados.qrTabelasExportacao.FieldByName('NOME_TABELA').AsString;
      cdsTabelasDisponiveis.Post;
      Dados.qrTabelasExportacao.Next ;
   end;

   while not Dados.qrTabelasExportacao.IsEmpty do
   begin
      Dados.qrTabelasExportacao.Close;
      Dados.qrTabelasExportacao.Open;
      Dados.qrTabelasExportacao.Delete;
   end;
end;

procedure TfrmConfigExportacao.edtpesquisaDisponivelChange(
  Sender: TObject);
begin
  inherited;
   if edtpesquisaDisponivel.Text = '' then
      Exit;

   cdsTabelasDisponiveis.Locate('Nome_Tabela', edtpesquisaDisponivel.Text , [loPartialKey]);
end;

procedure TfrmConfigExportacao.edtPesquisaSelecionadaChange(
  Sender: TObject);
begin
  inherited;
   if edtPesquisaSelecionada.Text = '' then
      Exit;

   Dados.qrTabelasExportacao.Locate('Nome_Tabela', edtPesquisaSelecionada.Text , [lopPartialKey ]);

end;

procedure TfrmConfigExportacao.BtCancelarClick(Sender: TObject);
begin
  inherited;
   Close;
end;

end.
