feat(templateMatcher): Убран хардкод РАБОЧАЯ_ГР_ОТВ_ЗА_ЭК при формировании шаблонов; добавлен метод для поиска аттрибутов ЭК по значению Code.
This commit is contained in:
@@ -3,9 +3,20 @@ using Microsoft.Extensions.Logging;
|
||||
using PARR.Core.Repositories.Interfaces.Job;
|
||||
using PARR.Domain.Entities.Base.History;
|
||||
using PARR.Domain.Entities.Job;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PARR.Core.Common.Helpers;
|
||||
|
||||
/// <summary>
|
||||
/// Сервис для синхронизации свойств Job внутри JobGroup.
|
||||
/// Эталоном считается Job с максимальным MaxValueRelationships.
|
||||
/// Синхронизируются: WorkName, маски, IsParentRelationships, AutoControl, UnitFilters.
|
||||
/// НЕ синхронизируются: Id, Name, MinValueRelationships, MaxValueRelationships, TnkId.
|
||||
/// </summary>
|
||||
public class JobGroupUnitFilterSynchronizeHelper
|
||||
{
|
||||
private readonly IJobRepository jobRepository;
|
||||
@@ -25,12 +36,13 @@ public class JobGroupUnitFilterSynchronizeHelper
|
||||
.ThenInclude(uf => uf.FieldFilters)
|
||||
.Include(j => j.UnitFilters)
|
||||
.ThenInclude(uf => uf.RelationshipFilters)
|
||||
.Include(j => j.AutoControl)
|
||||
.Where(j => j.GroupId == jobGroupId)
|
||||
.ToListAsync(ct);
|
||||
|
||||
if (jobs == null || jobs.Count < 2)
|
||||
{
|
||||
logger.LogDebug("JobGroup {JobGroupId} содержит менее двух Job. Синхронизация фильтров не требуется.", jobGroupId);
|
||||
logger.LogDebug("JobGroup {JobGroupId} содержит менее двух Job. Синхронизация не требуется.", jobGroupId);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -41,7 +53,7 @@ public class JobGroupUnitFilterSynchronizeHelper
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation("Начало синхронизации фильтров для JobGroup {JobGroupId}. Эталонный Job: {ReferenceJobId}.", jobGroupId, referenceJob.Id);
|
||||
logger.LogInformation("Начало синхронизации для JobGroup {JobGroupId}. Эталонный Job: {ReferenceJobId}.", jobGroupId, referenceJob.Id);
|
||||
|
||||
foreach (var job in jobs)
|
||||
{
|
||||
@@ -49,31 +61,84 @@ public class JobGroupUnitFilterSynchronizeHelper
|
||||
|
||||
if (job.Id == referenceJob.Id) continue;
|
||||
|
||||
if (!AreUnitFiltersIdentical(job.UnitFilters, referenceJob.UnitFilters))
|
||||
if (!AreJobsIdentical(job, referenceJob))
|
||||
{
|
||||
logger.LogDebug("Фильтры Job {JobId} отличаются от эталона. Запуск обновления.", job.Id);
|
||||
await ApplyFilterCorrectionAsync(job.Id, referenceJob.UnitFilters ?? Enumerable.Empty<JobUnitFilter>(), initiator, ct);
|
||||
logger.LogDebug("Свойства Job {JobId} отличаются от эталона. Запуск обновления.", job.Id);
|
||||
await ApplyJobCorrectionAsync(job.Id, referenceJob, initiator, ct);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogDebug("Фильтры Job {JobId} идентичны эталону. Пропуск.", job.Id);
|
||||
logger.LogDebug("Свойства Job {JobId} идентичны эталону. Пропуск.", job.Id);
|
||||
}
|
||||
}
|
||||
|
||||
logger.LogInformation("Синхронизация фильтров для JobGroup {JobGroupId} завершена.", jobGroupId);
|
||||
logger.LogInformation("Синхронизация для JobGroup {JobGroupId} завершена.", jobGroupId);
|
||||
}
|
||||
|
||||
private async Task ApplyFilterCorrectionAsync(Guid jobId, IEnumerable<JobUnitFilter> referenceFilters, HistoryInitiator initiator, CancellationToken ct)
|
||||
private bool AreJobsIdentical(Job current, Job reference)
|
||||
{
|
||||
// Сравнение скалярных полей (кроме Id, Name, Min/MaxValueRelationships, TnkId)
|
||||
if (current.WorkName != reference.WorkName) return false;
|
||||
if (current.IsParentRelationships != reference.IsParentRelationships) return false;
|
||||
if (current.TemplateNameMask != reference.TemplateNameMask) return false;
|
||||
if (current.WorkGroupMask != reference.WorkGroupMask) return false;
|
||||
if (current.ResponseAreaMask != reference.ResponseAreaMask) return false;
|
||||
|
||||
// Сравнение AutoControl
|
||||
if (current.AutoControl == null && reference.AutoControl != null) return false;
|
||||
if (current.AutoControl != null && reference.AutoControl == null) return false;
|
||||
if (current.AutoControl != null && reference.AutoControl != null)
|
||||
{
|
||||
if (current.AutoControl.InitUsedTemplateState != reference.AutoControl.InitUsedTemplateState) return false;
|
||||
if (current.AutoControl.InitUsedScheduleState != reference.AutoControl.InitUsedScheduleState) return false;
|
||||
}
|
||||
|
||||
// Сравнение фильтров
|
||||
if (!AreUnitFiltersIdentical(current.UnitFilters, reference.UnitFilters)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task ApplyJobCorrectionAsync(Guid jobId, Job referenceJob, HistoryInitiator initiator, CancellationToken ct)
|
||||
{
|
||||
var job = await jobRepository.Get()
|
||||
.Include(j => j.UnitFilters)
|
||||
.ThenInclude(uf => uf.FieldFilters)
|
||||
.Include(j => j.UnitFilters)
|
||||
.ThenInclude(uf => uf.RelationshipFilters)
|
||||
.Include(j => j.AutoControl)
|
||||
.FirstOrDefaultAsync(j => j.Id == jobId, ct);
|
||||
|
||||
if (job == null) return;
|
||||
|
||||
// 1. Обновляем скалярные поля
|
||||
job.WorkName = referenceJob.WorkName;
|
||||
job.IsParentRelationships = referenceJob.IsParentRelationships;
|
||||
job.TemplateNameMask = referenceJob.TemplateNameMask;
|
||||
job.WorkGroupMask = referenceJob.WorkGroupMask;
|
||||
job.ResponseAreaMask = referenceJob.ResponseAreaMask;
|
||||
job.DateModified = DateTimeOffset.UtcNow;
|
||||
|
||||
// 2. Обновляем AutoControl
|
||||
if (referenceJob.AutoControl != null)
|
||||
{
|
||||
if (job.AutoControl == null)
|
||||
{
|
||||
job.AutoControl = new JobAutoControl
|
||||
{
|
||||
JobId = job.Id,
|
||||
InitUsedTemplateState = referenceJob.AutoControl.InitUsedTemplateState,
|
||||
InitUsedScheduleState = referenceJob.AutoControl.InitUsedScheduleState
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
job.AutoControl.InitUsedTemplateState = referenceJob.AutoControl.InitUsedTemplateState;
|
||||
job.AutoControl.InitUsedScheduleState = referenceJob.AutoControl.InitUsedScheduleState;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Обновляем UnitFilters
|
||||
if (job.UnitFilters == null)
|
||||
{
|
||||
job.UnitFilters = new List<JobUnitFilter>();
|
||||
@@ -83,14 +148,14 @@ public class JobGroupUnitFilterSynchronizeHelper
|
||||
job.UnitFilters.Clear();
|
||||
}
|
||||
|
||||
var clonedFilters = CloneFilters(referenceFilters, job.Id);
|
||||
var clonedFilters = CloneFilters(referenceJob.UnitFilters ?? Enumerable.Empty<JobUnitFilter>(), job.Id);
|
||||
foreach (var filter in clonedFilters)
|
||||
{
|
||||
job.UnitFilters!.Add(filter);
|
||||
}
|
||||
|
||||
await jobRepository.CommitAsync(initiator);
|
||||
logger.LogInformation("Фильтры Job {JobId} успешно обновлены.", jobId);
|
||||
logger.LogInformation("Job {JobId} успешно синхронизирован с эталоном.", jobId);
|
||||
}
|
||||
|
||||
private bool AreUnitFiltersIdentical(IEnumerable<JobUnitFilter>? current, IEnumerable<JobUnitFilter>? reference)
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace PARR.Core.Repositories.Interfaces.Unit
|
||||
{
|
||||
public interface IUnitFieldRepository : IBaseRepository<UnitField>
|
||||
{
|
||||
Task<UnitField?> GetByAihitNameAsync(string name);
|
||||
Task<UnitField?> GetByCodeAsync(string code, CancellationToken ct = default);
|
||||
Task<UnitField?> GetByAihitNameAsync(string aihitName, CancellationToken ct = default);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user