Группировка документов¶
Модуль 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 | Акт выполненных работ |
| 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у всех документов группы и удаляет запись группы из базы данных.