uses
  'Un_ExpChange',
  'Un_InChange',
  'Un_SrcChange',
  'Un_Const',
{отладка}
  // при отладке заккоментировать модуль ..\Tools\Un_Query!
  '..\Tools\Un_Query',
{не стирать эту строку}

  'Un_LogTools',
  '..\Version\CheckVersion';

procedure Main(Xml: Variant);
begin

	CheckWorkAppVersion;
  with Xml.documentElement do
  if getAttribute('TESTED') = 'True' then
  begin
    setAttribute('TESTED', 'False');
    Xml.save(FFileName);
    ShowMessage('Тестовый пример приготовлен: ' + FFileName);
    Exit;
  end;
  FAzkIsLogin := AzkIsLogin;
  if not AzkIsLogin then
    if not AzkLogin then
      Exit;
  try
    try
      initialization(Xml);
      if FDebuger then
      begin
        Form.Show;
        repeat
          Application.handleMessage;
        until(not Form.Visible);
      end
      else
        Form.ShowModal;
    except
      WriteLog(LastException.Message);
      raise(LastException.Message);
    end;
  finally
    finalization;
    if not FAzkIsLogin then
      AzkLogout;
  end;

end; {End Main}

procedure initialization(Xml: Variant);
begin
  IniPath := ExtractFilePath(Xml.documentElement.getAttribute('INI_FILE'));
  FileLog := IniPath + 'ExportExpInSrcChange.log';
  FileInfo := IniPath + 'ExportExpInSrcChange.inf';
  Form := TFormCustom.Create(Application);
  Form.LoadDfm(IniPath + 'Fm_ExportExpInSrcChange.dfm');
  TLabel(Form.FindComponent('lblVersion')).Caption := 'Версия формата: ' + cFileVer;
  ProgressBar := TProgressBar(Form.FindComponent('ProgressBar'));
  Form.actExecute.OnExecute := @actExecuteExecute;
  dtmBeginDate := TDateTimeEh(Form.FindComponent('dtmBeginDate'));
  dtmBeginDate.Date :=  StrToDate('01.01.' + FormatDateTime('yyyy', Work_Date));
  dtmBeginDate.OnChange := @OnDateChange;
  dtmEndDate := TDateTimeEh(Form.FindComponent('dtmEndDate'));
  dtmEndDate.Date := Work_Date;
  dtmEndDate.OnChange := @OnDateChange;
  edtDir := TEdit(Form.FindComponent('edtDir'));
  TSpeedButton(Form.FindComponent('spbDir')).OnClick := @OnbtnDirClick;
  cmbForm := TComboBox(Form.FindComponent('cmbForm'));
  cmbForm.OnChange := @cmbFormOnChange;
  chkRepeat := TCheckBox(Form.FindComponent('chkRepeat') );
  // Выбираемые формы уведомлений об изменении бюджетных назначений
  FmExp := TFormCustom.Create(Form);
  FmExp.LoadDfm(IniPath + 'Fm_ExpChange.dfm');
  FmExp.Parent := TGroupBox(Form.FindComponent('grbForm'));
  FmIn := TFormCustom.Create(Form);
  FmIn.LoadDfm(IniPath + 'Fm_InChange.dfm');
  FmIn.Parent := FmExp.Parent;
  FmSrc := TFormCustom.Create(Form);
  FmSrc.LoadDfm(IniPath + 'Fm_SrcChange.dfm');
  FmSrc.Parent := FmExp.Parent;
  // Бланки расходов
  FmEstimate := TFormCustomTree.Create(Form);;
  FmEstimate.LoadDfm(IniPath + '..\Forms\Fm_Estimate.dfm');
  FmEstimate.SQLText := 'Select E.Id, E.Parent_Id, E.Caption || '' ('' || K.Caption || '')'' Caption' +
    ' From Estimate E Left Join Estkind K On K.Id = E.EstKind_Id' +
    ' Where E.Budget_Id = ' + Budget_Id + ' Order By E.Caption';
  FmEstimate.EditResFieldName := 'Caption';
  edtEstimate := TEdit(FmExp.FindComponent('edtEstimate'));
  FmEstimate.Edit := edtEstimate;
  FmEstimate.SpeedButton := TSpeedButton(FmExp.FindComponent('spbEstimate'));
  // Бюджетополучатели
  FmRecipient := TFormCustomList.Create(Form);
  FmRecipient.LoadDfm(IniPath + '..\Forms\Fm_Org.dfm');
  FmRecipient.SQLText := 'Select o.Id, o.Caption From Org o';
  FmRecipient.EditResFieldName := 'Caption';
  edtRecipient := TEdit(FmExp.FindComponent('edtRecipient'));
  FmRecipient.Edit := edtRecipient;
  FmRecipient.SpeedButton := TSpeedButton(FmExp.FindComponent('spbRecipient'));
  // Расходные обязательства
  FmDirection := TFormCustomList.Create(Form);
  FmDirection.LoadDfm(IniPath + '..\Forms\Fm_Directions.dfm');
  FmDirection.SQLText := 'Select D.Id, Coalesce(O.Caption, ''Не указана'') O_Caption, P.Caption D_Caption' +
    ' From  Pl_Direction D' +
    ' Join Pl_Permission P On P.Id = D.Pl_Permission_Id' +
    ' Left Outer Join Org O On D.Org_Id = O.Id' +
    ' Where D.Budget_Id = ' + Budget_Id +
    ' Order By 2';
  FmDirection.EditResFieldName := 'D_Caption';
  FmDirection.Edit := TEdit(FmExp.FindComponent('edtDirection'));
  FmDirection.SpeedButton := TSpeedButton(FmExp.FindComponent('spbDirection'));
  // Территории
  FmTerritory := TFormCustomTree.Create(Form);
  FmTerritory.LoadDfm(IniPath + '..\Forms\Fm_Territory.dfm');
  FmTerritory.SQLText := 'Select Cast(Null As Numeric(15)) Id' +
    ', Cast(-1  As Numeric(15)) Parent_Id, Cast(''Территории'' As VarChar(255)) Caption' +
    ' From Territory T Where T.Id = 0 Union' +
    ' Select T.Id, T.Parent_Id,  Cast(T.Caption As VarChar(255)) Caption From Territory T';
  FmTerritory.EditResFieldName := 'Caption';
  edtTerritory := TEdit(FmIn.FindComponent('edtTerritory'));
  FmTerritory.Edit := edtTerritory;
  FmTerritory.SpeedButton := TSpeedButton(FmIn.FindComponent('spbTerritory'));
  // Получатели
  FmReceiver := TFormCustomList.Create(Form);
  FmReceiver.LoadDfm(IniPath + '..\Forms\Fm_Org.dfm');
  FmReceiver.SQLText := 'Select Distinct R.Id, R.Caption' +
    ' From Inchange I' +
    ' Join Receiver R On R.Id = I.Receiver_Id' +
    ' Where I.Budget_Id = ' + Budget_Id +
    ' Order By 1';
  FmReceiver.EditResFieldName := 'Caption';
  edtReceiver := TEdit(FmIn.FindComponent('edtReceiver'));
  FmReceiver.Edit := edtReceiver;
  FmReceiver.SpeedButton := TSpeedButton(FmIn.FindComponent('spbReceiver'));
  // Гл. администратор
  FmKadmd := TFormKbk.Create(Form);
  FmKadmd.Kbk_Code := KADMD_CODE;
  edtKadmd := TEdit(FmIn.FindComponent('edtKadmd'));
  FmKadmd.Edit := edtKadmd;
  FmKadmd.SpeedButton := TSpeedButton(FmIn.FindComponent('spbKadmd'));
  // Контрагенты
  FmCounteragent := TFormCustomList.Create(Form);
  FmCounteragent.LoadDfm(IniPath + '..\Forms\Fm_Org.dfm');
  FmCounteragent.SQLText := 'Select Distinct O.Id, O.Caption' +
    ' From SourceChange S' +
    ' Join Org O On O.Id = S.Counteragent_Id' +
    ' Where S.Budget_Id = ' + Budget_Id +
    ' Order By 2';
  FmCounteragent.EditResFieldName := 'Caption';
  edtCounteragent := TEdit(FmSrc.FindComponent('edtCounteragent'));
  FmCounteragent.Edit := edtCounteragent;
  FmCounteragent.SpeedButton := TSpeedButton(FmSrc.FindComponent('spbCounteragent'));
  // Гл. администратор
  FmKadmi := TFormKbk.Create(Form);
  FmKadmi.Kbk_Code := KADMI_CODE;
  edtKadmi := TEdit(FmSrc.FindComponent('edtKadmi'));
  FmKadmi.Edit := edtKadmi;
  FmKadmi.SpeedButton := TSpeedButton(FmSrc.FindComponent('spbKadmi'));
  // Типы операций
  FmOperType :=  TFormCustomList.Create(Form);
  FmOperType.LoadDfm(IniPath + '..\Forms\Fm_OperType.dfm');
  FmOperType.EditResFieldName := 'Caption';
  // Источники изменения ассигнований и лимитов
  FmAssignSource :=  TFormCustomList.Create(Form);
  FmAssignSource.LoadDfm(IniPath + '..\Forms\Fm_AssignSource.dfm');
  FmAssignSource.SQLText := 'Select A.id,  A.Code, A.As_Type, A.Description, E.Caption Estimate, O.Caption Recipient' +
    ', Case When A.As_Type = 0 Then ''Балансировка по расходам''' +
    ' Else Case When A.As_Type = 1 Then ''Балансировка по источникам''' +
    ' Else ''Прочее'' End End As_Type_Name' +
    ' From Assign_Source A' +
  // exchange #2383
  // доработка запроса - добавлен префикс left в связанные таблицы
  // это дает выборку из Assign_Source, если связанных данных со справочниками
  // Estimate и Org нет (указано "Прочее").
    ' left Join Estimate E On E.Id = A.Estimate_Id' +
    ' left Join Org O On O.Id = A.Recipient_Id' +
    ' Where A.Budget_Id = ' + Budget_Id;
  FmAssignSource.EditResFieldName := 'Code';
  edtAssignSource := TEdit(FmExp.FindComponent('edtAssignSource'));
  FmAssignSource.Edit := edtAssignSource;
  FmAssignSource.SpeedButton := TSpeedButton(FmExp.FindComponent('btnAssignSource'));
  // ------
  TTimer(Form.FindComponent('Timer')).OnTimer := @OnTimer;
