{~CreateED215_IK_ZR
  exchange #2960
  создание эд 215го по блоку IK.ZR

  результат:
    =true - блок ZR обработан. эд либо создан либо нет.
    =false - блок ZR не обработан. требуется создать эд по блоку ZR
              как было по старому.}
function CreateED215_IK_ZR( aBudgetID: string;
                            aIK, aZR: Variant;
                            aZR_GUID_FK: TStringList;
                            aChangeKBKto0: boolean): boolean;
var
  xZR_BIC_RCP: string;
  xIK_LS_UBP: string;
  xIK_INN_UBP: string;
  xIK_KPP_UBP: string;
  xZR_GUID_FK: string;
  xDocInfo: string;
  xZR_NOM_ZR: string;
  xZR_DATE_ZR: string;
  xZR_INN_RCP: string;
  xZR_KPP_RCP: string;
  xZR_LS_UBP_RCP: string;
  xXmlDoc215: Variant;
  xDoc215: Variant;
  xOrgXML: Variant;
  xZRST: Variant;
  i: integer;
  xDocLines: Variant;
  xProblems: boolean;
//  xXmlOrg: Variant;
//  x10RCP_Org_Found: boolean;
  x10RCP_OrgID: string;
//  x10PAY_Org_Found: boolean;
  x10PAY_OrgID: string;
//  xOrgID: string;
//  xOrgID_Found: boolean;
  x31RCP_CountreAgentID: string;
  x31PAY_CountreAgentID: string;
//  x31RCP_OrgFound: boolean;
  x31RCP_Org_ID: string;
  x31RCP_Org_INN: string;
  x31RCP_Org_KPP: string;
  x31RCP_Org_Caption: string;
//  x31PAY_OrgFound: boolean;
  x31PAY_Org_ID: string;
  x31PAY_Org_INN: string;
  x31PAY_Org_KPP: string;
  x31PAY_Org_Caption: string;
  xRecipientID: string;
  x10RCP_OrgAccountXml: Variant;
  x10PAY_OrgAccountXml: Variant;
  x31RCP_OrgAccountXml: Variant;
  x31PAY_OrgAccountXml: Variant;
  xZR_BS_RCP: string;

  //---------------------------------------------------------------------

  {~FillLine10_
    заполнение расходной строки.
    здесь описывается бланк расходов, счет и бюджетополучетель.
    если будут проблемы - сообщение отображается в журнале info
    и выставляется флаг =true в переменной xProblems.}
  procedure FillLine10_( aOrgID, aAccount: string;
                          aRecipientINN, aRecipientKPP, aRecipientLS: string;
//                          aLS: string;
                          aLine: Variant);
  var
    xEstimateID: string;
  begin

      try
        // ищем бланк расходов с учетом КБК строки
{        xEstimateID := GetEstimateIdForED215(
                            aBudgetID,
                            aOrgID,
                            aAccount,
                            aLine);
                            }
        xEstimateID := GetEstimateId_2957_Ex( aBudgetID,
                                              aOrgID,
                                              aAccount,
                                              aLine);
        if (LENGTH( xEstimateID) <= 0) then begin
          WriteInfo('Не определен бланк расходов получателя');
          xProblems := TRUE;
          Exit;
        end;
        aLine.SetAttribute( 'ESTIMATE_ID', xEstimateID);

        // бюджетополучатель с учетом ролучателя из блока IK
        // здесь же заполняются доп коды и КВФО из РЧБ, либо нулями
        FillLineED_2957_ByZR( aBudgetId,
                              xEstimateID,
                              aRecipientINN,
                              aRecipientKPP,
                              aRecipientLS,
                              aLine,
                              aLine);

        // описание счета
        // искать среди счетов организации-оператора бланка расходов
        // нераспорядительный, с типом 5 равным aLS.
        // только не закрытые л/с.
        // результат сразу заполняем в строке ЭД 215го.
        // поскольку ищем счет у конкретной организации, то при описании
        // счета сразу описываются реквизиты организации (FillResultMode=ED215R).
        if (GetOrgAccountGetter(  aLine,
                                  #13#10'accountA1=' + aAccount //aLS
                                 +#13#10'org_id=' + aOrgID
                                 +#13#10'closed=is null'
                                 +#13#10'FillResultMode=ED215R',
                                  null) <> 1) then begin
            WriteInfo('Не определен лицевой счет');
            xProblems := TRUE;
            Exit;
          end;

        except
          ExceptionProc( 'FillLine10_');
      end;

  end;


  {~DoCreateLine_
    формирование строки.
    передается признак: получатель=RCP или платедьщик=PAY.
    это суффикс полей атрибутов раздела ZRST а так же определение, как
    заполнять поля сумм в строках.

    aRecipINN, aRecipKPP, aRecipLS
          определители орг для поиска бюджетополучателя.
      указываются для блока ZR:
        INN_RCP, KPP_RCP, LS_UBP_RCP
      или
        INN_UBP, KPP_UBP
      }
  procedure DoCreateLine_( aLineType{,
                           a10_RecipINN, a10_RecipKPP, a10_RecipLS}: string);
  var
    xDocLine: Variant;
    xZRST_KBK_Type: string;
    xZRST_KBK: string;
