
{~MakeDocumentIkBD_New
  exchange #2600 - Формирование документов
  параметры
    aFinYear - фин.год (год IK.DATE)
    aMode - строка режима.
            exchange #2600 пп.2.9.2 - заполняется как '2600_2.9'
            для старого варианта этот параметр должен быть пустой строкой.
  exchange #2831
    изменение заполнения полей в строках

  exchange #2965
    добавлен параметр aLock195by2965: если =false, то будет возможность
    создания эд 195го по блоку BDPD ( exchange #2965).
    если значение =true, это значит что возможность создания 195го по BDPD
    будет заблокирована. это связано с тем, что когда определяем что эд 195й
    будет создан по блоку BDPD, то фактически описываем создание эд 5го
    принудительно (без проверк DIR_SUM) и по этому описанию создаем 195й.
    а если при этом в бд будут обнаружен 195е, то 195й создавать не нужно,
    а нужно как раньше: 5/24й. в результате вызывается рекурсивно эта же
    подпрограмма но с заблокированной проверкой создания 195го.}
procedure MakeDocumentIkBD_New( aXmlED, aXmlBDPD, aXmlIK: Variant;
                                aFinYear: string;
                                aLock195by2965: boolean;
                                aList_ACC_I: TStringList;
                                aList_ACC_V: TStringList);
var
//  xmlOrg, xmlAcc,
  BudgXml: Variant;
  i: Integer;
  xSearchOrgBy_TaxCode: string;
  xSearchOrgBy_KPP: string;
  xSearchOrgBy_TaxCodeEqu: boolean;
  xOrgXml: Variant;

  xFSR_Value: string;     // exchange #2600
  xIK_LS_UBP: string;
  xIK_INN_UBP: string;
  xIK_KPP_UBP: string;

  xNode: Variant;
  xNodeLine: Variant;
  xLineFound: boolean;
//  xAmount: Variant;
  xDocInfo: string;
  xDocClass: string;
  xIK_KOD_UBP_PUBP: string;

  xDocRecID: string;
  xErrors: boolean;
  xCreateDoc195: boolean;
  xDocCopy: Variant;
  xDocXmlCopy: Variant;

  xREC_PAY_ID: string;
  xREC_PAY_ACCOUNT: string;
//  xOrgID_3081: string;

  xBDPD_BS_RCP_Analitical: boolean;
  xBDPD_BS_RCP: string;
  xBDPD_BS_PAY_Analitical: boolean;
  xBDPD_BS_PAY: string;
  xCountBDPDST: integer;
  xBDPDST_Analitical: boolean;

  xXmlED_Lines: variant;
  xXmlED_Line: variant;
  xXmlBDPDST: variant;
  xXmlED_Doc: variant;
//  xCreateEDLine: boolean;

  {~DoFill_Block1_
    определение бюджета, счета }
  procedure DoFill_Block1_( aPrefixField, aHowIs1: string);
  var
    xBudgetID: string;
    xLS_ID: string;
    xOrg_ID: string;
    xLS_Xml: Variant;
  begin

      try
        WriteLog( FORMAT( 'Заполнение данных %s...', [ aHowIs1]), True);

        { exchange #2600
           плательщика требуется заполнять по аналогии
           с заполнением плательщика при создании ЭД 195го класса по aXmlIK.ZR/aXmlIK.ZV
          Заполнять ID организации-плательщика и счет плательщика -
          номером счета и ID счета, найденным аналогично SP (#2436+#2516).
          поиск организации плательщика:
            л/с - равный по номеру aXmlIK.LS_UBP, без даты закрытия;
            Код организации должен быть равен aXmlIK.KOD_UBP_PUBP}
        xBudgetID := Exch2436_SearchBudgetID(  xIK_KOD_UBP_PUBP,
                                               aFinYear,
                                               xIK_LS_UBP,
                                               xLS_ID,
                                               xOrg_ID,
                                               // всегда проверяем чтобы л/с
                                               // был без даты закрытия.
                                               TRUE);
        // в случае проблем не создаем ЭД 195го класса
        if (xBudgetID = '') then begin
          WriteInfo( FORMAT(   'Не удалось определить бюджет загрузки по коду организации %s и номеру л/с %s.',
                              [ xIK_KOD_UBP_PUBP,
                                xIK_LS_UBP]));
          xErrors := TRUE;
          EXIT;
        end;

        if (xBudgetID <> BudgetId) then begin
          WriteInfo( FORMAT(   'Не совпадает бюджет найденной организации по коду организации %s и номеру л/с %s с бюджетом загрузки aXmlIK файла.',
                              [ xIK_KOD_UBP_PUBP,
                                xIK_LS_UBP]));
          xErrors := TRUE;
          EXIT;
        end;
        if (xLS_ID = '') then begin
          WriteInfo( FORMAT(  'Не удалось найти описание л/с по коду организации %s и номеру л/с %s.',
                              [ xIK_KOD_UBP_PUBP,
                                xIK_LS_UBP]));
          xErrors := TRUE;
          EXIT;
        end;
        // загружаем описание счета плательщика
        if (GetOrgAccountGetter_ToXML( xLS_Xml, 'id='+xLS_ID) <> 1)
          then begin
            WriteInfo( 'Не удалось прочитать описание найденного л/с в бд.');
            xErrors := TRUE;
            EXIT;
          end;
        aXmlED.setAttribute( aPrefixField + '_ID', xOrg_ID);
        // КПП - из файла aXmlIK. KPP_UBP
        aXmlED.setAttribute( aPrefixField + '_KPP', xIK_KPP_UBP);
        // ИНН плательщика заполнять из организации, ID которой заполняется
        // в этом блоке.
        aXmlED.setAttribute( aPrefixField + '_TAXCODE', GetOrgTaxCode( xOrg_ID));
        // Наименование - из файла aXmlIK.NAME_UBP_PUBP
        aXmlED.setAttribute( aPrefixField + '_NAME',
                              VarToStr( aXmlIK.GetAttribute( 'NAME_UBP_PUBP')));
        // описание л/с
        aXmlED.setAttribute( aPrefixField + '_ACC_ID'     , xLS_ID);
        aXmlED.setAttribute( aPrefixField + '_ACCOUNT'    , xIK_LS_UBP);
        // описание реквизиитов по ЛС
        aXmlED.setAttribute( aPrefixField + '_ACC_ID'     ,
                          xLS_Xml.GetAttribute('ORGACCOUNT_ID'));
        aXmlED.setAttribute( aPrefixField + '_OFK_NAME'   ,
                          xLS_Xml.GetAttribute('ORG_OFK_NAME'));
        aXmlED.setAttribute( aPrefixField + '_UFK_NAME'   ,
                          xLS_Xml.GetAttribute('ORG_UFK_NAME'));
        aXmlED.setAttribute( aPrefixField + '_UFK_ACCOUNT',
                          xLS_Xml.GetAttribute('ORG_UFK_ACCOUNT'));
        aXmlED.setAttribute( aPrefixField + '_UFK_ACC_ID' ,
                          xLS_Xml.GetAttribute('ORG_UFK_ACC_ID'));
        aXmlED.setAttribute( aPrefixField + '_BIC'        ,
                          xLS_Xml.GetAttribute('ORG_BIC'));
        aXmlED.setAttribute( aPrefixField + '_B_NAME'     ,
                          xLS_Xml.GetAttribute('ORG_B_NAME'));
        except
          ExceptionLog( 'Сбой MakeDocumentIkBD_New.DoFill_Block1_');
      end;

  end;



  {~SearchRecLS_for_ED193_
    exchange #2965
    поиск счета получателя требуется искать в орг. получателя с типом 5,
    актуальный (с пустой датой закрытия/блокировки),
    в поле "Единый счет бюджета" карточки которого, стоит значение BS_RCP.
    Если такой не найден, то поле остается пустым,
    полю "Счет УФК" присваивается значение счета BS_RCP.
    exchange #2993
    если счет взят из блока aXmlIK.LS_UBP (xACCOUNT_TYPE=2), то он ищется
    среди счетов орг.получателя, а если счет взят по
    BDPS.BS_RCP (xACCOUNT_TYPE=1), то ищется счет, у которого
    счет BDPS.BS_RCP является счетом единым счетом бюджета организации REC_ID.}
  procedure SearchRecLS_for_ED193_( aACCOUNT, aACCOUNT_TYPE: string);

    function DoFillAcc195_( aAccID: string): boolean;
    var
      xXml: Variant;
    begin

        try
          xXml := QueryXml(
                    ' Select A.Id Id, Ofk.Description Ofk_Description,'
                   +' a.account_number accnum,'
                   +' Ufk.Description Ufk_Description, UfkAcc.Account_Number Ufk_Account_Number,' +
                    ' UfkAcc.Id Ufk_Acc_Id, Ufkb.Bic Bic, Ufkb.Description B_Name, Ufkb.CorAccount CorAccount,' +
                    ' SpecAcc.Account_Number SpecUfk_Account_Number, SpecAcc.Id SpecUfk_Acc_Id,' +
                    ' Specb.Bic SpecBic, Specb.Description Specb_Name, Specb.CorAccount SpecCorAccount,' +
                    ' IncAcc.Account_Number IncUfk_Account_Number, IncAcc.Id IncUfk_Acc_Id, Incb.Bic IncBic,' +
                    ' Incb.Description Incb_Name, Incb.CorAccount IncCorAccount, IncUfkf.Name IncUfk_Filial_Name' +
                    ' From OrgAccount A' +
                    ' Left Join Org Ofk on Ofk.Id = A.Keeper_Id' +
                    ' Left Join Org Ufk on Ufk.Id = A.Executer_Id' +
                    ' Left Join OrgAccount UfkAcc on UfkAcc.Id = A.ExecuterAcc_Id' +
                    ' Left Join Bank Ufkb on Ufkb.Id = UfkAcc.Bank_Id' +
                    ' Left Join OrgAccount SpecAcc on SpecAcc.Id = A.SpecialFundsAcc_Id' +
                    ' Left Join Bank Specb on Specb.Id = SpecAcc.Bank_Id' +
                    ' Left Join OrgAccount IncAcc on IncAcc.Id = A.IncomeAcc_Id' +
                    ' Left Join Bank Incb on Incb.Id = IncAcc.Bank_Id' +
                    ' Left Join Filial IncUfkf on IncUfkf.Id = IncAcc.Filial_Id' +
                    ' Where A.id=?',
                    [ aAccID]);
          if (xXml.documentElement.childNodes.Length <> 1)
            then Result := FALSE
            else begin
              xXml := xXml.documentElement.childNodes.Item[0];
              WriteLog( FORMAT( 'Найден счет получателя с референсом: %s',
                                [ xXml.getAttribute('ID')]));

              aXmlED.setAttribute( 'REC_ACC_ID', xXml.getAttribute('ID'));
              aXmlED.SetAttribute( 'REC_ACCOUNT', xXml.getAttribute('ACCNUM'));
              aXmlED.setAttribute( 'REC_OFK_NAME', xXml.getAttribute('OFK_DESCRIPTION'));
              aXmlED.setAttribute( 'REC_UFK_NAME', xXml.getAttribute('UFK_DESCRIPTION'));
              aXmlED.setAttribute( 'REC_UFK_ACCOUNT', xXml.getAttribute('UFK_ACCOUNT_NUMBER'));
              aXmlED.setAttribute( 'REC_UFK_ACC_ID', xXml.getAttribute('UFK_ACC_ID'));
              Result := TRUE;
            end;
          except
            ExceptionProc( 'DoFillAcc195_');
        end;

    end;

  var
    xOrgID: string;
    xAccID: string;
//    xBDPD_BS_RCP: string;
    xSQL: string;
  begin

      try
        xOrgID := GetNodeAttributeEx( aXmlED, 'REC_ID');
        if (aACCOUNT_TYPE = '1') then begin
          // exchange #2965 - счет из BDPD.BS_RCP
          // при этом проверяется тип =2 а не тип =5.
//          xBDPD_BS_RCP := GetNodeAttributeEx( aXmlBDPD, 'BS_RCP');
          xSQL :=  ' from orgaccount a'
                  +' join orgaccount ae on ae.id=a.executeracc_id'
                  +' where a.org_id=?'
                  +' and a.orgacctype_id=2 and a.close_date is null'
                  +' and ae.account_number=?';
          if (QueryField( 'select count( * ) N' + xSQL,
                          [ xOrgID,
                            xBDPD_BS_RCP],
                          'N') = '1') then begin
            xAccID := QueryField( 'select distinct a.id ID' + xSQL,
                                  [ xOrgID,
                                    xBDPD_BS_RCP],
                                  'ID');
            if DoFillAcc195_( xAccID)
              then EXIT;
          end;
          WriteInfo( 'Референс получателя не опеределен', True);
          // счет УФК заполнить значением BDPD.BS_RCP
          aXmlED.setAttribute( 'REC_UFK_ACCOUNT', xBDPD_BS_RCP);
          EXIT;
        end;

        // exchange #2993 - счет из aXmlIK.LS_UBP 5го типа
        xSQL :=  ' from orgaccount a'
                +' where a.org_id=? and a.orgacctype_id=5'
                +' and a.close_date is null and a.account_number=?';
        if (QueryField( 'select count( * ) N' + xSQL,
                        [ xOrgID,
                          aACCOUNT],
                        'N') = '1') then begin
          xAccID := QueryField( 'select distinct a.id ID' + xSQL,
                                [ xOrgID,
                                  aACCOUNT],
                                'ID');
          if DoFillAcc195_( xAccID)
            then EXIT;
        end;
        WriteInfo( 'Референс получателя не опеределен', True);
        except
          ExceptionProc( 'SearchRecLS_for_ED193_');
      end;

  end;


  {~DoFill_Block2_
    заполнения блока плательщика (для ЭД 24го класса)/получателя (для ЭД 5го класса)
    поскольку код идентичен, а отличие только в префиксе полей:
      PAY - для плательщика;
      REC - для получателя.
    то создана подпрограмма, которая заполняет этот блок, а префикс передается
    в качестве параметра.
      aPrefixField должен принимать только значение REC или PAY.
      aDocClass - должен принимать значение '24' или '5'
      aHowIs - строка уточнения, в которой указывается 'плательщик' или 'получатель'.
    в принципе, достаточно только одной строки класса, и по этому параметру
    можно определить и префикс и строку уточнения. но чтобы не делать лишней
    проверки, принято решение указывать сразу все параметры:
      для ЭД 24го класса: '24', 'PAY', 'плательщика', 'плательщик'
      для ЭД 5го класса: '5', 'REC', 'получателя', 'получатель'
      }
  procedure DoFill_Block2_( aDocClass, aPrefixField, aHowIs1, aHowIs2: string);
  var
    xOrgID: string;
    xBDPD_ACCOUNT: string;
    xBDPD_INN: string;
    xBDPD_KPP: string;
    xXML_ORG: Variant;
    xXML_ORG_ACCOUNT: Variant;
    xBDPD_CNAME: string;
    s: string;
    xIndexAcc: integer;
    xACCOUNT_TYPE: string;
  begin

      try
        WriteLog( FORMAT( 'Заполнение данных %s...', [ aHowIs1]), True);

        // exchange #2891
        // загрузка полей получателя для разных классов разная
        if (aDocClass = '5') then begin

          xBDPD_INN     := TRIM( GetNodeAttributeEx( aXmlBDPD, 'INN_RCP'));
          xBDPD_KPP     := TRIM( GetNodeAttributeEx( aXmlBDPD, 'KPP_RCP'));
          xBDPD_CNAME   := GetNodeAttributeEx( aXmlBDPD, 'CNAME_UBP_RCP');
          xBDPD_ACCOUNT := GetNodeAttributeEx( aXmlBDPD, 'BS_RCP');
          // exchange #2993
          // при создании эд 195го из 5го, для эд 5го счет ищем по кешу.
          // если по кешу нашли, значит это счет aXmlIK.LS_UBP с типом 5.
          // если по кешу счет не определен, то остается как раньше
          // из поля BDPD.BS_RCP с типом 2.
          if xCreateDoc195 then begin
            // индекс = BDPD.GUID_FK+|+aXmlIK.INN_UBP+|+aXmlIK.KPP_UBPP
            s := GetNodeAttributeEx( aXmlBDPD, 'GUID_FK')
                         +'|' + xBDPD_INN
                         +'|' + xBDPD_KPP;
            xIndexAcc := aList_ACC_I.IndexOf( s);
            if (xIndexAcc = -1)
              then xACCOUNT_TYPE := '1'
              else begin
                xBDPD_ACCOUNT := aList_ACC_V.Strings[ xIndexAcc];
                xACCOUNT_TYPE := '2';
              end;

          end;
        end else begin
          xBDPD_INN     := TRIM( aXmlBDPD.getAttribute('INN_PAY'));
          xBDPD_KPP     := TRIM( aXmlBDPD.getAttribute('KPP_PAY'));
          xBDPD_CNAME   := aXmlBDPD.getAttribute('CNAME_PAY');
          xBDPD_ACCOUNT := aXmlBDPD.getAttribute('BS_PAY');
        end;

        aXmlED.setAttribute( aPrefixField + '_ID'     , '');
        aXmlED.setAttribute( aPrefixField + '_TAXCODE', xBDPD_INN);
        aXmlED.setAttribute( aPrefixField + '_KPP'    , xBDPD_KPP);
        aXmlED.setAttribute( aPrefixField + '_NAME'   , xBDPD_CNAME);
        aXmlED.setAttribute( aPrefixField + '_ACCOUNT', '');
        aXmlED.setAttribute( aPrefixField + '_ACC_ID' , '');

        // exchange #2965
        // счет ищем только если эд 195й не создается
        // для него счет ищем по другому
        if NOT xCreateDoc195
          then aXmlED.SetAttribute( aPrefixField + '_ACCOUNT', xBDPD_ACCOUNT);

        // если ИНН не указан - организацию не ищем
        if (LENGTH( xBDPD_INN) <= 0) then EXIT;

        WriteLog( FORMAT( 'Поиск референса %s по ИНН и КПП...', [ aHowIs1]), True);
        xXML_ORG := GetOrgByTaxKpp( xBDPD_INN,
                                    xBDPD_KPP,
                                    aDocClass,
                                    aPrefixField,
                                    False,
                                    aXmlED);
        if (xXML_ORG.documentElement.childNodes.Length <> 1)
          then WriteLog( FORMAT( 'Референс %s не опеределен', [ aHowIs1]), True)
          else begin
            xXML_ORG := xXML_ORG.documentElement.childNodes.Item[0];

            xOrgID := xXML_ORG.getAttribute('ID');

            WriteLog( FORMAT( 'Найден %s с референсом: %s',
                              [ aHowIs2,
                                xOrgID]));

            aXmlED.setAttribute( aPrefixField + '_ID', xOrgID);

            WriteLog( FORMAT( 'Поиск референса счета %s...', [ aHowIs1]), True);
            // exchange #2965
            // счет ищем только если эд 195й не создается
            // для него счет ищем по другому
            if xCreateDoc195 then begin
              // exchange #2965
              // счет ищем только если эд 195й создается
              SearchRecLS_for_ED193_( xBDPD_ACCOUNT, xACCOUNT_TYPE);
            end else begin
              xXML_ORG_ACCOUNT := GetAccAllRekByOrgIdAccNum( xOrgID,
                                                             xBDPD_ACCOUNT);
              if (xXML_ORG_ACCOUNT.documentElement.childNodes.Length <> 1)
                then WriteInfo( FORMAT( 'Референс счета %s не опеределен', [ aHowIs1]),
                               True)
                else begin
                  xXML_ORG_ACCOUNT := xXML_ORG_ACCOUNT.documentElement.childNodes.Item[0];

                  WriteLog( FORMAT( 'Найден счет %s с референсом: %s',
                                    [ aHowIs1,
                                      xXML_ORG_ACCOUNT.getAttribute('ID')]));

                  aXmlED.setAttribute( aPrefixField + '_ACC_ID',
                                    xXML_ORG_ACCOUNT.getAttribute('ID'));
                  aXmlED.setAttribute( aPrefixField + '_OFK_NAME',
                                    xXML_ORG_ACCOUNT.getAttribute('OFK_DESCRIPTION'));
                  aXmlED.setAttribute( aPrefixField + '_UFK_NAME',
                                    xXML_ORG_ACCOUNT.getAttribute('UFK_DESCRIPTION'));
                  aXmlED.setAttribute( aPrefixField + '_UFK_ACCOUNT',
                                    xXML_ORG_ACCOUNT.getAttribute('UFK_ACCOUNT_NUMBER'));
                  aXmlED.setAttribute( aPrefixField + '_UFK_ACC_ID',
                                    xXML_ORG_ACCOUNT.getAttribute('UFK_ACC_ID'));
              end;
            end;
          end;
        except
          ExceptionLog( 'Сбой MakeDocumentIkBD_New.DoFill_Block2_');
      end;

  end;

begin

    try
      xXmlED_Doc := aXmlED.ownerDocument;

      // пока ошибок нет
      xErrors := FALSE;

      // exchange #2965
      // если эд 195й нужно создавать, то выполняем копирование входных
      // параметров.
      if NOT aLock195by2965 then begin

        // копируем создаваемый ЭД из параметра aXmlED
        // это на случай, если проверка по exchange #2965 даст добро на
        // создание эд 195го, но в бд будут найдены уже существующие эд.
        // при этом нужно будет повторить обработку этого же блока BDPD
        // с созданием по нему эд 5/24 по старому.
        xDocCopy := CreateOleObject('Microsoft.XmlDom');
        xDocCopy.LoadXml( xXmlED_Doc.Xml);
        xDocCopy := xDocCopy.DocumentElement;
        // здесь просто сохраняем ссылку aXmlBDPD
        // при разборе строк, переменная aXmlBDPD может переходить на дочерние
        // узлы, но сам хмл не меняется, поэтому тут будем просто хранить
        // ссылку на текущий узел.
        xDocXmlCopy := aXmlBDPD;
      end;

      // exchange #3009
      // При загрузке BDPD пропускать все BDPD со значением поля "BS_RCP"
      // начинающимся на "40116"
      xBDPD_BS_RCP := GetNodeAttributeEx( aXmlBDPD, 'BS_RCP');
      if (POS( '40116', xBDPD_BS_RCP) = 1) then
        if vCfg3009 then begin
          WriteInfo(
              FORMAT( 'Пропущен раздел BDPD со счетом BS_RCP=%s по настройке конфигурации.',
                      [ GetNodeAttributeEx( aXmlBDPD, 'BS_RCP')]));
          EXIT;
        end;

      // exchange #3105
      // чтобы при создании эд 24го в строках понимать что заполнять
      // аналитичускую или бюджетную строку, это определяем по тому
      // как заполнено поле BDPD.BS_RCP.
      // если счет начинается на 406/407, то заполняется аналитическая строка
      // иначе - бюджетная.
      if (COPY(xBDPD_BS_RCP, 1, 3) in [ '406','407'])
        then xBDPD_BS_RCP_Analitical := TRUE
        else xBDPD_BS_RCP_Analitical := FALSE;


      // exchange #3081
      // для эд 5го класса тоже нужно формировать аналит.строку.
      // делается это аналогично как и по 24му, только проверяется
      // поле BDPD.BS_PAY.
      xBDPD_BS_PAY := GetNodeAttributeEx( aXmlBDPD, 'BS_PAY');
      if (COPY(xBDPD_BS_PAY, 1, 3) in [ '406','407'])
        then xBDPD_BS_PAY_Analitical := TRUE
        else xBDPD_BS_PAY_Analitical := FALSE;


      // это понадобится в дальнейшем
      xIK_LS_UBP   := GetNodeAttributeEx( aXmlIK, 'LS_UBP');
      // Код организации должен быть равен aXmlIK. KOD_UBP_PUBP
      xIK_KOD_UBP_PUBP := TRIM( GetNodeAttributeEx( aXmlIK, 'KOD_UBP_PUBP'));
      xIK_INN_UBP := TRIM( GetNodeAttributeEx( aXmlIK, 'INN_UBP'));
      xIK_KPP_UBP := TRIM( GetNodeAttributeEx( aXmlIK, 'KPP_UBP'));
 //     xPay_Org_KPP := TRIM( VarToStr( aXmlIK.getAttribute( 'KPP_UBP')));
      // для ЭД 24го класса это относится к получателю
//      xRec_Org_KPP := xPay_Org_KPP;


      // вычисляем сумму всех строк и записываем ее в шапку ЭД
      // exchange #3105
      // унификация кода, а заодно проверка заполнения кбк в строках BDPDST
      xCountBDPDST := CalcAmount_by_BDPDST( aXmlED, aXmlBDPD);

      if (aXmlBDPD.childNodes.Item[0].getAttribute('DIR_SUM') = '1')
        then xDocClass := '5'
        else xDocClass := '24';

      // exchange #3081
      // определяем, для каких эд будет формироваться аналитическая строка
      xBDPDST_Analitical := FALSE;
      case xDocClass of
        '24': if xBDPD_BS_RCP_Analitical
                then xBDPDST_Analitical := TRUE;
        '5':  if xBDPD_BS_PAY_Analitical
                then xBDPDST_Analitical := TRUE;
      end;//case//

      aXmlED.setAttribute('F_PARENTCLASS', ''); //Класс документа, среди которых надо искать пару.
      aXmlED.setAttribute('action', 'insert');
      aXmlED.setAttribute('class', xDocClass);
      aXmlED.setAttribute('DECLINE', 'False');
      aXmlED.setAttribute('USEGROUPBUH25', param_UseGroupBuh25);

      // предзаполнение шапки
      FillElementBySchemaLoad(aXmlED, aXmlBDPD);

{
      xAmount := 0.0;
      for i := 0 to aXmlBDPD.childNodes.Length - 1 do begin
        xNode := aXmlBDPD.childNodes.Item[i];
        xAmount := xAmount + StrToCurr( xNode.getAttribute('SUM'));
      end;//for//
      aXmlED.SetAttribute( 'AMOUNT', Format( '%.2f', [ xAmount]));
}

      // exchange #2965
      // создание 195го по BD
      // Для aXmlIK.LS_UBP, первые два знака значения которых равно «30»
      // и в блоке «Информация из расчетных документов» (BDPD)
      // загружаемого файла есть документ со значением BDPD.GUID=пусто,
      // и aXmlIK.INN_UBP, aXmlIK.KPP_UBP равны соответственно BDPD.INN_PAY,
      // BDPD.KPP_PAY, требуется проверить для этой же строки:
      // ЕСЛИ значение BDPD.BS_PAY+ BDPD.BIC_PAY = BDPD.BS_RCP+ BDPD.BIC_RCP
      // то создаем 195й из BD
      // exchange #2993
      // проверка BDPD.BS_PAY+ BDPD.BIC_PAY с BDPD.BS_RCP+ BDPD.BIC_RCP
      // перенесена в начало.
      // если BDPD.BS_PAY+ BDPD.BIC_PAY <> BDPD.BS_RCP+ BDPD.BIC_RCP,
      // то работаем по старому.

      xCreateDoc195 := FALSE;
      if NOT aLock195by2965 then begin
        // при проверке BDPD.BS_PAY+ BDPD.BIC_PAY с
        // BDPD.BS_RCP+ BDPD.BIC_RCP.
        // добавляем разделители: BDPD.BS_PAY+|+BDPD.BIC_PAY и
        // BDPD.BS_RCP+|+BDPD.BIC_RCP. это дает то, что если одно поле
        // не будет заполнено, а второе будет, а для второй группы полей
        // будет наоборот, то простое сложение строк даст одинаковый
        // результат. например: ''+'1' = '1'+''
        // с разделителями это не пройдет: ''+|+'1' <> '1'+|+''
        if (( TRIM( GetNodeAttributeEx( aXmlBDPD, 'BS_PAY'))+'|'
             +TRIM( GetNodeAttributeEx( aXmlBDPD, 'BIC_PAY')))
             = ( TRIM( GetNodeAttributeEx( aXmlBDPD, 'BS_RCP'))+'|'
                +TRIM( GetNodeAttributeEx( aXmlBDPD, 'BIC_RCP')))) then begin

          // если PDBD.BS_PAY+ BDPD.BIC_PAY = BDPD.BS_RCP+ BDPD.BIC_RCP
          // то проверяется гуид, инн+кпп и начало счета на 30.
          // если все проверки совпадают - создается эд 195й.
          // иначе - эд 195й не создается и обработку bdpd прерываем.
          if (LENGTH( TRIM( GetNodeAttributeEx( aXmlBDPD, 'GUID'))) <= 0) then
            if (    (TRIM( GetNodeAttributeEx( aXmlBDPD, 'INN_PAY')) = xIK_INN_UBP)
                AND (TRIM( GetNodeAttributeEx( aXmlBDPD, 'KPP_PAY')) = xIK_KPP_UBP)) then
              // exchange #2993
              // проверка счета перенесена на позже
              if (POS( '30', xIK_LS_UBP) = 1) then begin
                // заполнять в начале будем эд 5й
                // а в результате будем создавать эд 195й из 5го.
                xDocClass     := '5';
                xCreateDoc195 := TRUE;

              end;

          if NOT xCreateDoc195 then begin
            WriteInfo(
                FORMAT( 'Для документа внебанковского BDPD с № %s, датой %s и суммой %s, '
                       +'кредитовое приложение к выписке не будет создано.',
                       [ GetNodeAttributeEx( aXmlED, 'DOC_NUMBER'),
                         GetNodeAttributeEx( aXmlED, 'DOC_DATE') ,
                         GetNodeAttributeEx( aXmlED, 'AMOUNT')]));
            EXIT;
          end;
        end;
      end;


      // сразу отображаем описание ЭД в журнале.
      // в отличие от старого кода это дает то, что последующие сообщения
      // нормально соотносятся с ЭД.
      if xCreateDoc195
        then xDocInfo := 'Заявка БУ/АУ на выплату средств'
        else
          if (xDocClass = '5')
            then xDocInfo := 'Приложение к выписке дебетовое'
            else xDocInfo := 'Приложение к выписке кредитовое';
      xDocInfo := FORMAT( 'АЦК: "%s" № %s Дата: %s Сумма: %s',
                           [ xDocInfo,
                             aXmlED.getAttribute('DOC_NUMBER'),
                             aXmlED.getAttribute('DOC_DATE') ,
                             aXmlED.getAttribute('AMOUNT')]);
      WriteLog( xDocInfo, True);
      {
      if (xCountBDPDST < 0) then begin
        WriteInfo( 'Не найдено заполненных строк BDPDST.');
        xErrors := TRUE;
      end;
      }

      // exchange #3062 - проверка кбк
      // но только при создании эд 5/24, поскольку 195й порождается из 5го
      // exchange #2600
      // 2.9.2.	Если в IK.LS_UBP значение начинается с:
      // 20, 21, 22, 30, 31, 32, обрабатывать блок не по
      // существующему алгоритму, а по новому
      // exchange #2926
      // при загрузке по BDPD для нового алгоритма загружать требуется
      // код цели как при загрузке VK:
      // (п.2.10.2.1. Создавать по механизму, аналогичному выписке VK...
      // в результате нужно анализировать значение BDPDST.ADD_KLASS.
      // exchange #3105
      // нельзя проверять кбк в этот момент, поскольку для эд 24го будет
      // два варинта заполнения строк.
      {
      if NOT xCreateDoc195 then
        if NOT CheckKBK_All_BDPDST( aXmlBDPD, BudgetId, TRUE)
          then EXIT;
}

      { exchange #2886 п.1
        При разборе блока BDPD при загрузке по конфигурации  «Imp_FK_IK»,
        если в  поле BDPD.BS_PAY указано значение банковского счета,
        первые 4 знака которого соответствуют значению «2020»,
        то такой документ пропускать, продолжать обрабатывать блок далее.
        exchange #2965
        если создается эд 195й - эту проверку игнорируем}
      if NOT xCreateDoc195 then
        if (POS( '2020', aXmlBDPD.GetAttribute('BS_PAY')) = 1) then begin
          WriteInfo(
              FORMAT( 'ЭД игнорируется - расчетный счет Плательщика %s начинается на 2020.',
                      [ aXmlBDPD.GetAttribute('BS_PAY')]));
          EXIT;
        end;

      // exchange #2600
      // для выполнения пп.2.9.2.4 (создание ЭД 193го класса из 24го)
      // требуется в документе указать специальный параметр.
      // но только, если ЭД 24го класса создается из BDPD по новому
      // алгоритму, описанному по пп.2.9.2.
      if (xDocClass = '24')
        then aXmlED.SetAttribute( '__IK_MODE__', '2600_2.9.2.4');



      //ищем пару по полю GUID, проверку повторной загрузки оставляем по полю GUID_FK
      aXmlED.setAttribute('GUID', aXmlBDPD.getAttribute('GUID'));
      aXmlED.setAttribute('FOREIGN_KEY', aXmlBDPD.getAttribute('GUID_FK'));
      aXmlED.setAttribute('PAYKIND', PayKindSetAsAzk(aXmlBDPD.getAttribute('VID_PL')));
      aXmlED.setAttribute('CARRY_DATE', DateTimeToXml(StrToDate(aXmlIK.getAttribute('DATE'))));
      // разборка с идентификатором
      // exchange #3062 - унификация кода
      FillDepartmentalInfo2( aXmlED, aXmlBDPD);
      (*
      aXmlED.setAttribute('AUTHOR_ID', Get_Author_Id(aXmlBDPD.getAttribute('PAYSTATUS')));
      if (aXmlED.getAttribute('AUTHOR_ID') = '') and (aXmlBDPD.getAttribute('KBK') <> '') then
        aXmlED.setAttribute('AUTHOR_ID', 0);
      //Exchnge #771, если KBKD не пусто, а AUTHOR_ID пусто, то AUTHOR_ID заполняем нулем.
      if aXmlED.getAttribute('AUTHOR_ID') <> '' then
      begin
        // exchange #3062 - удален косгу
        // принимается всегда доходная
        aXmlED.setAttribute('PI_ANAL_KIND', '1');
{        aXmlED.setAttribute('PI_ANAL_KIND', GetPi_Anal_Kind(
          Copy(aXmlBDPD.getAttribute('KBK'), 18, 3)));}
        aXmlED.setAttribute('GROUND_ID', GetGrnd_Ground_Id(aXmlBDPD.getAttribute('OSNPLAT')));
        aXmlED.setAttribute('PAYTYPE_ID', GetGrnd_PayType_Id(aXmlBDPD.getAttribute('TYPE_PL')));
      end
      else begin
        aXmlED.setAttribute('PI_BUDGET_CODE', '');
        aXmlED.setAttribute('PAY_OKATO', '');
        aXmlED.setAttribute('TAXPERIOD', '');
        aXmlED.setAttribute('GRND_DOC_NUMBER', '');
      end;
      *)
      if aXmlBDPD.getAttribute('ORDER_PAY') = '0'
        then aXmlED.setAttribute('QUEUE_KIND', '');

      // проверяем бюджетные или спецсредства - не проверяются
      // согласовано с АО
      aXmlED.setAttribute('F_SS', 'False');


      if (xDocClass = '24') then begin
        // =================== Кредитовое приложение =========================\\
        aXmlED.setAttribute('F_CRUSH24', IfThen(param_CrushDoc24, 'True', 'False'));

        WriteLog('Заполнение данных получателя из выписки', True);
        // exchange #2497
        // При создании ПВК при загрузке ИК, блок получателя их выписки должен
        // тянуться из блока BDPD, а не из блока aXmlIK, а организация будет определяться
        // как раньше по реквизитам из aXmlIK
        xSearchOrgBy_TaxCode    := VarToStr( aXmlBDPD.getAttribute('INN_RCP'));
        xSearchOrgBy_KPP        := VarToStr( aXmlBDPD.getAttribute('KPP_RCP'));
        xSearchOrgBy_TaxCodeEqu := FALSE;

        aXmlED.setAttribute('ORG_ID'       , '');
        aXmlED.setAttribute('ORG_TAXCODE'  , xSearchOrgBy_TaxCode);
        aXmlED.setAttribute('ORG_KPP'      , xSearchOrgBy_KPP);
        aXmlED.setAttribute('ORG_NAME'     , VarToStr( aXmlBDPD.getAttribute('CNAME_UBP_RCP')));

        { exchange #2505
          если в файле aXmlIK.INN_UBP и BDPD.INN_RCP для 24 класса отличаются,
          то поиск для проставления референса осуществлять только по BDPD.INN_RCP
          и BDPD.INN_RCP (искать по ИНН и КПП только среди организаций, которые
          имеют хотя бы одну роль, кроме следующих: Контрагент, Крупный плательщик,
          ЦБФ, Кредитная организация, Генеральный агент, а если КПП 0,
          то только по ИНН только среди тех, которые имеют хотя бы одну роль,
          кроме следующих: Контрагент, Крупный плательщик, ЦБФ,
          Кредитная организация, Генеральный агент), как при загрузке VB.
          В блок "Получатель из выписки" (ИНН, КПП, Наименование) данные
          всегда записывать именно из блока BDPD, а не из найденной в системе
          организации.}
        if ( xSearchOrgBy_TaxCode = xIK_INN_UBP) then begin
          // здесь поиск будет выполняться для ИНН и КПП из aXmlIK, при этом
          // aXmlIK.КПП может быть <> BDPD.КПП.
          // такой случай возможет только для организаций филиалов,
          // когда ИНН у таких организаций одинаковый, но КПП и название разное.
          // при этом на форме delphi КПП и название не собъется (отобразится
          // именно из поле КПП и названия (из раздела BDPD)), а поскольку ИНН
          // должен быть одинаковым, то отображение ИНН будет правильным.
          // но если у филиалов будет другой ИНН - это будет считаться ошибкой БД.
          xSearchOrgBy_TaxCode    := xIK_INN_UBP;
          xSearchOrgBy_KPP        := xIK_KPP_UBP;//VarToStr( aXmlIK.getAttribute('KPP_UBP'));
          xSearchOrgBy_TaxCodeEqu := TRUE;
        end;
        // exchange #2497 + #2505
        if (xSearchOrgBy_TaxCode <> '') then begin
          // exchange #2497 + #2505
          xOrgXml := GetOrgByTaxKpp( xSearchOrgBy_TaxCode,
                                     xSearchOrgBy_KPP,
                                     '24',
                                     'REC',
                                     False,
                                     aXmlED);
          if xOrgXml.documentElement.childNodes.length = 1
            then aXmlED.setAttribute(
                      'ORG_ID',
                      xOrgXml.documentElement.childNodes.item[0].getAttribute('ID'))
            else
              // exchange #2505: если aXmlIK.ИНН и BDPD.ИНН отличаются,
              // то по BD ищем только по ИНН, потом по ИНН+КПП.
              // при этом #2093 не используется.
              // если aXmlIK.ИНН = BDPD.ИНН, то дополнительно ищем по #2093
              // с учетом кода организации.
              if xSearchOrgBy_TaxCodeEqu then begin
                // exchange #2093 + #2497 + #2505
                xOrgXml := GetOrgByTaxKppBudgIdCode(
                                  xSearchOrgBy_TaxCode,
                                  xSearchOrgBy_KPP,
                                  BudgetId,
                                  aXmlIK.getAttribute('KOD_UBP_PUBP'),
                                  '3,6,7,8,17',
                                  True);
                if xOrgXml.documentElement.childNodes.length = 1
                  then aXmlED.setAttribute(
                            'ORG_ID',
                            xOrgXml.documentElement.childNodes.item[0].getAttribute('ID'));
              end;
        end;


        // получатель
        DoFill_Block1_( 'REC', 'получателя');
        // --- Плательщик ---
        DoFill_Block2_( '24', 'PAY', 'плательщика', 'плательщик');

        // exchange #2979 - сохраняем орг.получателя (только для эд 24го класса)
        xREC_PAY_ID := GetNodeAttributeEx( aXmlED, 'REC_ID');
        // exchange #3081
        // сохраняем получатель эд
//        xOrgID_3081 := xREC_PAY_ID;
      end else begin
        // ================== Дебетовое приложение ==========================\\
        // плательщик
        DoFill_Block1_( 'PAY', 'плательщика');
        // --- Получатель ---
        DoFill_Block2_( '5', 'REC', 'получателя', 'получатель');
        // exchange #3081
        // сохраняем плательщика эд
  //      xOrgID_3081 := GetNodeAttributeEx( aXmlED, 'PAY_ID');
      end;

      // exchange #2926
      // здесь сохраняем значение Rec_ID (получатель для эд 24го
      // или плательщик для эд 5го)
      xDocRecID := GetNodeAttributeEx( aXmlED, 'REC_ID');


      // exchange #2702
      Exch2702_ImpUIN( aXmlED, aXmlBDPD);

      //======================================================================

      //получатель доходов, т.к доходы по идее не должны приходить
      aXmlED.setAttribute('F_INCRECORGID', '');
      aXmlED.setAttribute('F_INCRECACCID', '');

      // exchange #2965
      // при создании 195го из 5го, строки формируем по исходным блокам BDPD,
      // поэтому в эд 5м строки не формируем
      if NOT xCreateDoc195 then begin
        // exchange #3009
        // При загрузке BDPD со значением поля "BS_RCP" начинающимся на "40116"
        // и счет aXmlIK.LS_UBP начинается на 30,
        // при линковке 5го с эд 195м, если в бд эд 195й для линковки не найден,
        // то нельзя создавать эд 195й по 5му. поэтому, здесь выставляем флаг
        // блокировки создания эд 195го по 5му в подпрограмме LinkDoc.

        if (POS( '40116', xBDPD_BS_RCP) = 1) then
          if (POS( '30', xIK_LS_UBP) = 1) then
            if (xDocClass = '5')
              then aXmlED.SetAttribute( '_BS_RCP_40116_LS_UBP_30_', '1');

        //инициализим сумму шапки
//        xAmount := 0.0;
        // проверяем, если в ЭД загружается только одна строка и в ней есть флаг
        // F_EMPTYKBK, указывающий нулевой КБК (отсутствующий код КБК в БД,
        // замененный на 0)
        {
        xLineFound := FALSE;
        if (aXmlBDPD.childNodes.Length = 1) then begin
          xNodeLine := aXmlBDPD.childNodes.Item[0];
          if StrToBool( xNodeLine.getAttribute('F_EMPTYKBK'))
            then xLineFound := TRUE;
        end;
        if xLineFound then begin
        }
        if (xCountBDPDST = 0) then begin

{
          // тогда строки в ЭД не создаем, а сумма в шапке будет равна сумме
          // из входной строки.
          // поправлено: сумма должна браться из первой строки во входной файле,
          // а не из шапки.
          xAmount := StrToCurr( xNodeLine.getAttribute('SUM'));
          // записываем сумму документа из строки в шапку
          aXmlED.setAttribute( 'AMOUNT', Format('%.2f', [ xAmount]));
          // записываем атрибут в шапку ЭД: говорит о том что строк нет.
          aXmlED.setAttribute( 'NOROW', 'True');
}
          // exchange #2831
          // для безстрочных ЭД тоже генерируется 195й класс при линковке
          // если первые два знака aXmlIK.LS_UBP равны «30»
          // exchange #2843
          // в 193 классе при формировании зачисления на лицевой счет с
          // типом 5 или 7 (поскольку это проверяется в самом начале загрузки,
          // здесь тип счета не проверяем) и первыми знаками равными "30"
          // нужно формировать строку в 5/24м классе:
          // с нулевыми кодами бюджетной классификации, со значением КВФО = "8",
          // заполнение поля "Сумма" в строке обязательно, поэтому берем из
          // строки родительского документа (по 30 ЛСФК она всегда одна),
          // то есть заполняем все поля, которые точно можем определить из
          // родительского документа - ничего не заполняем (согласовано с АО).
          // тип КБК по-умолчанию "Доходы"
          // «КОСГУ» присвоить значение:
          //    «000» для 24го класса,
          //    «999» для 5го класса.
          if (POS( '30', xIK_LS_UBP) = 1) then
            // на всякий случай проверяем, чтобы во входном файле была строка
            if (aXmlBDPD.childNodes.Length = 1) then begin
              xXmlBDPDST := aXmlBDPD.childNodes.Item[ 0];

              // снимаем атрибут в шапке ЭД: строка будет.
              aXmlED.setAttribute( 'NOROW', 'False');
  
              xXmlED_Lines := aXmlED.appendChild(
                                      xXmlED_Doc.createElement('PAYORDERLINE'));
              xXmlED_Line := xXmlED_Lines.appendChild(
                                      xXmlED_Doc.createElement('PAYORDERLINE'));

              // предзаполнение
              FillElementBySchemaLoad( xXmlED_Line, xXmlBDPDST);
//              AddReplaceAttrVal(aXmlBDPD, aXmlED);

              // exchange #2891
              // тип КБК для 24го - доходы, для 5го - расходная
              // exchange #3105
              // для эд 24го всегда заполняется бюджетная строка
              if (xDocClass = '24') then begin
                xXmlED_Line.SetAttribute( 'ANAL_KIND', '1');     // доходная строка
                // КОСГУ
                // exchange #2850
                // для эд 24го класса «КОСГУ» присвоить значение поля «Код» «888»
                xXmlED_Line.setAttribute( 'KESD_CODE', '888');
                // КВФО
                xXmlED_Line.setAttribute( 'FSD_ID', '8');
              end else begin
                xXmlED_Line.SetAttribute( 'ANAL_KIND', '0');    // расходная
                // КОСГУ
                xXmlED_Line.setAttribute( 'KESR_CODE', '999');
                // КВФО
                xXmlED_Line.setAttribute( 'FSR_ID', '8');
              end;

              // ? - скопировано из заполнения многострочных ЭД
              // Exchange#2101 проставляем в шапку документа тип классификации
              // Anal_kind по последней строке, иначе АЦК некорректно отображает
              if (xDocClass = '5')
                then aXmlED.SetAttribute(
                            'ANAL_KIND',
                            GetNodeAttributeEx( xXmlED_Line, 'ANAL_KIND'));

              // ? - скопировано из заполнения многострочных ЭД
              // Exchange#2101 проставляем в шапку документа тип классификации
              if StrToBool(aXmlED.getAttribute('F_SS'))
                  and (xXmlED_Line.getAttribute('ANAL_KIND') = '0')
                then xXmlED_Line.setAttribute('FSR_ID', '2');


              // Exchange#2079 для доходной классификации в строки 24 класса проставляем плательщика и получателя
              if (xDocClass = '24')
                  and (xXmlED_Line.getAttribute('ANAL_KIND') = '1')
                then begin
                  if NOT StrIsEmpty( aXmlED.getAttribute('F_INCRECORGID'))
                    then xXmlED_Line.setAttribute(
                                'RECEIVER_ID',
                                GetNodeAttributeEx( aXmlED, 'F_INCRECORGID'));
                  if NOT StrIsEmpty( aXmlED.getAttribute('PAY_ID'))
                    then xXmlED_Line.setAttribute(
                                'PAYER_ID',
                                GetNodeAttributeEx( aXmlED, 'PAY_ID'));
                end;


              // exchange #2831 - помечаем ЭД 5/25го класса
              // EXCHANGE #2891 - поправлен флаг создания эд для линковки
              // exchange #2998 - небыл учтен параметр конфига
              // создание документов ау/бу при доработке #2831.
              // это работает только если счет начинается на 30.
              Doc5ByIK_BDPB_Mark2831( aXmlED,
                                      vCfg_2600_CreateED_AUBU,
                                      xIK_LS_UBP);

              // exchange #2926 - заполнение кода субсидии
              // exchange #2979 - поиск кода субсидии BDPDST.ADD_KLASS
              if (xDocClass = '24')
                then FillGrantinvestment2979(
                                    BudgetId,
                                    xXmlED_Line,
                                    GetNodeAttributeEx( xXmlBDPDST, 'ADD_KLASS'),
                                    xREC_PAY_ID);


//              aXmlED := aXmlED.parentNode;
//              aXmlBDPD := aXmlBDPD.parentNode;
            end;
        end else begin
          // здесь рассматривается случай для множества строк BDPDST
//        if (xCountBDPDST > 0) then begin
          // exchange #3081
          // сохраняем получатель эд для эд 24 и плательщика для эд 5го
          if (xDocClass = '24') then begin
            xREC_PAY_ID := GetNodeAttributeEx( aXmlED, 'REC_ID');
            xREC_PAY_ACCOUNT := GetNodeAttributeEx( aXmlED, 'REC_ACCOUNT');
          end else begin
            xREC_PAY_ID := GetNodeAttributeEx( aXmlED, 'PAY_ID');
            xREC_PAY_ACCOUNT := GetNodeAttributeEx( aXmlED, 'PAY_ACCOUNT');
          end;

          // строки документов.
          xXmlED_Lines := aXmlED.appendChild(
                                      xXmlED_Doc.createElement('PAYORDERLINE'));
//          aXmlED := aXmlED.appendChild(aXmlED.ownerDocument.createElement('PAYORDERLINE'));
          for i := 0 to aXmlBDPD.childNodes.Length - 1 do begin
            xXmlBDPDST := aXmlBDPD.childNodes.Item[i];
//            aXmlED := aXmlED.appendChild(aXmlED.ownerDocument.createElement('PAYORDERLINE'));


            // exchange #3105
            // именно здесь проверяем кбк в строках

            // для эд 24го - в зависимости от типа заполнения строки
            // аналитическая или бюджетная
            // exchange #3081
            // для эд 5го тоже проверяется создание аналит.строки
            if xBDPDST_Analitical then begin
              // проверяем, кбк в строке пустой ?
              if NOT IsExistsKBK_into_BDPDST( xXmlBDPDST) then begin
                WriteInfo( 'Для аналитических строк не определен тип КБК или КБК не заполнен.');
                xErrors := TRUE;
                CONTINUE;
              end;

              // аналитическая строка
              WriteLog( 'Формируется аналитическая строка...');

              // создается строка в ЭД
              xXmlED_Line := xXmlED_Lines.appendChild(
                                    xXmlED_Doc.createElement('PAYORDERLINE'));

              // предзаполнение
              FillElementBySchemaLoad( xXmlED_Line, xXmlBDPDST);

              // ацк-ф 21918
              // для эд 24го класса бюджетная строка не заполняется,
              // а только аналитическая часть.
              // заполняем отр код из поля bdpdst.add_klass, а так же
              // все прочие поля аналит.строки
              if NOT FillLineED24_21918_VI_VJ_VK(
                                  BudgetId,
                                  xXmlED_Line,
                                  xXmlBDPDST,
                                  xREC_PAY_ID,
                                  xIK_LS_UBP,
                                  xREC_PAY_ACCOUNT,
                                  xDocClass)
                then xErrors := TRUE;

              // подставляем квфо для аналит.строки
              CONTINUE;     // и все!
            end;

            WriteLog( 'Формируется бюджетная строка...');

            // создается строка в ЭД
            xXmlED_Line := xXmlED_Lines.appendChild(
                                      xXmlED_Doc.createElement('PAYORDERLINE'));

            // предзаполнение
            FillElementBySchemaLoad( xXmlED_Line, xXmlBDPDST);

            // проверка кбк - по старому
            Default_F_Line( xXmlED_Line);

            // копирование описания кбк в строку эд
            DoCopyKBK_from_BDPDST( xXmlBDPDST, xXmlED_Line);

            // для бюджетных строк проверяем указание кбк и тип кбк
            if NOT IsExistsKBK_into_BDPDST( xXmlED_Line) then begin
              // допускается отсутствие кбк, но тип кбк обязан быть указан
              if StrIsEmpty( GetNodeAttributeEx( xXmlED_Line, 'TYPE_KBK'))
                then begin
                  WriteInfo( 'Для бюджетных строк не указан тип КБК.');
                  xErrors := TRUE;
                  CONTINUE;
                end;
            end else begin
              // exchange #3062 - отмена косгу
              if NOT DoCheckKBK(  xXmlED_Line,
                                  BudgetId,
                                  FALSE, // пров.КЦ
                                  FALSE,   // без косгу
                                  param_ShemaLoadDopKbk)
                then begin
                  WriteInfo('Найдены КБК в файле, которые отсутствуют в базе АЦК.');
                  xErrors := TRUE;
                  CONTINUE;
                end;
            end;

            // Exchange#2101 проставляем в шапку документа тип классификации
            // Anal_kind по последней строке, иначе АЦК некорректно отображает
            if (xDocClass = '5')
              then aXmlED.setAttribute( 'ANAL_KIND',
                                        xXmlED_Line.getAttribute('ANAL_KIND'));
{
            //Если строка с неопределенны кбк, то выходим, сообщив пользователю
            if StrToBool(aXmlBDPD.getAttribute('F_EMPTYKBK')) then begin
              WriteInfo('ЭД не создан. Не определен тип КБК или КБК не заполнен.', True);
              Exit;
            end;
            }
//            xAmount := xAmount + StrToCurr(aXmlED.getAttribute('AMOUNT'));
//            AddReplaceAttrVal(aXmlBDPD, aXmlED);

            if StrToBool(aXmlED.getAttribute('F_SS'))
                and (xXmlED_Line.getAttribute('ANAL_KIND') = '0')
              then xXmlED_Line.setAttribute('FSR_ID', '2');

            // exchange #2600
            // 2.9.2.3.	КВФО заполнять:
            // 9 – если aXmlIK.LS_UBP начинается на 21 или 31,
            // в остальных случаях 8.
            // если реализуется старый алгоритм - в нем ничего не менять.
            if ((POS( '21', xIK_LS_UBP) = 1) OR (POS( '31', xIK_LS_UBP) = 1))
              then xFSR_Value := '9'
              else xFSR_Value := '8';

            // exchange #2831
            // ФТ-1.3.2 и ФТ-1.3.3
            // При формировании При формировании строки ЭД классов 24 и 5
            // по каждой строке блока BDPDST, если BDPDST.KBK пустое и первые два
            // знака aXmlIK.LS_UBP равны «30», то полям строки формируемого ЭД:
            // «КВФО» присвоить значение поля «Номер» строки справочника
            // «Виды финансового обеспечение»  «8»,
            // «КОСГУ» присвоить значение:
            //    «000» для 24го класса,
            //    «999» для 5го класса.
            // exchange #2850
            // для эд 24го класса «КОСГУ» присвоить значение поля «Код» «888»
            if StrIsEmpty( GetNodeAttributeEx( xXmlED_Line, 'KBK')) then
              if (POS( '30', xIK_LS_UBP) = 1) then begin

                xFSR_Value := '8';
                // в зависимости от поля "тип КБК" заполняем КОСГУ
                case xXmlED_Line.getAttribute('ANAL_KIND') of
                  // расходы
                  '0': if (xDocClass = '24')
                         then xXmlED_Line.setAttribute( 'KESR_CODE', '888')
                         else xXmlED_Line.setAttribute( 'KESR_CODE', '999');
                  // доходы
                  '1': if (xDocClass = '24')
                         then xXmlED_Line.setAttribute( 'KESD_CODE', '888')
                         else xXmlED_Line.setAttribute( 'KESD_CODE', '999');
                  // источники
                  '2': if (xDocClass = '24')
                         then xXmlED_Line.setAttribute( 'KESI_CODE', '888')
                         else xXmlED_Line.setAttribute( 'KESI_CODE', '999');
                end;//case//
              end;


            case xXmlED_Line.getAttribute('ANAL_KIND') of
              // расходы
              '0': xXmlED_Line.setAttribute( 'FSR_ID', xFSR_Value);
              // доходы
              '1': xXmlED_Line.setAttribute( 'FSD_ID', xFSR_Value);
              // источники
              '2': xXmlED_Line.setAttribute( 'FSI_ID', xFSR_Value);
            end;//case//


            // Exchange#2079 для доходной классификации в строки 24 класса проставляем плательщика и получателя
            if (xDocClass = '24')
                and (xXmlED_Line.getAttribute('ANAL_KIND') = '1')
              then begin
                if NOT StrIsEmpty( aXmlED.getAttribute('F_INCRECORGID'))
                  then xXmlED_Line.setAttribute(
                                        'RECEIVER_ID',
                                        aXmlED.getAttribute('F_INCRECORGID'));
                if NOT StrIsEmpty( aXmlED.getAttribute('PAY_ID'))
                  then xXmlED_Line.setAttribute(
                                        'PAYER_ID',
                                        aXmlED.getAttribute('PAY_ID'));
              end;


            // exchange #2831 - помечаем ЭД 5/25го класса
            // exchange #2998 - небыл учтен параметр конфига
            // создание документов ау/бу при доработке #2831.
            if (POS( '30', xIK_LS_UBP) = 1)
              then Doc5ByIK_BDPB_Mark2831( aXmlED,
                                           vCfg_2600_CreateED_AUBU,
                                           xIK_LS_UBP);

            // exchange #2926 - заполнение кода субсидии
            // exchange #2979 - поиск кода субсидии BDPDST.ADD_KLASS
            if (xDocClass = '24')
              then FillGrantinvestment2979(
                                  BudgetId,
                                  xXmlED_Line,
                                  GetNodeAttributeEx( xXmlED_Line, 'ADD_KLASS'),
                                  xREC_PAY_ID);


//            aXmlED := aXmlED.parentNode;
//            aXmlBDPD := aXmlBDPD.parentNode;
          end;//for//
          {
          // записываем сумму документа из строки в шапку
          aXmlED.parentNode.setAttribute( 'AMOUNT', Format('%.2f', [ xAmount]));
          }

          // если нет строк - эд не создаем
          if (xXmlED_Lines.childNodes.Length <= 0)
            then xErrors := TRUE;
        end;
      end;
//      aXmlED := aXmlED.ownerDocument;
//      aXmlED := aXmlED.documentElement;



      // при наличие ошибок - ничего не создаем
      if xErrors then begin
        WriteInfo( 'Сформированный ЭД имеет ошибки - не создается.');
        EXIT;
      end;

      // exchange #2965 - создание 195го по BDPD из эд 5го
      if xCreateDoc195 then
        if Create195_IK_BDPD_2965( BudgetId,
                                   aXmlED,
                                   aXmlIK,
                                   aXmlBDPD,     // BDPD
                                   vCfg_CreateParamAUBU,
                                   xDocInfo)
          then EXIT
          else begin
            // если определили что нужно создавать эд 195й, а потом передумали,
            // и в результате нужно создавать все по старому, то рекурсивно
            // вызываем обработку этого же блока по старому алгоритму,
            // а просерку создания эд 195го отключаем.
            WriteInfo( 'ЭД "Заявка БУ/АУ на выплату средств" не будет создан.');
            MakeDocumentIkBD_New( xDocCopy,
                                  xDocXmlCopy,
                                  aXmlIK,
                                  aFinYear,
                                  TRUE,
                                  aList_ACC_I,    // exchange #2993
                                  aList_ACC_V);   // exchange #2993
            EXIT;
          end;


{
      if aXmlED.getAttribute('class') = '5' then
        WriteInfo('АЦК: "Приложение к выписке дебетовое" № ' +
          aXmlED.getAttribute('DOC_NUMBER') + ' Дата: ' +
            aXmlED.getAttribute('DOC_DATE') + ' Сумма: ' +
            aXmlED.getAttribute('AMOUNT'), True)
      else begin
        WriteInfo('АЦК: "Приложение к выписке кредитовое" № ' +
          aXmlED.getAttribute('DOC_NUMBER') + ' Дата: ' +
            aXmlED.getAttribute('DOC_DATE') + ' Сумма: ' +
            aXmlED.getAttribute('AMOUNT'), True);

        // exchange #2600
        // для выполнения пп.2.9.2.4 (создание ЭД 193го класса из 24го)
        // требуется в документе указать специальный параметр.
        // но только, если ЭД 24го класса создается из BDPD по новому
        // алгоритму, описанному по пп.2.9.2.
        aXmlED.SetAttribute( '__IK_MODE__', '2600_2.9.2.4');
      end;
}
      // Вставка документа, проверки и прочее.
      //if not VarIsNull(aXmlED.getAttribute('NOROW'))
      if (xCountBDPDST <= 0)
        then InsertDebCred( aXmlED) //вставляем документ 5 или 24 класса без строк.
        else Documents_DebCred( aXmlED);

      aXmlBDPD := null;
      except
        ExceptionLog( 'Сбой MakeDocumentIkBD_New');
    end;

end;

begin
end.
