feat(api,core,dal): Группы работ - управление автокнотролем

This commit is contained in:
Mikhail Trubnikov
2026-06-18 16:39:35 +10:00
parent 108eb05853
commit 8151ea89b9
18 changed files with 4326 additions and 186 deletions

View File

@@ -1,33 +0,0 @@
using FluentValidation;
using PARR.API.Contracts.V1.Requests;
using PARR.Domain.Enums;
namespace PARR.API.Validators
{
public class JobAutoControlRequestValidator : AbstractValidator<JobAutoControlRequest>
{
public JobAutoControlRequestValidator()
{
RuleFor(t => t.EkMasks).Must(items =>
items.Count(t => t.Trim().Length > 0) > 0
).WithMessage("Должна быть указана хотя бы одна маска ЭК");
RuleFor(t => t.EnabledEkStatuses).Must(
items => items.Distinct().Count() == items.Count()
).WithMessage("Статусы ЭК не должны повторяться");
RuleFor(t => t.EnabledEkStatuses).Must(items =>
{
return !items.Any(item => !Enum.IsDefined(typeof(EkStatusEnum), item)) && !items.Any(t => t == 0);
})
.WithMessage($"Допустимые значения: {(int)EkStatusEnum.New} ({EkStatusEnum.New}), " +
$"{(int)EkStatusEnum.Preapre} ({EkStatusEnum.Preapre}), " +
$"{(int)EkStatusEnum.Exploitation} ({EkStatusEnum.Exploitation}), " +
$"{(int)EkStatusEnum.Repair} ({EkStatusEnum.Repair}), " +
$"{(int)EkStatusEnum.Reserve} ({EkStatusEnum.Reserve}), " +
$"{(int)EkStatusEnum.OutOfService} ({EkStatusEnum.OutOfService}), " +
$"{(int)EkStatusEnum.Test} ({EkStatusEnum.Test}), " +
$"{(int)EkStatusEnum.Development} ({EkStatusEnum.Development})");
}
}
}

View File

@@ -12,11 +12,11 @@ namespace PARR.API.Validators
public class JobGroupValidator : AbstractValidator<JobGroupRequest>
{
public JobGroupValidator(
IJobGroupTypeRepository jobGroupTypeService,
IUnitFieldRepository unitFieldService,
IScheduleExcludeTypeRepository scheduleExcludeTypeService,
IScheduleExcludeTypeCalendarRepository scheduleExcludeTypeCalendarService,
IDistributionPeriodRepository distributionPeriodService
IJobGroupTypeRepository jobGroupTypeRepository,
IUnitFieldRepository unitFieldRepository,
IScheduleExcludeTypeRepository scheduleExcludeTypeRepository,
IScheduleExcludeTypeCalendarRepository scheduleExcludeTypeCalendarRepository,
IDistributionPeriodRepository distributionPeriodRepository
)
{
RuleFor(t => t.Name)
@@ -35,7 +35,7 @@ namespace PARR.API.Validators
.NotNull().NotEmpty();
RuleFor(t => t.GroupTypeId)
.MustAsync(async (entity, value, c) => await jobGroupTypeService.GetAsync(value) != null)
.MustAsync(async (entity, value, c) => await jobGroupTypeRepository.GetAsync(value) != null)
.WithMessage("Указан несуществующий Id типа");
//Проверяем существует ли такой GroupingUnitFieldId в unitField
@@ -47,7 +47,7 @@ namespace PARR.API.Validators
return true;
}
return await unitFieldService.GetAsync(value.Value) != null;
return await unitFieldRepository.GetAsync(value.Value) != null;
})
.WithMessage("Указано несуществующий Id поля");
@@ -55,7 +55,7 @@ namespace PARR.API.Validators
RuleFor(t => t.GroupingUnitFieldId)
.MustAsync(async (entity, value, c) =>
{
var groupingJobType = await jobGroupTypeService.Get().FirstAsync(t => t.Code == JobGroupTypesEnum.Group);
var groupingJobType = await jobGroupTypeRepository.Get().FirstAsync(t => t.Code == JobGroupTypesEnum.Group);
// Если это сгруппированный тип, то у него обязательно должно быть заполнено поле GroupingUnitFieldId
if (entity.GroupTypeId == groupingJobType.Id)
@@ -68,14 +68,14 @@ namespace PARR.API.Validators
RuleFor(t => t.ScheduleExcludeTypeId)
.NotNull()
.NotEmpty()
.MustAsync(async (entity, value, c) => await scheduleExcludeTypeService.GetAsync(value) != null)
.MustAsync(async (entity, value, c) => await scheduleExcludeTypeRepository.GetAsync(value) != null)
.WithMessage("Некорректное значение");
RuleFor(t => t.ScheduleExcludeTypeCalendarId)
.MustAsync(async (entity, value, c) =>
{
// Если выбрано "Нет исключений", то это поле должно быть пустое, иначе, должно быть валидное значение
var type = await scheduleExcludeTypeService.GetAsync(entity.ScheduleExcludeTypeId);
var type = await scheduleExcludeTypeRepository.GetAsync(entity.ScheduleExcludeTypeId);
if (type == null)
return false;
@@ -89,7 +89,7 @@ namespace PARR.API.Validators
if (!value.HasValue)
return false;
return await scheduleExcludeTypeCalendarService.GetAsync(value.Value) != null;
return await scheduleExcludeTypeCalendarRepository.GetAsync(value.Value) != null;
})
.WithMessage("Некорректное значение");
@@ -115,7 +115,7 @@ namespace PARR.API.Validators
if (periodId.HasValue)
{
var exist = await distributionPeriodService.GetAsync(periodId.Value);
var exist = await distributionPeriodRepository.GetAsync(periodId.Value);
return exist != null;
}
@@ -129,7 +129,24 @@ namespace PARR.API.Validators
// если IsResponseAreaTimezone == true, то поле UserTimeZoneOffsetMinutes обязательно.
// если IsResponseAreaTimezone == false, то UserTimeZoneOffsetMinutes должно быть null
return (entity.IsWorkGroupTimezone && value != null) || (!entity.IsWorkGroupTimezone && value == null);
}).WithMessage("Некорректное значение."); ;
}).WithMessage("Некорректное значение.");
RuleFor(t => t.AutoControl)
.MustAsync(async (entity, value, c) =>
{
// Автоконтроль разрешен только типам работ у которых включен IsJobGroupAutoControl
var isAllowedAutocontrol = await jobGroupTypeRepository.Get().AsNoTracking().AnyAsync(t => t.Id == entity.GroupTypeId && t.IsJobGroupAutoControl == true);
// Разрешен автоконтроль и есть значение
if (isAllowedAutocontrol && value != null)
return true;
// Запрещен автоконтроль и нет значения
if (!isAllowedAutocontrol && value == null)
return true;
return false;
})
.WithMessage("Не верные параметры автоконтроля");
}
}