{~FillDepartmentalInfo
  Заполнение полей идентификатора платежа в ЭД aDocXml.
  эта функция приходна для ФК и УФЭБС.

  параметр
    aDocXml - узел ЭД, в котором заполняются поля идентификатора платежа;
    aBudgetID - бюджет
    aMsg - сообщение, которое отображается в начале строки сообщения,
          при отображении ошибки в журнале. строка ошибки отображается правее
          этой строки.
    aAUTHOR - статус лица, оформившего платёжь
              если строка пустая - поле в ЭД aDocXml не заполняется.
    aOKATO - ОКАТО
              если строка пустая - поле в ЭД aDocXml не заполняется.
    aGround - Основание налогового платежа
              если строка пустая - поле в ЭД aDocXml не заполняется.
    aTaxPeriod - Показатель налогового периода (дата в виде строки).
                 дату нужно заполнять в формате dd.mm.yyyy.
                 если строка пустая - поле в ЭД aDocXml не заполняется.
                 если значение =0 и параметр aValueZeroNotFill=true,
                 поле в ЭД aDocXml не заполняется.
    aPaytType - Тип налогового платежа
                если строка пустая - поле в ЭД aDocXml не заполняется.
                если значение =0 и параметр aValueZeroNotFill=true,
                 поле в ЭД aDocXml не заполняется.
    aDocNo - номер налогового платежа
    aDocDate - Дата налогового платежа
               дату нужно заполнять в формате dd.mm.yyyy.
    aKBK_Type - тип КБК. допускаются значения строки: 1 или 2 или 3.
    aKBK - КБК.
           если строка пустая - поле в ЭД aDocXml не заполняется.
           если aValidateKBK=true, выполняется проверка составляющих БК в
           строке КБК.
    aValidateKBK - если =true будет выполнена проверка составляющих БК в
                    строке КБК. если =false - проверка строки КБк не проверяется.
    aValidate - если =true, проверка параметров в БД не проверяется.
                проверяются поля: aAUTHOR, aGround, aTaxPeriod.
                проверка не касается кода КБК.
    aValueZeroNotFill - если =true, часть полей:
                          aTaxPeriod, aDocNo, aDocDate,aPaytType,
                      если имеют значение =0, поле в ЭД aDocXml не заполняется.
                      если =false, то значения переносятся в поля ЭД aDocXml
                      как есть.

  exchange #3062 - отмена косгу

  результат
    =true - все поля заполнены
    =false - часть полей не заполнена}
function FillDepartmentalInfo( var aDocXml: Variant;
                                aBudgetID: String;
                                aMsg: string;
                                aAUTHOR: string;
                                aOKATO: string;
                                aGround: string;
                                aTaxPeriod: string;
                                aPaytType: string;
                                aDocNo: string;
                                aDocDate: string;
                                aKBK_Type: string;
                                aKBK: string;
                                aValidateKBK: boolean = TRUE;
                                aValidate: boolean = TRUE;
                                aValueZeroNotFill: boolean = TRUE;
                                aCheckKES: boolean = TRUE): boolean;
var
  xDocDateCopy: string;
  xKBK: string;
  xKBKError: boolean;
  s: string;
  v: Variant;
(*
  procedure CheckKBK_( aTable: string;
                        aPosS, aLength: integer;
                        aName: string);
  begin

      try
        if ( QueryField( ' Select count ( * ) N From ' + aTable
                          +' Where Budget_Id = ? And Code = ?',
                           [ aBudgetID,
                            Copy( xKBK, aPosS, aLength)],
                            'N') <> '1')
          then begin
            WriteInfo( FORMAT( '%s - Не найден в АЦК %s: %s (%s)',
                                [ aMsg,
                                  aName,
                                  Copy( xKBK, aPosS, aLength),
                                  xKBK]));
            xKBKError := TRUE;
          end;

        except
          ExceptionLog( 'Сбой FillDepartmentalInfo.CheckKBK_');
      end;

  end;
  *)
