//Exchange #2325
function CheckPayOrder_Tolyati: Boolean;
var
  sql: String;
  Xml: Variant;
  i: Integer;
  Unclassified, isOneMask, ls1_flag, ls2_flag: Boolean;
begin

    try
      Result := False;
      if NOT vIsAzkVersion2_26_46_11 then begin
        CDSListField_Message('Модуль проверки работает начиная с версии АЦК-Финансы 2.26.46.11');
        Exit;
      end;

      //проверяются только документы, у которых счет получателя совпал со счетом
      //указанным в справочнике Бухгалтерия-Настройка счетов, поле расчетный счет,
      //тип счета "Счет для учета операций БУ/АУ".
      if NOT DoCheckRecAccountGeneral then EXIT;

      CDSListField_Enroll( NULL);

      //устанавливаем флаг неклассифицированных поступлений
      Unclassified := False;

      //определяет Id получателя из выписки
      if NOT DoCheckOrg( Unclassified) then EXIT;

      //лс
      if (not Unclassified) then
        //Определяем список лицевых счетов открытых на б/с счете получателя 24 класса
        if NOT DoSearchOrgAccount( 3, 3, Unclassified)
          then EXIT;

      //инициализирует значения отраслевого кода, косгу и кода субсидии
      CDSListField_Industry_Code( '');
      CDSListField_Industrycode_Id( '');
      CDSListField_Kesr_Code( '');

      // сброс полей описания кода субсидии
      DoResetGrantInvestment;//( cds);

      //получает отраслевой код, КОСГУ и код субсидии из назначения платежа
      if not Unclassified then
        //если счет плательщика равен 40204810100000000351, то после слова КОД, иначе сначала назначения
        if Copy(CDSListField_Pay_Account_Get, 1, 20) = '40204810100000000351'
          then begin
            if not isParceDescription_Tolyati( 'КОД') then begin
              CDSListField_Message('Не удалось получить отраслевой код и КОСГУ из назначения платежа');
              Unclassified := True;
            end;
          end else begin
            CDSListField_Industry_Code( Copy(CDSListField_Description_Get, 1, 17));
            CDSListField_Kesr_Code( Copy(CDSListField_Description_Get, 18, 3));
            CDSListField_GrantInvestment_Code( Copy(CDSListField_Description_Get, 14, 4));
            // как только модифицируем поле кода, сбрасываем идентификатор
            // ссылки на справочник "субсидии и инвестиции". это поле потребуется
            // для поиска записи из справочника если это не системный код.
            CDSListField_GrantInvestment_Id( '');
          end;

      //проверяем полученные коды
      if not Unclassified then
        // отраслевой код
        //проверка отраслевого кода на 17 нулей и пустоту
        if (StringReplace(CDSListField_Industry_Code_Get, '0', '') = '')
            or (Trim(CDSListField_Industry_Code_Get) = '') then begin
          CDSListField_Message(
              'Не удалось получить отраслевой код или отраслевой код равен 0');
          Unclassified := True;
        end else begin
          // exchange #2667 и #2666 исправлен поиск отр.кода.
          if NOT CheckIndustryCode//( cds)
            then Unclassified := True;
        end;

      // КОСГУ
      // exchange #2627 - расширенная проверка КОСГУ с учетом символьных КБК
      if not Unclassified then
        if NOT CheckKES//( cds)
          then Unclassified := TRUE;

     // код субсидии и инвестиции
      if (not Unclassified) then begin
        //проверка отраслевого кода на 17 нулей и пустоту
        if (StringReplace(CDSListField_GrantInvestment_Code_Get, '0', '') = '')
            or (Trim(CDSListField_GrantInvestment_Code_Get) = '') then begin
          CDSListField_Message('Не удалось получить код субсидии или код субсидии равен 0');
          Unclassified := True;
        end else begin
          // exchange #2369
          // получаем код субсидии из справочника
          if (DoSearchGrantInvestmentCode( {cds, }FALSE) = 1)
            then DoUpdateGrantInvestmentType//( cds)
            else begin
              CDSListField_Message(
                  'Код субсидии: ' + CDSListField_Grantinvestment_Code_Get
                + ' не найден в базе данных');
              Unclassified := True;
            end;
        end;
      end;

      //КВФО
      if not Unclassified then
        // exchange #2366
        if DoSearchMatchLS_Tolyati//( cds)
          then Unclassified := TRUE;

      //формирование данных неклассифицированых поступлений
      if Unclassified then begin
        if NOT DoUnclassified then EXIT;
        Result := True;
      end else begin
        DoCheckOk;
        Result := True;
      end;
      except
        ExceptionProc( 'CheckPayOrder_Tolyati');
    end;

end;
{------------------------------------------------------------------------------}
//разбирает основание платежа.
//параметры:
//cds - набор данных
//keyword - ключевое слово
//если в основании платежа не встречаются ключевые слова или встречаются более
//одного раза то False. В зависимости от ключевого слова заполняются поля в наборе
//данных
function isParceDescription_Tolyati( Keyword: String): Boolean;
var
  i, DescLength, offsetKeyword: Integer;
  Description, Code: String;
begin

    try
      Result := False;
      Code := '';
      Description := CDSListField_Description_Get{cds.FieldByName('Description').asString};
      DescLength := Length(Description);
      offsetKeyword := Length(Keyword);
      i := Pos(Keyword, Description);
      if (i > 0) and (Pos(Keyword, Copy(Description, i + 1, DescLength - i)) > 0)
        then Exit        //дубль
        else
          if i > 0 then begin
            //увеличиваем индекс на длину ключевого слова
            i := i + offsetKeyword;
            Code := Code + Copy(Description, i, 20);
          end;

      Result := Code <> '';
      if Result then begin
        CDSListField_Industry_Code( Copy(Code, 1, 17));
        CDSListField_GrantInvestment_Code( Copy(Code, 14, 4));
        CDSListField_Kesr_Code( Copy(Code, 18, 3));
        DoSetGrantInvestmentCode( Copy(Code, 14, 4));
      end;
      except
        ExceptionProc( 'isParceDescription_Tolyati');
    end;

