//АЦК: Исходящее платежное поручение
//Постановка: Exchange #1537
// #2389 - доработка получения значения ADD_KLASS по ТФФ9
uses
  'Un_Exch3117',    // exchange #3117
  'Un_Exch2719',    // exchange #2719
  'Un_Exch2467',     // exchange #2467
  'Un_Exch2791',    // exchange #2791
  'Exp_FK_Report',
  'Un_Report',
  'Un_Export_AuBu',    // exchange #3081
  'Un_Export',
  'Un_Default',
  'Un_Exch2353',
  '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 = 'Exp_Fk_PP.Xml';
  cnCfgTemplateKBKExp = 'Правило формирования значения аналитического кода с типом классификации “Расходы”';
  cnCfgTemplateKBKInc = 'Правило формирования значения аналитического кода с типом классификации “Доходы”';
  cnCfgTemplateKBKSrc = 'Правило формирования значения аналитического кода с типом классификации “Источники”';

var
  param_PayName, param_RecName, param_RepSession, param_SpecS: Boolean;
  param_RepTemplate, param_TO, param_UFK_TOFK: String;
  FPXml, Data_PP: Variant;
  FPFileOut: TStrings;
  vReportDBF: boolean;
  paramTemplateKBKInc, paramTemplateKBKExp, paramTemplateKBKSrc: String;
{==============================================================================}
function Main(Xml: Variant): Boolean;
var
  i: Integer;
begin
  Result := False;
  xml := InitializeMain( xml, TestFileName);
  if VarIsNull( xml) then exit;
  try
    try
      Initialize(Xml);

      FPXml := CreateOleObject('Microsoft.XmlDom');
      FPXml := FPXml.appendChild(Xml.documentElement.cloneNode(False));
      //заполнение содержимого файла.
      if not MakeFormat(Xml) then begin

        Exit;
      end;
      //валидация схем.

      if param_CtlValidOn then
      begin
        if not ValidateFormat then begin
{          ShellExecute('NotePad', FileValidate, False);
          WriteLog('Не пройден контроль валидности отдельными документами');
          if MessageDlg('Не пройден контроль валидности.' + cr +
            'Продолжить выгрузку?', mtConfirmation, mbYes + mbNo, 0) = mrNo then
          begin
}
          if NOT ShowMessageValid( FileValidate,
                                   'Не пройден контроль валидности отдельными документами')
            then begin
              WriteLog('Выгрузка прервана пользователем');
              if param_StopAllUnloadDocNotValid then begin
                Xml.documentElement.setAttribute('save_unload_file', 'False');
                //прервали всю выгрузку, поэтому принудительно устанавливаем
                //данный пакет последним.
                Xml.documentElement.setAttribute('PACKETLAST', 'True');
              end else begin
                Xml.documentElement.setAttribute('save_unload_file', 'False');
                Result := True;
              end;
            end;
        end;
      end;


      if StrToBool(Xml.documentElement.getAttribute('save_unload_file')) then
      begin

        try
          FileTmp := DirTmp + FileOut;
          WriteLog('Сохранение во временном каталоге: ' + FileTmp, True);
          XmlToTextFile(FileTmp);
        except
          raise('Ошибка сохранения: ' + FileTmp);
        end;
        Data_PP := Data;

        // exchange #2542 - переход на тфф11 + переработка модуля проверки версий схем
        LoadSchema( GetFileNameSchemaTFF( 'fp_txfp*'));
        //DirIni + 'Schems\fp_txfp100701.xml');

        { выгрузка FP усуществляется если в конфигурации параметр
          "Расшифровки к расчетным документам"=да
             (см.эксч Explanation_Enable в модуле Fm_PlatPor.pas)
          и в ПП должено быть (см.эксч TFmPlatPorUnload.DoSQL_PlatPor
          модуль Fm_PlatPorUnload.pas):
            (получатель с ролью=16 (иной получатель) или ПП для получения наличных)
          и (счет плательщика должен быть указан и не 2го типа)
          в этом случае в ЭД передаваемых в скрипт будет поле EXPLANATION=0
          (иначе EXPLANATION=-1) и эд будет добавлен в список FPXml.}
        FPXml := FPXml.ownerDocument.documentElement;
        for i := 0 to FPXml.childNodes.length - 1 do
        begin
          Data := CreateOleObject('Microsoft.XmlDom');
          Data.appendChild(Data.createElement('FORMAT'));
          if not MakeFPDocument(FPXml.childNodes.item[i]) then
          begin
            ClearTemp;
            Exit;
          end;
          //валидация схем.
          if param_CtlValidOn then begin
            if not ValidateFormat then begin
{              ShellExecute('NotePad', FileValidate, False);
              WriteLog('Не пройден контроль валидности отдельными документами');
              if MessageDlg('Не пройден контроль валидности.' + cr +
                'Продолжить выгрузку?', mtConfirmation, mbYes + mbNo, 0) = mrNo then
                }
              if NOT ShowMessageValid( FileValidate,
                                       'Не пройден контроль валидности отдельными документами')
                then begin
                  WriteLog('Выгрузка прервана пользователем');
                  if param_StopAllUnloadDocNotValid then begin
                    ClearTemp;
                    Exit;
                  end else begin
                    ClearTemp;
                    Result := True;
                    Exit;
                  end;
                end;
            end;
          end;
          try
            WriteLog('Сохранение во временном каталоге: ' + DirTmp +
              FPFileOut[FPFileOut.Count - 1], True);
            XmlToTextFile(DirTmp + FPFileOut[FPFileOut.Count - 1]);
          except
            raise('Ошибка сохранения: ' + DirTmp + FPFileOut[FPFileOut.Count - 1]);
          end;
        end;

        { Exchange #2357 - выгрузка ПП в dbf и опись.
          делаем это только при наличие файла akbar_out.dbf в рабочем каталоге
          +опция в конфиге (согласовано с АО).
          в инсталлятор файл akbar_out.dbf должен входить.
          наличие BDE у пользователей обязательно для выгрузки в dbf.
          файл akbar_out.dbf является пустой таблицей, которая копируется и в нее
          формируется отчет dbf.}
        if vReportDBF then begin
          
          if NOT FileExists(DirIni + 'akbar_out.dbf')
            then WriteLog( FORMAT( 'Не найден файл: "%s".',
                              [ DirIni + 'akbar_out.dbf']))
            else begin
              Xml.DocumentElement.SetAttribute('F_OUTFILENAME', FileOut);
              MakeReportTat(Xml);
              
            end;
        end;

        // exchange #2719
        ExportOutDirExch2719( Xml.documentElement.getAttribute('EXCH_DATE'),
                              'PP');

        WriteLog('Перенос документов в архив', True);

        Move_To_Arhiv(Xml);
        WriteLog('Перенос файла в исходящий каталог: ' + DirOut + FileOut, True);
