{~DoCreateDoc215_UF
  exchange #2845
    ФТ-1
      Если в системе не найден ЭД класса 114 и в конфигурации
      загрузки параметр «Создавать дополнительные документы»
      имеет «Справка по внебанковским операциям», то при наличии
      в структурированном файле раздела UF (Уведомление об уточнении
      вида и принадлежности платежа) формировать документ
      «Справка по внебанковским операциям» (ЭД класса 215)
      согласно описанию реквизитов, приведенного в таблице 1.

      Создавать ЭД "Справка по внебанковским операциям", если значение поля
        BH.ROD_DOC равно IV, VB, VT, VA, IP.

   aCfgIgnoreBadKBK - контроль кодов КБК.
                      =false, если коды кбк отсутствую в БД, то ЭД не будет
                      создан. =true (игнорировать "плохие" кбк) - в любом случае,
                      есть кбк в бд или нет, эд будет создан.
   aCfgResetBadKBK - сбрасывать коды "плохих" КБК в значение 0.
                      =true: если код кбк будет отсутствовать в бд, то его
                      значение будет установлено в 0. если =false, то не
                      зависимо от наличия кбк в бд, код не будет изменен.

   результат:
     0: aSource обработан успешно;
    10: документ уже существует в БД;
    14: в документе нет подразделов UFPP/UFPP_N либо они с ошибками.
    15: невозможно определить бюджетополучателя
    16: сбой создания эд 215го из 178го
    17: сбой при обновлении эд 215го созданного из 178го
    18: ошибки создания эд
    19: сбой при создании эд на ацк-ф

   ВНИМАНИЕ
     функция вызывается из Imp_FK_BH после DoUpdateDoc114_UF.
     в функции DoUpdateDoc114_UF уже отображается сообщение в журнале (Log)
     при начале анализа UF, так что все сообщения будут отображаться уже
     после описания aDocInfo

   exchange #2903
     проблема с логами. все сообщения приходится писать в журнал info.
     это связано с тем, что сообщения в журнале info дублируются в
     журнале log, но не наоборот. в результате, пока все нормально,
     сообщения пишуться в журнал log, а когда возникают проблемы,
     сообщения пишутся в журнал info. в результате в журнале info
     описываются только критические сообщения,  а детальной информации нет.
     если писать все в журнал info (как сейчас сделано в загрузке IK),
     то этот журнал будет открываться всегда, при нормальном и ненормальном
     завершении загрузки, что неверно. поскольку при нормальной загрузки,
     в принципе, открывать ничего не нужно, в лучшем случае сказать,
     что загрузка выполнена успешно.

   сейчас получается следующее:
     функция одна и так же для загрузки BH и IK.
     в загрузчике по BH логи формируются корректно, с разделением на
     журнал критических сообщений info и журнал загрузки log.
     а в загрузчике IK все сообщения пишутся в журнал info.
     в результате, при доработке по exchange #2903 будут проблемы с корректым
     отображением журналов в загрузке BH.
     в результате, добавлен новый параметр в функцию - aLogToInfo (по умолчанию
     =false). если значение =true, то все сообщения будут записываться
     в журнал info, а если =false - то в журнал log.

  exchange #3062
    отмена косгу.
    унификация кода ращепление кодов из строки кбк.}
function DoCreateDoc215_UF( var aSource: Variant;
                            aBudgetID: string;
                            aTO_KOD_UBP: string;
                            {aTO_KOD_UBP,} aIK_LS_UBP{, aBH_DATE, aBH_KOD_DOC}: string;
                            aCfgIgnoreBadKBK, aCfgResetBadKBK: boolean;
                            //var aConfig: TStringList;
                            aValidate: boolean;
                            aDocInfo: string;
                            aLogToInfo: boolean = FALSE): integer;
  //----------------------------------------------------------------------------
  {~DoWriteLog_
    запись сообщения в журнал:
    в зависимости от параметра aLogToInfo (целевой функции DoCreateDoc215_UF
    сообщение пишется либо в журнал info либо в журнал log.
    это нужно для разных загрузчиков: BH и IK.}
  procedure DoWriteLog_( aMsg: string; aShowBar: boolean = FALSE);
  begin

      try

        if aLogToInfo
          then WriteInfo( aMsg, aShowBar)
          else WriteLog( aMsg, aShowBar);
        except
          ExceptionLog( 'Сбой DoWriteLog_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~DoUpdateED215_
    из однострочного ЭД 215го класса формируется многострочный.
    если ЭД уже многострочный - ничего не делаем.
    многострочный формируется путем создания узлов LINES\LINE с копированием
    полей из шапки ЭД в тег LINE.
    в результате в aDocLines возвращается тег с описанием строк ЭД (LINES).}
  procedure DoUpdateED215_( aED215: Variant; var aDocLines: Variant;);
  var
    i: integer;
    xDocLine: Variant;
    xAttrList: Variant;
    xAttrName: string;
  begin

      try
        // если узел LINES есть, значит ЭД 215го класса многострочный
        for i := 0 to aED215.childNodes.length - 1 do
          if (aED215.childNodes.items[i].NodeName = 'LINES') then begin
            aDocLines := aED215.childNodes.items[i];
            EXIT;
          end;
        // для однострочного эд, нужно создать вложение LINES\LINE
        // и в строку LINE скопировать описание строки из шапки
        aDocLines := aED215.appendChild(
                                aED215.OwnerDocument.CreateElement( 'LINES'));
        xDocLine  := aDocLines.appendChild(
                                aED215.OwnerDocument.CreateElement( 'LINE'));
        // переносим атрибуты строки из шапки в строку LINE
        xAttrList := aED215.attributes;
        for i := 0 to xAttrList.length - 1 do begin
          xAttrName := xAttrList.item(i).NodeName;
          // атрибуты описания ЭД (шапки) оставляем
      	  case xAttrName of
            'DOC_DATE',
            'DOC_NUMBER',
            'OPERTYPE_ID',
            'FK_FLAG',
            'GUID_FK',
            'DESCRIPTION',
            'REMARK',
            'ID',
            'DOCUMENT_ID',
            'VERSION',
            'FOREIGN_KEY',
            'BUDGET_ID',
            'completed': CONTINUE;
          end;//case//
          // прочие атрибуты копируем из шапки в строку
          xDocLine.SetAttribute( xAttrName, aED215.GetAttribute( xAttrName));
        end;//for//
        except
          ExceptionLog( 'Сбой DoUpdateED215_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~CheckUF_Lines_
    проверка строк UFPP или UFPP_N.
    проверяется заполнение полей КБК и тип КБК.
    для строк UFPP_N проверяется счет UFPP_N.LS_UBP.

    результат:
      =true - есть хотя бы одна строка, по которой можно создать ЭД.
      =false - нет ни одной актуальной строки.

    строки помечаются атрибутом _checked_.
      для нормальных строк в нем "ok" для сбойных - "error".

    параметры:
      aUF_Lines - корневой узел со списком строк.
                  ожидается название узла UFPP или UFPP_N

    exchange #2953
    проверка UFPP_N.LS_UBP отменена}
  function CheckUF_Lines_( aUF_Lines: Variant): boolean;
  var
    xNode: Variant;
    i: integer;
    s: string;
    xUF_Line: string;
    xIsUFPP: boolean;
    xFatalError: boolean;
    xKBK: string;
    xTypeKBK: string;
    xUF_Line_SumPP: string;
//    xCheck_UFPP_N_LS_UBP: boolean;
  begin

      try
        Result := FALSE;
        xFatalError := FALSE;

        // это UFPP ?
        xIsUFPP := (aUF_Lines.NodeName = 'UFPP');

        // для разделов UFPP_N требуется проверять счет по ФТ-1
//        xCheck_UFPP_N_LS_UBP := (aUF_Lines.NodeName = 'UFPP_N');

        // проверка строк
        for i := 0 to aUF_Lines.childNodes.length - 1 do begin
          xNode := aUF_Lines.childNodes.item[i];

          // считаем что строка прошла проверку
          s := 'ok';

          // проверяем заполнение КБК и тип КБК
          // если хотя бы одно из полей пустое - такие строки не анализируем,
          // но фатальной ошибкой это не является.
          xKBK := VarToStr( xNode.GetAttribute( 'KBK'));
          xTypeKBK := VarToStr( xNode.GetAttribute( 'TYPE_KBK'));

          if ((LENGTH( xKBK) <= 0) OR (LENGTH( xTypeKBK) <= 0))
            then s := 'error'
            else begin
              // проверяется КБК с заменой отсуствующий кодов в БД на 0
              // (aCfgResetBadKBK=true).
              // если коды будут отсутствовать в бд, и опция
              // "игнорировать отсутствующие кбк" не будет выбрана
              // (aCfgIgnoreBadKBK=false), то ЭД не будем создавать.
              // если код КБК заменен на 0, то обновляем поле КБК в разделе
              // UFPP или UFPP_N.
              // exchange #3062 - отмена косгу
              if ValidateKbk( xKBK,
                              xTypeKBK,
                              aBudgetID,
                              aCfgResetBadKBK,
                              '',
                              FALSE) then
                // кбк имеет ошибки - проверяем, игнорируем ли ошибки или нет?
                if NOT aCfgIgnoreBadKBK then begin
                  WriteInfo( FORMAT( 'ЭД не создается - в строке %s с номером %s код КБК не определен в БД.',
                                      [ aUF_Lines.NodeName,
                                        INTTOSTR( i + 1)]));
                  s := 'error';
                  xFatalError := TRUE;
                end;
              // перезаписываем кбк (возможны заполнение
              // несуществующих бк нулями)
              xNode.SetAttribute( 'KBK', xKBK);
            end;

          // проверяем поле суммы - сумма всегда должна быть не пустой и не 0.00
          if xIsUFPP
            then xUF_Line_SumPP := VarToStr( xNode.GetAttribute( 'SUM_PP'))
            else xUF_Line_SumPP := VarToStr( xNode.GetAttribute( 'SUM'));
          // exchange #2874
          // пустое поле проверяется только для UFPP.SUM_PP.
          // для UFPP_N.SUM, если будет пустое значение, то подставляется
          // из UFPP.SUM_PP, поэтому для UFPP_N.SUM пустое значение не проверяем
          if (LENGTH( xUF_Line_SumPP) <= 0) then begin
            if xIsUFPP then begin
              s := 'error';
              // для строк с заполненными полями КБК и тип КБК, если поле
              // суммы не указано - это фатальная ошибка
              if ((LENGTH( xKBK) > 0) AND (LENGTH( xTypeKBK) > 0)) then begin
                WriteInfo( FORMAT( 'ЭД не создается - в строке UFPP с номером %s поле суммы (SUM_PP) не заполнено.',
                                   [ INTTOSTR( i + 1)]));
                xFatalError := TRUE;
              end;
            end;
          end else
            if (xUF_Line_SumPP = '0.00') then begin
              s := 'error';
              // для строк с заполненными полями КБК и тип КБК, если поле
              // суммы не указано - это фатальная ошибка
              if ((LENGTH( xKBK) > 0) AND (LENGTH( xTypeKBK) > 0)) then begin
                if xIsUFPP
                  then WriteInfo( FORMAT( 'ЭД не создается - в строке UFPP с номером %s поле суммы (SUM_PP) = 0.',
                                          [ INTTOSTR( i + 1)]))
                  else WriteInfo( FORMAT( 'ЭД не создается - в строке UFPP_N с номером %s поле суммы (SUM) = 0.',
                                          [ INTTOSTR( i + 1)]));
                xFatalError := TRUE;
              end;
            end;

          // если это UFPP, проверяем параметры
          // разделов в UFPP по Коду платежного документа (KOD_DOC).
          // если будут проблемы - создание ЭД прерываем,
          // уведомляем в логе о конкретно этой строке,
          // но продолжаем анализ прочих строк.
          // проверяем независимо от состояния предыдущих проверок,
          // чтобы найти все возможные проблемы за одну обработку файла.
          if xIsUFPP then
            case VarToStr( xNode.GetAttribute( 'KOD_DOC')) of
              'ZR','ZS','ZN','UF','SP':
                  if ((LENGTH( VarToStr( xNode.GetAttribute( 'NOM_PP'))) <= 0)
                      OR (LENGTH( VarToStr( xNode.GetAttribute( 'DATE_PP'))) <= 0))
                    then begin
                      WriteInfo( FORMAT( 'ЭД не создается - строка UFPP с номером %s содержит пустую дату или номер платежного документа.',
                                          [ INTTOSTR( i + 1)]));
                      s := 'error';
                      xFatalError := TRUE;
                    end;

              // здесь проверяем, если NOM_ZR или DATE_ZR пустые,
              // то NOM_PP и DATE_PP не должны быть пустыми.
              'PP':
                  if ((LENGTH( VarToStr( xNode.GetAttribute( 'NOM_ZR'))) <= 0)
                      OR (LENGTH( VarToStr( xNode.GetAttribute( 'DATE_ZR'))) <= 0))
                    then
                      if ((LENGTH( VarToStr( xNode.GetAttribute( 'NOM_PP'))) <= 0)
                          OR (LENGTH( VarToStr( xNode.GetAttribute( 'DATE_PP'))) <= 0))
                        then begin
                          WriteInfo( FORMAT( 'ЭД не создается - строка UFPP с номером %s содержит пустую дату или номер заявки и пустую дату или номер платежного документа.',
                                              [ INTTOSTR( i + 1)]));
                          s := 'error';
                          xFatalError := TRUE;
                        end;

              'ZV':
                  case VarToStr( xNode.GetAttribute( 'TYPE_KBK')) of
                    '10': begin
                            WriteInfo( FORMAT( 'ЭД не создается - строка UFPP с номером %s, значением KOD_DOC=ZV и типом КБК=10 не допустима.',
                                                [ INTTOSTR( i + 1)]));
                            s := 'error';
                            xFatalError := TRUE;
                          end;

                    '20': if ((LENGTH( VarToStr( xNode.GetAttribute( 'NOM_PP'))) <= 0)
                              OR (LENGTH( VarToStr( xNode.GetAttribute( 'DATE_PP'))) <= 0))
                            then begin
                              WriteInfo( FORMAT( 'ЭД не создается - строка UFPP с номером %s содержит пустую дату или номер платежного документа.',
                                                  [ INTTOSTR( i + 1)]));
                              s := 'error';
                              xFatalError := TRUE;
                            end;

                    '30': if ((LENGTH( VarToStr( xNode.GetAttribute( 'NOM_ZR'))) <= 0)
                              OR (LENGTH( VarToStr( xNode.GetAttribute( 'DATE_ZR'))) <= 0))
                            then begin
                              WriteInfo( FORMAT( 'ЭД не создается - строка UFPP с номером %s содержит пустую дату или номер заявки.',
                                                  [ INTTOSTR( i + 1)]));
                              s := 'error';
                              xFatalError := TRUE;
                            end;
                  end;//case//
            end;//case//

          // маркер проверки строки UFPP_N
          xNode.SetAttribute( '_checked_', s);

        end;//for//

        if NOT xFatalError then begin
          // проверяем, есть ли строки с найденным счетом UFPP_N.LS_UBP
          // или с пустым значением в UFPP_N.LS_UBP.
          for i := 0 to aUF_Lines.childNodes.length - 1 do begin
            xNode := aUF_Lines.childNodes.item[i];
            if (VarToStr( xNode.GetAttribute( '_checked_')) = 'ok') then begin
              Result := TRUE;
              BREAK;
            end;
          end;//for//
          if NOT Result
            then WriteInfo( FORMAT( 'Проверка раздела %s - не содержит актуальных строк для создания ЭД',
                                     [ aUF_Lines.NodeName ]));
        end;
        except
          ExceptionLog( 'Сбой CheckUF_Lines_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~IsBadLine_
    проверка строки aLine (раздел UFPP или UFPP_N) - актуальна ли эта
    строка для формирования эд 215го класса ?
    проверяется наличие атрибута _checked_ со значением "ok".
    атрибут заполняется подпрограммой CheckUF_Lines_.

    возвращается:
      =true - строка недействительна и не должна обрабатываться.
      =false - строка пригодна для создания эд 215го класса}
  function IsBadLine_( aLine: Variant): boolean;
  begin

      try
        Result := (aLine.GetAttribute( '_checked_') <> 'ok');

        except
          ExceptionLog( 'Сбой IsBadLine_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~QueryLS_
    описание счета с типом aLSType для организации aOrgID }
  function QueryLS_( aOrgID, aLS, aLSType: string; var aLSXml: Variant): boolean;
  var
    xLSXml: Variant;
  begin

      try
        if (LENGTH( aLSType) > 0)
          then xLSXml := QueryXml(
                             ' select * from orgaccount oa'
                            +' where oa.org_id=?'
                            +'   and oa.orgacctype_id in (' + aLSType + ')'
                            +'   and oa.account_number=?'
                            +'   and (oa.close_date is null or oa.close_date>?)',
                             [ aOrgID,
                               aLS,
                               Work_Date])
          else xLSXml := QueryXml(
                             ' select * from orgaccount oa'
                            +' where oa.org_id=?'
                            +'   and oa.account_number=?'
                            +'   and (oa.close_date is null or oa.close_date>?)',
                             [ aOrgID,
                               aLS,
                               Work_Date]);
        Result := (xLSXml.documentElement.childNodes.Length = 1);
        if Result
          then aLSXml := xLSXml.documentElement.childNodes.item[ 0]
          else aLSXml := NULL;

        except
          ExceptionLog( 'Сбой QueryLS_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~QueryOrg_
    описание организации aID }
  function QueryOrg_( aID: string): Variant;
  begin

      try
        Result := QueryXml( ' select * from org o where o.id=?', [ aID]);
        if (Result.documentElement.childNodes.Length = 1)
          then Result := Result.documentElement.childNodes.item[ 0]
          else Result := NULL;

        except
          ExceptionLog( 'Сбой QueryOrg_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~QueryDoc_
    загрузка эд по aID из таблицы  aTable.
    параметр aTitleOnly определяет, нужно ли проверять только шапку ЭД
    или если поля title_id в эд нет, тогда параметр должен быть =false.}
  function QueryDoc_( aTable, aID: string;
                      aTitleOnly: boolean = TRUE): Variant;
  begin

      try
        if aTitleOnly
          then Result := QueryXml(  ' select * from ' + aTable + ' where id=?'
                                   +' and (title_id=id or title_id is null)',
                                    [ aID])
          else Result := QueryXml( ' select * from ' + aTable + ' where id=?',
                                    [ aID]);
        if (Result.documentElement.childNodes.Length = 1)
          then Result := Result.documentElement.childNodes.item[ 0]
          else Result := NULL;

        except
          ExceptionLog( 'Сбой QueryDoc_');
      end;

  end;
  //----------------------------------------------------------------------------
var
  xNode_UFPP: Variant;
  xNode_UFPP_N: Variant;
  xGUID: string;
  i: integer;
  xIndexUFPP: integer;
  xIndexUFPP_N: integer;
//  s: string;
  xUFPP: Variant;
  xUFPP_N: Variant;
  xUF_NOM_ZF: string;
  xUF_DATE_ZF: string;
  xUF_NOM_UF: string;
  xUF_DATE_UF: string;
  xUFPP_KOD_DOC: string;
  xDocXml: Variant;
  xDoc: Variant;
  xDocLines: Variant;
  xDocLine: Variant;
  xDocInfo: string;
  xDoc_Problem: boolean;
  xDoc_Error: boolean;
  xED: Variant;
  xED_ID: string;
  xED_Class: string;
  xED80: Variant;
  xED11: Variant;
  xED5: Variant;
  xED118: Variant;
  xED24: Variant;
  xED19: Variant;
  xED25: Variant;
//  xED11_ADVPAYMENT: string;
//  xED11_ESTIMATE_ID: string;
  xUFPP_KBK: string;
  xUFPP_TYPE_KBK: string;
  xUFPP_NOM_PP: string;
  xUFPP_DATE_PP: string;
  xUFPP_PurposefullgrantID: string;
  xUFPP_SUM_PP: string;
  xUFPP_NOM_ZR: string;
  xUFPP_DATE_ZR: string;
  xUFPP_LINE_NOM: string;
  xUF_INN_PL: string;
  xUF_KPP_PL: string;
//  xIK_LS_UBP_ID: string;
//  xIK_LS_UBP_OrgID: string;
  xUFPP_N_SUM: string;
  xUF_TYPE_KR: string;
  //----------------------------------------------------------------------------
  {~Do_Search_UFPP_N_
    поиск раздела UFPP_N по текущему разделу UFPP с номером UFPP.LINE_NOM
    в переменной xUFPP_LINE_NOM.
    текущий раздел UFPP, который сейчас обрабатываем, описывается
    в переменной xNode_UFPP.
    если найденный раздел UFPP_N будет с ошибкой - то эд 215й создать нельзя.
    результат:
      =true - раздел UFPP_N найден и указан в переменной xNode_UFPP_N.
      =false - не найден или найденный раздел UFPP_N имеет ошибки.}
  function Do_Search_UFPP_N_: boolean;
  var
    j: integer;
  begin

      try
        for j := 0 to xUFPP_N.childNodes.length - 1 do begin
          xNode_UFPP_N := xUFPP_N.childNodes.item[ j];
          if (xNode_UFPP_N.GetAttribute( 'LINE_NOM') = xUFPP_LINE_NOM) then begin

            if IsBadLine_( xNode_UFPP_N) then begin
              Result := FALSE;
              WriteInfo( FORMAT( 'Уточненная строка (раздел UFPP_N) для раздела UFPP с порядковым номером %s содержит недопустимые значения.',
                                 [ INTTOSTR( xIndexUFPP + 1)]));
            end else begin
              Result := TRUE;
            end;
            EXIT;
          end;
        end;//for//
        WriteInfo( FORMAT( 'Не найдена уточненная строка (раздел UFPP_N) для раздела UFPP с порядковым номером %s.',
                           [ INTTOSTR( xIndexUFPP + 1)]));
        Result := FALSE;
        except
          ExceptionLog( 'Сбой Do_Search_UFPP_N_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~Do_Search_UFPP_
    exchange #2954
    поиск раздела UFPP по текущему разделу UFPP_N с номером UFPP_N.LINE_NOM
    в переменной xUFPP_LINE_NOM. это нужно, поскольку допускается несколько
    разделов UFPP_N на один раздел UFPP.
    текущий раздел UFPP_N, который сейчас обрабатываем, описывается
    в переменной xNode_UFPP_N.
    если найденный раздел UFPP будет с ошибкой - то эд 215й создать нельзя.
    результат:
      =true - раздел UFPP найден и указан в переменной xNode_UFPP.
      =false - не найден или найденный раздел UFPP имеет ошибки.}
  function Do_Search_UFPP_: boolean;
  var
    j: integer;
  begin

      try
        for j := 0 to xUFPP.childNodes.length - 1 do begin
          xNode_UFPP := xUFPP.childNodes.item[ j];
          if (xNode_UFPP.GetAttribute( 'LINE_NOM') = xUFPP_LINE_NOM) then begin

            if IsBadLine_( xNode_UFPP) then begin
              Result := FALSE;
              WriteInfo( FORMAT( 'Уточняемая строка (раздел UFPP) для раздела UFPP с порядковым номером %s содержит недопустимые значения.',
                                 [ INTTOSTR( xIndexUFPP_N + 1)]));
            end else begin
              Result := TRUE;
            end;
            EXIT;
          end;
        end;//for//
        WriteInfo( FORMAT( 'Не найдена уточняемая строка (раздел UFPP) для раздела UFPP_N с порядковым номером %s.',
                           [ INTTOSTR( xIndexUFPP_N + 1)]));
        Result := FALSE;
        except
          ExceptionLog( 'Сбой Do_Search_UFPP_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~Do_FT_7_
    ФТ-7
      Сформированный документ класса 215 доводить до статуса «новый»,
    при некорректном заполнении полей документа (xDoc_Problem=true)
    оставлять на статусе «Отложен».
      если будет сбой перевода статуса - фиксируем ошибку в журнале,
    но обработку файла не прерываем - считаем что загрузка эд 215го прошла
    успешно, т.е. итоговый результат функции обработки UF будет =0.}
  procedure Do_FT_7_;
  begin

      try
        if NOT xDoc_Problem then
          try

            xDocXml.LoadXml(
                  ExecProc( 'DOCUMENT',
                            [ 'action', 'process',
                              'class', '215',
                              'ID', xDocXml.documentElement.GetAttribute( 'ID')],
                            aBudgetID));
            DoWriteLog_( FORMAT( '%s переведен на статус "новый".', [ xDocInfo]));
            except
              // exchange #2930
              // поправлен текст сообщения в журнале
              WriteInfo( FORMAT( 'Ошибка перевода статуса %s - %s',
                                 [ xDocInfo,
                                   LastException.Message]));
          end;
        except
          ExceptionLog( 'Сбой Do_FT_7_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~DoCreateLineED215_
    создание узла для строки в создаваемом ЭД 215го класса.
    пока эта строка не добавляется в список строк эд 215го.
    это дает то, что создается узел строки, заполняется, и если будут проблемы
    то этот узел можно игнорировать и тем самым не будет добавлена строка
    в эд.
    результат:
      переменная xDocLine будет содержать узел с описанием новой строки.}
  procedure DoCreateLineED215_;
  begin

      try
        xDocLine := xDocXml.CreateElement( 'LINE');
        except
          ExceptionLog( 'Сбой DoCreateLineED215_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~DoAddLineED215_
    создание строки в создаваемом ЭД 215го класса.
    здесь проверяем, если тега LINES нету - создаем его.
    затем в теге LINES создаем новую строку LINE.
    результат:
      переменная xDocLine будет содержать узел с описанием новой строки.
    если параметр aNewLine<>NULL, то этот узел будет добавлен к строкам
    эд 215го и возвращен в качестве результата, иначе будет создан новый узел.}
  procedure DoAddLineED215_( aNewLine: Variant = NULL);
  begin

      try
        if VarIsNULL( xDocLines) then begin
          xDocLines := xDoc.appendChild( xDocXml.CreateElement( 'LINES'));

        end;
        if VarIsNULL( aNewLine)
          then xDocLine := xDocLines.appendChild( xDocXml.CreateElement( 'LINE'))
          else xDocLine := xDocLines.appendChild( aNewLine);
        except
          ExceptionLog( 'Сбой DoAddLineED215_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~DoFillLineFromUFLine_
    заполнение полей строки нового ЭД 215го:
      Основание
      Наименование
      Номер
      Дата
    из строки UFPP или UFPP_N - aUF_Line.
      для раздела UFPP_N полей как у UFPP нету, поэтому все поля будут в ЭД
    не заполнены.}
  procedure DoFillLineFromUFLine_(aUF_Line: Variant);
  var
    s: string;
  begin

      try
        // Основание - UFPP/UFPP_N.NOTE
        xDocLine.SetAttribute( 'DESCRIPTION_LINE',
                               VarToStr( aUF_Line.GetAttribute( 'NOTE')));

        // Наименование - UFPP/UFPP_N.NAME_PP
        xDocLine.SetAttribute( 'PAYDOC_NAME',
                               VarToStr( aUF_Line.GetAttribute( 'NAME_PP')));

        // Номер - UFPP/UFPP_N.NOM_PP
        xDocLine.SetAttribute( 'PAYDOC_DOC_NUMBER',
                               VarToStr( aUF_Line.GetAttribute( 'NOM_PP')));

        // Дата - UFPP/UFPP_N.DATE_PP
        // строка должна быть в формате YYYY-MM-DD
        s := VarToStr( aUF_Line.GetAttribute( 'DATE_PP'));
        if (LENGTH( s) > 0)
          then xDocLine.SetAttribute( 'PAYDOC_DOC_DATE',
                                      DateTimeToXml( StrToDate( s)));


        except
          ExceptionLog( 'Сбой DoFillLineFromUFLine_');
      end;

  end;
  //----------------------------------------------------------------------------
  // заполнение счета и орг
  //----------------------------------------------------------------------------
  // ФТ-5-2 и ФТ-5-3
  //----------------------------------------------------------------------------
  // ФТ-5-3
  //----------------------------------------------------------------------------
  {~DoUpdateMainED215_
    заполнение описания шапки эд 215го по UF.}
  procedure DoUpdateMainED215_( aDoc: Variant);
  begin

      try
        // Номер документа - Равно значению UF.NOM_UF
        aDoc.setAttribute( 'DOC_NUMBER', xUF_NOM_UF);
        // Дата документа - Равно значению UF.DATE_UF
        // в конечном документе формат даты: yyyy-mm-dd.
        aDoc.setAttribute( 'DOC_DATE', DateTimeToXml( StrToDate( xUF_DATE_UF)));
        // Признак "От ФК"
        // UF – Уведомление об уточнении вида и принадлежности платежа
        aDoc.setAttribute( 'FK_FLAG', '3');
        // Основание - Не заполнять
        aDoc.setAttribute( 'DESCRIPTION', '');
        // Комментарий	Не заполнять
        aDoc.setAttribute( 'REMARK', '');
        { тип операции - заполняется значением, выбранным для  Справки по
          внебанковским операциям в справочнике "Типы операций по-умолчанию",
          а в случае отсутствия настройки, значением "Не указано"}
        aDoc.setAttribute( 'OPERTYPE_ID',
                           INTTOSTR( OperTypeDefaultForClass( 215)));

        except
          ExceptionLog( 'Сбой DoUpdateMainED215_');
      end;

  end;
  //----------------------------------------------------------------------------
  // ФТ-2-1
  //----------------------------------------------------------------------------
  //----------------------------------------------------------------------------
  {~DoAddLine_UFPP_
    добавление строки в эд 215го класса по блоку UFPP_N или UFPP в aNodeUFPP
    с названием в aNodeUFPP_Name (строка UFPP или UFPP_N) и номером строки
    в файле aNodeUFPP_Index.}
  procedure DoAddLine_UFPP_( //aLS: string;
                                 aNodeUFPP: Variant;
                               //  aNodeUFPP_Name: string;
                                 aNodeUFPP_Index: string);
  var
    s: string;
    xESTIMATE_ID: string;
    xUF_Line_Is_UFPP: boolean;
//    xLS: string;
    xUF_Line_SumPP: string;
//    xLS_Search_Type: string;
    xPurpgrID: string;
    xKBK: string;
    xExp: Variant;
    xKFSR_CODE: string;
    xKVR_CODE: string;
    xKESR_CODE: string;
    xKCSR_CODE: string;
    xKADMR_CODE: string;
    xOrgXml: Variant;
    xLSXml: Variant;
    xOrgID: string;
    xLS: string;
    xKADMD_CODE: string;
    xKD_CODE: string;
    xKESD_CODE: string;
    xRECEIVER_ID: string;
    xInc: Variant;
    xKADMI_CODE: string;
    xKI_CODE: string;
    xKESI_CODE: string;
    xSrc: Variant;
//    xFoundAcount: integer;
    xFillLinebyFile: boolean;
    xLineError: boolean;
    xFound: string;
//    xEstimateLS: string;


(*
    function DoSearchLS_ForLine10_: boolean;
    begin
    
        try
          if (xLsXML.documentElement.childNodes.length <> 1)
            then Result := FALSE
            else begin
              xLsXML := xLsXML.documentElement.childNodes.item[ 0];
              // описание орг владельца счета
              xOrgID := GetNodeAttributeEx( xLsXML, 'ORG_ID');
              xOrgXML := QueryXml( 'select * from org where id=?', [ xOrgID]);
              if (xOrgXML.documentElement.childNodes.length <> 1)
                then Result := FALSE
                else begin
                  Result := TRUE;
                  xOrgXML := xOrgXML.documentElement.childNodes.item[ 0];
                end;
            end;
          except
            ExceptionProc( 'DoSearchLS_ForLine10_');
        end;
    
    end;
  *)


(*
    function DoSearchOrg10_F_: boolean;
    begin

        try
          xSQL := ' from orgaccount oa'
                  // орг. владелец счета
                 +' join org o on o.id=oa.org_id'
                  // галка актуальности орг
                 +' Join Contractor C on C.Org_Id = O.Id'
                 +' Join Budget B on B.Org_Id = C.Inspector_Id'
                  // проверка номера счета
                 +' where oa.account_number=?'
                  // тип счета 5 или 9
                 +' and OA.ORGACCTYPE_ID in (5,9)'
                 +' and b.id=?'
                 +' and oa.close_date is null'
                 +' and o.close_date is null';

          if (QueryField( ' select count( * ) N ' + xSQL,
                                [ aIK_LS_UBP,
                                  aBudgetID],
                                'N') <> '1')
            then Result := FALSE
            else begin
              xLsXML := QueryXml( 'select oa.* ' + xSQL,
                                [ aIK_LS_UBP,
                                  aBudgetID]);
              Result := DoSearchLS_ForLine10_;
            end;
{
              xOrgID := QueryXml( 'select oa.org_id ID ' + xSQL,
                                [ aIK_LS_UBP,
                                  aBudgetID],
                                'ID');
              xOrgXML := QueryXml( 'select * from org where id=?', [ xOrgID]);
              if (xOrgXML.documentElement.childNodes.length <> 1)
                then Result := FALSE
                else begin
                  Result := TRUE;
                  xOrgXML := xOrgXML.documentElement.childNodes.item[ 0];
                end;
            end;}
          except
            ExceptionProc( 'DoSearchOrg10_F_');
        end;

    end;
*)

  begin

      try
        // определяем тип раздела: UFPP или UFPP_N
      //  xUF_Line_Is_UFPP := (aNodeUFPP_Name = 'UFPP');
        // формируем новую строку в ЭД, но еще не помещаем ее к строкам эд 215го
//        DoAddLineED215_;
        DoCreateLineED215_;
        xLineError := FALSE;

        // параметры из UFPP_N
        xKBK      := aNodeUFPP.GetAttribute( 'KBK');
        xPurpgrID := GetPurposefullGraintIDByUF_(
                                VarToStr( aNodeUFPP.GetAttribute( 'ADD_KLASS')),
                                FALSE,  // (aNodeUFPP_Name = 'UFPP_N'),
                                aBudgetID);
        // сумма из раздела
//        if xUF_Line_Is_UFPP
  //        then xUF_Line_SumPP := aNodeUFPP.GetAttribute( 'SUM_PP')
    //      else xUF_Line_SumPP := aNodeUFPP.GetAttribute( 'SUM');
        xUF_Line_SumPP := aNodeUFPP.GetAttribute( 'SUM_PP');

        // логируем операцию
        WriteLog( FORMAT( 'Формирование строки ЭД по блоку UFPP с порядковым номером %s...',
                          [ aNodeUFPP_Index]));

        // заполнение строки
        case aNodeUFPP.GetAttribute( 'TYPE_KBK') of
          //-----------------------------------------------------------------
          '10': begin
                  // кбк расходной строки
                  // exchange #3062
                  DoEncodeKBK_R(
                        xKBK,
                        xKADMR_CODE, xKFSR_CODE, xKCSR_CODE, xKVR_CODE, xKESR_CODE,
                        FALSE);
                        {
                  xKFSR_CODE  := COPY( xKBK, 4, 4);
                  xKCSR_CODE  := COPY( xKBK, 8, 7);
                  xKVR_CODE   := COPY( xKBK,15, 3);
                  xKESR_CODE  := COPY( xKBK,18, 3);
                  xKADMR_CODE := COPY( xKBK, 1, 3);}

                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '1');
                  xDocLine.SetAttribute( 'KFSR_CODE', xKFSR_CODE);
                  xDocLine.SetAttribute( 'KCSR_CODE', xKCSR_CODE);
                  xDocLine.SetAttribute( 'KVR_CODE', xKVR_CODE);
                  // exchange #3062
                  //xDocLine.SetAttribute( 'KESR_CODE', xKESR_CODE);
                  xDocLine.SetAttribute( 'KADMR_CODE', xKADMR_CODE);
                  // код цели
                  xDocLine.SetAttribute( 'PURPOSEFULGRANT_ID', xPurpgrID);

                  //if xUF_Line_Is_UFPP then begin
                  // строка UFPP
