Files
parr_api/PARR.TemplateMatcher/Services/Implementations/TemplateMatcher.cs

296 lines
13 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}