Учёт фактического потребления и затрат

Запрос на изменение Версия: 0.1 в работе

Периодическая загрузка данных о фактическом потреблении автомобильного топлива и затратах из АИС ОИА ПЭО, их хранение по ТС и периоду, вывод в карточке ТС и в сводной статистике рядом с нормативным расходом.

⟨/⟩ Исходник

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

загрузка периодических данных о фактических потреблении автомобильного топлива и затратах из АИС ОИА ПЭО: процедура загрузки и структуры хранения в ЭНТС вывод данных в UI ЭНТС

SQL-запрос, показывающий какие и как берутся данные из АИС:

--Фактическое потребление Бензина/ДТ и затраты
--doc_ter_cars_petrol__values/disel__values
--doc_ter_cars_petrol/disel
--ref_car_points_petrol/disel
select
       p.car_fk as ais_vehicle_id,
       d.year,
       v.period_fk as ais_period_id,
       sum(v.consume_miliage) as consumption_per_mileage_l,
       sum(v.consume_hours) as consumption_per_hour_l,
       sum(v.consume_avr) as consumption_per_avr_l,
       sum(v.miliage) as miliage_tkm,
       sum(v.hours) as hours_h,
       sum(v.expenses) as expenses_trub
from doc_ter_cars_petrol__values as v
    left join ref_periods periods on periods.id = v.period_fk
    left join doc_ter_cars_petrol d on d.id = v.docid
    left join ref_car_points_petrol p on p.id = d.car_point_fk
    left join navs on navs.id = d.navid
where 1=1
      and navs.o_fsk_name like('ПАО "Россети"')
      and d.year >= 2025
    and periods.type = 'month'
group by ais_vehicle_id, year, ais_period_id
order by ais_vehicle_id, year, ais_period_id
;

Запрос приведён для бензина (doc_ter_cars_petrol*); для ДТ — параллельный набор таблиц doc_ter_cars_disel*, ref_car_points_disel, та же структура колонок. Алиасы tkm/ trub — суффикс t означает «тысяча»: miliage — тыс. км, expenses — тыс. руб.

Справочник периодов АИС, на который ссылается period_fk:

--Periods
--Периоды
select
    d.id as ais_id,
    d.name,
    d.code,
    d.number,
    d.type
from ref_periods d
;

