Перейти к содержанию

Группировка документов

Модуль grouping.py автоматически объединяет связанные документы в группы после обработки. Например, если из одного файла извлечены счёт-фактура, акт выполненных работ и справка к акту с одинаковым номером и датой, модуль объединит их в одну группу.

Алгоритм подсчёта баллов связи

Для каждой пары документов вычисляется балл связи. Чем больше общих признаков у двух документов, тем выше балл.

Критерии и веса

Критерий Баллы Условие
Совпадение номера +35 Цифры номеров совпадают после нормализации
Совпадение даты (точное) +30 Даты совпадают с учётом всех толкований
Совпадение даты (приблизительное) +20 Даты различаются не более чем на один день
Совпадение контрагента +25 Нечёткое сравнение названий даёт сходство выше 0.85
Один исходный файл +5 Оба документа извлечены из одного загруженного файла
Близость страниц +5 Документы расположены в файле через 0--2 страницы
Запасной критерий +25 У одного из документов нет номера, но документы рядом в файле и совпадают по дате

Порог для создания группы --- 65 баллов. Пары с баллом ниже порога не объединяются.

Примеры подсчёта

Счёт-фактура и акт с одинаковым номером, одинаковой датой и одним контрагентом, извлечённые из одного файла на соседних страницах:

35 (номер) + 30 (дата) + 25 (контрагент) + 5 (один файл) + 5 (рядом) = 100 баллов → группа

Два документа без номера, но рядом в одном файле с совпадающей датой:

0 (нет номера) + 30 (дата) + 5 (один файл) + 5 (рядом) + 25 (запасной) = 65 баллов → группа

Два документа с одинаковым номером, но разными датами и контрагентами, из разных файлов:

35 (номер) + 0 (дата) + 0 (контрагент) + 0 (разные файлы) = 35 баллов → не группируются

Нормализация полей перед сравнением

Номера

Из строки номера удаляются все символы кроме цифр. Например, № 123/45 превращается в 12345. Сравнение --- по точному совпадению цифр.

Контрагенты

Перед сравнением из названия контрагента удаляются организационно-правовые формы (ООО, ОАО, ПАО, АО, ЗАО, ИП и другие), кавычки всех типов и лишние пробелы. Затем строки сравниваются нечётко через SequenceMatcher из стандартной библиотеки. Порог сходства --- 0.85.

Даты

Сравнение дат выполняется через централизованный модуль date_utils (см. Работа с неоднозначными датами). Сначала проверяется точное совпадение с учётом всех толкований, затем --- приблизительное (±1 день).

Определение контрагента

Функция determine_contractor определяет, какую из двух сторон документа считать контрагентом:

  • Для счетов, актов, накладных контрагент --- сторона 1 (продавец или исполнитель).
  • Для договоров, дополнительных соглашений и судебных документов отображаются обе стороны через разделитель /.

Объединение пар в группы

Для объединения попарных связей в группы используется структура данных «система непересекающихся множеств» (Union-Find). Она работает следующим образом:

  1. Каждый документ изначально принадлежит отдельному множеству.
  2. Если балл связи между двумя документами достигает порога, их множества объединяются.
  3. После обработки всех пар каждое множество с двумя и более документами становится группой.

Благодаря сжатию путей и объединению по рангу операции выполняются практически за постоянное время.

Выбор основного документа группы

Внутри каждой группы один документ назначается основным. Выбор определяется таблицей приоритетов типов документов:

Приоритет Тип документа
1 УПД
2 Счёт-фактура
3 Акт выполненных работ
4 Справка к акту
5 Акт сверки
6 Накладная
7--9 Акты по материалам
10--11 Платёжные документы (счёт на оплату, платёжное поручение)
12--17 Юридические документы (договор, дополнительное соглашение, доверенность и другие)
99 Неизвестный тип

При одинаковом приоритете выбирается документ, расположенный раньше по номеру страницы.

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

Слияние данных из содержимого и имени файла

Функция merge_document_data объединяет данные, извлечённые из содержимого документа, с данными, извлечёнными из имени файла. Приоритет всегда у содержимого: если поле (номер, дата, контрагент, договор, дата договора) найдено в содержимом --- берётся оттуда. Имя файла используется только как запасной источник.

Сохранение групп в базу данных

После вычисления групп каждая из них записывается в коллекцию document_groups со следующими данными:

  • идентификаторы входящих документов;
  • идентификатор основного документа;
  • реквизиты из основного документа;
  • типы документов в группе;
  • метод группировки (auto), уверенность и критерии;
  • статус проверки (pending).

У каждого документа обновляется поле group_id и флаг is_primary.

Подтверждение и разгруппировка

  • Подтверждение (confirm_group) --- меняет статус группы на confirmed и записывает время подтверждения.
  • Разгруппировка (reject_group) --- убирает group_id у всех документов группы и удаляет запись группы из базы данных.