//АЦК: Ответы на 13, 148, 149, 114, + доходы - 24
//Постановка: Exchange #1529
//Доработка: Exchange #2389
//Доработка: exchange #2400 - ТФФ10}
uses
  'Un_Import',
  'Un_Imp_Doc195_from_Doc5', // exchange #2831: обязательно перед модулем Un_Import!
  'Un_Import_AuBu',       // exchange #3081
  'Un_DepartmentalInfo',     // требуется для exchange #2831
  'Un_ImportKBK',
  'Un_Org',                // требуется для exchange #2831
  'Un_Exch2702',   // exchange #2702
  'Un_Exch2405',   // обязательно перед модулем Un_Import!
  'Un_Exch2389',   // обязательно перед модулем Un_Import!
  'Un_ExportKBK',     // exchange #3062
  'Un_Exch2410',   // обязательно перед модулем Un_Import!
  'Un_Default',
  'QueryWork',
  'QueryKbk',
  'Un_SysParams',     // exchange #2412
  'QueryTools',
  'Un_MessageValidForm',
  'Un_VersionSupport',
  'Un_Schems',
  'Un_ToolsXml',
  'Un_Tools',
  'Un_Const',
  'Un_Progress',
  'Un_System',
  'Un_Log',
  'Un_Debug';

const
  TestFileName = 'Imp_Fk_VB.Xml';
var
  FilePair, Vp_Date, BudgetId, IncReceiverId, IncAccountId, param_Receiver,
  param_SpecSr, FinYear, param_ShemaLoadDopKbk, FormVer: String;
  XmlFirstFile, FO, Doc, XmlNodeFirstFile: Variant;
  GuidList, GuidListVb: TStrings;
  param_CrushDoc24, LoadFirstFileOnly, param_UseOrgRef, param_IgnoreGuid,
  param_UseGroupBuh25, param_Search_Bo, param_Fill_FK_in_IncRef: Boolean;



function Exch2400_Ignore_Section_VBR2PD( aSection: string): string;
begin

    try
      // exchange #2542 - переход на тфф11: все работает по тфф10 и выше
      if ( aSection = 'VBR2PD')
        then Result := ''
        else Result := aSection;
  {
      if IsVersionSupport( cnVersionTFF_10)
        then
          if ( aSection = 'VBR2PD')
            then Result := ''
            else Result := aSection
        else
          Result := aSection;
          }

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

end;


function Main(Xml: Variant): Boolean;
var
  Sr: TFileSearch;
  FileGuid: String;
  i: Integer;
begin
  Result := False;
  xml := InitializeMain( xml, TestFileName);
  if VarIsNull( xml) then exit;
  Sr := TFileSearch.Create;
  try
    try
      Initialize(Xml);
      // exchange #2389
      Initialize_Exch2389( DirIni, param_ShemaLoadDopKbk);
      if (param_IgnoreGuid) and (MessageDlg('Включен параметр "Игнорировать ' +
        'проверку на уникальность guid первичного документа при создании ' +
          'приложений к выписке кредитовых/дебетовых", это может привести к ' +
          'загрузке дублей документов указанных классов.' +
          cr + 'Вы уверены, что хотите продолжить загрузку?', mtWarning,
          mbYes + mbNo, 0) = mrNo) then Exit;



      if Sr.FindFirst(DirIn, faAnyFile) = 0 then
      begin
        repeat
          if (Sr.Name <> '.') and (Sr.Name <> '..') and (Sr.Attr <> faDirectory) then
          begin
            FirstInfo := True;
            FileIn := ExtractFilePath(DirIn) + Sr.Name;
            //ищем парный файл в том же каталоге
            FilePair := '';
            // exchange #2399 пп.13 ТФФ 10.0
            // exchange #2542 - переход на тфф11 + переработка модуля проверки версий схем
            FilePair := GetPairFileName( FileIn,
                                         GetFileNameSchemaTFF( 'vb_txvb*'),
            {
                                         DirIni + VersionSchemsDir
                                            + IfVersionSupportThenElse(
                                                cnVersionTFF_10,
                                                'vb_txvb130101.xml',
                                                'vb_txvb100701.xml'),
                                                }
                                         FileGuid);
            LoadFirstFileOnly := False;
            if FilePair = '' then
            begin
              WriteInfo('В каталоге поиска не найден файл информации из расчетных' +
                ' документов с GUID=' + FileGuid + ' c кодом документа VB.' +
                ' Поиск пары производился для файла:' + FileIn);
              LoadFirstFileOnly := True;
            end;
            //конвертация данных в xml
            Data := CreateOleObject('Microsoft.XmlDom');
            Data.appendChild(Data.createElement('FORMAT'));

            // exchange #2399 пп.13 ТФФ 10.0
            // exchange #2542 - переход на тфф11 + переработка модуля проверки версий схем
            LoadSchema( GetFileNameSchemaTFF( 'vb_txvb*'));
            {
            LoadSchema(
                DirIni + VersionSchemsDir
                  + IfVersionSupportThenElse(
                      cnVersionTFF_10,
                      'vb_txvb130101.xml',
                      'vb_txvb100701.xml'));
                      }

            FormVer := Schema.documentElement.selectSingleNode('FK').
              selectSingleNode('NUM_VER').getAttribute('value');
            if NOT TextFileToXml(FileIn) then begin
              WriteInfo( FORMAT( 'Файл %s не будет обрабатываться, поскольку он загружен с ошибками.',
                                  [ FileIn]));
              CONTINUE;
            end;
            XmlFirstFile := Data;
            if param_CtlValidOn then
              if not ValidateFormat then
              begin
                ShellExecute('NotePad', FileValidate, False);
                WriteLog('Не пройден контроль валидности отдельными документами');
                CONTINUE;//Exit;
              end;
            //проверка и загрузка файлов без пары.
            if LoadFirstFileOnly then
            begin
              //проверяем чтобы в выписке были только уведомления об уточнении или РР/РРР
              WriteInfo('Проверка файла на присутствие только документов 114' +
                ' класса или 148(149) классов...', True);
              XmlFirstFile := XmlFirstFile.documentElement;
              ProgressBar.Max := XmlFirstFile.childNodes.Length - 4;
              ProgressBar.Position := 0;
              //заполнение данных докумнетов
              for i := 4 to XmlFirstFile.childNodes.Length - 1 do
              begin
                XmlFirstFile := XmlFirstFile.childNodes.Item[i];
                // exchange #2400 игнорирование раздела VBR2PD по ТФФ 10
                if ((Exch2400_Ignore_Section_VBR2PD( XmlFirstFile.NodeName)
                            in ['VBR12', 'VBR2PD'])
                   AND (LowerCase(XmlFirstFile.getAttribute('NAME_DOC'))
                            <> 'уведомление об уточнении вида и принадлежности платежа'))
                  then begin

                    WriteInfo('В загружаемом файле есть докуметы, класс которых' +
                      ' отличен от 114 или 148(149). Такие файлы должны загружаться парами.');
                    Exit;
                  end;
                XmlFirstFile := XmlFirstFile.parentNode;
                ProgressBar.Position := ProgressBar.Position + 1;
              end;
              ProgressBar.Position := 0;
              XmlFirstFile := XmlFirstFile.parentNode;
              //загрузка одиночного файла
              if LoadFirstFile then
              begin
                CopyFile(FileIn, DirArh + Sr.Name, True);

                DeleteFile(FileIn);
                WriteInfo('Файл обработан.');
              end
              else
                  WriteInfo('Файл оставлен в каталоге поиска.');
            end
            //загрузка файлов парами (норм. схема)
            else begin
              Data := CreateOleObject('Microsoft.XmlDom');
              Data.appendChild(Data.createElement('FORMAT'));

