..

osv/synthetic — синтетические ОСВ

Синтетика для форматов шапки, иерархии и колонок, которых нет в реальных файлах osv/{rb,schastl}/. Данных реальных организаций здесь нет: организация «ООО "Тестовая организация"», контрагенты «ООО Альфа», «ООО Бета» и т. п., ИНН вымышленные. Файлы — вход парсера ОСВ (tabular-parser), а не эталон: ожидания по каждому файлу выведены из спеки (openspec/changes/slice-2a-osv-parser/specs/osv-parsing/spec.md) и лежат в тесте tabular-parser/api/tests/synthetic/test_synthetic_files.py.

Суммы согласованы арифметически (сальдо на конец = начало + обороты, родитель = сумма детей по колонкам), поэтому все файлы, кроме s10, сходятся по контрольным суммам §1.4 и дают статус done.

Генерация

Файлы собирает детерминированный генератор (openpyxl + минимальный писатель BIFF12 для xlsb); повторный запуск даёт те же байты (метки времени книги и zip зафиксированы):

cd tabular-parser/api
.venv/bin/python -m tests.synthetic.generate ../../fixtures/osv/synthetic

Правка набора — в tabular-parser/api/tests/synthetic/generate.py, затем перегенерация и коммит файлов здесь.

Набор