//    xRecipientID: string;
    xZRST_SUM_V_KBK: Currency;
//    xEstimateID: string;
//    xRecipientID: string;
//    xOrgAccountID: string;
//    xOrgAccountXml: Variant;
    xKBKChanges: integer;
    xADD_KLASS_xxx: string;
    xPURPOSEFULGRANT_ID: string;
  begin

      try
        // если поле типа кбк не заполнено или имеет значение 20,31,32
        // строку не создаем
        xZRST_KBK_Type := GetNodeAttributeEx( xZRST, 'TYPE_KBK_' + aLineType);
        if (xZRST_KBK_Type in ['','20','31','32']) then begin
          WriteInfo( 'Строки в ЭД по разделам ZRST для значений поля ZRST.TYPE_КБК = [пусто, 20, 31, 32] не создаются.');
          EXIT;
        end;

        // создаем строку
        xDocLine := xDocLines.appendChild( xXmlDoc215.createElement('LINE'));

        // разбор КБК
        // если поле КБК в файле пустое, коды выставляются в 0 автоматически.
        // это необходимо для поиска бланка расходов.
        xZRST_KBK := GetNodeAttributeEx( xZRST, 'KBK_' + aLineType);
        if (LENGTH( xZRST_KBK) <= 0)
          then xZRST_KBK := '00000000000000000000';
        // при проверке кбк, если коды отсутствуют в бд, проверяем параметр
        // "замены кбк на 0". если параметр =false, то эд не создаем
        // это актуально для плательщика. для получателя замену на 0
        // описываем только в журнале без критической проблемы.
        if (aLineType = 'RCP') then begin
          CheckKbkLineED( aBudgetId,
                          xZRST_KBK_Type,
                          xZRST_KBK,
                          xDocLine,
                          TRUE);
        end else begin
          if NOT CheckKbkLineED( aBudgetId,
                                xZRST_KBK_Type,
                                xZRST_KBK,
                                xDocLine,
                                aChangeKBKto0) then
            if NOT aChangeKBKto0 then begin
              xProblems := TRUE;
              Exit;
            end;
        end;

        // КЦ: если код цели не указан - заменяем его на 0
        // это актуально для плательщика. для получателя замену на 0
        // описываем только в журнале без критической проблемы.
        xADD_KLASS_xxx := GetNodeAttributeEx( xZRST,
                                              'ADD_KLASS_' + aLineType);
        if ( LENGTH( xADD_KLASS_xxx) <= 0)
          then xPURPOSEFULGRANT_ID :=
                        CheckPurposefullgrantCodeSet0(  aBudgetId,
                                                        xADD_KLASS_xxx,
                                                        xKBKChanges)
          else
            if (aLineType = 'RCP')
              then xPURPOSEFULGRANT_ID :=
                        CheckPurposefullgrantCodeSet0(  aBudgetId,
                                                        xADD_KLASS_xxx,
                                                        xKBKChanges)
              else begin
                xPURPOSEFULGRANT_ID :=
                        CheckPurposefullgrantCodeSet0(  aBudgetId,
                                                        xADD_KLASS_xxx,
                                                        xKBKChanges,
                                                        aChangeKBKto0);
                if ((xKBKChanges = 1) AND (NOT aChangeKBKto0))
                  then begin
                    // если код не найден в бд и замена кода на 0
                    // выключена - это критическая ошибка
                    xProblems := TRUE;
                    Exit;
                  end;
              end;

        case xZRST_KBK_Type of
          // расходная строка
          '10': begin
                // тип строки
                xDocLine.setAttribute('ANAL_KIND', '1');

                // код цели
                xDocLine.SetAttribute( 'PURPOSEFULGRANT_ID',
                                        xPURPOSEFULGRANT_ID);

                if (aLineType = 'RCP') then begin
                  // получатель
                  FillLine10_( x10RCP_OrgID,
                               xZR_LS_UBP_RCP,
                               xIK_INN_UBP,
                               xIK_KPP_UBP,
                               xIK_LS_UBP,
//                               xZR_LS_UBP_RCP,
                               xDocLine);
                end else begin
                  // плательщик
                  FillLine10_( x10PAY_OrgID,
                               xIK_LS_UBP,
                               xZR_INN_RCP,
                               xZR_KPP_RCP,
                               xZR_LS_UBP_RCP,
  //                             xIK_LS_UBP,
                               xDocLine);
                end;
                if xProblems then EXIT;