//fff
//                  if NOT QueryExp_( aBudgetID, xDocLine, xEXP) then begin
                    // ищем бланк расходов с организацией-оператором,
                    // владельцем счета  IK.LS_UBP (с ролью «Бюджетополучатель»,
                    // актуальная). если не нашли - заполнять будем по файлу.
                    if NOT DoSearchOrg10_( aBudgetID,
                                           aIK_LS_UBP,
                                           xOrgID,
                                           xOrgXML,
                                           xLsXml) then begin
                        WriteInfo(
                            FORMAT( 'Счет %s не подходит для поиска бланка расходов - строка в ЭД не создается.',
                                    [ aIK_LS_UBP]));
//                        xDoc_Error := TRUE;
                        xLineError := TRUE;
                        EXIT;
                      end;

//                      then xFillLinebyFile := TRUE    // по файлу
//                      else begin
                        // ищем БР по exchange #2957
                        // если не нашли - искать будем по файлу
                        xESTIMATE_ID := GetEstimateId_2957_Ex( aBudgetId,
                                                               xOrgID,
                                                               aIK_LS_UBP,
                                                               xDocLine);
                      if (LENGTH( xESTIMATE_ID) <= 0) then begin
                        WriteInfo(
                            FORMAT( 'Не найден бланк расходов по счету %s - строка в ЭД не создается.',
                                    [ aIK_LS_UBP]));
//                        xDoc_Error := TRUE;
                        xLineError := TRUE;
                        EXIT;
                      end;
                      // бланк расходов
                      xDocLine.SetAttribute( 'ESTIMATE_ID', xESTIMATE_ID);

//                          then xFillLinebyFile := TRUE    // по файлу
//                          else begin
                            //xFillLinebyFile := FALSE;
                            // поиск бюджетополучателя и заполнение доп кодов из РЧБ
                            FillLine10_ED_2953(  // для UFPP
                                        aBudgetId,
                                        xESTIMATE_ID,
                                        GetNodeAttributeEx( aNodeUFPP, 'INN_PP'),
                                        GetNodeAttributeEx( aNodeUFPP, 'KPP_PP'),
                                        '',   // с любым незакрытым счетом у орг.
                                        xDocLine,
                                        xDocLine);
//                              then xFillLinebyFile := FALSE // нашли в рчб
//                              else xFillLinebyFile := TRUE;  // не нашли в рчб
//                          end;
//                      end;
(*
                    //--------------------------------------------------------
                    if NOT xFillLinebyFile then begin
                      // заполняем строку по файлу
                      // в начале счет + организация
                      if NOT DoSearchOrg10_F_ then begin
                        WriteInfo(
                            FORMAT( 'Счет %s не подходит для поиска бланка расходов.',
                                    [ aIK_LS_UBP]));
                        xDoc_Error := TRUE;
                        EXIT;
                      end;
                      // ищем БР по exchange #2957
                      xESTIMATE_ID := GetEstimateId_2957_Ex( aBudgetId,
                                                             xOrgID,
                                                             aIK_LS_UBP,
                                                             xDocLine);
                      if (LENGTH( xESTIMATE_ID) <= 0) then begin
                        WriteInfo(
                            FORMAT( 'Не найден бланк расходов по счету %s.',
                                    [ aIK_LS_UBP]));
                        xDoc_Error := TRUE;
                        EXIT;
                      end;
                      // поиск бюджетополучателя и заполнение доп кодов из РЧБ
                      FillLineED_2957_ByZR(  // для UFPP
                                  aBudgetId,
                                  xESTIMATE_ID,
                                  GetNodeAttributeEx( aNodeUFPP, 'INN_PP'),
                                  GetNodeAttributeEx( aNodeUFPP, 'KPP_PP'),
                                  '',   // с любым незакрытым счетом у орг.
                                  xDocLine,
                                  xDocLine,
                                  '5,9');
                    end;
                    *)

                    // заполнение орг и счета
                    DoFillOrgAndLS_( xOrgID, xOrgXml, aIK_LS_UBP, xLSXml,
                                     xDocLine);
                    // бланк расходов
                    xDocLine.SetAttribute( 'ESTIMATE_ID', xESTIMATE_ID);

                    // exchange #2953
                    // для строк UFPP Если значение UF.TYPE_KR = «1»,
                    // то значение поля «Сумма»,
                    // иначе значение поля «Сумма» строки с минусом.
                    if (xUF_TYPE_KR = '1')
                      then xDocLine.SetAttribute(
                                    'AMOUNT',
                                    FORMAT( '%.2f',
                                            [ StrToCurrDef(
                                                    xUF_Line_SumPP,
                                                    0)]))
                      else xDocLine.SetAttribute(
                                    'AMOUNT',
                                    FORMAT( '%.2f',
                                            [ 0 - StrToCurrDef(
                                                    xUF_Line_SumPP,
                                                    0)]));
                    // передано - заполнить нулем, иначе на ацк-ф
                    // могут быть проблемы привставки строк
                    xDocLine.SetAttribute( 'PASS_AMT', '0.00');

                    // копируем в строку UFPP поля из сформированной строки
                    // это нужно для заполнения полей по ФТ-5.3
                    aNodeUFPP.SetAttribute( 'ESTIMATE_ID',
                                           xDocLine.GetAttribute( 'ESTIMATE_ID'));

                    aNodeUFPP.SetAttribute( 'RECIPIENT_ID',
                                           xDocLine.GetAttribute( 'RECIPIENT_ID'));

