


(*
{~FillEstimateIDintoED25fromED24byIKnew
  поиск БР для создаваемого эд 25го по эд 24му при загрузке из IK файла.

  exchange #2938
1. Для  организации из блока «Получатель» ЭД класса 24 ( ЭД класса 1)1
  (в зависимости от родительского документа для ЭД класса 25, текущую
  реализацию не меняем) производится поиск Бланка расходов (Далее по тексту БР),
  оператором - владельцем которого она является, в системе – с признаком
  «актуальный бланк расходов» и с типом «Смета» или «ПНО».
  Если БР определен однозначно, то поле «Бланк расходов» заполняется найденным
  значением.
2. Если БР найден не однозначно по условиям п.1, то к условиям поиска
  добавляем значение поля «Лицевой счет» БР, определенный по условиям текущей
  реализации на момент формирования ЭД класса 25и поиска БР, если БР определен
  однозначно, то поле «Бланк расходов» заполняется найденным значением.
  Иначе см. п.3.
3. Если БР не определен по п.1 или 2, то:
1)     фильтруем строки расходной части бюджета (далее по тексту РЧБ) по
      значениям «строка 20-го КБК» + «Код цели» бюджетной строки
      родительского ЭД, если «Код цели» в родительском документе не указан,
      исключаем его из фильтра поиска;
2)     Из найденных строк  выбираем строки с бюджетополучателем, определенным
      в п.1, если найдена однозначно  - то есть одна или несколько строк:
      бюджетополучатель + один БР, то БР и поле «Бюджетополучатель» заполняются
      из найденной строки (либо из первой найденной строки).
      Если  не найдено ни одной строки с бюджетополучателем, то в найденных
      строках ищем строку со значением поля «Бюджетополучатель» = «Не указана»,
      если найдена одна строка, то БР заполняем из данной строки.
      Иначе см. п.4
4. Если БР не удалось определить, то ЭД класса 25 формируем с БР из первой
      строки родительского ЭД.}
function FillEstimateIDintoED25fromED24byIKnew( aDoc25, aDoc24: Variant): boolean;
var
  i: Integer;
  xXml: Variant;
  xSQLEst: string;
  xListEstID: String;
  xListEstValue: array of string;
  xED24Lines: Variant;
  xED24Line: Variant;
  xBudgetID: String;
  xOrgID: String;
  xORGACCOUNT_ID: String;
  xEstimateID: string;
  xPURPOSEFULGRANT_ID: string;

  {~DoCheckFound_
    проверяет сколько найдено строк БР в результате поиска (в переменной xXml).
    результат:
      =true - одна строка
      =false - несколько/ни одной строк.

    если не найдено ни одной строки, в журнале info отображается
    сообщение aMsgFor0.

    если не найдено несколько строк, в журнале info отображается
    сообщение aMsgForN с форматированием строки и добавлением в сообщение
    количества найденных строк. }
  function DoCheckFound_( aMsgFor0, aMsgForN: string): boolean;
  var
    n: integer;
  begin

      try
        n := xXml.documentElement.childNodes.Length;

        case n of
          0: begin
                WriteInfo( aMsgFor0);
                Result := FALSE;
              end;
          1: Result := TRUE;
        else begin
                WriteInfo( FORMAT( aMsgForN, [ INTTOSTR( n)]));
                Result := FALSE;
              end;
        end;//case//

        except
          ExceptionProc( 'DoCheckFound_');
      end;

  end;

  {~DoSearchEstimateIntoDictByOrg_
    поиск БР для бюджета xBudgetID и организации-оператора xOrgID }
  procedure DoSearchEstimateIntoDictByOrg_;
  begin

      try
        xXml := QueryXml(  ' Select Id From Estimate'
                          +' Where EstKind_Id in (1, 7) and Actual_Flag = 1'
                          +' and Budget_Id = ? and Org_Id = ?',
                            [ xBudgetID,
                              xOrgID]);
        except
          ExceptionProc( 'DoSearchEstimateIntoDictByOrg_');
      end;

  end;

