основное сделано
This commit is contained in:
@@ -2,6 +2,11 @@ using Tnsu.ApprovalRoute.Domain.Enums;
|
||||
|
||||
namespace Tnsu.ApprovalRoute.Application.TemplateRouteSteps;
|
||||
|
||||
// SlaHours/AskOverdueReason у шага перекрывают одноимённые поля типа заявки.
|
||||
// null — «не задано, наследовать», поэтому оба поля nullable и необязательны
|
||||
// (0 часов и false — это осознанный выбор, а не «пусто»). Добавлены в конец
|
||||
// записей, чтобы не ломать существующие позиционные вызовы.
|
||||
|
||||
public sealed record TemplateRouteStepDto(
|
||||
int Id,
|
||||
int OrderNo,
|
||||
@@ -15,7 +20,9 @@ public sealed record TemplateRouteStepDto(
|
||||
string? FieldName,
|
||||
ComparisonOperator? Operation,
|
||||
string? Value,
|
||||
string? Warning = null);
|
||||
string? Warning = null,
|
||||
int? SlaHours = null,
|
||||
bool? AskOverdueReason = null);
|
||||
|
||||
public sealed record CreateTemplateRouteStepRequest(
|
||||
int OrderNo,
|
||||
@@ -27,7 +34,9 @@ public sealed record CreateTemplateRouteStepRequest(
|
||||
bool AllowReassignToOtherApprovers,
|
||||
string? FieldName,
|
||||
ComparisonOperator? Operation,
|
||||
string? Value);
|
||||
string? Value,
|
||||
int? SlaHours = null,
|
||||
bool? AskOverdueReason = null);
|
||||
|
||||
public sealed record UpdateTemplateRouteStepRequest(
|
||||
int OrderNo,
|
||||
@@ -39,7 +48,9 @@ public sealed record UpdateTemplateRouteStepRequest(
|
||||
bool AllowReassignToOtherApprovers,
|
||||
string? FieldName,
|
||||
ComparisonOperator? Operation,
|
||||
string? Value);
|
||||
string? Value,
|
||||
int? SlaHours = null,
|
||||
bool? AskOverdueReason = null);
|
||||
|
||||
public sealed record PatchTemplateRouteStepRequest(
|
||||
int? OrderNo,
|
||||
@@ -51,4 +62,6 @@ public sealed record PatchTemplateRouteStepRequest(
|
||||
bool? AllowReassignToOtherApprovers,
|
||||
string? FieldName,
|
||||
ComparisonOperator? Operation,
|
||||
string? Value);
|
||||
string? Value,
|
||||
int? SlaHours = null,
|
||||
bool? AskOverdueReason = null);
|
||||
|
||||
+11
-3
@@ -16,7 +16,7 @@ public sealed class TemplateRouteStepService(ApprovalRouteDbContext db)
|
||||
.OrderBy(x => x.OrderNo)
|
||||
.Select(x => new TemplateRouteStepDto(
|
||||
x.Id, x.OrderNo, x.ExecutorEmail, x.Position, x.ProjectRole, x.HeadType, x.Status, x.RouteId, x.AllowReassignToOtherApprovers,
|
||||
x.FieldName, x.Operation, x.Value))
|
||||
x.FieldName, x.Operation, x.Value, null, x.SlaHours, x.AskOverdueReason))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Result.Ok<IReadOnlyList<TemplateRouteStepDto>>(items);
|
||||
@@ -73,7 +73,9 @@ public sealed class TemplateRouteStepService(ApprovalRouteDbContext db)
|
||||
AllowReassignToOtherApprovers = r.AllowReassignToOtherApprovers,
|
||||
FieldName = r.FieldName,
|
||||
Operation = r.Operation,
|
||||
Value = r.Value
|
||||
Value = r.Value,
|
||||
SlaHours = r.SlaHours,
|
||||
AskOverdueReason = r.AskOverdueReason
|
||||
};
|
||||
db.TemplateRouteSteps.Add(entity);
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
@@ -125,6 +127,8 @@ public sealed class TemplateRouteStepService(ApprovalRouteDbContext db)
|
||||
entity.FieldName = r.FieldName;
|
||||
entity.Operation = r.Operation;
|
||||
entity.Value = r.Value;
|
||||
entity.SlaHours = r.SlaHours;
|
||||
entity.AskOverdueReason = r.AskOverdueReason;
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(await ToDtoWithWarningAsync(entity, route, cancellationToken));
|
||||
@@ -190,6 +194,10 @@ public sealed class TemplateRouteStepService(ApprovalRouteDbContext db)
|
||||
entity.FieldName = fieldName;
|
||||
entity.Operation = operation;
|
||||
entity.Value = value;
|
||||
// Как и остальные поля в PATCH, null значит «не менять». Вернуть шаг к
|
||||
// наследованию SLA от типа заявки можно через PUT.
|
||||
entity.SlaHours = r.SlaHours ?? entity.SlaHours;
|
||||
entity.AskOverdueReason = r.AskOverdueReason ?? entity.AskOverdueReason;
|
||||
await db.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return Result.Ok(await ToDtoWithWarningAsync(entity, route, cancellationToken));
|
||||
@@ -281,5 +289,5 @@ public sealed class TemplateRouteStepService(ApprovalRouteDbContext db)
|
||||
|
||||
private static TemplateRouteStepDto ToDto(TemplateRouteStep e) => new(
|
||||
e.Id, e.OrderNo, e.ExecutorEmail, e.Position, e.ProjectRole, e.HeadType, e.Status, e.RouteId, e.AllowReassignToOtherApprovers,
|
||||
e.FieldName, e.Operation, e.Value);
|
||||
e.FieldName, e.Operation, e.Value, null, e.SlaHours, e.AskOverdueReason);
|
||||
}
|
||||
|
||||
+12
@@ -14,6 +14,12 @@ public sealed class CreateTemplateRouteStepRequestValidator : AbstractValidator<
|
||||
RuleFor(x => x)
|
||||
.Must(x => TemplateRouteStepFields.IsConditionValid(x.FieldName, x.Operation, x.Value))
|
||||
.WithMessage("Поля условия (field_name, operation, value) должны быть заполнены все вместе или не заполнены вовсе.");
|
||||
// Отрицательный SLA сделал бы шаг просроченным уже в момент активации;
|
||||
// ноль допустим — это осознанное «напоминать сразу».
|
||||
RuleFor(x => x.SlaHours)
|
||||
.GreaterThanOrEqualTo(0)
|
||||
.When(x => x.SlaHours is not null)
|
||||
.WithMessage("SLA в часах не может быть отрицательным.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +34,12 @@ public sealed class UpdateTemplateRouteStepRequestValidator : AbstractValidator<
|
||||
RuleFor(x => x)
|
||||
.Must(x => TemplateRouteStepFields.IsConditionValid(x.FieldName, x.Operation, x.Value))
|
||||
.WithMessage("Поля условия (field_name, operation, value) должны быть заполнены все вместе или не заполнены вовсе.");
|
||||
// Отрицательный SLA сделал бы шаг просроченным уже в момент активации;
|
||||
// ноль допустим — это осознанное «напоминать сразу».
|
||||
RuleFor(x => x.SlaHours)
|
||||
.GreaterThanOrEqualTo(0)
|
||||
.When(x => x.SlaHours is not null)
|
||||
.WithMessage("SLA в часах не может быть отрицательным.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user