161 lines
18 KiB
Markdown
161 lines
18 KiB
Markdown
---
|
||
code: DOC-037740
|
||
title: "FNR01 Модуль загрузки документов и создания записи"
|
||
---
|
||
|
||
# FNR01 Модуль загрузки документов и создания записи
|
||
|
||
## ОСВ
|
||
|
||
### Алгоритм работы:
|
||
|
||
1. Пользователь авторизуется в системе
|
||
2. Система отрисовывает списочную форму сформированных консолидированных отчетов. Пользователь нажимает "Сформировать новый отчет"
|
||
3. Система отрисовывает модальное окно для выбора ГСК -> указания отчетного периода -> выбора компании -> добавления документов по компании
|
||
4. Пользователь нажимает "Добавить" и выбирает документы для загрузки (допустимые форматы файлов xls, xlsx).
|
||
5. Для каждого загружаемого файла ОСВ система создает запись в таблице **stored\\_file**
|
||
6. После создания записи **stored\\_file** система создает задание на распознавание в таблице **recognition\\_job.**
|
||
7. Сервис выполняет парсинг файла ОСВ. Для каждой распознанной расчетной строки система создает отдельную запись в таблице **osv\\_entry**.
|
||
8. После получения **account\\_code** система выполняет нормализацию счета и поиск соответствующей записи в справочнике **chart\\_of\\_account**.
|
||
1. в **osv\\_entry.account\\_id** записывается **chart\\_of\\_account.id.**
|
||
2. в **osv\\_entry.account\\_root** записывается корневой счет.
|
||
9. При наличии в строке контрагента система выполняет его сопоставление со справочником **legal\\_entity**. Если найдено единственное соответствие, в **osv\\_entry.counterparty\\_id** записывается **legal\\_entity.id**. Выполняется последовательный поиск по:
|
||
1. **counterparty\\_inn**
|
||
2. **legal\\_entity.name**
|
||
3. **legal\\_entity\\_alias.normalized\\_alias**
|
||
|
||
Маппинг stored\\_file
|
||
|
||
| | | | |
|
||
| --- | --- | --- | --- |
|
||
| **Поле stored\\_file** | **Источник** | **Пример** | **Правило заполнения** |
|
||
| id | Сгенерированный id | uuid | Генерируется до запуска парсинга |
|
||
| legal\\_entity\\_id | id владельца ОСВ | uuid организации | Идентификатор компании, для которой пользователь загрузил ОСВ |
|
||
| document\\_type | Константа для данного сценария | ОСВ | Всегда "ОСВ" |
|
||
| file\\_type | Расширение загруженного файла | XLSX | Для ОСВ используется тип XLSX, XLS |
|
||
| original\\_name | Имя исходного файла | ОСВ\\_ООО\\_Пекарня\\_6м2026.xlsx | Сохранить исходное имя файла |
|
||
| s3\\_key | Хранилище | ключ объекта | Формируется при сохранении файла в хранилище |
|
||
| content\\_hash | Содержимое файла | sha256 | Хеш файла для контроля дублей |
|
||
| size\\_bytes | Размер файла | 12345 | Размер файла |
|
||
| period\\_year | Шапка ОСВ | 2026 | Нормализованный год |
|
||
| period\\_quarter | Шапка ОСВ | Q2 | Заполнить нормализованным периодом |
|
||
| status | Система | Обработка | При запуске парсинга - "Обработка" После успешного завершения - "Загружен" При ошибке - "Ошибка" При расхождении контрольных сумм - "Требуется проверка" |
|
||
| current\\_recognition\\_job\\_id | Результат успешного запуска | uuid recognition\\_job | После успешного завершения парсинга записать id recognition\\_job |
|
||
| uploaded\\_by | id пользователя | uuid | Пользователь, выполнивший загрузку |
|
||
| uploaded\\_at | Системное время | timestamp | Дата и время загрузки |
|
||
|
||
Маппинг recognition\\_job
|
||
|
||
| | | | |
|
||
| --- | --- | --- | --- |
|
||
| **Поле recognition\\_job** | **Источник** | **Пример** | **Правило заполнения** |
|
||
| id | Сгенерированный id | uuid | Создать до передачи файла в сервис парсинга |
|
||
| file\\_id | id загруженного файла | uuid файла | stored\\_file.id на обрабатываемый файл |
|
||
| pipeline | Тип файла | tabular | Для ОСВ tabular |
|
||
| service\\_version | Версия сервиса парсинга | 1.0 | Заполняет сервис |
|
||
| status | Состояние обработки | queued / processing / done / error | Обновлять по жизненному циклу парсинга |
|
||
| attempt | Номер попытки | 1 | Увеличивать при повторном запуске |
|
||
| queue\\_msg\\_id | Сообщение очереди | id сообщения | Служебное поле дедупликации |
|
||
| requested\\_at | Системное время | timestamp | Время постановки в обработку |
|
||
| started\\_at | Системное время | timestamp | Время начала обработки |
|
||
| finished\\_at | Системное время | timestamp | Время завершения обработки |
|
||
| error\\_message | Ошибка сервиса | текст / NULL | Заполнять только при status = error |
|
||
| raw\\_result\\_s3\\_key | Результат парсинга | ключ JSON | Ключ JSON результата |
|
||
|
||
c. Система создаёт запись в таблице **osv\\_entry** и заполняет данными:
|
||
|
||
Маппинг osv\\_entry
|
||
|
||
| | | | | |
|
||
| --- | --- | --- | --- | --- |
|
||
| **Поле** | **Источник в ОСВ** | **Пример** | **Тип** | **Правило заполнения** |
|
||
| id | Сгенерированный id | - | uuid | Генерируется для каждой сохраняемой строки |
|
||
| stored\\_file\\_id | Сгенерированный id файла | stored\\_file.id | uuid | Записать id файла, из которого получена строка |
|
||
| recognition\\_job\\_id | Сгенерированный id парсинга | recognition\\_job.id | uuid | Записать id текущего запуска парсинга |
|
||
| legal\\_entity\\_id | id владельца ОСВ | stored\\_file.legal\\_entity\\_id | uuid | Организация-владелец ОСВ |
|
||
| account\\_code | Счет или унаследованный текущий счет | 62.01 | varchar | Сохранить исходный код счета |
|
||
| account\\_id | Результат нормализации account\\_code | id счета 62.01 | uuid / NULL | Найти точное соответствие account\\_code = chart\\_of\\_account.code. Если точного счета нет, account\\_id оставить NULL |
|
||
| account\\_root | Нормализация account\\_code до корневого счета | id счета 62.01 | varchar | Корневой счет первого уровня. 62.01.01 -> 62 |
|
||
| counterparty\\_name | Контрагенты | ООО «Ромашка» | varchar / NULL | Сохранить исходное наименование после |
|
||
| counterparty\\_inn | Поле ИНН контрагента | 1650123456 | varchar / NULL | Оставить только цифры. При пустом значении оставить NULL |
|
||
| counterparty\\_id | Результат сопоставления | uuid / NULL | uuid / NULL | Сначала поиск по ИНН. Если не найдено - по нормализованному имени legal\\_entity.name и legal\\_entity\\_alias.normalized\\_alias. При отсутствии совпадения оставить NULL |
|
||
| opening\\_debit | Сальдо на начало периода -> Дебет | 100000.00 | numeric / NULL | Перенести число из соответствующей ячейки |
|
||
| opening\\_credit | Сальдо на начало периода -> Кредит | 0.00 | numeric / NULL | Перенести число из соответствующей ячейки |
|
||
| turnover\\_debit | Обороты за период -> Дебет | 250000.00 | numeric / NULL | Перенести число из соответствующей ячейки |
|
||
| turnover\\_credit | Обороты за период -> Кредит | 170000.00 | numeric / NULL | Перенести число из соответствующей ячейки |
|
||
| closing\\_debit | Сальдо на конец периода -> Дебет | 180000.00 | numeric / NULL | Перенести число из соответствующей ячейки |
|
||
| closing\\_credit | Сальдо на конец периода -> Кредит | 0.00 | numeric / NULL | Перенести число из соответствующей ячейки |
|
||
|
||
Маппинг отчетного периода
|
||
|
||
| **Значение периода в исходной ОСВ** | **Возможные варианты написания** | **Значение в БД period\\_quarter** | **Нарастающий итог (is\\_cumulative)** | **Примечание** |
|
||
| --- | --- | --- | --- | --- |
|
||
| 1 квартал | 1 квартал, I квартал, 1 кв., I кв., за 1 квартал | 1 | true | |
|
||
| 3 месяца | 3 месяца, за 3 месяца, 3 мес., январь-март, 01.01-31.03 | 1 | true | |
|
||
| 2 квартал | 2 квартал, II квартал, 2 кв., II кв., за 2 квартал | 2 | false | Нужно уточнить, возможно ли такое, что в ОСВ указывается номер квартала, но считается все равно нарастающий итог |
|
||
| Полугодие | полугодие, 1 полугодие, I полугодие, за полугодие, за 1 полугодие | 2 | true | |
|
||
| 6 месяцев | 6 месяцев, за 6 месяцев, 6 мес., январь-июнь, 01.01-30.06 | 2 | true | |
|
||
| 3 квартал | 3 квартал, III квартал, 3 кв., III кв., за 3 квартал | 3 | false | Нужно уточнить, возможно ли такое, что в ОСВ указывается номер квартала, но считается все равно нарастающий итог |
|
||
| 9 месяцев | 9 месяцев, за 9 месяцев, 9 мес., январь-сентябрь, 01.01-30.09 | 3 | true | |
|
||
| 4 квартал | 4 квартал, IV квартал, 4 кв., IV кв., за 4 квартал | 4 | false | Нужно уточнить, возможно ли такое, что в ОСВ указывается номер квартала, но считается все равно нарастающий итог |
|
||
| Год | год, за год, за 2026 год, годовая, годовая отчетность | 4 | true | |
|
||
| 12 месяцев | 12 месяцев, за 12 месяцев, 12 мес., январь-декабрь, 01.01-31.12 | 4 | true | |
|
||
|
||
Данные полученные в формате json от ИС Сканирование маппируются:
|
||
|
||
* в таблицу **fin\\_report\\_header** по следующему правилу:
|
||
|
||
| | | |
|
||
| --- | --- | --- |
|
||
| Источник (JSON путь) | Целевое поле | Логика преобразования / Примечания/Пример заполнения |
|
||
| data\\_ocr[0].label.form\\_name | report\\_type | "Отчет о финансовых результатах"; "Бухгалтерский баланс" |
|
||
| data\\_ocr[0].inn.inn | org\\_id | Поиск организации по ИНН в справочнике получение org\\_id |
|
||
| data\\_ocr[0].organization.full\\_name | org\\_id | Сличение с наименованием в справочнике Organizations.full\\_name. При несовпадении ищем совпадение в связанной таблице Organization\\_aliases. alias\\_name по ключу org.id. Если не найдено совпадение то выводим предупреждение. |
|
||
| data\\_ocr[0].units.measurement | unit | в тыс рублей |
|
||
| - | currency | По умолчанию 'RUB', если валюта не указана в JSON |
|
||
| // ждем обновленный джейсон пока от ИС сканирование | reporting\\_date | формат даты: DD.MM.YYYY |
|
||
| Внешний контекст | package\\_id | ID пакета документов из внешней системы (не в JSON) |
|
||
| Системная генерация | report\\_id | Автоинкремент / UUID при вставке |
|
||
| Системное время | created\\_at | NOW() при загрузке документа |
|
||
| | | |
|
||
|
||
* в таблицу **F** **in\\_report\\_rows** по следующему правилу:
|
||
|
||
| | | |
|
||
| --- | --- | --- |
|
||
| Источник (JSON путь) | Целевое поле | Логика преобразования / Примечания/Пример |
|
||
| data\\_ocr[0].table\\_structure.rows[\\*] | (новая строка) | Итерация: одна запись в БД на каждую row из массива |
|
||
| rows[0].cells[1].value | наименование колонки | Строка нулевого индекса содержит значения для описания наименований колонок таблицы. Значения Наименование показателя и Код - константы, их можно не парсить каждый раз, но значения колонок периода потребуется переносить как есть полученное из json |
|
||
| rows[0].cells[2].value | наименование колонки |
|
||
| rows[0].cells[3].value | наименование колонки |
|
||
| rows[0].cells40].value | наименование колонки |
|
||
| rows[\\*].cells[0].value | row\\_name | Наименование показателя (напр. Выручка, Основные средства) |
|
||
| rows[\\*].cells[1].value | row\\_code | Код строки: '2110', '1150', '2400' и т.д. |
|
||
| rows[\\*].cells[2].value | value\\_current | Значение за текущий период. Парсить число, заменять , п, м NULL, значение данное в скобках трактовать как отрицательное. Пример: было (2100000) - стало -21000000 |
|
||
| rows[\\*].cells[3].value | value\\_prior\\_year | Значение за аналогичный период прошлого года. Аналогичная обработка |
|
||
| rows[\\*].cells[4].value (если есть) | value\\_prior2\\_year | Значение за второй предшествующий период (опционально) |
|
||
| rows[\\*].cells[\\*].confidence | confidence | Агрегация уверенности: пример: 0.91 |
|
||
| Контекст группировки (заголовки разделов) | section | Определение раздела: I. ВНЕОБОРОТНЫЕ АКТИВЫ, Доходы и расходы — по ближайшему заголовку выше строки |
|
||
| Анализ стиля/текста ячейки | is\\_total\\_row | TRUE, если row\\_name содержит Итого, БАЛАНС |
|
||
| rows[\\*].explanation\\_code (если есть в расширенной схеме) | explanation\\_code | Код пояснений (опционально, если присутствует в структуре) |
|
||
| Системная генерация | row\\_id | Автоинкремент / UUID |
|
||
| report\\_id из заголовка | report\\_id | FK: подставляется report\\_id из только что созданной записи fin\\_report\\_header |
|
||
|
||
На визуальную форму выводится шапка документа со структурой:
|
||
|
||
| Параметр | Поле | Пример |
|
||
| --- | --- | --- |
|
||
| Тип отчета | report\\_type | Баланс |
|
||
| Наименование организации | Organizations.full\\_name по ключу org\\_id | Акционерное общество Русский бисквит |
|
||
| ИНН | Organizations.inn по ключу org\\_id | 3528052718 |
|
||
| Единица измерения | unit | тыс. руб. |
|
||
| Отчетная дата | reporting\\_date | 30.09.2025 |
|
||
|
||
и табличной частью на основании данных таблицы **F** **in\\_report\\_rows** :
|
||
|
||
| Пояснение | Наименование показателя | Код | Период 1 (rows[0].cells[2].value) | Период 2 (rows[0].cells[3].value) | Период 3 (rows[0].cells[4].value) |
|
||
| --- | --- | --- | --- | --- | --- |
|
||
| | row\\_name | row\\_code | value\\_current | value\\_prior\\_year | value\\_prior2\\_year |
|
||
|
||
После того как парсинг по всем документам завершен (созданы и заполнены все таблицы по всем организациям участвующих в своде, создана сводная ОСВ, запись переходит в статус CREATED (черновик)
|