begin

    try
      Result := TRUE;
      aDoc25.SetAttribute( 'ESTIMATE_ID','');

      // в начале заполняем БР из первой строки ЭД 24го
      // это значение "по умолчанию".
      // ищем узел а не берем первый, поскольку возможны дополнительные
      // узлы описания полей в эд 24м
      xED24Lines := NULL;
      for i := 0 to aDoc24.ChildNodes.Length - 1 do
        if (aDoc24.ChildNodes.Item[i].NodeName = 'PAYORDERLINE') then begin
          xED24Lines := aDoc24.ChildNodes.Item[i];
          BREAK;
        end;
      if VarIsNULL( xED24Lines) then begin
        WriteInfo( 'В ЭД 24м не найдено описание строк.');
        EXIT;
      end;
      // берем первую строку эд 24го
      if (xED24Lines.ChildNodes.Length <= 0) then begin
        WriteInfo( 'В ЭД 24м отсутствуют строки.');
        EXIT;
      end;
      xED24Line := xED24Lines.ChildNodes.Item[ 0];
      aDoc25.SetAttribute( 'ESTIMATE_ID',
                           GetNodeAttributeEx( xED24Line, 'ESTIMATE_ID'));
      // код цели из первой строки эд 24го
      xPURPOSEFULGRANT_ID := GetNodeAttributeEx( xED24Line, 'PURPOSEFULGRANT_ID');


      // берем из эд 25го параметры орг и счета для поиска БР
      xBudgetID           := aDoc24.GetAttribute( 'F_BUDGET_ID');
      // ищем БР по организации и счету получателя - берем из эд 24го
      xOrgID              := aDoc24.GetAttribute( 'REC_ID');
      // счет берем из 25го, поскольку он заполняется в шапке эд 25го
      // в зависимости от файла загрузки
      xORGACCOUNT_ID      := GetNodeAttributeEx( aDoc25, 'ORGACCOUNT_ID');


      // ищем бланк расходов в справочнике по бюджету и орг.оператору
      DoSearchEstimateIntoDictByOrg_;
      if NOT DoCheckFound_(
                'Бланк расходов для организации оператора не найден в справочнике.',
                'Найдено несколько (%s) бланков расходов для организации оператора.')
        then
          if (LENGTH( xORGACCOUNT_ID) > 0) then begin
            //дополнительный поиск по счету
            WriteLog( 'Поиск бланка расходов с учетом лицевого счета...');
            xXml := QueryXml(  ' Select Id From Estimate'
                              +' Where EstKind_Id in (1, 7) and Actual_Flag = 1'
                              +' and Budget_Id = ? and Org_Id = ?'
                              +' and Face_Acc = ?',
                                [ xBudgetID,
                                  xOrgID,
                                  xORGACCOUNT_ID]);
            // здесь в логе отображаем результат поиска
            DoCheckFound_(
               'Бланк расходов не найден в справочнике с учетом лицевого счета.',
               'Найдено несколько (%s) бланков расходов в справочнике с учетом лицевого счета.');

            // проверим, если ничего не нашли, тогда будем искать БР без л/с
            // т.е. еще раз ищем бланк расходов в справочнике по бюджету и
            // орг.оператору и без л/с
            if (xXml.documentElement.childNodes.Length <= 0)
              then DoSearchEstimateIntoDictByOrg_;
          end;

      // поиск в РЧБ если найдено несколько БР в справочнике
      if (xXml.documentElement.childNodes.Length > 1) then begin
        xXml := xXml.documentElement;
        WriteLog( 'Выполняется поиск бланка расходов в РЧБ...');

        // получаем список id полученных из справочника бланков расходов
        // через запятую
        xListEstID := '';
        for i := 0 to xXml.childNodes.Length - 1 do begin
          if (i > 0)
            then xListEstID := xListEstID + ',';
          xListEstID := xListEstID
                           + xXml.childNodes.Item[i].getAttribute('ID');
        end;//for//

        // фомируем подзапрос и перечень параметров для запроса поиска в РЧБ
        // по списку ID бланков расходов
        xSQLEst := QueryGetParamsFromValue( xListEstID, xListEstValue);

        if (LENGTH( xPURPOSEFULGRANT_ID) <= 0)
          then xXml := QueryXml(  ' Select distinct E.Estimate_Id Id'
                                 +' From Expbudget E Where E.Budget_Id = ?'
                                 +' and E.Estimate_Id in (' + xSQLEst + ')'
                                 +' and E.Kfsr_Code = ?'
                                 +' and E.Kvr_Code = ? and E.Kesr_Code = ?'
                                 +' and E.Kcsr_Code = ? and E.Kadmr_Code = ?',
                                  [ xBudgetID,
                                    xListEstValue,
                                    xED24Line.GetAttribute( 'KFSR_CODE'),
                                    xED24Line.GetAttribute( 'KVR_CODE'),
                                    xED24Line.GetAttribute( 'KESR_CODE'),
                                    xED24Line.GetAttribute( 'KCSR_CODE'),
                                    xED24Line.GetAttribute( 'KADMR_CODE')])
          else xXml := QueryXml(  ' Select distinct E.Estimate_Id Id'
                                 +' From Expbudget E Where E.Budget_Id = ?'
                                 +' and E.Estimate_Id in (' + xSQLEst + ')'
                                 +' and E.Kfsr_Code = ?'
                                 +' and E.Kvr_Code = ? and E.Kesr_Code = ?'
                                 +' and E.Kcsr_Code = ? and E.Kadmr_Code = ?'
                                 +' and E.PURPOSEFULGRANT_ID=?',
                                  [ xBudgetID,
                                    xListEstValue,
                                    xED24Line.GetAttribute( 'KFSR_CODE'),
                                    xED24Line.GetAttribute( 'KVR_CODE'),
                                    xED24Line.GetAttribute( 'KESR_CODE'),
                                    xED24Line.GetAttribute( 'KCSR_CODE'),
                                    xED24Line.GetAttribute( 'KADMR_CODE'),
                                    xPURPOSEFULGRANT_ID]);

        if NOT DoCheckFound_(
                    'Бланк расходов не найден в РЧБ.',
                    'Найдено несколько (%s) бланков расходов в РЧБ.')
          then begin
            WriteLog( 'Поиск бланка расходов в РЧБ с бюджетополучателем = "НЕ УКАЗАН"...');
            if (LENGTH( xPURPOSEFULGRANT_ID) <= 0)
              then xXml := QueryXml(  ' Select distinct E.Estimate_Id Id'
                                     +' From Expbudget E Where E.Budget_Id = ?'
                                     +' and E.Estimate_Id in (' + xSQLEst + ')'
                                     +' and E.Kfsr_Code = ?'
                                     +' and E.Kvr_Code = ? and E.Kesr_Code = ?'
                                     +' and E.Kcsr_Code = ? and E.Kadmr_Code = ?'
                                     +' and E.RECIPIENT_ID=0',
                                      [ xBudgetID,
                                        xListEstValue,
                                        xED24Line.GetAttribute( 'KFSR_CODE'),
                                        xED24Line.GetAttribute( 'KVR_CODE'),
                                        xED24Line.GetAttribute( 'KESR_CODE'),
                                        xED24Line.GetAttribute( 'KCSR_CODE'),
                                        xED24Line.GetAttribute( 'KADMR_CODE')])
              else xXml := QueryXml(  ' Select distinct E.Estimate_Id Id'
                                     +' From Expbudget E Where E.Budget_Id = ?'
                                     +' and E.Estimate_Id in (' + xSQLEst + ')'
                                     +' and E.Kfsr_Code = ?'
                                     +' and E.Kvr_Code = ? and E.Kesr_Code = ?'
                                     +' and E.Kcsr_Code = ? and E.Kadmr_Code = ?'
                                     +' and E.PURPOSEFULGRANT_ID=?'
                                     +' and E.RECIPIENT_ID=0',
                                      [ xBudgetID,
                                        xListEstValue,
                                        xED24Line.GetAttribute( 'KFSR_CODE'),
                                        xED24Line.GetAttribute( 'KVR_CODE'),
                                        xED24Line.GetAttribute( 'KESR_CODE'),
                                        xED24Line.GetAttribute( 'KCSR_CODE'),
                                        xED24Line.GetAttribute( 'KADMR_CODE'),
                                        xPURPOSEFULGRANT_ID]);

            // здесь в логе отображаем результат поиска
            DoCheckFound_(
                'Бланк расходов с бюджетополучателем = "НЕ УКАЗАН" не найден в РЧБ.',
                'Найдено несколько (%s) бланков расходов в РЧБ с бюджетополучателем = "НЕ УКАЗАН".');
          end;
      end;

      // если найден один БР, его сохраняем в шапке эд 25го
      if (xXml.documentElement.childNodes.Length = 1)
        then aDoc25.SetAttribute(
                    'ESTIMATE_ID',
                    xXml.documentElement.childNodes.item[0].getAttribute('ID'));
      except
        ExceptionProc( 'FillEstimateIDintoED25fromED24byIKnew');
    end;