(*
                  // ищем бланк расходов с учетом КБК строки
                  xEstimateID := GetEstimateIdForED215(
                                      aBudgetID,
                                      ,
                                      xZR_LS_UBP_RCP,
                                      xDocLine);
                  if (LENGTH( xEstimateID) <= 0) then begin
                    WriteInfo('Не определен бланк расходов получателя');
                    xProblems := TRUE;
                    Exit;
                  end;
                  // бюджетополучатель с учетом ролучателя из блока IK
                  // здесь же заполняются доп коды и КВФО из РЧБ, либо нулями
                  FillLineED_2957_ByZR( aBudgetId,
                                        xEstimateID,

                                        xDocLine,
                                        xDocLine);
                  // описание счета
                  CopyXmlNodeAttributes( x10RCP_OrgAccountXml, xDocLine);
                end else begin
                  // ищем бланк расходов с учетом КБК строки
                  xEstimateID := GetEstimateIdForED215(
                                      aBudgetID,
                                      x10PAY_OrgID,
                                      xIK_LS_UBP,
                                      xDocLine);
                  if (LENGTH( xEstimateID) <= 0) then begin
                    WriteInfo('Не определен бланк расходов получателя');
                    xProblems := TRUE;
                    Exit;
                  end;

                  // бюджетополучатель с учетом ролучателя из блока ZR
                  // здесь же заполняются доп коды и КВФО из РЧБ, либо нулями
                  FillLineED_2957_ByZR( aBudgetId,
                                        xEstimateID,
                                        xZR_INN_RCP,
                                        xZR_KPP_RCP,
                                        xZR_LS_UBP_RCP,
                                        xDocLine,
                                        xDocLine);
                  // описание счета
                  CopyXmlNodeAttributes( x10PAY_OrgAccountXml, xDocLine);
                end;
*)

                // КВФО	Устанавливать 1 - обязательно после заполнения
                // бюджетополучателя функцией FillLineED_2957_ByZR,
                // поскольку в ней КВФО заполняется из РЧБ.
                xDocLine.setAttribute( 'FSR_ID', '1');

                // Расходное обязательство нужно искать после КЦ (только для расходов).
                // это связано с доработкой АЦК-Ф, поскольку при этом требутся
                // заполнение поля кода цели.
                xDocLine.setAttribute(
                        'DIRECTION_ID',
                        GetDirectionID( aBudgetId,
                                        xDocLine.GetAttribute( 'ESTIMATE_ID'),
                                        '215',
                                        xDocLine));

                // сумма расхода заполняется различно для RCP/PAY
                xZRST_SUM_V_KBK := StrToCurrDef(
                                      GetNodeAttributeEx( xZRST, 'SUM_V_KBK'),
                                      0);
                if (aLineType = 'RCP')
                  then xDocLine.SetAttribute(
                                'AMOUNT',
                                FORMAT( '%.2f', [ 0 - xZRST_SUM_V_KBK]))
                  else xDocLine.SetAttribute(
                                'AMOUNT',
                                FORMAT( '%.2f', [ xZRST_SUM_V_KBK]));
              end;