end;
{------------------------------------------------------------------------------}
{~DoSearchMatchLS_Ekaterinburg
  возвращает =true, если л/с не найден по маске.
  в этом случае ЭД нужно ставить на невыясненный.}
function DoSearchMatchLS_Tolyati: boolean;
  {----------------------------------------------------------------------------}
  function DoSearchMatchLS_( aSQLResult: string): boolean;
  var
    xXml: Variant;
    xRootXml: Variant;
    xNodeXml: Variant;
    i: integer;
  begin

      try
        Result := FALSE;
        xXml := vXML_Doc;// CreateOleObject('Microsoft.XmlDom');
        xXml.LoadXML( aSQLResult);
        xRootXml := xXml.documentElement;
        for i := 0 to xRootXml.childNodes.Length - 1 do begin
          xNodeXml := xRootXml.childNodes.Item[i];
          if (MatchesMask( CDSListField_LS_Number_Get{cds.FieldByName('LS_Number').asString},
                           xNodeXml.getAttribute('ACCOUNTNUMBER_MASK'))
            and
              MatchesMask( CDSListField_Industry_Code_Get{cds.FieldByName('Industry_Code').asString},
                           xNodeXml.getAttribute('INDUSTRYCODE_MASK'))) then
            if not Result then begin
              Result := True;
              CDSListField_Fsr_Id( xNodeXml.getAttribute('FSR_ID'));
              {
              cds.Edit;
              cds.FieldByName('Fsr_Id').AsString := xNodeXml.getAttribute('FSR_ID');
              cds.Post;}
            end else begin
              Result := False;
              CDSListField_Message( {cds,}
                    'Маски счета и отраслевого кода не совпадают с правилом'
                   +' соответствия классификаторов');
              Break;
            end;
        end;//for//
        except
          ExceptionProc( 'DoSearchMatchLS_');
      end;

  end;
  {----------------------------------------------------------------------------}
var
  sql: string;
  xFlag: boolean;
  isOneMask: boolean;
begin

    try
      //проверяем найденные счет и отраслевой код подпадает под маски
      sql := 'Select Accountnumber_Mask, Industrycode_Mask, Fsr_Id'
            +' From AubuclassifiersRules'
            // exchange #2872 - добавлен бюджет в запрос
            +' where BUDGET_ID=? ';

      { Exchange #2366
        Если код субсидии для строки  заполняется  значением, отличным от
        системного 0 «Не указан» (Код «0», наименование «Не указан»,
        Учредитель «Не указан», тип «Не указан»)}
      xFlag := FALSE;   // алгоритм 2
      if NOT DoGrantInvestmentCodeIsSystem{( cds)} then
        { если в поле «Тип субсидии» (GRANTINVESTMENTTYPE) которых указан тип,
          отличный от «Не указан» (3) - алгоритм 1}
        if (CDSListField_Grantinvestment_Type_Get{cds.FieldByName('Grantinvestment_Type').AsString} <> '3')
          then xFlag := TRUE;   // алгоритм 1

      if xFlag then begin
        // алгоритм 1
        Query.AddStr( CDSListField_Budget_Id_Get{cds.FieldByName('Budget_Id').AsString});    // #2872
        Query.AddStr( CDSListField_Grantinvestment_Type_Get{cds.FieldByName( 'Grantinvestment_Type').AsString});
        isOneMask := DoSearchMatchLS_(
                          Query.Run(sql + ' and GrantinvestmentType = ?'));
      end else begin
        { алгоритм 2
          1)	Выбираются все правила, у которых в поле «Тип субсидии»
          (GRANTINVESTMENTTYPE) указан код с типом 3 «Не указан»}
        Query.AddStr( CDSListField_Budget_Id_Get{cds.FieldByName('Budget_Id').AsString});    // #2872
        isOneMask := DoSearchMatchLS_(
                          Query.Run(sql + ' and GrantinvestmentType = 3'));
        { 4)	Если, в результате выполнения пунктов 1-3 Алгоритма2 не было
          найдено подходящее правило, то пункты 2 и 3 Алгоритма2 выполняются
          для правил, у которых в поле «Тип субсидии» (GRANTINVESTMENTTYPE)
          указаны коды с типами 0, 1, 2.}
        if NOT isOneMask then begin
          Query.AddStr( CDSListField_Budget_Id_Get{cds.FieldByName('Budget_Id').AsString});    // #2872
          isOneMask := DoSearchMatchLS_(
                          Query.Run(sql + ' and GrantinvestmentType in (0,1,2)'));
        end;
      end;

      // если подходящего л/с не нашли - ПП не линкуется
      if isOneMask
        then Result := FALSE
          else begin
          if NOT DoGrantInvestmentCodeIsSystem{( cds)} then
            CDSListField_Message( {cds, }'Не найдены правила соответствия классификаторов' +
              ' по типу Кода субсидии или маска счета не совпадает с полученными' +
              ' правилами')
          else
            CDSListField_Message( {cds,} 'Не найдены правила соответствия классификаторов' +
              ' или маска счета не совпадает с полученными правилами');
          Result := TRUE;
        end;

      except
        ExceptionProc( 'DoSearchMatchLS_Tolyati');
    end;

end;

begin
end.
