Skip to content

Дорожная карта: расчёт начислений и золотой тест (golden test)

Документ объединяет: привязку данных golden test к лицевым счетам, рекомендации UI/UX по связи «услуга ЖКХ ↔ общедомовой счётчик», дорожную карту проверки функционала как ИТ-архитектора, ввод данных (SQL/ручной), создание начислений, отображение результатов и оборотно-сальдовую ведомость с учётом пеней.


1. Excel → SQL: загрузка данных golden test в дом

1.1 Текущее состояние

  • Скрипт: scripts/generate_golden_test_jkh_12months.py генерирует golden_test_jkh_12months.xlsx с листами: лицевые счета (LS01–LS10), объёмы воды, подача показаний, тарифы, расчёты, финансовые итоги (начислено, пени, оплачено, сальдо).
  • Core-service: SeedGoldenTest в core-service/internal/database/seed_golden.go создаёт дом, помещения, ЛС, ИПУ и ОДПУ, показания за 12 месяцев. Вызов: POST /api/test-data/seed-golden с organizationId и houseId (0 = новый дом).
  • Связь с биллингом: лицевые счета и дома живут в core-service; начисления и проводки — в billing-service. Идентификация ЛС по account_number (LS01, LS02, …) или по внутреннему id после seed.

1.2 Рекомендуемый подход: SQL-файл для golden test

ЗадачаДействие
Единый источникОставить Excel как эталон для сверки; добавить генерацию SQL из тех же данных (или из результата seed).
SQL-файлСоздать scripts/seed_golden_test.sql (или генерировать из Python), который: вставляет/обновляет только данные, зависящие от выбранного дома (например, через подстановку :house_id или переменную).
Привязка к домуВ SQL явно указывать house_id, room_id, personal_account_id после того, как seed создал дом и ЛС (например, по account_number).
Привязка лицевых счетовВ billing-service начисления ссылаются на personal_account_id из core. После seed-golden ЛС уже привязаны к помещениям и дому; в SQL для billing используем эти ID (полученные из core API или из отдельной таблицы маппинга account_number → personal_account_id).

Конкретные шаги:

  1. Вариант A (минимальный): Продолжать использовать POST /api/test-data/seed-golden для создания дома и ЛС; затем отдельным скриптом или вручную создавать в billing-service учётные периоды (billing_cycles), тарифы (если хранятся в billing) и при необходимости тестовые начисления через API или SQL.
  2. Вариант B (полностью SQL):
    • В core: один раз выполнить seed-golden (или эквивалентный SQL), получить house_id и список (account_number, personal_account_id).
    • Сгенерировать seed_golden_billing.sql: вставка в billing_cycles, вставка в charges с подставленными personal_account_id и house_service_id.
    • Для показаний и справочников остаётся seed через API или миграции.

Итог: сначала использовать существующий seed-golden для дома и лицевых счетов; затем добавить SQL-скрипт (или небольшой генератор), который по выбранному дому заполняет billing (циклы, при необходимости тестовые начисления), чтобы не вводить их вручную.


2. UI/UX: привязка услуги ЖКХ к общедомовому счётчику

2.1 Как это уже реализовано

  • В Дом → Услуги (вкладка «Услуги», HouseServicesTab) для каждой услуги дома (в т.ч. общедомовой, например ОДН ХВС) при раскрытии строки отображается блок «Счетчик Общедомовой» (CommonMeterSection).
  • Кнопка «Добавить счетчик» открывает форму создания счётчика с предзаполнением: ownerType: 'house', houseServiceId: selectedServiceForMeter.id. То есть связь «услуга ↔ общедомовой счётчик» задаётся контекстом: пользователь добавляет счётчик именно в карточке этой услуги.
  • В core-service у Meter есть поле HouseServiceID; у HouseService — коллекция Meters. Общедомовые счётчики фильтруются по ownerType === 'house'.

2.2 Рекомендации как UI/UX дизайнер

РекомендацияОписание
Явная подпись услугиВ блоке «Счетчик Общедомовой» показывать название услуги, например: «Общедомовой счётчик: Холодное водоснабжение (ОДН)». Так сразу видно, к какой услуге привязан счётчик.
Один контекст = одна цельОставить добавление ОДПУ только из карточки услуги (не из общего списка счётчиков дома без контекста услуги), чтобы не возникало вопроса «к какой услуге этот счётчик?».
Состояние «нет счётчика»Текущее сообщение «Общедомовой счетчик не привязан. ОДН будет рассчитываться по нормативам» — хорошее; можно добавить короткую подсказку: «Добавьте ОДПУ для расчёта ОДН по показаниям».
Проверка типа счётчикаПри добавлении ОДПУ в форме предлагать только типы счётчиков с isHouseMeter: true (ОДПУ ХВС, ОДПУ отопления и т.д.), чтобы случайно не привязать ИПУ.
В карточке счётчикаНа странице просмотра счётчика показывать: «Услуга дома: <название>» и при необходимости «Дом: …», чтобы связь была видна и при редактировании.