//              LoadSchema(DirIni + 'Schems\bd_txbd100701.xml');
              LoadSchema( GetFileNameSchemaTFF( 'bd_txbd*'));

              if NOT TextFileToXml(FilePair) then begin
                WriteInfo( FORMAT( 'Файл %s не будет обрабатываться, поскольку он загружен с ошибками.',
                                    [ FilePair]));
                CONTINUE;
              end;
              if param_CtlValidOn then
                if not ValidateFormat then
                begin
                  ShellExecute('NotePad', FileValidate, False);
                  WriteLog('Не пройден контроль валидности отдельными документами');
                  CONTINUE;//Exit;
                end;
              GuidList := TStringList.Create;
              try
                if LoadFile then
                begin
                  CopyFile(FileIn, DirArh + Sr.Name, True);

                  DeleteFile(FileIn);
                  CopyFile(FilePair, DirArh + ExtractFileName(FilePair), True);

                  DeleteFile(FilePair);
                  WriteInfo('Файлы обработаны.');
                end
                else
                  WriteInfo('Файл оставлен в каталоге поиска.');
              finally
                GuidList.Free;
              end;
            end;
          end;
        until Sr.FindNext <> 0;
        Sr.FindClose;
      end;
    except
      WriteInfo(LastException.Message);
      raise(LastException.Message);
    end;
    Result := True;
  finally
    Sr.Free;
    Finalize_Exch2389;
    Finalize(Xml);
//    ProgressBar.Position := 0;
//    StatusBar.SimpleText := '';
    ShowJournalEnd;
  end;
end; {end Main}

function LoadFile: boolean;
var
  Xml: Variant;
  i: Integer;
  s: string;
begin

    try
      Result := False;
      XmlFirstFile := XmlFirstFile.documentElement;
      Data := Data.documentElement;
      GuidListVb := TStringList.Create;
      GuidListVb.Clear;
      for i := 0 to Data.childNodes.length -1 do
        if Data.childNodes.items[i].nodeName in ['BDPD'] then
          GuidList.Add(Data.childNodes.items[i].getAttribute('GUID') + '=' + IntToStr(i));
      WriteLog('Определение даты выписки', True);
      Vp_Date := XmlFirstFile.childNodes.Item[3].getAttribute('DATE_OTCH');
      WriteLog('Проверка версии формата', True);
      if XmlFirstFile.childNodes.Item[0].getAttribute('NUM_VER') <> FormVer then
      begin
        WriteInfo('Версия формата: ' + XmlFirstFile.childNodes.Item[0].getAttribute('NUM_VER')
          + ' не поддерживается');

        Exit;
      end;

      { exchange #2399 для ТФФ 10.0 пп.13
        загружать только со значением поля 0 «Итоговый».
        что загружаем только файлы, в которых это поле равно 0. В которых равно 1 -
        не загружаем. в лог можно в этом случае писать, что промежуточные отчеты
        не загружаем.}
    
      // exchange #2542 - переход на тфф11: все работает по тфф10 и выше
    //  if IsVersionSupport( cnVersionTFF_10) then
        if (XmlFirstFile.childNodes.length < 3)
          then
            begin
              WriteInfo( 'В файле отсутствует раздел VB.');
              Exit;
            end
          else
            if (VarToStr( XmlFirstFile.childNodes.Item[3].getAttribute('VID_OTCH')) <> '0')
              then begin
                WriteInfo( 'Промежуточные отчеты не загружаются.');

                Exit;
              end;

      WriteLog('Определение финансового года по данным выписки', True);
      FinYear := Copy(Vp_Date, 7, 4);
      //получение данных ФО и BudgetId
      if not GetFoAndBudgetId then Exit;
      IncReceiverId := '';
      IncAccountId := '';
      //Получатель доходов
      WriteLog('Определение получателя доходов', True);
      if param_Receiver = 'ФО бюджета без счета' then
      begin
        Xml := GetIncReceiverByBudget(BudgetId);
        if Xml.documentElement.childNodes.length <> 1 then
        begin
          WriteInfo(Format('Найдено %d получателей доходов. ' +
            'Возможно параметр "Получатель доходов" указан неверно.',
            [Xml.documentElement.childNodes.length]));
          Exit;
        end
        else
        begin
          IncReceiverId := Xml.documentElement.childNodes.item[0].
            getAttribute('REC_ID');
          IncAccountId:= '-1';
        end
      end
      else begin
        Xml := GetIncReceiverByBudgetOrgId(BudgetId, FO.getAttribute('ORG_ID'));
        if Xml.documentElement.childNodes.length = 0 then
        begin
          WriteInfo(Format('Не найден получатель доходов по умолчанию ' +
            '(справочник "Получатели доходов") для организации <%s>;',
            [FO.getAttribute('ORG_DESCRIPTION')]));
          Exit;
        end;
        if Xml.documentElement.childNodes.length > 1 then
        begin
          WriteInfo(Format('Найдено несколько <%d> получателей доходов по умолчанию ' +
            '(справочник "Получатели доходов") для организации <%s>; ',
            [Xml.documentElement.childNodes.length, FO.getAttribute('ORG_DESCRIPTION')]));
          Exit;
        end;
        if Xml.documentElement.childNodes.length = 1 then
          IncReceiverId := Xml.documentElement.childNodes.item[0].getAttribute('ID');
      end;
      //Проверка КБК
      WriteInfo('Проверка КБК в строках документов:', True);
      if param_ShemaLoadDopKbk <> '' then
        WriteInfo('Параметр "Схема загрузки доп кодов из поля ADD_KLASS" = ' +
          param_ShemaLoadDopKbk);
      ProgressBar.Max := Data.childNodes.Length - 4;
      ProgressBar.Position := 0;
      ChangeKbk := False;

      for i := 3 to Data.childNodes.Length - 1 do
      begin
        ProgressBar.Position := ProgressBar.Position + 1;
        Data := Data.childNodes.item[i];
        if (Data.NodeName = 'BDPDST') then
        begin
          Default_F_Line(Data);
          // exchange #3062 - отмена косгу
          if CheckKBK(Data, 'KBK', BudgetId, param_ShemaLoadDopKbk, FALSE, FALSE) then
            ChangeKbk := True;
        end;
        Data := Data.parentNode;
      end;
      if (ChangeKbk) and (not param_changeKBK) then
      begin
        WriteInfo('Найдены КБК в файле, которые отсутствуют в базе АЦК.');
        Exit;
      end;
      if ChangeKbk then
        WriteInfo('Отсутствующие КБК заменены на 0.')
      else
        WriteInfo('Пройдена успешно.');
      WriteInfo('Загрузка документов:');
      ProgressBar.Max := XmlFirstFile.childNodes.Length - 4;
      ProgressBar.Position := 0;
      //заполнение данных докумнетов
      for i := 4 to XmlFirstFile.childNodes.Length - 1 do
      begin
        XmlFirstFile := XmlFirstFile.childNodes.Item[i];
        Doc := CreateOleObject('Microsoft.XmlDom');
        Doc := Doc.appendChild(Doc.createElement('DOCUMENT'));
        // exchange #2400 игнорирование раздела VBR2PD по ТФФ 10
        case Exch2400_Ignore_Section_VBR2PD( XmlFirstFile.NodeName) of
          'VBR12', 'VBR2PD':
            // exchange #3085
            // немного поправлен код для наглядности
            case LowerCase(XmlFirstFile.getAttribute('NAME_DOC')) of
              'платежное поручение': begin
                    WriteInfo('---==============---');

                    MakeDocumentVbr;
                  end;
              'уведомление об уточнении вида и принадлежности платежа': begin
                    MakeDocumentAnswer('UF', i);
                    if XmlFirstFile.NodeName = 'VBR12' then
                      GuidListVb.Add(XmlFirstFile.getAttribute('GUID'));
                  end;
              'справка ф. 0504833': begin
                    WriteInfo('---==============---');
                    WriteInfo('Пропущен: документы с наименованием "справка ф. 0504833" ' +
                      'не загружаются по формату TXVB090101');
                  end;
              'реестр перечисленных поступлений': begin
                    WriteInfo('---==============---');
                    WriteInfo('Пропущен: документы с наименованием "реестр перечисленных поступлений" ' +
                      'не загружаются по формату VB.');
                  end;
              else
                  // exchange #2564
                  // нужно отображать сообщение в логе и не прерывать загрузку.
                  WriteInfo( 'Не определен класс документа по полю NAME_DOC = '
                              + XmlFirstFile.getAttribute('NAME_DOC'));
      {            Raise('Не определен класс документа по полю NAME_DOC = ' +
                    XmlFirstFile.getAttribute('NAME_DOC'));}
            end;//case//

          'VBR13':
            begin
              WriteInfo('---==============---');
              MakeDocumentAnswer('RRR', i);
            end;
        end;
        Doc := null;
        XmlFirstFile := XmlFirstFile.parentNode;
        ProgressBar.Position := ProgressBar.Position + 1;
      end;
      Result := True;

      except
        ExceptionProc( 'LoadFile');
    end;