2. Разбор

  1. Источник АИС. Данные берутся из таблиц АИС ОИА ПЭО doc_ter_cars_petrol/doc_ter_cars_disel (документ по ТС) и их табличных частей doc_ter_cars_petrol__values/doc_ter_cars_disel__values (значения по периоду), с привязкой ТС через ref_car_points_petrol/ref_car_points_disel. Бензин и ДТ — две параллельные пары таблиц одной структуры, не различающее поле внутри одной таблицы. Отбор — по организации (navs.o_fsk_name) и году (d.year); период — ref_periods с type = 'month'. На ключ «ТС + год + период» из таблицы __values агрегируются (sum) по ТС, году и периоду: consume_miliage, consume_hours, consume_avr (три компоненты фактического расхода топлива, л — по пробегу, по моточасам, по АВР — аварийным и ремонтным работам), miliage (пробег), hours (моточасы), expenses (затраты). Единицы: miliage — тыс. км (tkm), expenses — тыс. руб. (trub); hours — часы, множителя нет.

  2. Структура хранения. Новая сущность ActualConsumption (Nts/50_Domain/ActualConsumption.cs), по аналогии со связями Расчёт ТС на Транспортное средство — ссылками на сущности, не на Guid/примитивы напрямую: ссылка на Транспортное средство (сопоставление по ais_vehicle_id/car_fk), ссылка на вид топлива (бензин/ДТ — определяется тем, из какой пары таблиц АИС загружена запись, отдельным полем в АИС не хранится), ссылка на период — отдельный справочник Period (ref_periods в АИС: ais_id, name, code, number, type), не примитивное поле: ref_periods.type = 'month' отбирает только периоды нужной детализации, сам справочник может содержать периоды и другой детализации. Плюс год (d.year в источнике — отдельное поле, не выводится из Period), три компоненты фактического расхода топлива (по пробегу/по моточасам/по АВР, л), пробег за период (тыс. км), моточасы за период (ч), затраты за период (тыс. руб.). Ключ записи — «ТС + год + период + вид топлива».

    classDiagram
        class Vehicle {
            +Guid Id
            +Guid AisId
        }
    
        class FuelKind {
            +Guid Id
            +string Name
        }
    
        class Period {
            +Guid Id
            +Guid AisId
            +string Name
            +string Code
            +int Number
            +string Type
        }
    
        class ActualConsumptionLoadStatus {
            +Guid Id
            +string Name
        }
    
        class ActualConsumption {
            +Guid Id
            +Vehicle Vehicle
            +FuelKind FuelKind
            +Period Period
            +int Year
            +decimal ConsumptionByMileage
            +decimal ConsumptionByHours
            +decimal ConsumptionByAvr
            +decimal Mileage
            +decimal Hours
            +decimal Expenses
            +ActualConsumptionLoadStatus LoadStatus
        }
    
        ActualConsumption --> Vehicle
        ActualConsumption --> FuelKind
        ActualConsumption --> Period
        ActualConsumption --> ActualConsumptionLoadStatus
    
  3. Процедура загрузки. Контракт DOC_NtsActualConsumptionImport (Nts/70_Infrastructure/AisOiaPeo/ActualConsumptionImport.cs), отдельный от Приём данных из АИС ОИА ПЭО. Источники — doc_ter_cars_petrol/disel, __values, ref_car_points_*; результат — записи ActualConsumption (см. п.2) по ключу «ТС + год + период + вид топлива».

    Точки входа — те же, что у Приём данных из АИС ОИА ПЭО: пакетная — со страницы «Импорт» (Импорт данных из АИС ОИА ПЭО), роль «Администратор»; точечная, по своему ТС — из карточки ТС (Карточка транспортного средства), роль «Владелец ТС». Запуск — по требованию пользователя, без расписания.

    Загружаются данные за три последних завершённых года плюс прошедшие месяцы текущего года. Данные за период, уже имеющиеся в ActualConsumption, перезаписываются загружаемыми без накопления дублей. Статус загрузки — отдельная сущность, не Статус загрузки (тот — про готовность ТС к расчёту, не про загрузку периодических данных).

  4. Ролевая модель — переименование и новая роль, на весь модуль ЭНТС. Текущая роль «Пользователь» (ЭНТС — эталоны и нормативы потребления топлива, «Роли пользователей») переименовывается в «Владелец ТС» без изменения объёма прав — вносит данные по ТС и организационным объектам в своём периметре доступа (подчинённым своего орг. объекта). Заводится новая роль «Пользователь» — read-only: видит всё, не меняет ничего. Решение распространяется на весь модуль ЭНТС, не только на функционал этой CR — на все операции, которые сейчас выполняет роль «Пользователь» (подбор модификации, ввод параметров методики, запуск расчёта).

  5. Новый экран — вкладка «Расход автотоплива». Назначение — показать загруженные месячные факты потребления и объяснить исходные данные для расчёта аналитических показателей: «Фактический расход» в карточке ТС (п.6), «Фактический расход» сводной статистики (п.7). Только свод над загруженными фактами (сумма/группировка по оргструктуре, году, периоду, виду топлива). Рядом с вкладкой «Реестр ТС» (Реестр транспортных средств) заводится вкладка «Расход автотоплива». К уже принятым в Реестр транспортных средств переключателям «С потомками / Без потомков» и «Все / Действующие» (переиспользуются без изменений) добавляются: выбор периодичности отображения (месяц / год) и выбор отображаемых параметров — состав определён полями ActualConsumption (п.2): Расход на пробег, Расход на моточасы, Расход на АВР, Пробег, Моточасы, Затраты.

  6. «Фактический расход» — расчётный показатель VehicleCalc. По тому же правилу, что и остальные расчётные параметры карточки (вход, результат, подсказка) — новое поле Расчёт ТС: ActualConsumption, л, Calculated = "Да". Вход — записи ActualConsumption (п.2) этого ТС за отчётный год: три компоненты расхода (по пробегу/по моточасам/по АВР), каждая — сумма месячных записей года. Результат — одно число: свод трёх годовых компонент в «Фактический расход»; формула свода — открытый вопрос ниже (OQ-E), до его решения поле не вычисляется. Нет записей ActualConsumption за год — прочерк, как и у прочих расчётных полей без данных. Подсказка — та же иконка-алгоритм, что у прочих расчётных полей, с формулой свода после решения OQ-E.

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

  7. Сводная статистика — закрывает зарезервированное поле. В Сводная статистика ТС поле ActualConsumption уже заведено как резерв «источник фактических данных не определён». Эта CR вводит источник — ActualConsumption; период агрегации — тот же год, что и в п.6 (сумма месячных); свод трёх компонент — тот же открытый вопрос.

  8. Затраты — только на топливо, одной суммой. expenses — затраты на расход топлива за период; не включают прочие статьи (ГСМ, обслуживание). Источник отдаёт одно значение на пробег, моточасы и АВР вместе — без разбивки по этим трём компонентам, как consume_miliage/consume_hours/consume_avr для расхода. Структура хранения заводит одно поле «затраты за период» (п.2).

