{~LoadED108by2769
  подпрограмма загрузки ED108 по exchange #2769.}
procedure LoadED108by2769( aED108: Variant);
var
  xRecAccED108:  String;
  xPaytKind: string;
  xDateYYYY: integer;
//  xEDDate: TDateTime;
  xCTTInfo: Variant;
  xRecBIC: string;
  xDocInfo: string;
  xDoc24Info: string;
  i: integer;

  {~DoSearchOrgID
    поиск по ИНН в справочнике
    организаций незакрытой организации, актуальной для финоргана бюджета,
    в котором создается 24 класс.
    Если найдена однозначно, подставлять еще ID.
    Если не найдена, заполнять без ID.
    поиск по ИНН (а затем по ИНН+КПП – в т.ч. о дополнительным
    КПП, если не найдена однозначно по ИНН) в справочнике организаций
    незакрытой организации, актуальной для финоргана бюджета, в котором
    создается 24 класс.
    Если найдена однозначно, подставлять еще ID.
    Если не найдена, заполнять без ID.}
  procedure DoSearchOrgID( var aDoc24: Variant;
                           aBudgetID: string;
                            aINN_CTTInfo, aINN, aKPP: string;
                            aField_ID, aField_INN, aField_KPP: string);
  var
    xXml: Variant;
    xPayID: string;
  begin

      try
        xPayID := '';

        // добавляем поле КПП к ЭД в любом случае, указан КПП или нет,
        // участвует КПП при поиске или нет.
        // а ищем организацию с КПП, только если КПП указан.
        if (LENGTH( aKPP) > 0)
          then aDoc24.setAttribute( aField_KPP, aKPP);

        if (LENGTH( aINN_CTTInfo) > 0) then begin
          // инн из блока TransactionPayerInfo.
          aDoc24.setAttribute( aField_INN, aINN_CTTInfo);
          // если указан инн из блока TransactionPayerInfo - ищем по нему.
          // при этом результат определяется только этим поиском!
          xXml := QueryXml(  ' Select distinct O.Id From Org O'
                             // этот подзапрос определяет флажок актуальности
                             // для указанного бюджета.
                            +' Join Contractor C On C.Org_Id = O.Id'
                            // B.Org_Id - организация фин.орнаг в карточке
                            // бюджета.
                            +' Join Budget B On B.Org_Id = C.Inspector_Id'
//                            +' Join Budget B On B.Org_Id = O.Id'
                            +' Where B.Id=? And O.Close_Date Is Null and o.taxcode=?',
                            [ aBudgetID,
                              aINN_CTTInfo]);
          if (xXml.documentElement.childNodes.length > 1) then
            if (LENGTH( aKPP) > 0)
              then xXml := QueryXml(  ' Select distinct O.Id From Org O'
                                       // этот подзапрос определяет флажок актуальности
                                       // для указанного бюджета.
                                      +' Join Contractor C On C.Org_Id = O.Id'
                                      // B.Org_Id - организация фин.орнаг в карточке
                                      // бюджета.
                                      +' Join Budget B On B.Org_Id = C.Inspector_Id'
          //                            +' Join Budget B On B.Org_Id = O.Id'
                                      +' Where B.Id=? And O.Close_Date Is Null and o.taxcode=?'
                                      +' and (o.kpp=? or exists (select oo.id from orgkpp oo'
                                      +' where oo.org_id=o.id and oo.kpp=?))',
                                      [ aBudgetID,
                                        aINN_CTTInfo,
                                        aKPP,
                                        aKPP]);
          // Если не найдена, заполнять без ID.
          if (xXml.documentElement.childNodes.length = 1)
            then xPayID := xXml.documentElement.childNodes.Items[0].getAttribute('ID');
        end else begin
          if ( LENGTH( aINN) > 0) then begin
            // если TransactionPayerInfo.INN не заполнено - заполнять (INN) и (KPP)
            // блока (ed:Payer) – поиск по ИНН (а затем по ИНН+КПП – в т.ч. о
            // дополнительным КПП, если не найдена однозначно по ИНН) в справочнике
            // организаций незакрытой организации, актуальной для финоргана бюджета,
            // в котором создается 24 класс. Если найдена однозначно, подставлять
            // еще ID. Если не найдена, заполнять без ID.
            aDoc24.setAttribute( aField_INN, aINN);
            xXml := QueryXml(  ' Select distinct O.Id From Org O'
                              +' Join Contractor C On C.Org_Id = O.Id'
                              +' Join Budget B On B.Org_Id = C.Inspector_Id'
    //                          +' Left Join Budget B On B.Org_Id = O.Id'
                              +' Where B.Id=? And O.Close_Date Is Null and o.taxcode=?',
                              [ aBudgetID,
                                aINN]);
            // поиск по инн+кпп выполняется, только если по инн найдено
            // несколько организаций.
            if (xXml.documentElement.childNodes.length > 1) then
              // ищем ИНН+КПП, причем КПП проверяем среди дополнительных КПП
              if (LENGTH( aKPP) > 0)
                then xXml := QueryXml( ' Select distinct O.Id From Org O'
                                      +' Join Contractor C On C.Org_Id = O.Id'
                                      +' Join Budget B On B.Org_Id = C.Inspector_Id'
//                                      +' Left Join Budget B On B.Org_Id = O.Id'
                                      +' Where B.Id=? And O.Close_Date Is Null and o.taxcode=?'
                                      +' and (o.kpp=? or exists (select oo.id from orgkpp oo'
                                      +' where oo.org_id=o.id and oo.kpp=?))',
                                      [ aBudgetID,
                                        aINN,
                                        aKPP,
                                        aKPP]);
            if (xXml.documentElement.childNodes.length = 1)
              then xPayID := xXml.documentElement.childNodes.Items[0].getAttribute('ID');
          end;
        end;
        aDoc24.setAttribute( aField_ID, xPayID);

        except
          ExceptionLog( 'Сбой LoadED108by2769.DoSearchOrgID');
      end;

  end;

  {~DoFillOrgName
    Заполнять по формату: (ed:PersonName) (ed:PersonAddress).
    Если не заполнены, то из (ed:TradeName) .
    Если и оно не заполнено, из (ed:Name).}
  procedure DoFillOrgName( var aDoc24: Variant;
                           aPersonName, aPersonAddr: string;
                           aTradeName: string;
                           aName: string;
                           aField_OrgName: string);
  var
    xComment: string;
  begin

      try
        xComment := TRIM( aPersonName + ' ' + aPersonAddr);
        if (LENGTH( xComment) <= 0)
          then xComment := TRIM( aTradeName);
        if (LENGTH( xComment) <= 0)
          then xComment := TRIM( aName);
        aDoc24.setAttribute( aField_OrgName, xComment);

        except
          ExceptionLog( 'Сбой LoadED108by2769.DoFillOrgName');
      end;

  end;

  {~DoFillDepartmentalInfo
    заполнение полей идентификации платежа для ЭД 24го класса aDoc24
    всегда из раздела: DepartmentalInfo.
    для бюджета aBudgetID.}
  procedure DoFillDepartmentalInfo( var aDoc24: Variant;
                                    aBudgetID: String);
  var
    xFlagFill: boolean;
    xAutor: string;
//    xXml: Variant;
//    xFieldValue: Variant;
    xKBK: string;
    xKBKError: boolean;
    xOKATO: string;
    xPaytReason: string;
    xTaxPeriod: string;
    xDocNo: string;
    //xDocDate: string;
    xDocDateCopy: string;
    xTaxPaytKind: string;
    v: variant;
  begin

      try
        // статус лица, оформившего платёжь

        xAutor := Trim( aED108.DepartmentalInfo.DrawerStatus);
        // Проверка показателя статуса лица, оформившего платёжь
        if (LENGTH( xAutor) > 0) then begin
          // Ищем запросом по базе АЦК.
          // в банковских платёжах не часто заполняют для ФО идентификатор платежа.
          // основные платежи по налогам проходять через УФК
          if (QueryFieldEx( 'Select count( * ) N From PayDocAuthor Where Id = ?',
                          [ xAutor],
                          'N') = '1')
            then aDoc24.setAttribute(
                        'AUTHOR_ID',
                        QueryFieldEx( 'Select Id From PayDocAuthor Where Id = ?',
                                    [ xAutor],
                                    'ID'))
            else WriteInfo( FORMAT( '%s - Не найден в АЦК статус лица, оформившего платёж: %s',
                                    [ xDoc24Info,
                                      xAutor]));
        end;


        // Вид классификации - Доходная
        aDoc24.SetAttribute('PI_ANAL_KIND', '1');


        // КБК
        xKBK      := Trim( aED108.DepartmentalInfo.CBC);
        xKBKError := FALSE;

        case LENGTH( xKBK) of
          // если КБК не указан совсем - такое допустимо
          0: begin end;

          // exchange #2791
          // допускается указание кбк=0
          1: if (xKBK = '0')
               then xKBKError := FALSE
               else begin
                  WriteInfo( FORMAT( '%s - Не корректное значение кода бюджетной классификации (%s)',
                                     [ xDoc24Info,
                                       xKBK]));
                  xKBKError := TRUE;
                end;

          // Если заполнена бюджетная классификация (полностью - 20 знаков),
          // проверяем составляющие
          { exchange #3061
            нет теперь у нас КОСГУ.
            это должно работать только для бюджета с годом 2016 и выше.}
          20: if vBudgetYear2016andAbove then begin

                // код администратора
                if ( QueryFieldEx( ' Select count ( * ) N From Kadm'
                                +' Where Budget_Id = ? And Code = ?',
                                 [ aBudgetID,
                                  Copy( xKBK, 1, 3)],
                                  'N') <> '1')
                  then begin
                    WriteInfo( FORMAT( '%s - Не найден в АЦК классификатор администраторов: %s (%s)',
                                        [ xDoc24Info,
                                          Copy( xKBK, 1, 3),
                                          xKBK]));
                    xKBKError := TRUE;
                  end;
                // классификатор видов доходов
                if ( QueryFieldEx( ' Select count ( * ) N From Kd'
                                +' Where Budget_Id = ? And Code = ?',
                                 [ aBudgetID,
                                  Copy( xKBK, 4, 17)],
                                  'N') <> '1')
                  then begin
                    WriteInfo( FORMAT( '%s - Не найден в АЦК классификатор видов доходов: %s (%s)',
                                        [ xDoc24Info,
                                          Copy( xKBK, 4, 17),
                                          xKBK]));
                    xKBKError := TRUE;
                  end;
              end else begin

                // Если не найден КЭС, остальное проверять бесмысленно
                if ( QueryFieldEx( ' Select count ( * ) N From Kes'
                                +' Where Budget_Id = ? And Code = ?',
                                 [ aBudgetID,
                                  Copy( xKBK, 18, 3)],
                                  'N') <> '1')
                  then begin
                    WriteInfo( FORMAT( '%s - Не найден в АЦК экономический классификатор: %s (%s)',
                                      [ xDoc24Info,
                                        Copy( xKBK, 18, 3),
                                        xKBK]));
                    xKBKError := TRUE;
                  end else begin
                    // код администратора
                    if ( QueryFieldEx( ' Select count ( * ) N From Kadm'
                                    +' Where Budget_Id = ? And Code = ?',
                                     [ aBudgetID,
                                      Copy( xKBK, 1, 3)],
                                      'N') <> '1')
                      then begin
                        WriteInfo( FORMAT( '%s - Не найден в АЦК классификатор администраторов: %s (%s)',
                                            [ xDoc24Info,
                                              Copy( xKBK, 1, 3),
                                              xKBK]));
                        xKBKError := TRUE;
                      end;
                    // классификатор видов доходов
                    if ( QueryFieldEx( ' Select count ( * ) N From Kd'
                                    +' Where Budget_Id = ? And Code = ?',
                                     [ aBudgetID,
                                      Copy( xKBK, 4, 14)],
                                      'N') <> '1')
                      then begin
                        WriteInfo( FORMAT( '%s - Не найден в АЦК классификатор видов доходов: %s (%s)',
                                            [ xDoc24Info,
                                              Copy( xKBK, 4, 14),
                                              xKBK]));
                        xKBKError := TRUE;
                      end;
                  end;
              end;

          // если КБК указан не полностью - ругаемся
        else begin
              WriteInfo( FORMAT( '%s - Не корректное значение кода бюджетной классификации (%s)',
                                 [ xDoc24Info,
                                   xKBK]));
              xKBKError := TRUE;
            end;
        end;//case//
        // В любом случае заполняем кредитовое приложение бюджетной классификацией
        // АЦК при вставке не ругается, пусть будет как есть.
        // не заполнять КБК в создаваемом ЭД если есть ошибка КБК.
        if xKBKError
          then aDoc24.setAttribute( 'PI_BUDGET_CODE', '')
          else aDoc24.setAttribute( 'PI_BUDGET_CODE', xKBK);



        // ОКАТО

        xOKATO := Trim( aED108.DepartmentalInfo.OKATO);
        if (( LENGTH( xOKATO) > 0) and (xOKATO <> '0'))
          then aDoc24.setAttribute( 'PAY_OKATO', xOKATO);


        // Основание налогового платежа

        xPaytReason := Trim( aED108.DepartmentalInfo.PaytReason);
        // Проверка - ищется запросом по базе АЦК
        if (LENGTH( xPaytReason) > 0) then begin
          if ( QueryFieldEx( 'Select count ( * ) N From PayGround Where Name = ?',
                            [ xPaytReason],
                            'N') = '1')
            then aDoc24.setAttribute(
                      'GROUND_ID',
                      QueryFieldEx( 'Select Id From PayGround Where Name = ?',
                                  [ xPaytReason],
                                  'ID'))
            else WriteInfo( FORMAT( '%s - Не найден в АЦК показатель основания платежа: %s',
                                    [ xDoc24Info,
                                      xPaytReason]));
        end;


        // Налоговый период
        // дату нужно заполнять в формате dd.mm.yyyy.

        xTaxPeriod := Trim( aED108.DepartmentalInfo.TaxPeriod);
        if (LENGTH( xTaxPeriod) > 0)
          then aDoc24.setAttribute('TAXPERIOD', xTaxPeriod);


        // Номер налогового платежа

        xDocNo := Trim( aED108.DepartmentalInfo.DocNo);
        if (LENGTH( xDocNo) > 0)
          then aDoc24.setAttribute('GRND_DOC_NUMBER', xDocNo);


        // Дата налогового платежа
        // дату нужно заполнять в формате dd.mm.yyyy.


        // Тип налогового платежа, ищется запросом по базе АЦК

        xTaxPaytKind := Trim( aED108.DepartmentalInfo.TaxPaytKind);
        if (LENGTH( xTaxPaytKind) > 0) then
          if ( QueryFieldEx( 'Select count( * ) N From PayType Where Name = ?',
                           [ xTaxPaytKind],
                           'N') = '1')
            then aDoc24.setAttribute(
                          'PAYTYPE_ID',
                          QueryFieldEx( 'Select Id From PayType Where Name = ?',
                                      [ xTaxPaytKind],
                                      'ID'))
            else WriteInfo( FORMAT( '%s - Не найден в АЦК тип платежа: %s',
                                    [ xDoc24Info,
                                      xTaxPaytKind]));



        except
          ExceptionLog( 'Сбой LoadED108by2769.DoFillDepartmentalInfo');
      end;


  end;

  {~DoMake24
    СОЗДАНИЕ ЭД 24го класса.}
  procedure DoMake24;
  var
    xBudgetID: string;
    xXml: Variant;
    xDoc24: Variant;
    xForeign_Key: string;
    xDoc24Date: TDateTime;
    xDocNo: string;
    xXmlOrgAcc: Variant;
    xPayID: string;//Variant;
    xPayAcc: string;
    xPayBIC: string;
    xComment: string;
    xRecAcc: string;
    xPayAccID: string;
    i: integer;
    xDoc24Xml: Variant;
    xDoc24RegList: Variant;
    xDoc24RegItem: Variant;
    xCTTInfo: Variant;
//    XmlSpec, XmlLink, xXmlOrgAcc: Variant;
  begin

      try
        // описание создаваемого ЭД
        xDoc24Info := FORMAT( '%s из ED108', [ xDocInfo]);

        // Бюджет определяем только по (PersonalAcc)
        // без учета (Acc) блока (ed:TransactionPayeeInfo).
        xRecAcc := xRecAccED108;


        if FAccountLoginBudget then begin
          // ищем бюджет, организацию и счет по организации фин.органа
          // для прилогиненного бюджета
          xXmlOrgAcc := QueryXml( sqlOrgAccount_2583_OrgID_ByBudget,
                                 [xDateYYYY,
                                  xRecAcc,
                                  xRecBIC,
                                  Budget_Id]);
          if xXmlOrgAcc.documentElement.childNodes.Length <> 1 then begin
            //ищем бюджет, организацию и счет по организации осущ. исполнение
            // для прилогиненного бюджета
            xXmlOrgAcc := QueryXml( sqlOrgAccount_2583_ExecutorID_ByBudget,
                                  [xDateYYYY,
                                   xRecAcc,
                                   xRecBIC,
                                   Budget_Id]);
          end;
        end else begin
          // Поиск счёта в настройках счетов (Бухгалтерия - Настройка счетов -
          // Счета ФО - группа полей Счета бюджета) с любым типом.
          // Если счет в системе сущетсвует один, определить бюджет загрузки
          // по его BUDGET_ID.
          xXmlOrgAcc := QueryXml( sqlBuchFO_Account_2583,
                                 [ xDateYYYY,
                                   xRecAcc,
                                   xRecBIC]);
          if (xXmlOrgAcc.documentElement.childNodes.Length <> 1) then begin
            // ищем бюджет, организацию и счет по организации фин.органа
            // без учета прилогиненного бюджета
            xXmlOrgAcc := QueryXml( sqlOrgAccount_2583_OrgID_WithoutBudget,
                                  [ xDateYYYY,
                                    xRecAcc,
                                    xRecBIC]);
            //ищем бюджет, организацию и счет по организации осущ. исполнение
            if (xXmlOrgAcc.documentElement.childNodes.Length <> 1) then begin
              // ищем бюджет, организацию и счет по организации осущ. исполнение
              // без учета прилогиненного бюджета
              xXmlOrgAcc := QueryXml( sqlOrgAccount_2583_ExecutorID_WithoutBudget,
                                     [ xDateYYYY,
                                       xRecAcc,
                                       xRecBIC]);
            end;
          end;
        end;


        xXmlOrgAcc := xXmlOrgAcc.documentElement.childNodes;
        // если найдено несколько счетов (или ни одного) с указанным БИК,
        // то прерываем загрузку конкретного ED108.
        if xXmlOrgAcc.length  = 0 then begin
          WriteInfo( FORMAT( '%s - Счёт: %s БИК: %s не найден в базе АЦК',
                              [ xDoc24Info,
                                xRecAcc,
                                xRecBIC]));
          EXIT;
        end;
        if (xXmlOrgAcc.length > 1) then begin
          WriteInfo( FORMAT( '%s - Счёт: %s БИК: %s в базе АЦК не однозначен',
                              [ xDoc24Info,
                                xRecAcc,
                                xRecBIC]));
          EXIT;
        end;
        // найденный счет
        xXmlOrgAcc := xXmlOrgAcc.items[0];
        xBudgetID  := xXmlOrgAcc.getAttribute('BUDGET_ID');


        // если в найденном ответе бюджет не определен для найденной организации
        // то это ошибка, иначе ЭД будет вставлен в прилогиненный бюджет.
        // однако это не верно, поэтому, если бюджет будет пустым - даем ошибку
        if (xBudgetID = '') then begin
          WriteInfo( FORMAT( '%s - Для счёта: %s БИК: %s организации: %s'
                            +' в базе АЦК не найден бюджет',
                              [ xDoc24Info,
                                xRecAcc,
                                xRecBIC,
                                xXmlOrgAcc.getAttribute('ORG_ID')]));
          EXIT;
        end;

        // Проверяем условие фильтра по бюджету в настройках и бюджета, к которому относиться счёт
        if (FiltrBudget and (xBudgetID <> Budget_Id)) then begin
          WriteInfo( FORMAT( 'В настройках установлен фильтр по бюджету'#13#10
                            +'Текущий бюджет: %s'#13#10
                            +'Документ принадлежит бюджету: %s'#13#10
                            +'ЭД: %s',
                              [ Budget_Name,
                                xXmlOrgAcc.getAttribute('BUDGET_NAME'),
                                xDoc24Info]));
          EXIT;
        end;

        // exchange #3059
        // номер документа - из поля AccDoc.AccDocNo
//        xDocNo := aED108.EDNo;
        xDocNo := TRIM( aED108.AccDoc.AccDocNo);

        // Проверка на повторную загрузку ЭД: (EDNo)+ (EDDate)+(Sum)+(EDAuthor)
        // exchange #3059 - поправлено сообщение
        xForeign_Key :=  xDocNo //IntToStr( aED108.EDNo)
                         + FormatDateTime('yyyymmdd', aED108.EDDate)
                         + FORMAT( '%.2f', [ aED108.Sum])
                         + aED108.EDAuthor;

        xXml := QueryXml( ' Select P.Id From PayOrder P Where P.DocumentClass_Id = 24'
                         +' And P.Foreign_Key = ? And P.DispStatus_Id > -1',
                          [ xForeign_Key],
                          False);
        if (xXml.documentElement.childNodes.length > 0) then begin
          WriteInfo( FORMAT( '%s - был ранее загружен',
                              [ xDoc24Info]));

          Exit;
        end;

        // Создаём xXml - задание навставку 24 класса
        xDoc24Xml := CreateOleObject('Microsoft.XmlDom');
        xDoc24 := xDoc24Xml.appendChild( xDoc24Xml.createElement('DOCUMENT'));
        xDoc24.setAttribute( 'action'       , 'insert');
        xDoc24.setAttribute( 'class'        , '24');
        xDoc24.setAttribute( 'FOREIGN_KEY'  , xForeign_Key);
        xDoc24.setAttribute( 'BUDGET_ID'    , xBudgetID);

        // Дата ЭПД - ED108.EDDate
        // дату нужно заполнять в формате yyyy-mm-dd.
        xDoc24Date := aED108.EDDate;
        xDoc24.setAttribute( 'DOC_DATE',
                              FormatDateTime('yyyy-mm-dd', xDoc24Date));

        // номер документа - из поля ED108.EDNo
        // exchange #3059 - номер документа из поля AccDoc.AccDocNo
//        xDocNo := aED108.EDNo;
        xDoc24.setAttribute('DOC_NUMBER', xDocNo);

        // exchange #2696
        // поле 24 класса «Уникальный идентификатор начисления» закладки «ГИС ГМП»
        // для АЦК-Ф 2.33
        if (Version_CompareEx( Ufebs.FormatVer, '2.6.0') >= 0) then
          if ( LENGTH( aED108.PaymentID) > 0)
            then xDoc24.setAttribute('UIN', aED108.PaymentID);

        // "вид платежа".
        xDoc24.setAttribute('PAYKIND', xPaytKind);

        // вид операции
        xDoc24.setAttribute('BANKOPER_ID', aED108.TransKind);

        { тип операции - заполняется значением, выбранным для  Справки по
        внебанковским операциям в справочнике "Типы операций по-умолчанию",
        а в случае отсутствия настройки, значением "Не указано"}
        xXml := QueryXml( 'Select O.* From DEFOPERTYPE O Where O.DOCUMENTCLASS_ID = 24');
        xXml := xXml.documentElement.childNodes;
        if (xXml.Length = 1)
          then xDoc24.setAttribute( 'OPERTYPE_ID',
                                    xXml.Items[0].getAttribute('OPERTYPE_ID'))
          else xDoc24.setAttribute( 'OPERTYPE_ID',
                                    '0');

        // дата по банку - ED108.EDDate
        // дату нужно заполнять в формате yyyy-mm-dd.
        xDoc24.setAttribute( 'CARRY_DATE',
                              FormatDateTime( 'yyyy-mm-dd',
                                              aED108.EDDate));

        // сумма выписки - ED108.Sum
        xDoc24.setAttribute( 'AMOUNT', aED108.Sum);

        // очередность
        // exchange #2696 - очередность теперь 1...5. цифра 6 исключена.
        if (aED108.Priority in [1..5])
          then xDoc24.setAttribute('QUEUE_KIND', aED108.Priority)
          else xDoc24.setAttribute('QUEUE_KIND', '5');

        // плательщик
        { поиск по ИНН в справочнике
          организаций незакрытой организации, актуальной для финоргана бюджета,
          в котором создается 24 класс.
          Если найдена однозначно, подставлять еще ID. Если не найдена,
          заполнять без ID.
          поиск по ИНН (а затем по ИНН+КПП – в т.ч. о дополнительным КПП,
          если не найдена однозначно по ИНН) в справочнике организаций
          незакрытой организации, актуальной для финоргана бюджета,
          в котором создается 24 класс.
          Если найдена однозначно, подставлять еще ID. Если не найдена,
          заполнять без ID.}
        DoSearchOrgID( xDoc24,
                        xBudgetID,
                        '',
                        aED108.Payer.INN,
                        aED108.Payer.KPP,
                        'PAY_ID',
                        'PAY_TAXCODE',
                        'PAY_KPP');
        xPayID := xDoc24.GetAttribute( 'PAY_ID');

        // наименование
        DoFillOrgName( xDoc24,
                        '',
                        '',
                        '',
                        aED108.Payer.Name,
                        'PAY_NAME');

        // бик - пока только сохраняем в переменной
        xPayBIC := aED108.Payer.Bank.BIC;

        // счет
        xPayAccID := '';
        xPayAcc   := aED108.Payer.PersonalAcc;
        // если счет указан - заполняем его из ED108
        // это в любом случае - найден счет или нет.
        if (LENGTH( xPayAcc) > 0)
          then xDoc24.setAttribute('PAY_ACCOUNT', xPayAcc);

        if (LENGTH( xPayID) > 0) then
          // если ID орг.плательщика определен и если счет указан,
          // ищем счет в этой организации
          if (LENGTH( xPayAcc) > 0) then begin

            xXml := QueryXml(  'select b.description BANK_NAME, b.coraccount CORACCOUNT,'
                              +' a.id ID from orgaccount a join bank b on b.id=a.bank_id'
                              +' where a.org_id=? and a.orgacctype_id=2'
                              +'and a.account_number=? and b.bic=?',
                               [ xPayID,
                                 xPayAcc,
                                 xPayBIC]);
            if (xXml.documentElement.childNodes.length = 1) then begin
              xXml := xXml.documentElement.childNodes.Items[0];
              xPayAccID := xXml.getAttribute( 'ID');
              xDoc24.setAttribute( 'PAY_CORACCOUNT', xXml.getAttribute( 'CORACCOUNT'));
              xDoc24.setAttribute( 'PAY_ACC_ID'    , xPayAccID);
              xDoc24.setAttribute( 'PAY_B_NAME'    , xXml.getAttribute( 'BANK_NAME'));
              xDoc24.setAttribute( 'PAY_BIC'       , xPayBIC);
            end;
          end;

        // если организация плательщика не найдена, или счет плательщика
        // не найден, тогда подставляем счет и
        if (LENGTH( xPayAccID) <= 0) then begin
          // БИК ищем в справочнике
          xXml := QueryXml(  ' select b.description BANK_NAME, b.coraccount CORACCOUNT'
                            +' from bank b where b.bic=?',
                             [ xPayBIC]);
          if (xXml.documentElement.childNodes.length = 1) then begin
            xXml := xXml.documentElement.childNodes.Items[0];
            xDoc24.setAttribute( 'PAY_CORACCOUNT', xXml.getAttribute( 'CORACCOUNT'));
            xDoc24.setAttribute( 'PAY_B_NAME'    , xXml.getAttribute( 'BANK_NAME'));
            xDoc24.setAttribute( 'PAY_BIC'       , xPayBIC);
          end;
        end;

        // получатель
        xDoc24.setAttribute( 'REC_ID'         , xXmlOrgAcc.getAttribute( 'ORG_ID'));
        xDoc24.setAttribute( 'REC_KPP'        , xXmlOrgAcc.getAttribute( 'KPP'));
        xDoc24.setAttribute( 'REC_TAXCODE'    , xXmlOrgAcc.getAttribute( 'TAXCODE'));
        xDoc24.setAttribute( 'REC_ACC_ID'     , xXmlOrgAcc.getAttribute( 'ID'));
        xDoc24.setAttribute( 'REC_CORACCOUNT' , xXmlOrgAcc.getAttribute( 'BANK_CORACCOUNT'));
        xDoc24.setAttribute( 'REC_B_NAME'     , xXmlOrgAcc.getAttribute( 'BANK_NAME'));
        xDoc24.setAttribute( 'REC_NAME'       , xXmlOrgAcc.getAttribute( 'DESCRIPTION'));
        xDoc24.setAttribute( 'REC_BIC'        , xRecBIC);
        xDoc24.setAttribute( 'REC_ACCOUNT'    , xRecAcc);

        // получатель из выписки
        DoSearchOrgID( xDoc24,
                        xBudgetID,
                        '',
                        aED108.Payee.INN,
                        aED108.Payee.KPP,
                        'ORG_ID',
                        'ORG_TAXCODE',
                        'ORG_KPP');
        xPayID := xDoc24.GetAttribute( 'ORG_ID');

        // наименование из выписки
        // заполнять в любом случае из (ed:Name) блока (ed:Payee).
        DoFillOrgName(  xDoc24,
                        '',
                        '',
                        '',
                        aED108.Payee.Name,
                        'ORG_NAME');

        // основание
        xComment := TRIM( aED108.Purpose);
        xDoc24.setAttribute( 'DESCRIPTION', TRIM( xComment));

        // идентификатор платежа
        DoFillDepartmentalInfo( xDoc24, xBudgetID);

        // заполнение закладки "информация из реестра"
        // заполнять из блока (ed:CreditTransferTransactionInfo)
        // На каждый блок (ed:CreditTransferTransactionInfo)
        // формировать отдельную строку на закладке.
        // Если в файле блока (ed:CreditTransferTransactionInfo) нет,
        // закладку не заполнять.
        if (aED108.CreditTransferTransactionInfoCount > 0) then begin
          xDoc24RegList:= xDoc24.appendChild(
                                  xDoc24Xml.createElement( 'REGISTERINFO'));

          for i := 0 to aED108.CreditTransferTransactionInfoCount - 1 do begin
            xCTTInfo      := aED108.CreditTransferTransactionInfo[ i];


            // строка в реестре в ЭД
            xDoc24RegItem := xDoc24RegList.appendChild(
                                          xDoc24Xml.createElement( 'REGISTERINFO'));

            // Номер записи в реестре
            xDoc24RegItem.SetAttribute( 'REGISTER_NUMBER',
                                        xCTTInfo.TransactionID);

            // Номер распоряжения плательщика
            if (xCTTInfo.PayerDocNo >= 0)
              then xDoc24RegItem.SetAttribute( 'PAYER_DISPOSAL_NUMBER',
                                               xCTTInfo.PayerDocNo);
            // Дата распоряжения плательщика
            // дату нужно заполнять в формате yyyy-mm-dd.
            if (xCTTInfo.PayerDocDate > 1)
              then xDoc24RegItem.SetAttribute(
                                        'PAYER_DISPOSAL_DATE',
                                        FormatDateTime( 'yyyy-mm-dd',
                                                        xCTTInfo.PayerDocDate));

            // Дата перевода
            // дату нужно заполнять в формате yyyy-mm-dd.
            xDoc24RegItem.SetAttribute( 'TRANSFER_DATE',
                                        FormatDateTime( 'yyyy-mm-dd',
                                                        xCTTInfo.TransactionDate));

            // Уникальный идентификатор начисления
            xDoc24RegItem.SetAttribute( 'UIN',
                                        xCTTInfo.PaymentID);

            // Сумма перевода
            xDoc24RegItem.SetAttribute( 'TRANSFER_SUM',
                                        xCTTInfo.TransactionSum);


            // блок плательщик
            // ИНН
            xDoc24RegItem.SetAttribute( 'PAYER_TAXCODE',
                                        xCTTInfo.TransactionPayerInfo.INN);
            // ФИО физ.лица
            xDoc24RegItem.SetAttribute( 'PAYER_FIO',
                                        xCTTInfo.TransactionPayerInfo.PersonName);
            // Адрес физ.лица
            xDoc24RegItem.SetAttribute( 'PAYER_ADDRESS',
                                        xCTTInfo.TransactionPayerInfo.PersonAddress);
            // Наименование
            xDoc24RegItem.SetAttribute( 'PAYER_CAPTION',
                                        xCTTInfo.TransactionPayerInfo.TradeName);
            // Номер банковского счета
            xDoc24RegItem.SetAttribute( 'PAYER_ACCOUNT',
                                        xCTTInfo.TransactionPayerInfo.Acc);

            // Блок «Получатель»
            // ИНН
            xDoc24RegItem.SetAttribute( 'REC_TAXCODE',
                                        xCTTInfo.TransactionPayeeInfo.INN);
            // ФИО физ.лица
            xDoc24RegItem.SetAttribute( 'REC_FIO',
                                        xCTTInfo.TransactionPayeeInfo.PersonName);
            // Адрес физ.лица
            xDoc24RegItem.SetAttribute( 'REC_ADDRESS',
                                        xCTTInfo.TransactionPayeeInfo.PersonAddress);
            // Наименование
            xDoc24RegItem.SetAttribute( 'REC_CAPTION',
                                        xCTTInfo.TransactionPayeeInfo.TradeName);
            // Номер банковского счета
            xDoc24RegItem.SetAttribute( 'REC_ACCOUNT',
                                        xCTTInfo.TransactionPayeeInfo.Acc);

            // прочие параметры строки
            // Номер л/с в ФО
            xDoc24RegItem.SetAttribute( 'REC_FO_ACCOUNT',
                                        xCTTInfo.CTTDepartmentalInfo.F112R);

            // Назначение платежа
            xDoc24RegItem.SetAttribute( 'PAYMENT_DETAIL',
                                        xCTTInfo.TransactionPurpose);
          end;
        end;

        // Закладка «Расшифровка» 24 класса не заполняется

        // создание ЭД 24го класса

        xDoc24.ownerDocument.loadXML(
                ExecXML(
                    xDoc24.ownerDocument.xml,
                    xBudgetID));
        xDoc24 := xDoc24.ownerDocument.documentElement;

        // перевод статуса на "выполнен"
        ExecProc( 'DOCUMENT',
                  [ 'action', 'process',
                    'class', xDoc24.getAttribute('DOCUMENTCLASS_ID'),
                    'ID', xDoc24.getAttribute('ID')],
                  xBudgetID);


        WriteLog( xDocInfo);
        except
          ExceptionLog( 'Сбой LoadED108by2769.DoMake24');
      end;

  end;

begin

    try
      // дата создания пакета ufebs
//      xEDDate := FEDDate;//aED108.EDDate;

      // Формирует стандартное сообщение о документе
      xDocInfo := FORMAT( '%s № %s Дата: %s Сумма: %.2f',
                           [  edtName[aED108.EDType],
                              TRIM( aED108.AccDoc.AccDocNo),
                              FormatDateTime('dd.mm.yyyy', aED108.EDDate),
                              aED108.Sum]);

      // поле "вид платежа".
      // теперь либо берется из документа, либо то, что указано в конфиге.
      xPaytKind := ImpPayKind_2547( GetPayKindByED( aED108));
      // проверяем возможные значения "вид платежа". если поле не допустимо
      // то отказываем обработку документа.
      // сделано так, поскольку требуется, чтобы вид платежа проверялся не
      // всегда во входном файле, а только тогда, когда указано брать вид платежа
      // из документа. если вид платежа берется из конфигурации, проверять то,
      // что указано в конфигурации.
      // если на данном этапе параметр "вид платежа" не указан, считается
      // что он не указан в файле или указан как "пусто" в конфигурации.
      if (xPaytKind <> '?') then
        if (LENGTH( xPaytKind) <= 0)
          then xPaytKind := GetPayKindByValue( aED108.EDType, -1)
          else xPaytKind := GetPayKindByValue( aED108.EDType, STRTOINT( xPaytKind));

      if (xPaytKind = '?') then begin
        WriteInfo( xDocInfo + ' - недопустимое значение в поле "вид платежа". Документ не обрабатывается.');
        EXIT;
      end;

      ShowInfo( xDocInfo);

      // При поиске бюджета по предыдущим пунктам искать счет только в бюджете,
      // к году которого относится год даты составления ed108 (EDDate)
      xDateYYYY := StrToInt(FormatDateTime('yyyy', aED108.EDDate));

      // БИК получателя - обязателен
      xRecBIC := aED108.Payee.Bank.BIC;

      // счёт получателя
      xRecAccED108 := TRIM( aED108.Payee.PersonalAcc);



      // создаем эд 24го класса
      DoMake24;
      except
        ExceptionLog( 'Сбой Un_Exch2583.LoadED108by2769');
    end;

end;

begin
end.