end;


//Формирование документов для нодов 'VBR12', 'VBR2PD'
procedure MakeDocumentVbr;
var
  xmlOrg, xmlAcc, DocInFile: Variant;
  i, idx: Integer;
begin
//  LoadSchema(DirIni + 'Schems\bd_txbd100701.xml');
  LoadSchema( GetFileNameSchemaTFF( 'bd_txbd*'));

  WriteInfo('Данные строки файла: Марк.стр.=' + XmlFirstFile.NodeName +
    ', Марк.док.=' + XmlFirstFile.getAttribute('MARKER') +
    ', Имя=' + XmlFirstFile.getAttribute('NAME_DOC'), True);
  //для доков с маркером VD поиск пары не производится, отказы приходят в протоколе
  if XmlFirstFile.getAttribute('MARKER') = 'VD' then
  begin
    WriteInfo('Документы с маркером VD не обрабатываются');
    Exit;
  end;
  //ищем по GUID информацию из расчетных документов.
  WriteLog('Поиск документа по GUID = ' + XmlFirstFile.getAttribute('GUID'));
  idx := GuidList.indexOfName(XmlFirstFile.getAttribute('GUID'));
  if idx < 0 then
  begin
    WriteInfo('В информации из расчетных документов не найден документ с GUID = ' +
      XmlFirstFile.getAttribute('GUID'));
    Exit;
  end;
  idx := StrToInt(GuidList.ValueFromIndex(idx));
  DocInFile := Data.childNodes.items[idx];
  Inc(idx);
  while Data.childNodes.items[idx].nodeName <> 'BDPD' do
  begin
    DocInFile.appendChild(Data.childNodes.items[idx].cloneNode(False));
    Inc(idx);
    if idx > Data.childNodes.length - 1 then
      Break;
  end;
  //обработка документа.
  WriteLog('Формирование документа ...', True);
  // Exchange #1785 ищем файл CreateIncref.set, если найден и маркер документа
  // равен DP + КБК совпал в загружаемом документе со значением в CreateIncref.set
  // + VBR12.SUM_VYPL >0 или VBR12.SUM_POST <0 + документ на входе однострочный, то создаем
  // 35 класс (справка по доходам.)
  if (DocInFile.childNodes.Length = 1) and (XmlFirstFile.NodeName = 'VBR12')
    and (XmlFirstFile.getAttribute('MARKER') = 'DP') and
    (not StrToBool(DocInFile.childNodes.Item[0].getAttribute('F_EMPTYKBK')))
    and (not VarIsNull(DocInFile.childNodes.Item[0].getAttribute('ANAL_KIND')))
    and (DocInFile.childNodes.Item[0].getAttribute('ANAL_KIND') = 1)
    and ((XmlFirstFile.getAttribute('SUM_VYPL') > 0) or (XmlFirstFile.getAttribute('SUM_POST') < 0))
    and FileExists(DirIni + 'Settings\CreateIncref.set') then
    if isCreate35(DocInFile, DirIni + 'Settings\CreateIncref.set') then
    begin
      CreateDoc35(DocInFile, XmlFirstFile);
      Exit;
    end;
  Doc.setAttribute('F_BUDGET_ID', BudgetId);
  Doc.setAttribute('F_ORIGINAL_TYPE', 'VB');
  Doc.setAttribute('F_PARENTCLASS', '13'); //Класс документа, среди которых надо искать пару.

  // exchange #2400 игнорирование раздела VBR2PD по ТФФ 10
  if (( XmlFirstFile.NodeName = 'VBR12') and (param_SpecSr <> ''))
     or ( Exch2400_Ignore_Section_VBR2PD( XmlFirstFile.NodeName) = 'VBR2PD')
    then Doc.setAttribute('F_SS', 'True') // Flag спец.средств
    else Doc.setAttribute('F_SS', 'False');

  Doc.setAttribute('IGNORE_GUID', param_IgnoreGuid);
  Doc.setAttribute('USEGROUPBUH25', param_UseGroupBuh25);
  Doc.setAttribute('action', 'insert');
  Doc.setAttribute('class',
    IfThen((XmlFirstFile.getAttribute('MARKER') = 'DP'), '5', '24'));
  Doc.setAttribute('DECLINE', 'False');
  // предзаполнение шапки
  FillElementBySchemaLoad(Doc, DocInFile);
  Doc.setAttribute('DOC_DATE', XmlFirstFile.getAttribute('DATE_DOC'));
  Doc.setAttribute('DOC_NUMBER', Trim(XmlFirstFile.getAttribute('NOM_DOC')));
  Doc.setAttribute('CARRY_DATE', DateTimeToXml(StrToDate(Vp_Date)));
  // exchange #2702
  Exch2702_ImpUIN( Doc, DocInFile);
  // разборка с идентификатором
  // exchange #3062 - унификация кода
  FillDepartmentalInfo2( Doc, DocInFile);
  {
  Doc.setAttribute('AUTHOR_ID', Get_Author_Id(DocInFile.getAttribute('PAYSTATUS')));
  if (Doc.getAttribute('AUTHOR_ID') = '') and (DocInFile.getAttribute('KBK') <> '') then
    Doc.setAttribute('AUTHOR_ID', 0);
  //Exchnge #771, если KBKD не пусто, а AUTHOR_ID пусто, то AUTHOR_ID заполняем нулем.
  if Doc.getAttribute('AUTHOR_ID') <> '' then
  begin
    Doc.setAttribute('PI_ANAL_KIND', GetPi_Anal_Kind(
      Copy(DocInFile.getAttribute('KBK'), 18, 3)));
    Doc.setAttribute('GROUND_ID', GetGrnd_Ground_Id(DocInFile.getAttribute('OSNPLAT')));
    Doc.setAttribute('PAYTYPE_ID', GetGrnd_PayType_Id(DocInFile.getAttribute('TYPE_PL')));
  end
  else begin
    Doc.setAttribute('PI_BUDGET_CODE', '');
    Doc.setAttribute('PAY_OKATO', '');
    Doc.setAttribute('TAXPERIOD', '');
    Doc.setAttribute('GRND_DOC_NUMBER', '');
  end;
  }
  if DocInFile.getAttribute('ORDER_PAY') = '0' then
    Doc.setAttribute('QUEUE_KIND', '');
