ОСВ: запасной признак проверяет ту строку групп, что возьмёт разбор (#81, ревью I-1)
Преамбула «Обороты: …» над шапкой давала ОСВ, разбор листа падал и ронял книгу. Негатив s56 «Преамбула». Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
f7cb32e3d4
commit
57c22547be
@ -184,17 +184,21 @@ def has_osv_table(sheet: Sheet, rules: Rules) -> bool:
|
||||
"""Запасной признак листа ОСВ без названия ведомости (#81, design D1): в первых `SHEET_MARKER_ROWS` строках есть
|
||||
строка со всеми тремя группами сумм, и у каждой группы — колонки «Дебет» и «Кредит» (свёрнутое сальдо не годится,
|
||||
R-3), между которыми в строках заголовка нет других подписей (R-11: у отчёта 1С «Обороты счета» между «Оборот Дт» и
|
||||
«Оборот Кт» — колонки корр. счетов, это не ОСВ). Колонки ищутся тем же разбором, что у обычного заголовка (R-6)."""
|
||||
«Оборот Кт» — колонки корр. счетов, это не ОСВ). Проверяется та строка групп, которую возьмёт `find_table_header`
|
||||
(первая с «оборотами» и «концом»), — иначе преамбула «Обороты: …» над шапкой уронила бы разбор листа; колонки
|
||||
ищутся тем же разбором, что у обычного заголовка (R-6)."""
|
||||
for row in range(1, min(sheet.n_rows, SHEET_MARKER_ROWS) + 1):
|
||||
cells = _group_cells(sheet, row, rules)
|
||||
if {cell.group for cell in cells} != set(GROUP_ORDER):
|
||||
groups = {cell.group for cell in cells}
|
||||
if not REQUIRED_GROUPS <= groups:
|
||||
continue
|
||||
if groups != set(GROUP_ORDER):
|
||||
return False
|
||||
try:
|
||||
groups = [_columns_of_group(sheet, row, cells, group, rules) for group in GROUP_ORDER]
|
||||
columns = [_columns_of_group(sheet, row, cells, group, rules) for group in GROUP_ORDER]
|
||||
except InvalidFormatError:
|
||||
continue
|
||||
if all(_sides_side_by_side(sheet, row, columns) for columns in groups):
|
||||
return True
|
||||
return False
|
||||
return all(_sides_side_by_side(sheet, row, group_columns) for group_columns in columns)
|
||||
return False
|
||||
|
||||
|
||||
|
||||
@ -1359,9 +1359,19 @@ def _s56() -> list[SheetSpec]:
|
||||
],
|
||||
),
|
||||
_navision_sheet("Ниже 30", top_padding=30),
|
||||
_preamble_navision_sheet(),
|
||||
]
|
||||
|
||||
|
||||
def _preamble_navision_sheet() -> SheetSpec:
|
||||
"""Полная шапка Navision, над ней преамбула «Обороты за период: … | Остаток на конец: …»: разбор берёт строку
|
||||
преамбулы, значит, и запасной признак смотрит её — лист прочий, книга не падает (ревью #81, Important-1)."""
|
||||
sheet = _navision_sheet("Преамбула", top_padding=1)
|
||||
sheet.put(1, 1, "Обороты за период: 50")
|
||||
sheet.put(1, 2, "Остаток на конец: 150")
|
||||
return sheet
|
||||
|
||||
|
||||
def _s57() -> list[SheetSpec]:
|
||||
"""Негатив: форма ББ с примечанием «см. оборотную ведомость …» и текстом «Остаток на начало периода …», за ней
|
||||
лист слабого продолжения (одна строка с кодом) — форма и продолжение остаются формой."""
|
||||
|
||||
@ -955,7 +955,13 @@ def test_neg_s56_almost_osv_tables_are_other(fixtures_dir: Path) -> None:
|
||||
outcome = parse_named(fixtures_dir, S56)
|
||||
|
||||
assert [doc.locator for doc in documents(outcome)] == ["sheet:ОСВ 60"]
|
||||
assert sheet_other(outcome) == ["sheet:Расшифровка", "sheet:Без начала", "sheet:Свёрнутое начало", "sheet:Ниже 30"]
|
||||
assert sheet_other(outcome) == [
|
||||
"sheet:Расшифровка",
|
||||
"sheet:Без начала",
|
||||
"sheet:Свёрнутое начало",
|
||||
"sheet:Ниже 30",
|
||||
"sheet:Преамбула",
|
||||
]
|
||||
|
||||
|
||||
def test_neg_s57_form_with_osv_words_stays_form(fixtures_dir: Path) -> None:
|
||||
|
||||
@ -170,6 +170,23 @@ def test_has_osv_table_only_first_rows(rules: Rules, blank_rows: int, expected:
|
||||
assert has_osv_table(sheet, rules) is expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"preamble",
|
||||
[
|
||||
["Обороты за период: 50", "Остаток на конец: 150"],
|
||||
["Остаток на начало: 100", "Обороты: 50", "Остаток на конец: 150"],
|
||||
],
|
||||
)
|
||||
def test_has_osv_table_checks_the_row_find_table_header_takes(rules: Rules, preamble: list[object]) -> None:
|
||||
"""Финальное ревью, Important-1: преамбула с «оборотами» над полной шапкой — строка, которую возьмёт разбор
|
||||
(`find_table_header`); она не годится, значит, лист не ОСВ (иначе разбор листа упадёт и уронит книгу)."""
|
||||
sheet = sheet_from_rows([preamble, NAVISION_HEADER, NAVISION_ROW])
|
||||
|
||||
with pytest.raises(InvalidFormatError):
|
||||
find_table_header(sheet, rules)
|
||||
assert has_osv_table(sheet, rules) is False
|
||||
|
||||
|
||||
def test_classify_sheet_falls_back_to_table(rules: Rules) -> None:
|
||||
assert classify_sheet(sheet_from_rows([NAVISION_HEADER, NAVISION_ROW]), rules) is SheetKind.OSV
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@ xlsb) на main `a8c9605` и на ветке. Сравнение по каждо
|
||||
| 2026-10-28 | R-2. Запасной признак ищет строку групп только в первых `SHEET_MARKER_ROWS` (30) строках | у безымянных листов таблица начинается сразу; ограничение снижает время и ложные срабатывания на длинных листах «прочее» | безымянный лист с преамбулой длиннее 30 строк не распознаётся; поднимется регрессией D3 |
|
||||
| 2026-10-28 | R-3. Запасной признак не принимает свёрнутое сальдо (одна колонка в группе) | строгость против ложных ОСВ (D1) | ОСВ без названия со свёрнутым сальдо не распознаётся |
|
||||
| 2026-10-28 | R-5. Новые `sheet_markers` якорятся к началу ячейки (`^…`); якорь снимается для конкретного названия, только если по спискам 1717 файлы с ним иначе не находятся | «Оборотная ведомость», «Оборотный баланс» могут встретиться в примечаниях к ББ; признак по названию проверяется раньше форм | часть ведомостей с текстом перед названием не распознаётся; видно в регрессии D3 |
|
||||
| 2026-10-28 | R-6. Запасной признак переиспользует поиск строки групп и колонок обычного заголовка (`_find_group_row`, `_columns_of_group`) в строгом режиме, а не отдельную функцию | запасной признак и конвейер не должны расходиться в том, что считать заголовком | — |
|
||||
| 2026-10-28 | R-6. Запасной признак проверяет ту же строку групп, что возьмёт `find_table_header` (первую с «оборотами» и «концом» в первых 30 строках), и колонки ищет тем же `_columns_of_group`; строгие условия — только к этой строке (финальное ревью, I-1: иначе преамбула «Обороты: …» над шапкой давала ОСВ, разбор падал и ронял книгу; негатив s56 «Преамбула») | запасной признак и конвейер не должны расходиться в том, что считать заголовком | безымянная ОСВ с преамбулой «Обороты: …» над шапкой не распознаётся |
|
||||
| 2026-10-28 | R-7. Порядок PR: `fixtures` (golden синтетики, отдельный коммит `make golden-update`) → tabular-parser → docs | golden-тесты tabular-parser читают `../fixtures` | — |
|
||||
| 2026-10-28 | R-8. Приёмка — синтетика + `make check-full` + нет ухудшений D3; число исправленных файлов банка — отчёт, не порог | эксперимент автора задач — ориентир, а не обязательство; остаток держат 1720–1723 | — |
|
||||
| 2026-10-28 | R-9. Написание «Остаток по дебету/кредиту на начало/конец» (6 файлов КТЗ/ЧАЗ) включено в словарь: группа «остаток» с опережающей проверкой, сторона — из остатка ячейки | та же семья «Остаток на начало/конец» (1719), решается записью словаря | лишняя запись, удаляется |
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user