end;
*)
{==============================================================================}
{~FillEstimateIDintoED25fromED24byIK_3057
  exchange #3057
  поиск БР:
    1. Для  организации из блока «Получатель» ЭД класса 24 производится поиск
        Бланка расходов (Далее по тексту БР),оператором - владельцем которого
        она является, в системе – с признаком «актуальный бланк расходов» и с
        типом «Смета» или «ПНО». Если БР определен однозначно,
        то поле «Бланк расходов» заполняеиться найденным значением и перейти
        к  ФТ-2. Иначе п.2.
    2. Если БР найден не однозначно по условиям п.1, то к условиям поиска
        добавляем значение поля «Лицевой счет» БР, определенный по условиям
        текущей реализации на момент формирования ЭД класса 25 и поиска БР,
        если БР определен однозначно, то поле «Бланк расходов» заполняеиться
        найденным значением и перейти к  ФТ-2. Иначе см. п.3.
    3. Если БР не определен по п.1 или 2, то:
      1) фильтруем строки расходной части бюджета (далее по тексту РЧБ) по
          значениям «строка 20-го КБК» + «Код цели» бюджетной строки
          родительского ЭД, если «Код цели» в родительском документе не указан,
          исключаем его из фильтра поискато принимаем его равным «0»;
      2) Из найденных строк  выбираем строки с бюджетополучателем,
          определенным в п.1 (=организация из блока «Получатель»),
          если найдена однозначно  - то есть одна или
          несколько строк:  бюджетополучатель + одинаковый БР, то БР и
          поле «Бюджетополучатель» заполняютсяь из найденной строки (либо из
          первой найденной строки). Если  не найдено ни одной строки
          с бюджетополучателем, определенным по п.1, то в найденных строках
          ищем строку со значением поля «Бюджетополучатель» = «Не указана»
          или «Плательщик», плательщика определяем по значениям «ИНН» + «КПП»
          (из блока получатель эд 24го) из справочника «Организации»,
          с учетом «КПП» на вкладке
          «Дополнительные КПП», если найдена одна строка или несколько строк,
          но с одним значением БР, то БР заполняем из данной строки.
          Перейти к ФТ-2  Иначе см. п.4
    4. Если БР не удалось определить, то ЭД класса 25 формируем с БР из первой
        строки родительского ЭД.пустым бланком расходов, поля расходной строки
        заполнить из соответствующих полей строки родительского документа. }