// =========================== Кредитовое приложение =========================\\
  if Doc.getAttribute('class') = '24' then
  begin
    WriteLog('Заполнение данных получателя', True);
    Doc.setAttribute('F_CRUSH24', IfThen(param_CrushDoc24, 'True', 'False'));
    Doc.setAttribute('F_SPECSR', IfThen(XmlFirstFile.NodeName = 'VBR12', param_SpecSr, ''));
    Doc.setAttribute('F_SEARCH_BO', IfThen(param_Search_Bo, 'True', 'False'));
    // --- Получатель (ФО) ---
    Doc.setAttribute('REC_ID', FO.getAttribute('ORG_ID'));
    Doc.setAttribute('REC_TAXCODE', FO.getAttribute('TAXCODE'));
    Doc.setAttribute('REC_KPP', FO.getAttribute('KPP'));
    Doc.setAttribute('REC_NAME', FO.getAttribute('ORG_DESCRIPTION'));
    //Cчет
    Doc.setAttribute('REC_ACC_ID', FO.getAttribute('ACC_ID'));
    Doc.setAttribute('REC_ACCOUNT', FO.getAttribute('ACCOUNT_NUMBER'));
    Doc.setAttribute('REC_OFK_NAME', FO.getAttribute('OFK_DESCRIPTION'));
    Doc.setAttribute('REC_UFK_NAME', FO.getAttribute('UFK_DESCRIPTION'));
    if StrToBool(Doc.getAttribute('F_SS')) then //внебюджет
    begin
      Doc.setAttribute('REC_UFK_ACC_ID', FO.getAttribute('SPECUFK_ACC_ID'));
      Doc.setAttribute('REC_UFK_ACCOUNT', FO.getAttribute('SPECUFK_ACCOUNT_NUMBER'));
      Doc.setAttribute('REC_BIC', FO.getAttribute('SPECBIC'));
      Doc.setAttribute('REC_B_NAME', FO.getAttribute('SPECB_NAME'));
      Doc.setAttribute('REC_FILIAL_NAME', FO.getAttribute('SPECUFK_FILIAL_NAME'));
    end
    else begin
      Doc.setAttribute('REC_UFK_ACC_ID', FO.getAttribute('UFK_ACC_ID'));
      Doc.setAttribute('REC_UFK_ACCOUNT', FO.getAttribute('UFK_ACCOUNT_NUMBER'));
      Doc.setAttribute('REC_BIC', FO.getAttribute('BIC'));
      Doc.setAttribute('REC_B_NAME', FO.getAttribute('B_NAME'));
      Doc.setAttribute('REC_FILIAL_NAME', FO.getAttribute('UFK_FILIAL_NAME'));
    end;
    WriteLog('Заполнение данных плательщика', True);
    // --- Плательщик ---
    Doc.setAttribute('PAY_ID', '');
    //Cчет
    Doc.setAttribute('PAY_ACC_ID', '');
    WriteLog('Поиск референса плательщика по ИНН и КПП', True);
    
    if IsSysparamOn('org.require_taxcode') and (Trim(Doc.getAttribute('PAY_TAXCODE')) = '') then
    begin
      WriteInfo('Не создан - не заполнен ИНН плательщика');
      Exit;
    end;
    
    if Trim(Doc.getAttribute('PAY_TAXCODE')) <> '' then
    begin
      XmlOrg := GetOrgByTaxKppEx( Doc.getAttribute('PAY_TAXCODE'),
                                  Doc.getAttribute('PAY_KPP'),
                                  '24',
                                  'PAY',
                                  param_UseOrgRef,
                                  Doc);
      if XmlOrg.documentElement.childNodes.Length = 1 then
      begin
        XmlOrg := xmlOrg.documentElement.childNodes.Item[0];
        Doc.setAttribute('PAY_ID', xmlOrg.getAttribute('ID'));
        WriteLog('Найден плательщик с референсом: ' + XmlOrg.getAttribute('ID'));
        WriteLog('Поиск референса счета плательщика', True);
        XmlAcc := GetAccAllRekByOrgIdAccNum(xmlOrg.getAttribute('ID'),
          Doc.getAttribute('PAY_ACCOUNT'));
        if XmlAcc.documentElement.childNodes.Length = 1 then
        begin
          XmlAcc := XmlAcc.documentElement.childNodes.Item[0];
          Doc.setAttribute('PAY_ACC_ID', XmlAcc.getAttribute('ID'));
          Doc.setAttribute('PAY_OFK_NAME', XmlAcc.getAttribute('OFK_DESCRIPTION'));
          Doc.setAttribute('PAY_UFK_NAME', XmlAcc.getAttribute('UFK_DESCRIPTION'));
          Doc.setAttribute('PAY_UFK_ACCOUNT', XmlAcc.getAttribute('UFK_ACCOUNT_NUMBER'));
          Doc.setAttribute('PAY_UFK_ACC_ID', XmlAcc.getAttribute('UFK_ACC_ID'));
          WriteLog('Найден счет плательщика с референсом: ' + XmlAcc.getAttribute('ID'));
        end
        else
          WriteLog('Референс счета плательщика не опеределен', True);
      end
      else
        WriteLog('Референс плательщика не опеределен', True);
    end
    else begin
      if (not IsSysparamOn('org.permit_empty_taxcode')) then
      begin
        WriteInfo('Не создан - не заполнен ИНН плательщика и настройка "Позволять ' +
          'указывать в ЭД организацию-контрагент не из справочника без ИНН" выключена');
        Exit;
      end;
    end;
    
    WriteLog('Заполнение данных получателя из выписки', True);
    Doc.setAttribute('ORG_ID', '');
    Doc.setAttribute('ORG_TAXCODE', DocInFile.getAttribute('INN_RCP'));
    Doc.setAttribute('ORG_KPP', DocInFile.getAttribute('KPP_RCP'));
    Doc.setAttribute('ORG_NAME', DocInFile.getAttribute('CNAME_UBP_RCP'));
    XmlOrg := GetOrgByTaxKppEx( Doc.getAttribute('ORG_TAXCODE'),
                                Doc.getAttribute('ORG_KPP'),
                                '24',
                                'REC',
                                param_UseOrgRef,
                                Doc);
    if XmlOrg.documentElement.childNodes.length = 1 then
      Doc.setAttribute('ORG_ID',
        xmlOrg.documentElement.childNodes.item[0].getAttribute('ID'));
  end else
  begin