begin

    try
      Result := FALSE;

      // Статус лица,  оформившего документ

      aAUTHOR := TRIM( aAUTHOR);
      if (aAUTHOR <> '') then begin
        // Ищем запросом по базе АЦК, не стал заводить TClientDataSet на этот справочник,
        // в банковских платёжах не часто заполняют для ФО идентификатор платежа.
        // основные платежи по налогам проходять через УФК
        if NOT aValidate
          then aDocXml.setAttribute('AUTHOR_ID', aAUTHOR)
          else begin
            s := VarToStr( QueryField( 'Select Id From PayDocAuthor Where Id = ?',
                                        [ aAUTHOR],
                                        'ID'));
            if ( LENGTH( s) <= 0)
              then WriteInfo( FORMAT( '%s - Не найден в АЦК статус лица, оформившего платёж: %s',
                                      [ aMsg,
                                        aAUTHOR]))
              else aDocXml.setAttribute('AUTHOR_ID', s);
        end;
      end;




      // ОКАТО

      aOKATO := TRIM( aOKATO);
      if ((aOKATO <> '') and (aOKATO <> '0'))
        then aDocXml.setAttribute( 'PAY_OKATO', aOKATO);



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

      aGround := Trim( aGround);
      if (aGround <> '') then begin
        {if ValidInt( aGround)
          then aGround := StrToInt( aGround);}
        if NOT aValidate
          then aDocXml.setAttribute('GROUND_ID', aGround)
          else begin
            s := VarToStr( QueryField( 'Select Id From PayGround Where Name = ?',
                                        [ UPPERCASE( aGround)],
                                        'ID'));
            if ( LENGTH( s) <= 0)
              then WriteInfo( FORMAT( '%s - Не найден в АЦК показатель основания платежа: %s',
                                      [ aMsg,
                                        aGround]))
              else aDocXml.setAttribute( 'GROUND_ID', s);
          end;
      end;



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

      aTaxPeriod := TRIM( aTaxPeriod);
      if (LENGTH( aTaxPeriod) > 0) then begin
        if (aTaxPeriod = '0') then begin
          // проверка на 0 - замещать на пустую строку (без заполнения поля)
          // или заполнять нулем
          if NOT aValueZeroNotFill
            then aDocXml.setAttribute( 'TAXPERIOD', '0');
        end else begin
          aDocXml.setAttribute( 'TAXPERIOD', aTaxPeriod);
        end;
      end;



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

      aDocNo := Trim( aDocNo);
      if (LENGTH( aDocNo) > 0) then begin
        if (aDocNo = '0') then begin
          // проверка на 0 - замещать на пустую строку (без заполнения поля)
          // или заполнять нулем
          if NOT aValueZeroNotFill
            then aDocXml.setAttribute( 'GRND_DOC_NUMBER', '0');
        end else begin
          aDocXml.setAttribute( 'GRND_DOC_NUMBER', aDocNo);
        end;
      end;



      // Дата налогового платежа
      // дату нужно заполнять в формате dd.mm.yyyy.
      aDocDate := Trim( aDocDate);

      if (LENGTH( aDocDate) > 0) then begin
        xDocDateCopy := aDocDate;
        // если дата указана =0, то и выгружать ее именно так.
        // если <>0 - то проверят корректность ввода даты.
        if (aDocDate = '0')
          then aDocXml.setAttribute( 'GRND_DOC_DATE', '0')
          else begin
            { тут особенность в неявном преобразовании даты в строку
              используя variant.
              функция ValidDate проверяет дату в формате: dd.mm.yyyy.
              или в формате windows. в преобразовании variant формат даты
              используется какой нужно, поэтому проблем с проверкой
              даты не возникает.
              здесь, если в строке даты есть символ "-", предполагается
              формат xml: yyyy-mm-dd, поэтому в начале преобразуем в
              тип datetime и присваиваем варианту.
              если символа "-" нет - считается формат dd.mm.yyyy.
              затем преобразуем varint -> строка.
              если вариант типа даты, то будет неявное преобразование
              datetime в строку с учетом формата windows.
              в результате, проверка ValidDate должна выполнится успешно.}
            if (Pos('-', aDocDate) > 0)
              then v := XmlToDateTime( aDocDate)
              else v := aDocDate;
            aDocDate := v;

            if ValidDate( v)
              then aDocXml.setAttribute( 'GRND_DOC_DATE',
                                        FormatDateTime( 'dd.mm.yyyy',
                                                        StrToDateTime( aDocDate)))
              else WriteInfo( FORMAT( '%s - Неверно указана дата налогового платежа: %s',
                                      [ aMsg,
                                        xDocDateCopy]));
          end;
      end;




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

      aPaytType := TRIM( aPaytType);
      if (LENGTH( aPaytType) > 0) then begin
        if (aPaytType = '0') then begin
          // проверка на 0 - замещать на пустую строку (без заполнения поля)
          // или заполнять нулем
          // exchange #2814
          // при указании значения 0, нужно искать в БД ид. для нулевого кода,
          // а не подставлять 0 прямо как id.
          if NOT aValueZeroNotFill
            then aDocXml.setAttribute( 'PAYTYPE_ID',
                                       VarToStr( GetGrnd_PayType_Id( '0')));
        end else begin
          // exchange #2814
          // если проверка не требуется, то если в справочнике нет такого
          // кода, то в эд подставляется пустое значение вместо кода.
          // поэтому в бд всегда ищем код типа налогового платежа.
          s := VarToStr( GetGrnd_PayType_Id( aPaytType));
          if NOT aValidate
            then begin
              aDocXml.setAttribute( 'PAYTYPE_ID', s);
              // exchange #2814
              // в логе отразим сообщение, если код не найден в бд,
              // но загрузка эд будет выполнена.
              if ( LENGTH( s) <= 0)
                then WriteLog( FORMAT( '%s - Не найден в АЦК Тип налогового платежа: %s',
                                      [ aMsg,
                                        aPaytType]));
            end else begin
              if ( LENGTH( s) <= 0)
                then WriteInfo( FORMAT( '%s - Не найден в АЦК Тип налогового платежа: %s',
                                        [ aMsg,
                                          aPaytType]))
                else aDocXml.setAttribute( 'PAYTYPE_ID', s);
            end;
        end;
      end;



      // Вид классификации

      // проверяем допустимое множество (это больше нужно для контроля кода)
      if NOT (aKBK_Type in [ '1', '2', '3'])
        then WriteInfo( FORMAT( '%s - Неверно указан вид классификации: %s',
                                [ aMsg,
                                  aKBK_Type]))
        else aDocXml.SetAttribute( 'PI_ANAL_KIND', aKBK_Type);




      // КБК
      // отсекаем концевые пробелы, хотя для символьных КБК может это
      // не нужно делать.
      xKBK      := Trim( aKBK);
      xKBKError := FALSE;

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

          // Если заполнена бюджетная классификация (полностью - 20 знаков),
          // проверяем составляющие
          // Если не найден КЭС, остальное проверять бесмысленно
          // exchange #3062 - отмена косгу и уничифкация кода.
          // здесь проверяем КБК уже имеющимися функциями импорта.
          20: case aKBK_Type of   // проверяем составляющие КБК по типу
                // доходная
                '1': if ValidateKbk( xKBK, '20', aBudgetID, FALSE, '', aCheckKES)
                       then xKBKError := TRUE;
                // расходы
                '2': if ValidateKbk( xKBK, '10', aBudgetID, FALSE, '', aCheckKES)
                       then xKBKError := TRUE;
                // источники
                '3': if ValidateKbk( xKBK, '31', aBudgetID, FALSE, '', aCheckKES)
                       then xKBKError := TRUE;
                // для неопределенного типа КБК значение КБК не проверяется.
                else
                    WriteInfo(
                        FORMAT( '%s - значение кода бюджетной классификации (%s) '
                               +'не проверяется для неопределенного вида классификации',
                                 [ aMsg,
                                   xKBK]));
              end;//case//
          (*
          if ( QueryField( ' Select count ( * ) N From Kes'
                              +' Where Budget_Id = ? And Code = ?',
                               [ aBudgetID,
                                Copy( xKBK, 18, 3)],
                                'N') <> '1')
                then begin
                  WriteInfo( FORMAT( '%s - Не найден в АЦК экономический классификатор: %s (%s)',
                                    [ aMsg,
                                      Copy( xKBK, 18, 3),
                                      xKBK]));
                  xKBKError := TRUE;
                end else
              // проверяем составляющие КБК по типу
              case aKBK_Type of
                // доходная
                '1': begin
                      // код администратора
                      CheckKBK_( 'Kadm', 1, 3, 'классификатор администраторов доходов');
                      // классификатор видов доходов
                      CheckKBK_( 'Kd', 4, 14, ' классификатор видов доходов');
                    end;

                // расходы
                '2': begin
                      // c 4 позиции (4 символа) - Функциональный классификатор расходов
                      CheckKBK_( 'Kfsr', 4, 4, 'функциональный классификатор расходов');
                      // c 8 позиции (7 символа) - Классификатор целевой статьи расходов
                      CheckKBK_( 'Kcsr', 8, 7, 'классификатор целевой статьи расходов');
                      // c 15 позиции (3 символа) - Классификатор видов расходо
                      CheckKBK_( 'Kvr', 15, 3, 'классификатор видов расходов');
                    end;

                // источники
                '3': begin
                      // код администратора
                      CheckKBK_( 'Kadm', 1, 3, 'классификатор администраторов источников');
                      CheckKBK_( 'Ki', 4, 14, 'классификатор видов источников');
                    end;

                // для неопределенного типа КБК значение КБК не проверяется.
                else
                    WriteInfo( FORMAT( '%s - значение кода бюджетной классификации (%s) не проверяется для неопределенного вида классификации',
                                 [ aMsg,
                                   xKBK]));
              end;//case//
              *)

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


      Result := TRUE;
      except
        ExceptionLog( 'Сбой FillDepartmentalInfo');
    end;