//        CopyFile(DirTmp + FileOut, DirOut + FileOut, False);
        if Trim(DirArh) <> '' then
        begin
          WriteLog('Копирование файла в каталог архива, согласно настройке');
          CopyFile(DirTmp + FileOut, DirArh + FileOut, False);
          if not FileExists(DirArh + FileOut) then
            ShowMessage('Не удалось скопировать файл в каталог архива:' +
              DirArh + FileOut);
        end;

        // exchange #2968 - формируем конечный файл с учетом создания zip архива
//        CopyExportResultFile( DirTmp + FileOut, DirOut);
{
        if not FileExists(DirOut + FileOut) then
          MessageDlg('Ошибка копирования в исходящий каталог.' + #13 + #10 +
            'Файл находится: ' + DirTmp + FileOut, mtError, mbOk, 0)
        else
          DeleteFile(DirTmp + FileOut);
          }

        // exchange #2968 - формируем конечный файл с учетом создания zip архива
        // в один архив кладем и выгруженный PP и все FP
        FPFileOut.Add( FileOut);
        CopyExportResultFiles( FPFileOut, DirTmp, DirOut, TRUE);
{        for i := 0 to FPFileOut.Count - 1 do
        begin
          CopyFile(DirTmp + FPFileOut[i], DirOut + FPFileOut[i], False);
          DeleteFile(DirTmp + FPFileOut[i]);
        end;}
        Result := True;
      end;
      //формирование отчета о сформированных пп
      Data := Data_PP;

      MakeReport(param_RepSession, param_RepTemplate, Xml.documentElement);
{    except
      WriteLog(LastException.Message);
      raise(LastException.Message);
    end;}
  finally
    ShowJournalEnd;
{
    if FileExists(FileInfo)
      then ShowMessageValid( FileInfo,
                                 'Журнал выполнения операции',
                                 mvNew + mvBreakDisabled + mvNotepad);
}
    Finalize(Xml);
{    ProgressBar.Position := 0;
    StatusBar.SimpleText := '';}
//      ShellExecute('NotePad', FileInfo, False);
  end;
    except
//showmessage('final: '+LastException.Message);
      ExceptionHandler;
      Result := False;
  end;
end; {end Main}

function GetOrgCode5(code: String): String;
begin
  if Length(code) = 8 then
    Result := Copy(code, 4, 5)
  else
    Result := code;
end;
{==============================================================================}
{~DoAppendPPST_
   exchange #3081
   добавляем раздел PPST в список разделов.
   при этом контролируем идентичность полей:
   TYPE_KBK, KBK,ADD_KLASS.
   для одинаковых полей суммируем поле SUM.
   делаем это так:
   ищем одинаковость полей от текущего раздела выше до ближайшего
   раздела не PPST. если не нашли - добавляем раздел в хвост.
   если нащли - суммируем поле SUM и новый раздел не добавляем.}
procedure DoAppendPPST_( aXmlFile, aXmlPPST: variant);
begin
  try
    DoAppendUniqueChild(aXmlFile, aXmlPPST, 'TYPE_KBK,KBK,ADD_KLASS', 'SUM', 'PPST');
    except
      ExceptionProc( 'DoAppendPPST_');
  end;
end;
{==============================================================================}
function MakeFormat(Xml: Variant): Boolean;
var
  i, j: Integer;
  UfkAcc: String;
//  UfkAcc, PayAccId: String;
  Amount: Currency;
  xTypeKBK: string;
  xBudgetID: string;
  xNameUbp: string;
  xKESR_CODE: string;
  xXmlNode: Variant;
  xXmlNodeLine: Variant;
  xClientCode195: string;
  xRecAccount: string;
  xPayAccount: string;     // exchange #2467
  xPayAccID: string;      // exchange #2467
  xPayAccType: string;
//  xXmlNodePP: Variant;
  xXmlDocClassID: integer;
  xXmlNode0: Variant;
  xRecAccID: string;
  xRecAccType: string;
  xDataNode: Variant;
  xDataNodeLine: Variant;
  xXmlNodeLineKIF: string;
//  xCondition: boolean;
  xIndexKBK40: integer;
  xAmountKBK40: variant;
  xPayID: string;
  xIsMainED195: boolean;
  tmpStr: String;
  xKBKType, xKBKTemplate: String;
begin

    try
    
  Result := False;
  Xml := Xml.documentElement;

  // для ускорения заполняем локальные переменные, чтобы не искать
  // атрибуты первого ЭД в XML по нескольку раз
  xXmlNode0       := Xml.childNodes.Item[0];
  xBudgetID       := xXmlNode0.getAttribute('BUDGET_ID');
  xXmlDocClassID  := xXmlNode0.getAttribute('DOCUMENTCLASS_ID');
  xPayAccID       := xXmlNode0.getAttribute('PAY_ACC_ID');


  // exchange #2457
  // для 195-го класса параметр CLIENT_CODE выгружать из справочника.
  // Поскольку, если выгружается из транспорта, то поле - пустое.
//  if (Xml.childNodes.Item[0].getAttribute('DOCUMENTCLASS_ID') = 195)
  if (xXmlDocClassID = 195) then begin
    xClientCode195 := TRIM( QueryField(
                             ' select o.name from ORG o where o.id=?',
                             [ xXmlNode0.GetAttribute('PAY_ID')],
                             'NAME'));
    FileOut := GetFileName(GetOrgCode5(xClientCode195),
                            'PP',
                            XmlToDateTime( Xml.getAttribute('EXCH_DATE')),
                            Xml.getAttribute('EXCH_PACKET'),
                            FileOutIsLocalNet,
                            FileOutOrgCodeIsFk);

  end else begin
    //ломаем xml согласно настройки в AzkExchange Сервис-Проверять поля 101...
    if StrToBool(Xml.getAttribute('CHECK_AUTHOR_ID'))
      then Check_Author_Id(Xml);

    FileOut := GetFileName(GetOrgCode5(xXmlNode0.getAttribute('FIN_ORG_CODE')),
                            'PP',
                            XmlToDateTime(Xml.getAttribute('EXCH_DATE')),
                            Xml.getAttribute('EXCH_PACKET'),
                            FileOutIsLocalNet,
                            FileOutOrgCodeIsFk);
  end;
  WriteLog('Наименование формируемого файла: ' + FileOut, True);

  Data := Data.documentElement;
  WriteLog('Заполнение данных файла: ' + FileOut, True);

  xDataNode := Data.appendChild(FillElementBySchema(Xml, 'FK'));
  xDataNode.setAttribute('FORM_VER', AppVersion);


  // FROM
