feat(api): JobGroup - управление юнит фильтрами
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
namespace PARR.API.Contracts.V1.Requests
|
||||
{
|
||||
public record JobGroupRequest
|
||||
public record JobGroupRequest : UnitFiltersBaseRequest
|
||||
{
|
||||
public required string Name { get; init; }
|
||||
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
namespace PARR.API.Contracts.V1.Requests
|
||||
{
|
||||
public record JobRequest
|
||||
public record JobRequest : UnitFiltersBaseRequest
|
||||
{
|
||||
|
||||
public required Guid TnkId { get; init; }
|
||||
|
||||
public required Guid GroupId { get; init; }
|
||||
|
||||
public required string Name { get; init; }
|
||||
|
||||
//public int? MinValueRelationships { get; init; }
|
||||
|
||||
//public int? MaxValueRelationships { get; init; }
|
||||
|
||||
//public bool? IsParentRelationships { get; init; }
|
||||
|
||||
public JobRelationships? Relationships { get; init; }
|
||||
|
||||
public required string TemplateNameMask { get; init; }
|
||||
@@ -25,19 +18,9 @@
|
||||
|
||||
public required string ResponseAreaMask { get; init; }
|
||||
|
||||
//#region AutoControl
|
||||
|
||||
//public bool IsEnableAutoControl { get; set; }
|
||||
|
||||
//public bool InitUsedTemplateState { get; set; }
|
||||
|
||||
//public bool InitUsedScheduleState { get; set; }
|
||||
|
||||
//#endregion
|
||||
|
||||
public JobAutoControlRequest? AutoControl { get; init; }
|
||||
|
||||
public required List<UnitFilterRequest> UnitFilters { get; init; }
|
||||
//public required List<UnitFilterRequest> UnitFilters { get; init; }
|
||||
}
|
||||
|
||||
public record JobRelationships
|
||||
@@ -49,43 +32,38 @@
|
||||
public bool IsParentRelationships { get; init; }
|
||||
}
|
||||
|
||||
public record UnitFilterRequest
|
||||
{
|
||||
///// <summary>
|
||||
///// Id = null в методе Create, в Update обязателен
|
||||
///// </summary>
|
||||
//public Guid? Id { get; set; }
|
||||
//public record UnitFilterRequest
|
||||
//{
|
||||
// public required string UnitFilterMask { get; init; }
|
||||
|
||||
public required string UnitFilterMask { get; init; }
|
||||
// public List<FieldFilterRequest>? FieldFilters { get; init; }
|
||||
|
||||
public List<FieldFilterRequest>? FieldFilters { get; init; }
|
||||
|
||||
public List<RelationshipFilterRequest>? RelationshipFilters { get; init; }
|
||||
}
|
||||
// public List<RelationshipFilterRequest>? RelationshipFilters { get; init; }
|
||||
//}
|
||||
|
||||
|
||||
public record FieldFilterRequest
|
||||
{
|
||||
//public record FieldFilterRequest
|
||||
//{
|
||||
|
||||
public Guid FieldId { get; init; }
|
||||
// public Guid FieldId { get; init; }
|
||||
|
||||
public string? ValueMask { get; init; }
|
||||
// public string? ValueMask { get; init; }
|
||||
|
||||
public bool IsInverse { get; init; } = false;
|
||||
// public bool IsInverse { get; init; } = false;
|
||||
|
||||
}
|
||||
//}
|
||||
|
||||
|
||||
public record RelationshipFilterRequest
|
||||
{
|
||||
public Guid FieldId { get; init; }
|
||||
//public record RelationshipFilterRequest
|
||||
//{
|
||||
// public Guid FieldId { get; init; }
|
||||
|
||||
public bool? IsParent { get; init; }
|
||||
// public bool? IsParent { get; init; }
|
||||
|
||||
public string? ValueMask { get; init; }
|
||||
// public string? ValueMask { get; init; }
|
||||
|
||||
public bool? IsFullMatch { get; init; }
|
||||
// public bool? IsFullMatch { get; init; }
|
||||
|
||||
public bool? IsInverse { get; init; }
|
||||
}
|
||||
// public bool? IsInverse { get; init; }
|
||||
//}
|
||||
}
|
||||
42
PARR.API/Contracts/V1/Requests/UnitFiltersBaseRequest.cs
Normal file
42
PARR.API/Contracts/V1/Requests/UnitFiltersBaseRequest.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
namespace PARR.API.Contracts.V1.Requests
|
||||
{
|
||||
/// <summary>
|
||||
/// Unit фильтры для Job и JobGroup
|
||||
/// </summary>
|
||||
public record UnitFiltersBaseRequest
|
||||
{
|
||||
public required List<UnitFilterRequest> UnitFilters { get; init; }
|
||||
}
|
||||
|
||||
public record UnitFilterRequest
|
||||
{
|
||||
public required string UnitFilterMask { get; init; }
|
||||
|
||||
public List<FieldFilterRequest>? FieldFilters { get; init; }
|
||||
|
||||
public List<RelationshipFilterRequest>? RelationshipFilters { get; init; }
|
||||
}
|
||||
|
||||
public record FieldFilterRequest
|
||||
{
|
||||
public Guid FieldId { get; init; }
|
||||
|
||||
public string? ValueMask { get; init; }
|
||||
|
||||
public bool IsInverse { get; init; } = false;
|
||||
|
||||
}
|
||||
|
||||
public record RelationshipFilterRequest
|
||||
{
|
||||
public Guid FieldId { get; init; }
|
||||
|
||||
public bool? IsParent { get; init; }
|
||||
|
||||
public string? ValueMask { get; init; }
|
||||
|
||||
public bool? IsFullMatch { get; init; }
|
||||
|
||||
public bool? IsInverse { get; init; }
|
||||
}
|
||||
}
|
||||
@@ -361,7 +361,7 @@ namespace PARR.API.Controllers.V1
|
||||
.Include(t => t.Group).ThenInclude(t => t.GroupingUnitField)
|
||||
.Include(t => t.UnitFilters)
|
||||
.ThenInclude(t => t.FieldFilters)
|
||||
.ThenInclude(t => t.UnitField)
|
||||
.ThenInclude(t => t.UnitField)
|
||||
.Include(t => t.UnitFilters)
|
||||
.ThenInclude(t => t.RelationshipFilters)
|
||||
.Include(t => t.AutoControl)
|
||||
@@ -411,124 +411,6 @@ namespace PARR.API.Controllers.V1
|
||||
|
||||
orig.UnitFilters.Add(newUnitFilter);
|
||||
}
|
||||
|
||||
#region old
|
||||
/* Писал полноценный апдейт, но Миша сказал что нахрен это - просто все удаляем, а потом создаём заново... Ох уж этот Миша...
|
||||
//Сразу удаляем UnitFilter которых нет
|
||||
var toDelete = orig.UnitFilters.Where(t => !mappedRequest.UnitFilters.Any(e => e.Id == t.Id));
|
||||
foreach (var item in toDelete)
|
||||
orig.UnitFilters.Remove(item);
|
||||
|
||||
foreach (var mappedUnitFilter in mappedRequest.UnitFilters)
|
||||
{
|
||||
var origUnitFilter = orig.UnitFilters.FirstOrDefault(t => t.Id == mappedUnitFilter.Id);
|
||||
|
||||
if (origUnitFilter == null)
|
||||
{
|
||||
var newUnitFilter = new JobUnitFilter
|
||||
{
|
||||
UnitFilter = mappedUnitFilter.UnitFilter,
|
||||
DateCreated = DateTimeOffset.UtcNow,
|
||||
JobId = orig.Id
|
||||
};
|
||||
|
||||
foreach (var newRequestFieldFilter in mappedUnitFilter.FieldFilters)
|
||||
{
|
||||
var newFieldFilter = CreateFieldFilter(newUnitFilter.Id, newRequestFieldFilter.FieldId, newRequestFieldFilter.ValueMask);
|
||||
|
||||
newUnitFilter.FieldFilters.Add(newFieldFilter);
|
||||
}
|
||||
|
||||
foreach (var newRequestRelationshipFilter in mappedUnitFilter.RelationshipFilters)
|
||||
{
|
||||
var newRelationshipFilter = CreateRelationshipFilter(newRequestRelationshipFilter.FieldId,
|
||||
newRequestRelationshipFilter.IsParent,
|
||||
newRequestRelationshipFilter.IsFullMatch,
|
||||
newRequestRelationshipFilter.IsInverse,
|
||||
newRequestRelationshipFilter.ValueMask);
|
||||
newUnitFilter.RelationshipFilters.Add(newRelationshipFilter);
|
||||
}
|
||||
|
||||
orig.UnitFilters.Add(newUnitFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
#region Непосредственно UnitFilter
|
||||
if (origUnitFilter.UnitFilter != mappedUnitFilter.UnitFilter)
|
||||
{
|
||||
origUnitFilter.UnitFilter = mappedUnitFilter.UnitFilter;
|
||||
origUnitFilter.DateModified = DateTimeOffset.UtcNow;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region FieldFilters
|
||||
//Сразу удаляем неактуальные
|
||||
var fieldFiltersToDelete = origUnitFilter.FieldFilters.Where(t => !mappedUnitFilter.FieldFilters.Any(m => m.FieldId == t.FieldId));
|
||||
foreach (var item in fieldFiltersToDelete)
|
||||
origUnitFilter.FieldFilters.Remove(item);
|
||||
|
||||
//Перебираем FieldFilter
|
||||
foreach (var mappedFieldFilter in mappedUnitFilter.FieldFilters)
|
||||
{
|
||||
var origFieldFilter = origUnitFilter.FieldFilters.FirstOrDefault(t => t.FieldId == mappedFieldFilter.FieldId);
|
||||
|
||||
if (origFieldFilter == null)//Нет в БД? не проблема - создадим
|
||||
{
|
||||
var newFieldFilter = CreateFieldFilter(origUnitFilter.Id, mappedFieldFilter.FieldId, mappedFieldFilter.ValueMask);
|
||||
origUnitFilter.FieldFilters.Add(newFieldFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (origFieldFilter.ValueMask != mappedFieldFilter.ValueMask)
|
||||
{
|
||||
origFieldFilter.ValueMask = mappedFieldFilter.ValueMask;
|
||||
origFieldFilter.DateModified = DateTimeOffset.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RelationshipFilters
|
||||
//Сразу удаляем неактуальные
|
||||
var relationshipFiltersToDelete = origUnitFilter.RelationshipFilters.Where(t => !mappedUnitFilter.RelationshipFilters.Any(m => m.FieldId == t.FieldId));
|
||||
foreach (var item in relationshipFiltersToDelete)
|
||||
origUnitFilter.RelationshipFilters.Remove(item);
|
||||
|
||||
//Перебираем RelationshipFilters
|
||||
foreach (var mappedRelationshipFilter in mappedUnitFilter.RelationshipFilters)
|
||||
{
|
||||
var origRelationshipFilter = origUnitFilter.RelationshipFilters.FirstOrDefault(t => t.FieldId == mappedRelationshipFilter.FieldId);
|
||||
|
||||
if (origRelationshipFilter == null)//Нет в БД? не проблема - создадим
|
||||
{
|
||||
var newRelationshipFilter = CreateRelationshipFilter(mappedRelationshipFilter.FieldId,
|
||||
mappedRelationshipFilter.IsParent,
|
||||
mappedRelationshipFilter.IsFullMatch,
|
||||
mappedRelationshipFilter.IsInverse,
|
||||
mappedRelationshipFilter.ValueMask);
|
||||
|
||||
origUnitFilter.RelationshipFilters.Add(newRelationshipFilter);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (origRelationshipFilter.IsParent != mappedRelationshipFilter.IsParent)
|
||||
origRelationshipFilter.IsParent = mappedRelationshipFilter.IsParent;
|
||||
|
||||
if (origRelationshipFilter.ValueMask != mappedRelationshipFilter.ValueMask)
|
||||
origRelationshipFilter.ValueMask = mappedRelationshipFilter.ValueMask;
|
||||
|
||||
if (origRelationshipFilter.IsFullMatch != mappedRelationshipFilter.IsFullMatch)
|
||||
origRelationshipFilter.IsFullMatch = mappedRelationshipFilter.IsFullMatch;
|
||||
|
||||
if (origRelationshipFilter.IsInverse != mappedRelationshipFilter.IsInverse)
|
||||
origRelationshipFilter.IsInverse = mappedRelationshipFilter.IsInverse;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}*/
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
private static JobRelationshipFilter CreateRelationshipFilter(Guid fieldId, bool isParent, bool isFullMatch, bool isInverse, string valueMask)
|
||||
|
||||
@@ -177,7 +177,8 @@ namespace PARR.API.Controllers.V1
|
||||
ScheduleExcludeTypeCalendarId = request.ScheduleExcludeTypeCalendarId,
|
||||
IsAutoDistributionEnabled = request.IsAutoDistributionEnabled,
|
||||
IsResponseAreaTimezone = request.IsWorkGroupTimezone,
|
||||
IsGroupByResponsible = request.IsGroupByResponsible
|
||||
IsGroupByResponsible = request.IsGroupByResponsible,
|
||||
UnitFilters = new List<JobGroupUnitFilter>()
|
||||
//IsAgent = request.IsAgent,
|
||||
//AgentName = request.AgentName,
|
||||
//AgentTimeOutSec = request.AgentTimeOutSec,
|
||||
@@ -214,6 +215,12 @@ namespace PARR.API.Controllers.V1
|
||||
|
||||
#endregion
|
||||
|
||||
#region Фильтры
|
||||
|
||||
jobGroup.UnitFilters = MapUnitFilters(request.UnitFilters, jobGroup.Id);
|
||||
|
||||
#endregion
|
||||
|
||||
//Добавляем настройки планировщика
|
||||
request.Schedule.ForEach(item =>
|
||||
{
|
||||
@@ -264,6 +271,10 @@ namespace PARR.API.Controllers.V1
|
||||
.Include(t => t.EsppSchValues)
|
||||
.Include(t => t.AutoControl)
|
||||
.Include(t => t.DistributionConfig).ThenInclude(t => t.DistributionPeriod)
|
||||
.Include(t => t.UnitFilters)
|
||||
.ThenInclude(t => t.FieldFilters)
|
||||
.Include(t => t.UnitFilters)
|
||||
.ThenInclude(t => t.RelationshipFilters)
|
||||
.FirstOrDefaultAsync(t => t.Id == id);
|
||||
|
||||
if (orig == null)
|
||||
@@ -274,7 +285,6 @@ namespace PARR.API.Controllers.V1
|
||||
throw new AppValidationException("Запрещено изменение поля 'Тип работ'");
|
||||
|
||||
|
||||
|
||||
//Расписание было изменено, ниже добавим задание в очередь на обновление расписаний у связанных шаблонов
|
||||
var isScheduleChanged = IsScheduleChanged(orig, request);
|
||||
|
||||
@@ -371,6 +381,14 @@ namespace PARR.API.Controllers.V1
|
||||
|
||||
#endregion
|
||||
|
||||
#region Фильтры
|
||||
|
||||
orig.UnitFilters.Clear();
|
||||
|
||||
orig.UnitFilters = MapUnitFilters(request.UnitFilters, orig.Id);
|
||||
|
||||
#endregion
|
||||
|
||||
//обновляем планировщик
|
||||
orig.EsppSchValues.Clear();
|
||||
request.Schedule.ForEach(item =>
|
||||
@@ -465,6 +483,48 @@ namespace PARR.API.Controllers.V1
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Обновление юнит фильтров
|
||||
/// </summary>
|
||||
/// <param name="requestFilters"></param>
|
||||
/// <param name="jobGroupId"></param>
|
||||
/// <returns></returns>
|
||||
private List<JobGroupUnitFilter> MapUnitFilters(List<UnitFilterRequest> requestFilters, Guid jobGroupId)
|
||||
{
|
||||
return requestFilters.Select(requestFilter =>
|
||||
{
|
||||
var filterId = Guid.NewGuid();
|
||||
return new JobGroupUnitFilter
|
||||
{
|
||||
Id = filterId,
|
||||
DateCreated = DateTimeOffset.UtcNow,
|
||||
JobGroupId = jobGroupId, // Явно связываем с группой работ
|
||||
UnitFilter = requestFilter.UnitFilterMask,
|
||||
FieldFilters = requestFilter.FieldFilters?.Select(t => new JobGroupFieldFilter
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
DateCreated = DateTimeOffset.UtcNow,
|
||||
UnitFilterId = filterId,
|
||||
FieldId = t.FieldId,
|
||||
ValueMask = t.ValueMask ?? string.Empty,
|
||||
IsInverse = t.IsInverse
|
||||
}).ToList() ?? new List<JobGroupFieldFilter>(),
|
||||
RelationshipFilters = requestFilter.RelationshipFilters?.Select(t => new JobGroupRelationshipFilter
|
||||
{
|
||||
UnitFilterId = filterId,
|
||||
FieldId = t.FieldId,
|
||||
IsParent = t.IsParent ?? false,
|
||||
ValueMask = t.ValueMask ?? string.Empty,
|
||||
IsFullMatch = t.IsFullMatch ?? false,
|
||||
IsInverse = t.IsInverse ?? false
|
||||
}).ToList() ?? new List<JobGroupRelationshipFilter>()
|
||||
};
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Удалить настройки автоконтроля для связанных Job
|
||||
/// </summary>
|
||||
|
||||
@@ -16,7 +16,8 @@ namespace PARR.API.Validators
|
||||
IUnitFieldRepository unitFieldRepository,
|
||||
IScheduleExcludeTypeRepository scheduleExcludeTypeRepository,
|
||||
IScheduleExcludeTypeCalendarRepository scheduleExcludeTypeCalendarRepository,
|
||||
IDistributionPeriodRepository distributionPeriodRepository
|
||||
IDistributionPeriodRepository distributionPeriodRepository,
|
||||
UnitFiltersBaseRequestValidator unitFilterValidator
|
||||
)
|
||||
{
|
||||
RuleFor(t => t.Name)
|
||||
@@ -38,6 +39,9 @@ namespace PARR.API.Validators
|
||||
.MustAsync(async (entity, value, c) => await jobGroupTypeRepository.GetAsync(value) != null)
|
||||
.WithMessage("Указан несуществующий Id типа");
|
||||
|
||||
// Валидация фильтров (они могут быть пустые, мы так договорились)
|
||||
Include(unitFilterValidator);
|
||||
|
||||
//Проверяем существует ли такой GroupingUnitFieldId в unitField
|
||||
RuleFor(t => t.GroupingUnitFieldId)
|
||||
.MustAsync(async (entity, value, c) =>
|
||||
@@ -149,7 +153,6 @@ namespace PARR.API.Validators
|
||||
return false;
|
||||
})
|
||||
.WithMessage("Некорректные параметры автоконтроля");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ namespace PARR.API.Validators
|
||||
public JobRequestValidator(
|
||||
ITnkRepository tnkRepository,
|
||||
IJobGroupRepository jobGroupRepository,
|
||||
IUnitFieldRepository unitFieldRepository
|
||||
IUnitFieldRepository unitFieldRepository,
|
||||
UnitFiltersBaseRequestValidator unitFilterValidator
|
||||
)
|
||||
{
|
||||
_tnkRepository = tnkRepository;
|
||||
@@ -38,12 +39,15 @@ namespace PARR.API.Validators
|
||||
.MustAsync(async (entity, value, c) => await IsGroupExist(entity))
|
||||
.WithMessage("Указан несуществующий Id группы работ({PropertyValue})");
|
||||
|
||||
RuleForEach(t => t.UnitFilters)
|
||||
.NotNull().NotEmpty();
|
||||
//RuleForEach(t => t.UnitFilters)
|
||||
// .NotNull().NotEmpty();
|
||||
|
||||
RuleForEach(t => t.UnitFilters)
|
||||
.MustAsync(async (entity, value, c) => await IsUnitFiltersCorrect(entity))
|
||||
.WithMessage("Неверно заданы параметры фильтров. Внимательнее, пожалуйста!");
|
||||
// Валидация фильтров (они могут быть пустые, мы так договорились)
|
||||
Include(unitFilterValidator);
|
||||
|
||||
//RuleForEach(t => t.UnitFilters)
|
||||
// .MustAsync(async (entity, value, c) => await IsUnitFiltersCorrect(entity))
|
||||
// .WithMessage("Неверно заданы параметры фильтров.");
|
||||
|
||||
RuleFor(t => t.Relationships)
|
||||
.MustAsync(async (entity, value, c) =>
|
||||
@@ -95,35 +99,64 @@ namespace PARR.API.Validators
|
||||
.WithMessage("Некорректные параметры автоконтроля");
|
||||
}
|
||||
|
||||
private async Task<bool> IsUnitFiltersCorrect(JobRequest entity)
|
||||
{
|
||||
foreach (var unitFilter in entity.UnitFilters)
|
||||
{
|
||||
if (string.IsNullOrEmpty(unitFilter.UnitFilterMask))
|
||||
return false;
|
||||
//private async Task<bool> IsUnitFiltersCorrect(JobRequest entity)
|
||||
//{
|
||||
// // 1. Проверим маски, они не должны быть пустыми
|
||||
// foreach (var unitFilter in entity.UnitFilters)
|
||||
// {
|
||||
// if (string.IsNullOrEmpty(unitFilter.UnitFilterMask))
|
||||
// return false;
|
||||
// }
|
||||
|
||||
//if (unitFilter.FieldFilters == null || !unitFilter.FieldFilters.Any())
|
||||
// return false;
|
||||
// // 2. Собираем все уникальные FieldId из всех фильтров в памяти
|
||||
// var requestedFieldIds = entity.UnitFilters
|
||||
// .SelectMany(uf =>
|
||||
// (uf.FieldFilters ?? Enumerable.Empty<FieldFilterRequest>()).Select(ff => ff.FieldId)
|
||||
// .Concat((uf.RelationshipFilters ?? Enumerable.Empty<RelationshipFilterRequest>()).Select(rf => rf.FieldId)))
|
||||
// .Distinct()
|
||||
// .ToList();
|
||||
|
||||
if (unitFilter.FieldFilters != null && unitFilter.FieldFilters.Any())
|
||||
foreach (var fieldFilter in unitFilter.FieldFilters)
|
||||
{
|
||||
var fieldId = fieldFilter.FieldId;
|
||||
if (await _unitFieldRepository.GetAsync(fieldId) == null)
|
||||
return false;
|
||||
}
|
||||
// // Если фильтров с ID нет, то и проверять в БД нечего
|
||||
// if (!requestedFieldIds.Any())
|
||||
// return true;
|
||||
|
||||
if (unitFilter.RelationshipFilters != null && unitFilter.RelationshipFilters.Any())
|
||||
foreach (var relationshipFilter in unitFilter.RelationshipFilters!)
|
||||
{
|
||||
var fieldId = relationshipFilter.FieldId;
|
||||
if (await _unitFieldRepository.GetAsync(fieldId) == null)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// // 3. Выполняем ОДИН запрос к БД.
|
||||
// var existingFieldIds = await _unitFieldRepository.Get()
|
||||
// .Where(field => requestedFieldIds.Contains(field.Id))
|
||||
// .Select(field => field.Id)
|
||||
// .Distinct()
|
||||
// .ToListAsync();
|
||||
|
||||
return true;
|
||||
}
|
||||
// // 4. Если количество найденных ID в БД меньше, чем мы запрашивали,
|
||||
// // значит какого-то fieldId не существует
|
||||
// return requestedFieldIds.Count == existingFieldIds.Count;
|
||||
|
||||
// #region Old
|
||||
// //foreach (var unitFilter in entity.UnitFilters)
|
||||
// //{
|
||||
// // if (string.IsNullOrEmpty(unitFilter.UnitFilterMask))
|
||||
// // return false;
|
||||
|
||||
// // if (unitFilter.FieldFilters != null && unitFilter.FieldFilters.Any())
|
||||
// // foreach (var fieldFilter in unitFilter.FieldFilters)
|
||||
// // {
|
||||
// // var fieldId = fieldFilter.FieldId;
|
||||
// // if (await _unitFieldRepository.GetAsync(fieldId) == null)
|
||||
// // return false;
|
||||
// // }
|
||||
|
||||
// // if (unitFilter.RelationshipFilters != null && unitFilter.RelationshipFilters.Any())
|
||||
// // foreach (var relationshipFilter in unitFilter.RelationshipFilters!)
|
||||
// // {
|
||||
// // var fieldId = relationshipFilter.FieldId;
|
||||
// // if (await _unitFieldRepository.GetAsync(fieldId) == null)
|
||||
// // return false;
|
||||
// // }
|
||||
// //}
|
||||
|
||||
// //return true;
|
||||
// #endregion
|
||||
//}
|
||||
|
||||
private async Task<bool> IsGroupExist(JobRequest entity)
|
||||
{
|
||||
|
||||
85
PARR.API/Validators/UnitFiltersBaseRequestValidator.cs
Normal file
85
PARR.API/Validators/UnitFiltersBaseRequestValidator.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using FluentValidation;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using PARR.API.Contracts.V1.Requests;
|
||||
using PARR.Core.Repositories.Interfaces.Unit;
|
||||
|
||||
namespace PARR.API.Validators
|
||||
{
|
||||
/// <summary>
|
||||
/// Валидация фильтроп вдя JobGroup, Job
|
||||
/// </summary>
|
||||
public class UnitFiltersBaseRequestValidator: AbstractValidator<UnitFiltersBaseRequest>
|
||||
{
|
||||
private readonly IUnitFieldRepository _unitFieldRepository;
|
||||
|
||||
public UnitFiltersBaseRequestValidator(IUnitFieldRepository unitFieldRepository)
|
||||
{
|
||||
_unitFieldRepository = unitFieldRepository;
|
||||
|
||||
// Это правило будет применяться ко ВСЕМ, кто наследует UnitFiltersBaseRequest
|
||||
RuleForEach(t => t.UnitFilters)
|
||||
.MustAsync(async (entity, value, c) => await IsUnitFiltersCorrect(entity))
|
||||
.WithMessage("Неверно заданы параметры фильтров.");
|
||||
}
|
||||
|
||||
private async Task<bool> IsUnitFiltersCorrect(UnitFiltersBaseRequest entity)
|
||||
{
|
||||
// 1. Проверим маски, они не должны быть пустыми
|
||||
foreach (var unitFilter in entity.UnitFilters)
|
||||
{
|
||||
if (string.IsNullOrEmpty(unitFilter.UnitFilterMask))
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. Собираем все уникальные FieldId из всех фильтров в памяти
|
||||
var requestedFieldIds = entity.UnitFilters
|
||||
.SelectMany(uf =>
|
||||
(uf.FieldFilters ?? Enumerable.Empty<FieldFilterRequest>()).Select(ff => ff.FieldId)
|
||||
.Concat((uf.RelationshipFilters ?? Enumerable.Empty<RelationshipFilterRequest>()).Select(rf => rf.FieldId)))
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
// Если фильтров с ID нет, то и проверять в БД нечего
|
||||
if (!requestedFieldIds.Any())
|
||||
return true;
|
||||
|
||||
// 3. Выполняем ОДИН запрос к БД.
|
||||
var existingFieldIds = await _unitFieldRepository.Get()
|
||||
.Where(field => requestedFieldIds.Contains(field.Id))
|
||||
.Select(field => field.Id)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
// 4. Если количество найденных ID в БД меньше, чем мы запрашивали,
|
||||
// значит какого-то fieldId не существует
|
||||
return requestedFieldIds.Count == existingFieldIds.Count;
|
||||
|
||||
#region Old
|
||||
//foreach (var unitFilter in entity.UnitFilters)
|
||||
//{
|
||||
// if (string.IsNullOrEmpty(unitFilter.UnitFilterMask))
|
||||
// return false;
|
||||
|
||||
// if (unitFilter.FieldFilters != null && unitFilter.FieldFilters.Any())
|
||||
// foreach (var fieldFilter in unitFilter.FieldFilters)
|
||||
// {
|
||||
// var fieldId = fieldFilter.FieldId;
|
||||
// if (await _unitFieldRepository.GetAsync(fieldId) == null)
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// if (unitFilter.RelationshipFilters != null && unitFilter.RelationshipFilters.Any())
|
||||
// foreach (var relationshipFilter in unitFilter.RelationshipFilters!)
|
||||
// {
|
||||
// var fieldId = relationshipFilter.FieldId;
|
||||
// if (await _unitFieldRepository.GetAsync(fieldId) == null)
|
||||
// return false;
|
||||
// }
|
||||
//}
|
||||
|
||||
//return true;
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -194,5 +194,7 @@ namespace PARR.Domain.Entities.JobGroupEntities
|
||||
public JobGroupDistributionConfig? DistributionConfig { get; set; }
|
||||
|
||||
public JobGroupAutoControl? AutoControl { get; set; }
|
||||
|
||||
public ICollection<JobGroupUnitFilter> UnitFilters { get; set; } = new HashSet<JobGroupUnitFilter>();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user