function FillEstimateIDintoED25fromED24byIK_3057( aDoc25, aDoc24: Variant): boolean;
var
  i: Integer;
  xXml: Variant;
  xSQLEst: string;
  xListEstID: String;
  xListEstValue: array of string;
  xED24Lines: Variant;
  xED24Line: Variant;
  xBudgetID: String;
  xOrgID: String;
  xORGACCOUNT_ID: String;
  xEstimateID: string;
  xPURPOSEFULGRANT_ID: string;
  xPAY_TAXCODE: string;
  xPAY_KPP: string;
  xKFSR_CODE: string;
  xKVR_CODE: string;
  xKESR_CODE: string;
  xKCSR_CODE: string;
  xKADMR_CODE: string;
  xMsg2: string;
  {----------------------------------------------------------------------------}
  {~DoCheckFound_
    проверяет сколько найдено строк БР в результате поиска (в переменной xXml).
    результат:
      количество найденных строк результата запроса в xXml.

    если не найдено ни одной строки, в журнале info отображается
    сообщение aMsgFor0.

    если не найдено несколько строк, в журнале info отображается
    сообщение aMsgForN с форматированием строки и добавлением в сообщение
    количества найденных строк. }
  function DoCheckFound_( aMsgFor0, aMsgForN: string): integer;
  begin

      try
        Result := xXml.documentElement.childNodes.Length;
        case Result of
          0: WriteInfo( aMsgFor0);
          1: begin { заглушка } end;
        else WriteInfo( FORMAT( aMsgForN, [ INTTOSTR( Result)]));
        end;//case//
        except
          ExceptionProc( 'DoCheckFound_');
      end;

  end;
  {----------------------------------------------------------------------------}
  procedure DoStoryEstimateID_;
  begin

      try
        // если найден один БР, его сохраняем в шапке эд 25го
        if (xXml.documentElement.childNodes.Length = 1)
          then aDoc25.SetAttribute(
                      'ESTIMATE_ID',
                      xXml.documentElement.childNodes.item[0].getAttribute('ID'));
        except
          ExceptionProc( 'DoStoryEstimateID_');
      end;

  end;
  {----------------------------------------------------------------------------}
  {~DoSearchEstimateIntoDictByOrg_
    поиск БР для бюджета xBudgetID и организации-оператора xOrgID }
  procedure DoSearchEstimateIntoDictByOrg_;
  begin

      try
        xXml := QueryXml(  ' Select Id From Estimate'
                          +' Where EstKind_Id in (1, 7) and Actual_Flag = 1'
                          +' and Budget_Id = ? and Org_Id = ?',
                            [ xBudgetID,
                              xOrgID]);
        except
          ExceptionProc( 'DoSearchEstimateIntoDictByOrg_');
      end;

  end;
  {----------------------------------------------------------------------------}
begin

    try
      Result := TRUE;
      aDoc25.SetAttribute( 'ESTIMATE_ID','');


      // в начале заполняем БР из первой строки ЭД 24го
      // это значение "по умолчанию".
      // ищем узел а не берем первый, поскольку возможны дополнительные
      // узлы описания полей в эд 24м
      xED24Lines := NULL;
      for i := 0 to aDoc24.ChildNodes.Length - 1 do
        if (aDoc24.ChildNodes.Item[i].NodeName = 'PAYORDERLINE') then begin
          xED24Lines := aDoc24.ChildNodes.Item[i];
          BREAK;
        end;
      if VarIsNULL( xED24Lines) then begin
        WriteInfo( 'В ЭД 24м не найдено описание строк.');
        EXIT;
      end;
      // берем первую строку эд 24го
      if (xED24Lines.ChildNodes.Length <= 0) then begin
        WriteInfo( 'В ЭД 24м отсутствуют строки.');
        EXIT;
      end;
      xED24Line := xED24Lines.ChildNodes.Item[ 0];
      aDoc25.SetAttribute( 'ESTIMATE_ID',
                           GetNodeAttributeEx( xED24Line, 'ESTIMATE_ID'));
      // берем из эд 25го параметры орг и счета для поиска БР
      xBudgetID           := GetNodeAttributeEx( aDoc24, 'F_BUDGET_ID');
      // ищем БР по организации и счету получателя - берем из эд 24го
      xOrgID              := GetNodeAttributeEx( aDoc24, 'REC_ID');
      // счет берем из 25го, поскольку он заполняется в шапке эд 25го
      // в зависимости от файла загрузки
      xORGACCOUNT_ID      := GetNodeAttributeEx( aDoc25, 'ORGACCOUNT_ID');

      // кбк из строки. в дальнейшем это исключает дубли в коде
      xKFSR_CODE  := GetNodeAttributeEx( xED24Line, 'KFSR_CODE');
      xKVR_CODE   := GetNodeAttributeEx( xED24Line, 'KVR_CODE');
      xKESR_CODE  := GetNodeAttributeEx( xED24Line, 'KESR_CODE');
      xKCSR_CODE  := GetNodeAttributeEx( xED24Line, 'KCSR_CODE');
      xKADMR_CODE := GetNodeAttributeEx( xED24Line, 'KADMR_CODE');
      // код цели из первой строки эд 24го
      xPURPOSEFULGRANT_ID := GetNodeAttributeEx( xED24Line, 'PURPOSEFULGRANT_ID');
      if (LENGTH( xPURPOSEFULGRANT_ID) <= 0)
        then xPURPOSEFULGRANT_ID :=
                      Exch2389_GetPURPOSEFULGRANT_ID_NULL_ByBudget( xBudgetID);



      // ищем бланк расходов в справочнике по бюджету и орг.оператору
      DoSearchEstimateIntoDictByOrg_;

      case DoCheckFound_(
                'Бланк расходов для организации оператора не найден в справочнике.',
                'Найдено несколько (%s) бланков расходов для организации оператора.')
            of
        1: begin
             DoStoryEstimateID_;
             EXIT;
           end;
        0: EXIT;   // дальше искать безсмысленно
      end;//case//

      if (LENGTH( xORGACCOUNT_ID) > 0) then begin
        //дополнительный поиск по счету
        WriteLog( 'Поиск бланка расходов с учетом лицевого счета...');
        xXml := QueryXml(  ' Select Id From Estimate'
                          +' Where EstKind_Id in (1, 7) and Actual_Flag = 1'
                          +' and Budget_Id = ? and Org_Id = ?'
                          +' and Face_Acc = ?',
                            [ xBudgetID,
                              xOrgID,
                              xORGACCOUNT_ID]);

        // здесь в логе отображаем результат поиска
        case DoCheckFound_(
               'Бланк расходов не найден в справочнике с учетом лицевого счета.',
               'Найдено несколько (%s) бланков расходов в справочнике с учетом лицевого счета.')
             of
          1: begin
               DoStoryEstimateID_;
               EXIT;
             end;
          0: begin
               // если ничего не нашли, тогда будем искать БР без л/с
               // т.е. еще раз ищем бланк расходов в справочнике по бюджету и
               // орг.оператору и без л/с
               DoSearchEstimateIntoDictByOrg_;
             end;
        end;//case//
      end;

      // поиск в РЧБ если найдено несколько БР в справочнике
      xXml := xXml.documentElement;
      WriteLog( 'Выполняется поиск бланка расходов в РЧБ...');

      // получаем список id полученных из справочника бланков расходов
      // через запятую
      xListEstID := '';
      for i := 0 to xXml.childNodes.Length - 1 do begin
        if (i > 0) then xListEstID := xListEstID + ',';
        xListEstID := xListEstID + xXml.childNodes.Item[i].getAttribute('ID');
      end;//for//

      // фомируем подзапрос и перечень параметров для запроса поиска в РЧБ
      // по списку ID бланков расходов
      xSQLEst := QueryGetParamsFromValue( xListEstID, xListEstValue);

      // фт-1 п.3.2 - выбор БР из РЧБ по кбк и бюджетополучателем
      // по организации получателя ( берем из эд 24го)
      // exchange #3062 - убран косгу из поиска рчб
      xXml := QueryXml(   ' Select distinct E.Estimate_Id Id'
                         +' From Expbudget E Where E.Budget_Id = ?'
                         +' and E.Estimate_Id in (' + xSQLEst + ')'
                         +' and E.Kfsr_Code = ?'
                         +' and E.Kvr_Code = ?'// and E.Kesr_Code = ?'
                         +' and E.Kcsr_Code = ? and E.Kadmr_Code = ?'
                         +' and E.PURPOSEFULGRANT_ID=?'
                         +' and E.RECIPIENT_ID=?',
                          [ xBudgetID,
                            xListEstValue,
                            xKFSR_CODE,
                            xKVR_CODE,
//                            xKESR_CODE,
                            xKCSR_CODE,
                            xKADMR_CODE,
                            xPURPOSEFULGRANT_ID,
                            xOrgID]);

      case DoCheckFound_(
                  'Бланк расходов не найден в РЧБ по бюджетополучателю организации получателя.',
                  'Найдено несколько (%s) бланков расходов в РЧБ по бюджетополучателю организации получателя.')
            of
        1: begin
             DoStoryEstimateID_;
             EXIT;
           end;