//  Data := Data.parentNode;
  xDataNode := Data.appendChild(FillElementBySchema( xXmlNode0, 'FROM'));

  { exchange #2457
    поле KOD_UBP  блока FROM выгружать так же из справочника для 195-го класса.
    Поскольку, если выгружается из транспорта, то поле - пустое.}
  if (xXmlDocClassID = 195) then begin
    xDataNode.SetAttribute( 'KOD_UBP', xClientCode195);
  end else begin
    xDataNode.setAttribute( 'BUDG_LEVEL', GetBudgLevel( xBudgetID, xXmlNode0));
//                        GetBudgLevel( Xml.childNodes.Item[0].getAttribute('BUDGET_ID'), xXmlNode0));
  { Exchange, #3238
    поле NAME_UBP блока FROM для ПП берется как "Организация, осуществляющая исполнение" из карточки бюджета }
   if (xXmlDocClassID = 13) then
   begin
     xNameUbp := TRIM( QueryField(
                             'select coalesce(exec_org.caption, org.caption) as org_caption from budget b ' +
                             'left join org exec_org on (exec_org.id = b.executor_id) ' +
                             'left join org org on (org.id = b.org_id) where b.id=?',
                             [ xBudgetID],
                             'ORG_CAPTION'));

     xDataNode.setAttribute( 'NAME_UBP', xNameUbp);
   end;
  end;


  // TO
//  Data := Data.parentNode;
  xDataNode := Data.appendChild(FillElementBySchema( xXmlNode0, 'TO'));

  case xXmlDocClassID of
    13: begin
          // запишем во временную строчку тип счета
          tmpStr := GetAccType( xPayAccID);
          // если в параметре указаны значения - проставляем их
          if Trim(param_TO) <> '' then
          begin
            xDataNode.setAttribute('KOD_TOFK', Copy(Trim(param_TO), 0, Pos(',', Trim(param_TO)) - 1));
            xDataNode.setAttribute('NAME_TOFK', Trim(Copy (Trim(param_TO), Pos(',', Trim(param_TO)) + 1, Length(param_TO))));
          end
          // иначе, если счет с типом '2', то берем прямо из организации счета
          else if (tmpStr = '2') then
          begin
            xDataNode.setAttribute('KOD_TOFK', GetOrgCodeByAccIdBugetId( xPayAccID, xBudgetID));
            xDataNode.setAttribute('NAME_TOFK', QueryField( sqlOrgByOrgAccountId, [xPayAccID], 'DESCRIPTION'));
          end
          // иначе берем из ТОФК счета (надеемся, что не будет счетов, где нет ТОФК)
          else
          begin
            xDataNode.setAttribute('KOD_TOFK', QueryField( sqlTofkAcc, [ xPayAccID], 'NAME'));
            xDataNode.setAttribute('NAME_TOFK', QueryField( sqlTofkAcc, [ xPayAccID], 'DESCRIPTION'));
          end;
        end;

    195: begin
           // для 195-го класса берем всегда ТОФК счета
           xDataNode.setAttribute('KOD_TOFK', QueryField( sqlTofkAcc, [ xPayAccID], 'NAME'));
           xDataNode.setAttribute('NAME_TOFK', QueryField( sqlTofkAcc, [ xPayAccID], 'DESCRIPTION'));
         end;
  end;//case//