{                  end else begin
                    // строка UFPP_N
                    // ищем строку UFPP
                    if NOT Do_Search_UFPP_ then begin
                      WriteInfo( 'Не найден блок UFPP для блока UFPP_N');
                      xDoc_Error := TRUE;
                      EXIT;
                    end;
                    if (GetNodeAttributeEx( xNode_UFPP, 'TYPE_KBK') = '10')
                      then begin
                        aNodeUFPP.SetAttribute(
                                  'ESTIMATE_ID',
                                  GetNodeAttributeEx( xNode_UFPP, 'ESTIMATE_ID'));
                        aNodeUFPP.SetAttribute(
                                  'RECIPIENT_ID',
                                  GetNodeAttributeEx( xNode_UFPP, 'RECIPIENT_ID'));



                  // бланк расходов
                  xDocLine.SetAttribute( 'ESTIMATE_ID', xESTIMATE_ID);

                    // организацию берем из бланка расходов
                    //xOrgXml := QueryOrg_( xIK_LS_UBP_OrgID);
                    // лицевой счет
                    QueryLS_( xOrgID, aIK_LS_UBP, '', xLSXml);
                    // заполнение орг и счета
                    DoFillOrgAndLS_( xOrgID, xOrgXml, aIK_LS_UBP, xLSXml);

                    // Сумма - Значение UFPP_N/UFPP.SUM_PP
                    // для UFPP сумма со знаком "-"
                    xDocLine.SetAttribute( 'AMOUNT', xUF_Line_SumPP);
                  end;}

                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                  // НПА - Не заполнять
                  // Авансовый платеж - Выключен
                  // Выставленный счет - Не заполнять
                  // Денежное обязательство - Не заполнять
                  // Бюджетное обязательство - Не заполнять
                  // Расходное обязательство - Не заполнять
                end;
          //-----------------------------------------------------------------
          '20': begin
                  // exchange #3062
                  DoEncodeKBK_D( xKBK, xKADMD_CODE, xKD_CODE, xKESD_CODE, FALSE);
                  {
                  xKADMD_CODE := COPY( xKBK, 1, 3);
                  xKD_CODE    := COPY( xKBK, 4,14);
                  xKESD_CODE  := COPY( xKBK,18, 3);
                  }

                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '2');
                  xDocLine.SetAttribute( 'KADMD_CODE', xKADMD_CODE);
                  xDocLine.SetAttribute( 'KD_CODE', xKD_CODE);
                  // exchange #3062
                  //xDocLine.SetAttribute( 'KESD_CODE', xKESD_CODE);
                  // код цели
                  xDocLine.SetAttribute( 'PURPOSEFULGRANTD_ID', xPurpgrID);

                  // ищем в ДЧБ без получателя
                  // exchange #3001
                  // при поиске в ДЧБ добавлено поле территория, которое
                  // определяется по полю UFPP.ОКАТО
                  xFound := QueryInc_(
                                  aBudgetID,
                                  xDocLine,
                                  aTO_KOD_UBP,
                                  xInc,
                                  GetNodeAttributeEx( aNodeUFPP, 'OKATO'));
                  if (xFound <> '1') then begin
                    // заполнение строки UFPP по файлу
                    // если в дчб не нашли, то орг, счет, получатель,
                    // плательщик, территория не заполнять.
                    // поэтому независимо от того, нашли ли получателя для
                    // поиска в дчб или нет - чистим ид.получателя.
                    // получатель= "не указана"
                    xDocLine.SetAttribute( 'RECEIVER_ID', '0');
                    // КВФО
                    xDocLine.SetAttribute( 'FSD_ID', '1');
                    // exchange #2874
                    // нулевые доп коды нужно формировать с учето маски
                    // Доп.КД
                    xDocLine.SetAttribute(
                              'KDD_CODE',
                              FormatKbk( 'KDD', '0', aBudgetID));//, '000');
                    // тип дохода заполнять значением «Не указано»,
                    // если включен системный параметр Сервис – Системные
                    // параметры – Доходы – Заполнять тип дохода значением
                    // «Не указано»,
                    // иначе по-умолчанию значением «Доходы».
                    if (SysParam_Type_not_defined_by_default = '1')
                      then xDocLine.SetAttribute( 'KDT_CODE', '0')
                      else xDocLine.SetAttribute( 'KDT_CODE', '1');
                    // плательщик, территория - не заполняются
                  end else begin
                    if (xFound = '0')
                      then WriteInfo( 'Строка в ДЧБ не найдена.')
                      else WriteInfo( FORMAT( 'Найдено строк в ДЧБ: %s', [ xFound]));
                    // заполнение строки по ДЧБ
                    // КВФО
                    xDocLine.SetAttribute( 'FSD_ID',
                                            xInc.GetAttribute( 'FSD_ID'));
                    // Доп.КД
                    xDocLine.SetAttribute( 'KDD_CODE',
                                            xInc.GetAttribute( 'KDD_CODE'));
                    // тип дохода
                    xDocLine.SetAttribute( 'KDT_CODE',
                                            xInc.GetAttribute( 'KDT_CODE'));
                    // exchange #3111 - косгу тоже переносится из дчб
                    xDocLine.SetAttribute( 'KESD_CODE',
                                            xInc.GetAttribute( 'KESD_CODE'));
                    // плательщик
                    xDocLine.SetAttribute( 'PAYER_ID',
                                            xInc.GetAttribute( 'PAYER_ID'));
                    // территория (блок плательщик)
                    xDocLine.SetAttribute( 'TERRITORY_ID',
                                            xInc.GetAttribute( 'TERRITORY_ID'));
                    // получателя берем из ДЧБ
                    xRECEIVER_ID := xInc.GetAttribute( 'RECEIVER_ID');
                    xDocLine.SetAttribute( 'RECEIVER_ID', xRECEIVER_ID);
                    // только если получаетль <> не указан
                    if ( xRECEIVER_ID <> '0') then
                      // описание орг. по получателю
                      if (QueryOrg20_By_Receiver_( xRECEIVER_ID, 'count( * )') = '1')
                        then begin
                          xOrgID := QueryOrg20_By_Receiver_( xRECEIVER_ID, 'r.org_id');
                          xOrgXml := QueryOrg_( xOrgID);
                          // лицевой счет
                          QueryLS_20_( xOrgID, xLS, xLSXml);
                          // заполнение орг и счета
                          DoFillOrgAndLS_( xOrgID, xOrgXml, xLS, xLSXml,
                                           xDocLine);
                        end;
                  end;

                  // сумма
                  // Зачислено - заполнять 0.00
                  xDocLine.SetAttribute( 'AMOUNT', '0.00');
                  // передано - Значение UFPP.SUM_PP
                  xDocLine.SetAttribute( 'PASS_AMT', xUF_Line_SumPP);

                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                end;
          //-----------------------------------------------------------------
          '31','32': begin
                  // exchange #3062
                  DoEncodeKBK_I( xKBK, xKADMI_CODE, xKI_CODE, xKESI_CODE, FALSE);
{                  xKADMI_CODE := COPY( xKBK, 1, 3);
                  xKI_CODE    := COPY( xKBK, 4,14);
                  xKESI_CODE  := COPY( xKBK,18, 3);}

                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '3');
                  xDocLine.SetAttribute( 'KADMI_CODE', xKADMI_CODE);
                  xDocLine.SetAttribute( 'KI_CODE', xKI_CODE);
                  // exchange #3062
                  //xDocLine.SetAttribute( 'KESI_CODE',xKESI_CODE );
                  // код цели
                  xDocLine.SetAttribute( 'PURPOSEFULGRANTI_ID', xPurpgrID);

                  // ищем строку в ИЧБ
                  if NOT QuerySrc_( aBudgetID, xDocLine, xSrc) then begin
                    // заполнение строки по UFPP_N
                    // КВФО
                    xDocLine.SetAttribute( 'FSI_ID', '1');
                    // exchange #2874
                    // нулевые доп коды нужно формировать с учето маски
                    // Доп.КД
                    xDocLine.SetAttribute(
                              'KDI_CODE',
                              FormatKbk( 'KDI', '0', aBudgetID));//, '000');
                    // контрагент - не заполняется
                    xDocLine.SetAttribute( 'COUNTERAGENT_ID', '');
                  end else begin
                    // заполнение строки по ДЧБ
                    // КВФО
                    xDocLine.SetAttribute( 'FSI_ID',
                                            xSrc.GetAttribute( 'FSI_ID'));
                    // Доп.КД
                    xDocLine.SetAttribute( 'KDI_CODE',
                                            xSrc.GetAttribute( 'KDI_CODE'));
                    // exchange #3111 - косгу тоже переносится из ичб
                    xDocLine.SetAttribute( 'KESI_CODE',
                                           xSrc.GetAttribute( 'KESI_CODE'));

                    // контрагент
                    xDocLine.SetAttribute( 'COUNTERAGENT_ID',
                                            xSrc.GetAttribute( 'COUNTERAGENT_ID'));
                  end;

                  // сумма
                  // Зачислено - заполнять 0.00
                  xDocLine.SetAttribute( 'AMOUNT', '0.00');
                  // передано - Значение UFPP.SUM_PP
                  xDocLine.SetAttribute( 'PASS_AMT', xUF_Line_SumPP);

                  // фо/гл.администратор
                  if (QueryOrg31_( aBudgetID, aIK_LS_UBP, 'count ( * )') = '1')
                    then begin
                      xOrgID := QueryOrg31_( aBudgetID, aIK_LS_UBP, 'o.ID');
                      // описание орг.
                      xOrgXml := QueryOrg_( xOrgID);
                      // лицевой счет - с любым типом счета
                      QueryLS_( xOrgID, aIK_LS_UBP, '', xLSXml);
                      // заполнение орг и счета
                      DoFillOrgAndLS_( xOrgID, xOrgXml, aIK_LS_UBP, xLSXml,
                                     xDocLine);
                    end;

                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                end;
        end;//case//

        // поля: Основание, Наименование, Номер, Дата
        DoFillLineFromUFLine_( aNodeUFPP);

        // если ошибок при формировании строки нет - добавляем сформированную
        // строку в список строк эд 215го
        if NOT xLineError
          then DoAddLineED215_( xDocLine);
        except
          ExceptionLog( 'Сбой DoAddLine_UFPP_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~Do_FT_5_2_
    создание строки в эд 215м по разделу UFPP из строки бюджета }
  procedure Do_FT_5_2_;
  begin

      try
        DoAddLine_UFPP_(// aIK_LS_UBP,
                             xNode_UFPP,
                      //       'UFPP',
                             INTTOSTR( xIndexUFPP + 1));
        except
          ExceptionLog( 'Сбой Do_FT_5_2_');
      end;

  end;
  (*
  //----------------------------------------------------------------------------
  {~DoAddLine_
    добавление строки в эд 215го класса сформированной по блоку UFPP_N,
    описанному в переменной xNode_UFPP_N}
  procedure DoAddLine_FT_5_3_;
  var
    xLS: string;
  begin

      try
        DoAddLine_UFPP_N_( //aIK_LS_UBP,
                             xNode_UFPP_N,
                            // 'UFPP_N',
                             INTTOSTR( xIndexUFPP_N + 1));
        except
          ExceptionLog( 'Сбой DoAddLine_FT_5_3_');
      end;

  end;
  *)
  //----------------------------------------------------------------------------
  {~DoAddLine_UFPP_N_
    добавление строки в эд 215го класса по блоку UFPP_N_N или UFPP_N в aNodeUFPP_N
    с названием в aNodeUFPP_N_Name (строка UFPP_N или UFPP_N_N) и номером строки
    в файле aNodeUFPP_N_Index.}
  procedure DoAddLine_UFPP_N_( //aLS: string;
                                 aNodeUFPP_N: Variant;
                               //  aNodeUFPP_N_Name: string;
                                 aNodeUFPP_N_Index: string);
  var
    s: string;
    xESTIMATE_ID: string;
    xUF_Line_Is_UFPP_N: boolean;
//    xLS: string;
    xUF_Line_SumPP: string;
//    xLS_Search_Type: string;
    xPurpgrID: string;
    xKBK: string;
    xExp: Variant;
    xKFSR_CODE: string;
    xKVR_CODE: string;
    xKESR_CODE: string;
    xKCSR_CODE: string;
    xKADMR_CODE: string;
    xOrgXml: Variant;
    xLSXml: Variant;
    xOrgID: string;
    xLS: string;
    xKADMD_CODE: string;
    xKD_CODE: string;
    xKESD_CODE: string;
    xRECEIVER_ID: string;
    xInc: Variant;
    xKADMI_CODE: string;
    xKI_CODE: string;
    xKESI_CODE: string;
    xSrc: Variant;
//    xFoundAcount: integer;
    xFillLinebyFile: boolean;
    xLineError: boolean;
    xRECIPIENT_ID: string;
//    xUFPP_INN_PP: string;
//    xFlag: boolean;
//    xEstimateLS: string;


(*
    function DoSearchLS_ForLine10_: boolean;
    begin
    
        try
          if (xLsXML.documentElement.childNodes.length <> 1)
            then Result := FALSE
            else begin
              xLsXML := xLsXML.documentElement.childNodes.item[ 0];
              // описание орг владельца счета
              xOrgID := GetNodeAttributeEx( xLsXML, 'ORG_ID');
              xOrgXML := QueryXml( 'select * from org where id=?', [ xOrgID]);
              if (xOrgXML.documentElement.childNodes.length <> 1)
                then Result := FALSE
                else begin
                  Result := TRUE;
                  xOrgXML := xOrgXML.documentElement.childNodes.item[ 0];
                end;
            end;
          except
            ExceptionProc( 'DoSearchLS_ForLine10_');
        end;
    
    end;
  *)
  (*
    function DoSearchOrg10_: boolean;
    begin

        try
          xSQL := ' from orgaccount oa'
                  // орг. владелец счета
                 +' join org o on o.id=oa.org_id'
{
                  // галка актуальности орг
                 +' Join Contractor C on C.Org_Id = O.Id'
                 +' Join Budget B on B.Org_Id = C.Inspector_Id'
}
                  // проверка номера счета
                 +' where oa.account_number=?'
                  // тип счета 5
                 +' and OA.ORGACCTYPE_ID=5'
 //                +' and b.id=?'
                 +' and oa.close_date is null'
                 +' and o.close_date is null';

          if (QueryField( ' select count( * ) N ' + xSQL,
                                [ aIK_LS_UBP{,
                                  aBudgetID}],
                                'N') <> '1')
            then Result := FALSE
            else begin
              xLsXML := QueryXml( 'select oa.* ' + xSQL,
                                [ aIK_LS_UBP,
                                  aBudgetID]);
//              Result := DoSearchLS_ForLine10_;
              if (xLsXML.documentElement.childNodes.length <> 1)
                then Result := FALSE
                else begin
                  xLsXML := xLsXML.documentElement.childNodes.item[ 0];
                  // описание орг владельца счета
                  xOrgID := GetNodeAttributeEx( xLsXML, 'ORG_ID');
                  xOrgXML := QueryXml( 'select * from org where id=?', [ xOrgID]);
                  if (xOrgXML.documentElement.childNodes.length <> 1)
                    then Result := FALSE
                    else begin
                      Result := TRUE;
                      xOrgXML := xOrgXML.documentElement.childNodes.item[ 0];
                    end;
                end;
            end;
{
              xOrgID := QueryXml( 'select oa.org_id ID ' + xSQL,
                                [ aIK_LS_UBP,
                                  aBudgetID],
                                'ID');
              xOrgXML := QueryXml( 'select * from org where id=?', [ xOrgID]);
              if (xOrgXML.documentElement.childNodes.length <> 1)
                then Result := FALSE
                else begin
                  Result := TRUE;
                  xOrgXML := xOrgXML.documentElement.childNodes.item[ 0];
                end;
            end;}
          except
            ExceptionProc( 'DoSearchOrg10_');
        end;

    end;
    *)

  begin

      try
        if (GetNodeAttributeEx( aNodeUFPP_N, 'TYPE_KBK') = '20') then begin
          WriteInfo( 'Строка по разделу UFPP_N доходного типа не создается.');
          EXIT;
        end;

        // определяем тип раздела: UFPP_N или UFPP_N_N
      //  xUF_Line_Is_UFPP_N := (aNodeUFPP_N_Name = 'UFPP_N');
        // формируем новую строку в ЭД, но еще не помещаем ее к строкам эд 215го
//        DoAddLineED215_;
        DoCreateLineED215_;
        xLineError := FALSE;

        // параметры из UFPP_N_N
        xKBK      := GetNodeAttributeEx( aNodeUFPP_N, 'KBK');
        xPurpgrID := GetPurposefullGraintIDByUF_(
                                GetNodeAttributeEx( aNodeUFPP_N, 'ADD_KLASS'),
                                FALSE,  // (aNodeUFPP_N_Name = 'UFPP_N_N'),
                                aBudgetID);
        // сумма из раздела
//        if xUF_Line_Is_UFPP_N
  //        then xUF_Line_SumPP := aNodeUFPP_N.GetAttribute( 'SUM_PP')
    //      else xUF_Line_SumPP := aNodeUFPP_N.GetAttribute( 'SUM');
        xUF_Line_SumPP := GetNodeAttributeEx( aNodeUFPP_N, 'SUM');

        // логируем операцию
        WriteLog( FORMAT( 'Формирование строки ЭД по блоку UFPP_N с порядковым номером %s...',
                          [ aNodeUFPP_N_Index]));

        // заполнение строки
        case aNodeUFPP_N.GetAttribute( 'TYPE_KBK') of
          //-----------------------------------------------------------------
          '10': begin
                  // кбк расходной строки
                  // exchange #3062
                  DoEncodeKBK_R(
                        xKBK,
                        xKADMR_CODE, xKFSR_CODE, xKCSR_CODE, xKVR_CODE, xKESR_CODE,
                        FALSE);
                        {
                  xKFSR_CODE  := COPY( xKBK, 4, 4);
                  xKCSR_CODE  := COPY( xKBK, 8, 7);
                  xKVR_CODE   := COPY( xKBK,15, 3);
                  xKESR_CODE  := COPY( xKBK,18, 3);
                  xKADMR_CODE := COPY( xKBK, 1, 3);
                  }

                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '1');
                  xDocLine.SetAttribute( 'KFSR_CODE', xKFSR_CODE);
                  xDocLine.SetAttribute( 'KCSR_CODE', xKCSR_CODE);
                  xDocLine.SetAttribute( 'KVR_CODE', xKVR_CODE);
                  // exchange #3062
                  //xDocLine.SetAttribute( 'KESR_CODE', xKESR_CODE);
                  xDocLine.SetAttribute( 'KADMR_CODE', xKADMR_CODE);
                  // код цели
                  xDocLine.SetAttribute( 'PURPOSEFULGRANT_ID', xPurpgrID);

                  // ищем строку UFPP
                  if NOT Do_Search_UFPP_ then begin
                    WriteInfo( 'Не найден блок UFPP для блока UFPP_N');
                    xDoc_Error := TRUE;
                    EXIT;
                  end;

                  // если поле суммы UFPP_N.SUM пустое,
                  // сумму берем из UFPP.SUM_PP
                  if (LENGTH( xUF_Line_SumPP) <= 0)
                    then xUF_Line_SumPP := GetNodeAttributeEx( xNode_UFPP, 'SUM_PP');

                  // в начале счет + организация поскольку это сказано
                  // делать при любом раскладе
                  if NOT DoSearchOrg10_( aBudgetID,
                                           aIK_LS_UBP,
                                           xOrgID,
                                           xOrgXML,
                                           xLsXml) then begin
                    WriteInfo(
                        FORMAT( 'Счет %s не подходит для поиска бланка расходов - строка в ЭД не создается.',
                                [ aIK_LS_UBP]));
//                        xDoc_Error := TRUE;
                    xLineError := TRUE;
                    EXIT;
                  end;

                  // exchange #3026
                  // ФТ-5.3: убрана проверка: UFPP.TYPE_KBK имеет значение «10»
                  // и код получения БР из уточняемой строки.
                  // теперь всегда БР определяется по exchange #2957
                  // ищем БР по exchange #2957
                  xESTIMATE_ID := GetEstimateId_2957_Ex( aBudgetId,
                                                         xOrgID,
                                                         aIK_LS_UBP,
                                                         xDocLine);
                  if (LENGTH( xESTIMATE_ID) <= 0) then begin
                    WriteInfo(
                        FORMAT( 'Не найден бланк расходов по счету %s - строка в ЭД не создается.',
                                [ aIK_LS_UBP]));
//                        xDoc_Error := TRUE;
                    xLineError := TRUE;
                    EXIT;
                  end;
                  // поиск бюджетополучателя и заполнение доп кодов из РЧБ
                  // а организация определяется по счету
                  FillLine10_ED_2953(  // для UFPP_N
                              aBudgetId,
                              xESTIMATE_ID,
                              GetNodeAttributeEx( xNode_UFPP, 'INN_PP'),
                              GetNodeAttributeEx( xNode_UFPP, 'KPP_PP'),
                              '',   // с любым незакрытым счетом у орг.
                              xDocLine,
                              xDocLine);
                  // бланк расходов
                  xDocLine.SetAttribute( 'ESTIMATE_ID', xESTIMATE_ID);


                  // заполнение орг и счета
                  DoFillOrgAndLS_( xOrgID, xOrgXml, aIK_LS_UBP, xLSXml,
                                   xDocLine);

                  // exchange #2953
                  // для строк UFPP_N Если значение UF.TYPE_KR = «1»,
                  // то значение поля «Сумма»,
                  // иначе значение поля «Сумма» строки с минусом.
                  // exchange #3011
                  // Если значение UF.TYPE_KR = «1», или UF.UFPP.TYPE_KBK=”20”
                  // то значение UFPP_N.SUM с минусом (либо UFPP.SUM_PP
                  // с минусом при пустом значении UFPP_N.SUM)
                  // иначе значение UFPP_N. SUM, если значение UFPP_N. SUM
                  // пустое, то присвоить значение UFPP. SUM_PP

                  if (   (xUF_TYPE_KR = '1')
                      OR (GetNodeAttributeEx( xNode_UFPP, 'TYPE_KBK') = '20'))
                    then xDocLine.SetAttribute(
                                  'AMOUNT',
                                  FORMAT( '%.2f',
                                          [ 0 - StrToCurrDef(
                                                  xUF_Line_SumPP,
                                                  0)]))
                    else xDocLine.SetAttribute(
                                  'AMOUNT',
                                  FORMAT( '%.2f',
                                          [ StrToCurrDef(
                                                  xUF_Line_SumPP,
                                                  0)]));
                    // передано - заполнить нулем, иначе на ацк-ф
                    // могут быть проблемы привставки строк
                    xDocLine.SetAttribute( 'PASS_AMT', '0.00');


                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                  // НПА - Не заполнять
                  // Авансовый платеж - Выключен
                  // Выставленный счет - Не заполнять
                  // Денежное обязательство - Не заполнять
                  // Бюджетное обязательство - Не заполнять
                  // Расходное обязательство - Не заполнять
                end;
          //-----------------------------------------------------------------
          // доходная строка не создается