Файл Что проверяет Ожидание
s01_variant2_header.xlsx шапка варианта 2: «Период: …», «Детализация по субсчетам, субконто: Контрагенты, Договоры», заголовок «Субконто»; данные «Сумма» header_variant=2, group_schema=[ACCOUNT, COUNTERPARTY, CONTRACT], Q1/2026, data_type=SUM, hierarchy=outline
s02_no_outline_indent.xlsx уровни только отступами ячеек (без outline level); Валюта БУ, НУ: руб.; период «2 квартал 2025 г.» hierarchy=indent, дерево 0/1/2
s03_no_outline_no_indent.xlsx ни outline, ни отступов: уровни по кодам счетов и жирности; период «I кв. 2025 г.» (римский квартал) hierarchy=account_pattern, дерево как у s02
s04_currency_quantity_rows.xlsx под контрагентом строки «USD», «Кол.» (и «Вал.» у другого) data_type CURRENCY/QUANTITY, в проверку суммы детей не входят, done
s05_text_numbers.xlsx суммы текстом: «1 234 567,89», «(1 234,00)», «—»; неразрывные и узкие пробелы, прочерки «–», «-»; период «полугодие 2025 г.» 1234567.89, -1234.00, null
s06_two_osv_and_other_sheet.xlsx листы «ОСВ 60», «Справка», «ОСВ 62» два документа в порядке листов, предупреждение о пропуске «Справка»
s07_no_opening_collapsed_closing.xlsx нет группы «Сальдо на начало»; сальдо на конец — одна колонка со знаком; период «9 месяцев 2025 г.» opening_* = null, отрицательное сальдо — в closing_credit, предупреждение о свёрнутом сальдо
s08_extra_kpp_column.xlsx колонка «КПП» между «ИНН» и суммами; период «с 01.01.2025 по 31.03.2025» extra["КПП"] у контрагентов, суммы не сдвинуты
s09_subaccount_names.xlsx «60.01, Расчеты с поставщиками и подрядчиками», буквенный субсчёт «60.АВ, …» ACCOUNT, account_code_raw без названия, row_value — исходный текст
s10_broken_sum.xlsx у «ООО Бета» closing_debit увеличен на 1 needs_check, нарушение тождества — строка контрагента, суммы родителя — строка «60.01»
s11_header_repeat.xlsx заголовок таблицы повторяется внутри данных (печать по страницам); период «12 месяцев 2025 г.» строки заголовка пропущены, дерево и суммы не нарушены
s12_statement_and_osv.xlsx лист ББ («Бухгалтерский баланс», 0710001) и лист «ОСВ 60»; данные «НУ», период «январь - сентябрь 2025 г.» один документ, предупреждение «skipped: statement»
s13_no_outline_indent.xlsb та же ведомость, что s02, в формате xlsb; отступ — ведущими пробелами текста результат равен s02 кроме предупреждения «xlsb: outline level недоступен»
s14_statement_forms.xlsx три листа форм, каждый опознаётся одним признаком: «Форма по ОКУД 0710001», «Отчет о финансовых результатах», «Форма по ОКУД 0710002»; лист «ОСВ 60» один документ, три предупреждения «skipped: statement»
s15_group_title_synonyms.xlsx названия групп сумм: лист «ОСВ 60» — «Входящее сальдо»/«Конечное сальдо», лист «ОСВ 62» — «Начальное сальдо»/«Исходящее сальдо» два документа, все шесть колонок сумм найдены, done
s16_header_synonyms.xlsx лист «ОСВ 60»: нет названия организации, период «2024», валюта «RUB (код 643)», «Счет» и «Контрагенты» отдельными строками под «Дебет/Кредит»; лист «ОСВ 62» (вариант 2): «Детализация по субсчетам: Номенклатура, Статьи затрат, Нематериальные активы, Валюта» organization_name="" + предупреждение, Q4/2024, currency=RUB, схема листа 62 — ACCOUNT + четыре OTHER
s17_inn_in_name.xlsx колонки ИНН нет, ИНН записан в текст названия контрагента: «ООО Альфа, 7701234567», «ООО Бета (ИНН 7707654321)», «ООО Гамма ИНН: 5001234567», «ИП Сидоров 500100732259» (OQ-100) counterparty_inn — цифры, counterparty_name — без ИНН и разделителя, row_value не меняется; физлицо без ИНН — null; done
s18_inn_row_above.xlsx у «ООО Альфа» и «ООО Гамма» ИНН с верной контрольной суммой (7701234560, 5001234561) стоит отдельной строкой над названием (без сумм, тот же уровень), колонки ИНН нет (OQ-130); без подсказки в шапке строка с неверной контрольной суммой не склеивается (#35) строка с ИНН в rows не попадает и не уходит в OTHER; ИНН — у контрагента, предупреждение «строка N: ИНН … отнесён к контрагенту в строке M»; done
s19_inn_kpp_cell.xlsx колонка «ИНН/КПП»: в ячейках склеенное «7701234567/770101001» (OQ-100) counterparty_inn — только ИНН; колонка распознана как колонка ИНН; done
s20_inn_above_sibling_blank.xlsx ИНН строкой над наименованием, сосед того же уровня, без сумм (#35) ИНН — у своего контрагента, строк ИНН в rows нет, done
s21_inn_above_sibling_sums.xlsx ИНН строкой над наименованием, сосед, с теми же суммами то же; пара — по равенству сумм
s22_inn_above_parent_blank.xlsx строка ИНН — родитель наименования (уровень выше), без сумм наименование поднимается на её место, ИНН — ему, done
s23_inn_above_parent_sums.xlsx строка ИНН — родитель наименования, с суммами то же
s24_inn_below_child_blank.xlsx строка ИНН — ребёнок наименования (уровень ниже), без сумм ИНН — родителю, строка из rows уходит, done
s25_inn_below_child_sums.xlsx строка ИНН — ребёнок наименования, с суммами (как «Контрагенты.ИНН» в 1С, но без подсказки в шапке) то же
s26_inn_below_sibling_sums.xlsx ИНН строкой под наименованием, сосед, с суммами ИНН — своему контрагенту, done
s27_inn_below_sibling_blank.xlsx ИНН строкой под наименованием, сосед, без сумм (дефект main: ИНН уходил следующему контрагенту) ИНН — своему контрагенту; направление — по блоку 60.02, кончающемуся строкой ИНН; done
s28_inn_bad_checksum.xlsx раскладка s20 («над, не в дереве, без сумм»), но у ООО Альфа строка ИНН 7701234567 с неверной контрольной суммой (#35) строка остаётся обычной, у Альфы ИНН нет, предупреждение «похожа на ИНН … контрольная сумма не сходится», needs_check; остальные контрагенты — со своими ИНН (направление «над» — по блоку 60.02)
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
s40_flat_header_account.xlsx плоская форма 1С (#59, AURORA-1661): «по счету: 76.Н.1» с двоеточием, вид аналитики «Контрагенты» строкой между названием и периодом, организация ниже периода; строк-счетов нет, без outline и отступов; «Итого развернутое» перед «Итого» account_code_raw=76.Н.1, hierarchy=header_account, строки COUNTERPARTY, «Итого развернутое» и «Итого» — TOTAL, done
s41_flat_chart_of_accounts.xlsx плоская форма: вид аналитики «Организации», период «за 2 Квартал 2026 г. План счетов ООО Хреновская Нива» одной строкой, «Итого развернутое» перед «Итого» организация из хвоста «План счетов», account_code_raw=60, Q2/2026, hierarchy=header_account, строки COUNTERPARTY без предупреждения о виде субконто, done
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; период «За период» | «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
s47_indent_hierarchy_code_sums.xlsx три листа «Субконто» без вида аналитики в шапке, иерархия по отступам (AURORA-1858, tabular-parser#78): «68 сч.» — подуровень 68.01.1 на том же отступе, что 68.01; «90 сч.» — безымянная строка закрытия сразу за счётом 90.09 (пустая ячейка отступа не хранится); «91 сч.» — аналитика на одном отступе, вложенность видна только по суммам (100 = 60 + 40, 30 = 20 + 10, 40 ⊃ 40) hierarchy=indent, 68.01.1 — ребёнок 68.01, строка закрытия — ребёнок 90.09/91.09, аналитика 91 вложена по суммам, три листа done

s17–s19 — регрессия извлечения ИНН из текста (issue #9). s14–s16 добавлены тестом покрытия словарей tabular-parser (rules/*.yaml, решение R-22): каждая запись словаря должна сработать на реальных или синтетических файлах; эти файлы закрывают записи, которых нет в реальных ОСВ.

s29–s32 — tabular-parser#47 (кодировка xls без CODEPAGE, «Вал»/«Кол-во», строки ниже «Итого», итог «Итого по счету»).

s20–s27 — восемь раскладок строки ИНН рядом с контрагентом (issue tabular-parser#35); ИНН с верной контрольной суммой — без подсказки в шапке другие не склеиваются.

О файле xlsb

s13_no_outline_indent.xlsb собран не Excel и не LibreOffice (их на машине разработки нет), а минимальным писателем BIFF12 tabular-parser/api/tests/synthetic/xlsb_writer.py: он пишет только то, что читает pyxlsb (workbook, таблица общих строк, лист; без стилей и объединений). Файл читается pyxlsb и парсером, но совместимость с Excel не проверялась и этот файл не доказывает чтение xlsb, сохранённого Excel (другая раскладка записей, стили, BrtCellSt и т. д.). Когда появится возможность — заменить s13 настоящим: открыть s02_no_outline_indent.xlsx в Excel или LibreOffice, «Сохранить как» → Книга Excel двоичная (.xlsb), имя s13_no_outline_indent.xlsb; в xlsb нет outline level и форматирования ячеек, отступ нужно продублировать ведущими пробелами в колонке текста до сохранения.