//  Data := Data.parentNode;

  if (xXmlDocClassID = 195) then begin

    // exchange #2475
    // раздел PP должен быть обязательно, просто он не заполняется.
    xDataNode := Data.appendChild(FillElementBySchema(Xml, 'PP'));
    xDataNode.SetAttribute( 'DATE', '');
    xDataNode.SetAttribute( 'KOL', '');
    xDataNode.SetAttribute( 'SUM_TOTAL', '');
  end else begin
    xDataNode := Data.appendChild(FillElementBySchema(Xml, 'PP'));
  end;



  //Шапка ПП (PPT) - список ЭД ПП

  ProgressBar.Max := Xml.childNodes.length;
  for i := 0 to Xml.childNodes.length - 1 do begin
    ProgressBar.Position := i;
    xXmlNode := Xml.childNodes.items[i];

    // сохраняем класс документа.
    xXmlDocClassID  := STRTOINT( xXmlNode.getAttribute('DOCUMENTCLASS_ID'));
    // бюджет в каждой строке может быть свой, если группировка по
    // бюджету не выполняется
    xBudgetID       := xXmlNode.getAttribute('BUDGET_ID');
    // счет получателя и тип счета
    xRecAccount     := xXmlNode.getAttribute('REC_ACCOUNT');
    xRecAccID       := xXmlNode.getAttribute('REC_ACC_ID');
    // сли счет не указан, то и тип сбрасываем
    // это дает удаление лишней проверки в коде на xRecAccID<>''
    if (xRecAccID <> '')
      then xRecAccType := GetAccType( xRecAccID)
      else xRecAccType := 'x';
    // счет плательщика и тип счета
    xPayAccount     := xXmlNode.getAttribute('PAY_ACCOUNT');
    xPayAccID       := xXmlNode.getAttribute('PAY_ACC_ID');
    // сли счет не указан, то и тип сбрасываем
    // это дает удаление лишней проверки в коде на xPayAccID<>''
    if (xPayAccID <> '')
      then xPayAccType := GetAccType( xPayAccId)
      else xPayAccType := 'x';

    UfkAcc          := xXmlNode.getAttribute('PAY_UFK_ACCOUNT');

    // строка PPT
    xDataNode := Data.appendChild(FillElementBySchema( xXmlNode, 'PPT'));



    xDataNode.setAttribute( 'NOM_PP',
                            Trim( xDataNode.getAttribute('NOM_PP')));


    xDataNode.setAttribute( 'DATE_PP',
                            FormatDateTime(
                                  'dd.mm.yyyy',
                                  XmlToDateTime(
                                        xDataNode.getAttribute('DATE_PP'))));


    xDataNode.setAttribute( 'VID_PL',
                            PayKindSetAsFk( xXmlNode.getAttribute('PAYKIND')));


    xDataNode.setAttribute( 'VID_OPER',
                            StringReplace(
                                  Format( '%2s',
                                          [xDataNode.getAttribute('VID_OPER')]),
                                  ' ', '0'));


    if (xXmlDocClassID = 195) then begin

      // exchange #2467
      if (xRecAccType in ['1', '5', '6', '7', '8', '9'])
        then xDataNode.setAttribute('BS_RCP', xXmlNode.getAttribute('REC_UFK_ACCOUNT'))
        else xDataNode.setAttribute('BS_RCP', xRecAccount);


      //Exchange #2240
      if (xXmlNode.getAttribute('PAY_UFK_ACC_ID') = xXmlNode.getAttribute('REC_UFK_ACC_ID'))
          and {(xRecAccID <> '') and }(xRecAccType = '5')
        then xDataNode.setAttribute('LS_PAY_RCP', xRecAccount);


      // exchange #2457
      // проверяем ЭД "вид документа в ФК"="платежное поручение",
      // тип счета плательщика=5 (лицевой счет в ФК).
      // если это так - то в поле KOD_UBP_PAY нужно помещать значение, указанное
      // в поле "Код организации" из карточки организации указанной в поле
      // "Организация" блока "Плательщик".
      // код организации брать не из поля CLIENT_CODE а из справочника
      // организаций! поскольку при формировании ЭД "Заявки БУ/АУ на выплату
      // средств" из транспорта, поле CLIENT_CODE может быть не заполнено.
      if ((xXmlNode.GetAttribute('PAYDOC_CODE') = 'PP') AND (xPayAccType = '5'))
        then xDataNode.SetAttribute(
                    'KOD_UBP_PAY',
                     TRIM( QueryField( ' select o.name from ORG o where o.id=?',
                                       [ xXmlNode.GetAttribute('PAY_ID')],
                                       'NAME')));


      setTOFKProps(param_UFK_TOFK, xDataNode, xPayAccID, 'KOD_TOFK_PAY', 'NAME_TOFK_PAY');

    end else begin

      // не 195й класс (13й или 5й)
      if not param_PayName
        then xDataNode.setAttribute( 'CNAME_PAY',
                                      xXmlNode.getAttribute('PAY_NAME_BANK_REQUEST'));


      if not param_RecName
        then xDataNode.setAttribute( 'CNAME_UBP_RCP',
                                      xXmlNode.getAttribute('REC_NAME_BANK_REQUEST'));


      //Exchange#1946
      if (xXmlNode.getAttribute('REC_ID') <> '')
          and HasOrgRole( xXmlNode.getAttribute('REC_ID'), '6')
          and ( xRecAccount = '00000000000000000000')
        then xDataNode.setAttribute('BS_RCP', '')
        else
          if Trim( xXmlNode.getAttribute('REC_UFK_ACCOUNT')) <> ''
            then xDataNode.setAttribute( 'BS_RCP',
                                          xXmlNode.getAttribute('REC_UFK_ACCOUNT'));


      // алгоритм заполнения кода и наименования ТОФК/УФК для 2 типа счета.
      if (xPayAccType = '2') then
      begin
        xDataNode.setAttribute('KOD_TOFK_PAY', GetOrgCodeByAccIdBugetId( xPayAccID, xBudgetID));
        xDataNode.setAttribute('NAME_TOFK_PAY', QueryField( sqlOrgByOrgAccountId, [ xPayAccID], 'DESCRIPTION'));
        xDataNode.setAttribute( 'LS_PAY', '');
        //to do в постановке нет, а надо выгружать, сделано ОР самостоятельно
        xDataNode.setAttribute( 'BS_PAY', xPayAccount);
      end
      // алгоритм заполнения кода и наименования ТОФК/УФК для всех остальных счетов.
      else
        setTOFKProps(param_UFK_TOFK, xDataNode, xPayAccID, 'KOD_TOFK_PAY', 'NAME_TOFK_PAY');



      if (xRecAccType in ['5', '7', '9'])
        then xDataNode.setAttribute('LS_PAY_RCP', xRecAccount);

    end;

    if (Trim( VarToStr( xXmlNode.getAttribute('AUTHOR_ID'))) <> '')
      then xDataNode.setAttribute(
                    'PAYSTATUS',
                    StringReplace(
                          Format( '%2s', [ xXmlNode.getAttribute('AUTHOR_ID')]),
                          ' ', '0'));


    // exchange #2702 - ТФФ 12.2
    // в поле UIN передавать значение «Уникальный идентификатор начисления»
    // закладки «ГИС ГМП» при выгрузке ЭД 13, 195 классов
    // для АЦК-Ф версии 2.33.
    // exchange #2727
    // при добавлении временных схем 12.2.1 нужно чтобы поле UIN выгружалось,
    // поэтому добавлена проверка схем 12.2.1
    // exchange #2772
    // по тфф13 выгрузка поля УИН выгружается из ЭД как есть
    // exchange #2808
    // при переходе на ТФФ 14.0, в скриптах остается только тфф 13 и тфф 14.
    // поэтому проверка версии тут уже не нужна.
    {
    if (IsVersionSupport( cnVersionTFF_12_2)
       OR IsVersionSupport( cnVersionTFF_12_2_1)
       OR IsVersionSupport( cnVersionTFF_13)) then begin}
      case xXmlDocClassID of
        '13': xDataNode.setAttribute(
                      'UIN',
                      VarToStr( xXmlNode.getAttribute( 'UIN')));
        '195': xDataNode.setAttribute(
                      'UIN',
                      VarToStr( xXmlNode.getAttribute( 'CHARGE_NUMBER')));
      end;//case//
      // exchange #2707
      // Добавить условие для выгрузки значения поля «Уникальный идентификатор
      // начисления» закладки «ГИС ГМП» при выгрузке 13, 195 класса по
      // формату PP – если в поле указано значение «0»,
      // не выгружать это значение, выгружать поле пустым.
      // exchange #2727
      // требуется выгрузка значения 0 в поле UIN.
      // для этого вместо доп.настройки в конфиге, добавлены схемы 12.2.1.
      // если выбирают эти схемы, то в поле UIN будет выгружаться значение 0.
      // в результате, для схем 12.2.1 проверка выгрузки поля UIN отключается.
      // exchange #2772
      // при добавлении ТФФ13 проверка выгрузки УИН отключена.
      // т.е. если заполнено 0 то и выгружаться должно 0, а не пусто.
      // exchange #2808
      // при переходе на ТФФ 14.0, в скриптах остается только тфф 13 и тфф 14.
      // поэтому выгрузка УИН будет как есть (без замены 0 на пусто).
      (*

      if NOT (IsVersionSupport( cnVersionTFF_12_2_1)
              OR IsVersionSupport( cnVersionTFF_13)) then
        if ( VarToStr( xDataNode.GetAttribute( 'UIN')) = '0')
          then xDataNode.SetAttribute( 'UIN', '');
          *)
