From 0268b5343c26c21aaae84d4c6cc8fedef60a722e Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 18 Oct 2026 12:04:48 +0400 Subject: [PATCH] =?UTF-8?q?Golden:=20rb/2024-Q1=20=D0=B1=D0=B5=D0=B7=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B5=D0=B4=D1=83=D0=BF=D1=80=D0=B5=D0=B6=D0=B4?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE=20=D1=85=D0=B2=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B5,=20=D1=81=D0=B8=D0=BD=D1=82=D0=B5=D1=82=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0=20s32=20(tabular-parser=20#47,=20AURORA-1664)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 --- .../rb/2024-Q1/сч 60_ 1 кв 2024 г.json | 3 +- .../synthetic/s32_total_with_suffix.json | 251 ++++++++++++++++++ osv/synthetic/README.md | 3 +- osv/synthetic/s32_total_with_suffix.xlsx | Bin 0 -> 5810 bytes 4 files changed, 254 insertions(+), 3 deletions(-) create mode 100644 golden/expected_osv_parse/synthetic/s32_total_with_suffix.json create mode 100644 osv/synthetic/s32_total_with_suffix.xlsx diff --git a/golden/expected_osv_parse/rb/2024-Q1/сч 60_ 1 кв 2024 г.json b/golden/expected_osv_parse/rb/2024-Q1/сч 60_ 1 кв 2024 г.json index 63dfa1e..17f7610 100644 --- a/golden/expected_osv_parse/rb/2024-Q1/сч 60_ 1 кв 2024 г.json +++ b/golden/expected_osv_parse/rb/2024-Q1/сч 60_ 1 кв 2024 г.json @@ -7,8 +7,7 @@ "metrics": { "rows": 612, "warnings": [ - "sheet=Лист_1 hierarchy=outline", - "строки 625–626: ниже таблицы (после «Итого») есть числа — строки ниже «Итого» вне документа и не разобраны" + "sheet=Лист_1 hierarchy=outline" ] }, "documents": [ diff --git a/golden/expected_osv_parse/synthetic/s32_total_with_suffix.json b/golden/expected_osv_parse/synthetic/s32_total_with_suffix.json new file mode 100644 index 0000000..a16d888 --- /dev/null +++ b/golden/expected_osv_parse/synthetic/s32_total_with_suffix.json @@ -0,0 +1,251 @@ +{ + "schema_version": "1.2", + "service": { + "name": "tabular-parser" + }, + "status": "done", + "metrics": { + "rows": 9, + "warnings": [ + "sheet=Лист_1 hierarchy=outline" + ] + }, + "documents": [ + { + "document_type": "OSV", + "locator": "sheet:Лист_1", + "header": { + "organization_name": "ООО \"Тестовая организация\"", + "organization_inn": null, + "account_code_raw": "60", + "period_text": "1 квартал 2025 г.", + "period_year": 2025, + "period_quarter": "Q1", + "is_cumulative": true, + "period_start": "2025-01-01", + "period_end": "2025-03-31", + "is_from_year_start": true, + "data_type": "BU", + "currency": "RUB", + "header_variant": 1 + }, + "group_schema": [ + { + "type": "ACCOUNT", + "name": "Счет" + }, + { + "type": "COUNTERPARTY", + "name": "Контрагенты", + "has_inn": true + } + ], + "columns": { + "opening_debit": "G", + "opening_credit": "H", + "turnover_debit": "I", + "turnover_credit": "J", + "closing_debit": "K", + "closing_credit": "L", + "inn": "E" + }, + "rows": [ + { + "row_number": 11, + "level": 0, + "parent_row_number": null, + "row_value": "60", + "group_type": "ACCOUNT", + "group_name": "Счет", + "account_code_raw": "60", + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": "135000.00", + "opening_credit": "262500.60", + "turnover_debit": "311000.35", + "turnover_credit": "572000.35", + "closing_debit": "115000.00", + "closing_credit": "503500.60", + "extra": null + }, + { + "row_number": 12, + "level": 1, + "parent_row_number": 11, + "row_value": "60.01", + "group_type": "ACCOUNT", + "group_name": "Счет", + "account_code_raw": "60.01", + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": "15000.00", + "opening_credit": "253000.50", + "turnover_debit": "273000.25", + "turnover_credit": "460000.00", + "closing_debit": "65000.00", + "closing_credit": "490000.25", + "extra": null + }, + { + "row_number": 13, + "level": 2, + "parent_row_number": 12, + "row_value": "ООО Альфа", + "group_type": "COUNTERPARTY", + "group_name": "Контрагенты", + "account_code_raw": "60.01", + "counterparty_name": "ООО Альфа", + "counterparty_inn": "7701234567", + "data_type": "BU", + "opening_debit": null, + "opening_credit": "250000.50", + "turnover_debit": "180000.25", + "turnover_credit": "420000.00", + "closing_debit": null, + "closing_credit": "490000.25", + "extra": null + }, + { + "row_number": 14, + "level": 2, + "parent_row_number": 12, + "row_value": "ООО Бета", + "group_type": "COUNTERPARTY", + "group_name": "Контрагенты", + "account_code_raw": "60.01", + "counterparty_name": "ООО Бета", + "counterparty_inn": "7707654321", + "data_type": "BU", + "opening_debit": "15000.00", + "opening_credit": null, + "turnover_debit": "90000.00", + "turnover_credit": "40000.00", + "closing_debit": "65000.00", + "closing_credit": null, + "extra": null + }, + { + "row_number": 15, + "level": 2, + "parent_row_number": 12, + "row_value": "Иванов Иван", + "group_type": "COUNTERPARTY", + "group_name": "Контрагенты", + "account_code_raw": "60.01", + "counterparty_name": "Иванов Иван", + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "3000.00", + "turnover_debit": "3000.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 16, + "level": 1, + "parent_row_number": 11, + "row_value": "60.02", + "group_type": "ACCOUNT", + "group_name": "Счет", + "account_code_raw": "60.02", + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": "120000.00", + "opening_credit": "9500.10", + "turnover_debit": "38000.10", + "turnover_credit": "112000.35", + "closing_debit": "50000.00", + "closing_credit": "13500.35", + "extra": null + }, + { + "row_number": 17, + "level": 2, + "parent_row_number": 16, + "row_value": "ООО Гамма", + "group_type": "COUNTERPARTY", + "group_name": "Контрагенты", + "account_code_raw": "60.02", + "counterparty_name": "ООО Гамма", + "counterparty_inn": "5001234567", + "data_type": "BU", + "opening_debit": "120000.00", + "opening_credit": null, + "turnover_debit": "30000.00", + "turnover_credit": "100000.00", + "closing_debit": "50000.00", + "closing_credit": null, + "extra": null + }, + { + "row_number": 18, + "level": 2, + "parent_row_number": 16, + "row_value": "ООО Дельта", + "group_type": "COUNTERPARTY", + "group_name": "Контрагенты", + "account_code_raw": "60.02", + "counterparty_name": "ООО Дельта", + "counterparty_inn": "7812345678", + "data_type": "BU", + "opening_debit": null, + "opening_credit": "8000.10", + "turnover_debit": "8000.10", + "turnover_credit": "12000.35", + "closing_debit": null, + "closing_credit": "12000.35", + "extra": null + }, + { + "row_number": 19, + "level": 2, + "parent_row_number": 16, + "row_value": "ИП Сидоров", + "group_type": "COUNTERPARTY", + "group_name": "Контрагенты", + "account_code_raw": "60.02", + "counterparty_name": "ИП Сидоров", + "counterparty_inn": "500100732259", + "data_type": "BU", + "opening_debit": null, + "opening_credit": "1500.00", + "turnover_debit": null, + "turnover_credit": null, + "closing_debit": null, + "closing_credit": "1500.00", + "extra": null + }, + { + "row_number": 20, + "level": 0, + "parent_row_number": null, + "row_value": "Итого по счету 60", + "group_type": "TOTAL", + "group_name": null, + "account_code_raw": null, + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": "135000.00", + "opening_credit": "262500.60", + "turnover_debit": "311000.35", + "turnover_credit": "572000.35", + "closing_debit": "115000.00", + "closing_credit": "503500.60", + "extra": null + } + ], + "checks": { + "total_row_matches_root": true, + "balance_identity_violations": [], + "parent_sum_violations": [] + } + } + ] +} diff --git a/osv/synthetic/README.md b/osv/synthetic/README.md index 9ae48cc..96289ea 100644 --- a/osv/synthetic/README.md +++ b/osv/synthetic/README.md @@ -56,11 +56,12 @@ cd tabular-parser/api | `s29_xls_no_codepage.xls` | xls BIFF5 без записи CODEPAGE, строки в cp1251 (собран `tests/synthetic/xls_writer.py`); отступ — ведущими пробелами (AURORA-1662) | кириллица читается как cp1251, предупреждение «xls без кодовой страницы — строки прочитаны как cp1251», `done` | | `s30_val_kol_vo_materials.xlsx` | счёт 10 (вариант 2, номенклатура): материал «Вал» без точки, под материалами строки «Кол-во» (AURORA-1663) | «Вал» — обычная строка (`data_type` шапки, `OTHER`), «Кол-во» — `QUANTITY`, `done` | | `s31_rows_below_total.xlsx` | под «Итого» дописаны «Ответственный:», блок «ООО Альфа (ГК)» с числами и строка «Итого по ГК» (AURORA-1664) | таблица кончается на первой «Итого», хвост вне документа, предупреждение «ниже таблицы … есть числа», `done` | +| `s32_total_with_suffix.xlsx` | итоговая строка подписана «Итого по счету 60», точного «Итого» нет (I-1: правило `total_row` — запасное после `total_row_exact`) | `TOTAL` — последняя строка, `done` | `s17`–`s19` — регрессия извлечения ИНН из текста (issue #9). `s14`–`s16` добавлены тестом покрытия словарей `tabular-parser` (`rules/*.yaml`, решение R-22): каждая запись словаря должна сработать на реальных или синтетических файлах; эти файлы закрывают записи, которых нет в реальных ОСВ. -`s29`–`s31` — tabular-parser#47 (кодировка xls без CODEPAGE, «Вал»/«Кол-во», строки ниже «Итого»). +`s29`–`s32` — tabular-parser#47 (кодировка xls без CODEPAGE, «Вал»/«Кол-во», строки ниже «Итого», итог «Итого по счету»). `s20`–`s27` — восемь раскладок строки ИНН рядом с контрагентом (issue tabular-parser#35); ИНН с верной контрольной суммой — без подсказки в шапке другие не склеиваются. diff --git a/osv/synthetic/s32_total_with_suffix.xlsx b/osv/synthetic/s32_total_with_suffix.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..af171c2bb0a6ae284b7590165ae28c1ba161c70a GIT binary patch literal 5810 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 literal 0 HcmV?d00001