3. Открытые вопросы (для пользователя — не домысливаются)

4. Blast radius

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

Документ Правка
Nts/50_Domain/ActualConsumption.cs новая сущность: ссылки на ТС/вид топлива/период (Period — новый справочник), год, три компоненты расхода (по пробегу/моточасам/АВР), пробег, моточасы, затраты за период, статус загрузки пакета
Nts/50_Domain/Period.cs новый справочник периодов АИС (ref_periods): AisId, Name, Code, Number, Type
Nts/50_Domain/BC_Nts.cs добавить Rel.Uses<DOC_ActualConsumption>(), Rel.Uses<DOC_Period>() в состав домена
Nts/50_Domain/VehicleSummaryStatistics.cs снять резерв с ActualConsumption после решения OQ-E (не в этой CR — отдельный шаг)
Nts/70_Infrastructure/AisOiaPeo/ActualConsumptionImport.cs новый контракт периодической загрузки из doc_ter_cars_petrol/disel (+ __values, ref_car_points_*): ключ сопоставления, статус пакета, модель (nav, car?) по аналогии с DOC_NtsAisImport — детали после ответа на OQ-C
Nts/50_Domain/NtsImportRun.cs возможно — добавить измерение «вид данных» для переиспользования под запуски загрузки фактического потребления (решение — OQ-C)
Nts/50_Domain/VehicleCalc.cs новое расчётное поле ActualConsumption, л (Calculated = "Да") — свод трёх компонент ActualConsumption-записей (п.2) за год; формула свода — после OQ-E
Nts/65_Ui/VehicleCard.cs в группе «Результаты расчёта» — поле «Фактический расход, л» (= VehicleCalc.ActualConsumption), только чтение, рядом с Нормативным/Эталонным расходом, с иконкой подсказки-алгоритма
Nts/65_Ui/ActualConsumptionTab.cs новая вкладка «Расход автотоплива» рядом с «Реестр ТС»: свод по оргструктуре и году по всем параметрам, с измерением «Вид топлива»; по аналогии с Ntr/65_Ui/Componetns/ActualConsumptionTab.cs — детальная спека отдельным шагом
Nts/10_Vision/NtsVision.cs раздел «Роли пользователей» — переименование «Пользователь» → «Владелец ТС», новая read-only роль «Пользователь» (действует на весь модуль ЭНТС, п.4); раздел «Модель данных»/«Пользовательский интерфейс» — ссылка на новую сущность, контракт и вкладку
Nts/60_Epics/NtsFuelCalc/EPIC_NtsFuelCalc.cs новая OQ-секция после ответа пользователя на OQ-C, OQ-E (не добавляется этой CR без ответа)

4.2. Прототип

Прототип (Nts/65_Ui/html/vehicle-card.html, vehicle-registry.html, общий shell.js) не трогается до согласования макетов новой вкладки и поля карточки ТС — по правилу «UI-изменения сначала макет».

5. План

  1. Получить ответы пользователя на OQ-C, OQ-E.
  2. Спека: ActualConsumption.cs, Period.cs, BC_Nts.cs, ActualConsumptionImport.cs, правка VehicleCalc.cs (поле ActualConsumption) и VehicleCard.cs (поле «Фактический расход»), новая ActualConsumptionTab.cs, правка NtsVision.cs (роли), при необходимости VehicleSummaryStatistics.cs и NtsImportRun.cs.
  3. Макеты — поле в карточке ТС и новая вкладка «Расход автотоплива» — показать пользователю, получить «ок».
  4. Обновить прототипы (vehicle-card.html, новый actual-consumption-tab.html, shell.js) по согласованным макетам.
  5. Собрать (dotnet build, build-html.cmd).
  6. doc/testovich — отдельным проходом.
  7. Зафиксировать «Итог».

6. Итог

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

Документы