296 lines
13 KiB
C#
296 lines
13 KiB
C#
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.Logging;
|
||
using PARR.Core.Repositories.Interfaces.JobGroupRepositories;
|
||
using PARR.Core.Repositories.Interfaces.JobRepositories;
|
||
using PARR.Domain.Entities.Base.History;
|
||
using PARR.Domain.Entities.JobEntities;
|
||
using PARR.Domain.Enums;
|
||
using PARR.TemplateMatcher.Services.Interfaces;
|
||
|
||
namespace PARR.TemplateMatcher.Services.Implementations
|
||
{
|
||
internal class TemplateMatcher : ITemplateMatcher
|
||
{
|
||
private readonly ILogger<TemplateMatcher> _logger;
|
||
private readonly IJobRepository _jobService;
|
||
private readonly IJobGroupRepository _jobGroupService;
|
||
private readonly IEnumerable<ITemplateSynchronizer> _synchronizers;
|
||
|
||
public TemplateMatcher(
|
||
ILogger<TemplateMatcher> logger,
|
||
IJobRepository jobService,
|
||
IJobGroupRepository jobGroupService,
|
||
IEnumerable<ITemplateSynchronizer> synchronizers
|
||
)
|
||
{
|
||
_logger = logger;
|
||
_jobService = jobService;
|
||
_jobGroupService = jobGroupService;
|
||
_synchronizers = synchronizers;
|
||
|
||
}
|
||
|
||
public async Task SyncTemplatesForJob(Guid jobId, HistoryInitiator initiator)
|
||
{
|
||
_logger.LogDebug("Начало синхронизации шаблонов для JobId {JobId}", jobId);
|
||
|
||
var job = await GetJobWithGroupAndAutoControlAsync(jobId);
|
||
if (job == null)
|
||
{
|
||
_logger.LogError("Job с Id {JobId} не найден.", jobId);
|
||
return;
|
||
}
|
||
|
||
// Проверяем, является ли Job "групповым"
|
||
bool isGroupJob = job.Group != null && job.Group.GroupType?.Code == JobGroupTypesEnum.Group;
|
||
|
||
if (isGroupJob && job.Group!.GroupingUnitFieldId.HasValue)
|
||
{
|
||
_logger.LogInformation("Job {JobId} является групповым. Передаём в GroupedSynchronizer.", jobId);
|
||
// Находим нужный синхронизатор
|
||
var synchronizer = _synchronizers.FirstOrDefault(s => s is GroupedTemplateSynchronizer);
|
||
if (synchronizer != null)
|
||
{
|
||
// Так как Job групповой, вызываем синхронизацию для его JobGroup
|
||
await synchronizer.SyncTemplatesForJobGroupAsync(job.GroupId, initiator);
|
||
}
|
||
else
|
||
{
|
||
_logger.LogError("GroupedTemplateSynchronizer не найден.");
|
||
}
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
_logger.LogInformation("Job {JobId} является обычным. Передаём в SimpleSynchronizer.", jobId);
|
||
// Находим нужный синхронизатор
|
||
var synchronizer = _synchronizers.FirstOrDefault(s => s is SimpleTemplateSynchronizer);
|
||
if (synchronizer != null)
|
||
{
|
||
await synchronizer.SyncTemplatesForJobAsync(jobId, initiator);
|
||
}
|
||
else
|
||
{
|
||
_logger.LogError("SimpleTemplateSynchronizer не найден.");
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
|
||
public async Task SyncTemplatesForJobGroup(Guid jobGroupId, HistoryInitiator initiator)
|
||
{
|
||
_logger.LogDebug("Начало синхронизации шаблонов для JobGroup {JobGroupId}", jobGroupId);
|
||
|
||
var jobGroup = await _jobGroupService.Get()
|
||
.AsNoTracking()
|
||
.Include(jg => jg.GroupType)
|
||
.FirstOrDefaultAsync(jg => jg.Id == jobGroupId);
|
||
|
||
if (jobGroup == null || jobGroup.GroupType == null)
|
||
{
|
||
_logger.LogWarning("JobGroup {JobGroupId} не найден или не содержит GroupType.", jobGroupId);
|
||
return;
|
||
}
|
||
|
||
// Определяем стратегию по типу группы
|
||
switch (jobGroup.GroupType.Code)
|
||
{
|
||
case JobGroupTypesEnum.Group:
|
||
// Проверяем, есть ли GroupingUnitFieldId — это признак "настоящей" группировки
|
||
if (jobGroup.GroupingUnitFieldId.HasValue)
|
||
{
|
||
_logger.LogInformation("JobGroup {JobGroupId} является Group с GroupingUnitFieldId. Передаём в GroupedTemplateSynchronizer.", jobGroupId);
|
||
var synchronizer = _synchronizers.FirstOrDefault(s => s is GroupedTemplateSynchronizer);
|
||
if (synchronizer != null)
|
||
{
|
||
await synchronizer.SyncTemplatesForJobGroupAsync(jobGroupId, initiator);
|
||
}
|
||
else
|
||
{
|
||
_logger.LogError("GroupedTemplateSynchronizer не найден для JobGroup {JobGroupId}.", jobGroupId);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
_logger.LogInformation("JobGroup {JobGroupId} является Group, но не имеет GroupingUnitFieldId. Обрабатываем как Collection.", jobGroupId);
|
||
//await SyncJobGroupAsCollectionAsync(jobGroupId, initiator);
|
||
}
|
||
break;
|
||
|
||
case JobGroupTypesEnum.Umbrella:
|
||
_logger.LogInformation("JobGroup {JobGroupId} является Umbrella. Обрабатываем как Collection (каждый Job — независимо).", jobGroupId);
|
||
await SyncJobGroupAsCollectionAsync(jobGroupId, initiator);
|
||
break;
|
||
|
||
case JobGroupTypesEnum.Simple:
|
||
default:
|
||
_logger.LogInformation("JobGroup {JobGroupId} имеет тип Simple. Обрабатываем как Collection.", jobGroupId);
|
||
await SyncJobGroupAsCollectionAsync(jobGroupId, initiator);
|
||
break;
|
||
}
|
||
}
|
||
|
||
public async Task UpdateTemplatesForJobGroup(Guid jobGroupId, HistoryInitiator initiator)
|
||
{
|
||
_logger.LogDebug("Начало обновления шаблонов для JobGroup {JobGroupId}", jobGroupId);
|
||
|
||
var jobGroup = await _jobGroupService.Get()
|
||
.AsNoTracking()
|
||
.Include(jg => jg.GroupType)
|
||
.FirstOrDefaultAsync(jg => jg.Id == jobGroupId);
|
||
|
||
if (jobGroup == null || jobGroup.GroupType == null)
|
||
{
|
||
_logger.LogWarning("JobGroup {JobGroupId} не найден или не содержит GroupType.", jobGroupId);
|
||
return;
|
||
}
|
||
|
||
switch (jobGroup.GroupType.Code)
|
||
{
|
||
case JobGroupTypesEnum.Group:
|
||
if (jobGroup.GroupingUnitFieldId.HasValue)
|
||
{
|
||
_logger.LogWarning("UpdateTemplatesForJobGroup не поддерживается для Group с GroupingUnitFieldId. Id: {JobGroupId}", jobGroupId);
|
||
}
|
||
else
|
||
{
|
||
_logger.LogInformation("JobGroup {JobGroupId} — Group без GroupingUnitFieldId. Обновляем как Collection.", jobGroupId);
|
||
await UpdateJobGroupAsCollectionAsync(jobGroupId, initiator);
|
||
}
|
||
break;
|
||
|
||
case JobGroupTypesEnum.Umbrella:
|
||
_logger.LogInformation("JobGroup {JobGroupId} — Umbrella. Обновляем как Collection.", jobGroupId);
|
||
await UpdateJobGroupAsCollectionAsync(jobGroupId, initiator);
|
||
break;
|
||
|
||
case JobGroupTypesEnum.Simple:
|
||
default:
|
||
_logger.LogInformation("JobGroup {JobGroupId} — Simple. Обновляем как Collection.", jobGroupId);
|
||
await UpdateJobGroupAsCollectionAsync(jobGroupId, initiator);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
public async Task UpdateTemplatesForJob(Guid jobId, HistoryInitiator initiator)
|
||
{
|
||
_logger.LogDebug("Начало обновления шаблонов для JobId {JobId}", jobId);
|
||
|
||
var job = await GetJobWithGroupAndAutoControlAsync(jobId);
|
||
if (job == null)
|
||
{
|
||
_logger.LogError("Job с Id {JobId} не найден.", jobId);
|
||
return;
|
||
}
|
||
|
||
// Проверяем, является ли Job "групповым"
|
||
bool isGroupJob = job.Group != null && job.Group.GroupType?.Code == JobGroupTypesEnum.Group;
|
||
|
||
if (isGroupJob && job.Group!.GroupingUnitFieldId.HasValue)
|
||
{
|
||
_logger.LogInformation("Job {JobId} является групповым. Передаём в GroupedSynchronizer для Update.", jobId);
|
||
// Находим нужный синхронизатор
|
||
var synchronizer = _synchronizers.FirstOrDefault(s => s is GroupedTemplateSynchronizer);
|
||
if (synchronizer != null)
|
||
{
|
||
// Вызов UpdateTemplatesForJobAsync для GroupedTemplateSynchronizer (который делает предупреждение)
|
||
await synchronizer.UpdateTemplatesForJobAsync(jobId, initiator);
|
||
}
|
||
else
|
||
{
|
||
_logger.LogError("GroupedTemplateSynchronizer не найден.");
|
||
}
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
_logger.LogInformation("Job {JobId} является обычным. Передаём в SimpleSynchronizer для Update.", jobId);
|
||
// Находим нужный синхронизатор
|
||
var synchronizer = _synchronizers.FirstOrDefault(s => s is SimpleTemplateSynchronizer);
|
||
if (synchronizer != null)
|
||
{
|
||
await synchronizer.UpdateTemplatesForJobAsync(jobId, initiator);
|
||
}
|
||
else
|
||
{
|
||
_logger.LogError("SimpleTemplateSynchronizer не найден.");
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
|
||
// --- Вспомогательные методы ---
|
||
private async Task SyncJobGroupAsCollectionAsync(Guid jobGroupId, HistoryInitiator initiator)
|
||
{
|
||
_logger.LogDebug("Синхронизация JobGroup {JobGroupId} как Collection (по каждому Job'у отдельно)", jobGroupId);
|
||
|
||
var jobIds = await _jobService.Get()
|
||
.AsNoTracking()
|
||
.Where(j => j.GroupId == jobGroupId)
|
||
.Select(j => j.Id)
|
||
.ToListAsync();
|
||
|
||
if (!jobIds.Any())
|
||
{
|
||
_logger.LogWarning("JobGroup {JobGroupId} не содержит Job'ов.", jobGroupId);
|
||
return;
|
||
}
|
||
|
||
_logger.LogDebug("Найдено {Count} Job'ов в JobGroup {JobGroupId}", jobIds.Count, jobGroupId);
|
||
|
||
var simpleSynchronizer = _synchronizers.FirstOrDefault(s => s is SimpleTemplateSynchronizer);
|
||
|
||
if (simpleSynchronizer == null)
|
||
{
|
||
_logger.LogError("SimpleTemplateSynchronizer не найден для синхронизации Job'ов в JobGroup {JobGroupId}.", jobGroupId);
|
||
return;
|
||
}
|
||
|
||
foreach (var jobId in jobIds)
|
||
{
|
||
_logger.LogDebug("Синхронизация Job {JobId} в рамках JobGroup {JobGroupId}", jobId, jobGroupId);
|
||
await simpleSynchronizer.SyncTemplatesForJobAsync(jobId, initiator);
|
||
}
|
||
|
||
_logger.LogInformation("Синхронизация JobGroup {JobGroupId} как Collection завершена.", jobGroupId);
|
||
}
|
||
|
||
|
||
private async Task UpdateJobGroupAsCollectionAsync(Guid jobGroupId, HistoryInitiator initiator)
|
||
{
|
||
_logger.LogDebug("Обновление JobGroup {JobGroupId} как Collection (по каждому Job'у)", jobGroupId);
|
||
|
||
var jobIds = await _jobService.Get()
|
||
.AsNoTracking()
|
||
.Where(j => j.GroupId == jobGroupId)
|
||
.Select(j => j.Id)
|
||
.ToListAsync();
|
||
|
||
if (!jobIds.Any())
|
||
{
|
||
_logger.LogWarning("JobGroup {JobGroupId} не содержит Job'ов.", jobGroupId);
|
||
return;
|
||
}
|
||
|
||
foreach (var jobId in jobIds)
|
||
{
|
||
_logger.LogDebug("Обновление шаблонов для Job {JobId} в рамках JobGroup {JobGroupId}", jobId, jobGroupId);
|
||
await UpdateTemplatesForJob(jobId, initiator);
|
||
}
|
||
|
||
_logger.LogInformation("Обновление JobGroup {JobGroupId} как Collection завершено.", jobGroupId);
|
||
}
|
||
|
||
|
||
private async Task<Job?> GetJobWithGroupAndAutoControlAsync(Guid jobId)
|
||
{
|
||
return await _jobService.Get()
|
||
.AsNoTracking()
|
||
.Include(j => j.Group)
|
||
.ThenInclude(j => j!.GroupType)
|
||
.Include(j => j.AutoControl)
|
||
.FirstOrDefaultAsync(j => j.Id == jobId);
|
||
}
|
||
}
|
||
} |