using FluentValidation; using Microsoft.EntityFrameworkCore; using PARR.API.Contracts.V1.Requests; using PARR.Core.Repositories.Interfaces; using PARR.Core.Repositories.Interfaces.JobGroupRepositories; using PARR.Core.Repositories.Interfaces.Unit; namespace PARR.API.Validators { public class JobRequestValidator : AbstractValidator { private readonly ITnkRepository _tnkRepository; private readonly IJobGroupRepository _jobGroupRepository; private readonly IUnitFieldRepository _unitFieldRepository; public JobRequestValidator( ITnkRepository tnkRepository, IJobGroupRepository jobGroupRepository, IUnitFieldRepository unitFieldRepository, UnitFiltersBaseRequestValidator unitFilterValidator ) { _tnkRepository = tnkRepository; _jobGroupRepository = jobGroupRepository; _unitFieldRepository = unitFieldRepository; RuleFor(t => t.Name) .NotNull().NotEmpty(); RuleFor(t => t.WorkName) .NotNull().NotEmpty(); RuleFor(t => t.TnkId) .MustAsync(async (entity, value, c) => await IsTnkExist(entity)) .WithMessage("Указан несуществующий Id ТНК({PropertyValue})"); RuleFor(t => t.GroupId) .MustAsync(async (entity, value, c) => await IsGroupExist(entity)) .WithMessage("Указан несуществующий Id группы работ({PropertyValue})"); #region UnitFiters When(t => t.UnitFilters != null && t.UnitFilters.Any(), () => { RuleFor(t => t.UnitFilters) .MustAsync(async (entity, value, c) => { // Проверяем флаг в БД: разрешены ли фильтры для этой группы return await jobGroupRepository.Get() .AnyAsync(t => t.Id == entity.GroupId && t.GroupType!.IsAllowJobUnitFilter == true, c); }) .WithMessage("Дополнительные фильтры запрещены") // Stop делает так, что если флаг равен false, FluentValidation остановится // и НЕ пойдет выполнять Include базового валидатора (сэкономим запрос к БД) .DependentRules(() => { // Этот валидатор сработает ПОСЛЕ успешной проверки флага IsAllowJobUnitFilter Include(unitFilterValidator); }); }); #endregion RuleFor(t => t.Relationships) .MustAsync(async (entity, value, c) => { // Relationships должны быть обязательно заполнены если в типе работ IsRelationshipsAllowed==true var relationshipsIsRequired = await jobGroupRepository.Get() .AnyAsync(t => t.Id == entity.GroupId && t.GroupType!.IsRelationshipsAllowed, c); if (relationshipsIsRequired && value != null) return true; if (!relationshipsIsRequired && value == null) return true; return false; }) .WithMessage("Некорректные настройки кол-ва связей"); When(t => t.Relationships != null, () => { RuleFor(t => t.Relationships!.MinValueRelationships) .GreaterThanOrEqualTo(0); RuleFor(t => t.Relationships!.MaxValueRelationships) .GreaterThanOrEqualTo(t => t.Relationships!.MinValueRelationships); }); RuleFor(t => t.ResponseAreaMask) .NotNull().NotEmpty(); RuleFor(t => t.AutoControl) .MustAsync(async (entity, value, c) => { // Автоконтроль разрешен только типам работ, у которых выключен IsJobGroupAutoControl var isAllowedJobAutocontrol = await jobGroupRepository.Get() .AnyAsync(t => t.Id == entity.GroupId && t.GroupType!.IsJobGroupAutoControl == false, c); // Разрешен автоконтроль и есть значение if (isAllowedJobAutocontrol && value != null) return true; // Запрещен автоконтроль и нет значения if (!isAllowedJobAutocontrol && value == null) return true; return false; }) .WithMessage("Некорректные параметры автоконтроля"); } private async Task IsGroupExist(JobRequest entity) { var jobGroup = await _jobGroupRepository.GetAsync(entity.GroupId); return jobGroup != null; } private async Task IsTnkExist(JobRequest entity) { return await _tnkRepository.GetAsync(entity.TnkId) != null; } } }