//        0: EXIT;   // дальше искать безсмысленно
      end;//case//

      WriteLog( 'Поиск бланка расходов в РЧБ с бюджетополучателем = "НЕ УКАЗАН"...');
      // exchange #3062 - убран косгу из поиска рчб
      xXml := QueryXml( ' Select distinct E.Estimate_Id Id'
                       +' From Expbudget E Where E.Budget_Id = ?'
                       +' and E.Estimate_Id in (' + xSQLEst + ')'
                       +' and E.Kfsr_Code = ?'
                       +' and E.Kvr_Code = ?'// and E.Kesr_Code = ?'
                       +' and E.Kcsr_Code = ? and E.Kadmr_Code = ?'
                       +' and E.PURPOSEFULGRANT_ID=?'
                       +' and E.RECIPIENT_ID=0',
                        [ xBudgetID,
                          xListEstValue,
                          xKFSR_CODE,
                          xKVR_CODE,
//                          xKESR_CODE,
                          xKCSR_CODE,
                          xKADMR_CODE,
                          xPURPOSEFULGRANT_ID]);

      // здесь в логе отображаем результат поиска
      if (DoCheckFound_(
              'Бланк расходов с бюджетополучателем = "НЕ УКАЗАН" не найден в РЧБ.',
              'Найдено несколько (%s) бланков расходов в РЧБ с бюджетополучателем = "НЕ УКАЗАН".')
            = 1)
        then begin
          DoStoryEstimateID_;
          EXIT;
        end;

      // инн+кпп из блока плательщик эд 24го
      xPAY_TAXCODE := GetNodeAttributeEx( aDoc24, 'PAY_TAXCODE');
      xPAY_KPP     := GetNodeAttributeEx( aDoc24, 'PAY_KPP');
      if ((LENGTH( xPAY_TAXCODE) <= 0) AND (LENGTH( xPAY_KPP) <= 0)) then begin
        WriteInfo( 'ИНН и КПП плательщика не указаны. Поиск бланка расходов в РЧБ не выполняется.');
        EXIT;
      end;

      if (LENGTH( xPAY_KPP) > 0) then begin
        xMsg2 := 'ИНН и КПП';
        WriteLog(
            FORMAT( 'Поиск бланка расходов в РЧБ с бюджетополучателем по ИНН=%s и КПП=%s плательщика...',
                    [ xPAY_TAXCODE,
                      xPAY_KPP]));
      end else  begin
        xMsg2 := 'ИНН';
        WriteLog(
            FORMAT( 'Поиск бланка расходов в РЧБ с бюджетополучателем по ИНН=%s плательщика...',
                    [ xPAY_TAXCODE]));
      end;

      // инн+(кпп или среди дополнительных кпп)
      // exchange #3062 - убран косгу из поиска рчб
      if (LENGTH( xPAY_KPP) > 0)
        then xXml := QueryXml(  ' Select distinct E.Estimate_Id Id'
                               +' From Expbudget E Where E.Budget_Id = ?'
                               +' and E.Estimate_Id in (' + xSQLEst + ')'
                               +' and E.Kfsr_Code = ?'
                               +' and E.Kvr_Code = ?'// and E.Kesr_Code = ?'
                               +' and E.Kcsr_Code = ? and E.Kadmr_Code = ?'
                               +' and E.PURPOSEFULGRANT_ID=?'
                               +' and E.RECIPIENT_ID in ('
                               +'   select OOO.ID from ORG OOO'
                               +'   where OOO.TAXCODE = ? and'
                               +'    (OOO.KPP = ? or exists('
                               +'       select * from ORGKPP OK where'
                               +'       OK.ORG_ID = OOO.ID and OK.KPP = ?)))',
                                [ xBudgetID,
                                  xListEstValue,
                                  xKFSR_CODE,
                                  xKVR_CODE,
//                                  xKESR_CODE,
                                  xKCSR_CODE,
                                  xKADMR_CODE,
                                  xPURPOSEFULGRANT_ID,
                                  xPAY_TAXCODE,
                                  xPAY_KPP,
                                  xPAY_KPP])
        else xXml := QueryXml(  ' Select distinct E.Estimate_Id Id'
                               +' From Expbudget E Where E.Budget_Id = ?'
                               +' and E.Estimate_Id in (' + xSQLEst + ')'
                               +' and E.Kfsr_Code = ?'
                               +' and E.Kvr_Code = ?'// and E.Kesr_Code = ?'
                               +' and E.Kcsr_Code = ? and E.Kadmr_Code = ?'
                               +' and E.PURPOSEFULGRANT_ID=?'
                               +' and E.RECIPIENT_ID in ('
                               +'   select OOO.ID from ORG OOO'
                               +'   where OOO.TAXCODE = ?)',
                                [ xBudgetID,
                                  xListEstValue,
                                  xKFSR_CODE,
                                  xKVR_CODE,
                                  //xKESR_CODE,
                                  xKCSR_CODE,
                                  xKADMR_CODE,
                                  xPURPOSEFULGRANT_ID,
                                  xPAY_TAXCODE]);
      // здесь в логе отображаем результат поиска

      if (DoCheckFound_(
              FORMAT( 'Бланк расходов с бюджетополучателем по %s плательщика не найден в РЧБ.',
                      [ xMsg2]),
              FORMAT( 'Найдено несколько (%s) бланков расходов в РЧБ с бюджетополучателем по %s плательщика.',
                      [ '%s', xMsg2]))
            = 1)
        then begin
          DoStoryEstimateID_;
          EXIT;
        end;
      except
        ExceptionProc( 'FillEstimateIDintoED25fromED24byIK_3057');
    end;

