14 KiB
Design: колонка «Показатели» и валютные строки ОСВ
Правило — 05-domain-rules.md §1.3 (абзацы «строки-показатели», «Колонка «Показатели»»), §1.4 (сверка родителя),
ветка docs feat/58-osv-indicators.
Как выглядит файл (реальный образец контура, в git не кладётся)
result_dir.zip, files/3da66219-….xlsx — ОСВ по счёту 02, шапка без «Выводимые данные» («Параметры: Валюта БУ, НУ:
Руб»):
r7 Счет | Показа-\nтели | Сальдо на начало | Обороты за период | Сальдо на конец
r8 Основные средства | | Дебет | Кредит | Дебет | Кредит | Дебет | Кредит
r10 02 | БУ | | 480896,82 | 45754,41 | 46336,70 | | 481479,11 outline 0
r11 | НУ | | 480896,82 | 45754,41 | 46336,71 | | 481479,12 outline 0
r12 Интерактивная … | БУ | … outline 1
r13 | НУ | … outline 1
r16 Машина … (A16:D17 объединены) | БУ | … outline 1
r17 (продолжение объединения) | НУ | … outline 1
r30 Итого (A30:D31 объединены) | БУ | … outline 0
r31 (продолжение) | НУ | … outline 0
files/270b41da-….xlsx (плоская форма, трек B) — пары строк «Валюта CNY» (рубли) / «В валюте» (сумма в валюте) под
субсчётом 76.55.
Сейчас: колонка «Показа-тели» попадает в extra_cols и в _label_cols (r11, r13 — пустой текст → текст «НУ» из
колонки E, отступ +1000 → ребёнок строки БУ); r17 — текст объединённой ячейки (повтор названия), data_type всех строк
null (шапка молчит); r31 — не «Итого развернутое», _trailing_totals обрывается, строка уходит в подвал с
предупреждением «ниже таблицы есть числа».
Решения
Признак строки-показателя — поле строки, не значение data_type
Сейчас «показатель» = data_type ∈ {CURRENCY, QUANTITY} (checks._INDICATOR_DATA_TYPES). NU в этот набор добавить
нельзя: документ с «Выводимые данные: НУ» (s12) целиком состоит из строк NU, и все его проверки пропали бы. Поэтому
вводится признак indicator: bool у BodyRow (вычисляется при сборе строк) и у ClassifiedRow; checks._is_indicator
читает признак. Строка-показатель — если:
- в листе есть колонка «Показатели», ячейка строки в ней непуста и метка ≠ «БУ» (словарь
data_types.indicator_column);data_type— из словаря; «ПР», «ВР» —null(словарьindicator_column_untyped); метка не из обоих словарей —null+ предупреждениеOSV_ROWS«строка N: метка «X» в колонке «Показатели» не распознана — строка не участвует в проверках»; - иначе — текст строки матчит
data_types.row(«Вал.», «Кол.», «Кол-во», «В валюте») или равен коду валюты (как сейчас,row_data_type).
Метка «БУ» в колонке даёт строке data_type = BU явно (даже если шапка молчит или называет НУ — колонка точнее шапки).
Текст строки с меткой колонки — метка
У строки-показателя из колонки текст в колонке текста либо пуст, либо повторяет объединённую ячейку строки БУ (r17).
BodyRow.text = метка («НУ»), is_account = False. Так row_value не дублирует название объекта, а ИНН-логика и
классификатор не принимают строку за счёт или контрагента. Колонка «Показатели» исключается из _label_cols (как колонка
ИНН) и остаётся в extra под своим заголовком.
Иерархия: показатели вне каскада, родитель — предыдущая строка данных
Новый модуль src/parser/indicators.py (чтобы не пересекаться с треком B в hierarchy.py):
levels_with_indicators(rows, total_row, deadline) -> Levels: функция сама запускает каскад resolve_levels на
строках без показателей (в OsvParser.parse_sheet вызывается она одна); затем каждому показателю (до «Итого») назначается родитель — ближайшая строка выше, которая не
показатель, — и уровень level(родителя) + 1; показатель в начале таблицы без строки данных выше — уровень 0 без
родителя. Итоговые строки-показатели — уровень 0 без родителя (как «Итого»). Стратегия иерархии (Levels.strategy) —
стратегия каскада.
Для строк «Вал.»/«Кол.» под контрагентом (s04, s30, реальные файлы) результат совпадает с прежним: 1С печатает показатель сразу под строкой, к которой он относится. Golden-проверка это подтверждает; любое расхождение golden на реальных файлах — стоп и вопрос владельцу (не перегенерировать молча).
Итоговые строки-показатели
_trailing_totals продолжает серию итоговых строк и через строки с меткой показателя в колонке «Показатели»
(r31 после r30): они остаются в таблице, классифицируются TOTAL с data_type метки и indicator = True;
checks._total берёт первую итоговую строку не показатель. Трек B добавляет _leading_totals и меняет
_total под «Итого развернутое» перед «Итого» (_trailing_totals не трогает) — при слиянии второй трек добавляет
своё условие к версии первого.
Вид данных по умолчанию
Если шапка не называет вид данных (doc.data_type is None), строки без собственного вида (не показатели и без метки
«БУ») получают BU; один раз на лист — предупреждение OSV_HEADER «вид данных в шапке не указан — строки без метки
приняты как БУ». Если все строки данных размечены колонкой «Показатели», предупреждения нет (умолчание не
применялось). header.data_type остаётся null; существующее предупреждение шапки «тип выводимых данных … не найден»
сохраняется.
Что не меняется
balance_identityпроверяет все строки, включая показатели (как сейчас у «Вал.»/«Кол.»): у НУ/количества тождество «начало + обороты = конец» тоже выполняется.- «Валюта <код>» — обычная строка OTHER (рубли):
row_data_type("Валюта USD")=Noneуже сейчас; закрепляется тестом. - Контракт, DBML, arm-core.
Decisions made without discussion
| Дата | Решение | Обоснование | Что стоит ошибка |
|---|---|---|---|
| 19.10.2026 | «ПР», «ВР» и метка не из словаря — data_type = null, строка-показатель |
В контракте нет значения для разниц; null ядро не берёт в свод, проверки строку не видят |
Разницы не видны как отдельный вид данных до AURORA-1669; переразметка — правка словаря |
| 19.10.2026 | Признак показателя — поле indicator, а не набор значений data_type |
Документ «Выводимые данные: НУ» не должен терять проверки | Лишнее поле в двух dataclass; контракт не меняется |
| 19.10.2026 | row_value строки с меткой колонки — метка, а не текст колонки текста |
Текст там пуст или повтор объединённой ячейки строки БУ | Если 1С когда-то печатает в строке НУ своё название — оно теряется (не встречалось в 31 файле контура) |
| 19.10.2026 | Колонка «Показатели» остаётся в extra |
Первичка не теряется, ядро extra хранит как есть |
Дублирование метки в extra и data_type |
| 19.10.2026 | Родитель показателя — предыдущая строка данных для всех показателей, включая «Вал.»/«Кол.» в колонке текста | Один механизм для колонки, «В валюте» и старых меток; каскад не видит строк, которые ломают дерево | Если показатель стоит не сразу под своей строкой, родитель будет неверным; ловит golden |
| 19.10.2026 | Умолчание BU — только строкам без собственного вида; header.data_type остаётся null |
Шапка действительно молчит; ядру нужен вид строки, не шапки | Предупреждение на листах без «Выводимые данные» (были без него) |
| 19.10.2026 | Синтетика s33–s36 (R-1: s40–s44 заняты треком B #59, s37–s39 резерв) | Рулинг владельца R-1: параллельные треки не конфликтуют по именам файлов набора | Пропуск номеров в наборе |
| 19.10.2026 | Новый модуль indicators.py вместо правки hierarchy.resolve_levels |
Трек B меняет каскад иерархии параллельно | Ещё один модуль конвейера |
| 19.10.2026 | T1.1: в колонке «Показатели» метка «Вал» без точки = CURRENCY (^вал\.?$), хотя в тексте строки (row) «Вал» без точки — не метка (материал, AURORA-1663) |
В колонке меток закрытый набор | Ложный показатель для метки «Вал» вместо БУ |
| 19.10.2026 | T4.1: любая метка колонки «Показатели», кроме «БУ», у строки сразу после «Итого» делает её итоговой строкой-показателем (включая неизвестную метку) | Показатели не должны превращаться в «хвост ниже таблицы»; предупреждение о неизвестной метке выдаёт read_label |
Неизвестная метка у реальной строки ниже таблицы будет втянута в таблицу |
| 19.10.2026 | R-2: трейлер коммитов «Claude Sonnet 5.5» вместо «Claude Opus 5.5» из плана | Атрибуция сессии | Правка трейлеров |
| 19.10.2026 | R-3: Task 3 плана (haiku) исполнен sonnet | Проза с рефакторингом | Стоимость |
| 19.10.2026 | R-4: мелкие находки T6.1/T6.3 исправлены до записи golden, а не отложены | Golden пишется один раз на исправленном коде | Лишний коммит |
| 19.10.2026 | R-5: golden s34 обновлён владельцем вручную после отказа классификатора в make golden-update |
Снимок s34 — собственный новый снимок ветки; изменилась одна строка (текст предупреждения о неизвестной метке по I-2) | Ручное обновление без агентского ревью diff; diff проверен контроллером: одна строка |
Решения владельца 19.10.2026 (чат): п. 1 колонка «Показатели» как метки §1.3, НУ без своих проверок; п. 2 «В валюте» → CURRENCY, «Валюта <код>» — строка OTHER в рублях, код валюты не хранится; п. 3 BU по умолчанию с предупреждением — по рекомендации агента, владелец принял без возражений («ошибки давай исправлять сейчас»).