//    end;

    // exchange #3081
    // проверяем код ид.платежа PPT.KBK.
    CheckField_PI_BUDGET_CODE( xDataNode, 'KBK', vCfg_2791_LoadKBK0_PI_BUDGET_CODE);

    // exchange #2791 - проверка КБК в ид.платежа
    DoCheck_2791_LoadKBK0_PI_BUDGET_CODE(
            GetNodeAttributeEx( xDataNode, 'KBK'),
            FORMAT( 'Платежное поручение № %s от %s на сумму %s',
                    [ VarToStr( xDataNode.GetAttribute( 'NOM_PP')),
                      VarToStr( xDataNode.GetAttribute( 'DATE_PP')),
                      VarToStr( xDataNode.GetAttribute( 'SUM_PP'))]));

    // exchange #3081
    // созраняем ид.плательщика из шапки эд 195го
    // здесь класс эд не проверяем, поскольку это лишнее.
    // для эд 13го это поле не нужно и если его нет в эд, будет пустая строка.
    xPayID := GetNodeAttributeEx( xXmlNode, 'PAY_ID');

    //------------------------------------------------------------------
    // Exchange #2264
    if (xPayAccType = '2') and (xXmlDocClassID = 13) then begin


      // для случая, когда класс=13 с типом счета = 2 требутся выгружать
      // только один раздел PPST с суммой = сумме всех строк, включая
      // строки расшифровки АУ/БУ (тип КБК=40).
      // так сделано, поскольку при формировании каждой строки формируется PPST
      // и заполняется только поле суммы и DIR_SUM=1.
      // в результате вместо множества пустых строк можно выгружать только
      // одну строку с общей суммой.
      // при этом за исходную строку берется узел с описанием ЭД 13-го класса,
      // из которого берется только поле AMOUNT.

      Data.appendChild( FillElementBySchema( xXmlNode, 'PPST'));


    end else begin
      //------------------------------------------------------------------
      //строки ПП (PPST) 13/195го класса


      { exchange #2567
        теперь требуется для строк с КБК=40 выгружать только одну строк
        с общей суммой и без заполнения КБК.
        для этого заводим флаг - наличие строк с КБК=40, а так же переменную,
        в которой будем суммировать сумму для всех строк.
        в качестве флага будем использовать индекс первой (или последней)
        строки в исходном ЭД, где встретится КБК=40.
        это даcт то, что в конце будем позицироваться на нее и создадим строку
        PPST относительной этой строки ЭД, а затем изменим в ней нужные поля.}
      xIndexKBK40  := -1;
      xAmountKBK40 := 0.0;

      { exchange #3081
        для строк PPST с типом "расшифровка ау/бу"
        TYPE_KBK – определять по правилу 1 ФТ-1.
        Для выгрузки ЭД класса 13 анализировать строки  с родительскогоим
        документа	ом ЭД класса 195, анализировать строки вкладки
        «Расшифровка АУ/БУ»;.
        здесь определяем для эд 13го, порожден ли он от 195го с типом ПП}
      xIsMainED195 := FALSE;
      if (xXmlDocClassID = 13) then
        if ( QueryField( ' select count( * ) Z from payorder p'
                        +' join document dp on dp.id=p.document_id'
                        +' join document dr on dr.id=dp.parent_id'
                        +' join AuBuCashRequest r on r.document_id=dr.id'
                        +' where p.ID = ? and r.PAYDOC_CODE = ?',
                         [ GetNodeAttributeEx( xXmlNode, 'ID'),
                           'PP'],
                           'Z') = '1')
          then xIsMainED195 := TRUE;



      // фикл перебора строк в эд
      for j := 0 to xXmlNode.childNodes.length - 1 do begin
        xXmlNodeLine  := xXmlNode.childNodes.items[j];


        xTypeKBK   := GetTypeKBK( xXmlNodeLine, xBudgetID);//}Xml.getAttribute('BUDGET_ID'));
        xKESR_CODE := GetNodeAttributeEx( xXmlNodeLine, 'KESR_CODE');


        //------------------------------------------------------------------
        if (xXmlDocClassID = 195) then begin
          // exchange #3081 - создаем, но не выгружаем PPST
{          xDataNodeLine := xDataNode.appendChild(
                                    FillElementBySchema(xXmlNodeLine, 'PPST'));}
          xDataNodeLine := FillElementBySchema(xXmlNodeLine, 'PPST');

          { exchange #3081
            Изменить формирование значений полей блока PPST:
              TYPE_KBK – определять по правилу 1 ФТ-1.
              Для выгрузки ЭД класса 13 анализировать строки родительского
              документа ЭД класса 195;
              Если значение поля «тип классификации»= «Расходы»,
              то значение KBK формировать по правилу 2 ФТ-1.}
              xKBKType := ExportTypeKbk_LineED_AuBu( xXmlNodeLine);
              xDataNodeLine.setAttribute(
                  'TYPE_KBK',
                  xKBKType);
              case xKBKType of
                '20' :
                  xKBKTemplate := paramTemplateKBKInc;
                '10' :
                  xKBKTemplate := paramTemplateKBKExp;
                else
                  xKBKTemplate := paramTemplateKBKSrc;
              end;

              xDataNodeLine.setAttribute(
                      'KBK',
                      ExportKbk_Rule( xXmlNodeLine.getAttribute('BUDGET_ID'), xXmlNodeLine,
                                      xKBKTemplate, xXmlNodeLine.getAttribute('DOCUMENTCLASS_ID')));


          // exchange #2467
          Exch2467_Export_ADD_CLASS( xDataNodeLine,
                                      xPayAccount,
                                      xPayAccID,
                                      xXmlNodeLine.getAttribute('GRANTINVESTMENT_ID'));

          // Exchange #2353:
          // п.5 В поле PPST.ADD_KLASS_RCP каждого блока PPST выгружать
          // значение из поля «Код субсидии/инвестиции получателя».
          Exch2353_SetPurposeGrantToADD_KLASS_RCP( xDataNodeLine, xXmlNodeLine);
          Exch2353_SetGrantInvestmentToADD_KLASS_RCP( xDataNodeLine, xXmlNodeLine);

          // exchange #3081 - выгружаем PPST
          DoAppendPPST_( xDataNode, xDataNodeLine);
          CONTINUE;
        end;

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


        // exchange #2566
        // при выгрузке строк ау/бу (тип кбк=40 / analkind=3)
        // тип кбк и поля add_klass и add_klass_rcp не выгружаются
        if (xTypeKBK = '40') then begin
          { exchange #3081
            TYPE_KBK – определять по правилу 1 ФТ-1.
            Для выгрузки ЭД класса 13 анализировать строки  с родительскогоим
            документа	ом ЭД класса 195, анализировать строки вкладки
            «Расшифровка АУ/БУ»;
            Если значение поля «тип классификации»= «Расходы», то значение
            KBK формировать по правилу 2 ФТ-1.
            Изменить формирование значения поля PPT.KBK по правилу 3 ФТ-1}
          if xIsMainED195 then begin
            // exchange #3081 - создаем, но не выгружаем PPST
{            xDataNodeLine := xDataNode.appendChild(
                                    FillElementBySchema(xXmlNodeLine, 'PPST'));}
            xDataNodeLine := FillElementBySchema(xXmlNodeLine, 'PPST');

            xDataNodeLine.setAttribute(
                    'KBK',
                    ExportKbk_LineED_AuBu_Ex( xBudgetID,
                                              xPayID,
                                              xXmlNodeLine,
                                              'AUBU_KESR_CODE',
                                              'AUBU_KVR_CODE',
                                              TRUE));
            xDataNodeLine.setAttribute(
                    'TYPE_KBK',
                    ExportTypeKbk_LineED_AuBu( xXmlNodeLine));

            // exchange #3081 - выгружаем PPST
            DoAppendPPST_( xDataNode, xDataNodeLine);
          end else begin
            // exchange #2567
            // здесь сохраняем индекс строки с КБК=40 и накапливаем сумму.
            // пока разделы PPST по таким строкам не создаем!
            xIndexKBK40  := j;
            xAmountKBK40 := xAmountKBK40
                              + StrToCurrDef(
                                      xXmlNodeLine.getAttribute('AMOUNT'),
                                      0);

          end;

          CONTINUE;
        end;

        //------------------------------------------------------------------
        // создается строка PPST для эд 13
        // exchange #3081 - создаем, но не выгружаем PPST
{        xDataNodeLine := xDataNode.appendChild(
                                    FillElementBySchema(xXmlNodeLine, 'PPST'));}
        xDataNodeLine := FillElementBySchema(xXmlNodeLine, 'PPST');


        xDataNodeLine.setAttribute( 'TYPE_KBK', xTypeKBK);

        // exchange #2399 переход на ТФФ 10.0 с удалением кода ТФФ9
        // exchange #2412 доработка выгрузки кода цели
        xDataNodeLine.setAttribute(
                      'ADD_KLASS',
                      GetPurposeFulgrantCodeExKBK(
                                      //Xml.getAttribute('PURPOSEFULGRANT_ID'),
                                      xXmlNodeLine,
                                      xTypeKBK));
        // Exchange #2353:
        // п.5 В поле PPST.ADD_KLASS_RCP каждого блока PPST выгружать
        // значение из поля «Код субсидии/инвестиции получателя».
        Exch2353_SetPurposeGrantToADD_KLASS_RCP( xDataNodeLine, xXmlNodeLine);
        Exch2353_SetGrantInvestmentToADD_KLASS_RCP( xDataNodeLine, xXmlNodeLine);

        xXmlNodeLineKIF := GetRuleKif( xXmlNodeLine);





        // exchange #3062 - отменен КОСГУ, но только не для 195х классов
        if ((not param_SpecS) and ( xTypeKBK = '10')
            AND (( xXmlNodeLineKIF = '2')
                   OR (GetUfkSpec( xPayAccId, UfkAcc))))
          then xDataNodeLine.setAttribute(
                  'KBK',
                  ExportKbkWithout0(
                    GetRuleKBKLine_R(
                        GetNodeAttributeEx( xXmlNodeLine, 'KADMR_CODE'),
                        '0',
                        '0',
                        '0',
                        GetNodeAttributeEx( xXmlNodeLine, 'KESR_CODE'),
                        xBudgetID,
                        FALSE)))
                              {
                  KadmCodeFormat( xXmlNodeLine.getAttribute('KADMR_CODE'),
                                  xBudgetID)
                 +KfsrCodeFormat('0', xBudgetID)
                 +KcsrCodeFormat('0', xBudgetID)
                 +KvrCodeFormat('0', xBudgetID)
                 +KesCodeFormat( xKESR_CODE, xBudgetID, 0, FALSE))
                 }
          else xDataNodeLine.setAttribute(
                  'KBK',
                  ExportKbkWithout0(
                      GetRuleKBKLine( xXmlNodeLine, xBudgetID, '', FALSE)));

        // KOD_FIN заполняем только при включении галки "получение наличных"
        // строка может не существовать для строки с типом КБК=40,
        // поэтому добавлена проверка, существует ли строка для выгрузки?
        if ( GetNodeAttributeEx( xXmlNode, 'CASH_INCOME') = '1')
          then xDataNodeLine.setAttribute('KOD_FIN', xXmlNodeLineKIF);

        // exchange #3081 - выгружаем PPST
        DoAppendPPST_( xDataNode, xDataNodeLine);
      end;//for//


      //------------------------------------------------------------------
      { exchange #2567
        теперь, после обработки всех строк ЭД, проверяем, если в ЭД есть строки
        с КБК=40, то создаем раздел PPST и заполняем его:
          поля КБК, тип кбк, ADD_KLASS и прочие - не заполняются.
          заполняется только итоговая сумма, в которой объединяется сумма
          из всех строк с КБК=40 в этом ЭД.}
      if (xIndexKBK40 > -1) then begin
        xXmlNodeLine  := xXmlNode.childNodes.items[ xIndexKBK40];
        xDataNodeLine := xDataNode.appendChild(
                                    FillElementBySchema(xXmlNodeLine, 'PPST'));
        xDataNodeLine.setAttribute( 'KBK', '');
        xDataNodeLine.setAttribute( 'TYPE_KBK', '');
        xDataNodeLine.setAttribute( 'ADD_KLASS', '');
        xDataNodeLine.setAttribute( 'ADD_KLASS_RCP', '');
        xDataNodeLine.SetAttribute( 'SUM',
                                    Format('%0.2f', [ xAmountKBK40]));

      end;
    end;

    //------------------------------------------------------------------
    if (xXmlNode.getAttribute('EXPLANATION') = 0)

      then begin

        FPXml.appendChild( xXmlNode.cloneNode(true));
        xDataNode.setAttribute('PRIZ', 0);

      end;


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

  end;//for//


  Data := Data.ownerDocument;

  // exchange 3117
  UpdateXmlOutBy3117( Data);



  Xml := Xml.ownerDocument;
  if FileExists(FileInfo) then Exit;
  Result := True;

      except
        ExceptionProc( 'MakeFormat');
    end;