// =========================== Дебетовое приложение ==========================\\
    WriteLog('Заполнение данных плательщика', True);
    Doc.setAttribute('PAY_ID', '');
    //Cчет
    Doc.setAttribute('PAY_ACC_ID', FO.getAttribute('ACC_ID'));
    Doc.setAttribute('PAY_ACCOUNT', FO.getAttribute('ACCOUNT_NUMBER'));
    Doc.setAttribute('PAY_OFK_NAME', FO.getAttribute('OFK_DESCRIPTION'));
    Doc.setAttribute('PAY_UFK_NAME', FO.getAttribute('UFK_DESCRIPTION'));
    if StrToBool(Doc.getAttribute('F_SS')) then //внебюджет
    begin
      Doc.setAttribute('PAY_UFK_ACC_ID', FO.getAttribute('SPECUFK_ACC_ID'));
      Doc.setAttribute('PAY_UFK_ACCOUNT', FO.getAttribute('SPECUFK_ACCOUNT_NUMBER'));
      Doc.setAttribute('PAY_BIC', FO.getAttribute('SPECBIC'));
      Doc.setAttribute('PAY_B_NAME', FO.getAttribute('SPECB_NAME'));
      Doc.setAttribute('PAY_FILIAL_NAME', FO.getAttribute('SPECUFK_FILIAL_NAME'));
    end
    else begin
      Doc.setAttribute('PAY_UFK_ACC_ID', FO.getAttribute('UFK_ACC_ID'));
      Doc.setAttribute('PAY_UFK_ACCOUNT', FO.getAttribute('UFK_ACCOUNT_NUMBER'));
      Doc.setAttribute('PAY_BIC', FO.getAttribute('BIC'));
      Doc.setAttribute('PAY_B_NAME', FO.getAttribute('B_NAME'));
      Doc.setAttribute('PAY_FILIAL_NAME', FO.getAttribute('UFK_FILIAL_NAME'));
    end;
    // --- Получатель ---
    WriteLog('Заполнение данных получателя', True);
    Doc.setAttribute('REC_ID', '');
    //Cчет
    Doc.setAttribute('REC_ACC_ID', '');
    if Trim(Doc.getAttribute('REC_TAXCODE')) <> '' then
    begin
      WriteLog('Поиск референса получателя по ИНН и КПП', True);
      XmlOrg := GetOrgByTaxKppEx( Doc.getAttribute('REC_TAXCODE'),
                                  Doc.getAttribute('REC_KPP'),
                                  '5',
                                  'REC',
                                  param_UseOrgRef,
                                  Doc);
      if xmlOrg.documentElement.childNodes.Length = 1 then
      begin
        XmlOrg := XmlOrg.documentElement.childNodes.item[0];
        Doc.setAttribute('REC_ID', XmlOrg.getAttribute('ID'));
        WriteLog('Найден получатель с референсом: ' + XmlOrg.getAttribute('ID'));
        WriteLog('Поиск референса счета получателя', True);
        XmlAcc := GetAccAllRekByOrgIdAccNum(xmlOrg.getAttribute('ID'),
          Doc.getAttribute('REC_ACCOUNT'));
        if XmlAcc.documentElement.childNodes.Length = 1 then
        begin
          XmlAcc := XmlAcc.documentElement.childNodes.item[0];
          Doc.setAttribute('REC_ACC_ID', XmlAcc.getAttribute('ID'));
          Doc.setAttribute('REC_OFK_NAME', XmlAcc.getAttribute('OFK_DESCRIPTION'));
          Doc.setAttribute('REC_UFK_NAME', XmlAcc.getAttribute('UFK_DESCRIPTION'));
          Doc.setAttribute('REC_UFK_ACCOUNT', XmlAcc.getAttribute('UFK_ACCOUNT_NUMBER'));
          Doc.setAttribute('REC_UFK_ACC_ID', XmlAcc.getAttribute('UFK_ACC_ID'));
        end
        else
          WriteLog('Референс счета получателя не опеределен', True);
      end
      else
        WriteLog('Референс получателя не опеределен', True);
    end;
  end;
  // на будующее получатель доходов
  Doc.setAttribute('F_INCRECORGID', IncReceiverId);
    if IncAccountId = '-1' then
      Doc.setAttribute('F_INCRECACCID', '')
  else
    Doc.setAttribute('F_INCRECACCID', Doc.getAttribute('REC_ACC_ID'));
  //инициализим сумму шапки
  Doc.setAttribute('AMOUNT', 0.00);
  if (DocInFile.childNodes.Length = 1) and
    (StrToBool(DocInFile.childNodes.Item[0].getAttribute('F_EMPTYKBK'))) then
  begin
    // записываем сумму документа из строки в шапку
    Doc.setAttribute('AMOUNT',
      Format('%.2f', [StrToCurr(DocInFile.childNodes.Item[0].getAttribute('SUM'))]));
    //атрибут говорит о том что строк нет.
    Doc.setAttribute('NOROW', 'True');
  end
  else begin
    // строки документов.
    Doc := Doc.appendChild(Doc.ownerDocument.createElement('PAYORDERLINE'));
    for i := 0 to DocInFile.childNodes.Length - 1 do
    begin
      DocInFile := DocInFile.childNodes.Item[i];
      Doc := Doc.appendChild(Doc.ownerDocument.createElement('PAYORDERLINE'));
      //Если строка с неопределенны кбк, то выходим, сообщив пользователю
      if StrToBool(DocInFile.getAttribute('F_EMPTYKBK')) then
      begin
        if Doc.parentNode.parentNode.getAttribute('class') = '5' then
          WriteInfo('АЦК: "Приложение к выписке дебетовое" № ' +
            Doc.parentNode.parentNode.getAttribute('DOC_NUMBER') + ' Дата: ' +
              Doc.parentNode.parentNode.getAttribute('DOC_DATE') + ' - не создан. ' +
              'Не определен тип КБК или КБК не заполнен.', True)
        else
          WriteInfo('АЦК: "Приложение к выписке кредитовое" № ' +
            Doc.parentNode.parentNode.getAttribute('DOC_NUMBER') + ' Дата: ' +
              Doc.parentNode.parentNode.getAttribute('DOC_DATE') + ' - не создан. ' +
              'Не определен тип КБК или КБК не заполнен.', True);
        Exit;
      end;
      // предзаполнение
      FillElementBySchemaLoad(Doc, DocInFile);
      Doc.parentNode.parentNode.setAttribute('AMOUNT',
        Doc.parentNode.parentNode.getAttribute('AMOUNT') +
          StrToCurr(Doc.getAttribute('AMOUNT')));
      AddReplaceAttrVal(DocInFile, Doc);
      // Exchange#2101 проставляем в шапку документа тип классификации
      // Anal_kind по последней строке, иначе АЦК некорректно отображает
      if Doc.parentNode.parentNode.getAttribute('class') = '5' then
        Doc.parentNode.parentNode.setAttribute('ANAL_KIND', Doc.getAttribute('ANAL_KIND'));

      // exchange #2400 игнорирование раздела VBR2PD по ТФФ 10
      if (Exch2400_Ignore_Section_VBR2PD( XmlFirstFile.nodeName) = 'VBR2PD')
         and (Doc.getAttribute('ANAL_KIND') = '0')
        then Doc.setAttribute('FSR_ID', 2);

      // Exchange#2079 для доходной классификации в строки 24 класса проставляем плательщика и получателя
      if (Doc.parentNode.parentNode.getAttribute('class') = '24') and (Doc.getAttribute('ANAL_KIND') = '1') then
      begin
        if Doc.parentNode.parentNode.getAttribute('F_INCRECORGID') <> '' then
          Doc.setAttribute('RECEIVER_ID', Doc.parentNode.parentNode.getAttribute('F_INCRECORGID'));
        if Doc.parentNode.parentNode.getAttribute('PAY_ID') <> '' then
          Doc.setAttribute('PAYER_ID', Doc.parentNode.parentNode.getAttribute('PAY_ID'));
      end;
      // Exchange#2089 для доходной классификации в строки проставляем территорию
      if Doc.getAttribute('ANAL_KIND') = '1' then
      begin
        if Doc.getAttribute('OKATO') <> '' then
          Doc.setAttribute('TERRITORY_ID', GetTerritory_IdByOkato(Doc.getAttribute('OKATO')))
        else if Doc.parentNode.parentNode.getAttribute('PAY_ID') <> '' then
          Doc.setAttribute('TERRITORY_ID', QueryField(sqlOrgId,
            Doc.parentNode.parentNode.getAttribute('PAY_ID'), 'TERRITORY_ID'));
      end;
      Doc := Doc.parentNode;
      DocInFile := DocInFile.parentNode;
    end;
    Doc.parentNode.setAttribute('AMOUNT',
      Format('%.2f', [StrToCurr(Doc.parentNode.getAttribute('AMOUNT'))]));
  end;
  Doc := Doc.ownerDocument;
  Doc := Doc.documentElement;
  if Doc.getAttribute('class') = '5' then
    WriteInfo('АЦК: "Приложение к выписке дебетовое" № ' +
      Doc.getAttribute('DOC_NUMBER') + ' Дата: ' +
        Doc.getAttribute('DOC_DATE') + ' Сумма: ' +
        Doc.getAttribute('AMOUNT'), True)
  else
    WriteInfo('АЦК: "Приложение к выписке кредитовое" № ' +
      Doc.getAttribute('DOC_NUMBER') + ' Дата: ' +
        Doc.getAttribute('DOC_DATE') + ' Сумма: ' +
        Doc.getAttribute('AMOUNT'), True);
  // Вставка документа, проверки и прочее.
  if not VarIsNull(Doc.getAttribute('NOROW')) then
    InsertDebCred(Doc) //вставляем документ 5 или 24 класса без строк.
  else
    Documents_DebCred(Doc);
  DocInFile := null;
