var
  FmGrantInvestList: TFormCustom;
  DBGridGrantInvest: TDBGridEh;
  actRefreshGrantInvest, actSelectGrantInvest: TAction;
  cdsGrantInvest: TClientDataSet;
  TimerGrantInvest: TTimer;
  BudgetId, Org_Id, Code: String;
  vIniPath_GrantIntvestment: String;

function GetGrantIntvestmentId(CdsMain: TClientDataSet; IniPath: String): String;
begin
  Result := '';
  Initialize(CdsMain, IniPath);
  if FmGrantInvestList.ShowModal = MrOk then
    Result := DBGridGrantInvest.Bookmark.CommaText;
  Finalize;
end;
  
procedure Initialize(CdsMain: TClientDataSet; IniPath: String);
begin
  FmGrantInvestList := TFormCustom.Create(Application);
  FmGrantInvestList.LoadDfm(IniPath + 'Fm_GrantInvestList.dfm');
  FmGrantInvestList.Caption := 'Выбор кода субсидии в документе № ' +
    CdsMain.FieldByName('Doc_Number').asString + ' Дата: ' +
    CdsMain.FieldByName('Doc_Date').asString  + ' Сумма = ' +
    CdsMain.FieldByName('Amount').asString;
  cdsGrantInvest :=
    TClientDataSet(FmGrantInvestList.FindComponent('cdsGrantInvestList'));
  cdsGrantInvest.CreateDataSet;
  DBGridGrantInvest := TDBGridEh(FmGrantInvestList.FindComponent('DBGrid'));
  actRefreshGrantInvest := TAction(FmGrantInvestList.FindComponent('actRefresh'));
  actRefreshGrantInvest.OnExecute := @actRefreshFmGrantInvestExecute;
  actSelectGrantInvest := TAction(FmGrantInvestList.FindComponent('actSelect'));
  actSelectGrantInvest.OnExecute := @actSelectFmGrantInvestExecute;
   //actClose := TAction(FmGrantInvestList.FindComponent('actClose'));
  BudgetId := CdsMain.FieldByName('Budget_Id').AsString;
  Org_Id := CdsMain.FieldByName('Org_Id').AsString;
  Code := CdsMain.FieldByName('Grantinvestment_Code').AsString;
  TimerGrantInvest := TTimer(FmGrantInvestList.FindComponent('Timer'));
  TimerGrantInvest.onTimer := @actRefreshFmGrantInvestExecute;
  TimerGrantInvest.Enabled := True;
  FmGrantInvestList.AppEvents.onMessage := @GrantInvestAppEventsMessage;
end;

procedure actRefreshFmGrantInvestExecute(Sender: TObject);
var
  sql: String;
begin
  TimerGrantInvest.Enabled := False;
  cdsGrantInvest.DisableControls;
  DBGridGrantInvest.BookmarkUnCheckAll;
  DBGridGrantInvest.Enabled := False;
  DBGridGrantInvest.SavePosition;
  SetAppDisable;
  try
    sql := 'Select G.Id, G.FType, (case when G.FType = 0 then ''Госзадание''' +
      ' when G.FType = 1 then ''Капитальные вложения''' +
      ' when G.FType = 2 then ''Субсидии на иные цели''' +
      ' when G.FType = 3 then ''Не указан''' +
      ' else ''не определено'' end) DType,' +

//      ' G.Code, G.Caption, O.Description Org_Name' +
//      ' From Grantinvestment G' +
//      ' Join Org O on O.Manager_Id = G.Org_id' +
//      ' Where G.Budget_Id = ? and O.Id = ? and G.Code = ?' +

      ' G.Code, G.Caption,'+
      ' O.Description Org_Name, '+          // учредитель
      ' OU.Description UCHREGD_NAME' +       // учреждение
      ' From Grantinvestment G' +
      // exchange #2588
      // чтобы отобразить учреждение (название организации вышестоящего
      // ГРБС у организации, которая является учредителем кода субсидии),
      // т.е. нужна связка:
      // G.ORG_ID -> O.ID -> OU.MANAGER_ID
      // учреждение будет OU (отображать название организации OU), а учредитель O.
      ' Join Org O on O.id = G.Org_id'+
      ' left Join Org OU on OU.manager_id=O.id'+
      // при этом нужно фильтровать список по учреждениям,
      // которые являются организациями получателя из выписки (org_id)
      ' Where G.Budget_Id = ? and OU.Id = ? and G.Code = ?' +

      ' Union' +
      ' Select G.Id, G.FType, (case when G.FType = 0 then ''госзадание''' +
      ' when G.FType = 1 then ''бюджетные инвестиции'' else ''субсидии на иные цели'' end) DType,' +
      ' G.Code, G.Caption, ''НЕ УКАЗАНА'' Org_Name, '#39'НЕ УКАЗАНА'#39' UCHREGD_NAME' +
      ' From Grantinvestment G' +
      ' Where G.Budget_Id = ? and (G.Org_Id = 0 or G.Org_Id is null) '+
      ' and G.Code = ?';
    Query.AddStr(BudgetId);
    Query.AddStr(Org_Id);
    Query.AddStr(Code);
    Query.AddStr(BudgetId);
    Query.AddStr(Code);
    Query.RunCds(cdsGrantInvest, sql);
  finally
    cdsGrantInvest.EnableControls;
    DBGridGrantInvest.RestorePosition;
    DBGridGrantInvest.DefaultApplySorting;
    DBGridGrantInvest.Enabled := True;
    SetAppEnable;
  end;
