using Rugrid.Sdaid.Notation.Documents;
using Rugrid.Sdaid.Notation.Glossary;
using AisTerm = Rugrid.Sdaid.Epas.Ntr.Glossary.Terms.AisOiaPeo;
namespace Rugrid.Sdaid.Epas.Ntr.Infrastructure.AisOiaPeo
{
/// <summary>
/// Контракт загрузки данных учёта фактического потребления из АИС ОИА ПЭО: что берётся из
/// источника, какие преобразования выполняются и куда записывается результат.
/// </summary>
public class DOC_ActualConsumptionImport : IInfrastructureDocument, IHasStructuralLinks
{
public SdaidLink[] Links => new[]
{
Rel.Uses<DOC_AisDataImport>(),
Rel.Uses<Rugrid.Sdaid.Epas.Ntr.Domain.ActualConsumptionModel.DOC_EeConsumption>(),
Rel.Uses<Rugrid.Sdaid.Epas.Ntr.Domain.ActualConsumptionModel.DOC_TeConsumption>(),
Rel.Uses<Rugrid.Sdaid.Epas.Ntr.Domain.Reference.DOC_Period>(),
Rel.Uses<Rugrid.Sdaid.Epas.Ntr.Domain.BuildingModel.DOC_Building>(),
};
public static string _refName = "Загрузка данных учёта";
public string Name => "Загрузка данных учёта фактического потребления";
public string Description =>
@"Блок импорта, переносящий в Сервис фактическое потребление электрической и тепловой энергии: месячные значения точек учёта сводятся к зданию.";
public string Version => "0.1";
public string Status => "draft";
public string[] Comments => new string[0];
public static string Place = $"""
## Место в импорте
Блок выполняется в составе общего прогона
{SdaidAnchors.RefTo<DOC_AisDataImport>()} — отдельной точки входа нет.
Потребление загружается после справочников и зданий: оно ссылается на учётные периоды и
привязывается к зданиям.
""";
public static string Source = $"""
## Что берётся из АИС ОИА ПЭО
Каждый вид ТЭР ведётся в {GlossaryAnchors.RefTo<AisTerm>(AisTerm.Name)} собственным набором
таблиц одинаковой структуры; вид ТЭР задан суффиксом в наименовании таблицы: `_ee` —
электрическая энергия, `_te` — тепловая.
| Таблица | Модель АИС | Назначение | Поля |
|---|---|---|---|
| `ref_building_points_ee` / `_te` | `RefBuildingPointsEe` / `…Te` | Точка учёта здания | `id`, `building_fk` → `ref_e_buildings.id`, обязательное |
| `doc_ter_buildings_ee` / `_te` | `DocTerBuildingsEe` / `…Te` | Документ учёта по точке за год | `id`, `year`, `building_point_fk` |
| `doc_ter_buildings_ee__values` / `_te__values` | `DocTerBuildingsEeValues` / `…TeValues` | Значение за период | `docid`, `period_fk`, `payload` |
| `ref_periods` | `RefPeriods` | Учётный период | `id`, `name`, `code`, `number`, `type` |
Модели АИС лежат в `NrjPack.Bizmod.Eo.EfCoreData.Models` — это код АИС ОИА ПЭО.
**Отбор:**
| Условие | Назначение |
|---|---|
| `ref_periods.type = 'month'` | Учёт ведётся месяцами; периоды иных типов не загружаются |
| `doc_ter_buildings_*.year >= 2017` | Глубина истории в источнике |
| Здание точки учёта (`ref_building_points_*.building_fk`) есть в Сервисе | Потребление привязывается к зданию Сервиса |
""";
public static string Transform = """
## Преобразования
**Сведение точек учёта к зданию.** Значение расхода по точке учёта здания суммируется в
значение расхода по зданию. Группировка — здание, `doc_ter_buildings_*.year`,
`doc_ter_buildings_*__values.period_fk`; агрегат — сумма `payload`. Точки учёта в Сервис не
переносятся.
**Разрешение ссылок.** Внешний ключ в таблице АИС хранит `id` записи АИС. Здание и учётный
период в Сервисе несут `ais_id` — по нему находится нужная запись, и её `id` пишется в
загружаемую запись потребления: в `build_id` — здания, в `period_id` — учётного периода.
**Единицы измерения не пересчитываются:** значение переносится как есть — тыс. кВт·ч для
электрической энергии, Гкал для тепловой.
**Отсутствующее значение переносится как отсутствующее.** `payload` может быть не задан;
такое значение не приравнивается к нулю и из выборки не исключается.
""";
public static string Target = $"""
## Куда записывается
| Источник | Сущность Сервиса |
|---|---|
| Таблицы с суффиксом `_ee` | {SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Ntr.Domain.ActualConsumptionModel.DOC_EeConsumption>()} |
| Таблицы с суффиксом `_te` | {SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Ntr.Domain.ActualConsumptionModel.DOC_TeConsumption>()} |
Поля записи потребления: `build_id` — здание точки учёта, `year` — год документа,
`period_id` — период значения, `consumption` — значение расхода.
Справочник учётных периодов из `ref_periods` —
{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Ntr.Domain.Reference.DOC_Period>()}: `ais_id` ← `id`
источника, `name`, `code`, `number`, `type` — без изменений.
""";
public static string Idempotency = """
## Повторная загрузка
Запись потребления — агрегат нескольких строк источника, поэтому `ais_id` у неё, в отличие
от прочих загружаемых записей, нет. Повторная загрузка находит её по естественному ключу —
здание, год, период: найденная запись обновляется значением, отсутствующая создаётся.
Незаданное значение записывается так же, как заданное: если в источнике значения нет, ранее
загруженное затирается.
Удаление записи в источнике Сервисом не отслеживается: блок не удаляет записи, которых нет
в текущей выборке.
""";
public static string Volume = $"""
## Объём
Учёт ведётся только по зданиям, подключённым к сторонним источникам энергии: 235 точек
учёта электрической энергии и 108 точек учёта тепловой.
Верхняя оценка на год учёта: 343 точки × 12 месяцев ≈ 4,1 тысячи записей, и меньше после
сведения точек к зданию. При глубине с 2017 года это порядка 40 тысяч записей за десять
лет.
""";
}
}