(*
          '20': begin
                  xKADMD_CODE := COPY( xKBK, 1, 3);
                  xKD_CODE    := COPY( xKBK, 4,14);
                  xKESD_CODE  := COPY( xKBK,18, 3);

                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '2');
                  xDocLine.SetAttribute( 'KADMD_CODE', xKADMD_CODE);
                  xDocLine.SetAttribute( 'KD_CODE', xKD_CODE);
                  xDocLine.SetAttribute( 'KESD_CODE', xKESD_CODE);
                  // код цели
                  xDocLine.SetAttribute( 'PURPOSEFULGRANTD_ID', xPurpgrID);

                  // ищем в ДЧБ без получателя
                  if NOT QueryInc_( aBudgetID, xDocLine, xInc) then begin
                    // заполнение строки UFPP_N по файлу
                    // если в дчб не нашли, то орг, счет, получатель,
                    // плательщик, территория не заполнять.
                    // поэтому независимо от того, нашли ли получателя для
                    // поиска в дчб или нет - чистим ид.получателя.
                    // получатель= "не указана"
                    xDocLine.SetAttribute( 'RECEIVER_ID', '0');
                    // КВФО
                    xDocLine.SetAttribute( 'FSD_ID', '0');
                    // exchange #2874
                    // нулевые доп коды нужно формировать с учето маски
                    // Доп.КД
                    xDocLine.SetAttribute(
                              'KDD_CODE',
                              FormatKbk( 'KDD', '0', aBudgetID));//, '000');
                    // тип дохода заполнять значением «Не указано»,
                    // если включен системный параметр Сервис – Системные
                    // параметры – Доходы – Заполнять тип дохода значением
                    // «Не указано»,
                    // иначе по-умолчанию значением «Доходы».
                    if (SysParam_Type_not_defined_by_default = '1')
                      then xDocLine.SetAttribute( 'KDT_CODE', '0')
                      else xDocLine.SetAttribute( 'KDT_CODE', '1');
                    // плательщик, территория - не заполняются
                  end else begin
                    // заполнение строки по ДЧБ
                    // КВФО
                    xDocLine.SetAttribute( 'FSD_ID',
                                            xInc.GetAttribute( 'FSD_ID'));
                    // Доп.КД
                    xDocLine.SetAttribute( 'KDD_CODE',
                                            xInc.GetAttribute( 'KDD_CODE'));
                    // тип дохода
                    xDocLine.SetAttribute( 'KDT_CODE',
                                            xInc.GetAttribute( 'KDT_CODE'));
                    // плательщик
                    xDocLine.SetAttribute( 'PAYER_ID',
                                            xInc.GetAttribute( 'PAYER_ID'));
                    // территория (блок плательщик)
                    xDocLine.SetAttribute( 'TERRITORY_ID',
                                            xInc.GetAttribute( 'TERRITORY_ID'));
                    // получателя берем из ДЧБ
                    xRECEIVER_ID := xInc.GetAttribute( 'RECEIVER_ID');
                    // только если получаетль <> не указан
                    if ( xRECEIVER_ID <> '0') then
                      // описание орг. по получателю
                      if (QueryOrg20_By_Receiver_( xRECEIVER_ID, 'count( * )') = '1')
                        then begin
                          xOrgID := QueryOrg20_By_Receiver_( xRECEIVER_ID, 'r.org_id');
                          xOrgXml := QueryOrg_( xOrgID);
                          // лицевой счет
                          QueryLS_20_( xOrgID, xLS, xLSXml);
                          // заполнение орг и счета
                          DoFillOrgAndLS_( xOrgID, xOrgXml, xLS, xLSXml);
                        end;

                  // сумма
                  // Зачислено - заполнять 0.00
                  xDocLine.SetAttribute( 'AMOUNT', '0.00');
                  // передано - Значение UFPP_N.SUM_PP
                  xDocLine.SetAttribute( 'PASS_AMT', xUF_Line_SumPP);

                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                end;
                *)
          //-----------------------------------------------------------------
          '31','32': begin
                  // exchange #3062
                  DoEncodeKBK_I( xKBK, xKADMI_CODE, xKI_CODE, xKESI_CODE, FALSE);
                  {
                  xKADMI_CODE := COPY( xKBK, 1, 3);
                  xKI_CODE    := COPY( xKBK, 4,14);
                  xKESI_CODE  := COPY( xKBK,18, 3);}

                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '3');
                  xDocLine.SetAttribute( 'KADMI_CODE', xKADMI_CODE);
                  xDocLine.SetAttribute( 'KI_CODE', xKI_CODE);
                  // exchange #3062
                  //xDocLine.SetAttribute( 'KESI_CODE',xKESI_CODE );
                  // код цели
                  xDocLine.SetAttribute( 'PURPOSEFULGRANTI_ID', xPurpgrID);

                  // ищем строку в ИЧБ
                  if NOT QuerySrc_( aBudgetID, xDocLine, xSrc) then begin
                    // заполнение строки по UFPP_N_N
                    // КВФО
                    xDocLine.SetAttribute( 'FSI_ID', '0');
                    // exchange #2874
                    // нулевые доп коды нужно формировать с учето маски
                    // Доп.КД
                    xDocLine.SetAttribute(
                              'KDI_CODE',
                              FormatKbk( 'KDI', '0', aBudgetID));//, '000');
                    // контрагент - не заполняется
                    xDocLine.SetAttribute( 'COUNTERAGENT_ID', '');
                  end else begin
                    // заполнение строки по ДЧБ
                    // КВФО
                    xDocLine.SetAttribute( 'FSI_ID',
                                            xSrc.GetAttribute( 'FSI_ID'));
                    // Доп.КД
                    xDocLine.SetAttribute( 'KDI_CODE',
                                            xSrc.GetAttribute( 'KDI_CODE'));
                    // exchange #3111 - косгу из дчб
                    xDocLine.SetAttribute( 'KESI_CODE',
                                            xSrc.GetAttribute( 'KESI_CODE'));
                    // контрагент
                    xDocLine.SetAttribute( 'COUNTERAGENT_ID',
                                            xSrc.GetAttribute( 'COUNTERAGENT_ID'));
                  end;

                  // сумма
                  // передано - заполнять 0.00
                  xDocLine.SetAttribute( 'PASS_AMT', '0.00');

                  // exchange #3011
                  // ищем строку UFPP всегда, а не только когда UFPP_N.SUM
                  // не заполнено.
                  if NOT Do_Search_UFPP_ then begin
                    WriteInfo( 'Не найден блок UFPP для блока UFPP_N по источникам');
                    xDoc_Error := TRUE;
                    EXIT;
                  end;

                  // exchange #2991
                  // Зачислено - Значение UFPP_N.SUM_PP
                  // если поле суммы не заполнено, ищем строку UFPP
                  if (LENGTH( xUF_Line_SumPP) <= 0)
                    then xUF_Line_SumPP := GetNodeAttributeEx( xNode_UFPP, 'SUM_PP');
                  // exchange #3011
                  // Если значение UF.TYPE_KR = «1», или UF.UFPP.TYPE_KBK=”20”
                  // то значение UFPP_N.SUM с минусом (либо UFPP.SUM_PP
                  // с минусом при пустом значении UFPP_N.SUM)
                  // иначе значение UFPP_N. SUM, если значение UFPP_N. SUM
                  // пустое, то присвоить значение UFPP. SUM_PP
                  if (   (xUF_TYPE_KR = '1')
                      OR (GetNodeAttributeEx( xNode_UFPP, 'TYPE_KBK') = '20'))
                    then xDocLine.SetAttribute(
                                    'AMOUNT',
                                    FORMAT( '%.2f',
                                            [ 0 - StrToCurrDef(
                                                    xUF_Line_SumPP,
                                                    0)]))
                    else xDocLine.SetAttribute(
                                    'AMOUNT',
                                    FORMAT( '%.2f',
                                            [ StrToCurrDef(
                                                    xUF_Line_SumPP,
                                                    0)]));


                  // фо/гл.администратор
                  if (QueryOrg31_( aBudgetID, aIK_LS_UBP, 'count ( * )') = '1')
                    then begin
                      xOrgID := QueryOrg31_( aBudgetID, aIK_LS_UBP, 'o.ID');
                      // описание орг.
                      xOrgXml := QueryOrg_( xOrgID);
                      // лицевой счет - с любым типом счета
                      QueryLS_( xOrgID, aIK_LS_UBP, '', xLSXml);
                      // заполнение орг и счета
                      DoFillOrgAndLS_( xOrgID, xOrgXml, aIK_LS_UBP, xLSXml,
                                     xDocLine);
                    end;

                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                end;
        end;//case//

        // поля: Основание, Наименование, Номер, Дата
        // по UFPP_N не заполняются
        //DoFillLineFromUFLine_( aNodeUFPP_N);

        // если ошибок при формировании строки нет - добавляем сформированную
        // строку в список строк эд 215го
        if NOT xLineError
          then DoAddLineED215_( xDocLine);
        except
          ExceptionLog( 'Сбой DoAddLine_UFPP_N_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~DoFT_5_3_
    exchange #2954
    формирование нескольких строк в ЭД по блокам UFPP_N, которые соответствуют
    текущему блоку UFPP (с номером UFPP.LINE_NOM = xUFPP_LINE_NOM)}
  procedure DoFT_5_3_;
  begin

      try
        for xIndexUFPP_N := 0 to xUFPP_N.childNodes.length - 1 do begin
          xNode_UFPP_N := xUFPP_N.childNodes.item[ xIndexUFPP_N];
          if NOT IsBadLine_( xNode_UFPP_N) then
            if (xNode_UFPP_N.GetAttribute( 'LINE_NOM') = xUFPP_LINE_NOM)
              then begin

//                DoAddLine_FT_5_3_;
                DoAddLine_UFPP_N_( //aIK_LS_UBP,
                             xNode_UFPP_N,
                            // 'UFPP_N',
                             INTTOSTR( xIndexUFPP_N + 1));
              end;
        end;//for//
        except
          ExceptionProc( 'DoFT_5_3_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~Do_FT_5_1_
    вызывается, если найдены строки эд (в переменной xED) для класса
    ЭД в переменной xED_Class по разделу UFPP.
    здесь требуется копировать строки из найденного ЭД в новый эд.}
  procedure Do_FT_5_1_;
  var
    j: integer;
    xEDLine: variant;
//    xLS: string;
    xOrgXml: Variant;
    xLSXml: Variant;
    xOrgID: string;
    xRECEIVER_ID: string;
    xAccount: string;

    {~CopyAttrEDLine_
      копирование атрибута aAttr из строки xEDLine найденного
      эд класса xED_Class в строку эл 215го класса xDocLine}
    procedure CopyAttrEDLine_( aAttr: string);
    begin

        try
          xDocLine.SetAttribute( aAttr, xEDLine.GetAttribute( aAttr));
          except
            ExceptionLog( 'Сбой CopyAttrEDLine_');
        end;

    end;

    {~CopyAttrEDLineTo_
      копирование атрибута aAttrFrom из строки xEDLine найденного
      эд класса xED_Class в поле aAttrTo строки эл 215го класса xDocLine}
    procedure CopyAttrEDLineTo_( aAttrTo, aAttrFrom: string);
    begin

        try
          xDocLine.SetAttribute( aAttrTo, xEDLine.GetAttribute( aAttrFrom));
          except
            ExceptionLog( 'Сбой CopyAttrEDLineTo_');
        end;

    end;

    {~CopyAttrEDLineTo_
      копирование атрибута aAttrFrom из шапки эд aFromED класса xED_Class
      в поле aAttrTo строки эл 215го класса xDocLine}
    procedure CopyAttrEDLineFrom_( aAttrTo: string;
                                   aFromED: Variant;
                                   aAttrFrom: string);
    begin

        try
          xDocLine.SetAttribute( aAttrTo, aFromED.GetAttribute( aAttrFrom));
          except
            ExceptionLog( 'Сбой CopyAttrEDLineFrom_');
        end;

    end;


    {~CopyLineED215_
      копирование орг+счет из строки эд 215го}
    procedure CopyLineED215_;
    begin

        try
          // если берем строки из эд 215го, то там все поля аналогичны строке
          // в формируемом эд, поэтому поля организации заполняем сразу
          if (xED_Class in ['215d','215i','215r']) then begin
            // орг+счет
            CopyAttrEDLine_( 'ORG_ID');
            CopyAttrEDLine_( 'ORG_TAXCODE');
            CopyAttrEDLine_( 'ORG_KPP');
            CopyAttrEDLine_( 'ORG_NAME');
            // лицевой счет
            CopyAttrEDLine_( 'ORGACCOUNT_ID');
            CopyAttrEDLine_( 'ORG_ACCOUNT');
            // ТОФК
            CopyAttrEDLine_( 'ORG_OFK_NAME');
            // УФК из счета
            CopyAttrEDLine_( 'ORG_UFK_NAME');
            // Счет УФК
            CopyAttrEDLine_( 'ORG_UFK_ACC_ID');
            // Счет УФК
            CopyAttrEDLine_( 'ORG_UFK_ACCOUNT');
            // БИК
            CopyAttrEDLine_( 'ORG_BIC');
            // БАНК
            CopyAttrEDLine_( 'ORG_B_NAME');
          end;
          except
            ExceptionLog( 'Сбой CopyLineED215_');
        end;

    end;

    {~FillLine10_IK_LS_UBP_
      заполнение описания счета IK.LS_UBP в строке расходов }
    procedure FillLine10_IK_LS_UBP_;
    begin

        try
          // лицевой счет
//          xDocLine.SetAttribute( 'ORGACCOUNT_ID', xIK_LS_UBP_ID);
          xDocLine.SetAttribute( 'ORG_ACCOUNT', aIK_LS_UBP);
          except
            ExceptionProc( 'FillLine10_IK_LS_UBP_');
        end;

    end;


    {~QueryLS_D_
      Указывается счет для организации-получателя (aOrgID)
      типа 5 с признаком бюджетный,
      распорядительный организации, если организация имеет  роль «Финороган»,
      либо лицевой счет типа 8, если организация имеет роль
      «Администратор доходов» либо «Главный администратор доходов»

      Если Организация-получатель (aOrgID)
      имеет значение «Не указана», то не заполнять}
    function QueryLS_D_( aOrgID: string; var aLSXml: Variant): boolean;
    var
      xLSXml: Variant;
    begin
    
        try
          if (LENGTH( aOrgID) <= 0)
            then aLSXml := NULL
            else begin
              xLSXml := QueryXml(  'select a.* from orgaccount a'
                                  +' where a.org_id=?'
                                  +' and ((a.orgacctype_id=5'
                                  +'   and a.BUDGET_FLAG = 1'
                                  +'   and a.DISTRIBUTIVE_FLAG = 1'
                                  +'   and exists( select r.* from orgroles r'
                                  +'     where r.org_id=a.org_id'
                                  +'      and r.orgrole_id=4))'
                                  +' or (a.orgacctype_id=8'
                                  +'   and a.BUDGET_FLAG = 1'
                                  +'   and a.DISTRIBUTIVE_FLAG = 1'
                                  +'   and exists( select r.* from orgroles r'
                                  +'     where r.org_id=a.org_id'
                                  +'       and r.orgrole_id in (9,13))))',
                                   [ aOrgID]);
              Result := (xLSXml.documentElement.childNodes.Length = 1);
              if Result
                then aLSXml := xLSXml.documentElement.childNodes.item[ 0]
                else aLSXml := NULL;
            end;

          except
            ExceptionProc( 'QueryLS_D_');
        end;
    
    end;

  begin

      try
        WriteLog( FORMAT( 'Формируется строка по разделу UFPP с порядковым номером %s:',
                        [ INTTOSTR( xIndexUFPP + 1)]));

        // заполнение строк из эд
        case xED_Class of
          // exchange #2930 - добавлена загрузка стрки из эд 24го класса
          '11r','5r','215r','24r','25r':
                for j := 0 to xED.childNodes.length - 1 do begin
                  xEDLine := xED.childNodes.item[ j];

                  // формируем новую строку в ЭД
                  DoAddLineED215_;
                  // копируем атрибуты строки расходов

                  // сумма.
                  // по фт-5.1 для расходной строки сумма подставляется с
                  // отрицательным знаком
                  // exchange #2953
                  // Если значение UF.TYPE_KR = «1», то значение поля «Сумма»,
                  // иначе значение поля «Сумма» строки с минусом.
                  if (xUF_TYPE_KR = '1')
                    then xDocLine.SetAttribute(
                                  'AMOUNT',
                                  FORMAT( '%.2f',
                                          [ StrToCurrDef(
                                                  xEDLine.GetAttribute( 'AMOUNT'),
                                                  0)]))
                    else xDocLine.SetAttribute(
                                  'AMOUNT',
                                  FORMAT( '%.2f',
                                          [ 0 - StrToCurrDef(
                                                  xEDLine.GetAttribute( 'AMOUNT'),
                                                  0)]));

                  // копирование орг+счет из строки эд 215го
                  CopyLineED215_;
                  // бюджетополучатель
                  CopyAttrEDLine_( 'RECIPIENT_ID');
                  // ДопФК
                  CopyAttrEDLine_( 'KDF_CODE');
                  // Доп.ЭК
                  CopyAttrEDLine_( 'KDE_CODE');
                  // Доп.КР
                  CopyAttrEDLine_( 'KDR_CODE');
                  // КВФО
                  CopyAttrEDLine_( 'FSR_ID');
                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                  case xED_Class of
                    '215r': begin
                              // бланк расходов
                              CopyAttrEDLine_( 'ESTIMATE_ID');
                              // НПА
                              CopyAttrEDLine_( 'LAWACT_ID');
                              // Авансовый платеж + Выставленный счет
                              CopyAttrEDLine_( 'ADVPAYMENT');
                              // Денежное обязательство
                              CopyAttrEDLine_( 'CONTRACT_ID');
//                              CopyAttrEDLine_( 'CONTRACT_DATA');
                              // Бюджетное обязательство
                              CopyAttrEDLine_( 'BUDGORDER_ID');
