Алгоритм проверки уникальности и корректности ИНН, КПП при записи контрагента для БП 1.6 и 2.0 через подписку на события




В УПП есть типовой механизм проверки контрагента на уникальность при записи.
В БП 2.0 такой типовой проверки нет, пришлось добавлять свою, к тому же логика УПП-шной проверки меня не совсем устраивает.

Предлагаю свой вариант алгоритма проверки ИНН и КПП при записи элемента справочника Контрагенты.

Ни на что не претендую, если инфа будет кому-то полезна, значит не зря потратил время :).
К тому же этот вопрос возникает с неизменной периодичностью на всех форумах.

Реализовано с помощью подписки на событие, что позволяет спокойно обновлять конфигурацию.

Приведенный ниже код проверяет корректность в ИНН и КПП на:
    — длина
    — недопустимые символы
    — уникальность ИНН+КПП (для юрлица) или уникальность ИНН (для физлица)
    — проверка корректности ИНН на контрольный разряд

P.S. это первая публикация, сильно не ругайте, если есть замечания — сообщите

обновлено 13.03.2012 : добавлена проверка на Отказ, ОбменДанными.Загрузка,  ЭтоГруппа (спасибо http://forum.infostart.ru/forum24/topic51955/message616590/#message616590)

В конфигурации БП реализовал следующим образом:

1) создал подписку на событие

Источник: СправочникОбъект.Контрагенты

Событие: ПередЗаписью

Обработчик: МойОбщийМодуль.ПередЗаписьюКонтрагента (где МойОбщийМодуль — собственный общий модуль, но можно при желании можно и в один из типовых засунуть)

2) собственно сам обработчик

//добавлено — 11/05/2010 (проверка на корректность и уникальность ИНН и КПП)
Процедура ПередЗаписьюКонтрагента(Источник, Отказ) Экспорт

    Если Отказ ИЛИ Источник.ОбменДанными.Загрузка ИЛИ Источник.ЭтоГруппа Тогда
        Возврат;
    КонецЕсли;

    Если Источник.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ФизЛицо Тогда
       
ЭтоФизлицо = Истина;
    Иначе
       
ЭтоФизлицо = Ложь;
    КонецЕсли;

    // проверка ИНН на заполнение
   
ИНН = Источник.ИНН;
    Если
СтрДлина(ИНН) <> ?(ЭтоФизлицо, 12, 10) Тогда
       
СообщениеОНевозможностиЗаписи = «Неверное количество символов в реквизите ИНН!!!» + Символы.ПС
            + «Текущее количество символов: » + СтрДлина(ИНН) + Символы.ПС
            + «Требуемое количество символов для » + ?(ЭтоФизлицо, «Физлица: 12»,«Юрлица: 10»);
       
ОбщегоНазначения.СообщитьОбОшибке(СообщениеОНевозможностиЗаписи);
       
Отказ = Истина;
        Возврат;
    КонецЕсли;

    // проверка ИНН на недопустимые символы
   
Результат = Истина;
    Для
а = 1 По СтрДлина(ИНН) Цикл
        Если
Найти(«0123456789», Сред(ИНН,а,1)) = 0 Тогда
           
НекорректныйСимвол = Сред(ИНН,а,1);
           
Результат = Ложь;
            Прервать;
        КонецЕсли;
    КонецЦикла;

    Если НЕ Результат Тогда
        СообщениеОНевозможностиЗаписи = «Недопустимый символ в реквизите ИНН: <« + НекорректныйСимвол + «> !!!»;
       
ОбщегоНазначения.СообщитьОбОшибке(СообщениеОНевозможностиЗаписи);
       
Отказ = Истина;
        Возврат;
    КонецЕсли;

    // проверка ИНН на контрольный разряд

    Если НЕ РегламентированнаяОтчетность.ИННСоответствуетТребованиям(ИНН, ЮрФизЛицо) Тогда
        СообщениеОНевозможностиЗаписи = «ИНН задан неверно (не прошел проверку на контрольный разряд)!!!»;
        ОбщегоНазначения.СообщитьОбОшибке(СообщениеОНевозможностиЗаписи);
       
Отказ = Истина;
        Возврат;
    КонецЕсли;

    Если НЕ
ЭтоФизлицо Тогда
   
// проверка КПП на заполнение
       
КПП = Источник.КПП;
        Если
СтрДлина(КПП) <> 9 Тогда
           
СообщениеОНевозможностиЗаписи = «Неверное количество символов в реквизите КПП!!!» + Символы.ПС
            + «Текущее количество символов: » + СтрДлина(КПП) + Символы.ПС
            + «Требуемое количество символов: 9»;
           
ОбщегоНазначения.СообщитьОбОшибке(СообщениеОНевозможностиЗаписи);
           
Отказ = Истина;
            Возврат;
        КонецЕсли;

        // проверка КПП на недопустимые символы
       
Результат = Истина;
        Для