end;
{==============================================================================}
{~GetLineExpbudget_3057
  exchange #3057
  заполнение строки эд 25го из строки эд 24го
  ФТ-2	Поиск бюджетной строки:
      Доработка только для значения параметра «Схема загрузки доп кодов
      из ADD_KLASS» = нет (пусто).
    Бюджетную строку ищем в РЧБ по определенному в ФТ-1 БР.
    1.	Требуется отфильтровать строки РЧБ по найденному БР + значениям кодов
        бюджетной классификации, входящих в 20й КБК, равный IK.ZRST.KBK_PAY
        + «Код цели», равный IK.ZRST.ADD_KLASS_PAY(если поле в
        структурированном файле пустое, то принимать как «0»).
          Если строка найдена однозначно, то заполнить все поля формируемой
        строки ЭД класса 25 из найденной строки РЧБ. Если строка найдена
        не однозначно и различается значением поля «Бюджетополучатель»,
        то перейти к п.2. Если найденные строки содержат одинаковое значение
        «Бюджетополучатель», то искать строку с КВФО=1 и заполнять поля
        формируемой строки из одноименных полей найденной строки (если
        определено несколько строк с КВФО=1, то брать первую попавшуюся).

          Если не найдено ни одной строки, то поля  расходной строки заполнить
        из соответствующих полей строки родительского документа.

    2. Поиск строки осуществить с учетом значения поля «Бюджетополучатель»,
        значение которого определять в зависимости от наличия признака
        «Межбюджетные трансферты» в найденном бланке:
        - если признак не установлен, то в фильтр отбора строк ставить
            Бюджетополучатель=Организация-оператор бланка расходов.
            Перейти к п.3;
        - если признак установлен, то Бюджетополучатель = Контрагент.
          Контрагента определять так: искать в справочнике организаций
          организацию по ИНН+КПП (с учетом КПП во вкладке «Дополнительно»),
          равным соответствующим значениям полей блока «Плательщик»
          родительского ЭД класса 24, актуальную.
            Если организация найдена однозначно, устанавливать ее в
          Бюджетополучателя. Если организация не найдена или найдена не
          однозначно, то в Бюджетополучателя устанавливать «Не указана».
          Перейти к п. 3.

    3. Осуществить поиск строки РЧБ с учетом фильтра по Бюджетополучателю,
        определенному в п.2:
      a)	Если строка найдена единственная, то подставлять в ЭД ее реквизиты:
          Бюджетополучатель, КБК, Код цели, КВФО, доп.коды.
      b)	Если строка не найдена или найдена не однозначно,
          то в Бюджетополучателя устанавливать «Не указана» (если в найденных
          строках РЧБ он отличается) или из строки РЧБ (если во всех найденных
          строках РЧБ он совпадает), заполнять в ЭД КБК, Код цели из файла,
          КВФО =1, доп.коды = нули.}
