# Как работает обработка отчетов из 1С ## Оборотно-сальдовая ведомость по счету 20 ### Распознавание файла Файл `Оборотно_сальдовая_ведомость_по_счету_20_за_2025_г_ООО_Дружба.csv` **автоматически распознается** как `balance_sheet` по ключевым словам в названии: - "оборотн" - "сальд" - "ведомост" ### Формат CSV (схема колонок и чисел) - **Разделитель**: точка с запятой (`;`). - **Кодировка**: UTF-8 (при наличии BOM он автоматически убирается). - **Строки 1–9**: метаданные и заголовки (организация, «Счет, Наименование счета», «Обороты за период», «Статьи затрат» и т.д.). Строка начала данных определяется автоматически (по подстроке «Обороты за период» / «Счет, Наименование» или по первой строке, где в колонке 0 есть текст, а в колонке 3 или 4 — число). **Колонки (индексы 0–6):** | Индекс | Содержимое | |--------|------------| | 0 | Наименование (адрес дома / номенклатурная группа / статья затрат) | | 1, 2 | Сальдо на начало периода (Дебет, Кредит), часто пусто | | **3** | **Обороты за период — Дебет** (источник расходов по счёту 20) | | 4 | Обороты за период — Кредит | | 5, 6 | Сальдо на конец периода (Дебет, Кредит) | **Формат чисел**: пробел — разделитель тысяч, запятая — десятичный знак (например, `2 229,20`). Парсер удаляет пробелы и заменяет запятую на точку. **Пример строки данных:** `Булата Имашева 6/1;;;2 229,20;;2 229,20;` — адрес в колонке 0, оборот по дебету (расход) в колонке 3: 2 229,20. ### Куда сохраняются данные 1. **Таблица `financial_reports`**: - Запись о загруженном файле - Поля: `id`, `filename`, `file_type`, `uploaded_by`, `status`, `report_type`, `uploaded_at` - Статус: `processing` → `completed` / `partial` / `failed` 2. **Таблица `building_financial_data`**: - Финансовые данные по каждому дому - Поля: - `building_id` - ID дома из таблицы `buildings` - `report_id` - ID отчета из `financial_reports` - `period_start`, `period_end`, `period_type` - период (извлекается из названия файла) - `total_income` - общий доход - `total_expenses` - общие расходы - `expenses_by_items` - JSONB с разбивкой по статьям: `{"Группа > Статья": сумма}` - `balance` - баланс - `metadata` - JSONB с полной структурой групп и статей ### Как извлекаются адреса Функция `isBuildingAddress()` определяет адрес дома по следующим признакам: - Содержит буквы (название улицы) И цифры (номер дома) - Паттерны: `"6/1"`, `"Булата Имашева 6/1"`, `"Авроры 5/12"` - НЕ является счетом (20, 20.01) - НЕ является статьей затрат **Важно**: Чтобы данные по адресу попали в отчёт, адрес из файла должен быть найден в системе. Поиск выполняется в таком порядке: 1. Таблица **`doma_address_mappings`** — по нормализованному адресу (LOWER, TRIM) ищется `building_id`. Это позволяет явно связать адрес из 1С/ОСВ (например, «Авроры 5/12», «Булата Имашева 6/1») с домом в системе. 2. Таблица **`buildings`** — по полному совпадению `data->'passport'->>'address'`, затем без учёта регистра и пробелов, затем по нормализованному адресу (без «ул.», «д.», запятых), затем по основной части адреса (ILIKE). Если дом не найден ни одним способом, данные по этому адресу пропускаются и адрес добавляется в `error_log` отчета. ### Примеры адресов из файла - ✅ **"Булата Имашева 6/1"** - распознается (есть цифры и буквы) - ✅ **"Авроры 5/12"** - распознается (есть цифры и буквы) - ⚠️ **"Зеленая Роща"** - НЕ распознается как адрес дома (нет цифр в первой колонке) - Это может быть участок или комплекс, но не отдельный дом - Если это участок, данные по нему не сохранятся в `building_financial_data` ### Структура данных в `expenses_by_items` ```json { "Административно-управленческие расходы > Набор персонала": 805.84, "Административно-управленческие расходы > Налоги": 4416.06, "Текущее обслуживание общедомового имущества > Ремонт кровли": 34000.00, ... } ``` ### Где посмотреть загруженные данные 1. **Список отчетов**: Вкладка "Отчеты" → "Загруженные отчеты" 2. **Детали отчета**: Клик на отчет → показывает дома, участки, детальную разбивку 3. **Данные по дому**: В паспорте дома → раздел "Финансы" → данные из `building_financial_data` ### Проблемы и решения **Проблема**: "Дом не найден в базе" - **Причина**: Адрес из файла не найден ни в `doma_address_mappings`, ни в таблице `buildings` (с учётом нормализации). - **Решение**: Добавить запись в `doma_address_mappings` (адрес из ОСВ → `building_id`), либо привести адрес дома в паспорте к формату из файла, либо добавить дом вручную. **Проблема**: "Зеленая Роща" не распознается - **Причина**: Нет цифр в первой колонке (это участок, а не дом) - **Решение**: Если это участок, данные должны быть привязаны к конкретным домам внутри участка --- ## Оборотно-сальдовая ведомость по счёту 76.06 (лицевые счета жителей) ### Назначение ОСВ по счёту 76.06 содержит **лицевые счета** (жители/собственники): в 1С колонка может называться «Контрагенты», по смыслу это лицевые счета с суммами (обороты, сальдо). ### Распознавание файла - По названию файла: подстроки `"76"`, `"76.06"`, `"счету 76"` (без учёта регистра) — тип `balance_sheet_76`. - По фронту: при выборе типа «ОСВ по счёту 76» передаётся `detailedReportType: 'balance_sheet_76'`. ### Формат CSV (схема колонок) - Разделитель `;`, кодировка UTF-8, BOM убирается. - Строки 1–8: метаданные, заголовки «Счет», «Контрагенты», «Дебет», «Кредит». Начало данных определяется автоматически (по «Обороты за период» / «Контрагенты» или по первой строке с числом в колонке 3/4). - Колонки те же, что у ОСВ 20: 0 — наименование (лицевой счёт: код + ФИО (л/с) или просто ФИО/ИП/юрлицо); 1, 3, 4, 5, 6 — сальдо на начало, обороты дебет/кредит, сальдо на конец. Пропускаются строки с колонкой 0 = `76.06` или `Итого`. ### Куда сохраняются данные 1. **Таблица `financial_reports`**: запись с `report_type = 'balance_sheet_76'`. 2. **Таблица `report_76_rows`**: по одной строке на каждый лицевой счёт (report_id, row_index, account_label, account_ls, saldo_start_debet, turnover_debet, turnover_credit, saldo_end_debet, saldo_end_credit). 3. **Таблица `building_personal_account_mappings`** (сопоставление домов и лицевых счетов): привязка лицевого счёта к дому (building_id, account_ls, account_label, apartment). Используется для фильтра «ОСВ 76 по дому» и отображения данных 76 в карточке дома. Заполняется вручную или импортом. ### API - `GET /api/finance/reports/:reportId/balance-sheet-76-rows` — строки отчёта (лицевые счета). Опциональный параметр `buildingId`: при указании возвращаются только строки, чей лицевой счёт привязан к этому дому в `building_personal_account_mappings`. - `GET /api/finance/buildings/:buildingId/personal-accounts` — лицевые счета, привязанные к дому. - `POST /api/finance/building-personal-account-mappings` — добавить/обновить привязку (body: building_id, account_ls, опционально account_label, apartment). ### Где посмотреть 1. **Список отчетов**: Финансы → Отчеты; фильтр «Лицевые счета (ОСВ 76)». 2. **Детали отчёта**: Клик на отчёт ОСВ 76 → таблица лицевых счетов (колонки: Лицевой счёт, Сальдо на начало, Обороты дебет/кредит, Сальдо на конец). При наличии маппинга можно добавить фильтр по дому.