end; {End initialization}

procedure finalization;
begin
  FmExp.Close;
  FmIn.Close;
  FmSrc.Close;
  Form.Free;
end; {End finalization}

procedure OnbtnDirClick(Sender: TObject);
begin
  ChooseFolder('Укажите каталог экспорта', edtDir.Text);
end; {End OnbtnDirClick}

procedure OnDateChange(Sender: TObject);
begin
  if Sender = dtmBeginDate then
  begin
    if dtmBeginDate.Date > dtmEndDate.Date then
      dtmEndDate.Date := dtmBeginDate.Date;
  end
  else
  begin
    if dtmBeginDate.Date > dtmEndDate.Date then
      dtmBeginDate.Date := dtmEndDate.Date;
  end;
end; {End OnDateChange}

procedure OnTimer(Sender: TObject);
begin
  if Form.Visible then
  begin
    TTimer(Sender).Enabled := False;
    cmbFormOnChange(Sender);
  end;
end; {End OnTimer}

procedure cmbFormOnChange(Sender: TObject);
begin
  FmOperType.SQLText := 'Select O.Id, O.Caption' +
    ' From OperType O' +
    ' Left Join ClassOper C On C.OperType_Id = O.Id';
  case cmbForm.ItemIndex of
    0:
      begin
        FmDirection.Edit := TEdit(FmExp.FindComponent('edtDirection'));
        FmDirection.SpeedButton := TSpeedButton(FmExp.FindComponent('spbDirection'));
        FmOperType.SQLText := FmOperType.SQLText +
          ' Where C.DocumentClass_Id = 128 Or O.Id = 0';
        FmOperType.Edit := TEdit(FmExp.FindComponent('edtOperType'));
        FmOperType.SpeedButton := TSpeedButton(FmExp.FindComponent('btnOperType'));
        FmExp.Show;
      end;
    1:
      begin
        FmOperType.SQLText := FmOperType.SQLText +
          ' Where C.DocumentClass_Id = 26 Or O.Id = 0';
        FmOperType.Edit := TEdit(FmIn.FindComponent('edtOperType'));
        FmOperType.SpeedButton := TSpeedButton(FmIn.FindComponent('btnOperType'));
        FmIn.Show;
      end;
    2:
      begin
        FmDirection.Edit := TEdit(FmSrc.FindComponent('edtDirection'));
        FmDirection.SpeedButton := TSpeedButton(FmSrc.FindComponent('spbDirection'));
        FmOperType.SQLText := FmOperType.SQLText +
          ' Where C.DocumentClass_Id = 27 Or O.Id = 0';
        FmOperType.Edit := TEdit(FmSrc.FindComponent('edtOperType'));
        FmOperType.SpeedButton := TSpeedButton(FmSrc.FindComponent('btnOperType'));
        FmSrc.Show;
      end;
  end;
end; {End cmbFormOnChange}

procedure actExecuteExecute(Sender: TObject);
begin
  if Trim(edtDir.Text) = '' then
  begin
    MessageDlg('Не указан каталог выгрузки', mtError, mbOk, 0);
    Exit;
  end;
  if Trim(edtDir.Text) = '' then
  begin
    MessageDlg('Не указан каталог выгрузки', mtError, mbOk, 0);
    Exit;
  end;
  edtDir.Text := StringReplace(edtDir.Text + '\', '\\', '\');
  if not DirectoryExists(edtDir.Text) then
  begin
    MessageDlg('Отсутствует каталог: ' + edtDir.Text, mtError, mbOk, 0);
    Exit;
  end;
  if chkRepeat.Checked then
    if MessageDlg('Выгружать повторно документы ?', mtConfirmation,
      mbYes + mbNo , 0) <> mrYes then
      Exit;
  try
    QueryInitialization;
    WriteLog('====== НАЧАЛО ЭКСПОРТА ======');
    WriteLog('==== ПАРАМЕТРЫ ЭКСПОРТА =====');
    WriteLog('Экспортируемые документы: ' + cmbForm.Items.Strings[cmbForm.ItemIndex]);
    WriteLog('Период C ' + FormatDateTime('dd.mm.yyyy', dtmBeginDate.Date) +
      ' По ' + FormatDateTime('dd.mm.yyyy', dtmEndDate.Date));
    WriteLog('Повторная выгрузка документов: ' + IfThen(chkRepeat.Checked, 'Да', 'Нет'));
    SetAppDisable;
    CursorDisable;
    Key := '';
    if FileExists(FileInfo) then
      DeleteFile(FileInfo);
    try
      case cmbForm.ItemIndex of
        0: OnExpChange(Sender);
        1: OnInChange(Sender);
        2: OnSrcChange(Sender);
      end;
    except
      WriteLog('Ошибка исполнения: ' + LastException.Message);
      raise(LastException.Message);
    end;
  finally
    QueryFinalization;
    CursorEnable;
    SetAppEnable;
    WriteLog('==== ЗАВЕРШЕНИЕ ЭКСПОРТА ====');
    ProgressBar.Position := 0;
    Form.SimpleText := '';
    if FileExists(FileInfo) then
      ShellExecute('NotePad', FileInfo, False);
  end;
end; {End actExecuteExecute}

begin
  FAzkIsLogin := AzkIsLogin;
  FDebuger := True;
  Xml := CreateOleObject('Microsoft.XmlDom');

  {отладка}
  if not FileExists(FFileName) then
  begin
    ShowMessage('Не найден тестовый пример: ' + FFileName);
    Exit;
  end;
  if not Xml.Load(FFileName) then
  begin
    ShowMessage('Ошибка при загрузке: ' + FFileName);
    Exit;
  end;
  {не стирать эту строку}



  if not AzkIsLogin then
    if not AzkLogin then
      Exit;
  try
    Main(Xml);
  finally
    if not FAzkIsLogin then
      AzkLogout;
  end;
end.
