ad62ac96ac
Шаг маршрута получает флаг «Автосогласование» (AutoApprove). Когда у активной строки такого шага истекает SLA, часовая задача Hangfire принимает за согласующего положительное решение: помечает строку, двигает очередь и пересчитывает статус заявки — тем же набором правил, что и портал, когда решение принимает человек (зеркало approverDecision.service.ts/decide). Флаг не nullable, в отличие от SLA рядом: наследовать его неоткуда — у типа заявки такого поля нет и быть не должно. - ApprovalRow и константы статусов переехали в общий Approvals: их теперь читают и напоминания, и автосогласование, разъезжаться разбору одного и того же списка нельзя; - SharePointClient научился MERGE'ить элементы (раньше умел только читать). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
64 lines
3.9 KiB
C#
64 lines
3.9 KiB
C#
using Tnsu.ApprovalRoute.Domain.Enums;
|
||
|
||
namespace Tnsu.ApprovalRoute.Application.TemplateRoutes;
|
||
|
||
/// <param name="SlaHours">
|
||
/// ДЕЙСТВУЮЩИЙ SLA шага в часах — наследование уже применено: значение шага, а
|
||
/// если на шаге не задано, то значение типа заявки. null означает, что SLA не
|
||
/// настроен нигде, то есть напоминаний по этому шагу не будет.
|
||
/// Резолв отдаёт именно итоговое значение, чтобы вызывающая сторона
|
||
/// (request-portal) просто записала его в строку списка согласования и не
|
||
/// повторяла у себя правило наследования.
|
||
/// </param>
|
||
/// <param name="AskOverdueReason">
|
||
/// Спрашивать ли причину просрочки — так же с уже применённым наследованием.
|
||
/// </param>
|
||
/// <param name="PositionCode">
|
||
/// HeadType шага (Chief/DirectionHead/DirectorTansu/ManagingDirectorTansu/DepartmentHead),
|
||
/// если исполнитель задан типом руководителя, иначе null. В отличие от <see cref="Position"/>
|
||
/// (реальная должность резолвнутого сотрудника из справочника api.tnsu.kz — свободный
|
||
/// текст), это код роли из самого шага маршрута — чтобы вызывающая сторона могла отличить,
|
||
/// например, «директора Tansu» от «руководителя направления», не разбирая Position текстом.
|
||
/// </param>
|
||
/// <param name="AutoApprove">
|
||
/// Согласовать шаг автоматически по истечении SLA. Значение шага маршрута как есть —
|
||
/// наследовать его неоткуда (у типа заявки такого поля нет, см.
|
||
/// TemplateRouteStep.AutoApprove). Вызывающая сторона (request-portal) просто
|
||
/// переносит его в строку списка согласования: решает по нему не она, а фоновая
|
||
/// задача бэкенда (AutoApproveService).
|
||
/// </param>
|
||
public sealed record ResolvedRouteStepDto(
|
||
int Id,
|
||
int OrderNo,
|
||
string? ExecutorEmail,
|
||
string? Position,
|
||
bool AllowReassignToOtherApprovers,
|
||
string? Warning = null,
|
||
int? SlaHours = null,
|
||
bool? AskOverdueReason = null,
|
||
HeadType? PositionCode = null,
|
||
bool AutoApprove = false);
|
||
|
||
public sealed record ResolveTemplateRouteResultDto(
|
||
int RouteId,
|
||
bool RequiresControl,
|
||
IReadOnlyList<ResolvedRouteStepDto> Steps);
|
||
|
||
/// <summary>Значение поля списка SharePoint (field_name шага) для проверки условий шагов при resolve.</summary>
|
||
public sealed record ResolveFieldValueDto(string FieldName, string Value);
|
||
|
||
/// <param name="DepartmentId">
|
||
/// Отдел для шагов с HeadType.DepartmentHead ("руководитель указанного отдела") —
|
||
/// не выводится из инициатора, поэтому должен быть передан явно. Необязателен:
|
||
/// если в маршруте нет такого шага, поле не нужно; если есть, а поле не
|
||
/// передано — шаг не резолвится и получает предупреждение (см.
|
||
/// TemplateRouteService.ResolveStepAsync), весь запрос при этом не падает.
|
||
/// </param>
|
||
public sealed record ResolveTemplateRouteRequest(
|
||
int RequestTypeId,
|
||
string? UserEmail,
|
||
Guid? ProjectId,
|
||
RouteStepStatus Status,
|
||
IReadOnlyList<ResolveFieldValueDto>? FieldValues = null,
|
||
Guid? DepartmentId = null);
|