(*
          // источники
          '31','32': begin
                // тип строки
                xDocLine.setAttribute('ANAL_KIND', '3');
                // КВФО	Устанавливать 1
                xDocLine.setAttribute( 'FSI_ID', '1');
                // доп коды заполнять нулями
                xDocLine.setAttribute( 'KDF_CODE', FormatKbk( 'KDF', '0', aBudgetId));
                xDocLine.setAttribute( 'KDE_CODE', FormatKbk( 'KDE', '0', aBudgetId));
                xDocLine.setAttribute( 'KDR_CODE', FormatKbk( 'KDR', '0', aBudgetId));

                // код цели
                xDocLine.SetAttribute( 'PURPOSEFULGRANTI_ID',
                                        xPURPOSEFULGRANT_ID);

                if (aLineType = 'RCP') then begin
                  // ФО / Гл.администратор
                  xDocLine.setAttribute( 'ORG_ID', x31RCP_Org_ID);
                  xDocLine.setAttribute( 'ORG_TAXCODE', x31RCP_Org_INN);
                  xDocLine.setAttribute( 'ORG_KPP', x31RCP_Org_KPP);
                  xDocLine.setAttribute( 'ORG_NAME', x31RCP_Org_Caption);
                  // контрагент
                  xDocLine.setAttribute( 'COUNTERAGENT_ID', x31RCP_CountreAgentID);
                  // описание счета
                  CopyXmlNodeAttributes( x31RCP_OrgAccountXml, xDocLine);
                end else begin
                  // ФО / Гл.администратор
                  xDocLine.setAttribute( 'ORG_ID', x31PAY_Org_ID);
                  xDocLine.setAttribute( 'ORG_TAXCODE', x31PAY_Org_INN);
                  xDocLine.setAttribute( 'ORG_KPP', x31PAY_Org_KPP);
                  xDocLine.setAttribute( 'ORG_NAME', x31PAY_Org_Caption);
                  // контрагент
                  xDocLine.setAttribute( 'COUNTERAGENT_ID', x31PAY_CountreAgentID);
                  // описание счета
                  CopyXmlNodeAttributes( x31PAY_OrgAccountXml, xDocLine);
                end;

                // сумма расхода заполняется различно для RCP/PAY
                xZRST_SUM_V_KBK := StrToCurrDef(
                                      GetNodeAttributeEx( xZRST, 'SUM_V_KBK'),
                                      0);
                if (aLineType = 'RCP')
                  then xDocLine.SetAttribute(
                                'AMOUNT',        // Зачислено
                                FORMAT( '%.2f', [ xZRST_SUM_V_KBK]))
                  else xDocLine.SetAttribute(
                                'PASS_AMT',            // передано
                                FORMAT( '%.2f', [ xZRST_SUM_V_KBK]));
              end;
              *)
        end;//case//

        // Основание - Назначение платежа	ZRST.PURPOSE_KBK
        xDocLine.SetAttribute( 'DESCRIPTION_LINE',
                               GetNodeAttributeEx( xZRST, 'PURPOSE_KBK'));
        // Наименование первичного документа	- Заявка на кассовый расход
        xDocLine.SetAttribute( 'PAYDOC_NAME', 'Заявка на кассовый расход');
        // Номер первичного документа	- Номер заявки - ZR.NOM_ZR
        xDocLine.SetAttribute( 'PAYDOC_DOC_NUMBER',
                               GetNodeAttributeEx( aZR, 'NOM_ZR'));
        // Дата первичного документа - Дата заявки: ZR.DATE_ZR
        // формат: YYYY-MM-DD
        xDocLine.SetAttribute( 'PAYDOC_DOC_DATE',
                               DDdMMdYYYY_To_YYYYmMMmDD(
                                    GetNodeAttributeEx( aZR, 'DATE_ZR')));
        // ID платежного документа Не заполнять

        except
          ExceptionProc( 'DoCreateLine_');
      end;

  end;
  (*
  //---------------------------------------------------------------------
  {~SearchOrgGAdmin_
    поиск ФО / Гл.администратор по инн+кпп+счет.

    Определяется по сочетанию ИНН+КПП (RecipINN, aRecipKPP)
    клиента среди актуальных незакрытых организаций для данного бюджета
    с ролью «Администрация/Финорган»,
    «Администратор источников», «Гл.администратор источников»
    и имеющих счет с типом 7 нераспорядительный с номером,
    равным aRecipLS или с типом 6 нераспорядительный с номером
    счета финоргана в карточке, равным aRecipLS.

    результат:
      =true - орг. найдена и заполнены параметры орг. в возвращаемых параметрах.
      =false - орг.не найдена. параметры результата не заполняются.}
  function SearchOrgGAdmin_( aRecipINN, aRecipKPP, aRecipLS: string;
                             var aRecipientID: string;
                             var aOrgID, aOrgINN, aOrgKPP, aOrgCaption: string): boolean;
  begin

      try
        Result := SearchRecipientID_ToXML( aBudgetID,
                                            aRecipINN,
                                            aRecipKPP,
                                            aRecipLS,
                                            'account2',
                                            '11,10,14',
                                            aRecipientID,
                                            xXmlOrg);
        if Result then begin
          xXmlOrg     := xXmlOrg.documentElement.childNodes.Item[0];
          aOrgID      := GetNodeAttributeEx( xXmlOrg, 'ID');
          aOrgINN     := GetNodeAttributeEx( xXmlOrg, 'TAXCODE');
          aOrgKPP     := GetNodeAttributeEx( xXmlOrg, 'KPP');
          aOrgCaption := GetNodeAttributeEx( xXmlOrg, 'CAPTION');
        end else begin
          aOrgID      := '';
          aOrgINN     := '';
          aOrgKPP     := '';
          aOrgCaption := '';
        end;

        except
          ExceptionProc( 'SearchOrgGAdmin_');
      end;

  end;
  *)
  //---------------------------------------------------------------------
  {~SearchOrgForEstimate_
    поиск организации для поиска бланка расходов по инн и кпп.
    возвращается:
      =true - организация найдена в aOrgID.
      =false - орг. не найдена. aOrgID может быть не заполнено.}
  function SearchOrgForEstimate_( aINN, aKPP: string;
                                  var aOrgID: string): boolean;
  var
    xSQL: string;
  begin

      try
        aOrgID := '';

        xSQL := ' From Org O'
                // актуальность
               +' Join Contractor C on C.Org_Id = O.Id'
               +' Left Join Budget B on B.Org_Id = C.Inspector_Id'
                // роли
               +' Join OrgRoles Ors on O.Id = Ors.Org_Id'
               +' Where B.Id = ? and Ors.OrgRole_Id in (0)'
               +' and o.TAXCODE=? and'
               // кпп + доп.кпп
               +' (o.KPP=? or exists(select * from orgkpp ok'
               +' where ok.org_id=o.id and ok.kpp=?))';



        if (QueryField( ' Select count( * ) N' + xSQL,
                        [ aBudgetID,
                          aINN,
                          aKPP,
                          aKPP],
                        'N') <> '1')