end;


{~FillDepartmentalInfo2
  заполнение идентификатора платежа загрузки файлов:
    IP/IV/SB/VA/VB/VC/VG/VI/VJ/VK/VT.
  exchange #3062 - унификация кода + отмена косгу
  перенесено из файлов загрузки.}
procedure FillDepartmentalInfo2( aXmlDoc, aXmlFile: Variant);
begin

    try
      aXmlDoc.setAttribute( 'AUTHOR_ID',
                            Get_Author_Id( aXmlFile.getAttribute('PAYSTATUS')));

      if ((aXmlDoc.getAttribute('AUTHOR_ID') = '')
           and (aXmlFile.getAttribute('KBK') <> ''))
        then aXmlDoc.setAttribute('AUTHOR_ID', 0);

      //Exchnge #771, если KBKD не пусто, а AUTHOR_ID пусто, то AUTHOR_ID заполняем нулем.
      if aXmlDoc.getAttribute('AUTHOR_ID') <> '' then begin
        // exchange #3062 - отмена косгу
        // теперь всегда доходная.
        aXmlDoc.setAttribute('PI_ANAL_KIND', '1');
    {    Doc.setAttribute('PI_ANAL_KIND', GetPi_Anal_Kind(
          Copy(DocInFile.getAttribute('KBK'), 18, 3)));}
        aXmlDoc.setAttribute( 'GROUND_ID',
                              GetGrnd_Ground_Id(aXmlFile.getAttribute('OSNPLAT')));
        aXmlDoc.setAttribute( 'PAYTYPE_ID',
                              GetGrnd_PayType_Id(aXmlFile.getAttribute('TYPE_PL')));
      end else begin
        aXmlDoc.setAttribute('PI_BUDGET_CODE', '');
        aXmlDoc.setAttribute('PAY_OKATO', '');
        aXmlDoc.setAttribute('TAXPERIOD', '');
        aXmlDoc.setAttribute('GRND_DOC_NUMBER', '');
      end;
      except
        ExceptionProc( 'FillDepartmentalInfo2');
    end;

