Сводная статистика ТС (плашки)

Запрос на изменение Версия: 0.4 done

Сводная статистика по реестру ТС — состояние обработки и потребление топлива в разрезе вида топлива, выводится плашками на главной странице модуля и на вкладке «Сведения» организационного объекта.

⟨/⟩ Исходник

1. Источник (как есть)

В модуле ЭНТС нет сводного представления состояния реестра ТС. Чтобы увидеть, сколько ТС находится в каждом статусе обработки или каков суммарный нормативный расход топлива, нужно открывать реестр ТС и просматривать строки вручную — нет агрегированной сводки.

Согласованы метрики двух групп:

  1. Состояние обработки. Всего ТС и разбивка по каждому из семи значений справочника «Статус обработки ТС»: Не выполнена, Мало данных загружено, Нет модификаций, Отсутствуют данные для расчёта, Автовыбор не подтверждён, Модификация не определена, Завершена.
  2. Потребление топлива ТС, в разрезе вида топлива. Для каждого вида топлива (бензин/дизельное топливо — не складываются, два отдельных разреза): нормативный расход (сумма, максимум, минимум, среднее) из уже сохранённого поля VehicleCalc.NormConsumption по ТС этого вида топлива с успешным расчётом; фактический расход — зарезервированное поле на будущее, источник не определён.

Место вывода: плашки на вкладке «Сведения» организационного объекта (фильтр — ТС этого объекта) и плашки на главной странице модуля (без фильтра, по всему реестру ТС).

2. Разбор

Технология. Не отчётный движок (ClosedXML и т. п. — для скачиваемых xlsx, не для веб-плашек): обычный агрегирующий backend-эндпоинт/read-model + UI-виджет. Отдельная задача на будущее — если понадобится скачиваемый xlsx-отчёт по этим же метрикам, переиспользовать паттерн Ntr.Reports/NtrReportApiController (сейчас не проектируется).

Форма read-model. Статистика не хранимая сущность — вычисляется по запросу из уже сохранённых Транспортное средство и Расчёт ТС. По аналогии с OutputModel (форма результата калькулятора, не хранимая сущность, Модель результата расчёта) заведена новая сущность Сводная статистика ТС с двумя построчными формами разрезов — по статусу обработки и по виду топлива — каждая из которых документирована отдельным [DomainEntity]-классом и встроена в тело основного документа через SdaidTable.OfClass<T>() (приём, уже применённый в Nts/70_Infrastructure/AisOiaPeo/AisImportMaps.cs для карт приёма данных АИС).

Фильтр по организационному объекту. Переиспользован принцип Реестр транспортных средств: объект задаёт организационный фильтр, при включённом «С потомками» — включаются подчинённые объекты (ТС числятся за МЭС и ПМЭС). На вкладке «Сведения» отдельного переключателя «С потомками» нет — сводка по объекту всегда считается с подчинёнными; на главной странице модуля фильтр не задаётся вовсе.

Почему не use-case. Виджет — агрегирующее чтение в рамках одного модуля без фонового процесса и без состояния, сохраняемого между шагами; значит, по методологии — поведение страницы/компонента, не use-case.

Почему «Фактический» не проектируется как рабочее поле. В домене ЭНТС сейчас нет источника фактических данных по топливу ТС. «Фактическое потребление» ЭНЗС (Ntr) — про тепло/электричество зданий, другая модель данных и другой модуль; переиспользовать её как источник для ЭНТС нельзя. Поле ActualConsumption зафиксировано в структуре как зарезервированное (nullable, без Calculated), но не вычисляется и не выводится в виджете, пока источник не определён — чтобы в будущем расширить read-model без изменения состава уже существующих полей.

3. Blast radius

3.1. Спецификация

Документ Правка
Nts/50_Domain/VehicleSummaryStatistics.cs (новый) Сводная статистика ТС — read-model, две построчные формы разрезов
Nts/65_Ui/VehicleSummaryWidget.cs (новый) Плашки сводной статистики ТС — UI-компонент плашек, встраиваемый в двух местах
Главная страница ЭНТС добавлена ссылка на виджет; раздел «Структура экрана» — плашки без фильтра до выбора объекта, плашки с фильтром на вкладке «Сведения»

3.2. Прототип

Файл Правка
Nts/65_Ui/html/main-page.html блок плашек без фильтра (по всему реестру ТС), встроенный в разметку главной страницы
орг.объектная страница/вкладка «Сведения» (найти по разметке VehicleRegistry/оргструктуры в Nts/65_Ui/html/) блок плашек с фильтром по текущему орг. объекту
Ntr/65_Ui/html/shell.js функция агрегации по данным NTS_VEHICLE/ensureNtsState (количество по статусу обработки; сумма/макс/мин/среднее NormConsumption по виду топлива для ТС с успешным расчётом) + функция рендера плашек; вызовы в обоих местах вывода
Ntr/65_Ui/html/shell.css стили плашек (переиспользовать существующие паттерны карточек/бейджей, не изобретать новый визуальный язык)

Прототип — часть того же CR, не отдельный шаг «потом»: спека без рабочего прототипа, который testovich может сверить выполнением, не считается законченной итерацией.

4. План

  1. Завести доменную сущность «Сводная статистика ТС» с двумя построчными формами разрезов («Количество ТС по статусу обработки», «Потребление топлива по виду топлива»), структурные связи на Vehicle, VehicleCalc, справочники.
  2. Завести UI-компонент «Плашки сводной статистики ТС» с описанием структуры (два ряда плашек) и поведения (фильтр внешний, компонент только отображает).
  3. Обновить NtsMainPage.cs: ссылка на компонент, упоминание плашек в обоих местах рабочей области (до выбора объекта — без фильтра; вкладка «Сведения» — с фильтром).
  4. Собрать (dotnet build, build-html.cmd), проверить отсутствие документов-сирот.
  5. Прототип: функция агрегации по демо-данным (shell.js) + разметка плашек в обоих местах вывода (main-page.html, вкладка «Сведения» орг. объекта) + стили.
  6. testovich — реальным выполнением на нескольких орг. объектах/без фильтра сверить подсчёт плашек с фактическим составом демо-ТС.
  7. Зафиксировать «Итог» по факту проверки.

5. Acceptance criteria

6. Итог

Реализовано и проверено testovich реальным выполнением. Read-model {SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleSummaryStatistics>()} и виджет {SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Ui.DOC_VehicleSummaryWidget>()} зафиксированы в спеке, прототип — в обоих местах вывода (главная страница без фильтра, вкладка «Сведения» с фильтром по орг. объекту). По итогам ревью пользователя доведены до соответствия: группировка по виду топлива — только бензин/дизель (как и методика расчёта), ряд 2 скрывается лишь при пустой выборке, добавлена строка сверки «Без успешного расчёта: N ТС», виджет размещён после полей сведений об объекте, не между ними. AC-1 — AC-7 подтверждены. По итогам ещё одного ревью пользователя обнаружено: «ряд»/«группа» были реализованы как множество отдельных плашек (10 штук — по одной на статус/вид топлива), хотя имелось в виду ровно 2 плашки с разбивкой строками внутри каждой (AC-8). Переделано: summaryTilesHtml() строит 2 .summary-group, разбивка — .summary-row внутри; спека и CSS согласованы. AC-8 подтверждён testovich реальным выполнением (несколько орг. объектов, ручной пересчёт сумм/мин/макс/среднего, случай пустой выборки — вторая плашка действительно отсутствует в DOM). AC-1 — AC-8 подтверждены.

Связанные артефакты

Документы