end;

//Ответы на документы (отказов по постановке - нет, приходят в ЭД протокол)
procedure MakeDocumentAnswer(Marker: String; NodeIndx: Integer = -1);
var
  j, Len: Integer;
  FileNode: Variant;
begin

    try
      // загрузка схемы первого документа, для предзаполнения полей
      // exchange #2399 пп.13 ТФФ 10.0
      // exchange #2542 - переход на тфф11 + переработка модуля проверки версий схем
      LoadSchema( GetFileNameSchemaTFF( 'vb_txvb*'));
      {
      LoadSchema(
          DirIni + VersionSchemsDir
            + IfVersionSupportThenElse(
                cnVersionTFF_10,
                'vb_txvb130101.xml',
                'vb_txvb100701.xml'));
                }
      Doc.setAttribute('F_BUDGET_ID', BudgetId);
      Doc.setAttribute('F_ORIGINAL_TYPE', 'VB');
      Doc.setAttribute('DECLINE', 'False'); //отказы здесь не приходят
      Doc.setAttribute('CARRY_DATE', DateTimeToXml(StrToDate(Vp_Date)));

      if (Marker = 'UF') and
        (GuidListVb.indexOf(XmlFirstFile.getAttribute('GUID')) < 0) then
      begin

        WriteInfo('---==============---');
        WriteInfo('Данные строки файла: Марк.стр.=' + XmlFirstFile.NodeName +
         ', Имя=' + XmlFirstFile.getAttribute('NAME_DOC'), True);
        Doc.setAttribute('DOC_DATE', XmlFirstFile.getAttribute('DATE_DOC'));
        Doc.setAttribute('class', '114');
        FillElementBySchemaLoad(Doc, XmlFirstFile);
        // накопление суммы для VBR12
        if XmlFirstFile.NodeName = 'VBR12' then
          Doc.setAttribute('AMOUNT', 0.00);
        FileNode := XmlFirstFile.parentNode.childNodes.item[NodeIndx];

        Len := XmlFirstFile.parentNode.childNodes.Length;
        while (NodeIndx < Len)
              and (FileNode.NodeName <> 'VB')
              and (FileNode.NodeName <> 'VBR')
              and (FileNode.NodeName <> 'VBR13')
              and (FileNode.NodeName <> 'VBR13BPST')
              and (FileNode.NodeName <> 'VBR2')
              and (FileNode.NodeName <> 'VBR2PD') do
        begin

          if (Doc.getAttribute('FOREIGN_KEY') = FileNode.getAttribute('GUID')) and
            (Doc.getAttribute('DOC_DATE') = FileNode.getAttribute('DATE_DOC')) and
            (Doc.getAttribute('DOC_NUMBER') = FileNode.getAttribute('NOM_DOC')) then
          begin
            if (FileNode.getAttribute('MARKER') =  'KP')  then
              Doc.setAttribute('AMOUNT', Doc.getAttribute('AMOUNT') +
                StrToCurr(FileNode.getAttribute('SUM_POST')));
          end;
          inc(NodeIndx);
          if (Len < NodeIndx) then
            break;
          FileNode := XmlFirstFile.parentNode.childNodes.Item[NodeIndx];
        end;
        Doc.setAttribute('AMOUNT', Format('%.2f', [StrToCurr(Doc.getAttribute('AMOUNT'))]));
        WriteInfo('АЦК: "Уведомление об уточнении вида и принадлежности платежа" № ' +
          Doc.getAttribute('DOC_NUMBER') + ' Дата: ' +
            Doc.getAttribute('DOC_DATE') + ' Сумма: ' +
            Doc.getAttribute('AMOUNT'), True);
      end else
      if Marker = 'RRR' then
      begin

        WriteInfo('Данные строки файла: Марк.стр.=' + XmlFirstFile.NodeName, True);
        //для рр и ррр передаем класс рр, далее разбор поиска происходить в Documents_Answer
        Doc.setAttribute('class', '148');
        Doc.setAttribute('DOC_DATE', XmlFirstFile.getAttribute('DATE_RRR'));
        Doc.setAttribute('AMOUNT','0.00');
        FillElementBySchemaLoad(Doc, XmlFirstFile);
        // накопление суммы
        Doc.setAttribute('AMOUNT', 0.00);
        inc(NodeIndx);
        Len := XmlFirstFile.parentNode.childNodes.Length;
        FileNode := XmlFirstFile.parentNode.childNodes.Item[NodeIndx];

        while (NodeIndx < Len)
              and (FileNode.NodeName <> 'VB')
              and (FileNode.NodeName <> 'VBR')
              and (FileNode.NodeName <> 'VBR12')
              and (FileNode.NodeName <> 'VBR13')
              and (FileNode.NodeName <> 'VBR2')
              and (FileNode.NodeName <> 'VBR2PD') do
          begin
            if FileNode.NodeName = 'VBR13BPST' then
              Doc.setAttribute('AMOUNT', Doc.getAttribute('AMOUNT') +
                StrToCurr(FileNode.getAttribute('SUM_STR')));
            inc(NodeIndx);
            if (Len < NodeIndx) then
              break;
            FileNode := XmlFirstFile.parentNode.childNodes.Item[NodeIndx];
          end;
        Doc.setAttribute('AMOUNT', Format('%.2f', [StrToCurr(Doc.getAttribute('AMOUNT'))]));
        WriteInfo('АЦК: "Расходное расписание/Реестр расходных расписаний" № ' +
          Doc.getAttribute('DOC_NUMBER') + ' Дата: ' + Doc.getAttribute('DOC_DATE') +
          ' Сумма: ' + Doc.getAttribute('AMOUNT'), True);
      end
      else

          Exit;


      //Поиск и перевод статусов документа

      // exchange #2638 - доп поиск
      Documents_Answer(Doc, 'VB');
      except
        ExceptionLog( 'Сбой MakeDocumentAnswer');
    end;