//                              CopyAttrEDLine_( 'BO_DATA');
                              // Расходное обязательство
                              CopyAttrEDLine_( 'DIRECTION_ID');
                            end;

                    '11r': begin
                              // орг+счет из блока плательщика (ГРБС) шапки ЭД
                              CopyAttrEDLineFrom_( 'ORG_ID', xED11, 'ORG_ID');
                              CopyAttrEDLineFrom_( 'ORG_TAXCODE', xED11, 'ORG_TAXCODE');
                              CopyAttrEDLineFrom_( 'ORG_KPP', xED11, 'ORG_KPP');
                              CopyAttrEDLineFrom_( 'ORG_NAME', xED11, 'ORG_NAME');
                              // лицевой счет
                              //FillLine10_IK_LS_UBP_;
                              CopyAttrEDLineFrom_( 'ORGACCOUNT_ID', xED11, 'ORGACCOUNT_ID');
                              CopyAttrEDLineFrom_( 'ORG_ACCOUNT', xED11, 'ORG_ACCOUNT');
                              // ТОФК
                              CopyAttrEDLineFrom_( 'ORG_OFK_NAME', xED11, 'ORG_OFK_NAME');
                              // УФК из счета
                              CopyAttrEDLineFrom_( 'ORG_UFK_NAME', xED11, 'ORG_UFK_NAME');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACC_ID', xED11, 'ORG_UFK_ACC_ID');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACCOUNT', xED11, 'ORG_UFK_ACCOUNT');
                              // БИК
                              CopyAttrEDLineFrom_( 'ORG_BIC', xED11, 'ORG_BIC');
                              // БАНК
                              CopyAttrEDLineFrom_( 'ORG_B_NAME', xED11, 'ORG_B_NAME');

                              // бланк расходов - из шапки ЭД 11го
                              CopyAttrEDLineFrom_( 'ESTIMATE_ID', xED11, 'ESTIMATE_ID');
                              // НПА
                              CopyAttrEDLine_( 'LAWACT_ID');
                              // Авансовый платеж - из шапки эд 11го
                              CopyAttrEDLineFrom_( 'ADVPAYMENT', xED11, 'ADVPAYMENT');
                              // Денежное обязательство
                              CopyAttrEDLine_( 'CONTRACT_ID');
                              //CopyAttrEDLine_( 'CONTRACT_DATA');
                              // Бюджетное обязательство
                              CopyAttrEDLineTo_( 'BUDGORDER_ID', 'BO_ID');
                              //CopyAttrEDLine_( 'BO_DATA');
                              // Расходное обязательство
                              CopyAttrEDLine_( 'DIRECTION_ID');
                            end;

                    '5r': begin
                              // орг+счет из блока плательщика шапки ЭД
                              CopyAttrEDLineFrom_( 'ORG_ID', xED5, 'PAY_ID');
                              CopyAttrEDLineFrom_( 'ORG_TAXCODE', xED5, 'PAY_TAXCODE');
                              CopyAttrEDLineFrom_( 'ORG_KPP', xED5, 'PAY_KPP');
                              CopyAttrEDLineFrom_( 'ORG_NAME', xED5, 'PAY_NAME');
                              // лицевой счет
                              //FillLine10_IK_LS_UBP_;
                              CopyAttrEDLineFrom_( 'ORGACCOUNT_ID', xED5, 'PAY_ACC_ID');
                              CopyAttrEDLineFrom_( 'ORG_ACCOUNT', xED5, 'PAY_ACCOUNT');
                              // ТОФК
                              CopyAttrEDLineFrom_( 'ORG_OFK_NAME', xED5, 'PAY_OFK_NAME');
                              // УФК из счета
                              CopyAttrEDLineFrom_( 'ORG_UFK_NAME', xED5, 'PAY_UFK_NAME');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACC_ID', xED5, 'PAY_UFK_ACC_ID');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACCOUNT', xED5, 'PAY_UFK_ACCOUNT');
                              // БИК
                              CopyAttrEDLineFrom_( 'ORG_BIC', xED5, 'PAY_BIC');
                              // БАНК
                              CopyAttrEDLineFrom_( 'ORG_B_NAME', xED5, 'PAY_B_NAME');

                              // бланк расходов
                              CopyAttrEDLine_( 'ESTIMATE_ID');
                              // для эд 5го класса прочие поля не заполняются.
                            end;

                    // exchange #2930 - заполняем строку из эд 24го расходной строки
                    // здесь все тоже самое что и у 5го, только поля начинаются
                    // с префикса REC и эд 24й.
                    '24r': begin
                              // орг+счет из блока получатель шапки ЭД
                              CopyAttrEDLineFrom_( 'ORG_ID', xED24, 'REC_ID');
                              CopyAttrEDLineFrom_( 'ORG_TAXCODE', xED24, 'REC_TAXCODE');
                              CopyAttrEDLineFrom_( 'ORG_KPP', xED24, 'REC_KPP');
                              CopyAttrEDLineFrom_( 'ORG_NAME', xED24, 'REC_NAME');
                              // лицевой счет
                              //FillLine10_IK_LS_UBP_;
                              CopyAttrEDLineFrom_( 'ORGACCOUNT_ID', xED24, 'REC_ACC_ID');
                              CopyAttrEDLineFrom_( 'ORG_ACCOUNT', xED24, 'REC_ACCOUNT');
                              // ТОФК
                              CopyAttrEDLineFrom_( 'ORG_OFK_NAME', xED24, 'REC_OFK_NAME');
                              // УФК из счета
                              CopyAttrEDLineFrom_( 'ORG_UFK_NAME', xED24, 'REC_UFK_NAME');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACC_ID', xED24, 'REC_UFK_ACC_ID');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACCOUNT', xED24, 'REC_UFK_ACCOUNT');
                              // БИК
                              CopyAttrEDLineFrom_( 'ORG_BIC', xED24, 'REC_BIC');
                              // БАНК
                              CopyAttrEDLineFrom_( 'ORG_B_NAME', xED24, 'REC_B_NAME');

                              // бланк расходов
                              CopyAttrEDLine_( 'ESTIMATE_ID');
                              // для эд 24го класса прочие поля не заполняются.
                            end;

                    // exchange #2953
                    // добавлен эд 25й
                    '25r': begin
                              // лицевой счет
                              //FillLine10_IK_LS_UBP_;
                              // бланк расходов
                              CopyAttrEDLine_( 'ESTIMATE_ID');
                              // НПА
                              CopyAttrEDLine_( 'LAWACT_ID');
                              // Авансовый платеж + Выставленный счет
                              CopyAttrEDLine_( 'ADVPAYMENT');
                              // Денежное обязательство
                              CopyAttrEDLine_( 'CONTRACT_ID');
                              //CopyAttrEDLine_( 'CONTRACT_DATA');
                              // Бюджетное обязательство
                              CopyAttrEDLine_( 'BUDGORDER_ID');
                              //CopyAttrEDLine_( 'BO_DATA');
                              // Расходное обязательство
                              CopyAttrEDLine_( 'DIRECTION_ID');

                              // орг из оператора бланка расходов
                              xOrgID := QueryField( ' select e.org_id ID from estimate e'
                                                   +' where e.id=?',
                                                    [ GetNodeAttributeEx( xEDLine,
                                                                          'ESTIMATE_ID')],
                                                    'ID');
                              xOrgXml := QueryOrg_( xOrgID);
                              // по ID из ЭД
                              DoSearchLS_by_ID_(
                                    GetNodeAttributeEx( xEDLine, 'ORGACCOUNT_ID'),
                                    xAccount,
                                    xLSXml);
                              // описание орг + счет
                              DoFillOrgAndLS_( xOrgID,
                                               xOrgXml,
                                               xAccount,
                                               xLSXml,
                                               xDocLine);

                            end;
                  end;//case//
                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '1');
                  CopyAttrEDLine_( 'KFSR_CODE');
                  CopyAttrEDLine_( 'KCSR_CODE');
                  CopyAttrEDLine_( 'KVR_CODE');
                  CopyAttrEDLine_( 'KESR_CODE');
                  CopyAttrEDLine_( 'KADMR_CODE');
                  // КВФО
                  CopyAttrEDLine_( 'FSR_ID');
                  // код цели
                  CopyAttrEDLine_( 'PURPOSEFULGRANT_ID');
                  // доп коды
                  CopyAttrEDLine_( 'KDF_CODE');
                  CopyAttrEDLine_( 'KDE_CODE');
                  CopyAttrEDLine_( 'KDR_CODE');
                  // поля: Основание, Наименование, Номер, Дата из UFPP
                  DoFillLineFromUFLine_( xNode_UFPP);
                  // копируем в строку UFPP поля из сформированной строки
                  // это нужно для заполнения полей по ФТ-5.3
                  xNode_UFPP.SetAttribute( 'ESTIMATE_ID',
                                           xEDLine.GetAttribute( 'ESTIMATE_ID'));
                  xNode_UFPP.SetAttribute( 'RECIPIENT_ID',
                                           xEDLine.GetAttribute( 'RECIPIENT_ID'));


                end;//for//

          '215d','24d','43d','19d':
                for j := 0 to xED.childNodes.length - 1 do begin
                  xEDLine := xED.childNodes.item[ j];

                  // формируем новую строку в ЭД
                  DoAddLineED215_;
                  // копируем атрибуты строки расходов

                  // сумма зачисленно - из передано только для строк эд 215го
                  // класса, для остальных - нулями
                  if (xED_Class = '215d')
                    then CopyAttrEDLineTo_( 'AMOUNT', 'PASS_AMT')
                    else xDocLine.SetAttribute( 'AMOUNT', '0.00');

                  // Передано - Заполнять значением поля:
                  // «Зачислено» строки ЭД класса 215;
                  // «Сумма» строки расшифровки ЭД класса 24 или 43.
                  CopyAttrEDLineTo_( 'PASS_AMT', 'AMOUNT');

                  // копирование орг+счет из строки эд 215го
                  CopyLineED215_;

                  // получатель
                  CopyAttrEDLine_( 'RECEIVER_ID');

                  // для 43го и 24го организация и счет заполняются из
                  // организации получателя.
                  // если получатель указан, из получателя берем организацию,
                  // и для этой орг. ищем счет
                  if (xED_Class <> '215d') then begin
                    xRECEIVER_ID := xDocLine.GetAttribute( 'RECEIVER_ID');

                    if (LENGTH( xRECEIVER_ID) > 0) then begin
                      xOrgXml := QueryOrg_(
                                    QueryField( ' select r.org_id ID'
                                               +' from receiver r where r.id=?',
                                                [ xRECEIVER_ID],
                                                'ID'));
                      if NOT VarIsNULL( xOrgXml) then begin
                        xOrgID := xOrgXml.GetAttribute( 'ID');
                        // счет для организации-получателя aOrgID
                        if QueryLS_D_( xOrgID, xLSXml)
                          then xAccount := GetNodeAttributeEx( xLSXml,
                                                               'ACCOUNT_NUMBER')
                          else xAccount := '';
                        // заполнение орг и счета
                        DoFillOrgAndLS_( xOrgID, xOrgXml, xAccount, xLSXml,
                                     xDocLine);
                      end;
                    end;
                  end;

                  // КВФО
                  CopyAttrEDLine_( 'FSD_ID');
                  // Доп.КД
                  CopyAttrEDLine_( 'KDD_CODE');
                  // тип дохода
                  if (xED_Class <> '43d')
                    then CopyAttrEDLine_( 'KDT_CODE')
                    else
                      // тип дохода заполнять значением «Не указано»,
                      // если включен системный параметр Сервис – Системные
                      // параметры – Доходы – Заполнять тип дохода значением
                      // «Не указано»,
                      // иначе по-умолчанию значением «Доходы».
                      if (SysParam_Type_not_defined_by_default = '1')
                        then xDocLine.SetAttribute( 'KDT_CODE', '0')
                        else xDocLine.SetAttribute( 'KDT_CODE', '1');

                  // плательщик
                  CopyAttrEDLine_( 'PAYER_ID');
                  // территория
                  CopyAttrEDLine_( 'TERRITORY_ID');

                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '2');
                  CopyAttrEDLine_( 'KADMD_CODE');
                  CopyAttrEDLine_( 'KD_CODE');
                  CopyAttrEDLine_( 'KESD_CODE');
                  // код цели
                  // для разных классов, название поля отличается.
                  // для эд 43го класса, код цели в поле PURPOSEFULGRANT_ID.
                  if (xED_Class in ['43d', '19d'])
                    then CopyAttrEDLineTo_( 'PURPOSEFULGRANTD_ID',
                                            'PURPOSEFULGRANT_ID')
                    else CopyAttrEDLine_( 'PURPOSEFULGRANTD_ID');
                  // поля: Основание, Наименование, Номер, Дата из UFPP
                  DoFillLineFromUFLine_( xNode_UFPP);

                end;//for//

          '215i','118i','80i','5i','24i':
                for j := 0 to xED.childNodes.length - 1 do begin
                  xEDLine := xED.childNodes.item[ j];

                  // формируем новую строку в ЭД
                  DoAddLineED215_;
                  // копируем атрибуты строки расходов

                  // сумма зачисленно - из передано только для строк эд 215го
                  // класса, для остальных - нулями
                  if (xED_Class = '215i')
                    then CopyAttrEDLineTo_( 'AMOUNT', 'PASS_AMT')
                    else xDocLine.SetAttribute( 'AMOUNT', '0.00');

                  // Передано - Заполнять значением поля:
                  // «Зачислено» строки ЭД класса 215;
                  // «Сумма» строки расшифровки ЭД класса 118 или 80.
                  CopyAttrEDLineTo_( 'PASS_AMT', 'AMOUNT');

                  // копирование орг+счет из строки эд 215го
                  CopyLineED215_;

                  // КВФО
                  CopyAttrEDLine_( 'FSI_ID');
                  // Доп.КД
                  CopyAttrEDLine_( 'KDI_CODE');
                  // контрагент
                  CopyAttrEDLine_( 'COUNTERAGENT_ID');

                  case xED_Class of
                    '118i': begin
                              // плательщик из шапки эд
                              // орг+счет
                              CopyAttrEDLineFrom_( 'ORG_ID', xED118, 'PAY_ID');
                              CopyAttrEDLineFrom_( 'ORG_TAXCODE', xED118, 'PAY_TAXCODE');
                              CopyAttrEDLineFrom_( 'ORG_KPP', xED118, 'PAY_KPP');
                              CopyAttrEDLineFrom_( 'ORG_NAME', xED118, 'PAY_NAME');
                              // лицевой счет
                              CopyAttrEDLineFrom_( 'ORGACCOUNT_ID', xED118, 'PAY_ACC_ID');
                              CopyAttrEDLineFrom_( 'ORG_ACCOUNT', xED118, 'PAY_ACCOUNT');
                              // ТОФК
                              CopyAttrEDLineFrom_( 'ORG_OFK_NAME', xED118, 'PAY_OFK_NAME');
                              // УФК из счета
                              CopyAttrEDLineFrom_( 'ORG_UFK_NAME', xED118, 'PAY_UFK_NAME');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACC_ID', xED118, 'PAY_UFK_ACC_ID');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACCOUNT', xED118, 'PAY_UFK_ACCOUNT');
                              // БИК
                              CopyAttrEDLineFrom_( 'ORG_BIC', xED118, 'PAY_BIC');
                              // БАНК
                              CopyAttrEDLineFrom_( 'ORG_B_NAME', xED118, 'PAY_B_NAME');
                            end;
                    '5i': begin
                              // плательщик из шапки эд
                              // орг+счет
                              CopyAttrEDLineFrom_( 'ORG_ID', xED5, 'PAY_ID');
                              CopyAttrEDLineFrom_( 'ORG_TAXCODE', xED5, 'PAY_TAXCODE');
                              CopyAttrEDLineFrom_( 'ORG_KPP', xED5, 'PAY_KPP');
                              CopyAttrEDLineFrom_( 'ORG_NAME', xED5, 'PAY_NAME');
                              // лицевой счет
                              CopyAttrEDLineFrom_( 'ORGACCOUNT_ID', xED5, 'PAY_ACC_ID');
                              CopyAttrEDLineFrom_( 'ORG_ACCOUNT', xED5, 'PAY_ACCOUNT');
                              // ТОФК
                              CopyAttrEDLineFrom_( 'ORG_OFK_NAME', xED5, 'PAY_OFK_NAME');
                              // УФК из счета
                              CopyAttrEDLineFrom_( 'ORG_UFK_NAME', xED5, 'PAY_UFK_NAME');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACC_ID', xED5, 'PAY_UFK_ACC_ID');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACCOUNT', xED5, 'PAY_UFK_ACCOUNT');
                              // БИК
                              CopyAttrEDLineFrom_( 'ORG_BIC', xED5, 'PAY_BIC');
                              // БАНК
                              CopyAttrEDLineFrom_( 'ORG_B_NAME', xED5, 'PAY_B_NAME');
                            end;
                    '80i': begin
                              // администратор шапки эд 80
                              // орг+счет
                              CopyAttrEDLineFrom_( 'ORG_ID', xED80, 'ADMIN_ID');
                              CopyAttrEDLineFrom_( 'ORG_TAXCODE', xED80, 'ADMIN_TAXCODE');
                              CopyAttrEDLineFrom_( 'ORG_KPP', xED80, 'ADMIN_KPP');
                              CopyAttrEDLineFrom_( 'ORG_NAME', xED80, 'ADMIN_NAME');
                              // лицевой счет
                              CopyAttrEDLineFrom_( 'ORGACCOUNT_ID', xED80, 'ADMIN_ACCOUNT_ID');
                              CopyAttrEDLineFrom_( 'ORG_ACCOUNT', xED80, 'ADMIN_ACCOUNT');
                              // ТОФК
                              CopyAttrEDLineFrom_( 'ORG_OFK_NAME', xED80, 'ADMIN_OFK_NAME');
                              // УФК из счета
                              CopyAttrEDLineFrom_( 'ORG_UFK_NAME', xED80, 'ADMIN_UFK_NAME');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACC_ID', xED80, 'ADMIN_UFK_ACC_ID');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACCOUNT', xED80, 'ADMIN_UFK_ACCOUNT');
                              // БИК
                              CopyAttrEDLineFrom_( 'ORG_BIC', xED80, 'ADMIN_BIC');
                              // БАНК
                              CopyAttrEDLineFrom_( 'ORG_B_NAME', xED80, 'ADMIN_B_NAME');
                            end;
                    // exchange #2930
                    // добавлено заполнение строк из эд 24го класса
                    // аналогично эд 5го класса, только из блока получатель
                    '24i': begin
                              // орг+счет из блока получатель шапки ЭД
                              CopyAttrEDLineFrom_( 'ORG_ID', xED24, 'REC_ID');
                              CopyAttrEDLineFrom_( 'ORG_TAXCODE', xED24, 'REC_TAXCODE');
                              CopyAttrEDLineFrom_( 'ORG_KPP', xED24, 'REC_KPP');
                              CopyAttrEDLineFrom_( 'ORG_NAME', xED24, 'REC_NAME');
                              // лицевой счет
                              CopyAttrEDLineFrom_( 'ORGACCOUNT_ID', xED24, 'REC_ACC_ID');
                              CopyAttrEDLineFrom_( 'ORG_ACCOUNT', xED24, 'REC_ACCOUNT');
                              // ТОФК
                              CopyAttrEDLineFrom_( 'ORG_OFK_NAME', xED24, 'REC_OFK_NAME');
                              // УФК из счета
                              CopyAttrEDLineFrom_( 'ORG_UFK_NAME', xED24, 'REC_UFK_NAME');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACC_ID', xED24, 'REC_UFK_ACC_ID');
                              // Счет УФК
                              CopyAttrEDLineFrom_( 'ORG_UFK_ACCOUNT', xED24, 'REC_UFK_ACCOUNT');
                              // БИК
                              CopyAttrEDLineFrom_( 'ORG_BIC', xED24, 'REC_BIC');
                              // БАНК
                              CopyAttrEDLineFrom_( 'ORG_B_NAME', xED24, 'REC_B_NAME');
                            end;
                  end;//case//

                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '3');
                  CopyAttrEDLine_( 'KADMI_CODE');
                  CopyAttrEDLine_( 'KI_CODE');
                  CopyAttrEDLine_( 'KESI_CODE');

                  // код цели
                  // для эд 80го класса поле кода цели отличается от поля
                  // кода цели для 215го класса
                  if (xED_Class = '80i')
                    then  CopyAttrEDLineTo_( 'PURPOSEFULGRANTI_ID',
                                              'PURPOSEFULGRANT_ID')
                    else CopyAttrEDLine_( 'PURPOSEFULGRANTI_ID');

                  // поля: Основание, Наименование, Номер, Дата из UFPP
                  DoFillLineFromUFLine_( xNode_UFPP);

                end;//for//

          // проверка на случай, если чтонибудь забыли
          else raise( FORMAT( 'Не распознан класс %s.', [ xED_Class]));
        end;//case//
        except
          ExceptionLog( 'Сбой Do_FT_5_1_');
      end;

  end;
  //----------------------------------------------------------------------------