procedure GetLineExpbudget_3057( aDoc25, aDoc25Line, aDoc24, aDoc24Line: Variant);
var
  xXml: Variant;
  xPURPOSEFULGRANT_ID: string;
  xBudgetID: string;
  xRECIPIENT_ID: string;
  xKFSR_CODE: string;
  xKVR_CODE: string;
  xKESR_CODE: string;
  xKCSR_CODE: string;
  xKADMR_CODE: string;
  xPAY_TAXCODE: string;
  xPAY_KPP: string;
  xESTIMATE_ID: string;
  {----------------------------------------------------------------------------}
  procedure DoFillDoc25Line_;
  begin

      try
        xXml := xXml.childNodes.item[0];
        aDoc25Line.SetAttribute( 'KDF_CODE', GetNodeAttributeEx( xXml, 'KDF_CODE'));
        aDoc25Line.SetAttribute( 'KDE_CODE', GetNodeAttributeEx( xXml, 'KDE_CODE'));
        aDoc25Line.SetAttribute( 'KDR_CODE', GetNodeAttributeEx( xXml, 'KDR_CODE'));
        aDoc25Line.SetAttribute( 'FSR_ID',   GetNodeAttributeEx( xXml, 'FSR_ID'));
        // exchange #3111 теперь косгу вытягивается из рчб как доп код
        aDoc25Line.SetAttribute( 'KESR_CODE',
                                GetNodeAttributeEx( xXml, 'KESR_CODE'));
        // сохраняем бюджетополучателя в строке из РЧБ (фт-2 п.3.а)
        aDoc25Line.SetAttribute( 'RECIPIENT_ID',
                                 GetNodeAttributeEx( xXml, 'RECIPIENT_ID'));
        except
          ExceptionProc( 'DoFillDoc25Line_');
      end;

  end;
  {----------------------------------------------------------------------------}
  function CheckFound_: integer;
  begin

      try
        Result := xXml.childNodes.Length;
        if (Result = 1) then DoFillDoc25Line_;
        except
          ExceptionProc( 'CheckFound_');
      end;

  end;
  {----------------------------------------------------------------------------}