end;

//True - создаем 35 класс. На входе однострочнный документ
//SetFile - файл настроек
function isCreate35(Doc: Variant; SetFile: String): Boolean;
var
  List: TStringList;
  OperType: String;
  Line: Variant;
begin

    try
      Result := False;
      List := LoadSettings(SetFile);
      //если КБК не заменялся на 0, то проверям значение файла настроек
      Line := Doc.childNodes.Item[0];
      try
        if not StrToBool(Line.getAttribute('F_CHANGEDKBK')) then
        begin
          OperType := FindSettingsType2(Line.getAttribute('F_PRIMARYKBK'), List);
          if (OperType <> '') and OperTypeExists('35', OperType) then
          begin
            Doc.setAttribute('F_OPERTYPE_ID_35', OperType);
            Result := True;
          end;
        end;
      finally
        List.Free;
      end;
      except
        ExceptionLog( 'Сбой isCreate35');
    end;

end;

//заполнение полей документа 35 класса
procedure CreateDoc35(DocInFile, XmlFirstFile: Variant);
var
  i: Integer;
begin
  WriteLog('Формирование документа ...', True);
  Doc := CreateOleObject('Microsoft.XmlDom');
  Doc := Doc.appendChild(Doc.createElement('DOCUMENT'));
  Doc.setAttribute('F_ORIGINAL_TYPE', 'VB');
  Doc.setAttribute('FOREIGN_KEY', XmlFirstFile.getAttribute('GUID'));
  Doc.setAttribute('F_BUDGET_ID', BudgetId);
  Doc.setAttribute('action', 'insert');
  Doc.setAttribute('class', 35);
  Doc.setAttribute('DOC_NUMBER', Trim(XmlFirstFile.getAttribute('NOM_DOC')));
  Doc.setAttribute('DOC_DATE', DateTimeToXml(StrToDate(Vp_Date)));
  //KDT_CODE =1 всегда (Exchange #1785)
  Doc.setAttribute('KDT_CODE', 1);
  Doc.setAttribute('DESCRIPTION', DocInFile.getAttribute('PURPOSE'));
  Doc.setAttribute('OPERTYPE_ID', DocInFile.getAttribute('F_OPERTYPE_ID_35'));
  Doc.setAttribute('FK_TYPE_CODE', IfThen(param_Fill_FK_in_IncRef, 1, 0));  //Exchange, #3209
  //инициализация сумм
  Doc.setAttribute('PASS_AMT', 0.00);
  Doc := Doc.appendChild(Doc.ownerDocument.createElement('LINES'));
  for i := 0 to DocInFile.childNodes.Length - 1 do
  begin
    DocInFile := DocInFile.childNodes.Item[i];
    Doc := Doc.appendChild(Doc.ownerDocument.createElement('LINE'));
    WriteLog('Заполнение данных получателя');
    Doc.setAttribute('RECEIVER_ID', IncReceiverId);
    Doc.setAttribute('ORGACCOUNT_ID', FO.getAttribute('ACC_ID'));
    WriteLog('Заполнение данных плательщика');
    Doc.setAttribute('PAYER_ID', FO.getAttribute('ORG_ID'));
    Doc.setAttribute('PAYER_TAXCODE', FO.getAttribute('TAXCODE'));
    Doc.setAttribute('PAYER_KPP', FO.getAttribute('KPP'));
    Doc.setAttribute('PAYER_NAME', FO.getAttribute('ORG_CAPTION'));
    //копируем КБК
    AddReplaceAttrVal(DocInFile, Doc);
    Doc.setAttribute('PASS_AMT', abs(DocInFile.getAttribute('SUM')));
    Doc.parentNode.parentNode.setAttribute('PASS_AMT',
      Doc.parentNode.parentNode.getAttribute('PASS_AMT') + StrToCurr(Doc.getAttribute('PASS_AMT')));
    Doc.setAttribute('DESCRIPTION', DocInFile.parentNode.getAttribute('PURPOSE'));
    Doc.setAttribute('TERRITORY_ID',
      QueryField('Select Territory_Id From Org Where Id = ?',
        [FO.getAttribute('ORG_ID')], 'TERRITORY_ID'));

    // exchange #2389 - доходы
    // exchange #2410 - код цели для доходов в поле PURPOSEFULGRANTD_ID!
    Exch2389_Update_PURPOSEFULGRANT_ID(
//          Doc.parentNode.parentNode,
          Doc,
          '20',
          // exchange #2764
          // бюджет указывается в поле:
          // Doc.parentNode.parentNode.GetAttribute('F_BUDGET_ID')
          // или же взять прилогиненный бюджет (см.выше).
          BudgetId,
          //Doc.parentNode.parentNode.GetAttribute('BUDGET_ID'),
          'PURPOSEFULGRANTD_ID',
          Doc.parentNode.parentNode.getAttribute('class'),
          Doc.parentNode.parentNode.GetAttribute('KDT_CODE'));

    Doc := Doc.parentNode;
    DocInFile := DocInFile.parentNode;
  end;
  Doc.parentNode.setAttribute('PASS_AMT',
    Format('%.2f', [StrToCurr(Doc.parentNode.getAttribute('PASS_AMT'))]));
  Doc := Doc.ownerDocument.documentElement;
  WriteInfo('АЦК: "Справка по доходам" № ' +
    Doc.getAttribute('DOC_NUMBER') + ' Дата: ' +
      Vp_Date + ' Сумма: ' +
      Doc.getAttribute('PASS_AMT'), True);
  // Вставка
  InsDoc(Doc);
  DocInFile := null;
end;

//Функция загрузки файлов без пары, документы только 114, 148(149) классов.
function LoadFirstFile: Boolean;
var
  Xml: Variant;
  i: Integer;