Кратко: привязка уже есть через контекст «услуга → добавить счётчик»; улучшения — явные подписи услуги в блоке ОДПУ и фильтр типов счётчиков по «общедомовой».


3. Дорожная карта проверки функционала (ИТ-архитектор)

Последовательность проверок, чтобы убедиться, что цепочка «данные → расчёт → проводки → отчётность» работает.

ЭтапЧто проверяемГде
1Данные и привязкиДом, помещения, ЛС, услуги дома, тарифы/нормативы, ИПУ и ОДПУ привязаны к услугамcore-service, БД, UI «Дом → Услуги»
2ПоказанияПоказания за тестовые месяцы есть по ИПУ и ОДПУ; при необходимости ввод вручную или через SQLcore-service (meter_readings / periods), UI или SQL
3Учётные периодыВ billing созданы billing_cycles на нужные месяцы (DRAFT)billing-service, БД
4Расчёт начисленийЗапуск расчёта (job) создаёт записи charges с привязкой к ЛС и house_service_idbilling-service, handlers/calculations.go
5Просмотр начисленийСписок начислений по дому/периоду/задаче; фильтры и пагинацияAPI GET /api/billing/charges, by-house/:houseId, by-job/:jobId
6Применение периодаPOST /api/billing/cycles/:cycleId/apply создаёт проводки в ledger_entries и обновляет account_balancesbilling-service, LedgerService
7Оборотно-сальдовая ведомостьОтчёт по дому: по каждому ЛС и услуге (или по типам операций) — обороты и сальдо, с итогамиНовый API + UI (см. раздел 5)
8ПениНачисление пеней (расчёт и проводки типа PENALTY), отображение размера пеней по ЛС/домуbilling-service (penalty calc), API балансов и OSV

Ниже — пошаговый план с акцентом на ввод данных (SQL vs вручную), создание начисления и отображение результатов.


4. Ввод значений: SQL vs вручную

ДанныеСейчасРекомендация
Дом, помещения, ЛС, собственникиAPI seed-golden или ручное создание в UIОставить seed-golden; при необходимости дублировать логику в SQL для окружений без API.
Услуги дома, тарифы, нормативыUI «Дом → Услуги»Часть можно вынести в SQL: например, фиксированный набор услуг и тарифов для golden-дома по справочникам (utility_services, house_services, service_tariffs).
Показания счётчиковSeed-golden создаёт 120 показаний (12 мес × 10 ЛС); ОДПУ — отдельноЕсли нужны другие значения — либо правка seed_golden.go, либо SQL по таблицам показаний (meter_readings / meter_periods в core).
Учётные периоды (billing_cycles)Нет API создания в маршрутах; только модель и миграцииДобавить API POST /api/billing/cycles (month, year) или выполнять вставку через SQL для тестов.
Начисления (charges)Создаются задачей расчёта (пока заглушка — processedAccounts=0)Довести логику расчёта в calculations.go до создания Charge; для тестов допустимо временно вставлять тестовые charges через SQL с привязкой к cycle и ЛС.
Ставки пенейAPI POST /api/billing/penalty-ratesДля golden test можно добавить SQL-вставку в penalty_rates с фиксированными датами и ставками.

Итог: максимум автоматизировать через SQL: циклы, тестовые начисления (если расчёт ещё не готов), ставки пеней, при необходимости тарифы/нормативы. Ручной ввод оставить для разовых правок и проверок в UI.


5. Создание начисления и отображение результата калькуляции

5.1 Создание начисления

  • Целевой путь: Задача расчёта (CalculationJob) по домам/периоду получает из core список ЛС и услуг, считает объёмы и суммы, создаёт записи Charge со статусом DRAFT и привязкой к billing_cycle_id, personal_account_id, house_service_id.
  • Текущее состояние: В handlers/calculations.go после подсчёта домов и ЛС идёт TODO: реализовать логику расчёта и создание Charge. Сейчас job завершается без создания начислений.
  • Шаги: Реализовать в job цикл: для каждого дома → лицевые счета → услуги дома → формула (объём × тариф или норматив) → Charge (period, rate_type, consumption, amount, status=DRAFT). Для ОДН использовать показания ОДПУ и привязку услуги к счётчику через house_service_id.

5.2 Отображение результата расчёта

ВариантОписание
Таблица в UIСтраница «Начисления»: фильтры дом, период, задача; таблица строк: ЛС, услуга, период, объём, тариф, сумма, статус. Уже есть GET /api/billing/charges, by-house/:houseId, by-job/:jobId.
Выгрузка в ExcelДобавить endpoint GET /api/billing/charges/export?houseId=&period=&format=xlsx (и при необходимости по job). На фронте — кнопка «Скачать Excel». Формат: столбцы как в таблице + при необходимости сводка по ЛС/услугам.

