{~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.
}
function DoCreateDoc215_UF( var aSource: Variant;
                            aBudgetID: string;
                            {aTO_KOD_UBP,} aBH_LS{, 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}
  function CheckUF_Lines_( aUF_Lines: Variant): boolean;
  var
    xNode: Variant;
    i: integer;
    s: string;
    xUF_Line: string;
    xUFPP_N_LS_UBP: string;
    xCheck_UFPP_N_LS_UBP: boolean;
    xIsUFPP: boolean;
    xFatalError: boolean;
    xKBK: string;
    xTypeKBK: string;
    xUF_Line_SumPP: string;
  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';

          if xCheck_UFPP_N_LS_UBP then begin
            { если проверка строки UFPP_N:
              проверяем по ФТ-1 все поля UFPP_N.LS_UBP.
              UFPP_N.LS_UBP если значение не пустое (анализируем только непустое
              значение реквизита).
              В справочнике «Счета организаций» должна быть строка со значением
              «Счет» равным  значению одного из вышеуказанных реквизитов,
              с типом «Лицевой счет в ФК», «Лицевой счет по доходам в ФК»,
              «Лицевой счет по источникам в ФК», «Лицевой счет бюджета в ФК»,
              с пустой датой блокирования. Причем организация – владелец данного
              счета должна иметь включенную галку активности и пустую дату закрытия.}
            xUFPP_N_LS_UBP := VarToStr( xNode.GetAttribute( 'LS_UBP'));
            if (LENGTH( xUFPP_N_LS_UBP) > 0) then
              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,8,9)'
                             +' and b.id=?'
                             +' and oa.close_date is null'
                             +' and o.close_date is null',
                              [ xUFPP_N_LS_UBP,
                                aBudgetID],
                              'N') <> '1')
                then begin
                  // поскольку перед вызовом этой функции в журнале (log) уже
                  // есть сообщение о проверке раздела по UF, то тот дописываем
                  // только конкретное сообщение.
                  // под номером строки отображаем порядковый номер строки в
                  // разделе UF (начиная с 1), а не поле LINE_NOM
                  WriteInfo( FORMAT( 'В строке %s %s не найден счет %s в БД.',
                                    [ aUF_Lines.NodeName,
                                      INTTOSTR( i + 1),
                                      xUFPP_N_LS_UBP]));
                  // строка UFPP_N не прошла проверку
                  s := 'error';
                end;
          end;

          // проверяем заполнение КБК и тип КБК
          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
              WriteInfo( FORMAT( 'ЭД не создается - в строке UFPP с номером %s поле суммы (SUM_PP) не заполнено.',
                                 [ INTTOSTR( i + 1)]));
              s := 'error';
              xFatalError := TRUE;
            end;
          end else
            if (xUF_Line_SumPP = '0.00') 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)]));
              s := 'error';
              xFatalError := TRUE;
            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}
  function QueryDoc_( aTable, aID: string): Variant;
  begin

      try
        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;