begin

    try
      // БР берем из строки. туда его помещают из шапки.
      // если БР не определен - ничего больше не делаем
      xESTIMATE_ID := GetNodeAttributeEx( aDoc25Line, 'ESTIMATE_ID');
      if (LENGTH( xESTIMATE_ID) <= 0) then begin
        // в бюджетополучателя подставляем = не указано
        // согласовано с АО.
        aDoc25Line.setAttribute( 'RECIPIENT_ID', '0');
        EXIT;
      end;

      // берем из эд 25го параметры орг и счета для поиска БР
      xBudgetID := GetNodeAttributeEx( aDoc24, 'F_BUDGET_ID');

      // код цели для расходов берем из PURPOSEFULGRANT_ID из строки эд 24го
      xPURPOSEFULGRANT_ID := GetNodeAttributeEx( aDoc24Line,
                                                 'PURPOSEFULGRANT_ID');
      if (LENGTH( xPURPOSEFULGRANT_ID) <= 0)
        then xPURPOSEFULGRANT_ID :=
                      Exch2389_GetPURPOSEFULGRANT_ID_NULL_ByBudget( xBudgetID);

      // КБК из строки эд 24. это унифицирует код
      xKFSR_CODE  := GetNodeAttributeEx( aDoc24Line, 'KFSR_CODE');
      xKVR_CODE   := GetNodeAttributeEx( aDoc24Line, 'KVR_CODE');
      xKESR_CODE  := GetNodeAttributeEx( aDoc24Line, 'KESR_CODE');
      xKCSR_CODE  := GetNodeAttributeEx( aDoc24Line, 'KCSR_CODE');
      xKADMR_CODE := GetNodeAttributeEx( aDoc24Line, 'KADMR_CODE');

      // фт-2 пп.1

      // exchange #3062 - убран косгу из поиска рчб
      xXml := QueryXml2(  ' Select * From ExpBudget'
                         +' Where Budget_Id = ? and Estimate_Id = ?'
                         +' and Kfsr_Code = ? and Kvr_Code = ?'
//                         +' and Kesr_Code = ?'
                         +' and Kcsr_Code = ?'
                         +' and Kadmr_Code = ? and PURPOSEFULGRANT_ID = ?',
                          [ xBudgetID,
                            xESTIMATE_ID,
                            xKFSR_CODE,
                            xKVR_CODE,
                            //xKESR_CODE,
                            xKCSR_CODE,
                            xKADMR_CODE,
                            xPURPOSEFULGRANT_ID]);
      // если не найдено ничего или найдена одна строка - дальше не ищем

      if (CheckFound_ <= 1)
        then EXIT;

      // получаем список только бюджетополучателей
      xXml := QueryXml2(  ' Select distinct RECIPIENT_ID From ExpBudget'
                         +' Where Budget_Id = ? and Estimate_Id = ?'
                         +' and Kfsr_Code = ? and Kvr_Code = ?'
//                         +' and Kesr_Code = ?'
                         +' and Kcsr_Code = ?'
                         +' and Kadmr_Code = ? and PURPOSEFULGRANT_ID = ?',
                          [ xBudgetID,
                            xESTIMATE_ID,
                            xKFSR_CODE,
                            xKVR_CODE,
                            //xKESR_CODE,
                            xKCSR_CODE,
                            xKADMR_CODE,
                            xPURPOSEFULGRANT_ID]);

      // если бюджетополучатель один, тогда запрашиваем все из рчб, с КВФО=1
      // exchange #3062 - убран косгу из поиска рчб
      if (xXml.childNodes.Length = 1) then begin
        xXml := QueryXml2(  ' Select * From ExpBudget'
                           +' Where Budget_Id = ? and Estimate_Id = ?'
                           +' and Kfsr_Code = ? and Kvr_Code = ?'
//                           +' and Kesr_Code = ?'
                           +' and Kcsr_Code = ?'
                           +' and Kadmr_Code = ? and PURPOSEFULGRANT_ID = ?'
                           +' and FSR_ID=1',
                            [ xBudgetID,
                              xESTIMATE_ID,
                              xKFSR_CODE,
                              xKVR_CODE,
                              //xKESR_CODE,
                              xKCSR_CODE,
                              xKADMR_CODE,
                              xPURPOSEFULGRANT_ID]);

        // если найдено несколько строк - берем из первой найденной строки
        if (CheckFound_ > 1)
          then DoFillDoc25Line_;
        EXIT;
      end;

      // фт-2 пп.2

      // проверяем флаг МБТ
      if (QueryField(
                  'select INTER_BUDG_TRANS_FLAG X from estimate where id=?',
                  [ xESTIMATE_ID],
                  'X') = '0')
        then begin
          xRECIPIENT_ID :=
                        // орг.оператор БР из карточки БР
                        QueryField(
                            'select ORG_ID X from estimate where id=?',
                            [ xESTIMATE_ID],
                            'X');

        end else begin
          // принимаем бюджетополучатель = "не указан"
          xRECIPIENT_ID := '0';
          // инн+кпп из блока плательщик эд 24го
          // искать в справочнике организаций организацию по ИНН+КПП
          // (с учетом КПП во вкладке «Дополнительно»), равным соответствующим
          // значениям полей блока «Плательщик» родительского ЭД класса 24,
          // актуальную.
          // флаг актуальности проверяется для бюджета, в котором создается эд.
          xPAY_TAXCODE := GetNodeAttributeEx( aDoc24, 'PAY_TAXCODE');
          xPAY_KPP     := GetNodeAttributeEx( aDoc24, 'PAY_KPP');
          if (LENGTH( xPAY_TAXCODE) > 0) then begin
            if (LENGTH( xPAY_KPP) > 0)
              then xXml := QueryXml2(
                                ' select OOO.ID from ORG OOO'
                                // здесь проверяется галка "актуальная" у организации
                               +' Join Contractor C on C.Org_Id = ooo.Id'
                               +' Join Budget b on b.Org_Id = C.Inspector_Id'
                               +' where b.ID=? and OOO.TAXCODE = ?'
                               +'   and (OOO.KPP = ? or exists('
                               +'       select * from ORGKPP OK where'
                               +'       OK.ORG_ID = OOO.ID and OK.KPP = ?))',
                                [ xBudgetID,
                                  xPAY_TAXCODE,
                                  xPAY_KPP,
                                  xPAY_KPP])
              else  xXml := QueryXml2(
                                ' select OOO.ID from ORG OOO'
                                // здесь проверяется галка "актуальная" у организации
                               +' Join Contractor C on C.Org_Id = ooo.Id'
                               +' Join Budget b on b.Org_Id = C.Inspector_Id'
                               +' where b.ID=? and OOO.TAXCODE = ?',
                                [ xBudgetID,
                                  xPAY_TAXCODE]);
              // если орг найдена однозначно - берем ее
              if (xXml.childNodes.Length = 1)
                then xRECIPIENT_ID := GetNodeAttributeEx(
                                                xXml.childNodes.item[0],
                                                'ID');
          end;
        end;

      // фт-2 пп.3

      // exchange #3062 - убран косгу из поиска рчб
      xXml := QueryXml2(  ' Select * From ExpBudget'
                         +' Where Budget_Id = ? and Estimate_Id = ?'
                         +' and Kfsr_Code = ? and Kvr_Code = ?'
//                         +' and Kesr_Code = ?'
                         +' and Kcsr_Code = ?'
                         +' and Kadmr_Code = ? and PURPOSEFULGRANT_ID = ?'
                         +' and RECIPIENT_ID=?',
                          [ xBudgetID,
                            xESTIMATE_ID,
                            xKFSR_CODE,
                            xKVR_CODE,
                            //xKESR_CODE,
                            xKCSR_CODE,
                            xKADMR_CODE,
                            xPURPOSEFULGRANT_ID,
                            xRECIPIENT_ID]);

      if (CheckFound_ <> 1) then begin
        // фт-2 пп. 3.б)
        aDoc25Line.SetAttribute( 'KDF_CODE', '0');
        aDoc25Line.SetAttribute( 'KDE_CODE', '0');
        aDoc25Line.SetAttribute( 'KDR_CODE', '0');
        aDoc25Line.SetAttribute( 'FSR_ID', '1');
        // бюджетополучатель устанавливается в строке = не указан (фт-2 п.3.б)
        aDoc25Line.SetAttribute( 'RECIPIENT_ID', '0');
      end;
      except
        ExceptionProc( 'GetLineExpbudget_3057');
    end;

end;

begin
end.