//        xXmlOrg := GetOrgByTaxKpp( aINN, aKPP, '', '', False, xDoc215);
//        if (GetQueryXmlField( xXmlOrg, 'ID', aOrgID) <> 1)
          then Result := FALSE
          else begin
            Result := TRUE;
            aOrgID := QueryField( ' Select o.id ID' + xSQL,
                                  [ aBudgetID,
                                    aINN,
                                    aKPP,
                                    aKPP],
                                  'ID');
          end;
          {
            // проверяем актуальность орг. в бюджете
            if IsActual( aOrgID, aBudgetID)
              then Result := TRUE
              else Result := FALSE;
              }

        except
          ExceptionProc( 'SearchOrgForEstimate_');
      end;

  end;
  //---------------------------------------------------------------------

begin

    try
      // пока считаем что блок IK.ZR будет обрабатываться по старому алгоритму
      Result := FALSE;




      // если IK.ZR.TYPE равен «1», то переходим к ФТ-1.1,
      // иначе формируем ЭД по существующему алгоритму.
      if (GetNodeAttributeEx( aZR, 'TYPE') <> '1') then EXIT;

      xIK_LS_UBP := GetNodeAttributeEx( aIK, 'LS_UBP');
      if (LENGTH( xIK_LS_UBP) <= 0) then EXIT;


      // Требуется сравнить значения IK.ZR.BS_RCP со значением банковского
      // счета, указанного в поле «Единый счет бюджета» карточки лицевого
      // счета IK.LS_UBP.
      // Если значения счетов равны, то сравнить значение IK.ZR.BIC_RCP
      // со значением поля «БИК» строки справочника «Счета организаций»,
      // имеющей значение в поле «Счет» равное  IK.ZR.BS_RCP,
      // иначе формировать документ по существующему алгоритму.
      // Если значения БИК равны, то переходить к ФТ-2,
      // иначе формировать документ по существующему алгоритму.

      // прверяем сколько есть в бд счетов IK.LS_UBP с типом 5 не закрытых,
      // связанныс по единому счету бюджета со счетом ZR.BS_RCP.
      // если не нашли ни одного - на выход.
      if (QueryField( ' select count( * ) N'
                     +' from orgaccount o'
                     +' join orgaccount oo on oo.id = o.EXECUTERACC_ID'
                     +' where o.account_number=? and o.orgacctype_id=5'
                     +' and o.close_date is null'
                     +' and oo.account_number=?',
                      [ xIK_LS_UBP,
                        GetNodeAttributeEx( aZR, 'BS_RCP')],
                      'N') = '0')
        then EXIT;

      // здесь проверяем, сколько нашли биков банков, совпадающих с ZR.BIC_RCP,
      // для указанного банковсвого счета IK.ZR.BS_RCP.
      // если нашли 0 - тогда работаем по старому.
      xZR_BIC_RCP := GetNodeAttributeEx( aZR, 'BIC_RCP');
      if (LENGTH( xZR_BIC_RCP) <= 0) then EXIT;
      xZR_BS_RCP  := GetNodeAttributeEx( aZR, 'BS_RCP');
      if (LENGTH( xZR_BS_RCP) <= 0) then EXIT;

      if (QueryField( ' select count( * ) N from bank b where b.bic in ( ?)'
                     +' and b.id in (select a.bank_id from orgaccount a'
                     +' where a.ACCOUNT_NUMBER = ? and a.orgacctype_id=2)',
                      [ xZR_BIC_RCP,
                        xZR_BS_RCP],
                      'N') = '0') then EXIT;

      //------------------------------------------------------------------
      // дальше блок ZR обработан по новому алгоритму
      Result := TRUE;


      // Требуется сравнить значения IK.LS_UBP и IK.ZR.LS_UBP_RCP,
      // если значения равны, то в загружаемом IK – файле по всем блокам ZR
      // требуется искать значение ZR.GUID_FK, равное значению загружаемого
      // (анализируемого в текущий момент блока IK.ZR) IK.ZR.GUID_FK.
      // Иначе переходим к ФТ-3.
      xZR_LS_UBP_RCP  := GetNodeAttributeEx( aZR, 'LS_UBP_RCP');
      xZR_GUID_FK     := GetNodeAttributeEx( aZR, 'GUID_FK');

      if (xZR_LS_UBP_RCP = xIK_LS_UBP) then
        if (aZR_GUID_FK.IndexOf( xZR_GUID_FK) <> -1) then begin
          WriteInfo( FORMAT( 'Найдено несколько разделов ZR с одинаковым значением ZR.GUID_FK %s.',
                             [ xZR_GUID_FK]));
          EXIT;
        end;


      // провяем наличие в бд эд 215го по guid_fk принудительно всегда
      // на любом статусе (кроме удаленного)

      if IsLoaded215( aBudgetID, xZR_GUID_FK, TRUE) then begin
        WriteInfo( FORMAT( 'В БД найден ЭД "Справка по внебанковским операциям" с GUID_FK %s'
                          +' - новый эд по блоку ZR не будет создан.',
                           [ xZR_GUID_FK]));
        EXIT;
      end;

      //------------------------------------------------------------------
      xZR_NOM_ZR  := GetNodeAttributeEx( aZR, 'NOM_ZR');
      xZR_DATE_ZR := GetNodeAttributeEx( aZR, 'DATE_ZR');

      xDocInfo := FORMAT( '"Справка по внебанковским операциям" № %s Дата: %s',
                          [ xZR_NOM_ZR,
                            xZR_DATE_ZR]);
      WriteLog( FORMAT( 'Создается %s...', [ xDocInfo]), TRUE);


      //------------------------------------------------------------------
      // пока считаем что проблем нет
      xProblems := FALSE;

      // формируем эд 215й по блоку ZR
      xXmlDoc215 := CreateOleObject('Microsoft.XmlDom');
      xDoc215 := xXmlDoc215.appendChild(
                                     xXmlDoc215.createElement('DOCUMENT'));

      xDoc215.SetAttribute( 'action', 'insert');
      xDoc215.setAttribute( 'class', '215');

      // бюджет. это может потребоваться для определения бюджетополучателя и
      // других операций
      xDoc215.setAttribute('BUDGET_ID', aBudgetID);
      xDoc215.setAttribute('F_BUDGET_ID', aBudgetID);

      // шапка
      xDoc215.setAttribute('GUID_FK', xZR_GUID_FK);
      // Номер документа
      xDoc215.setAttribute('DOC_NUMBER', xZR_NOM_ZR);
      // Дата документа. в конечном документе формат даты: yyyy-mm-dd.
      xDoc215.setAttribute('DOC_DATE', DDdMMdYYYY_To_YYYYmMMmDD( xZR_DATE_ZR));
      // Признак "От ФК" 	Не устанавливать признак
      xDoc215.setAttribute('FK_FLAG', '0');
      // Основание Заполнять текстом
      xDoc215.setAttribute(
          'DESCRIPTION',
          FORMAT( 'Создана на основании Информации о кассовых операциях по л/с %s от %s',
                  [ xIK_LS_UBP,
                    GetNodeAttributeEx( aIK, 'DATE')]));
      // Комментарий	Не заполнять
      //xDoc215.setAttribute('REMARK', '');
      { тип операции - заполняется значением, выбранным для  Справки по
        внебанковским операциям в справочнике "Типы операций по-умолчанию",
        а в случае отсутствия настройки, значением "Не указано"}
      xDoc215.setAttribute( 'OPERTYPE_ID',
                            INTTOSTR( OperTypeDefaultForClass( 215)));

      // это поле необходимо для линковки
      xDoc215.SetAttribute( 'GUID', xZR_GUID_FK);
      // признак загрузки из файла IK
      xDoc215.SetAttribute( 'F_ORIGINAL_TYPE', 'IK');
      // бюджет
      xDoc215.SetAttribute( 'F_BUDGET_ID', aBudgetID);
      // поле GUID для ЭД
      xDoc215.SetAttribute( 'FOREIGN_KEY', xZR_GUID_FK);

      //------------------------------------------------------------------
      // вспомогательные данные для строк
      xIK_INN_UBP     := GetNodeAttributeEx( aIK, 'INN_UBP');
      xIK_KPP_UBP     := GetNodeAttributeEx( aIK, 'KPP_UBP');
      xZR_INN_RCP     := GetNodeAttributeEx( aZR, 'INN_RCP');
      xZR_KPP_RCP     := GetNodeAttributeEx( aZR, 'KPP_RCP');


      // для поиска БР в строках ищем орг. по ИНН/КПП
      // получатель: IK.ZR.INN_RCP, KPP_RCP
      // это нужно для строк получателя с кбк=10
      WriteLog('Поиск организация получателя по ИНН и КПП...');
      if NOT SearchOrgForEstimate_( xZR_INN_RCP,
                                     xZR_KPP_RCP,
                                     x10RCP_OrgID) then begin
        WriteInfo('Не найдена организация получателя по ИНН и КПП.');