begin
  Result := False;
  XmlFirstFile := XmlFirstFile.documentElement;
  GuidListVb := TStringList.Create;
  GuidListVb.Clear;
  WriteLog('Определение даты выписки', True);
  Vp_Date := XmlFirstFile.childNodes.Item[3].getAttribute('DATE_OTCH');
  WriteLog('Проверка версии формата', True);
  if XmlFirstFile.childNodes.Item[0].getAttribute('NUM_VER') <> FormVer then
  begin
    WriteInfo('Версия формата: ' + XmlFirstFile.childNodes.Item[0].getAttribute('NUM_VER')
      + ' не поддерживается');
    Exit;
  end;
  WriteLog('Определение финансового года по данным выписки', True);
  FinYear := Copy(Vp_Date, 7, 4);
  //получение данных ФО и BudgetId
  if not GetFoAndBudgetId then Exit;
  WriteInfo('Загрузка документов:');
  ProgressBar.Max := XmlFirstFile.childNodes.Length - 4;
  ProgressBar.Position := 0;
  //заполнение данных докумнетов
  for i := 4 to XmlFirstFile.childNodes.Length - 1 do
  begin
    XmlFirstFile := XmlFirstFile.childNodes.Item[i];
    Doc := CreateOleObject('Microsoft.XmlDom');
    Doc := Doc.appendChild(Doc.createElement('DOCUMENT'));
    // exchange #2400 игнорирование раздела VBR2PD по ТФФ 10
    case Exch2400_Ignore_Section_VBR2PD( XmlFirstFile.NodeName) of
      'VBR12', 'VBR2PD':
        begin
          MakeDocumentAnswer('UF', i);
          if XmlFirstFile.NodeName = 'VBR12' then
            GuidListVb.Add(XmlFirstFile.getAttribute('GUID'));
        end;
      'VBR13':
        begin
          WriteInfo('---==============---');
          MakeDocumentAnswer('RRR', i);
        end;
    end;
    Doc := null;
    XmlFirstFile := XmlFirstFile.parentNode;
    ProgressBar.Position := ProgressBar.Position + 1;
  end;
  Result := True;
end;

//получает данные ФО и Id бюджета.
function GetFoAndBudgetId: Boolean;
var
  Xml: Variant;
begin
  Result := False;
  WriteLog('Получение данных ФО', True);
  FO := GetOrgByAccNumOrgCode(XmlFirstFile.childNodes.Item[3].getAttribute('LS'),
    XmlFirstFile.childNodes.Item[2].getAttribute('KOD_UBP'), '', False,  False, FinYear);
  if FO.documentElement.childNodes.Length = 0 then
  begin
    WriteInfo(Format('Не найден финансовый орган и его ЛС: код фин. органа' +
      ' <TO.KOD_UBP=%s>, номер лс <VB.LS=%s>; ',
      [XmlFirstFile.childNodes.Item[2].getAttribute('KOD_UBP'),
      XmlFirstFile.childNodes.Item[3].getAttribute('LS')]));
    Exit;
  end;
  if FO.documentElement.childNodes.Length > 1 then
  begin
    WriteInfo(Format('Найдено несколько <%d> финансовых органов: код фин. органа ' +
      '<TO.KOD_UBP=%s>, номер лс <VB.LS=%s>;',
      [FO.documentElement.childNodes.Length,
      XmlFirstFile.childNodes.Item[2].getAttribute('KOD_UBP'),
      XmlFirstFile.childNodes.Item[3].getAttribute('LS')]));
    Exit;
  end;
  FO := FO.documentElement.childNodes.item[0];
  WriteLog('Определение бюджета загрузки', True);
  BudgetId := '';
  Xml := GetBudgetByFinYearFoCodeUbp(FO.getAttribute('ORG_ID'),
  XmlFirstFile.childNodes.Item[2].getAttribute('KOD_UBP'), FinYear);
  if Xml.documentElement.childNodes.length = 1 then
  begin
    BudgetId := Xml.documentElement.childNodes.Item[0].getAttribute('BUDGET_ID');
    WriteInfo('Бюджет загрузки определен по коду УБП');
  end;
  //если не нашли по первому алгоритму, то ищем как раньше по справочнику бюждета
  if BudgetId = '' then
  begin
    //Ищем бюджет, по "орг., осущ исполнение"
    Xml := GetBudgetByFinYearExecutor(FinYear, FO.getAttribute('ORG_ID'));
    if Xml.documentElement.childNodes.length <> 1 then
    begin
      //Ищем бюджет, у которого "ФО бюджета" равен заданному
      Xml := GetBudgetByFinYearOrgId(FinYear, FO.getAttribute('ORG_ID'));
      if Xml.documentElement.childNodes.Length = 0 then
      begin
        WriteInfo(Format('Не найден бюджет в справочнике бюджетов для ' +
          'организации <%s> на <%s> год;',
          [FO.getAttribute('ORG_DESCRIPTION'), FinYear]));
        Exit;
      end;
      if Xml.documentElement.childNodes.length > 1 then
      begin
        WriteInfo(Format('Найдено несколько бюджетов в справочнике бюджетов для ' +
          'организации <%s> на <%s> год;',
          [FO.getAttribute('ORG_DESCRIPTION'), FinYear]));
        Exit;
      end;
      if Xml.documentElement.childNodes.length = 1 then begin
        BudgetId := Xml.documentElement.childNodes.item[0].getAttribute('ID');
        WriteInfo('Бюджет загрузки определен по организации ФО');
      end;
    end
    else  begin
      BudgetId := Xml.documentElement.childNodes.item[0].getAttribute('ID');
      WriteInfo('Бюджет загрузки определен по организации осуществляющей исполнение');
    end;
  end;
  Result := True;
end;

procedure Initialize(Xml: Variant);
var SL: TStringList;
begin
  SL := TStringList.Create;
  with SL do
    try
      CommaText := InitializeDefault(Xml, ChangeFileExt(TestFileName, ''), False);
      param_Receiver := Values['Получатель доходов'];
      param_CrushDoc24 := Values['Схема загрузки кредитового приложения'] =
        'разбивать многострочный документ';
      param_SpecSr := Values['Учет специальных средств'];
      param_UseOrgRef := Values['Выбирать организацию вручную, при невозможности ' +
        'однозначного определения'] = 'Да';
      param_IgnoreGuid := Values['Игнорировать проверку на уникальность guid первичного' +
        ' документа при создании приложений к выписке кредитовых/дебетовых'] = 'Да';
      param_UseGroupBuh25 := Values['Поиск разрешения на открытие л/с с ' +
        'учетом группы по бухгалтерии'] = 'Да';
      param_ShemaLoadDopKbk := Values['Схема загрузки доп кодов из поля ADD_KLASS'];
      param_Search_Bo := Values['Автоподстановка бюджетного обязательства'] = 'Да';
      param_Fill_FK_in_IncRef := Values['Указывать документ ФК в справке по доходам'] = 'Да';
      // exchange #2405
      Exch2405_Initialize( SL);
      finally
        SL.Free;
    end;
end; {End Initialize}

procedure Finalize(Xml: Variant);
begin
  
  FinalizeDefault(Xml);
  FinalizeMain;
end; {End Finalize}


begin
  Main(NULL);
end. {End Begin}
