From 4b32b3602f2e62551eaf3e5cb8f7f13bfce65420 Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Tue, 27 Oct 2026 01:19:37 +0400 Subject: [PATCH] =?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-