//  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;
  //----------------------------------------------------------------------------
  {~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;
  //----------------------------------------------------------------------------
  {~DoAddLineED215_
    создание строки в создаваемом ЭД 215го класса.
    здесь проверяем, если тега LINES нету - создаем его.
    затем в теге LINES создаем новую строку LINE.
    результат:
      переменная xDocLine будет содержать узел с описанием новой строки.}
  procedure DoAddLineED215_;
  begin

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

        end;
        xDocLine := xDocLines.appendChild( xDocXml.CreateElement( 'LINE'));
        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;
  //----------------------------------------------------------------------------
  {~DoFillOrgAndLS_
    заполнение орг., счета, ТоУФК, УФК по описанию орг xOrgXml и счета xLSXml}
  procedure DoFillOrgAndLS_( aOrgID: string;
                             aOrgXml: variant;
                             aLS: string;
                             aLSXml: variant);
  var
    xLS_KEEPER_ID: string;
    xLS_EXECUTER_ID: string;
    xLS_EXECUTERACC_ID: string;
  begin

      try
        if NOT VarIsNULL( aOrgXml) then begin
          xDocLine.SetAttribute( 'ORG_ID',
                                  aOrgID);
          xDocLine.SetAttribute( 'ORG_TAXCODE',
                                  aOrgXml.GetAttribute( 'TAXCODE'));
          xDocLine.SetAttribute( 'ORG_KPP',
                                  aOrgXml.GetAttribute( 'KPP'));
          xDocLine.SetAttribute( 'ORG_NAME',
                                  aOrgXml.GetAttribute( 'DESCRIPTION'));

          // лицевой счет
          xDocLine.SetAttribute( 'ORG_ACCOUNT', aLS);

          // если описание счета не определено, реквизиты счета не заполняем
          if NOT VarIsNULL( aLSXml) then begin
            xDocLine.SetAttribute( 'ORGACCOUNT_ID',
                                    aLSXml.GetAttribute( 'ID'));

            xLS_KEEPER_ID := aLSXml.GetAttribute( 'KEEPER_ID');
            xLS_EXECUTER_ID := aLSXml.GetAttribute( 'EXECUTER_ID');

            // ТОФК - Значение поля «ТОФК» карточки лицевого счета.
            // Если ТОФК=УФК, то не заполнять.
            if (LENGTH( xLS_KEEPER_ID) > 0) then
              if ( xLS_KEEPER_ID <> xLS_EXECUTER_ID)
                then xDocLine.SetAttribute(
                            'ORG_OFK_NAME',
                            QueryField( ' select CAPTION from org'
                                       +' where id=?',
                                        [ xLS_KEEPER_ID],
                                        'CAPTION'));
            // УФК из счета
            if (LENGTH( xLS_EXECUTER_ID) > 0) then begin

              // УФК - Значение поля «УФК» карточки лицевого счета.
              xDocLine.SetAttribute(
                            'ORG_UFK_NAME',
                            QueryField( ' select DESCRIPTION from org'
                                       +' where id=?',
                                        [ xLS_EXECUTER_ID],
                                        'DESCRIPTION'));
              // Счет УФК, если УФК заполнено
              xLS_EXECUTERACC_ID := aLSXml.GetAttribute( 'EXECUTERACC_ID');

              xDocLine.SetAttribute(
                            'ORG_UFK_ACC_ID',
                            xLS_EXECUTERACC_ID);
              if (LENGTH( xLS_EXECUTERACC_ID) > 0) then begin

                // Счет УФК	- Значение поля «Единый счет бюджета»
                xDocLine.SetAttribute(
                            'ORG_UFK_ACCOUNT',
                            QueryField( ' select ACCOUNT_NUMBER'
                                       +' from orgaccount where id=?',
                                        [ xLS_EXECUTERACC_ID],
                                        'ACCOUNT_NUMBER'));
                // БИК - Значение одноименных полей карточки счета
                // «Единый счет бюджета»
                xDocLine.SetAttribute(
                            'ORG_BIC',
                            QueryField( ' select b.BIC, b.DESCRIPTION'
                                       +' from orgaccount oa'
                                       +' join BANK b on b.id=oa.BANK_ID'
                                       +' where oa.id=?',
                                        [ xLS_EXECUTERACC_ID],
                                        'BIC'));
                // БАНК - Значение одноименных полей карточки счета
                // «Единый счет бюджета»
                xDocLine.SetAttribute(
                            'ORG_B_NAME',
                            QueryField( ' select b.BIC, b.DESCRIPTION'
                                       +' from orgaccount oa'
                                       +' join BANK b on b.id=oa.BANK_ID'
                                       +' where oa.id=?',
                                        [ xLS_EXECUTERACC_ID],
                                        'DESCRIPTION'));
              end;
            end;
          end;

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

  end;
  //----------------------------------------------------------------------------
  {~DoAddLine_
    добавление строки в эд 215го класса по блоку UFPP_N или UFPP в aUF_Line
    с названием в aUF_Line_Name (строка UFPP или UFPP_N) и номером строки
    в файле aUF_Line_Index.}
  procedure DoAddLineByUF_Line_( aLS: string;
                                 aUF_Line: Variant;
                                 aUF_Line_Name: string;
                                 aUF_Line_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;
    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;
    xEstimateLS: string;

    {~QueryEstimateID_
      «Бланк расходов» - организация – оператор бланка расходов должна
      быть владельцем лицевого счета  UFPP_N.LS_UBP, если UFPP_N.LS_UBP не
      заполнено в структурированном файле, то BH.LS.
      Счет должен быть с пустой датой блокирования, с типом «Лицевой счет в ФК»
      (5) либо «Лицевой счет бюджета в ФК» (9);
      проверяется дата закрытия орг и счета + актуальность орг.

      exchange #2908
      здесь нужно проверить тип бланка расходов на тип: смета(=1) или ПНО(=7)}
    function QueryEstimateID_( aLSType, aSelect, aField: string): string;
    begin

        try
          if ( LENGTH( aLSType) > 0)
            // с проверкой типа счета
            then Result := QueryField(
                             ' select ' + aSelect +' from ESTIMATE e'
                            +' join org o on o.id = e.org_id'
                            // актуальность орг.
                            +' Join Contractor C on C.Org_Id = O.Id'
                            +' Left Join Budget B on B.Org_Id = C.Inspector_Id'
                            +'   and b.id=e.budget_id'
                            +' where e.budget_id=?'
                            // тип бланка расходов: смета или ПНО
                            +' and e.ESTKIND_ID in (1,7)'
                            +' and (o.CLOSE_DATE is null or o.close_date>?)'
                            +' and exists (select * from orgaccount oa'
                            +'   where oa.org_id=o.id'
                            +'   and oa.orgacctype_id in (' + aLSType + ')'
                            +'   and oa.account_number=?'
                            // Счет должен быть с пустой датой блокирования
                            +'   and (oa.close_date is null))',
                             [ aBudgetID,
                               Work_Date,
                               xEstimateLS],
                             aField)
            // без проверки типа счета
            else Result := QueryField(
                             ' select ' + aSelect +' from ESTIMATE e'
                            +' join org o on o.id = e.org_id'
                            // актуальность орг.
                            +' Join Contractor C on C.Org_Id = O.Id'
                            +' Left Join Budget B on B.Org_Id = C.Inspector_Id'
                            +'   and b.id=e.budget_id'
                            +' where e.budget_id=?'
                            // тип бланка расходов: смета или ПНО
                            +' and e.ESTKIND_ID in (1,7)'
                            +' and (o.CLOSE_DATE is null or o.close_date>?)'
                            +' and exists (select * from orgaccount oa'
                            +'   where oa.org_id=o.id'
                            +'   and oa.account_number=?'
                            // Счет должен быть с пустой датой блокирования
                            +'   and (oa.close_date is null))',
                             [ aBudgetID,
                               Work_Date,
                               xEstimateLS],
                             aField);
          except
            ExceptionLog( 'Сбой QueryEstimateID_');
        end;

    end;

    {~QueryExp_
      поиск строки рчб с учетом найденного бланка расходов:
      1) по КБК+код цели+бланк расходов
      если не нашли, то:
      2) по КБК+код цели+бланк расходов + бюджетополучатель (exchange #2916)

      exchange #2916
         если нашли несколько строк, то ищем в РЧБ повторно с учетом
         бюджетополучателя, с ИНН=UK.INN_PL и КПП=UF.KPP_PL.
         проблема в том, что эти поля необязательны для заполнения.
         если инн не заполнен, то даже не пытаемся искать по кпп.
         если инн заполнен, то если кпп не заполнен то ищем без кпп.
         если инн не заполнен, то поиск не выполняем и сразу выходим
         с отрицательным результатом.

     здесь же в лог info заносим информацию о результатах поиска.}
    procedure QueryExp_;
    var
      xSQL: string;
      xFound: string;
    begin

        try
          WriteLog( 'Поиск строк в РЧБ с найденным бланком расходов...');

          xExp := NULL;

          xSQL := ' From ExpBudget'
                 +' Where Budget_Id = ?'
                 +' and Estimate_Id = ?'
                 +' and Kfsr_Code = ?'
                 +' and Kvr_Code = ?'
                 // exchange #3062 - убрано косгу
//                 +' and Kesr_Code = ?'
                 +' and Kcsr_Code = ?'
                 +' and Kadmr_Code = ?'
                 +' and PURPOSEFULGRANT_ID = ?';

          xFound := QueryField( ' Select count( * ) N ' + xSQL,
                                [ aBudgetID,
                                  xESTIMATE_ID,
                                  xKFSR_CODE,
                                  xKVR_CODE,
                                  // exchange #3062 - убрано косгу
                                  //xKESR_CODE,
                                  xKCSR_CODE,
                                  xKADMR_CODE,
                                  xPurpgrID],
                                'N');
          if (xFound <> '1') then begin
            // если не нашли ни одной строки - сразу выходим
            if (xFound = '0') then begin
              WriteInfo( 'Не найдена строка в РЧБ с найденным бланком расходов.');
              EXIT;
            end;

            // exchange #2916
            // если нащли несколько строк в рчб, ищем с учетом бюджетополучателя,
            // с ИНН=UK.INN_PL и КПП=UF.KPP_PL.
            WriteInfo( FORMAT( 'Найдено несколько (%s) строк в РЧБ с найденным бланком расходов.',
                               [ xFound]));
            // если инн не заполнен, то даже не пытаемся искать по кпп.
            // если инн заполнен, то если кпп не заполнен то ищем без кпп.
            // если инн не заполнен, то поиск не выполняем и сразу выходим
            // с отрицательным результатом.
            WriteInfo( FORMAT( 'Поиск строк в РЧБ с найденным бланком расходов и бюджетополучателем (UF.INN_PL=%s, UF.KPP_PL=%s)...',
                               [ xUF_INN_PL,
                                 xUF_KPP_PL]));
            if (LENGTH( xUF_INN_PL) <= 0) then begin
              WriteInfo( 'Бюджетополучатель не указан - повторный поиск строк в РЧБ не выполняется.');
              EXIT;
            end;
            if (LENGTH( xUF_KPP_PL) <= 0) then begin
              // только с ИНН
              xFound := QueryField(  ' Select count( * ) N ' + xSQL
                                    +' and recipient_id in (select o.id from org o'
                                    +' where o.taxcode=?)',
                                    [ aBudgetID,
                                      xESTIMATE_ID,
                                      xKFSR_CODE,
                                      xKVR_CODE,
                                      // exchange #3062 - убрано косгу
                                      //xKESR_CODE,
                                      xKCSR_CODE,
                                      xKADMR_CODE,
                                      xPurpgrID,
                                      xUF_INN_PL],
                                      'N');
              if (xFound <> '1') then begin
                if (xFound = '0')
                  then WriteInfo( 'Не найдена строка в РЧБ с найденным бланком расходов и бюджетополучателем.')
                  else WriteInfo( FORMAT( 'Найдено несколько (%s) строк в РЧБ с найденным бланком расходов и бюджетополучателем.',
                                          [ xFound]));
                EXIT;
              end;
              xExp := QueryXml(  ' Select * ' + xSQL
                                +' and recipient_id in (select o.id from org o'
                                +' where o.taxcode=?)',
                                [ aBudgetID,
                                  xESTIMATE_ID,
                                  xKFSR_CODE,
                                  xKVR_CODE,
                                  // exchange #3062 - убрано косгу
                                  //xKESR_CODE,
                                  xKCSR_CODE,
                                  xKADMR_CODE,
                                  xPurpgrID,
                                  xUF_INN_PL]);
            end else begin
              // ИНН+КПП
              xFound := QueryField(  ' Select count( * ) N ' + xSQL
                                    +' and recipient_id in (select o.id from org o'
                                    +' where o.taxcode=? and o.kpp=?)',
                                    [ aBudgetID,
                                      xESTIMATE_ID,
                                      xKFSR_CODE,
                                      xKVR_CODE,
                                      // exchange #3062 - убрано косгу
                                      //xKESR_CODE,
                                      xKCSR_CODE,
                                      xKADMR_CODE,
                                      xPurpgrID,
                                      xUF_INN_PL,
                                      xUF_KPP_PL],
                                      'N');
              if (xFound <> '1') then begin
                if (xFound = '0')
                  then WriteInfo( 'Не найдена строка в РЧБ с найденным бланком расходов и бюджетополучателем.')
                  else WriteInfo( FORMAT( 'Найдено несколько (%s) строк в РЧБ с найденным бланком расходов и бюджетополучателем.',
                                          [ xFound]));
                EXIT;
              end;
              xExp := QueryXml(  ' Select * ' + xSQL
                                +' and recipient_id in (select o.id from org o'
                                +' where o.taxcode=? and o.kpp=?)',
                                [ aBudgetID,
                                  xESTIMATE_ID,
                                  xKFSR_CODE,
                                  xKVR_CODE,
                                  // exchange #3062 - убрано косгу
                                  //xKESR_CODE,
                                  xKCSR_CODE,
                                  xKADMR_CODE,
                                  xPurpgrID,
                                  xUF_INN_PL,
                                  xUF_KPP_PL]);
            end;
          end else begin
            xExp := QueryXml( ' Select * ' + xSQL,
                              [ aBudgetID,
                                xESTIMATE_ID,
                                xKFSR_CODE,
                                xKVR_CODE,
                                // exchange #3062 - убрано косгу
                                //xKESR_CODE,
                                xKCSR_CODE,
                                xKADMR_CODE,
                                xPurpgrID]);
          end;
          if (xExp.documentElement.childNodes.length <> 1)
            then xExp := NULL
            else xExp := xExp.documentElement.childNodes.item[ 0];
          except
            ExceptionLog( 'Сбой QueryExp_');
        end;

    end;

    {~QueryOrg20_
      поиск организации – владельца лицевого счета:
      Если значение реквизита  UFPP_N.LS_UBP (BH.LS) соответствует одному
      из счетов с типом «Лицевой счет по доходам в ФК» (8)
      или «Лицевой счет бюджета в ФК» (9).}
    function QueryOrg20_( aLSType, aSelect, aField: string): string;
    begin

        try
          if ( LENGTH( aLSType) > 0)
            // с проверкой типа счета
            then Result := QueryField(
                                 'select ' + aSelect + ' from org o'
                                // актуальность орг.
                                +' Join Contractor C on C.Org_Id = O.Id'
                                +' Left Join Budget B on B.Org_Id = C.Inspector_Id'
                                +' where b.id=?'
                                +' and (o.CLOSE_DATE is null or o.close_date>?)'
                                +' and exists (select * from orgaccount oa'
                                +'   where oa.org_id=o.id'
                                +'   and oa.orgacctype_id in (' + aLSType + ')'
                                +'   and oa.account_number=?'
                                +'   and (oa.close_date is null or oa.close_date>?))',
                                 [ aBudgetID,
                                   Work_Date,
                                   aLS,
                                   Work_Date],
                                 aField)
            // без проверки типа счета
            else Result := QueryField(
                                 'select ' + aSelect + ' from org o'
                                // актуальность орг.
                                +' Join Contractor C on C.Org_Id = O.Id'
                                +' Left Join Budget B on B.Org_Id = C.Inspector_Id'
                                +' where b.id=?'
                                +' and (o.CLOSE_DATE is null or o.close_date>?)'
                                +' and exists (select * from orgaccount oa'
                                +'   where oa.org_id=o.id'
                                +'   and oa.account_number=?'
                                +'   and (oa.close_date is null or oa.close_date>?))',
                                 [ aBudgetID,
                                   Work_Date,
                                   aLS,
                                   Work_Date],
                                 aField);
          except
            ExceptionLog( 'Сбой QueryOrg20_');
        end;

    end;

    {~QueryInc_
      поиск строки дчб}
    procedure QueryInc_;
    begin

        try
          if (QueryField( ' Select count( * ) N From IncBudget'
                         +' Where Budget_Id = ?'
                         +' and RECEIVER_ID = ?'
                         +' and KADMD_CODE = ?'
                         +' and KD_CODE = ?'
                         // exchange #3062 - убрано косгу
//                         +' and KESD_CODE = ?'
                         +' and PURPOSEFULGRANTD_ID = ?',
                          [ aBudgetID,
                            xRECEIVER_ID,
                            xKADMD_CODE,
                            xKD_CODE,
                            // exchange #3062 - убрано косгу
                            //xKESD_CODE,
                            xPurpgrID],
                          'N') <> '1')
            then EXIT;

          xInc := QueryXml( ' Select * From IncBudget'
                           +' Where Budget_Id = ?'
                           +' and RECEIVER_ID = ?'
                           +' and KADMD_CODE = ?'
                           +' and KD_CODE = ?'
                           // exchange #3062 - убрано косгу
  //                         +' and KESD_CODE = ?'
                           +' and PURPOSEFULGRANTD_ID = ?',
                            [ aBudgetID,
                              xRECEIVER_ID,
                              xKADMD_CODE,
                              xKD_CODE,
                              // exchange #3062 - убрано косгу
//                              xKESD_CODE,
                              xPurpgrID]);

          if (xInc.documentElement.childNodes.length <> 1)
            then xInc := NULL
            else xInc := xInc.documentElement.childNodes.item[ 0];
          except
            ExceptionLog( 'Сбой QueryInc_');
        end;

    end;

    {~QueryOrg31_
      поиск организации для источников:
      Если значение реквизита  UFPP_N.LS_UBP (BH.LS) есть среди счетов
      организации.}
    function QueryOrg31_( aSelect, aField: string): string;
    begin

        try
          Result := QueryField(  'select ' + aSelect + ' from org o'
                                // актуальность орг.
                                +' Join Contractor C on C.Org_Id = O.Id'
                                +' Left Join Budget B on B.Org_Id = C.Inspector_Id'
                                +' where b.id=?'
                                +' and (o.CLOSE_DATE is null or o.close_date>?)'
                                +' and exists (select * from orgaccount oa'
                                +'   where oa.org_id=o.id'
                                +'   and oa.account_number=?'
                                +'   and (oa.close_date is null or oa.close_date>?))',
                                 [ aBudgetID,
                                   Work_Date,
                                   aLS,
                                   Work_Date],
                                 aField);
          except
            ExceptionLog( 'Сбой QueryOrg31_');
        end;

    end;

    {~QuerySrc_
      поиск строки ичб}
    procedure QuerySrc_;
    begin

        try
          if (QueryField( ' Select count( * ) N From SrcBudget'
                         +' Where Budget_Id = ?'
                         +' and KADMI_CODE = ?'
                         +' and KI_CODE = ?'
                         // exchange #3062 - убрано косгу
                         //+' and KESI_CODE = ?'
                         +' and PURPOSEFULGRANTI_ID = ?',
                          [ aBudgetID,
                            xKADMI_CODE,
                            xKI_CODE,
                            // exchange #3062 - убрано косгу
                           // xKESI_CODE,
                            xPurpgrID],
                          'N') <> '1')
            then EXIT;

          xSrc := QueryXml( ' Select * From SrcBudget'
                           +' Where Budget_Id = ?'
                           +' and KADMI_CODE = ?'
                           +' and KI_CODE = ?'
                           // exchange #3062 - убрано косгу
                           //+' and KESI_CODE = ?'
                           +' and PURPOSEFULGRANTI_ID = ?',
                            [ aBudgetID,
                              xKADMI_CODE,
                              xKI_CODE,
                              // exchange #3062 - убрано косгу
                              //xKESI_CODE,
                              xPurpgrID]);

          if (xSrc.documentElement.childNodes.length <> 1)
            then xSrc := NULL
            else xSrc := xSrc.documentElement.childNodes.item[ 0];
          except
            ExceptionLog( 'Сбой QuerySrc_');
        end;

    end;

    {~QueryReceiver_
      определение получателя для доходов }
    function QueryReceiver_( aSelect, aField: string): string;
    begin

        try
          Result := QueryField( ' select ' + aSelect + ' from RECEIVER r'
                               +' where r.ISACTUAL = 1 and r.org_id=?',
                                [ xOrgID],
                                aField);
          except
            ExceptionLog( 'Сбой QueryReceiver_');
        end;

    end;


    {~QueryExpEstimate_
      требуется определить по строкам РЧБ бланк расходов.
      результат:
        =true - результат определен.
        =false - бланк расходов не определен.

      запрашиваем рчб с кбк для таких строк, которые имеют бланк расходов
      владельца указанного счета с типом aLS_Type.
      в результате возвращается столько бланков расходов, сколько есть их
      разных в строках рчб

      exchange #2908
      здесь нужно проверить тип бланка расходов на тип: смета(=1) или ПНО(=7)

      exchange #2916
      «Бланк расходов» - тип бланка расходов должен быть "Смета" или "ПНО";
      организация – оператор бланка расходов должна быть владельцем лицевого
      счета  UFPP_N.LS_UBP,
      если UFPP_N.LS_UBP не заполнено в структурированном файле, то IK.LS_UBP.
      Счет должен быть с пустой датой блокирования, с типом
      «Лицевой счет в ФК» (5) либо «Лицевой счет бюджета в ФК» (9);

      добавлен параметр aWithReceipientUF:
        =true - требуется искать в РЧБ с учетом бюджетополучателя со
                значениями ИНН из UF.INN_PL и КПП = UF.KPP_PL.
        =false - без учета бюджетополучателя}
    function QueryExpEstimate_( aLSType: string;
                                aWithReceipientUF: boolean = FALSE): boolean;
    var
      xSubQuery: string;
      xSQL: string;
    begin

        try
          if (LENGTH( aLSType) <= 0)
            then xSubQuery := ''
            else xSubQuery := ' and oa.orgacctype_id in (' + aLSType + ')';

          xSQL := ' Select distinct Estimate_Id X From ExpBudget'
                 +' Where Budget_Id = ?'
                 +' and Kfsr_Code = ?'
                 +' and Kvr_Code = ?'
                 // exchange #3062 - убрано косгу
//                 +' and Kesr_Code = ?'
                 +' and Kcsr_Code = ?'
                 +' and Kadmr_Code = ?'
                 +' and PURPOSEFULGRANT_ID = ?'
                 +' and Estimate_Id in ('
                 +'   select e.id from ESTIMATE e'
                 +' join org o on o.id = e.org_id'
                  // актуальность орг.
                 +' Join Contractor C on C.Org_Id = O.Id'
                 +' Left Join Budget B on B.Org_Id = C.Inspector_Id'
                 +'   and b.id=e.budget_id'
                 +' where e.budget_id=?'
                 // тип бланка расходов: смета или ПНО
                 +' and e.ESTKIND_ID in (1,7)'
                 +' and (o.CLOSE_DATE is null or o.close_date>?)'
                 +' and exists (select * from orgaccount oa'
                 +'   where oa.org_id=o.id'
                 +xSubQuery
                 +'   and oa.account_number=?'
                 // Счет должен быть с пустой датой блокирования
                 +'   and (oa.close_date is null)))';

          // exchange #2916
          // если ищем с учетом бюджетополучателя, анализируем поля UK.INN_PL
          // и UF.KPP_PL на предмет заполнения. проблема в том, что эти поля
          // необязательны для заполнения. если инн не заполнен, то даже не
          // пытаемся искать по кпп. если инн заполнен, то если кпп не заполнен
          // то ищем без кпп.
          // если инн не заполнен, то поиск не выполняем и сразу выходим
          // с отрицательным результатом.
          if aWithReceipientUF then begin

            if (LENGTH( xUF_INN_PL) <= 0) then begin
              xFoundAcount := 0;
              xESTIMATE_ID := '';
              Result := FALSE;
              EXIT;
            end;
            if (LENGTH( xUF_KPP_PL) <= 0) then begin
              // только с ИНН
              xExp := QueryXml( xSQL
                                +' and recipient_id in (select o.id from org o'
                                +' where o.taxcode=?)',
                                [ aBudgetID,
                                  xKFSR_CODE,
                                  xKVR_CODE,
                                  // exchange #3062 - убрано косгу
                                 // xKESR_CODE,
                                  xKCSR_CODE,
                                  xKADMR_CODE,
                                  xPurpgrID,
                                  aBudgetID,
                                  Work_Date,
                                  xEstimateLS,
                                  xUF_INN_PL]);
            end else begin
              // ИНН+КПП
              xExp := QueryXml( xSQL
                                +' and recipient_id in (select o.id from org o'
                                +' where o.taxcode=? and o.kpp=?)',
                                [ aBudgetID,
                                  xKFSR_CODE,
                                  xKVR_CODE,
                                  // exchange #3062 - убрано косгу
                                  //xKESR_CODE,
                                  xKCSR_CODE,
                                  xKADMR_CODE,
                                  xPurpgrID,
                                  aBudgetID,
                                  Work_Date,
                                  xEstimateLS,
                                  xUF_INN_PL,
                                  xUF_KPP_PL]);
            end;
          end else begin
            // без бюджетополучателя
            xExp := QueryXml( xSQL,
                              [ aBudgetID,
                                xKFSR_CODE,
                                xKVR_CODE,
                                // exchange #3062 - убрано косгу
                                //xKESR_CODE,
                                xKCSR_CODE,
                                xKADMR_CODE,
                                xPurpgrID,
                                aBudgetID,
                                Work_Date,
                                xEstimateLS]);
          end;

          xFoundAcount := xExp.documentElement.childNodes.length;
          if (xFoundAcount <> 1) then begin



            Result := FALSE;
            xESTIMATE_ID := '';
          end else begin



            Result := TRUE;
            xESTIMATE_ID := xExp.documentElement.childNodes.Item[ 0].GetAttribute( 'X');
          end;
          except
            ExceptionLog( 'Сбой QueryExpEstimate_');
        end;

    end;

  begin

      try
        // определяем тип раздела: UFPP или UFPP_N
        xUF_Line_Is_UFPP := (aUF_Line_Name = 'UFPP');
        // формируем новую строку в ЭД
        DoAddLineED215_;
        // параметры из UFPP_N
        xKBK      := aUF_Line.GetAttribute( 'KBK');
        xPurpgrID := GetPurposefullGraintIDByUF_(
                                VarToStr( aUF_Line.GetAttribute( 'ADD_KLASS')),
                                (aUF_Line_Name = 'UFPP_N'),
                                aBudgetID);
        // сумма из раздела
        if xUF_Line_Is_UFPP
          then xUF_Line_SumPP := aUF_Line.GetAttribute( 'SUM_PP')
          else xUF_Line_SumPP := aUF_Line.GetAttribute( 'SUM');

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

        // заполнение строки
        case aUF_Line.GetAttribute( 'TYPE_KBK') of
          //-----------------------------------------------------------------
          '10': begin
                  // кбк расходной строки
                  // exchange #3062 - унификация кода
                  {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);}
                  DoEncodeKBK_R(
                      xKBK,
                      xKADMR_CODE, xKFSR_CODE, xKCSR_CODE, xKVR_CODE, xKESR_CODE,
                      FALSE);
                  // шаг 1 - ищем бланк расходов:
                  // 1) поиск в рчб по кбк+код цели+орг.владелец.бл.расх
                  // имеющая счет (либо в UFPP_N.LS_UBP либо в IK.LS_UBP/BH.LS_UBP)
                  // если не нашли, то (exchange #2916):
                  // 2)  поиск в рчб по кбк+код цели+орг.владелец.бл.расх
                  // имеющая счет + бюджетополучатель
                  // если не нашли, то:
                  // 3) искать бланк расходов в справочнике БР.
                  // если не нашли - эд не создается.

                  // если раздел UFPP_N, то тип счета должен быть 5 или 9.
                  // для раздела UFPP тип счета не проверяется.
                  xLS_Search_Type := '';
                  {if xUF_Line_Is_UFPP
                    then xLS_Search_Type := ''
                    else xLS_Search_Type := '5,9';}

                  // exchange #2908
                  // был перепутан порядок поиска бланка расходов.
                  // в начале нужно искать в РЧБ, а потом в справочнике,
                  // а не наоборот.
                  // так же в лог добавляем запись, что в рчб не нашли БР
                  // и дальше ищем вторым способом
                  xEstimateLS := aLS;
                  if NOT xUF_Line_Is_UFPP then begin
                    // exchange #2916
                    // тип счета: «Лицевой счет в ФК» (5) либо «Лицевой счет
                    // бюджета в ФК» (9)
                    xLS_Search_Type := '5,9';
                    // для UFPP_N счет для бланка расходов берем из UFPP_N.LS_UBP.
                    // если поле не заполнено, то IK.LS_UBP.
                    s := TRIM( VarToStr( aUF_Line.GetAttribute( 'LS_UBP')));
                    if (LENGTH( s) > 0)
                      then xEstimateLS := s;
                  end;
                  WriteLog( 'Поиск бланка расходов в РЧБ...');
                  if NOT QueryExpEstimate_( xLS_Search_Type) then begin
                    // exchange #2908
                    // если не нашли БР, то в лог добавляем сообщение
                    // о количестве найденных БР
                    if (xFoundAcount <= 0)
                      then WriteInfo(
                              FORMAT( 'Не найден бланк расходов в РЧБ по блоку %s с порядковым номером %s.',
                                      [ aUF_Line_Name,
                                        aUF_Line_Index]))
                      else begin
                        WriteInfo(
                            FORMAT( 'Найдено несколько (%s) строк в РЧБ при поиске бланков расходов по блоку %s с порядковым номером %s.',
                                    [ INTTOSTR( xFoundAcount),
                                      aUF_Line_Name,
                                      aUF_Line_Index]));
                        // exchange #2916
                        // Если найдено несколько строк, то добавляем в фильтр
                        // поиска строки "Бюджетополучатель"= организации,
                        // в карточке которой значение полей  ИНН и КПП равны
                        // UF.INN_PL и UF.KPP_PL соответственно.
                        WriteLog( FORMAT( 'Поиск бланка расходов в РЧБ с учетом бюджетополучателя (UF.INN_PL=%s, UF.KPP_PL=%s)...',
                                          [ xUF_INN_PL,
                                            xUF_KPP_PL]));
                        if NOT QueryExpEstimate_( xLS_Search_Type, TRUE) then
                          if (xFoundAcount <= 0)
                            then WriteInfo(
                                    FORMAT( 'Не найден бланк расходов в РЧБ с бюджетополучателем по блоку %s с порядковым номером %s.',
                                            [ aUF_Line_Name,
                                              aUF_Line_Index]))
                            else WriteInfo(
                                    FORMAT( 'Найдено несколько (%s) строк в РЧБ с бюджетополучателем при поиске бланков расходов по блоку %s с порядковым номером %s.',
                                            [ INTTOSTR( xFoundAcount),
                                              aUF_Line_Name,
                                              aUF_Line_Index]));
                      end;
                  end;
                  if (xFoundAcount <> 1) then begin
                     WriteLog( 'Поиск бланка расходов в справочнике бланков расходов...');
                    // если не нашли в РЧБ - ищем бланк расходов в справочнике
                    // без него безсмысленно заполнять строку
                    // счет организации с типом «Лицевой счет в ФК» (5),
                    // «Лицевой счет бюджета в ФК» (9)
                    xFoundAcount := STRTOINT(
                                      QueryEstimateID_( xLS_Search_Type,
                                                        'count( * ) N', 'N'));
                    case xFoundAcount of
                      0: begin
                            WriteInfo( FORMAT( 'Не найден бланк расходов в справочнике по блоку %s с порядковым номером %s.',
                                                [ aUF_Line_Name,
                                                  aUF_Line_Index]));
                            xDoc_Error := TRUE;
                            EXIT;
                          end;

                      // однозначное определение бланка расходов
                      1: xESTIMATE_ID := QueryEstimateID_( xLS_Search_Type,
                                                           'e.id ID', 'ID');

                      else begin
                            // в лог добавляем запись, что не нашли БР
                          WriteInfo( FORMAT( 'Найдено несколько (%s) бланков расходов в справочнике по блоку %s с порядковым номером %s.',
                                              [ INTTOSTR( xFoundAcount),
                                                aUF_Line_Name,
                                                aUF_Line_Index]));
                          xDoc_Error := TRUE;
                          EXIT;
                        end;
                    end;//case//
                  end;

                  //Организация – оператор бланка расходов
                  xOrgID := QueryField( ' select e.org_id ID from ESTIMATE e'
                                       +' where e.id=?',
                                        [ xESTIMATE_ID],
                                        'ID');

                  // шаг 2 - пробуем найти строку РЧБ по найденному бланку
                  // расходов
                  QueryExp_;
                  if VarIsNULL( xExp) then begin
                    // заполнение строки по UFPP_N
                    // бюджетополучатель - Организация – оператор бланка расходов
                    xDocLine.SetAttribute( 'RECIPIENT_ID', xOrgID);
                    // exchange #2874
                    // нулевые доп коды нужно формировать с учето маски
                    // ДопФК - нуль
                    xDocLine.SetAttribute(
                              'KDF_CODE',
                              FormatKbk( 'KDF', '0', aBudgetID));//'00000');
                    // Доп.ЭК
                    xDocLine.SetAttribute(
                              'KDE_CODE',
                              FormatKbk( 'KDE', '0', aBudgetID));//, '000');
                    // Доп.КР
                    xDocLine.SetAttribute(
                              'KDR_CODE',
                              FormatKbk( 'KDR', '0', aBudgetID));//, '00000');
                    // КВФО
                    xDocLine.SetAttribute( 'FSR_ID', '0');
                  end else begin
                    // заполнение строки по РЧБ
                    // бюджетополучатель - из РЧБ
                    xDocLine.SetAttribute( 'RECIPIENT_ID',
                                            xExp.GetAttribute( 'RECIPIENT_ID'));
                    // ДопФК
                    xDocLine.SetAttribute( 'KDF_CODE',
                                            xExp.GetAttribute( 'KDF_CODE'));
                    // Доп.ЭК
                    xDocLine.SetAttribute( 'KDE_CODE',
                                            xExp.GetAttribute( 'KDE_CODE'));
                    // Доп.КР
                    xDocLine.SetAttribute( 'KDR_CODE',
                                            xExp.GetAttribute( 'KDR_CODE'));
                    // КВФО
                    xDocLine.SetAttribute( 'FSR_ID',
                                            xExp.GetAttribute( 'FSR_ID'));
                  end;

                  // Сумма - Значение UFPP_N/UFPP.SUM_PP
                  // для UFPP сумма со знаком "-"
                  if NOT xUF_Line_Is_UFPP
                    then xDocLine.SetAttribute( 'AMOUNT', xUF_Line_SumPP)
                    else xDocLine.SetAttribute(
                              'AMOUNT',
                              FORMAT( '%.2f',
                                      [ 0 - StrToCurrDef( xUF_Line_SumPP, 0)]));

                  // организацию берем из бланка расходов
                  xOrgXml := QueryOrg_( xOrgID);
                  // лицевой счет
                  QueryLS_( xOrgID, aLS, xLS_Search_Type, xLSXml);
                  // заполнение орг и счета
                  DoFillOrgAndLS_( xOrgID, xOrgXml, aLS, xLSXml);
                  // Доп.офис - не заполнять
                  xDocLine.SetAttribute( 'ORG_FILIAL_CODE', '');
                  // бланк расходов
                  xDocLine.SetAttribute( 'ESTIMATE_ID', xESTIMATE_ID);
                  // НПА - Не заполнять
                  // Авансовый платеж - Выключен
                  // Выставленный счет - Не заполнять
                  // Денежное обязательство - Не заполнять
                  // Бюджетное обязательство - Не заполнять
                  // Расходное обязательство - Не заполнять
                  // КБК
                  xDocLine.SetAttribute( 'ANAL_KIND', '1');
                  xDocLine.SetAttribute( 'KFSR_CODE', xKFSR_CODE);
                  xDocLine.SetAttribute( 'KCSR_CODE', xKCSR_CODE);
                  xDocLine.SetAttribute( 'KVR_CODE', xKVR_CODE);
                  xDocLine.SetAttribute( 'KESR_CODE', xKESR_CODE);
                  xDocLine.SetAttribute( 'KADMR_CODE', xKADMR_CODE);
                  // код цели
                  xDocLine.SetAttribute( 'PURPOSEFULGRANT_ID', xPurpgrID);
                end;
          //-----------------------------------------------------------------
          '20': begin
                  // если раздел UFPP_N, то тип счета должен быть 8 или 9.
                  // для раздела UFPP тип счета не проверяется.
                  if xUF_Line_Is_UFPP
                    then xLS_Search_Type := ''
                    else xLS_Search_Type := '8,9';
                  // получателя ищем только если нашли организацию – владельца
                  // лицевого счета
                  xRECEIVER_ID := '';
                  // организация – владельца лицевого счета
                  if (QueryOrg20_( xLS_Search_Type, 'count ( * ) N', 'N') <> '1')
                    then xOrgID := ''
                    else begin
                      xOrgID := QueryOrg20_( xLS_Search_Type, 'o.ID', 'ID');
                      if (QueryReceiver_( 'count( * ) N', 'N') = '1')
                        then xRECEIVER_ID := QueryReceiver_( 'r.id ID', 'ID');
                    end;

                  // 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);
                  }

                  // если определен получатель, ищем строку в ДЧБ
                  xInc := NULL;
                  if (LENGTH( xRECEIVER_ID) > 0)
                    then QueryInc_;

                  if VarIsNULL( xInc) then begin
                    // заполнение строки по UFPP_N
                    // если в дчб не нашли, то орг, счет, получатель,
                    // плательщик, территория не заполнять.
                    // поэтому независимо от того, нашли ли получателя для
                    // поиска в дчб или нет - чистим ид.получателя.
                    xRECEIVER_ID := '';
                    // КВФО
                    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'));
                  end;

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

                  // организация - получатель заполняется, если определен
                  // получатель

                  if (LENGTH( xRECEIVER_ID) > 0) then begin
                    // получатель
                    xDocLine.SetAttribute( 'RECEIVER_ID', xRECEIVER_ID);
                    if (LENGTH( xOrgID) > 0) then begin
                      // описание орг.
                      xOrgXml := QueryOrg_( xOrgID);
                      // лицевой счет
                      QueryLS_( xOrgID, aLS, xLS_Search_Type, xLSXml);
                      // заполнение орг и счета
                      DoFillOrgAndLS_( xOrgID, xOrgXml, aLS, xLSXml);
                    end;
                  end;

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

                  // КБК
                  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);
                end;
          //-----------------------------------------------------------------
          '31','32': begin
                  // фо/гл.администратор
                  if (QueryOrg31_( 'count ( * ) N', 'N') <> '1')
                    then xOrgID := ''
                    else xOrgID := QueryOrg31_( 'o.ID', 'ID');

                  // 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);}

                  // ищем строку в ИЧБ
                  xSrc := NULL;
                  QuerySrc_;

                  if VarIsNULL( xSrc) then begin
                    // заполнение строки по UFPP_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'));
                    // контрагент
                    xDocLine.SetAttribute( 'COUNTERAGENT_ID',
                                            xSrc.GetAttribute( 'COUNTERAGENT_ID'));
                  end;

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

                  // фо/гл.администратор
                  if (LENGTH( xOrgID) > 0) then begin
                    // описание орг.
                    xOrgXml := QueryOrg_( xOrgID);
                    // лицевой счет - с любым типом счета
                    QueryLS_( xOrgID, aLS, '', xLSXml);
                    // заполнение орг и счета
                    DoFillOrgAndLS_( xOrgID, xOrgXml, aLS, xLSXml);
                  end;

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

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

        // поля: Основание, Наименование, Номер, Дата
        DoFillLineFromUFLine_( aUF_Line);
        except
          ExceptionLog( 'Сбой DoAddLineByUF_Line_');
      end;

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

      try
        // Значение поля «Счет» карточки лицевого счета по UFPP_N.LS_UBP,
        // если значение в структурированном файле отсутствует,
        // то по значению BH.LS
        xLS := xNode_UFPP_N.GetAttribute( 'LS_UBP');

        if (LENGTH( xLS) <= 0)
          then xLS := aBH_LS;

        DoAddLineByUF_Line_( xLS,
                             xNode_UFPP_N,
                             'UFPP_N',
                             INTTOSTR( xIndexUFPP_N + 1));
        except
          ExceptionLog( 'Сбой DoAddLine_FT_5_3_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~DoAddLines_UFPP_N_FT_5_3_
    exchange #2954
    формирование нескольких строк в ЭД по блокам UFPP_N, которые соответствуют
    текущему блоку UFPP (с номером UFPP.LINE_NOM = xUFPP_LINE_NOM)}
  procedure DoAddLines_UFPP_N_FT_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_;
              end;
        end;//for//
        except
          ExceptionProc( 'DoAddLines_UFPP_N_FT_5_3_');
      end;

  end;
  //----------------------------------------------------------------------------
  {~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;
  //----------------------------------------------------------------------------
  {~Do_FT_2_1_
    ФТ-2.1
    Если значения реквизитов загружаемого документа UF.NOM_ZF и UF.DATE_ZF
    имеют не пустое значение, то в списке ЭД класса 178 требуется искать
    документ со значениями полей: «Номер» = UF.NOM_ZF и «Дата» = UF.DATE_ZF,
    в статусе «Новый» (1).
    Если документ найден, то требуется вызывать серверный метод
    формирования строки ЭД класса 215 по действию «выбор ПД»
    из ЭД класса 178.
      дальше перейти к ФТ-5.3 - доформировываем строки в созданном ЭД 215м
    из 178го по всем строкам UFPP_N без разбора строк UFPP.

    результат:
      -1 - условие ФТ-2.1 не выполняется.
      =0 - 215й по 178му создан успешно.
      =16 - 215й по 178му не создан.}
  function Do_FT_2_1_: integer;
  var
    xID_178: string;
    xED215_ID: string;
    xLine178: variant;
  begin

      try
        Result := -1;

        xUF_NOM_ZF:= VarToStr( aSource.GetAttribute( 'NOM_ZF'));
        xUF_DATE_ZF:= VarToStr( aSource.GetAttribute( 'DATE_ZF'));

        if ((LENGTH( xUF_NOM_ZF) <= 0) OR (LENGTH( xUF_DATE_ZF) <= 0))
          then EXIT;

        // формат даты UF.DATE_ZF - "DD.MM.YYYY".
        // если 178й однозначно не найден - фт-2.1 не соблюдается.
        if (QueryField( ' select count( * ) N'
                       +' from EXPLAINREQ e'
                       +' where e.documentclass_id=178'
                       +' and e.dispstatus_id=1'
                       +' and ltrim(e.doc_number)=?'
                       +' and e.doc_date=?'
                       +' and e.budget_id=?',
                        [ xUF_NOM_ZF,
                          StrToDate( xUF_DATE_ZF),
                          aBudgetID],
                        'N') <> '1')
          then EXIT;

        // если нашли ЭД 178го однозначно - получаем его ID
        xID_178 := QueryField(  ' select e.id ID'
                               +' from EXPLAINREQ e'
                               +' where e.documentclass_id=178'
                               +' and e.dispstatus_id=1'
                               +' and ltrim(e.doc_number)=?'
                               +' and e.doc_date=?'
                               +' and e.budget_id=?',
                                [ xUF_NOM_ZF,
                                  StrToDate( xUF_DATE_ZF),
                                  aBudgetID],
                                'ID');
        // создаем ЭД 215го класса из этого ЭД
        // exchange #2903 - записываем в журнал в зависимости от параметра
        DoWriteLog_( FORMAT( 'Создание ЭД "Справка по внебанковским операциям"'
                         +' из ЭД "Запрос на выяснение" с номером %s и датой %s...',
                          [ xUF_NOM_ZF,
                            xUF_DATE_ZF]));
        // создаем xml, в который будет загружаться созданный эд 215й
        xDocXml := CreateOleObject('Microsoft.XmlDom');
        xDocXml.appendChild( xDocXml.createElement('DOCUMENT'));
        try
          xDocXml.LoadXml(
                ExecProc( 'DOCUMENT',
                          [ 'action', 'create_nonbankoper',
                            'class', '178',
                            'ID', xID_178],
                          aBudgetID));
          WriteLog( FORMAT( '%s создан.', [ xDocInfo]));
          except
            WriteInfo( FORMAT( 'Сбой создания %s из ЭД 178го класса - %s',
                               [ xDocInfo,
                                 LastException.Message]));
            Result := 16;
            EXIT;
        end;


        xDoc := xDocXml.documentElement;


        { в результате action=create_nonbankoper возвращается xDoc вида:
          <DOCUMENT DISPSTATUS_ID="13" DOCUMENTCLASS_ID="178"
            DOCUMENT_ID="1003854444" DOC_NUMBER="2" ID="1000000201"
            VERSION="3" completed="true"/> }
        // загружаем 215й эд
        WriteLog( FORMAT( 'Загрузка созданного %s...',
                          [ xDocInfo]));
        xED215_ID := QueryField(  ' select n.id ID from nonbankoper n'
                                 +' join EXPLAINREQ E on e.document_id'
                                 +'= n.paydoc_document_id'
                                 +' where E.ID = ? and n.dispstatus_id=0',
                                  [ xDoc.GetAttribute( 'ID')],
                                  'ID');
        xDocXml.LoadXml(
                ExecProc( 'DOCUMENT',
                          [ 'action', 'read',
                            'class', '215',
                            'ID', xED215_ID],
                          aBudgetID));

        xDoc := xDocXml.documentElement;

        // обновляем эд 215го класса
        // переносим строку из шапки эд в тег LINES
        DoUpdateED215_( xDoc, xDocLines);
        // обновляем шапку эд
        DoUpdateMainED215_( xDoc);
        // в 178м всегда есть одна строка, поэтому в созданном эд 215м из 178го
        // тоже будет одна строка. ее и берем.
        // из нее нужно заполнять связки со 178мым для каждой новой строки
        // в 215м.
        xLine178 := xDocLines.ChildNodes.Item[0];


        // дальше доформировываем строки в созданном ЭД 215м из 178го
        // по всем строкам UFPP_N без разбора строк UFPP
        // игнорируем сбойные разделы UFPP_N, т.е. те, которые не прошли
        // проверку. по каждому разделу UFPP_N создаем строку в ЭД 215м
        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 begin
              DoAddLine_FT_5_3_;

              // поля связи 215го со 178м, из которого 215й создан
              // копируем из строки, которая создана при порождении 215го
              // из 178го во все новые строки.
              // в требованиях АО этого нету, но если это не делать,
              // то при удалении 215го, связанный с ним 178й не будет
              // менять статус на новый.
              xDocLine.SetAttribute(
                    'PAYDOC_DOCUMENT_ID',
                    VarToStr( xLine178.GetAttribute( 'PAYDOC_DOCUMENT_ID')));
              xDocLine.SetAttribute(
                    'PAYDOC_CLASS',
                    VarToStr( xLine178.GetAttribute( 'PAYDOC_CLASS')));
{
              xDocLine.SetAttribute(
                    'PAYDOC_DOC_NUMBER',
                    VarToStr( xLine178.GetAttribute( 'PAYDOC_DOC_NUMBER')));
              xDocLine.SetAttribute(
                    'PAYDOC_DOC_DATE',
                    VarToStr( xLine178.GetAttribute( 'AYDOC_DOC_DATE')));
              xDocLine.SetAttribute(
                    'PAYDOC_NAME',
                    VarToStr( xLine178.GetAttribute( 'PAYDOC_NAME')));
}
            end;
        end;//for//

        // если при обновлении эд возникли ошибки, то эд не обновляем
        if xDoc_Error then begin
          WriteInfo( FORMAT( 'Созданный %s не будет изменен.',
                            [ xDocInfo]));
          Result := 17;
          EXIT;
        end;

        // затем выполняем обновление ЭД
        xDoc.setattribute( 'action', 'update');
        xDoc.SetAttribute( 'class', '215');
        xDoc.SetAttribute( 'BUDGET_ID', aBudgetID);
        WriteLog( FORMAT( 'Выполняется обновление %s...',
                          [ xDocInfo]));
        try

          xDocXml.LoadXml( ExecXml(xDocXml.xml, aBudgetID));

          WriteLog( FORMAT( 'Обновление %s выполнено успешно.',
                            [ xDocInfo]));
          except
            WriteInfo( FORMAT( 'Сбой обновления %s - %s',
                               [ xDocInfo,
                                 LastException.Message]));
            Result := 16;
            EXIT;
        end;

        // дальше меняем статус эд
        Do_FT_7_;
        Result := 0;
        except
          ExceptionLog( 'Сбой Do_FT_2_1_');
      end;

  end;
(*
  //----------------------------------------------------------------------------
  procedure Do_FT_5_3_;
  var
    j: integer;
    s: string;
    xNode_UFPP_N: Variant;
    xFound_UFPP_N: boolean;
  begin

      try
        // ищем раздел UFPP_N
        xFound_UFPP_N := FALSE;
        for j := 0 to xUFPP_N.childNodes.length - 1 do begin
          xNode_UFPP_N := xUFPP_N.childNodes.item[ j];
          // игнорируем сбойные разделы UFPP_N
          if IsBadLine_( xNode_UFPP_N) then CONTINUE;
          // ищем раздел UFPP_N.LINE_NOM по UFPP.LINE_NOM
          if (xNode_UFPP_N.GetAttribute( 'LINE_NOM') <> xUFPP_LINE_NOM)
            then CONTINUE;
          // нашли раздел UFPP_N с текущим номером раздела UFPP, который
          // сейчас обрабатываем (раздел UFPP сейчас соответствует узлу xNode_UFPP)
          BREAK;
        end;//for//
        if NOT xFound_UFPP_N then begin

          if (VarToStr( xNode_UFPP_N.GetAttribute( '_checked_')) <> 'ok')
            then CONTINUE;
          //
          {
GetPurposeFulgrantId(
                                    aBudgetID,
                                    aSource.GetAttribute( aSource_ADD_KLASS)
                                    }
        end;//for//
        except
          ExceptionLog( 'Сбой Imp_FK_BH_UF.DoCreateDoc215_UF');
      end;

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

      try
        DoAddLineByUF_Line_( aBH_LS,
                             xNode_UFPP,
                             'UFPP',
                             INTTOSTR( xIndexUFPP + 1));
        except
          ExceptionLog( 'Сбой Do_FT_5_2_');
      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;

    {~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;


  begin

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

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

                  // сумма.
                  // по фт-5.1 для расходной строки сумма подставляется с
                  // отрицательным знаком
                  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');
                              // лицевой счет
                              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');
                              // лицевой счет
                              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');
                              // лицевой счет
                              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;
                  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);

                end;//for//

          '215d','24d','43d':
                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');
                        // лицевой счет: Если значение лицевого счета реквизита
                        // BH.LS соответствует одному из счетов с типом
                        // «Лицевой счет по доходам в ФК» (8) или
                        // «Лицевой счет бюджета в ФК» (9) организации,
                        // указанной в поле «Организация» строки ЭД, то
                        // заполнять значением BH.LS. Иначе не заполнять.
                        QueryLS_( xOrgID, aBH_LS, '8,9', xLSXml);
                        // заполнение орг и счета
                        DoFillOrgAndLS_( xOrgID, xOrgXml, aBH_LS, xLSXml);
                      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 = '43d')
                    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 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,
                             aBH_LS,
                             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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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 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,
                             aBH_LS,
                             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,
                                   aBH_LS,
                                   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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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,
                           aBH_LS,
                           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 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,
                             aBH_LS,
                             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,
                                   aBH_LS,
                                   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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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,
                           aBH_LS,
                           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 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,
                             aBH_LS,
                             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,
                                   aBH_LS,
                                   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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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,
                           aBH_LS,
                           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 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),
                             aBH_LS,
                             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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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го класа
        xED5 := QueryDoc_( 'payorder', xID);
        Result := TRUE;
        except
          ExceptionLog( 'Сбой Do_SearchDoc5_0_');
      end;

  end;
  //----------------------------------------------------------------------------
  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.REC_ACCOUNT = ?'
                           +' and s.budget_id=?'
                           +' 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),
                             aBH_LS,
                             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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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ласа
        xED24 := QueryDoc_( 'payorder', xID);
        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 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),
                             aBH_LS,
                             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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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го класа
        xED5 := QueryDoc_( 'payorder', xID);
        Result := TRUE;
        except
          ExceptionLog( 'Сбой Do_SearchDoc5_2_');
      end;

  end;
  //----------------------------------------------------------------------------
  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.REC_ACCOUNT = ?'
                           +' and s.budget_id=?'
                           +' 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),
                             aBH_LS,
                             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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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го класа
        xED24 := QueryDoc_( 'payorder', xID);
        Result := TRUE;
        except
          ExceptionLog( 'Сбой Do_SearchDoc24_2_');
      end;

  end;
  //----------------------------------------------------------------------------
  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.REC_ACCOUNT = ?'
                           +' and s.budget_id=?'
                           +' 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),
                             aBH_LS,
                             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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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го класа
        xED24 := QueryDoc_( 'payorder', xID);
        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 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,
                             aBH_LS,
                             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,
                                 aBH_LS,
                                 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,
                           aBH_LS,
                           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 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,
                             aBH_LS,
                             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,
                                   aBH_LS,
                                   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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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,
                           aBH_LS,
                           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 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,
                             aBH_LS,
                             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,
                                   aBH_LS,
                                   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');
        // здесь сверяем строки, поскольку при сравнении веществ. чисел
        // могут быть проблемы.
        if (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,
                           aBH_LS,
                           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;
  //----------------------------------------------------------------------------
begin
  try

    try
      Result := 0;

      //----------------------------------------------------------------------
      // поля из UF
      xUF_NOM_UF  := VarToStr( aSource.GetAttribute( 'NOM_UF'));
      xUF_DATE_UF := VarToStr( aSource.GetAttribute( 'DATE_UF'));
      xUF_INN_PL  := VarToStr( aSource.GetAttribute( 'INN_PL'));
      xUF_KPP_PL  := VarToStr( aSource.GetAttribute( 'KPP_PL'));
      // предварительное описание создаваемого ЭД 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

          if (LENGTH( VarToStr( xNode_UFPP_N.GetAttribute( 'SUM'))) <= 0)
            then xNode_UFPP_N.SetAttribute(
                              'SUM',
                              VarToStr( xNode_UFPP.GetAttribute( 'SUM_PP')));
        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);
      if IsLoaded215( aBudgetID, xGUID) 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'));
        xUFPP_SUM_PP  := 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
                    // если поле xUFPP_NOM_ZR или xUFPP_DATE_ZR пустое
                    // ФТ-2.1.3
                    case xUFPP_TYPE_KBK of
                      // exchange #2930
                      // поиск в эд 5м и 24м (счет плательщика)
                      '10'     : if NOT Do_SearchDoc5_0_  // расходные строки
                                   then Do_SearchDoc24_0_;

                      // exchange #2930
                      // Если ЭД класса 24 найден однозначно, то переходим
                      // к ФТ-5.1, иначе, Если значение  с 1 по 3 знак UFPP.KBK
                      // равно «100» , то переходим к 5.3, иначе строку
                      // пропускаем.
                      '20'     : if NOT Do_SearchDoc24_1_ then begin
                                   if (POS( '100', xUFPP_KBK) = 1) then begin
                                     // выполняем ФТ-5.3
                                     // ищем раздел UFPP_N по полю UFPP.LINE_NOM.
                                     // если раздел UFPP_N будет найден
                                     // создаем строку по UFPP_N.
                                     // exchange #2954
                                     // здесь выполняется добавление нескольких
                                     // строк по UFPP_N для текущего блока UFPP
                                     DoAddLines_UFPP_N_FT_5_3_;
//                                     if Do_Search_UFPP_N_
//                                       then DoAddLine_FT_5_3_;
                                   end else begin
                                     // в журнале пишем почему проигнорировали строку
                                     // а в конце, если эд не создается из-за того
                                     // что нет строк - сообщение пишется именно так.
                                     WriteInfo(
                                         FORMAT( 'Строка UFPP с номером %s игнорируется - по ней не найден'
                                                +' ЭД "Приложение к выписке кредитовое" и'
                                                +' первые 3 знака КБК не имеют значени 100.',
                                                 [ INTTOSTR( xIndexUFPP + 1)]));
                                   end;
                                   // пропускаем дальнейшую обработку строки UKPP
                                   CONTINUE;
                                 end;

                      // 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
        DoAddLines_UFPP_N_FT_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
          // отправляем ЭД на сервер
          // после создания меняем статус на "новый"
          if BuildDoc215_BH( xDocXml, xDoc, aValidate) then begin
            Do_FT_7_;
            Result:= 0;
          end else begin
            Result := 19;
          end;
        end;
      except
        ExceptionLog( 'Сбой скрипта: "Imp_FK_BH.DoCreateDoc215_UF".');
    end;
    finally

  end;
end;

begin
end.