Рекомендация: сначала закрепить таблицу в UI (существующие API); затем добавить экспорт в Excel для сверки с golden_test_jkh_12months.xlsx.


6. Оборотно-сальдовая ведомость (ОСВ) по дому

6.1 Требования

  • По одному дому.
  • По каждой услуге (или по типам операций: начисление, оплата, пени).
  • По лицевым счетам дома: начальное сальдо, обороты (дебет/кредит или приход/расход), конечное сальдо.
  • Итого по дому: итоговые обороты и итоговое сальдо.

6.2 Модель данных (уже есть)

  • ledger_entries: personal_account_id, transaction_type (CHARGE, PAYMENT, PENALTY, STORNO), debit, credit, reference_id, created_at.
  • account_balances: personal_account_id, principal_debt, penalty_debt, last_updated_at.
  • Связь ЛС с домом: через core (personal_accounts → room → house).

6.3 Что нужно реализовать

КомпонентДействие
APIНовый endpoint, например GET /api/billing/reports/turnover-balance?houseId=&periodFrom=&periodTo= (или по month/year). Логика: по houseId получить список personal_account_id из core; по ним выбрать ledger_entries за период и агрегировать по ЛС и по transaction_type; при необходимости разнести по услугам через reference_id (charge:id) и связь charge → house_service_id.
АгрегацияПо каждому ЛС: сальдо на начало (из предыдущих проводок или из account_balances на дату), обороты за период (дебет/кредит по типам), сальдо на конец. Итого по дому: суммы по столбцам.
УслугиДля «по каждой услуге» нужна разбивка начислений по house_service_id (из charges по reference_id). В отчёт можно добавить таблицу: ЛС × Услуга × Начислено/Оплачено/Пени × Сальдо.
UIСтраница отчётов: выбор дома, период; кнопка «Сформировать»; таблица ОСВ + итоговая строка; при необходимости экспорт в Excel.

6.4 Пени в ОСВ

  • В проводках уже есть тип PENALTY (debit увеличивает долг по пеням).
  • В account_balances есть penalty_debt.
  • В отчёте: отдельная колонка «Пени» (оборот за период и/или сальдо по пеням) и возможность фильтра «показывать размер начисленных пеней» по ЛС и по дому в итоге.

Рекомендация: в том же API ОСВ возвращать по каждому ЛС поля penalty_accrued (оборот по PENALTY за период) и penalty_balance (из баланса или сумма проводок PENALTY на конец периода); в итоге по дому — сумма по всем ЛС.


7. Пошаговый план (сводка)

  1. Подготовка данных golden test

    • Выполнить seed-golden для организации и дома (или использовать существующий дом).
    • Убедиться, что в «Дом → Услуги» добавлены нужные услуги (ХВС, ОДН ХВС и т.д.), тарифы и нормативы; при необходимости добавить SQL-скрипт для тарифов/нормативов.
    • Проверить привязку ОДПУ к услугам в UI (блок «Счетчик Общедомовой» в каждой услуге).
  2. Показания и учётные периоды

    • Проверить наличие показаний за тестовые месяцы (seed уже создаёт их).
    • Создать учётные периоды в billing: либо API POST /api/billing/cycles, либо SQL-вставка в billing_cycles (DRAFT) на нужные месяц/год.
  3. Расчёт начислений

    • Реализовать в job создания записей Charge по ЛС и услугам (формулы, тарифы, ОДН по ОДПУ).
    • Запустить расчёт по дому/периоду; проверить по API список начислений по дому и по job.
  4. Отображение начислений

    • В UI: страница/таблица начислений с фильтрами дом, период, задача.
    • Опционально: выгрузка в Excel для сверки с golden Excel.
  5. Применение периода и проводки

    • Вызвать POST /api/billing/cycles/:cycleId/apply.
    • Проверить по БД: появление записей в ledger_entries, обновление account_balances.
  6. Оборотно-сальдовая ведомость

    • Реализовать API отчёта ОСВ по дому за период (обороты, сальдо по ЛС, разбивка по типам операций и при необходимости по услугам).
    • Добавить в отчёт колонки/поля по пеням (оборот и сальдо).
    • UI: форма выбора дома и периода, таблица с итогом; при необходимости экспорт в Excel.
  7. Пени

    • Реализовать расчёт пеней (по ключевой ставке и срокам) и создание проводок типа PENALTY.
    • Убедиться, что в ОСВ и в карточке ЛС отображается размер начисленных пеней (из проводок и/или account_balances.penalty_debt).
  8. Сверка с golden Excel

    • Сравнить итоги начислений, пеней и сальдо по ЛС/месяцам с листом Financials (и при необходимости с другими листами) из golden_test_jkh_12months.xlsx.

Этот план можно использовать как чек-лист для поочерёдной проверки и доработки функционала начислений, проводок, ОСВ и пеней.