end; {end MakeFormat}
{==============================================================================}
function MakeFPDocument(Xml: Variant): Boolean;
var
  i: Integer;
  Resperson: Variant;
  Fio, Dolzhnost: String;
  xPayID: string;
  xBudgetID: string;
  xTypeKBK: string;
  xIsMainED195: boolean;
begin

    try
      xBudgetID := Xml.getAttribute('BUDGET_ID');

  Result := False;

  FPFileOut.Add(GetFileName(GetOrgCode5(Xml.getAttribute('FIN_ORG_CODE')), 'FP',
    XmlToDateTime(Xml.parentNode.getAttribute('EXCH_DATE')),
    Xml.parentNode.getAttribute('EXCH_PACKET') +
    IntToStr(FPFileOut.Count + 1), FileOutIsLocalNet, FileOutOrgCodeIsFk));
  WriteLog('Наименование формируемого файла: ' + FPFileOut[FPFileOut.Count - 1], True);
  Data := Data.documentElement;
  WriteLog('Заполнение данных файла: ' + FPFileOut[FPFileOut.Count - 1], True);
  Data := Data.appendChild(FillElementBySchema(Xml, 'FK'));
  Data.setAttribute('FORM_VER', AppVersion);
  Data := Data.parentNode;
  Data := Data.appendChild(FillElementBySchema(Xml, 'FROM'));
  Data.setAttribute('BUDG_LEVEL',
    GetBudgLevel(Xml.getAttribute('BUDGET_ID')));
  Data := Data.parentNode;
  Data.appendChild(FillElementBySchema(Xml, 'TO'));
  Data := Data.appendChild(FillElementBySchema(Xml, 'FP'));
  Data.setAttribute('NOM_PP', Trim(Data.getAttribute('NOM_PP')));
  Data.setAttribute('DATE_PP', FormatDateTime('dd.mm.yyyy',
    XmlToDateTime(Data.getAttribute('DATE_PP'))));
  Data.setAttribute('NAME_BUD', QueryField(sqlBudgId, [Xml.
    getAttribute('BUDGET_ID')], 'CAPTION'));
  Data.setAttribute('DATE_POD', FormatDateTime('dd.mm.yyyy',
    XmlToDateTime(Data.getAttribute('DATE_POD'))));
  if GetAccType(Xml.getAttribute('PAY_ACC_ID')) = '2' then
  begin
    Data.setAttribute('LS_ACC', QueryField(sqlAccTofkByBuh,
      [Xml.getAttribute('BUDGET_ID')], 'ACCOUNT_NUMBER'));
    Data.setAttribute('BS_PL', QueryField(sqlAccByBudg,
      [Xml.childNodes.Item[0].getAttribute('BUDGET_ID')], 'ACCOUNT_NUMBER'));
    Data.setAttribute('NAME_BANK_PL', QueryField(sqlAccByBudg,
      [Xml.getAttribute('BUDGET_ID')], 'BANK_NAME'));
    Data.setAttribute('BIC_PL', QueryField(sqlAccByBudg,
      [Xml.getAttribute('BUDGET_ID')], 'BIC'));
  end;
  Resperson := RespersonFromSys('1', Xml.getAttribute('BUDGET_ID'));
  Data.setAttribute('DOL_ISP', Xml.getAttribute('EXECUTOR_POST'));
  Data.setAttribute('NAME_ISP', Xml.getAttribute('EXECUTOR_FIO'));
  Data.setAttribute('TEL_ISP', Xml.getAttribute('EXECUTOR_PHONE'));
  Data.setAttribute('DOL_RUK', VarToStr(Resperson.documentElement.getAttribute('HEAD_POST')));
  Data.setAttribute('NAME_RUK', VarToStr(Resperson.documentElement.getAttribute('HEAD_FIO')));
  Data.setAttribute('DOL_BUH', VarToStr(Resperson.documentElement.getAttribute('BOOKKEEPER_POST')));
  Data.setAttribute('NAME_BUH', VarToStr(Resperson.documentElement.getAttribute('BOOKKEEPER_FIO')));
  GetResperson(Xml.getAttribute('FIN_ORG_ID'),'-2' , Fio, Dolzhnost);
  if Data.getAttribute('DOL_RUK') = '' then
    Data.setAttribute('DOL_RUK', Dolzhnost);
  if Data.getAttribute('NAME_RUK') = '' then
    Data.setAttribute('NAME_RUK',Fio);
  GetResperson(Xml.getAttribute('FIN_ORG_ID'),'-3' , Fio, Dolzhnost);
  if Data.getAttribute('DOL_BUH') = '' then
    Data.setAttribute('DOL_BUH', Dolzhnost);
  if Data.getAttribute('NAME_BUH') = '' then
    Data.setAttribute('NAME_BUH',Fio);

    // exchange #3081
    // созраняем ид.плательщика из шапки эд 195го
    // здесь класс эд не проверяем, поскольку это лишнее.
    // для эд 13го это поле не нужно и если его нет в эд, будет пустая строка.
    xPayID := GetNodeAttributeEx( Xml, 'PAY_ID');

    { exchange #3081
      для строк PPST с типом "расшифровка ау/бу"
      TYPE_KBK – определять по правилу 1 ФТ-1.
      Для выгрузки ЭД класса 13 анализировать строки  с родительскогоим
      документа	ом ЭД класса 195, анализировать строки вкладки
      «Расшифровка АУ/БУ»;.
      здесь определяем для эд 13го, порожден ли он от 195го с типом ПП}
    xIsMainED195 := FALSE;
    if (GetNodeAttributeEx( Xml, 'DOCUMENTCLASS_ID') = '13') then
      if ( QueryField( ' select count( * ) Z from payorder p'
                      +' join document dp on dp.id=p.document_id'
                      +' join document dr on dr.id=dp.parent_id'
                      +' join AuBuCashRequest r on r.document_id=dr.id'
                      +' where p.ID = ? and r.PAYDOC_CODE = ?',
                       [ GetNodeAttributeEx( Xml, 'ID'),
                         'PP'],
                         'Z') = '1')
        then xIsMainED195 := TRUE;


  for i := 0 to Xml.childNodes.length - 1 do
  begin
    Xml := Xml.childNodes.items[i];
    Data := Data.appendChild(FillElementBySchema(Xml, 'FPKBK'));
    // exchange #3062 - отменен КОСГУ
    // exchange #3081
    // Если параметр «Расшифровки к расчетным документам» имеет значение «Да»,
    // то поля FPKBK.КBK и FPKBK.TYPE_KBK формировать по правилу 1 и 2 ФТ-1.
    // это для строк расшифровки ау/бу (тип кбк=40)
    xTypeKBK := GetTypeKBK(Xml, Xml.getAttribute('BUDGET_ID'), '');
    if (xTypeKBK = '40') then begin
      if xIsMainED195 then begin
        Data.setAttribute(
                'KBK',
                ExportKbk_LineED_AuBu_Ex( xBudgetID,
                                          xPayID,
                                          Xml,
                                          'AUBU_KESR_CODE',
                                          'AUBU_KVR_CODE',
                                          TRUE));
        Data.setAttribute(
                'TYPE_KBK',
                ExportTypeKbk_LineED_AuBu( Xml));
      end else begin
        Data.setAttribute('TYPE_KBK', xTypeKBK);
        Data.setAttribute('KBK', GetRuleKBKLine(Xml, Xml.getAttribute('BUDGET_ID'), '', FALSE));
      end;
    end else begin
      Data.setAttribute('TYPE_KBK', xTypeKBK);
      Data.setAttribute('KBK', GetRuleKBKLine(Xml, Xml.getAttribute('BUDGET_ID'), '', FALSE));
    end;

    Data := Data.parentNode;
    Xml := Xml.parentNode;
  end;
  Data := Data.ownerDocument;
  Xml := Xml.ownerDocument;



  if FileExists(FileInfo) then
    Exit;
  Result := True;

      except
        ExceptionProc( 'MakeFPDocument');
    end;