//        xProblems := TRUE;
        Exit;
      end;
      // для плательщика:
      WriteLog('Поиск организация плательщика по ИНН и КПП...');
      // получатель: IK.IK_INN_UBP, IK.KPP_UBP
      // это нужно для строк плательщика с кбк=10
      if NOT SearchOrgForEstimate_( xIK_INN_UBP,
                                    xIK_KPP_UBP,
                                    x10PAY_OrgID) then begin
        WriteInfo('Не найдена организация плательщика по ИНН и КПП.');
  //      xProblems := TRUE;
        Exit;
      end;
      (*
      { Искать с номером, равным IK.LS_UBP, нераспорядительный.
        В строке с типом КБК: «Расходы» - искать среди счетов
        организаций-оператора бланка расходов с типом 5 (в карточке л/с)
        это нужно для строк плательщика с кбк=10 }
      WriteLog( 'Описание л/с организация плательщика...', TRUE);
      if (GetOrgAccountGetter_ToXML(
              x10PAY_OrgAccountXml,            // результат добавляем к строке
              #13#10'account=' + xIK_LS_UBP
             +#13#10'account_type=5'
             +#13#10'org_id=' + x10PAY_OrgID
             +#13#10'closed=is null',                // только не закрытые л/с
              null) <> 1)
        then begin
          WriteInfo('Не распознан л/с.', True);
//          xProblems := TRUE;
          Exit;
        end;


      {   Контрагент для строк:
          Краткое наименование организации, найденной по ИНН+КПП среди
        актуальных незакрытых организаций. Если не найдена однозначно,
        заполнять значением "Не указанна".}

      WriteLog( 'Поиск контрагента получателя по ИНН+КПП...');
      // Контрагент получателя: IK.INN_UBP, IK.KPP_UBP
      // это нужно для строк получателя с кбк=31
      if NOT SearchRecipientID( aBudgetID,
                                xIK_INN_UBP,
                                xIK_KPP_UBP,
                                '',   // л/с не указан
                                '',   // параметр л/с не нужен
                                '',   // фильтр ролей организации
                                x31RCP_CountreAgentID)
        then x31RCP_CountreAgentID := '0';

      // Контрагент плательщика: ZR.INN_UBP_RCP, ZR.KPP_UBP_RCP
      // это нужно для строк плательщика с кбк=31
      WriteLog( 'Поиск контрагента плательщика по ИНН+КПП...');
      if NOT SearchRecipientID( aBudgetID,
                                GetNodeAttributeEx( aZR, 'INN_UBP_RCP'),
                                GetNodeAttributeEx( aZR, 'KPP_UBP_RCP'),
                                '',   // л/с не указан
                                '',   // параметр л/с не нужен
                                '',   // фильтр ролей организации
                                x31PAY_CountreAgentID)
        then x31PAY_CountreAgentID := '0';

      // ФО / Гл.администратор
      WriteLog( 'Поиск ФО / Гл.администратор получателя...');
      // Определяется по сочетанию ИНН+КПП (ZR.INN_RCP, ZR.KPP_RCP)
      // и счета ZR.LS_UBP_RCP
      if NOT SearchOrgGAdmin_(  xZR_INN_RCP,
                                xZR_KPP_RCP,
                                xZR_LS_UBP_RCP,
                                xRecipientID,
                                x31RCP_Org_ID,
                                x31RCP_Org_INN,
                                x31RCP_Org_KPP,
                                x31RCP_Org_Caption) then begin
        WriteInfo('Не определен ФО / Гл.администратор для источников получателя.');
    //    xProblems := TRUE;
        Exit;
      end;
      { Искать с номером, равным ZR_LS_UBP_RCP, нераспорядительный.
        В строке с типом КБК: «Источники» -  среди счетов организации
        ФО / Гл.администратор с типом 7 (в карточке л/с). }
      WriteLog( 'Описание л/с клиента получателя в строках источников...', TRUE);
      if (GetOrgAccountGetter_ToXML(
              x31RCP_OrgAccountXml,            // результат добавляем к строке
              #13#10'account=' + xZR_LS_UBP_RCP        // поиск счета
             +#13#10'ls_bs=' + xZR_BS_RCP                 // л/с УФК
             +#13#10'account2=' + xRecipientID        // орг.счета
             +#13#10'closed=is null',                // только не закрытые л/с
              null) <> 1)
        then begin
          WriteInfo('Не распознан л/с для ФО/Гл.администратор.', True);
          xProblems := TRUE;
          Exit;
        end;

      WriteLog( 'Поиск ФО / Гл.администратор плательщика...');
      // Определяется по сочетанию ИНН+КПП (IK.INN_UBP, KPP_UBP)
      // и счета IK.LS_UBP
      if NOT SearchOrgGAdmin_(  xIK_INN_UBP,
                                xIK_KPP_UBP,
                                xIK_LS_UBP,
                                xRecipientID,
                                x31PAY_Org_ID,
                                x31PAY_Org_INN,
                                x31PAY_Org_KPP,
                                x31PAY_Org_Caption)then begin
        WriteInfo('Не определен ФО / Гл.администратор для источников плательщика.');
//        xProblems := TRUE;
        Exit;
      end;
      { Искать с номером, равным IK.LS_UBP, нераспорядительный.
        В строке с типом КБК: «Расходы» - искать среди счетов
        организаций-оператора бланка расходов с типом 5 (в карточке л/с) }
      WriteLog( 'Описание л/с клиента плательщика в строках источников...', TRUE);
      if (GetOrgAccountGetter_ToXML(
              x31PAY_OrgAccountXml,            // результат добавляем к строке
              #13#10'account=' + xIK_LS_UBP
             +#13#10'ls_bs=' + xZR_BS_RCP                 // л/с УФК
             +#13#10'account2=' + xRecipientID
             +#13#10'closed=is null',                // только не закрытые л/с
              null) <> 1)
        then begin
          WriteInfo('Не распознан л/с для ФО/Гл.администратор.', True);
//          xProblems := TRUE;
          Exit;
        end;
        *)

      //------------------------------------------------------------------

        xDocLines := xDoc215.appendChild( xXmlDoc215.createElement('LINES'));
        // формируем новые строки
        for i := 0 to aZR.childNodes.length - 1 do begin
          xZRST := aZR.childNodes.item[i];

          if (xZRST.NodeName <> 'ZRST') then CONTINUE;
          // на каждый блок ZRST создаются две строки в ЭД
          // формирование строк одинаковое, за исключением того, что исходные
          // данные беруться из разных полей блока ZRST, а суммы для расходной
          // строки отличаются знаком, а для строки источников записываются
          // в разные поля строк ЭД. это пометим специальным параметром.
          DoCreateLine_( 'RCP');    // получатель
          // если есть проблемы заполнения полей в эд - эд не создаем.
          if xProblems then BREAK;

          DoCreateLine_( 'PAY');    // плательщик
          // если есть проблемы заполнения полей в эд - эд не создаем.
          if xProblems then BREAK;
        end;//for//


      // если есть проблемы заполнения полей в эд - эд не создаем.
      // здесь подразумеваются критические проблемы, а не игнорируемые.
      if xProblems then begin
        WriteInfo( 'Имеются проблемы заполнения полей - документ не создается.');
        EXIT;
      end;

      // проверяем, если в сформированном эд нет строк, такой эд не создаем
      if ( xDocLines.childNodes.length <= 0) then begin
        WriteInfo( 'Документ не содержит строк - не создается.');
        EXIT;
      end;

      // Вставка и обработка.
      // после вставки документ переводится на статус "отложен"

      xXmlDoc215.loadXml( ExecXml( xXmlDoc215.xml));

      except
        ExceptionProc( 'CreateED215_IK_ZR');
    end;

end;

begin
end.
