From 4b32b3602f2e62551eaf3e5cb8f7f13bfce65420 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Tue, 27 Oct 2026 01:19:37 +0400 Subject: [PATCH 1/2] =?UTF-8?q?test(osv):=20=D1=81=D0=B8=D0=BD=D1=82=D0=B5?= =?UTF-8?q?=D1=82=D0=B8=D0=BA=D0=B0=20s45=20=E2=80=94=20=D1=81=D1=87=D1=91?= =?UTF-8?q?=D1=82=20=D1=88=D0=B0=D0=BF=D0=BA=D0=B8=20=C2=AB=D0=A1=D1=87?= =?UTF-8?q?=D0=B5=D1=82=20=D0=9F=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D1=89=D0=B8?= =?UTF-8?q?=D0=BA=D0=B0=20|=2060*=C2=BB=20=D0=B8=20=D0=B3=D0=BE=D0=BB?= =?UTF-8?q?=D1=8B=D0=B5=20=D0=BA=D0=BE=D0=B4=D1=8B=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D1=82=D1=80=D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=BE=D0=B2=20(tabul?= =?UTF-8?q?ar-parser#71)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- .../s45_account_label_value_cells.json | 162 ++++++++++++++++++ osv/synthetic/README.md | 1 + .../s45_account_label_value_cells.xlsx | Bin 0 -> 5304 bytes 3 files changed, 163 insertions(+) create mode 100644 golden/expected_osv_parse/synthetic/s45_account_label_value_cells.json create mode 100644 osv/synthetic/s45_account_label_value_cells.xlsx diff --git a/golden/expected_osv_parse/synthetic/s45_account_label_value_cells.json b/golden/expected_osv_parse/synthetic/s45_account_label_value_cells.json new file mode 100644 index 0000000..3553eaf --- /dev/null +++ b/golden/expected_osv_parse/synthetic/s45_account_label_value_cells.json @@ -0,0 +1,162 @@ +{ + "schema_version": "2.0", + "service": { + "name": "tabular-parser" + }, + "status": "done", + "metrics": { + "rows": 3, + "warnings": [] + }, + "documents": [ + { + "document_type": "OSV", + "locator": "sheet:Лист_1", + "status": "done", + "warnings": [ + { + "code": "OSV_HIERARCHY_BY_HEADER_ACCOUNT", + "severity": "info", + "message": "иерархия строк — плоский список под счётом шапки (header_account)" + }, + { + "code": "OSV_HEADER", + "severity": "info", + "message": "период (после «за» или «Период:») в шапке не найден" + }, + { + "code": "OSV_HEADER", + "severity": "info", + "message": "тип выводимых данных (БУ/НУ/сумма) в шапке не найден" + }, + { + "code": "OSV_HEADER", + "severity": "info", + "message": "валюта в шапке не найдена" + }, + { + "code": "OSV_HEADER", + "severity": "info", + "message": "вид данных в шапке не указан — строки без метки приняты как БУ" + }, + { + "code": "OSV_ROWS", + "severity": "info", + "message": "вид субконто в шапке не назван: строки аналитики счёта 60 приняты за контрагентов по плану счетов — проверьте" + } + ], + "header": { + "organization_name": "За период", + "organization_inn": null, + "account_code_raw": "60", + "period_text": "", + "period_year": null, + "period_quarter": null, + "is_cumulative": null, + "period_start": null, + "period_end": null, + "is_from_year_start": null, + "data_type": null, + "currency": null, + "header_variant": 1 + }, + "group_schema": [ + { + "type": "ACCOUNT", + "name": "Субконто" + } + ], + "columns": { + "opening_debit": "B", + "opening_credit": "C", + "turnover_debit": "D", + "turnover_credit": "E", + "closing_debit": "F", + "closing_credit": "G" + }, + "rows": [ + { + "row_number": 8, + "level": 0, + "parent_row_number": null, + "row_value": "441", + "group_type": "COUNTERPARTY", + "group_name": null, + "account_code_raw": "60", + "counterparty_name": "441", + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "108000.00", + "turnover_debit": "108000.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 9, + "level": 0, + "parent_row_number": null, + "row_value": "431", + "group_type": "COUNTERPARTY", + "group_name": null, + "account_code_raw": "60", + "counterparty_name": "431", + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "200.00", + "turnover_debit": "200.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 10, + "level": 0, + "parent_row_number": null, + "row_value": "199", + "group_type": "COUNTERPARTY", + "group_name": null, + "account_code_raw": "60", + "counterparty_name": "199", + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "50.00", + "turnover_debit": "50.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 11, + "level": 0, + "parent_row_number": null, + "row_value": "Итого", + "group_type": "TOTAL", + "group_name": null, + "account_code_raw": null, + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "108250.00", + "turnover_debit": "108250.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "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 b527857..883001d 100644 --- a/osv/synthetic/README.md +++ b/osv/synthetic/README.md @@ -62,6 +62,7 @@ cd tabular-parser/api | `s42_subaccounts_totals_reversed.xlsx` | под счётом 76 в шапке идут строки-субсчета «76.2», «76.5», «76.Н», «76.Н.1» (корня «76» нет), «Итого развернутое» перед «Итого» | `account_code_raw=76`, «Итого развернутое» — `TOTAL`, сверка по основной «Итого», `done` | | `s43_subkonto_unnamed_60.xlsx` | счёт 60: корень «60.01» и два элемента аналитики с отступом, вид субконто в шапке не назван; «Итого» перед «Итого развернутое» | `hierarchy=indent`, подстроки — `COUNTERPARTY` по плану счетов с предупреждением `OSV_ROWS`, `done` | | `s44_subkonto_unnamed_10.xlsx` | то же, что `s43`, но счёт 10 (материалы «Мука пшеничная», «Сахар-песок») | счёт 10 не расчётный: подстроки остаются `OTHER` без имени, предупреждения нет, `done` | +| `s45_account_label_value_cells.xlsx` | выгрузка 1С «ОСВ по счёту 60 по контрагентам» (tabular-parser#71, AURORA-1714): слов «по счету» нет, счёт — «Счет Поставщика» \| «60*» в соседних ячейках, «Счет Клиента» без значения; в первой колонке голые числовые коды 441, 431, 199 | `account_code_raw=60`, голые коды не счета, строки `COUNTERPARTY`, `done` | `s17`–`s19` — регрессия извлечения ИНН из текста (issue #9). `s14`–`s16` добавлены тестом покрытия словарей `tabular-parser` (`rules/*.yaml`, решение R-22): каждая запись словаря должна сработать на реальных или синтетических файлах; эти файлы закрывают записи, которых нет в реальных ОСВ. diff --git a/osv/synthetic/s45_account_label_value_cells.xlsx b/osv/synthetic/s45_account_label_value_cells.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7425649d8ab6cad40daac8ef8a7ac324b281ad49 GIT binary patch literal 5304 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�wSM|<(f|8;`?Kwg3Rr_u7YB6`LF@}a{AuT`;2a4^t zr?Kj4(F6s3xIvlRD&xJBLI-irua-v~E#jJ0H>Mm2$>!^^1Glp5cgms$6ygR<#5bT; zsQJ6lWf$TLeKD;w)`FM&*u7Q5Oh=wMcfT3adXwaS`{FwTD@^RuA`V}bhRLF*Mhr{} ztpBYtp`+&SPY{~n|F1dSMBfy6eqsTDAdH@WqyHoK+=Sm$J$}Ja=)eCj8purpH>ciz z3~_H^Dda{1;ddtrVg+{6Dh(rk$Iq^ve!4TCV#qiKVTMgBGdKrwsHZgD&Y- Date: Tue, 27 Oct 2026 10:39:06 +0400 Subject: [PATCH 2/2] =?UTF-8?q?test(osv):=20=D1=81=D0=B8=D0=BD=D1=82=D0=B5?= =?UTF-8?q?=D1=82=D0=B8=D0=BA=D0=B0=20s46=20(=D0=B1=D0=BB=D0=BE=D0=BA?= =?UTF-8?q?=D0=B8=20=D1=81=D1=83=D0=B1=D1=81=D1=87=D0=B5=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=20=D1=81=20=D0=BA=D0=BE=D0=B4=D0=B0=D0=BC=D0=B8=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D1=82=D1=80=D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D0=BE=D0=B2),?= =?UTF-8?q?=20s45=20=D1=81=20=D0=BF=D0=B5=D1=80=D0=B8=D0=BE=D0=B4=D0=BE?= =?UTF-8?q?=D0=BC=20=D0=B8=20=D0=BE=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B5=D0=B9,=20golden=20(tabular-parser#71)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- .../s45_account_label_value_cells.json | 21 +- .../s46_counterparty_code_blocks.json | 270 ++++++++++++++++++ osv/synthetic/README.md | 3 +- .../s45_account_label_value_cells.xlsx | Bin 5304 -> 5360 bytes .../s46_counterparty_code_blocks.xlsx | Bin 0 -> 5651 bytes 5 files changed, 280 insertions(+), 14 deletions(-) create mode 100644 golden/expected_osv_parse/synthetic/s46_counterparty_code_blocks.json create mode 100644 osv/synthetic/s46_counterparty_code_blocks.xlsx diff --git a/golden/expected_osv_parse/synthetic/s45_account_label_value_cells.json b/golden/expected_osv_parse/synthetic/s45_account_label_value_cells.json index 3553eaf..3fd605b 100644 --- a/golden/expected_osv_parse/synthetic/s45_account_label_value_cells.json +++ b/golden/expected_osv_parse/synthetic/s45_account_label_value_cells.json @@ -19,11 +19,6 @@ "severity": "info", "message": "иерархия строк — плоский список под счётом шапки (header_account)" }, - { - "code": "OSV_HEADER", - "severity": "info", - "message": "период (после «за» или «Период:») в шапке не найден" - }, { "code": "OSV_HEADER", "severity": "info", @@ -46,16 +41,16 @@ } ], "header": { - "organization_name": "За период", + "organization_name": "ООО \"Тестовая организация\"", "organization_inn": null, "account_code_raw": "60", - "period_text": "", - "period_year": null, - "period_quarter": null, - "is_cumulative": null, - "period_start": null, - "period_end": null, - "is_from_year_start": null, + "period_text": "01.01.25..30.06.25", + "period_year": 2025, + "period_quarter": "Q2", + "is_cumulative": true, + "period_start": "2025-01-01", + "period_end": "2025-06-30", + "is_from_year_start": true, "data_type": null, "currency": null, "header_variant": 1 diff --git a/golden/expected_osv_parse/synthetic/s46_counterparty_code_blocks.json b/golden/expected_osv_parse/synthetic/s46_counterparty_code_blocks.json new file mode 100644 index 0000000..04a1b15 --- /dev/null +++ b/golden/expected_osv_parse/synthetic/s46_counterparty_code_blocks.json @@ -0,0 +1,270 @@ +{ + "schema_version": "2.0", + "service": { + "name": "tabular-parser" + }, + "status": "done", + "metrics": { + "rows": 9, + "warnings": [] + }, + "documents": [ + { + "document_type": "OSV", + "locator": "sheet:Лист_1", + "status": "done", + "warnings": [ + { + "code": "OSV_HIERARCHY_BY_CODE_BLOCKS", + "severity": "info", + "message": "иерархия строк — блоки субсчетов с кодами контрагентов (code_blocks)" + }, + { + "code": "OSV_HEADER", + "severity": "info", + "message": "тип выводимых данных (БУ/НУ/сумма) в шапке не найден" + }, + { + "code": "OSV_HEADER", + "severity": "info", + "message": "валюта в шапке не найдена" + }, + { + "code": "OSV_HEADER", + "severity": "info", + "message": "вид данных в шапке не указан — строки без метки приняты как БУ" + } + ], + "header": { + "organization_name": "ООО \"Тестовая организация\"", + "organization_inn": null, + "account_code_raw": "60", + "period_text": "01.01.25..30.06.25", + "period_year": 2025, + "period_quarter": "Q2", + "is_cumulative": true, + "period_start": "2025-01-01", + "period_end": "2025-06-30", + "is_from_year_start": true, + "data_type": null, + "currency": null, + "header_variant": 1 + }, + "group_schema": [ + { + "type": "ACCOUNT", + "name": "Субконто" + }, + { + "type": "COUNTERPARTY", + "name": "Поставщики" + } + ], + "columns": { + "opening_debit": "B", + "opening_credit": "C", + "turnover_debit": "D", + "turnover_credit": "E", + "closing_debit": "F", + "closing_credit": "G" + }, + "rows": [ + { + "row_number": 9, + "level": 0, + "parent_row_number": null, + "row_value": "60.111", + "group_type": "ACCOUNT", + "group_name": "Субконто", + "account_code_raw": "60.111", + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "150.00", + "turnover_debit": "170.00", + "turnover_credit": "20.00", + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 10, + "level": 1, + "parent_row_number": 9, + "row_value": "П005482", + "group_type": "COUNTERPARTY", + "group_name": "Поставщики", + "account_code_raw": "60.111", + "counterparty_name": "ВЕСТ БИР ООО", + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "100.00", + "turnover_debit": "100.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 12, + "level": 2, + "parent_row_number": 10, + "row_value": "ДП87825;З-139/21-1", + "group_type": "CONTRACT", + "group_name": null, + "account_code_raw": "60.111", + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "100.00", + "turnover_debit": "100.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 13, + "level": 1, + "parent_row_number": 9, + "row_value": "П002913", + "group_type": "COUNTERPARTY", + "group_name": "Поставщики", + "account_code_raw": "60.111", + "counterparty_name": "М ДИСТРИБЬЮШН", + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "50.00", + "turnover_debit": "70.00", + "turnover_credit": "20.00", + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 15, + "level": 2, + "parent_row_number": 13, + "row_value": "ДП60469;З-46/20", + "group_type": "CONTRACT", + "group_name": null, + "account_code_raw": "60.111", + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "20.00", + "turnover_debit": "30.00", + "turnover_credit": "10.00", + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 16, + "level": 2, + "parent_row_number": 13, + "row_value": "441", + "group_type": "CONTRACT", + "group_name": null, + "account_code_raw": "60.111", + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "30.00", + "turnover_debit": "40.00", + "turnover_credit": "10.00", + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 18, + "level": 0, + "parent_row_number": null, + "row_value": "60.112", + "group_type": "ACCOUNT", + "group_name": "Субконто", + "account_code_raw": "60.112", + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "10.00", + "turnover_debit": "10.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 19, + "level": 1, + "parent_row_number": 18, + "row_value": "П003258", + "group_type": "COUNTERPARTY", + "group_name": "Поставщики", + "account_code_raw": "60.112", + "counterparty_name": "ООО \"РОМАШКА\"", + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "10.00", + "turnover_debit": "10.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 21, + "level": 2, + "parent_row_number": 19, + "row_value": "ДП1;1", + "group_type": "CONTRACT", + "group_name": null, + "account_code_raw": "60.112", + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "10.00", + "turnover_debit": "10.00", + "turnover_credit": null, + "closing_debit": null, + "closing_credit": null, + "extra": null + }, + { + "row_number": 23, + "level": 0, + "parent_row_number": null, + "row_value": "ИТОГ", + "group_type": "TOTAL", + "group_name": null, + "account_code_raw": null, + "counterparty_name": null, + "counterparty_inn": null, + "data_type": "BU", + "opening_debit": null, + "opening_credit": "160.00", + "turnover_debit": "180.00", + "turnover_credit": "20.00", + "closing_debit": null, + "closing_credit": null, + "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 883001d..3c1d262 100644 --- a/osv/synthetic/README.md +++ b/osv/synthetic/README.md @@ -62,7 +62,8 @@ cd tabular-parser/api | `s42_subaccounts_totals_reversed.xlsx` | под счётом 76 в шапке идут строки-субсчета «76.2», «76.5», «76.Н», «76.Н.1» (корня «76» нет), «Итого развернутое» перед «Итого» | `account_code_raw=76`, «Итого развернутое» — `TOTAL`, сверка по основной «Итого», `done` | | `s43_subkonto_unnamed_60.xlsx` | счёт 60: корень «60.01» и два элемента аналитики с отступом, вид субконто в шапке не назван; «Итого» перед «Итого развернутое» | `hierarchy=indent`, подстроки — `COUNTERPARTY` по плану счетов с предупреждением `OSV_ROWS`, `done` | | `s44_subkonto_unnamed_10.xlsx` | то же, что `s43`, но счёт 10 (материалы «Мука пшеничная», «Сахар-песок») | счёт 10 не расчётный: подстроки остаются `OTHER` без имени, предупреждения нет, `done` | -| `s45_account_label_value_cells.xlsx` | выгрузка 1С «ОСВ по счёту 60 по контрагентам» (tabular-parser#71, AURORA-1714): слов «по счету» нет, счёт — «Счет Поставщика» \| «60*» в соседних ячейках, «Счет Клиента» без значения; в первой колонке голые числовые коды 441, 431, 199 | `account_code_raw=60`, голые коды не счета, строки `COUNTERPARTY`, `done` | +| `s45_account_label_value_cells.xlsx` | выгрузка 1С «ОСВ по счёту 60 по контрагентам» (tabular-parser#71, AURORA-1714): слов «по счету» нет, счёт — «Счет Поставщика» \| «60*» в соседних ячейках, «Счет Клиента» без значения; в первой колонке голые числовые коды 441, 431, 199; период «За период» \| «01.01.25..30.06.25» | `account_code_raw=60`, 2025 Q2 нарастающий, голые коды не счета, строки `COUNTERPARTY`, `done` | +| `s46_counterparty_code_blocks.xlsx` | та же выгрузка целиком: вид субконто «Поставщики» в колонке суммы первой строки данных; блоки субсчетов 60.111, 60.112 (сумм в строке нет); в блоке — код контрагента с суммами, строка названия без сумм, договоры (в том числе «441»); «ИТОГ по 60.111» с суммами блока; в конце «ИТОГ» | `hierarchy=code_blocks`, субсчета `ACCOUNT` с суммами из «ИТОГ по …», коды — `COUNTERPARTY` с названием, договоры — `CONTRACT`, строки «ИТОГ по …», названий и «Поставщики» в `rows` нет, «ИТОГ» — `TOTAL`, `done` | `s17`–`s19` — регрессия извлечения ИНН из текста (issue #9). `s14`–`s16` добавлены тестом покрытия словарей `tabular-parser` (`rules/*.yaml`, решение R-22): каждая запись словаря должна сработать на реальных или синтетических файлах; эти файлы закрывают записи, которых нет в реальных ОСВ. diff --git a/osv/synthetic/s45_account_label_value_cells.xlsx b/osv/synthetic/s45_account_label_value_cells.xlsx index 7425649d8ab6cad40daac8ef8a7ac324b281ad49..6813c05157bb5ed21ae1b8f5a410ffaa69261b7c 100644 GIT binary patch delta 913 zcmV;C18)4dDex(<{X0FzD=8h@Qu-EP`26n+&eSKFi!CqN1a zkOs8fE+$p2wq2)SAZik`#FXxC?W9iAs`X~lre18?o`C*oRlBlRaNcOg4g_dps#YLk z`<(NA-#IopE)Qt16?O?>XvcH?u%dMt>y>mpY<7ufhZ))b= z zc?sC0ZYY1zAa>4yce5Wd>W!m;*mL~&Y41#`p~r!ewqY~7S`O#{1;Pw)VjvU)kK>CX zZ?FK?9f)96{zH6_#((qkXgAv9BYwh%(IMia=siE>Lw?OK_#ar>=NHkTR@NEtiCDck z#(%CYz&@5RBf!1pqo>g>;9W%r{A@~d!q4UOFL(iebTH4LLncW&W|EGnpfvIbWPSmX zLu6tz|Hvqma`=`AB%NAT zrR7)j5rpg^{xdEQ)bAwv1iCKyFin>V$bZ6576{2DLUMNsIpSA9f6lLkm<5MZMI(B-J5S*={`~i)yDpqE;FSSq&CGgCdjXooB^6xqfEB6p7lLfT> zg%alqxs+_ql8Wam?8mX#p0p#Oj5-2(@!z{hjcYuJZTW$0D-U8@y+7MrX$#32Eq^G0 zaycWdrm?$dVB1v#7cjf^Aa$mVS!3p`>m`b^LCNYIhJK15C0_gVac zPFCX!MZ+pBTe9iiFx0G4J=L&cl{i*ogFa=5Z!jP?L-lCI*}m00000)K98> delta 846 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 literal 0 HcmV?d00001 -- 2.47.2