end;

procedure actSelectFmGrantInvestExecute(Sender: TObject);
begin
  FmGrantInvestList.ModalResult := MrOk;
end;

procedure GrantInvestAppEventsMessage;
begin
  FmGrantInvestList.actRefresh.Enabled := AppEnable;
  FmGrantInvestList.actClose.Enabled := AppEnable;
  FmGrantInvestList.actSelect.Enabled := DBGridGrantInvest.Bookmark.Count = 1;
end;

procedure finalize;
begin
  FmGrantInvestList.Free
end; {End finalization}

{ exchange #3039
  в целях оптимизации, форма выбора реализована целиком в скрипте,
  а не отдельным скриптом. в результате все компилится единым кодом,
  а не подгружается по ходу необходимости.
  это реально ускоряет работу скрипта в случае необходимости вызова,
  выбора кода из формы но несколько увеличивает время старта и завершения
  скрипта.
  особенности:
    1) форма инициализируется один раз, если указатель на форму =NIL.
    2) при активации диалога GetGrantInvestmentIdEx указывается не DataSet
        с чтением значений полей из DataSet, а передача непосредственно
        значений через параметры. это дает то, что будет ли чтение из dataset
        или по другому, здесь это не важно - это делается в вызывающем коде.
        это согласуется с кешированием значений в dataset.
    3) форма не уничтожается до завершения скрипта. это ускоряет проверку,
        которая выполняется по нескольку раз.
  самое существенное:
    этот подход будет работать как со старым, так и с новым кодом.}
procedure GrantInvestmentExInitialize( aIniPath: string);
begin
  FmGrantInvestList := NIL;
  vIniPath_GrantIntvestment := aIniPath;
end;

procedure GrantInvestmentExFinalize;
begin
  if (FmGrantInvestList <> NIL) then begin
    FmGrantInvestList.Free;
    FmGrantInvestList := NIL;
  end;
end;

function GetGrantInvestmentIdEx( aDocInfo, aBudgetId, aOrg_Id, aGrInvCode: string): string;
begin
  Result := '';

  // форма создается только один раз при первом обращении к подпрограмме
  if (FmGrantInvestList = NIL) then begin
    FmGrantInvestList := TFormCustom.Create(Application);
    FmGrantInvestList.LoadDfm(vIniPath_GrantIntvestment + 'Fm_GrantInvestList.dfm');
//  end;
    cdsGrantInvest :=
      TClientDataSet(FmGrantInvestList.FindComponent('cdsGrantInvestList'));

    cdsGrantInvest.CreateDataSet;
    DBGridGrantInvest := TDBGridEh(FmGrantInvestList.FindComponent('DBGrid'));
    actRefreshGrantInvest := TAction(FmGrantInvestList.FindComponent('actRefresh'));
    actRefreshGrantInvest.OnExecute := @actRefreshFmGrantInvestExecute;
    actSelectGrantInvest := TAction(FmGrantInvestList.FindComponent('actSelect'));
    actSelectGrantInvest.OnExecute := @actSelectFmGrantInvestExecute;
     //actClose := TAction(FmGrantInvestList.FindComponent('actClose'));

    TimerGrantInvest := TTimer(FmGrantInvestList.FindComponent('Timer'));
    TimerGrantInvest.onTimer := @actRefreshFmGrantInvestExecute;
    TimerGrantInvest.Enabled := True;
    FmGrantInvestList.AppEvents.onMessage := @GrantInvestAppEventsMessage;
  end;

  FmGrantInvestList.Caption :=
      FORMAT( 'Выбор кода субсидии в документе %s', [ aDocInfo]);

  BudgetId := aBudgetId;
  Org_Id := aOrg_Id;
  Code := aGrInvCode;

//  Initialize(CdsMain, IniPath);

  if (FmGrantInvestList.ShowModal = MrOk)
    then Result := DBGridGrantInvest.Bookmark.CommaText;
//  Finalize;
  GrantInvestmentExFinalize;
end;


begin
end.