а = 1 По СтрДлина(КПП) Цикл
            Если
Найти(«0123456789», Сред(КПП,а,1)) = 0 Тогда
               
НекорректныйСимвол = Сред(КПП,а,1);
               
Результат = Ложь;
                Прервать;
            КонецЕсли;
        КонецЦикла;

        Если НЕ Результат Тогда
            СообщениеОНевозможностиЗаписи = «Недопустимый символ в реквизите КПП: <« + НекорректныйСимвол + «> !!!»;
           
ОбщегоНазначения.СообщитьОбОшибке(СообщениеОНевозможностиЗаписи);
           
Отказ = Истина;
            Возврат;
        КонецЕсли;
    КонецЕсли;

    // поиск дубликатов в справочнике
   
Запрос = Новый Запрос();
   
Запрос.УстановитьПараметр(«ТекущийИНН», ИНН);
   
Запрос.УстановитьПараметр(«ТекущийКПП», КПП);
   
Запрос.УстановитьПараметр(«Ссылка», Источник.Ссылка);

    Запрос.Текст = «ВЫБРАТЬ РАЗРЕШЕННЫЕ ПЕРВЫЕ 1
    |    Контрагенты.Ссылка,
    |    ПРЕДСТАВЛЕНИЕ(Контрагенты.Ссылка) КАК ПредставлениеКонтрагента
    |ИЗ
    |    Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |    НЕ Контрагенты.Ссылка = &Ссылка
    |    И Контрагенты.ИНН = &ТекущийИНН
    |   «
+ ?(ЭтоФизлицо, «», » И Контрагенты.КПП = &ТекущийКПП»);

    ВыборкаКонтрагентов = Запрос.Выполнить().Выбрать();

    Если ВыборкаКонтрагентов.Количество() <> 0 Тогда
       
ВыборкаКонтрагентов.Следующий();
       
СообщениеОНевозможностиЗаписи = «Уже существует контрагент с таким ИНН» + ?(ЭтоФизлицо, «», » И КПП») + » (» + ВыборкаКонтрагентов.Ссылка.Код + » » + ВыборкаКонтрагентов.ПредставлениеКонтрагента + «) !!!» ;
       
ОбщегоНазначения.СообщитьОбОшибке(СообщениеОНевозможностиЗаписи);
       
Отказ = Истина;
        Возврат;
    КонецЕсли;

КонецПроцедуры
//финиш — 11/05/2010 (проверка на корректность и уникальность ИНН и КПП)

15 Comments

  1. ms200999

    Напрашивается проверка по контрольному числу. 🙂

    Reply ↓
  2. DSatan

    (1) не спорю, можно добавить и такой контроль, например из http://infostart.ru/public/70687/

    мне такая проверка не нужна, т.к. часто при создании контрагента-физлица отсутствует информация об ИНН, тогда пользователи используют в качестве ИНН СерияНомерПаспорта+»00″

    Reply ↓
  3. DSatan

    (1) в типовой конфе БП оказывается уже есть функция проверки на контрольное число, добавил сюда эту проверку, спасибо за полезное замечание

    Reply ↓
  4. DDos76

    Спасибо за готовый код! Иногда просто бывает некогда писать и думать — а тут скопировал вставил и работает!

    Reply ↓
  5. artbear

    Сабж пока слабо готов к реальной эксплуатации

    1. Нет проверки на ОбменДанными.Загрузка

    2. ИМХО в подобных обработчиках лучше сразу проверять Отказ. Если Истина, то ничего не делать, так будет производительнее для системы.

    Reply ↓
  6. DSatan

    (5) artbear — прав, спасибо за замечания, одна голова хорошо, а две лучше 🙂

    в принципе этот алгоритм используется на практике уже 2 года, но для универсальности добавлю твои предложения

    Reply ↓
  7. JLaikova

    Спасибо!!!! Пригодилось

    Reply ↓
  8. kalaratra

    Спасибо огромное! Только сегодня пришла такая же задача) Не пришлось самой разбираться)))

    Reply ↓
  9. bashirov.rs

    Проверка на значения типа «0000000000» или «1111111111» и т.д. будет? Возможно проверить по регионам ИНН (начинается ли ИНН с кода региона — 01, 02, … 99) ?

    Reply ↓
  10. байт

    Автору спасибо, благодаря статье сделал все быстро.

    Reply ↓
  11. Nordkas

    Спасибо, я не много доработал и получилось очень достойно.

    Reply ↓
  12. b-dm

    Молодец! Проверка при записи правильное дело.

    Reply ↓
  13. wertyoz453
    Reply ↓
  14. maksa2005

    Чтобы не вводили вместо чисел буквы и цифры в ИНН и КПП для счастья луше добавить маску в ИНН — 999999999999 и КПП 999999999

    Reply ↓
  15. maksa2005

    Не добавил проверку по ИП у которых стоит КПП.

    Reply ↓

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *