{~Bk_Kcsr_Ex
  Данные по КЦСР

  exchange #3102
    ФТ1: требуется формировать выгрузку из записей справочника
          "коды целевых статей расходов" с пустой датой "окончание действия"
          либо большей даты, на которую формируется выгрузка (дата логина),
          и пустой датой выгрузки.
    ФТ2:  если параметр "Выгружать из списка"=Да, то пользовательскй список
          требуется формировать из записей с  пустой датой "окончание действия"
          либо большей даты,  на которую формируется выгрузка (дата логина),
          без учета даты выгрузки.}
function Bk_Kcsr_Ex( BudgetId: String;
                      StatusBar: TStatusBar;
                      ProgressBar: TProgressBar;
                      Ref: Boolean;
                      aCfgSelector: integer;
                      aCfgOutFromList: boolean;
                      aEndDate: TDateTime): Variant;
var
  i, cnt: Integer;
  xsql, kcsr: String;
  xCode: string;
  xNode: Variant;
  s: string;
begin

    try
      if not Ref then begin
        xsql :=
     ' select'
    //+' kl.master_id KBK_ID,'
    +' kl.ID LINE_ID,'
    +' kl.CAPTION CAPTION,'
    +' kl.DESCRIPTION DESCRIPTION,'
    +' kl.begin_date BEGIN_DATE,'
    +' kl.end_date END_DATE,'
    +' kl.change_date CHANGE_DATE,'
    +' kl.unload_date UNLOAD_DATE,'
    +' C.CODE KCSR_CODE,'
    +' 0 TYPE_KBK,'
    +' 0 LIMITED_FLAG'
    +' from EXPBUDGET B'
    +' join KCSR C on (C.CODE = B.KCSR_CODE and C.BUDGET_ID = B.budget_id)'
    +' join KCSR_LINES KL on (KL.MASTER_ID = C.ID)'
    +' where B.BUDGET_ID = ?'
//          +' ~3 '         // exchange #3102
          +' ~2 '
    +' group by'
    //+' kl.master_id,'
    +' kl.ID,'
    +' kl.CAPTION,'
    +' kl.DESCRIPTION,'
    +' kl.begin_date,'
    +' kl.end_date,'
    +' kl.change_date,'
    +' kl.unload_date,'
    +' C.CODE';


    (*    'Select
        +' .ID KBK_ID,'
        +' C.Kcsr_Code, KL.Description, KL.Caption, KL.Begin_Date,' +
          ' KL.Change_Date, KL.End_Date' +
          ' From ExpBudget C' +
          ' Join Kcsr On (Kcsr.Code = C.Kcsr_Code And Kcsr.Budget_Id = ?)' +
          ' Join Kcsr_Lines KL on (KL.Master_Id = Kcsr.Id)' +
          ' Where C.Budget_Id = ?'
          +' ~1 ~2 '
          +' Group By C.Kcsr_Code, KL.Description, KL.Caption, KL.Begin_Date,' +
          ' KL.Change_Date, KL.End_Date';
          *)
    //    Query.AddStr( BudgetId);
        Query.AddStr( BudgetId);
      end else begin
        xsql :=
     ' select distinct '
    //+' kl.master_id KBK_ID,'
    +' kl.ID LINE_ID,'
    +' 0 TYPE_KBK,'
    +' kl.CAPTION CAPTION,'
    +' kl.DESCRIPTION DESCRIPTION,'
    +' kl.begin_date BEGIN_DATE,'
    +' kl.end_date END_DATE,'
    +' kl.change_date CHANGE_DATE,'
    +' kl.unload_date UNLOAD_DATE,'
    +' C.CODE KCSR_CODE,'
    +' 0 TYPE_KBK,'
    +' 0 LIMITED_FLAG,'
    +' 0 LINE_VERSION'
    +' from KCSR C'
    +' join KCSR_LINES KL on (KL.MASTER_ID = C.ID)'
    +' where C.BUDGET_ID = ?'
       //   +' ~3 '         // exchange #3102
          +' ~2 ';
    (*
        xsql := 'Select distinct C.Code Kcsr_Code, KL.Description, KL.Caption,' +
          ' KL.Begin_Date, KL.Change_Date, KL.End_Date' +
          ' From Kcsr C' +
          ' Join Kcsr_Lines KL on (KL.Master_Id = C.Id)' +
          ' Where C.Budget_Id = ? ~1 ~2';
          *)
        Query.AddStr( BudgetId);
      end;

      {
      // exchange #3102
      if aCfgOutFromList then begin
        // выбор из списка - дату выгрузки не учитываем
        s := 'and (kl.end_date is null or kl.end_date>?)';
      end else begin
        // выбор не из списка - дата выгрузки должна быть не указана
        s := 'and (kl.end_date is null or kl.end_date>?)';
//            +' and (kl.unload_date is null))';
      end;
      // заменяем подзапрос ~3 на выражение
      xSQL := StringReplace( xSQL, '~3', s);
      Query.AddDate( aEndDate);
      }


      // exchange #2596
      // если параметр Выгружать только «Утвержден на уровне субъекта
      // (муниципального образования)»» = да, то фильтруем по полю
      // «Утвержден на уровне субъекта (муниципального образования)».
      // допускаются записи у которых значение в этом поле =1.
      if vCfg_2596
        then Result := ExecuteQueryLoadEx( xSql, 'KL', '~2', ' and C.APPROVED_ENTITY_LEVEL=1 ')
        else Result := ExecuteQueryLoadEx( xSql, 'KL', '~2');

      cnt := Result.documentElement.ChildNodes.Length;
      ProgressBar.Max := cnt;
      for i := 0 to Result.documentElement.ChildNodes.Length - 1 do begin
        xNode := Result.documentElement.ChildNodes.item[i];

        ProgressBar.Position := i + 1;
        StatusBar.SimpleText := 'Приведение КБК в соответсвие с маской. Обработано: ' +
          IntToStr(i + 1) + ' из ' + IntToStr(cnt);

        { доработка заключается в удалении кеша - это не нужно.
          поскольку теперь при форматировании используется кэш более эффективно.
          это связано с тем, что в разных бюджетов маски могут быть разными.
          и потом: иметь один кеш на все коды - не эффективно: много памяти
          потребляется.
          так же добавлено новое поле: CODE_COPY.
          в него заносится исходный код БК, а в поле CODE сохраняем форматированный
          по максе (в отличие от старого кода, где форматирование только по длине).
          это больше похоже на АЦК-Ф, только для линейного списка.}
        xCode := xNode.getAttribute('KCSR_CODE');
    {
        Kcsr := CacheFormatKbk.Values['Kcsr' + xCode];
        if Kcsr = '' then begin
          Kcsr := KcsrCodeFormat( xCode, BudgetId, kbkMaskOfChar);
          CacheFormatKbk.Add('Kcsr' + xCode + '=' + Kcsr);
        end;
    }
        xNode.setAttribute( 'CODE',
                            KcsrCodeFormat( xCode, BudgetId, kbkMaskOfChar, FALSE));
        //Kcsr);
        xNode.setAttribute('CODE_COPY', xCode);
      end;
      ProgressBar.Position := 0;

      except
        ExceptionProc( 'Bk_Kcsr_Ex');
    end;

end;

begin
end.