(*
  //----------------------------------------------------------------------------
  {~DoCreateQuery_
    создание эд 215го класса - создается xml }
  procedure DoCreateQuery_( var aQuery: TRunQuery);
  begin

      try
        // создаем объект запроса
        aQuery:= TRunQuery.Create;
        // создаем XML для разбора ответа на запрос
        xED := CreateOleObject('Microsoft.XmlDom');
        xED.appendChild( xED.createElement('DOCUMENT'));
        except
          ExceptionLog( 'Сбой DoCreateQuery_');
      end;

  end;
  *)
  //----------------------------------------------------------------------------
  //----------------------------------------------------------------------------
  {~Do_SearchDoc11_
    поиск ЗОР (ЭД 11го класса) ФТ-2.2.1 и ФТ-2.2.2}
  procedure Do_SearchDoc11_( aSubConditional: string;
                             aNom, aDate: string);

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField( ' select ' + aSubSQL
                          +' from budgorder b'
                          +' join ORGACCOUNT OA on OA.ID = B.ORGACCOUNT_ID'
                          +' where b.documentclass_id=11'
                          +' and b.dispstatus_id=10'
                          +' and ltrim(b.doc_number)=?'
                          +' and b.doc_date=?'
                          +' and b.budget_id=?'
                          +aSubConditional
                          +' and oa.account_number=?'
                          +' and b.DISPSTATUS_ID=10'  // ФТ-2.1
                          +' and exists ('
                          +' select * from budgorder bb'
                          +' join orgaccount oa on oa.id=bb.orgaccount_id'
                          +' where ((bb.title_id=b.id) or'
                          +' (bb.title_id is null and bb.id=b.id))'
                          +' and bb.KFSR_CODE = ?'
                          +' and bb.KCSR_CODE = ?'
                          +' and bb.KVR_CODE = ?'
                          // exchange #3062
//                          +' and bb.KESR_CODE = ?'
                          +' and bb.KADMR_CODE = ?'
                          +' and bb.PURPOSEFULGRANT_ID = ?)',
                           [ aNom,
                             StrToDate( aDate),
                             aBudgetId,
                             aIK_LS_UBP,
                             DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                             DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                             DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                             //COPY( xUFPP_KBK,18, 3),
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 'b.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(   ' select sum(bb.amount) S from budgorder bb'
                                +' where ((bb.title_id=?)'
                                +' or (bb.title_id is null and bb.id=?))'
                                +' and bb.KFSR_CODE = ?'
                                +' and bb.KCSR_CODE = ?'
                                +' and bb.KVR_CODE = ?'
                                // exchange #3062
//                                +' and bb.KESR_CODE = ?'
                                +' and bb.KADMR_CODE = ?'
                                +' and bb.PURPOSEFULGRANT_ID = ?',
                                 [ xID,
                                   xID,
                                   DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                                   DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                                   DoEncodeKBK_KVR(xUFPP_KBK , FALSE), //COPY( xUFPP_KBK,15, 3),
                                   //COPY( xUFPP_KBK,18, 3),
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from budgorder where id=?', [ xID]);
        xED_Class := '11r';
        xED := QueryXml(   ' select * from budgorder bb'
                          +' where ((bb.title_id=?)'
                          +' or (bb.title_id is null and bb.id=?))'
                          +' and bb.KFSR_CODE = ?'
                          +' and bb.KCSR_CODE = ?'
                          +' and bb.KVR_CODE = ?'
                          // exchange #3062
//                          +' and bb.KESR_CODE = ?'
                          +' and bb.KADMR_CODE = ?'
                          +' and bb.PURPOSEFULGRANT_ID = ?',
                           [ xID,
                             xID,
                             DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                             DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                             DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                             //COPY( xUFPP_KBK,18, 3),
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             xUFPP_PurposefullgrantID]);
        // загрузка эд 11го класа
        xED11 := QueryDoc_( 'budgorder', xID);
        except
          ExceptionLog( 'Сбой Do_SearchDoc11_');
      end;

  end;
  //----------------------------------------------------------------------------
  function Do_SearchDoc118_( aNom, aDate: string): string;

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField( ' select ' + aSubSQL
                          +' from srcrequest s'
                          +' where s.documentclass_id=118'
                          +' and s.dispstatus_id=10'
                          +' and ltrim(s.DOC_NUMBER) = ?'
                          +' and s.DOC_DATE = ?'
                          +' and s.budget_id=?'
                          +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                          +' and exists('
                          +' select * from srcrequest ss'
                          +' where ((ss.title_id=s.id)'
                          +' or (ss.title_id is null and ss.id=s.id))'
                          +' and ss.PAY_ACCOUNT=?'
                          +' and ss.KADMI_CODE = ?'
                          +' and ss.KI_CODE = ?'
                          // exchange #3062
//                          +' and ss.KESI_CODE = ?'
                          +' and ss.PURPOSEFULGRANTI_ID = ?)',
                           [ aNom,
                             StrToDate( aDate),
                             aBudgetId,
                             aIK_LS_UBP,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        Result := Query_( 'count( * ) N', 'N');
        if (Result <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(   ' select sum(ss.amount) S from srcrequest ss'
                                +' where ((ss.title_id=?)'
                                +' or (ss.title_id is null and ss.id=?))'
                                +' and ss.PAY_ACCOUNT=?'
                                +' and ss.KADMI_CODE = ?'
                                +' and ss.KI_CODE = ?'
                                // exchange #3062
//                                +' and ss.KESI_CODE = ?'
                                +' and ss.PURPOSEFULGRANTI_ID = ?',
                                 [ xID,
                                   xID,
                                   aIK_LS_UBP,
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                                   //COPY( xUFPP_KBK,18, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from srcrequest where id=?', [ xID]);
        xED_Class := '118i';
        xED := QueryXml( ' select * from srcrequest ss'
                        +' where ((ss.title_id=?)'
                        +' or (ss.title_id is null and ss.id=?))'
                        +' and ss.PAY_ACCOUNT=?'
                        +' and ss.KADMI_CODE = ?'
                        +' and ss.KI_CODE = ?'
                        // exchange #3062
//                        +' and ss.KESI_CODE = ?'
                        +' and ss.PURPOSEFULGRANTI_ID = ?',
                         [ xID,
                           xID,
                           aIK_LS_UBP,
                           DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                           DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                           //COPY( xUFPP_KBK,18, 3),
                           xUFPP_PurposefullgrantID]);
        // загрузка эд 118го класа
        xED118 := QueryDoc_( 'srcrequest', xID);
        except
          ExceptionLog( 'Сбой Do_SearchDoc118_');
      end;

  end;
  //----------------------------------------------------------------------------
  procedure Do_SearchDoc43_( aNom, aDate: string);

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField( ' select ' + aSubSQL
                          +' from incorder s'
                          +' where s.documentclass_id=43'
                          +' and s.dispstatus_id=10'
                          +' and ltrim(s.DOC_NUMBER) = ?'
                          +' and s.DOC_DATE = ?'
                          +' and s.budget_id=?'
                          +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                          +' and exists('
                          +' select * from incorder ss'
                          +' where ((ss.title_id=s.id)'
                          +' or (ss.title_id is null and ss.id=s.id))'
                          +' and ss.PAY_ACCOUNT=?'
                          +' and ss.KADMD_CODE = ?'
                          +' and ss.KD_CODE = ?'
                          // exchange #3062
//                          +' and ss.KESD_CODE = ?'
                          +' and ss.PURPOSEFULGRANT_ID = ?)',
                           [ aNom,
                             StrToDate( aDate),
                             aBudgetId,
                             aIK_LS_UBP,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(   ' select sum(ss.amount) S from incorder ss'
                                +' where ((ss.title_id=?)'
                                +' or (ss.title_id is null and ss.id=?))'
                                +' and ss.PAY_ACCOUNT=?'
                                +' and ss.KADMD_CODE = ?'
                                +' and ss.KD_CODE = ?'
                                // exchange #3062
//                                +' and ss.KESD_CODE = ?'
                                +' and ss.PURPOSEFULGRANT_ID = ?',
                                 [ xID,
                                   xID,
                                   aIK_LS_UBP,
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                                   //COPY( xUFPP_KBK,18, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from incorder where id=?', [ xID]);
        xED_Class := '43d';
        xED := QueryXml( ' select * from incorder ss'
                        +' where ((ss.title_id=?)'
                        +' or (ss.title_id is null and ss.id=?))'
                        +' and ss.PAY_ACCOUNT=?'
                        +' and ss.KADMD_CODE = ?'
                        +' and ss.KD_CODE = ?'
                        // exchange #3062
//                        +' and ss.KESD_CODE = ?'
                        +' and ss.PURPOSEFULGRANT_ID = ?',
                         [ xID,
                           xID,
                           aIK_LS_UBP,
                           DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                           DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                           //COPY( xUFPP_KBK,18, 3),
                           xUFPP_PurposefullgrantID]);
        except
          ExceptionLog( 'Сбой Do_SearchDoc43_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~Do_SearchDoc80_
    ФТ-2.2.2 И ФТ-2.2.5
    поиск эд 80го класса по xUFPP_NOM_ZR и xUFPP_DATE_ZR}
  procedure Do_SearchDoc80_;

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField( ' select ' + aSubSQL
                          +' from srcorder s'
                          +' where s.documentclass_id=80'
                          +' and s.dispstatus_id=10'
                          +' and ltrim(s.DOC_NUMBER) = ?'
                          +' and s.DOC_DATE = ?'
                          +' and s.budget_id=?'
                          +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                          +' and exists('
                          +' select * from srcorder ss'
                          +' where ((ss.title_id=s.id)'
                          +' or (ss.title_id is null and ss.id=s.id))'
                          +' and ss.admin_account=?'
                          +' and ss.KADMI_CODE = ?'
                          +' and ss.KI_CODE = ?'
                          // exchange #3062
//                          +' and ss.KESI_CODE = ?'
                          +' and ss.PURPOSEFULGRANT_ID = ?)',
                           [ xUFPP_NOM_ZR,
                             StrToDate( xUFPP_DATE_ZR),
                             aBudgetId,
                             aIK_LS_UBP,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(   ' select sum(ss.amount) S from srcorder ss'
                                +' where ((ss.title_id=?)'
                                +' or (ss.title_id is null and ss.id=?))'
                                +' and ss.admin_account=?'
                                +' and ss.KADMI_CODE = ?'
                                +' and ss.KI_CODE = ?'
                                // exchange #3062
//                                +' and ss.KESI_CODE = ?'
                                +' and ss.PURPOSEFULGRANT_ID = ?',
                                 [ xID,
                                   xID,
                                   aIK_LS_UBP,
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                                   //COPY( xUFPP_KBK,18, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from srcorder where id=?', [ xID]);
        xED_Class := '80i';
        xED := QueryXml( ' select * from srcorder ss'
                        +' where ((ss.title_id=?)'
                        +' or (ss.title_id is null and ss.id=?))'
                        +' and ss.admin_account=?'
                        +' and ss.KADMI_CODE = ?'
                        +' and ss.KI_CODE = ?'
                        // exchange #3062
//                        +' and ss.KESI_CODE = ?'
                        +' and ss.PURPOSEFULGRANT_ID = ?',
                         [ xID,
                           xID,
                           aIK_LS_UBP,
                           DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                           DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                           //COPY( xUFPP_KBK,18, 3),
                           xUFPP_PurposefullgrantID]);
        // загрузка эд 80го класа
        xED80 := QueryDoc_( 'srcorder', xID);
        except
          ExceptionLog( 'Сбой Do_SearchDoc80_');
      end;

  end;
  //----------------------------------------------------------------------------
  function Do_SearchDoc5_0_: boolean;

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField(  ' select ' + aSubSQL
                           +' from payorder s'
                           +' where s.documentclass_id=5'
                           +' and s.dispstatus_id=10'
                           +' and ltrim(s.DOC_NUMBER) = ?'
                           +' and s.DOC_DATE = ?'
                           +' and s.PAY_ACCOUNT = ?'
                           +' and s.budget_id=?'
                           +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                           +' and exists('
                           +' select * from PAYORDERLINE ss'
                           +' where ss.payorder_id=s.id'
                           +' and ss.anal_kind=0'
                           +' and ss.KFSR_CODE = ?'
                           +' and ss.KCSR_CODE = ?'
                           +' and ss.KVR_CODE = ?'
                           // exchange #3062
//                           +' and ss.KESR_CODE = ?'
                           +' and ss.KADMR_CODE = ?'
                           +' and ss.PURPOSEFULGRANT_ID = ?)',
                           [ xUFPP_NOM_PP,
                             StrToDate( xUFPP_DATE_PP),
                             aIK_LS_UBP,
                             aBudgetId,
                             DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                             DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                             DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                             //COPY( xUFPP_KBK,18, 3),
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        Result := FALSE;
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(  ' select sum(ss.amount) S from PAYORDERLINE ss'
                               +' where ss.payorder_id=?'
                               +' and ss.anal_kind=0'
                               +' and ss.KFSR_CODE = ?'
                               +' and ss.KCSR_CODE = ?'
                               +' and ss.KVR_CODE = ?'
                               // exchange #3062
//                               +' and ss.KESR_CODE = ?'
                               +' and ss.KADMR_CODE = ?'
                               +' and ss.PURPOSEFULGRANT_ID = ?',
                                 [ xID,
                                   DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                                   DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                                   DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                                   //COPY( xUFPP_KBK,18, 3),
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from PAYORDER where id=?', [ xID]);
        xED_Class := '5r';
        xED := QueryXml(  'select * from PAYORDERLINE ss'
                         +' where ss.payorder_id=?'
                         +' and ss.anal_kind=0'
                         +' and ss.KFSR_CODE = ?'
                         +' and ss.KCSR_CODE = ?'
                         +' and ss.KVR_CODE = ?'
                         // exchange #3062
//                         +' and ss.KESR_CODE = ?'
                         +' and ss.KADMR_CODE = ?'
                         +' and ss.PURPOSEFULGRANT_ID = ?',
                           [ xID,
                             DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                             DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                             DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                             //COPY( xUFPP_KBK,18, 3),
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             xUFPP_PurposefullgrantID]);
        // загрузка эд 5го класа - здесь нет title_id
        xED5 := QueryDoc_( 'payorder', xID, FALSE);
        Result := TRUE;
        except
          ExceptionLog( 'Сбой Do_SearchDoc5_0_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~Do_SearchDoc24_0_
    ЭД класса 24 требуется искать документ со значениями полей:
    «Номер» = UFPP. NOM_PP,
    «Дата» = UFPP. DATE_PP,
    UF.INN_PL и  UF.KPP_PL, равными ИНН и КПП блока плательщика
    бюджетной строкой расшифровки
    «КВСР» = с 1 по 3 знак UFPP.KBK,
    «КФСР» = с 4 по 7 знак UFPP.KBK,
    «КЦСР» = с 8 по 14 знак UFPP.KBK,
    «КВР» = с 15 по 17 знак UFPP.KBK,
    «КОСГУ» = с 18 по 20 знак UFPP.KBK,
    «Код цели» = UFPP. ADD_KLASS, причем суммовое значение полей
    «Сумма»  строк с данной комбинацией кодов в искомом ЭД должна быть
    равна UFPP. SUM_PP}
  function Do_SearchDoc24_0_: boolean;

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField(  ' select ' + aSubSQL
                           +' from payorder s'
                           +' where s.documentclass_id=24'
                           +' and s.dispstatus_id=10'
                           +' and ltrim(s.DOC_NUMBER) = ?'
                           +' and s.DOC_DATE = ?'
                           +' and s.PAY_TAXCODE = ?'
                           +IfThen( (LENGTH( xUF_KPP_PL) > 0),
                                    ' and s.PAY_KPP = ?',
                                    ' and (s.PAY_KPP = ? or s.PAY_KPP is null)')
//                           +' and s.PAY_KPP = ?'
                           +' and s.budget_id=?'
                           +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                           +' and exists('
                           +' select * from PAYORDERLINE ss'
                           +' where ss.payorder_id=s.id'
                           +' and ss.anal_kind=0'
                           +' and ss.KFSR_CODE = ?'
                           +' and ss.KCSR_CODE = ?'
                           +' and ss.KVR_CODE = ?'
                           // exchange #3062
//                           +' and ss.KESR_CODE = ?'
                           +' and ss.KADMR_CODE = ?'
                           +' and ss.PURPOSEFULGRANT_ID = ?)',
                           [ xUFPP_NOM_PP,
                             StrToDate( xUFPP_DATE_PP),
                             xUF_INN_PL,
                             xUF_KPP_PL,
                             aBudgetId,
                             DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                             DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                             DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                             //COPY( xUFPP_KBK,18, 3),
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        Result := FALSE;
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(  ' select sum(ss.amount) S from PAYORDERLINE ss'
                               +' where ss.payorder_id=?'
                               +' and ss.anal_kind=0'
                               +' and ss.KFSR_CODE = ?'
                               +' and ss.KCSR_CODE = ?'
                               +' and ss.KVR_CODE = ?'
                               // exchange #3062
//                               +' and ss.KESR_CODE = ?'
                               +' and ss.KADMR_CODE = ?'
                               +' and ss.PURPOSEFULGRANT_ID = ?',
                                 [ xID,
                                   DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                                   DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                                   DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                                   //COPY( xUFPP_KBK,18, 3),
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from PAYORDER where id=?', [ xID]);
        xED_Class := '24r';
        xED := QueryXml(  'select * from PAYORDERLINE ss'
                         +' where ss.payorder_id=?'
                         +' and ss.anal_kind=0'
                         +' and ss.KFSR_CODE = ?'
                         +' and ss.KCSR_CODE = ?'
                         +' and ss.KVR_CODE = ?'
                         // exchange #3062
//                         +' and ss.KESR_CODE = ?'
                         +' and ss.KADMR_CODE = ?'
                         +' and ss.PURPOSEFULGRANT_ID = ?',
                           [ xID,
                             DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                             DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                             DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                             //COPY( xUFPP_KBK,18, 3),
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             xUFPP_PurposefullgrantID]);
        // загрузка эд 5го 24ласа - здесь нет title_id
        xED24 := QueryDoc_( 'payorder', xID, FALSE);
        Result := TRUE;
        except
          ExceptionLog( 'Сбой Do_SearchDoc24_0_');
      end;

  end;
  //----------------------------------------------------------------------------
  function Do_SearchDoc5_2_: boolean;

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField(  ' select ' + aSubSQL
                           +' from payorder s'
                           +' where s.documentclass_id=5'
                           +' and s.dispstatus_id=10'
                           +' and ltrim(s.DOC_NUMBER) = ?'
                           +' and s.DOC_DATE = ?'
                           +' and s.PAY_ACCOUNT = ?'
                           +' and s.budget_id=?'
                           +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                           +' and exists('
                           +' select * from PAYORDERLINE ss'
                           +' where ss.payorder_id=s.id'
                           +' and ss.anal_kind=2'
                           +' and ss.KADMI_CODE = ?'
                           +' and ss.KI_CODE = ?'
                           // exchange #3062
//                           +' and ss.KESI_CODE = ?'
                           +' and ss.PURPOSEFULGRANTI_ID = ?)',
                           [ xUFPP_NOM_PP,
                             StrToDate( xUFPP_DATE_PP),
                             aIK_LS_UBP,
                             aBudgetId,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        Result := FALSE;
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(  ' select sum(ss.amount) S from PAYORDERLINE ss'
                               +' where ss.payorder_id=?'
                               +' and ss.anal_kind=2'
                               +' and ss.KADMI_CODE = ?'
                               +' and ss.KI_CODE = ?'
                               // exchange #3062
//                               +' and ss.KESI_CODE = ?'
                               +' and ss.PURPOSEFULGRANTI_ID = ?',
                                 [ xID,
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                                   //COPY( xUFPP_KBK,18, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from PAYORDER where id=?', [ xID]);
        xED_Class := '5i';
        xED := QueryXml(  ' select * from PAYORDERLINE ss'
                         +' where ss.payorder_id=?'
                         +' and ss.anal_kind=2'
                         +' and ss.KADMI_CODE = ?'
                         +' and ss.KI_CODE = ?'
                         // exchange #3062
//                         +' and ss.KESI_CODE = ?'
                         +' and ss.PURPOSEFULGRANTI_ID = ?',
                           [ xID,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID]);
        // загрузка эд 5го класа - здесь нет title_id
        xED5 := QueryDoc_( 'payorder', xID, FALSE);
        Result := TRUE;
        except
          ExceptionLog( 'Сбой Do_SearchDoc5_2_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~Do_SearchDoc24_2_
    ЭД класса 24 требуется искать документ со значениями полей:
    «Номер» = UFPP. NOM_PP,
    «Дата» = UFPP. DATE_PP,
    UF.INN_PL и  UF.KPP_PL, равными ИНН и КПП блока плательщика
    бюджетной строкой расшифровки
    «Гл. администратор» = с 1 по 3 знак UFPP.KBK,
    «КВИ» = с 4 по 17 знак UFPP.KBK,
    «КОСГУ» = с 18 по 20 знак UFPP.KBK,
    «Код цели» = UFPP. ADD_KLASS,
    причем суммовое значение полей
    «Сумма»  строк с данной комбинацией кодов в искомом ЭД должна
    быть равна UFPP. SUM_PP}
  function Do_SearchDoc24_2_: boolean;

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField(  ' select ' + aSubSQL
                           +' from payorder s'
                           +' where s.documentclass_id=24'
                           +' and s.dispstatus_id=10'
                           +' and ltrim(s.DOC_NUMBER) = ?'
                           +' and s.DOC_DATE = ?'
                           +' and s.PAY_TAXCODE = ?'
                           +IfThen( (LENGTH( xUF_KPP_PL) > 0),
                                    ' and s.PAY_KPP = ?',
                                    ' and (s.PAY_KPP = ? or s.PAY_KPP is null)')
                          // +' and s.PAY_KPP = ?'
                           +' and s.budget_id=?'
                           +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                           +' and exists('
                           +' select * from PAYORDERLINE ss'
                           +' where ss.payorder_id=s.id'
                           +' and ss.anal_kind=2'
                           +' and ss.KADMI_CODE = ?'
                           +' and ss.KI_CODE = ?'
                           // exchange #3062
//                           +' and ss.KESI_CODE = ?'
                           +' and ss.PURPOSEFULGRANTI_ID = ?)',
                           [ xUFPP_NOM_PP,
                             StrToDate( xUFPP_DATE_PP),
                             xUF_INN_PL,
                             xUF_KPP_PL,
                             aBudgetId,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        Result := FALSE;
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(  ' select sum(ss.amount) S from PAYORDERLINE ss'
                               +' where ss.payorder_id=?'
                               +' and ss.anal_kind=2'
                               +' and ss.KADMI_CODE = ?'
                               +' and ss.KI_CODE = ?'
                               // exchange #3062
//                               +' and ss.KESI_CODE = ?'
                               +' and ss.PURPOSEFULGRANTI_ID = ?',
                                 [ xID,
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                                   //COPY( xUFPP_KBK,18, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from PAYORDER where id=?', [ xID]);
        xED_Class := '24i';
        xED := QueryXml(  ' select * from PAYORDERLINE ss'
                         +' where ss.payorder_id=?'
                         +' and ss.anal_kind=2'
                         +' and ss.KADMI_CODE = ?'
                         +' and ss.KI_CODE = ?'
                         // exchange #3062
//                         +' and ss.KESI_CODE = ?'
                         +' and ss.PURPOSEFULGRANTI_ID = ?',
                           [ xID,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID]);
        // загрузка эд 24го класа - здесь нет title_id
        xED24 := QueryDoc_( 'payorder', xID, FALSE);
        Result := TRUE;
        except
          ExceptionLog( 'Сбой Do_SearchDoc24_2_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~Do_SearchDoc24_1_
    ЭД класса 24 требуется искать документ со значениями полей:
    «Номер» = UFPP. NOM_PP,
    «Дата» = UFPP. DATE_PP,
    UBP UF.INN_PL и  UF.KPP_PL, равными ИНН и КПП блока плательщика,
    бюджетной строкой расшифровки
    «Гл. администратор» = с 1 по 3 знак UFPP.KBK,
    «КВД» = с 4 по 17 знак UFPP.KBK, UFPP.KBK,
    «КОСГУ» = с 18 по 20 знак UFPP.KBK,
    «Код цели» = UFPP. ADD_KLASS,
    причем суммовое значение полей «Сумма»  строк с данной комбинацией
    кодов в искомом ЭД должна быть равна UFPP. SUM_PP}
  function Do_SearchDoc24_1_: boolean;

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField(  ' select ' + aSubSQL
                           +' from payorder s'
                           +' where s.documentclass_id=24'
                           +' and s.dispstatus_id=10'
                           +' and ltrim(s.DOC_NUMBER) = ?'
                           +' and s.DOC_DATE = ?'
                           +' and s.PAY_TAXCODE = ?'
                           +IfThen( (LENGTH( xUF_KPP_PL) > 0),
                                    ' and s.PAY_KPP = ?',
                                    ' and (s.PAY_KPP = ? or s.PAY_KPP is null)')
                           +' and s.budget_id=?'
                           +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                           +' and exists('
                           +' select * from PAYORDERLINE ss'
                           +' where ss.payorder_id=s.id'
                           +' and ss.anal_kind=1'
                           +' and ss.KADMD_CODE = ?'
                           +' and ss.KD_CODE = ?'
                           // exchange #3062
//                           +' and ss.KESD_CODE = ?'
                           +' and ss.PURPOSEFULGRANTD_ID = ?)',
                           [ xUFPP_NOM_PP,
                             StrToDate( xUFPP_DATE_PP),
                             xUF_INN_PL,
                             xUF_KPP_PL,
                             aBudgetId,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        Result := FALSE;
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(  ' select sum(ss.amount) S from PAYORDERLINE ss'
                               +' where ss.payorder_id=?'
                               +' and ss.anal_kind=1'
                               +' and ss.KADMD_CODE = ?'
                               +' and ss.KD_CODE = ?'
                               // exchange #3062
//                               +' and ss.KESD_CODE = ?'
                               +' and ss.PURPOSEFULGRANTD_ID = ?',
                                 [ xID,
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                                   //COPY( xUFPP_KBK,18, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from PAYORDER where id=?', [ xID]);
        xED_Class := '24d';
        xED := QueryXml(  ' select * from PAYORDERLINE ss'
                         +' where ss.payorder_id=?'
                         +' and ss.anal_kind=1'
                         +' and ss.KADMD_CODE = ?'
                         +' and ss.KD_CODE = ?'
                         // exchange #3062
//                         +' and ss.KESD_CODE = ?'
                         +' and ss.PURPOSEFULGRANTD_ID = ?',
                           [ xID,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID]);
        // загрузка эд 24го класа - здесь нет title_id
        xED24 := QueryDoc_( 'payorder', xID, FALSE);
        Result := TRUE;
        except
          ExceptionLog( 'Сбой Do_SearchDoc24_1_');
      end;

  end;
  //----------------------------------------------------------------------------
  procedure Do_SearchDoc215_2_( aFK_CODE: string);

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField( ' select ' + aSubSQL
                          +' from nonbankoper s'
                          +' where s.documentclass_id=215'
                          +' and s.dispstatus_id=10'
                          +' and ltrim(s.DOC_NUMBER) = ?'
                          +' and s.DOC_DATE = ?'
                          +' and s.budget_id=?'
                          +' and s.fk_flag=?'
                          +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                          +' and exists('
                          +' select * from nonbankoper ss'
                          +' where ((ss.title_id=s.id)'
                          +' or (ss.title_id is null and ss.id=s.id))'
                          +' and ss.org_account=?'
                          +' and ss.ANAL_KIND = 3'
                          +' and ss.KADMI_CODE = ?'
                          +' and ss.KI_CODE = ?'
                          // exchange #3062
//                          +' and ss.KESI_CODE = ?'
                          +' and ss.PURPOSEFULGRANTI_ID = ?)',
                           [ xUFPP_NOM_PP,
                             StrToDate( xUFPP_DATE_PP),
                             aBudgetId,
                             aFK_CODE,
                             aIK_LS_UBP,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xSummXml: variant;  begin

      try
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        // здесь нужно считать сумму и "сумма", и "передано", поэтому
        // вместа подзапросов по каждой сумме, получаем сразу две суммы
        xSummXml := QueryXml(  ' select sum(ss.pass_amt) S, sum(SS.amount) A'
                              +' from nonbankoper ss'
                              +' where ((ss.title_id=?)'
                              +' or (ss.title_id is null and ss.id=?))'
                              +' and ss.org_account=?'
                              +' and ss.ANAL_KIND = 3'
                              +' and ss.KADMI_CODE = ?'
                              +' and ss.KI_CODE = ?'
                              // exchange #3062
//                              +' and ss.KESI_CODE = ?'
                              +' and ss.PURPOSEFULGRANTI_ID = ?',
                               [ xID,
                                 xID,
                                 aIK_LS_UBP,
                                 DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                 DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                                 //COPY( xUFPP_KBK,18, 3),
                                 xUFPP_PurposefullgrantID]);
        xSummXml := xSummXml.documentElement.childNodes.item[ 0];
        // проверяем совпадение одной из двух сумм
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if ((xUFPP_SUM_PP <> xSummXml.GetAttribute( 'S'))
            AND (xUFPP_SUM_PP <> xSummXml.GetAttribute( 'A')))
          then EXIT;
//        xED := QueryXml( 'select * from nonbankoper where id=?', [ xID]);
        xED_Class := '215i';
        xED := QueryXml( ' select * from nonbankoper ss'
                        +' where ((ss.title_id=?)'
                        +' or (ss.title_id is null and ss.id=?))'
                        +' and ss.org_account=?'
                        +' and ss.ANAL_KIND = 3'
                        +' and ss.KADMI_CODE = ?'
                        +' and ss.KI_CODE = ?'
                        // exchange #3062
//                        +' and ss.KESI_CODE = ?'
                        +' and ss.PURPOSEFULGRANTI_ID = ?',
                         [ xID,
                           xID,
                           aIK_LS_UBP,
                           DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                           DoEncodeKBK_KI( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                          // COPY( xUFPP_KBK,18, 3),
                           xUFPP_PurposefullgrantID]);
        except
          ExceptionLog( 'Сбой Do_SearchDoc215_2_');
      end;

  end;
  //----------------------------------------------------------------------------
  procedure Do_SearchDoc215_1_( aFK_CODE: string);

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField( ' select ' + aSubSQL
                          +' from nonbankoper s'
                          +' where s.documentclass_id=215'
                          +' and s.dispstatus_id=10'
                          +' and ltrim(s.DOC_NUMBER) = ?'
                          +' and s.DOC_DATE = ?'
                          +' and s.budget_id=?'
                          +' and s.fk_flag=?'
                          +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                          +' and exists('
                          +' select * from nonbankoper ss'
                          +' where ((ss.title_id=s.id)'
                          +' or (ss.title_id is null and ss.id=s.id))'
                          +' and ss.org_account=?'
                          +' and ss.ANAL_KIND = 2'
                          +' and ss.KADMD_CODE = ?'
                          +' and ss.KD_CODE = ?'
                          // exchange #3062
//                          +' and ss.KESD_CODE = ?'
                          +' and ss.PURPOSEFULGRANTD_ID = ?)',
                           [ xUFPP_NOM_PP,
                             StrToDate( xUFPP_DATE_PP),
                             aBudgetId,
                             aFK_CODE,
                             aIK_LS_UBP,
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                             //COPY( xUFPP_KBK,18, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(   ' select sum(ss.amount) S from nonbankoper ss'
                                +' where ((ss.title_id=?)'
                                +' or (ss.title_id is null and ss.id=?))'
                                +' and ss.org_account=?'
                                +' and ss.ANAL_KIND = 2'
                                +' and ss.KADMD_CODE = ?'
                                +' and ss.KD_CODE = ?'
                                // exchange #3062
//                                +' and ss.KESD_CODE = ?'
                                +' and ss.PURPOSEFULGRANTD_ID = ?',
                                 [ xID,
                                   xID,
                                   aIK_LS_UBP,
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                                   //COPY( xUFPP_KBK,18, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from nonbankoper where id=?', [ xID]);
        xED_Class := '215d';
        xED := QueryXml( ' select * from nonbankoper ss'
                        +' where ((ss.title_id=?)'
                        +' or (ss.title_id is null and ss.id=?))'
                        +' and ss.org_account=?'
                        +' and ss.ANAL_KIND = 2'
                        +' and ss.KADMD_CODE = ?'
                        +' and ss.KD_CODE = ?'
                        // exchange #3062
//                        +' and ss.KESD_CODE = ?'
                        +' and ss.PURPOSEFULGRANTD_ID = ?',
                         [ xID,
                           xID,
                           aIK_LS_UBP,
                           DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                           DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                           //COPY( xUFPP_KBK,18, 3),
                           xUFPP_PurposefullgrantID]);
        except
          ExceptionLog( 'Сбой Do_SearchDoc215_1_');
      end;

  end;
  //----------------------------------------------------------------------------
  procedure Do_SearchDoc215_0_( aFK_CODE: string);

    function Query_( aSubSQL, aField: string): string;
    begin
      Result:= QueryField( ' select ' + aSubSQL
                          +' from nonbankoper s'
                          +' where s.documentclass_id=215'
                          +' and s.dispstatus_id=10'
                          +' and ltrim(s.DOC_NUMBER) = ?'
                          +' and s.DOC_DATE = ?'
                          +' and s.budget_id=?'
                          +' and s.fk_flag=?'
                          +' and s.DISPSTATUS_ID=10'  // ФТ-2.1
                          +' and exists('
                          +' select * from nonbankoper ss'
                          +' where ((ss.title_id=s.id)'
                          +' or (ss.title_id is null and ss.id=s.id))'
                          +' and ss.org_account=?'
                          +' and ss.ANAL_KIND = 1'
                          +' and ss.KFSR_CODE = ?'
                          +' and ss.KCSR_CODE = ?'
                          +' and ss.KVR_CODE = ?'
                          // exchange #3062
//                          +' and ss.KESR_CODE = ?'
                          +' and ss.KADMR_CODE = ?'
                          +' and ss.PURPOSEFULGRANT_ID = ?)',
                           [ xUFPP_NOM_PP,
                             StrToDate( xUFPP_DATE_PP),
                             aBudgetId,
                             aFK_CODE,
                             aIK_LS_UBP,
                             DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                             DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                             DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                             //COPY( xUFPP_KBK,18, 3),
                             DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                             xUFPP_PurposefullgrantID],
                           aField);
    end;

  var
    xID: string;
    xAmount: string;
  begin

      try
        if (Query_( 'count( * ) N', 'N') <> '1')
          then EXIT;
        xID := Query_( 's.id ID', 'ID');
        // проверяем итоговую сумму  в найденных строках эд
        xAmount := QueryField(   ' select sum(ss.amount) S from nonbankoper ss'
                                +' where ((ss.title_id=?)'
                                +' or (ss.title_id is null and ss.id=?))'
                                +' and ss.org_account=?'
                                +' and ss.ANAL_KIND = 1'
                                +' and ss.KFSR_CODE = ?'
                                +' and ss.KCSR_CODE = ?'
                                +' and ss.KVR_CODE = ?'
                                // exchange #3062
//                                +' and ss.KESR_CODE = ?'
                                +' and ss.KADMR_CODE = ?'
                                +' and ss.PURPOSEFULGRANT_ID = ?',
                                 [ xID,
                                   xID,
                                   aIK_LS_UBP,
                                   DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                                   DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                                   DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                                   //COPY( xUFPP_KBK,18, 3),
                                   DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                   xUFPP_PurposefullgrantID],
                                 'S');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        if (FORMAT( '%.2f', [ StrToFloat( xAmount)]) <> xUFPP_SUM_PP)
          then EXIT;
//        xED := QueryXml( 'select * from nonbankoper where id=?', [ xID]);
        xED_Class := '215r';
        xED := QueryXml( ' select * from nonbankoper ss'
                        +' where ((ss.title_id=?)'
                        +' or (ss.title_id is null and ss.id=?))'
                        +' and ss.org_account=?'
                        +' and ss.ANAL_KIND = 1'
                        +' and ss.KFSR_CODE = ?'
                        +' and ss.KCSR_CODE = ?'
                        +' and ss.KVR_CODE = ?'
                        // exchange #3062
//                        +' and ss.KESR_CODE = ?'
                        +' and ss.KADMR_CODE = ?'
                        +' and ss.PURPOSEFULGRANT_ID = ?',
                         [ xID,
                           xID,
                           aIK_LS_UBP,
                           DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                           DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                           DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                           //COPY( xUFPP_KBK,18, 3),
                           DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                           xUFPP_PurposefullgrantID]);
        except
          ExceptionLog( 'Сбой Do_SearchDoc215_0_');
      end;

  end;
  //----------------------------------------------------------------------------
  function Do_SearchDoc19_Linked_Doc24_: boolean;
  var
    xSQL: string;
    xED24_ID: string;
    xID: string;
  begin
  
      try
        xSQL :=  ' X from incorder b'
                +' join document d on d.id=b.document_id'
                +' join document dd on dd.id=d.parent_id'
                +' join payorder p on p.document_id=dd.id'
                +' where  p.ID = ? and'
                +' (b.title_id=b.id or b.title_id is null)'
                +' and b.dispstatus_id>-1';

        xED24_ID := GetNodeAttributeEx( xED24, 'ID');

        if (QueryField( 'select count( * )' + xSQL, [ xED24_ID], 'X') <> '1')
          then Result := FALSE
          else begin
            xED_Class := '19d';
            xID := QueryField( 'select b.id' + xSQL, [ xED24_ID], 'X');
            xED := QueryXml(  ' select * from incorder ss'
                             +' where ((ss.title_id=?) or'
                             +'  (ss.title_id is null and ss.id=?))'
                             +' and ss.KADMD_CODE = ?'
                             +' and ss.KD_CODE = ?'
                             // exchange #3062
//                             +' and ss.KESD_CODE = ?'
                             +' and ss.purposefulgrant_id = ?',
                               [ xID,
                                 xID,
                                 DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                                 DoEncodeKBK_KD( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4,14),
                                 //COPY( xUFPP_KBK,18, 3),
                                 xUFPP_PurposefullgrantID]);
            // загрузка эд 19го класа
            xED19 := QueryDoc_( 'incorder', xID);
            Result := TRUE;
          end;
        except
          ExceptionProc( 'Do_SearchDoc19_Linked_Doc24_');
      end;
  
  end;
  //----------------------------------------------------------------------------
  function Do_SearchDoc25_Linked_Doc24_: boolean;
  var
    xSQL: string;
    xED24_ID: string;
    xID: string;
  begin
  
      try
        xSQL :=  ' X from backorder b'
                +' join document d on d.id=b.document_id'
                +' join document dd on dd.id=d.parent_id'
                +' join payorder p on p.document_id=dd.id'
                +' where  p.ID = ? and'
                +' (b.title_id=b.id or b.title_id is null)'
                +' and b.dispstatus_id>-1';

        xED24_ID := GetNodeAttributeEx( xED24, 'ID');

        if (QueryField( 'select count( * )' + xSQL, [ xED24_ID], 'X') <> '1')
          then Result := FALSE
          else begin
            xED_Class := '25r';
            xID := QueryField( 'select b.id' + xSQL, [ xED24_ID], 'X');
            xED := QueryXml(  ' select * from backorder ss'
                             +' where ((ss.title_id=?) or'
                             +'  (ss.title_id is null and ss.id=?))'
                            +' and ss.KFSR_CODE = ?'
                            +' and ss.KCSR_CODE = ?'
                            +' and ss.KVR_CODE = ?'
                            // exchange #3062
//                            +' and ss.KESR_CODE = ?'
                            +' and ss.KADMR_CODE = ?'
                            +' and ss.PURPOSEFULGRANT_ID = ?',
                             [ xID,
                               xID,
                               DoEncodeKBK_KFSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 4, 4),
                               DoEncodeKBK_KCSR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 8, 7),
                               DoEncodeKBK_KVR( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK,15, 3),
                              // COPY( xUFPP_KBK,18, 3),
                               DoEncodeKBK_KADM( xUFPP_KBK, FALSE), //COPY( xUFPP_KBK, 1, 3),
                               xUFPP_PurposefullgrantID]);
            // загрузка эд 25го класа
            xED25 := QueryDoc_( 'backorder', xID);
            Result := TRUE;
          end;
        except
          ExceptionProc( 'Do_SearchDoc25_Linked_Doc24_');
      end;
  
  end;
  //----------------------------------------------------------------------------
  function Do_SearchDoc_Linked_Doc24_: boolean;
  begin
  
      try
        case xED_Class of
          '24r': Result := Do_SearchDoc25_Linked_Doc24_;
          '24d': Result := Do_SearchDoc19_Linked_Doc24_;
          else   Result := FALSE;
        end;//case//
        // еесли слинкованный эд не найден, 24й считаем тоже не найденным
        if NOT Result then xED_Class := '';
        except
          ExceptionProc( 'Do_SearchDoc_Linked_Doc24_');
      end;
  
  end;
  //----------------------------------------------------------------------------
  (*
  //----------------------------------------------------------------------------
  {~DoSearch_IK_LS_UBP_
    значением «Счет» равным  значению одного из вышеуказанных реквизитов,
    с типом «Лицевой счет в ФК», «Лицевой счет по источникам в ФК»,
    с пустой датой блокирования. Причем организация – владелец данного счета
    должна иметь включенную галку активности и пустую дату закрытия.
    здесь орг роль организации не проверяется.}
  function DoSearch_IK_LS_UBP_( aSelect: string): string;
  begin

      try
        Result := QueryField( aSelect + ' X from orgaccount oa'
                             +' join org o on o.id=oa.org_id'
                             +' Join Contractor C on C.Org_Id = O.Id'
                             +' Join Budget B on B.Org_Id = C.Inspector_Id'
                             +' where oa.account_number=?'
                             +' and oa.orgacctype_id in (5,7)'
                             +' and b.id=?'
                             +' and oa.close_date is null'
                             +' and o.close_date is null',
                              [ aIK_LS_UBP,
                                aBudgetID],
                              'X');
        except
          ExceptionProc( 'DoSearch_IK_LS_UBP_');
      end;

  end;
  *)
  //----------------------------------------------------------------------------
begin
  try

    try
      Result := 0;

      { ищем счет IK.LS_UBP по ФТ-1
        ЭД класса 215 формировать только при условии, что:
          В справочнике «Счета организаций» должны присутствовать лицевые счета
          клиентов, заданные в параметрах IK.LS_UBP (обязательно).
        В справочнике «Счета организаций» должна быть строка со значением
        «Счет» равным  значению одного из вышеуказанных реквизитов,
        с типом «Лицевой счет в ФК»,
        «Лицевой счет по источникам в ФК»,
        с пустой датой блокирования.
        Причем организация – владелец данного счета должна иметь включенную
        галку активности и пустую дату закрытия.}
      if (QueryField( 'select count( * ) N from orgaccount oa'
                     +' join org o on o.id=oa.org_id'
                     +' Join Contractor C on C.Org_Id = O.Id'
                     +' Join Budget B on B.Org_Id = C.Inspector_Id'
                     +' where oa.account_number=?'
                     +' and oa.orgacctype_id in (5,7)'
                     +' and b.id=?'
                     +' and oa.close_date is null'
                     +' and o.close_date is null',
                      [ aIK_LS_UBP,
                        aBudgetID],
                      'N') = '0') then begin
        WriteInfo(
            FORMAT( 'Не найдно ни одного счета %s подходящего '
                   +'для создания ЭД "Справка по внебанковским операциям".',
                    [ aIK_LS_UBP]));
        Result := 40;
        EXIT;
      end;
//      xIK_LS_UBP_ID    := DoSearch_IK_LS_UBP_( 'select oa.ID');
//      xIK_LS_UBP_OrgID := DoSearch_IK_LS_UBP_( 'select oa.org_id');

      //----------------------------------------------------------------------
      // поля из UF
      xUF_NOM_UF  := GetNodeAttributeEx( aSource, 'NOM_UF');
      xUF_DATE_UF := GetNodeAttributeEx( aSource, 'DATE_UF');
      xUF_INN_PL  := GetNodeAttributeEx( aSource, 'INN_PL');
      xUF_KPP_PL  := GetNodeAttributeEx( aSource, 'KPP_PL');
      xUF_TYPE_KR := GetNodeAttributeEx( aSource, 'TYPE_KR');
      // предварительное описание создаваемого ЭД 215го класса
      xDocInfo := FORMAT( 'ЭД "Справка по внебанковским операциям" номер № %s от %s',
                              [ xUF_NOM_UF,
                                xUF_DATE_UF]);

      //----------------------------------------------------------------------
      { если UF не содержит строк UFPP и UFPP_N, то ЭД создать не сможем
        и прерываем операцию.
        структура XML:
          UF
            UFPP  <--- список строк
              UFPP...   <-- строки
            UFPP_N  <--- список строк
              UFPP_N...   <-- строки
              UFPP_N...}

      xUFPP:= NULL;
      xUFPP_N:= NULL;
      for i := 0 to aSource.childNodes.length - 1 do begin
        xNode_UFPP := aSource.childNodes.item[i];
        case xNode_UFPP.nodeName of
          'UFPP': begin
                    // есть ли строки в узле?
                    if (xNode_UFPP.childNodes.length > 0)
                      then xUFPP := xNode_UFPP;
                  end;
          'UFPP_N': begin
                    // есть ли строки в узле?
                    if (xNode_UFPP.childNodes.length > 0)
                      then xUFPP_N := xNode_UFPP;
                  end;
        end;//case//
      end;//for//
      if VarIsNull( xUFPP) then begin
        WriteInfo( FORMAT( '%s не может быть создан - не содержит строк UFPP',
                            [ xDocInfo]));
        Result := 14;
        EXIT;
      end;
      if VarIsNull( xUFPP_N) then begin
        WriteInfo( FORMAT( '%s не может быть создан - не содержит строк UFPP_N',
                            [ xDocInfo]));
        Result := 14;
        EXIT;
      end;

      //----------------------------------------------------------------------
      { проверяем по ФТ-1 разделы UFPP и UFPP_N.
        в дальнейшем, когда будем создавать эд, проверка полей в разделах
        UFPP и UFPP_N уже не будет выполняться. }

      if NOT CheckUF_Lines_( xUFPP)
        then Result := 14;
      if NOT CheckUF_Lines_( xUFPP_N)
        then Result := 14;
      // проверяем чтобы по проверенным разделам UFPP были найдены разделы
      // UFPP_N по номеру UFPP.LINE_NOM.
      // exchange #2954
      // в файле возможно что несколько блоков UFPP_N связаны с одним
      // блоком UFPP, поэтому в первый раз проверяем наличие хотя бы одного
      // блока UFPP_N для UFPP с номером в UFPP.LINE_NOM, а следующем цикле
      // для каждого UFPP_N ищем UFPP и проверяем поля UFPP_N по найденному
      // UFPP.

      for xIndexUFPP := 0 to xUFPP.childNodes.length - 1 do begin
        xNode_UFPP := xUFPP.childNodes.item[ xIndexUFPP];

        if IsBadLine_( xNode_UFPP) then CONTINUE;
        xUFPP_LINE_NOM:= VarToStr( xNode_UFPP.GetAttribute( 'LINE_NOM'));
        if NOT Do_Search_UFPP_N_ then begin
          WriteInfo(
            FORMAT(
              'Не найдено ни одного блока UFPP_N для блока UFPP со значением UFPP.LINE_NOM = %s.',
              [ xUFPP_LINE_NOM]));
          Result := 14;
        end;
      end;//for//
      // exchange #2954
      // теперь перебираем все блоки UFPP_N, для каждого блока ищем связанны
      // с ним блок UFPP и обновляем поля в UFPP_N по связанныму блоку UFPP

      for xIndexUFPP_N := 0 to xUFPP_N.childNodes.length - 1 do begin
        xNode_UFPP_N := xUFPP_N.childNodes.item[ xIndexUFPP_N];

        if IsBadLine_( xNode_UFPP_N) then CONTINUE;
        xUFPP_LINE_NOM:= VarToStr( xNode_UFPP_N.GetAttribute( 'LINE_NOM'));
        if NOT Do_Search_UFPP_ then begin
          WriteInfo(
            FORMAT(
              'Не найдено ни одного блока UFPP для блока UFPP_N со значением UFPP_N.LINE_NOM = %s.',
              [ xUFPP_LINE_NOM]));
          Result := 14;
        end;
        (*
         else begin
          // exchange #2874
          // здесь проверяем, если UFPP_N.SUM пустое, то в это поле
          // заносим значение из UFPP.SUM_PP
          // exchange #2953
          // поскольку придется анализировать пустое значение сумм
          // то используем временное поле _SUM_ в котором будем хранить
          // заполненное поле суммы для строки UFPP_N, а исходное
          // остается как есть для анализа.
          xUFPP_N_SUM := GetNodeAttributeEx( xNode_UFPP_N, 'SUM');

          if (LENGTH( xUFPP_N_SUM) <= 0)
            then xNode_UFPP_N.SetAttribute(
                              '_SUM_',
                              GetNodeAttributeEx(  xNode_UFPP, 'SUM_PP'))
            else xNode_UFPP_N.SetAttribute(
                              '_SUM_',
                              xUFPP_N_SUM);
        end;
        *)
      end;//for//
      if (Result <> 0) then begin
        WriteInfo( FORMAT( '%s не может быть создан.', [ xDocInfo]));

        EXIT;
      end;

      // пока считаем что в создаваемом ЭД 215го класса проблем не возникло
      xDoc_Problem  := FALSE;
      xDoc_Error    := FALSE;

(*
      //----------------------------------------------------------------------
      // по ФТ-2.1 проверяем UF.NOM_ZF и UF.DATE_ZF и создаем 215й из 178го.
      // если результат функции >=0 - считаем операцию выполненной.
      // если результат отрицательный, значит условие фт-2.1 не выполнено
      // и продолжаем создание 215го с нуля.

      Result := Do_FT_2_1_;
      if (Result >= 0) then EXIT;
      *)
      Result := 0;

      //----------------------------------------------------------------------
      // создаем ЭД 215го класса
      // exchange #2903 - записываем в журнал в зависимости от параметра
      WriteLog( FORMAT( 'Создается ЭД %s...', [ xDocInfo]), TRUE);
      xGUID := aSource.GetAttribute( 'GUID_FK');
      WriteLog( FORMAT( 'Проверка существования документа (%s)...',
                        [ xGUID]),
                True);
      // проверку дублей выполняем всегда, не зависимо от параметра
      // создавать эд 215й.
      if IsLoaded215( aBudgetID, xGUID, TRUE) then begin
        // exchange #2903
        // сообщение добавляется в журнал info с описанием эд
        WriteInfo( FORMAT( 'Документ %s уже есть в БД.',
                            [ xDocInfo]));
        Result := 10;

        EXIT;
      end;
      // создаем ЭД "Справка по внебанковским операциям"
      xDocXml := CreateOleObject('Microsoft.XmlDom');
      xDoc    := xDocXml.appendChild( xDocXml.createElement('DOCUMENT'));
      // шапка
      xDoc.setAttribute('GUID_FK', xGUID);
      // бюджет. это может потребоваться для определения бюджетополучателя и
      // других операций
      xDoc.setAttribute('BUDGET_ID', aBudgetID);
      xDoc.setAttribute('F_BUDGET_ID', aBudgetID);
      // обновляем поля шапки эд 215го
      DoUpdateMainED215_( xDoc);

      // пока строк в ЭД 215м нету
      xDocLines := NULL;
      //----------------------------------------------------------------------

      // формируем список строк в ЭД 215м по разделам UFPP
      for xIndexUFPP := 0 to xUFPP.childNodes.length - 1 do begin
        xNode_UFPP := xUFPP.childNodes.item[ xIndexUFPP];
        // игнорируем ошибочные строки
        if IsBadLine_( xNode_UFPP) then CONTINUE;

        // параметры UFPP для подзапросов
        xUFPP_KBK     := VarToStr( xNode_UFPP.GetAttribute( 'KBK'));
        xUFPP_TYPE_KBK:= VarToStr( xNode_UFPP.GetAttribute( 'TYPE_KBK'));
        xUFPP_NOM_PP  := VarToStr( xNode_UFPP.GetAttribute( 'NOM_PP'));
        xUFPP_DATE_PP := VarToStr( xNode_UFPP.GetAttribute( 'DATE_PP'));
        // exchange #3000
        // проблема в дробных значениях. в файле могут не указать дробную часть,
        // а сравнение выполняется на строках, поэтому обязательно требуется
        // преобразование к двум знакам дробной части!
        xUFPP_SUM_PP  := FORMAT( '%.2f',
                                 [ StrToFloat(
                                      VarToStr(
                                          xNode_UFPP.GetAttribute( 'SUM_PP')))]);
        xUFPP_NOM_ZR  := VarToStr( xNode_UFPP.GetAttribute( 'NOM_ZR'));
        xUFPP_DATE_ZR := VarToStr( xNode_UFPP.GetAttribute( 'DATE_ZR'));
        xUFPP_LINE_NOM:= VarToStr( xNode_UFPP.GetAttribute( 'LINE_NOM'));
        xUFPP_KOD_DOC := VarToStr( xNode_UFPP.GetAttribute( 'KOD_DOC'));
        // код цели
        xUFPP_PurposefullgrantID :=
                              GetPurposefullGraintIDByUF_(
                                  VarToStr( xNode_UFPP.GetAttribute( 'ADD_KLASS')),
                                  FALSE,
                                  aBudgetID);
        // пока уточняемый ЭД не найден
        xED := NULL;
        xED_Class := '';



        { ФТ-2.2
          Если в UFPP.KOD_DOC указано значение, то уточняемые строки
          формируемого ЭД класса 215 требуется формировать из подлежащего
          уточнению ЭД в статусе «Обработка завершена», нужно искать ЭД
          в системе с нужными реквизитами.}
        case xUFPP_KOD_DOC of
          'ZR': case xUFPP_TYPE_KBK of
                  // с неуказанным признаком получения наличных
                  '10'     : Do_SearchDoc11_( ' and b.CASH_INCOME=0',
                                              xUFPP_NOM_PP,
                                              xUFPP_DATE_PP);
                  '31','32': Do_SearchDoc118_( xUFPP_NOM_PP,
                                               xUFPP_DATE_PP);
                end;//case//
          'ZS': case xUFPP_TYPE_KBK of
                  // получение наличных с признаком "чек"
                  '10'     : Do_SearchDoc11_( ' and b.CASH_INCOME=1'
                                             +' and b.WAYTOGETCASH=0',
                                              xUFPP_NOM_PP,
                                              xUFPP_DATE_PP);
                  '31','32': Do_SearchDoc118_( xUFPP_NOM_PP,
                                               xUFPP_DATE_PP);
                end;//case//
          'ZN': case xUFPP_TYPE_KBK of
                  // получение наличных с признаком "карта"
                  '10'     : Do_SearchDoc11_( ' and b.CASH_INCOME=1'
                                             +' and b.WAYTOGETCASH=1',
                                              xUFPP_NOM_PP,
                                              xUFPP_DATE_PP);
                  '31','32': Do_SearchDoc118_( xUFPP_NOM_PP,
                                               xUFPP_DATE_PP);
                end;//case//

          // ФТ-2.1.2 и ФТ-2.1.3
          'PP': if ((LENGTH( xUFPP_NOM_ZR) > 0) AND (LENGTH( xUFPP_DATE_ZR) > 0))
                  then
                    // если поля xUFPP_NOM_ZR и xUFPP_DATE_ZR заполнены
                    // ФТ-2.1.2
                    case xUFPP_TYPE_KBK of
                      '10'     : Do_SearchDoc11_( '',
                                                  xUFPP_NOM_ZR,
                                                  xUFPP_DATE_ZR);
                      '20'     : Do_SearchDoc43_( xUFPP_NOM_ZR,
                                                  xUFPP_DATE_ZR);

                      // ищем 118й. если нашли ни одного 118х, то ищем 80й.
                      // если 118й не нашли или нашли несколько - тогда 80й не ищем.
                      '31','32': if (Do_SearchDoc118_( xUFPP_NOM_ZR,
                                                       xUFPP_DATE_ZR) = '0')
                                   then Do_SearchDoc80_;
                    end//case//
                  else
                // если оба поля будут пустыми то ФТ-2-1.3, иначе - ФТ-5.1
                // согласовано с АО устно.
                if ((LENGTH( xUFPP_NOM_ZR) <= 0) AND (LENGTH( xUFPP_DATE_ZR) <= 0))
                  then
                    // если поле xUFPP_NOM_ZR или xUFPP_DATE_ZR пустое
                    // ФТ-2.1.3
                    case xUFPP_TYPE_KBK of
                      // расходные строки
                      // exchange #2930
                      // поиск в эд 5м и 24м (счет плательщика)
                      // exchange #2953
                      // если нашли 24й - ищем прилинкованный 25й
                      '10'     : if NOT Do_SearchDoc5_0_ then
                                   if Do_SearchDoc24_0_
                                     then Do_SearchDoc_Linked_Doc24_;

                      // exchange #2953
                      // если нашли 24й - ищем прилинкованный 19й
                      '20'     : if Do_SearchDoc24_1_
                                   then Do_SearchDoc_Linked_Doc24_;

                      // exchange #2930
                      // если не нашли в 5м - ищем в 24м
                      '31','32': if NOT Do_SearchDoc5_2_   // источники
                                   then Do_SearchDoc24_2_;
                    end;//case//

          // ФТ-2.1.4
          'SP': case xUFPP_TYPE_KBK of
                  '10'      : Do_SearchDoc215_0_( '1');
                  '20'      : Do_SearchDoc215_1_( '1');
                  '31','32' : Do_SearchDoc215_2_( '1');
                end;
          'UF': case xUFPP_TYPE_KBK of
                  '10'      : Do_SearchDoc215_0_( '3');
                  '20'      : Do_SearchDoc215_1_( '3');
                  '31','32' : Do_SearchDoc215_2_( '3');
                end;

          // ФТ-2.1.5
          'ZV': case xUFPP_TYPE_KBK of
                  '20'      : Do_SearchDoc43_( xUFPP_NOM_PP,
                                               xUFPP_DATE_PP);
                  '31','32' : Do_SearchDoc80_;
                end;

          // ФТ-2.1.6
          // в данном случае этот пункт относится к прочим (см.ниже)
          //'AT': xED := NULL;

          // прочие -> ФТ-5.2
        end;//case//

        // если найден уточняемый ЭД, то по ФТ-2.2.1...ФТ-2.2.5
        // переходим на ФТ-5.1, иначе на ФТ-5.2 (включая ФТ-2.2.6)
        if (LENGTH( xED_Class) <= 0)
          then Do_FT_5_2_
          else begin
            xED := xED.documentElement;
            Do_FT_5_1_;
          end;

        // выполняем ФТ-5.3
        // ищем раздел UFPP_N по полю UFPP.LINE_NOM.
        // если раздел UFPP_N будет найден - создаем строку по UFPP_N.
        // exchange #2954
        // здесь выполняется добавление нескольких
        // строк по UFPP_N для текущего блока UFPP
        DoFT_5_3_;
//        if Do_Search_UFPP_N_
//          then DoAddLine_FT_5_3_;
      end;//for//

      //----------------------------------------------------------------------
      // проверяем, если есть ошибки формирования эд - такой эд не создаем
      if xDoc_Error then begin
        WriteInfo( FORMAT( '%s не создан - загружен с ошибками.', [ xDocInfo]));
        Result := 18;
      end else
        // если есть строки в ЭД 215-м - создаем его в ацк-ф
        if VarIsNULL( xDocLines) then begin
          WriteInfo( FORMAT( '%s не создан - нет строк в создаваемом эд.', [ xDocInfo]));
          Result := 18;
        end else begin
          // отправляем ЭД на сервер
          WriteLog( 'Передача ЭД на АЦК-Ф...');
          // после создания меняем статус на "новый"
          xDoc.setAttribute('action', 'insert');
          xDoc.setAttribute('class', '215');
          // Вставка и обработка.
          // после вставки документ переводится на статус "отложен"
          try

            xDocXml.loadXml( ExecXml( xDocXml.xml));

            WriteLog( 'Создан.');
            Do_FT_7_;
            Result:= 0;
            except
              WriteInfo( FORMAT( 'Сбой создания ЭД - %s',
                                  [ LastException.Message]));
              Result := 19;
          end;
        end;
      except
        ExceptionLog( 'Сбой скрипта: "Imp_FK_BH.DoCreateDoc215_UF".');
    end;
    finally

  end;
end;

{~DoCreateDoc215_UF_IK
  создание эд 215х из IK.UF.
  здесь особенность в том, что на вход приходит узел aSource
  сгруппированный так:
    UF
      UFPP
      ...
      UFPP
      UFPP_N
      ...
      UFPP_N
  а нужно сгруппировать так:
    UF
      UFPP
        UFPP
        ...
      UFPP_N
        UFPP_N
        ...

  все остальное аналогично созданию 215го по BH.UF
  функция создания по IK создана здесь, чтобы не создавать отдельный модуль.}
function DoCreateDoc215_UF_IK(  aSource: Variant;
                                aBudgetID: string;
                                aTO_KOD_UBP: string;
                                aIK_LS: string;
                                aCfgIgnoreBadKBK, aCfgResetBadKBK: boolean;
                                aValidate: boolean;
                                aLogToInfo: boolean = FALSE): integer;
var
  i: integer;
  xXml: Variant;
  xDoc: Variant;
  xNode: Variant;
  xNodeUFPP: Variant;
  xNodeUFPP_N: Variant;
begin

    try
      { формируем промежуточную xml со структурой:
        UF (aSource)
          UFPP
            разделы UFPP из вложенных узлов aSource
          UFPP_N
            разделы UFPP_N из вложенных узлов aSource}
      xXml        := CreateOleObject('Microsoft.XmlDom');
      xDoc        := xXml.AppendChild( aSource.CloneNode( FALSE));
      xNodeUFPP   := xDoc.AppendChild( xXml.CreateElement( 'UFPP'));
      xNodeUFPP_N := xDoc.AppendChild( xXml.CreateElement( 'UFPP_N'));
      for i := 0 to aSource.ChildNodes.length -1 do begin
        xNode := aSource.childNodes.items[ i];
        case xNode.NodeName of
          'UFPP'  : xNodeUFPP.AppendChild( xNode.CloneNode( FALSE));
          'UFPP_N': xNodeUFPP_N.AppendChild( xNode.CloneNode( FALSE));
        end;//case//
      end;//for//



      // формируем эд 215го из временного xml
      Result := DoCreateDoc215_UF(  xDoc,
                                    aBudgetID,
                                    aTO_KOD_UBP,
                                    aIK_LS,
                                    aCfgIgnoreBadKBK,
                                    aCfgResetBadKBK,
                                    aValidate,
                                    '',
                                    aLogToInfo);
      except
        ExceptionLog( 'Сбой DoCreateDoc215_UF_IK');
    end;

end;


{~Search_ED114_By_IK_UF
  поиск эд 114го класса при загрузке IK.UF.
  изначально поиск реализован по функции GetAnswerDocId.

  exchange #2930
  Требуется расширить условие поиска ЭД класса 114 следующим образом:
    Если ЭД класса 114 по реквизитам UF. NOM_UF, UF.DATE_UF, IK.LS_UBP
    не найден (по условиям текущей реализации),
    то требуется искать ЭД класса 114 по UF. NOM_UF и UF.DATE в любом статусе,
    кроме «Удален» (-1) или «Отказан» (7).

  Если ЭД класса 114 с номером и датой, равными UF. NOM_UF и UF.DATE
  соответственно, найден, то  требуется проверить наличие  целевой
  строки (уточненной строки) в ЭД с реквизитами:
    - «Счет» = IK.LS_UBP;
    - «Вид классификации»,  равном: «Доходы», если UFPP_N. TYPE_KBK=”20” ,
      «Расходы» - “10”, «Источники» - “31” или “32”;
    - «КВСР»+ «КФСР»+ «КЦСР»+ «КВР»+ «КОСГУ» + «Код цели» = UFPP_N.KBK
      + UFPP_N.ADD_KLASS  для вида классификации «Расходы»;
    - «Гл. администратор»+ «КВД» + «КОСГУ»+ «Код цели»= UFPP_N.KBK
      + UFPP_N.ADD_KLASS  для вида классификации «Доходы»;
    - «Гл. администратор»+ «КВИ» + «КОСГУ»+ «Код цели»= UFPP_N.KBK
      + UFPP_N.ADD_KLASS  для вида классификации «Источники»;
    - «Сумма», равном  UFPP_N.SUM, если UFPP_N_SUM пустая, то UFPP.SUM_PP.

  Если равенство соблюдается, то ЭД класса 215 формировать не требуется,
  переходить к следующему документу загружаемого блока UF.
  В журнал загрузки вынести сообщение о том, что найден документ
  «Уведомление об уточнении принадлежности платежа» с номером <>
  и датой <> на сумму <> в статусе <>, поэтому справка  не сформирована.}
function Search_ED114_By_IK_UF( //aDoc114: variant;
                                aDoc114_Number, aDoc114_Date: string;
                                aSource: Variant;
                                aBudgetID: string;
                                aIK_LS: string): string;
var
  xXML: Variant;
  Q: TRunQuery;
  i,i2,i3: integer;
  xXmlLines: Variant;
  xXmlLine: Variant;
  xSource_UFPP_N: Variant;
  xED114ID: string;
  xLine_ANAL_KIND: string;
  xUFPP_N_TYPE_KBK: string;
  xLine_KBK: string;
  xUFPP_N_KBK: string;
  xUFPP_N_PurposefullgrantID: string;
  xLine_Purposefullgrant: string;
  xUFPP_N_SUM: string;
begin

    try
      Result := '';

      xXML := CreateOleObject('Microsoft.XmlDom');

      Q := TRunQuery.Create;
      try

        // проверяем статус выгрузки: не "удален" или не «Отказан» (7)
        // статус выгрузки не проверяем
        Q.AddStr( aBudgetID);
        Q.AddStr( '114');
        Q.AddStr( aDoc114_Number);//.getAttribute('DOC_NUMBER'));
        Q.AddDate( StrToDate( aDoc114_Date));//.getAttribute('DOC_DATE')));
        Q.AddStr( aIK_LS);
        xXML.LoadXml(
                Q.Run( ' Select A.Id From Document D'
                      +' Left Join PayDetail A on A.Document_Id = D.Id'
                      +' Where D.Budget_Id = ? and not D.DispStatus_Id in (-1,7)'
                      +' and D.DocumentClass_Id = ? and LTrim(D.Doc_Number) = ?'
                      +' and D.Doc_Date = ?'
                      +' and A.Org_Account = ?'
                      // здесь получаем только такие эд,
                      // у которых есть целевые строки
                      +' and exists (select * from paydetailline AL'
                      +' where AL.paydetail_id = A.ID'
                      +' and AL.IS_SOURCE_LINE=0)'));   // нужны только dslline

        // если ничего не нашли - делать больше нечего
        if (xXML.documentElement.childNodes.Length <= 0)
          then EXIT;
        finally
          Q.Free;
      end;

      // перебираем все найденные эд
      xXML := xXML.documentElement;
      for i := 0 to xXML.childNodes.Length - 1 do begin
        xED114ID := xXML.childNodes.Item[ i].GetAttribute('ID');

        xXmlLines := QueryXml( ' select * from paydetailline AL'
                              +' where AL.paydetail_id = ?'
                              +' and AL.IS_SOURCE_LINE=0',
                               [ xED114ID]);

        // по каждому найденному эд 114го класса загружаем все целевые строки
        xXmlLines := xXmlLines.documentElement;
        for i2 := 0 to xXmlLines.childNodes.Length - 1 do begin
          xXmlLine := xXmlLines.childNodes.Item[ i2];


          // перебираем все разделы UFPP_N
          for i3 := 0 to aSource.ChildNodes.length -1 do begin
            xSource_UFPP_N := aSource.childNodes.items[ i3];
            if (xSource_UFPP_N.NodeName <> 'UFPP_N')
              then CONTINUE;


            // раздел UFPP_N сверяем с целевой строкой
            // сумма: если в UFPP_N поле SUM пустая, подставляем 0.00
            // и сравниваем с суммой в строке
            xUFPP_N_SUM := VarToStr( xSource_UFPP_N.GetAttribute( 'SUM'));
            if (LENGTH( xUFPP_N_SUM) <= 0)
              then xUFPP_N_SUM := '0.00';

            if (xXmlLine.GetAttribute( 'AMOUNT') <> xUFPP_N_SUM)
              then CONTINUE;

            // вид классификации строки сохраняем
            xLine_ANAL_KIND := xXmlLine.GetAttribute( 'ANAL_KIND');

            // тип КБК=вид классификации
            // тип КБК из UFPP_N. если поле пустое - подставляем доходы (20)
            xUFPP_N_TYPE_KBK := GetNodeAttributeEx( xSource_UFPP_N, 'TYPE_KBK');
            {
            xUFPP_N_TYPE_KBK := VarToStr(
                                     xSource_UFPP_N.GetAttribute( 'TYPE_KBK'));}
            if (LENGTH( xUFPP_N_TYPE_KBK) <= 0)
              then xUFPP_N_TYPE_KBK := '20';

            case xLine_ANAL_KIND of
              '0': if (xUFPP_N_TYPE_KBK <> '10')
                     then CONTINUE;
              '1': if (xUFPP_N_TYPE_KBK <> '20')
                     then CONTINUE;
              '2': if NOT (xUFPP_N_TYPE_KBK in ['31','32'])
                     then CONTINUE;
              else CONTINUE;
            end;//case//

            // код цели
            // если поле в UFPP_N не заполнено - ищем нулевой код цели
            xUFPP_N_PurposefullgrantID :=
                        GetPurposefullGraintIDByUF_(
                            GetNodeAttributeEx( xSource_UFPP_N, 'ADD_KLASS'),
//                            VarToStr( xSource_UFPP_N.GetAttribute( 'ADD_KLASS')),
                            TRUE,
                            aBudgetID);
            case xLine_ANAL_KIND of
              '0': xLine_Purposefullgrant := 'PURPOSEFULGRANT_ID';
              '1': xLine_Purposefullgrant := 'PURPOSEFULGRANTD_ID';
              '2': xLine_Purposefullgrant := 'PURPOSEFULGRANTI_ID';
            end;//case//

            if ( xXmlLine.GetAttribute( xLine_Purposefullgrant)
                 <> xUFPP_N_PurposefullgrantID)
              then CONTINUE;

            // КБК
            // exchange #3062 - уницикация кода
            xLine_KBK := GetRuleKBKLineEx( xXmlLine,
                                           STRTOINT( xLine_ANAL_KIND),
                                           '',
                                           '',
                                           FALSE,   // косгу отменен
                                           FALSE);  // форматирование не нужно
                                           {
            case xLine_ANAL_KIND of
              '0': xLine_KBK := VarToStr( xXmlLine.GetAttribute( 'KADMR_CODE'))
                               +VarToStr( xXmlLine.GetAttribute( 'KFSR_CODE'))
                               +VarToStr( xXmlLine.GetAttribute( 'KCSR_CODE'))
                               +VarToStr( xXmlLine.GetAttribute( 'KVR_CODE'))
                               +VarToStr( xXmlLine.GetAttribute( 'KESR_CODE'));
              '1': xLine_KBK := VarToStr( xXmlLine.GetAttribute( 'KADMD_CODE'))
                               +VarToStr( xXmlLine.GetAttribute( 'KD_CODE'))
                               +VarToStr( xXmlLine.GetAttribute( 'KESD_CODE'));
              '2': xLine_KBK := VarToStr( xXmlLine.GetAttribute( 'KADMI_CODE'))
                               +VarToStr( xXmlLine.GetAttribute( 'KI_CODE'))
                               +VarToStr( xXmlLine.GetAttribute( 'KESI_CODE'));
            end;//case//                    }
            // если поле UFPP_N.KBK пустое - то заполняем его всеми нулями.
            // так же если там указан один 0, то так же дополняем строку
            // нулями слева.
            xUFPP_N_KBK := VarToStr( xSource_UFPP_N.GetAttribute( 'KBK'));
            while (LENGTH( xUFPP_N_KBK) < 20)
              do xUFPP_N_KBK := '0' + xUFPP_N_KBK;

            if (xLine_KBK <> xUFPP_N_KBK)
              then CONTINUE;

            // если строка нам подошла - тогда считаем эд найденным.
            // остальные эд даже проверяем, даже если таких эд будет несколько
            // дальнейший поиск прерываем.

            Result := xED114ID;
            EXIT;

          end;//for//


        end;//for//


      end;//for//
      except
        ExceptionLog( 'Сбой Search_ED114_By_IK_UF');
    end;

end;

begin
end.