end;
{==============================================================================}
procedure Initialize(Xml: Variant);
var
  SL: TStringList;
begin

    try
  FPFileOut := TStringList.Create;
  SL := TStringList.Create;
  with SL do
  try
    CommaText := InitializeDefault(Xml, ChangeFileExt(TestFileName, ''));
    param_PayName := Values['Наименование плательщика'] = 'оригинальное АЦК';
    param_RecName := Values['Наименование получателя'] = 'оригинальное АЦК';
    param_SpecS := Values['Заменять КФСР, КЦСР и КВР на нуль'] = 'Нет';
    param_RepSession := Values['Отчет по сессии'] = 'Да';
    param_RepTemplate := Values['Шаблон отчёта'];
    param_TO := Values['Фомирование блока TO'];
    param_UFK_TOFK := Values['Формирование значения КОФК'];
    vReportDBF := (Values['Выгрузка ПП в УФК по счетам налички в DBF'] = 'Да');
    paramTemplateKBKInc := SL.Values[cnCfgTemplateKbkInc];
    paramTemplateKBKExp := SL.Values[cnCfgTemplateKbkExp];
    paramTemplateKBKSrc := SL.Values[cnCfgTemplateKbkSrc];

    // инициализируем модуль сообщений
    InitializeMessageValid( 'Exp_Fk_PP', DirIni);
    // Exchange 2336 загружаем схему в зависимости от версии
    // exchange #2399 пп.6 ТФФ 10.0
    // exchange #2542 - переход на тфф11 + переработка модуля проверки версий схем
    LoadSchema( GetFileNameSchemaTFF( 'pp_txpp*'));
    {
    LoadSchema( DirIni + VersionSchemsDir
                + IfVersionSupportThenElse(
                    cnVersionTFF_10,
                    'pp_txpp120701.xml',
                    'pp_txpp120701.xml'));
                    }
    //атрибут, используемый для сохранения файла. По умолчанию файл сохраняем.
    Xml.documentElement.setAttribute('save_unload_file', 'True');
    //удаление темповой xml для отчетов.
    if StrToBool(Xml.documentElement.getAttribute('PACKETFIRST')) then
      if (FileExists(DirIni + '~Report.xml')) and
        (not DeleteFile(DirIni + '~Report.xml')) then
        Raise('Не удалось удалить файл: ' + DirIni +
          '~Report.xml. Выгрузка остановлена.');

    // exchange #2791
    // настройка "Позволять загружать 0 в КБК ИДП"
    DoConfig_2791_LoadKBK0_PI_BUDGET_CODE( SL);

    // exchange #2968
    InitializeExportCfgZip( SL);
    // exchange #3117
    InitializeExportBy3117( SL);
  finally
    SL.Free;
  end;
      except
        ExceptionProc( 'Initialize');
    end;

end; {End Initialize}
{==============================================================================}
procedure Finalize(Xml: Variant);
begin

  FPFileOut.Free;
  FinalizeDefault(Xml);
  FinalizeMessageValid;
  FinalizeMain;
end; {End Finalize}
{==============================================================================}
procedure ClearTemp;
var
  i: Integer;
begin
  DeleteFile(DirTmp + FileOut);
  for i := 0 to FPFileOut.Count - 1 do
    DeleteFile(DirTmp + FPFileOut[i]);
end; {End ClearTemp}
{==============================================================================}
begin
  Main(NULL);
end.
