⟨/⟩ Nts/55_Backend/Calc/ProcessingStatusPolicy.cs

97 строк · в начало

using Rugrid.Sdaid.Notation.Documents;

namespace Rugrid.Sdaid.Epas.Nts.Backend.Calc
{
    /// <summary>
    /// Политика вычисления итогового статуса обработки ТС. Выполняется прикладным слоем после
    /// расчёта: по результату калькулятора, статусу подбора модификации и способу подбора.
    /// </summary>
    public class DOC_ProcessingStatusPolicy : ISdaidDocument, IHasStructuralLinks, IFolder<NtsBackendFolder>
    {
        public SdaidLink[] Links => new[]
        {
            Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_NtsAisLoadStatus>(),
            Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_CalculationStatus>(),
            Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_ProcessingStatus>(),
            Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_NtsModificationSelectionStatus>(),
            Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_NtsSelectionMethod>(),
            Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_Vehicle>(),
            Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleCalc>(),
            Rel.Uses<DOC_NtsCalcErrors>(),
        };

        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 Body = $$"""
        ## Назначение

        Политика вычисляет {{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_ProcessingStatus>()}}
        и читает (не вычисляет) {{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_NtsAisLoadStatus>()}} —
        его устанавливает процедура приёма данных
        ({{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Infrastructure.AisOiaPeo.DOC_NtsAisImport>()}}),
        а не эта политика. Сама политика не входит в калькулятор: `CalcService` возвращает только
        {{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_CalculationStatus>()}}, а итоговый
        статус обработки ТС определяется прикладным слоем и сохраняется в
        {{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleCalc>()}}.

        ## Входы

        - статус загрузки — {{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_NtsAisLoadStatus>()}};
        - результат калькулятора — {{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_CalculationStatus>()}};
        - способ подбора — {{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_NtsSelectionMethod>()}};
        - статус подбора модификации — {{SdaidAnchors.RefTo<Rugrid.Sdaid.Epas.Nts.Domain.DOC_NtsModificationSelectionStatus>()}}.

        ## Порядок

        1. Если статус загрузки — «Данных мало» — «Мало данных загружено», независимо от статуса
           расчёта/подбора/способа подбора: без обязательных для расчёта данных АИС они не могли
           дать осмысленный результат. Это не «проверка без обработки» — статус загрузки сам
           вычисляется процедурой приёма данных, политика только его читает.
        2. Если статус загрузки — «Загрузка выполнена» и статус подбора — «Не определена» (подбор
           выполнялся — автоматически или вручную, но для вида ТС и вида топлива этого ТС в
           справочнике «Марка, модель и модификация ТС» нет ни одной модификации с установленной
           нормой) — «Нет модификаций», **независимо от статуса расчёта**. Расчёт всё равно
           запускается безусловно (как и при любом другом составе входных данных) — валидатор
           секции `fuel.base_norm` честно вернёт `empty_collection`: «Базовая норма не определена»
           (см. {{SdaidAnchors.RefTo<DOC_NtsCalcErrors>()}}), и статус расчёта станет «Выполнен с
           ошибкой». Это не отдельная «проверка перед запуском» — политика здесь, как и везде,
           только читает уже случившийся результат расчёта и подбора, не предотвращает попытку.
           Отличие от п.3 (подбор в принципе не проводился) — в том, что здесь поиск уже состоялся
           и дал пустой результат.
        3. Если статус загрузки — «Не выполнена» или расчёт не выполнялся (и статус подбора не
           «Не определена» — см. п.2) — «Не выполнена». Отдельной ветки для «загрузка вообще не
           выполнялась» не нужно: без загрузки расчёт тоже не мог запуститься, итог тот же.
        4. Если расчёт выполнен с ошибкой — «Отсутствуют данные для расчёта».
        5. Если расчёт успешен и способ подбора — «авто» — «Автовыбор не подтверждён».
        6. Если расчёт успешен, способ подбора — «эксперт», статус подбора — «Определена группа» —
           «Модификация не определена».
        7. Если расчёт успешен, способ подбора — «эксперт», статус подбора — «Определена» —
           «Завершена».
        8. Если успешный расчёт пришёл со способом «не определён» или со статусом подбора
           «не выполнен» / «не определена», это противоречит инварианту: без базовой нормы
           успешный расчёт невозможен. Политика возвращает «Отсутствуют данные для расчёта».

        ## Таблица

        | Статус обработки | Статус загрузки | Статус подбора | Статус расчёта | Способ подбора | Цвет |
        |---|---|---|---|---|---|
        | Не выполнена | Не выполнена | любой | Не выполнен | любой | серый |
        | Мало данных загружено | Данных мало | любой | любой | любой | красный |
        | Нет модификаций | Загрузка выполнена | Не определена (подбор проводился) | Выполнен с ошибкой («Базовая норма не определена») | авто/эксперт | красный |
        | Отсутствуют данные для расчёта | Загрузка выполнена | любой | Выполнен с ошибкой | любой | красный |
        | Автовыбор не подтверждён | Загрузка выполнена | любой | Успешно выполнен | авто | жёлтый |
        | Модификация не определена | Загрузка выполнена | Определена группа | Успешно выполнен | эксперт | жёлтый |
        | Завершена | Загрузка выполнена | Определена | Успешно выполнен | эксперт | зелёный |
        """;
    }
}