end;


{~CopyDepartmentalInfo
  копирование всех полей идентификации платежа из aDocS в aDocD.
  функция добавлена для exchange #2831.}
procedure CopyDepartmentalInfo( aDocD, aDosS: Variant);
begin

    try
      // Статус лица, оформившего документ
      CopyNodeAttributeEx( aDocD, 'AUTHOR_ID', aDosS, 'AUTHOR_ID');
      // ОКТМО
      CopyNodeAttributeEx( aDocD, 'PAY_OKATO', aDosS, 'PAY_OKATO');
      // Показатель основания платежа
      CopyNodeAttributeEx( aDocD, 'GROUND_ID', aDosS, 'GROUND_ID');
      // Налоговый период
      CopyNodeAttributeEx( aDocD, 'TAXPERIOD', aDosS, 'TAXPERIOD');
      // Номер документа
      CopyNodeAttributeEx( aDocD, 'GRND_DOC_NUMBER', aDosS, 'GRND_DOC_NUMBER');
      // Дата документа
      CopyNodeAttributeEx( aDocD, 'GRND_DOC_DATE', aDosS, 'GRND_DOC_DATE');
      // Тип платежа
      CopyNodeAttributeEx( aDocD, 'PAYTYPE_ID', aDosS, 'PAYTYPE_ID');
      // Классификация по  КБК
      CopyNodeAttributeEx( aDocD, 'PI_ANAL_KIND', aDosS, 'PI_ANAL_KIND');
      // классификация КБК (Доходная,Расходная,источникам)
      CopyNodeAttributeEx( aDocD, 'PI_BUDGET_CODE', aDosS, 'PI_BUDGET_CODE');
(*
      // Статус лица, оформившего документ
      aDocD.SetAttribute( 'AUTHOR_ID',
                          GetNodeAttributeEx( aDosS, 'AUTHOR_ID'));
      // ОКТМО
      aDocD.SetAttribute( 'PAY_OKATO',
                          GetNodeAttributeEx( aDosS, 'PAY_OKATO'));
      // Показатель основания платежа
      aDocD.SetAttribute( 'GROUND_ID',
                          GetNodeAttributeEx( aDosS, 'GROUND_ID'));
      // Налоговый период
      aDocD.SetAttribute( 'TAXPERIOD',
                          GetNodeAttributeEx( aDosS, 'TAXPERIOD'));
      // Номер документа
      aDocD.SetAttribute( 'GRND_DOC_NUMBER',
                          GetNodeAttributeEx( aDosS, 'GRND_DOC_NUMBER'));
      // Дата документа
      aDocD.SetAttribute( 'GRND_DOC_DATE',
                          GetNodeAttributeEx( aDosS, 'GRND_DOC_DATE'));
      // Тип платежа
      aDocD.SetAttribute( 'PAYTYPE_ID',
                          GetNodeAttributeEx( aDosS, 'PAYTYPE_ID'));
      // Классификация по  КБК
      aDocD.SetAttribute( 'PI_ANAL_KIND',
                          GetNodeAttributeEx( aDosS, 'PI_ANAL_KIND'));
      // классификация КБК (Доходная,Расходная,источникам)
      aDocD.SetAttribute( 'PI_BUDGET_CODE',
                          GetNodeAttributeEx( aDosS, 'PI_BUDGET_CODE'));
                          *)
      except
        ExceptionLog( 'Сбой CopyDepartmentalInfo');
    end;

end;


begin
end.
