From f9f234d1196eccd963a87cb33da7428f58453b35 Mon Sep 17 00:00:00 2001 From: Mikhail Kuznetsov Date: Wed, 14 Oct 2026 14:28:58 +1000 Subject: [PATCH] =?UTF-8?q?refactor(templateMatcher):=20-=20=D1=83=D0=BD?= =?UTF-8?q?=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B4=D0=B5?= =?UTF-8?q?=D0=B0=D0=BA=D1=82=D0=B8=D0=B2=D0=B0=D1=86=D0=B8=D0=B8=20=D1=88?= =?UTF-8?q?=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=BE=D0=B2=20=D0=BC=D0=B5=D0=B6?= =?UTF-8?q?=D0=B4=D1=83=20=D1=80=D0=B0=D0=B7=D0=BD=D1=8B=D0=BC=D0=B8=20?= =?UTF-8?q?=D1=81=D0=B8=D0=BD=D1=85=D1=80=D0=BE=D0=BD=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B0=D0=BC=D0=B8=20-=20=D0=BF=D0=BE=D0=B8?= =?UTF-8?q?=D1=81=D0=BA=20=D0=AD=D0=9A=20=D0=B2=D1=8B=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=B2=20=D0=BE=D1=82=D0=B4=D0=B5=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D1=83=D1=8E=20=D1=81=D1=83=D1=89=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Constants/UnusedTemplateConstants.cs | 10 + .../Services/GroupedSync/BuildGroupsStage.cs | 3 +- .../GroupedSync/DeactivateTemplatesStage.cs | 107 ++++++--- .../Services/GroupedSync/FilterUnitsStage.cs | 3 +- .../Services/GroupedSync/GroupFilterStage.cs | 3 +- .../GroupedSync/GroupedSyncContext.cs | 2 +- .../Services/GroupedSync/IGroupedSyncStage.cs | 4 +- .../Services/GroupedSync/LoadJobGroupStage.cs | 3 +- .../GroupedSync/ProcessGroupsStage.cs | 3 +- .../GroupedSync/ResolveConflictsStage.cs | 3 +- .../GroupedTemplateSynchronizer.cs | 1 - .../Implementations/TemplateDeactivator.cs | 155 ++++++------- .../UnusedTemplateMessageFactory.cs | 83 +++++++ .../UnusedTemplateTargetUnitResolver.cs | 209 ++++++++++++++++++ .../Interfaces/ITemplateDeactivator.cs | 7 +- .../IUnusedTemplateMessageFactory.cs | 18 ++ .../IUnusedTemplateTargetUnitResolver.cs | 12 + .../SimpleSync/AllocateTemplatesStage.cs | 4 +- .../SimpleSync/AnalyzeChangesStage.cs | 3 +- .../SimpleSync/DeactivateTemplatesStage.cs | 62 +++++- .../Services/SimpleSync/FilterUnitsStage.cs | 3 +- .../Services/SimpleSync/LoadJobStage.cs | 3 +- .../Services/SimpleSync/UpdateNamesStage.cs | 3 +- .../TemplateMatcherInstaller.cs | 28 +-- PARR.Test/PARR.Test.csproj | 4 + PARR.Test/Worker.cs | 73 +++++- 26 files changed, 643 insertions(+), 166 deletions(-) create mode 100644 PARR.TemplateMatcher/Services/Implementations/UnusedTemplateMessageFactory.cs create mode 100644 PARR.TemplateMatcher/Services/Implementations/UnusedTemplateTargetUnitResolver.cs create mode 100644 PARR.TemplateMatcher/Services/Interfaces/IUnusedTemplateMessageFactory.cs create mode 100644 PARR.TemplateMatcher/Services/Interfaces/IUnusedTemplateTargetUnitResolver.cs diff --git a/PARR.TemplateMatcher/Constants/UnusedTemplateConstants.cs b/PARR.TemplateMatcher/Constants/UnusedTemplateConstants.cs index 2e33d272..3fd053d8 100644 --- a/PARR.TemplateMatcher/Constants/UnusedTemplateConstants.cs +++ b/PARR.TemplateMatcher/Constants/UnusedTemplateConstants.cs @@ -21,5 +21,15 @@ /// Значение тега, обозначающее неиспользуемый юнит. /// public const string NotUsedTagValue = "ПАРР-НЕИСП"; + + /// + /// Состояние шаблонов по-умолчанию + /// + public const bool DefaultUnusedTemplateState = false; + + /// + /// Состояние расписаний по-умолчанию + /// + public const bool DefaultUnusedScheduleState = false; } } diff --git a/PARR.TemplateMatcher/Services/GroupedSync/BuildGroupsStage.cs b/PARR.TemplateMatcher/Services/GroupedSync/BuildGroupsStage.cs index 4e585e0c..157eaf15 100644 --- a/PARR.TemplateMatcher/Services/GroupedSync/BuildGroupsStage.cs +++ b/PARR.TemplateMatcher/Services/GroupedSync/BuildGroupsStage.cs @@ -1,7 +1,6 @@ using Microsoft.Extensions.Logging; -using PARR.TemplateMatcher.Services.GroupedSync; -namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync; +namespace PARR.TemplateMatcher.Services.GroupedSync; internal class BuildGroupsStage : IGroupedSyncStage { diff --git a/PARR.TemplateMatcher/Services/GroupedSync/DeactivateTemplatesStage.cs b/PARR.TemplateMatcher/Services/GroupedSync/DeactivateTemplatesStage.cs index d944fa2b..566de49b 100644 --- a/PARR.TemplateMatcher/Services/GroupedSync/DeactivateTemplatesStage.cs +++ b/PARR.TemplateMatcher/Services/GroupedSync/DeactivateTemplatesStage.cs @@ -2,15 +2,15 @@ using Microsoft.Extensions.Logging; using PARR.Core.Repositories.Interfaces; using PARR.Domain.Enums; -using PARR.TemplateMatcher.Services.GroupedSync; using PARR.TemplateMatcher.Services.Interfaces; -namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync; +namespace PARR.TemplateMatcher.Services.GroupedSync; internal class DeactivateTemplatesStage : IGroupedSyncWriteStage { private readonly ITemplateRepository _templateRepository; private readonly ITemplateDeactivator _deactivator; + private readonly IUnusedTemplateTargetUnitResolver _targetUnitResolver; private readonly ILogger _logger; public string StageName => "Деактивация шаблонов"; @@ -18,16 +18,22 @@ internal class DeactivateTemplatesStage : IGroupedSyncWriteStage public DeactivateTemplatesStage( ITemplateRepository templateRepository, ITemplateDeactivator deactivator, + IUnusedTemplateTargetUnitResolver targetUnitResolver, ILogger logger) { _templateRepository = templateRepository; _deactivator = deactivator; + _targetUnitResolver = targetUnitResolver; _logger = logger; } - public async Task ExecuteAsync(GroupedSyncContext context, CancellationToken ct = default) + public async Task ExecuteAsync( + GroupedSyncContext context, + CancellationToken ct = default) { - var allJobIds = context.JobsInGroup.Select(j => j.Id).ToHashSet(); + var allJobIds = context.JobsInGroup + .Select(j => j.Id) + .ToHashSet(); var existingTemplates = await _templateRepository.Get() .AsNoTracking() @@ -39,45 +45,76 @@ internal class DeactivateTemplatesStage : IGroupedSyncWriteStage && t.Job!.GroupId == context.JobGroupId) .ToListAsync(ct); - int deactivated = 0; - foreach (var template in existingTemplates) + var staleTemplates = existingTemplates + .Where(t => !context.ExpectedTemplateKeys.Contains( + (t.JobId, t.UnitId, t.Index ?? -1))) + .ToList(); + + if (staleTemplates.Count == 0) { - var key = (template.JobId, template.UnitId, template.Index ?? -1); - if (!context.ExpectedTemplateKeys.Contains(key)) + _logger.LogDebug( + "JobGroup '{JobGroupName}' ({JobGroupId}): шаблонов для деактивации нет.", + context.JobGroupName, + context.JobGroupId); + + return context; + } + + var targetUnits = await _targetUnitResolver.ResolveAsync(staleTemplates, ct); + + int deactivated = 0; + + foreach (var template in staleTemplates) + { + var unitLogName = context.UnitNames.TryGetValue(template.UnitId, out var unitName) + ? $"'{unitName}' ({template.UnitId})" + : template.Unit != null + ? $"'{template.Unit.Name}' ({template.UnitId})" + : $"({template.UnitId})"; + + _logger.LogInformation( + "JobGroup '{JobGroupName}' ({JobGroupId}): деактивация шаблона '{TemplateName}' ({TemplateId}), Job '{JobName}' ({JobId}), Unit {Unit}", + context.JobGroupName, + context.JobGroupId, + template.Name, + template.Id, + template.Job?.Name ?? string.Empty, + template.JobId, + unitLogName); + + if (!targetUnits.TryGetValue(template.Id, out var targetUnit)) { - var unitLogName = context.UnitNames.TryGetValue(template.UnitId, out var unitName) - ? $"'{unitName}' ({template.UnitId})" - : template.Unit != null - ? $"'{template.Unit.Name}' ({template.UnitId})" - : $"({template.UnitId})"; + _logger.LogError( + "Не удалось определить целевой Unit для деактивации шаблона {TemplateId}.", + template.Id); - _logger.LogInformation( - "JobGroup '{JobGroupName}' ({JobGroupId}): деактивация шаблона '{TemplateName}' ({TemplateId}), Job '{JobName}' ({JobId}), Unit {Unit}", - context.JobGroupName, context.JobGroupId, - template.Name, template.Id, - template.Job?.Name ?? string.Empty, template.JobId, - unitLogName); + continue; + } - var success = await _deactivator.DeactivateTemplateAsync(template, context.Initiator); + var success = await _deactivator.DeactivateTemplateAsync( + template, + targetUnit, + context.Initiator, + ct); - if (success) - { - deactivated++; - } - else - { - _logger.LogError( - "JobGroup '{JobGroupName}' ({JobGroupId}): не удалось деактивировать шаблон '{TemplateName}' ({TemplateId}).", - context.JobGroupName, - context.JobGroupId, - template.Name, - template.Id); - } + if (success) + { + deactivated++; + } + else + { + _logger.LogError( + "Не удалось деактивировать шаблон {TemplateId}.", + template.Id); } } - _logger.LogDebug("JobGroup '{JobGroupName}' ({JobGroupId}): деактивировано {Count} шаблонов из {Total}", - context.JobGroupName, context.JobGroupId, deactivated, existingTemplates.Count); + _logger.LogDebug( + "JobGroup '{JobGroupName}' ({JobGroupId}): деактивировано {Count} шаблонов из {Total}", + context.JobGroupName, + context.JobGroupId, + deactivated, + staleTemplates.Count); return context; } diff --git a/PARR.TemplateMatcher/Services/GroupedSync/FilterUnitsStage.cs b/PARR.TemplateMatcher/Services/GroupedSync/FilterUnitsStage.cs index 023f6f52..c60d421c 100644 --- a/PARR.TemplateMatcher/Services/GroupedSync/FilterUnitsStage.cs +++ b/PARR.TemplateMatcher/Services/GroupedSync/FilterUnitsStage.cs @@ -1,8 +1,7 @@ using Microsoft.Extensions.Logging; using PARR.Core.Services.UnitFilterService; -using PARR.TemplateMatcher.Services.GroupedSync; -namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync; +namespace PARR.TemplateMatcher.Services.GroupedSync; internal class FilterUnitsStage : IGroupedSyncStage { diff --git a/PARR.TemplateMatcher/Services/GroupedSync/GroupFilterStage.cs b/PARR.TemplateMatcher/Services/GroupedSync/GroupFilterStage.cs index e81489e2..2d28408e 100644 --- a/PARR.TemplateMatcher/Services/GroupedSync/GroupFilterStage.cs +++ b/PARR.TemplateMatcher/Services/GroupedSync/GroupFilterStage.cs @@ -1,7 +1,6 @@ using Microsoft.Extensions.Logging; -using PARR.TemplateMatcher.Services.GroupedSync; -namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync; +namespace PARR.TemplateMatcher.Services.GroupedSync; internal class GroupFilterStage : IGroupedSyncStage { diff --git a/PARR.TemplateMatcher/Services/GroupedSync/GroupedSyncContext.cs b/PARR.TemplateMatcher/Services/GroupedSync/GroupedSyncContext.cs index 25b3f081..103eb13d 100644 --- a/PARR.TemplateMatcher/Services/GroupedSync/GroupedSyncContext.cs +++ b/PARR.TemplateMatcher/Services/GroupedSync/GroupedSyncContext.cs @@ -4,7 +4,7 @@ using PARR.Domain.Entities.JobEntities; using PARR.Domain.Entities.JobGroupEntities; using PARR.TemplateMatcher.Models; -namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync; +namespace PARR.TemplateMatcher.Services.GroupedSync; /// /// Контекст групповой синхронизации. Передаётся между этапами. diff --git a/PARR.TemplateMatcher/Services/GroupedSync/IGroupedSyncStage.cs b/PARR.TemplateMatcher/Services/GroupedSync/IGroupedSyncStage.cs index 279a5fd0..eb5a210b 100644 --- a/PARR.TemplateMatcher/Services/GroupedSync/IGroupedSyncStage.cs +++ b/PARR.TemplateMatcher/Services/GroupedSync/IGroupedSyncStage.cs @@ -1,6 +1,4 @@ -using PARR.TemplateMatcher.Services.Implementations.GroupedSync; - -namespace PARR.TemplateMatcher.Services.GroupedSync +namespace PARR.TemplateMatcher.Services.GroupedSync { /// /// Этап групповой синхронизации, который только читает данные. diff --git a/PARR.TemplateMatcher/Services/GroupedSync/LoadJobGroupStage.cs b/PARR.TemplateMatcher/Services/GroupedSync/LoadJobGroupStage.cs index 08dcc868..6c494545 100644 --- a/PARR.TemplateMatcher/Services/GroupedSync/LoadJobGroupStage.cs +++ b/PARR.TemplateMatcher/Services/GroupedSync/LoadJobGroupStage.cs @@ -2,9 +2,8 @@ using Microsoft.Extensions.Logging; using PARR.Core.Repositories.Interfaces.JobGroupRepositories; using PARR.TemplateMatcher.Exceptions; -using PARR.TemplateMatcher.Services.GroupedSync; -namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync; +namespace PARR.TemplateMatcher.Services.GroupedSync; internal class LoadJobGroupStage : IGroupedSyncStage { diff --git a/PARR.TemplateMatcher/Services/GroupedSync/ProcessGroupsStage.cs b/PARR.TemplateMatcher/Services/GroupedSync/ProcessGroupsStage.cs index c106b13d..2698d7c2 100644 --- a/PARR.TemplateMatcher/Services/GroupedSync/ProcessGroupsStage.cs +++ b/PARR.TemplateMatcher/Services/GroupedSync/ProcessGroupsStage.cs @@ -1,7 +1,6 @@ using Microsoft.Extensions.Logging; -using PARR.TemplateMatcher.Services.GroupedSync; -namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync; +namespace PARR.TemplateMatcher.Services.GroupedSync; internal class ProcessGroupsStage : IGroupedSyncWriteStage { diff --git a/PARR.TemplateMatcher/Services/GroupedSync/ResolveConflictsStage.cs b/PARR.TemplateMatcher/Services/GroupedSync/ResolveConflictsStage.cs index c960f66e..7d1de3aa 100644 --- a/PARR.TemplateMatcher/Services/GroupedSync/ResolveConflictsStage.cs +++ b/PARR.TemplateMatcher/Services/GroupedSync/ResolveConflictsStage.cs @@ -1,7 +1,6 @@ using Microsoft.Extensions.Logging; -using PARR.TemplateMatcher.Services.GroupedSync; -namespace PARR.TemplateMatcher.Services.Implementations.GroupedSync; +namespace PARR.TemplateMatcher.Services.GroupedSync; internal class ResolveConflictsStage : IGroupedSyncStage { diff --git a/PARR.TemplateMatcher/Services/Implementations/GroupedTemplateSynchronizer.cs b/PARR.TemplateMatcher/Services/Implementations/GroupedTemplateSynchronizer.cs index 3318a46c..0d719ded 100644 --- a/PARR.TemplateMatcher/Services/Implementations/GroupedTemplateSynchronizer.cs +++ b/PARR.TemplateMatcher/Services/Implementations/GroupedTemplateSynchronizer.cs @@ -5,7 +5,6 @@ using PARR.Domain.Entities.Base.History; using PARR.Domain.Enums; using PARR.TemplateMatcher.Exceptions; using PARR.TemplateMatcher.Services.GroupedSync; -using PARR.TemplateMatcher.Services.Implementations.GroupedSync; using PARR.TemplateMatcher.Services.Interfaces; using System.Diagnostics; diff --git a/PARR.TemplateMatcher/Services/Implementations/TemplateDeactivator.cs b/PARR.TemplateMatcher/Services/Implementations/TemplateDeactivator.cs index d1974096..645e5d81 100644 --- a/PARR.TemplateMatcher/Services/Implementations/TemplateDeactivator.cs +++ b/PARR.TemplateMatcher/Services/Implementations/TemplateDeactivator.cs @@ -3,10 +3,10 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using PARR.Core.Repositories.Interfaces; using PARR.Core.Repositories.Interfaces.JobRepositories; -using PARR.Domain.Common.Rabbit.Messages.TemplateMatching; using PARR.Domain.Entities; using PARR.Domain.Entities.Base.History; using PARR.Domain.Entities.JobEntities; +using PARR.Domain.Entities.Unit; using PARR.Domain.Enums; using PARR.Domain.Settings; using PARR.TemplateMatcher.Services.Interfaces; @@ -16,106 +16,113 @@ namespace PARR.TemplateMatcher.Services.Implementations; internal class TemplateDeactivator : ITemplateDeactivator { - private const bool DefaultUnusedTemplateState = false; - private const bool DefaultUnusedScheduleState = false; + private readonly ILogger _logger; + private readonly ITemplateRepository _templateRepository; + private readonly IJobRepository _jobRepository; + private readonly ITemplateMqPublisher _templateMqPublisher; + private readonly IUnusedTemplateMessageFactory _unusedTemplateMessageFactory; + private readonly SettingsFromDb _settingsFromDb; + private readonly IOptions _templateSettings; - private readonly ILogger logger; - private readonly ITemplateRepository templateService; - private readonly IJobRepository jobService; - private readonly ITemplateNameNormalizer namenormalizer; - private readonly ITemplateMqPublisher templateMqPublisher; - private readonly SettingsFromDb settingsFromDb; - private readonly IOptions templateSettings; + private Job? _unusedJob; public TemplateDeactivator( ILogger logger, - ITemplateRepository templateService, - IJobRepository jobService, - ITemplateNameNormalizer namenormalizer, + ITemplateRepository templateRepository, + IJobRepository jobRepository, ITemplateMqPublisher templateMqPublisher, + IUnusedTemplateMessageFactory unusedTemplateMessageFactory, SettingsFromDb settingsFromDb, - IOptions templateSettings - ) + IOptions templateSettings) { - this.logger = logger; - this.templateService = templateService; - this.jobService = jobService; - this.namenormalizer = namenormalizer; - this.templateMqPublisher = templateMqPublisher; - this.settingsFromDb = settingsFromDb; - this.templateSettings = templateSettings; + _logger = logger; + _templateRepository = templateRepository; + _jobRepository = jobRepository; + _templateMqPublisher = templateMqPublisher; + _unusedTemplateMessageFactory = unusedTemplateMessageFactory; + _settingsFromDb = settingsFromDb; + _templateSettings = templateSettings; } - public async Task DeactivateTemplateAsync(Template template, HistoryInitiator initiator) + public async Task DeactivateTemplateAsync( + Template template, + Unit targetUnit, + HistoryInitiator initiator, + CancellationToken ct = default) { - if (template.StatusTypeId == TemplateStatusTypeEnum.Updating) - return true; - if (template.StatusTypeId == TemplateStatusTypeEnum.Unused) { - logger.LogDebug("Шаблон {TemplateId} уже неактивен (Unused), пропускаем деактивацию.", template.Id); + _logger.LogDebug( + "Шаблон {TemplateId} уже находится в статусе Unused. Пропускаем деактивацию.", + template.Id); + return true; } - logger.LogInformation("Шаблон {TemplateId} (UnitId {UnitId}) → деактивация.", - template.Id, template.UnitId); + if (template.StatusTypeId == TemplateStatusTypeEnum.Updating) + { + _logger.LogDebug( + "Шаблон {TemplateId} уже находится в статусе Updating. Пропускаем повторную деактивацию.", + template.Id); + + return true; + } + + var unusedJob = await GetUnusedJobAsync(ct); + + if (unusedJob == null) + { + _logger.LogError( + "Job для неиспользуемых шаблонов не найден. Шаблон {TemplateId} не деактивирован.", + template.Id); + + return false; + } + + _logger.LogInformation( + "Деактивация шаблона {TemplateId}. Текущий UnitId: {CurrentUnitId}, целевой UnitId: {TargetUnitId}.", + template.Id, + template.UnitId, + targetUnit.Id); template.StatusTypeId = TemplateStatusTypeEnum.Updating; template.DateModified = DateTimeOffset.UtcNow; - if (!await templateService.CommitAsync(initiator)) + if (!await _templateRepository.CommitAsync(initiator)) { - logger.LogError("Не удалось перевести шаблон {TemplateId} в Updating.", template.Id); + _logger.LogError( + "Не удалось перевести шаблон {TemplateId} в статус Updating.", + template.Id); + return false; } - var unusedJob = await jobService.Get() + var updateRequest = await _unusedTemplateMessageFactory.CreateAsync( + template, + unusedJob, + targetUnit, + initiator, + ct); + + await _templateMqPublisher.PublishUpdateAsync(updateRequest); + + return true; + } + + private async Task GetUnusedJobAsync(CancellationToken ct) + { + if (_unusedJob != null) + return _unusedJob; + + _unusedJob = await _jobRepository.Get() .AsNoTracking() .Include(j => j.Tnk) .Include(j => j.Group) .ThenInclude(g => g!.GroupType) - .FirstOrDefaultAsync(j => j.Id == settingsFromDb.JobIdForUnusedTemplates); + .FirstOrDefaultAsync( + j => j.Id == _settingsFromDb.JobIdForUnusedTemplates, + ct); - - if (unusedJob == null) - { - logger.LogError("Job для деактивированных шаблонов не найден."); - return false; - } - - unusedJob.TemplateNameMask = templateSettings.Value.UnusedTemplateNameMask; - - // === Создаём временный Template для нормализации имени === - var tempTemplateForName = new Template - { - Id = template.Id, - Name = template.Name, - JobId = unusedJob.Id, - UnitId = template.UnitId, - Index = template.Index, - Job = unusedJob, - Unit = template.Unit, - UnitsInTemplate = new List() - }; - - var expectedName = await namenormalizer.GetNormalizedTemplateNameAsync(tempTemplateForName); - - var updateRequest = new TemplateUpdaterMessage - { - TemplateId = template.Id, - JobId = unusedJob.Id, - UnitId = template.UnitId, - Name = expectedName, - IsActiveTemplate = DefaultUnusedTemplateState, - IsActiveSchedule = DefaultUnusedScheduleState, - IsNew = false, - Index = template.Index, - StatusTypeId = TemplateStatusTypeEnum.Unused, - Initiator = initiator, - UnitsInTemplate = new List() - }; - - await templateMqPublisher.PublishUpdateAsync(updateRequest); - return true; + return _unusedJob; } } \ No newline at end of file diff --git a/PARR.TemplateMatcher/Services/Implementations/UnusedTemplateMessageFactory.cs b/PARR.TemplateMatcher/Services/Implementations/UnusedTemplateMessageFactory.cs new file mode 100644 index 00000000..8b9cf462 --- /dev/null +++ b/PARR.TemplateMatcher/Services/Implementations/UnusedTemplateMessageFactory.cs @@ -0,0 +1,83 @@ +using Microsoft.Extensions.Options; +using PARR.Domain.Common.Rabbit.Messages.TemplateMatching; +using PARR.Domain.Entities; +using PARR.Domain.Entities.Base.History; +using PARR.Domain.Entities.JobEntities; +using PARR.Domain.Entities.Unit; +using PARR.Domain.Enums; +using PARR.TemplateMatcher.Constants; +using PARR.TemplateMatcher.Services.Interfaces; +using PARR.TemplateMatcher.Settings; + +namespace PARR.TemplateMatcher.Services.Implementations; + +internal class UnusedTemplateMessageFactory : IUnusedTemplateMessageFactory +{ + private readonly ITemplateNameNormalizer _templateNameNormalizer; + private readonly IOptions _templateSettings; + + public UnusedTemplateMessageFactory( + ITemplateNameNormalizer templateNameNormalizer, + IOptions templateSettings) + { + _templateNameNormalizer = templateNameNormalizer; + _templateSettings = templateSettings; + } + + public async Task CreateAsync( + Template template, + Job unusedJob, + Unit targetUnit, + HistoryInitiator initiator, + CancellationToken ct = default) + { + var jobForName = new Job + { + Id = unusedJob.Id, + Name = unusedJob.Name, + WorkName = unusedJob.WorkName, + MinValueRelationships = unusedJob.MinValueRelationships, + MaxValueRelationships = unusedJob.MaxValueRelationships, + IsParentRelationships = unusedJob.IsParentRelationships, + TemplateNameMask = _templateSettings.Value.UnusedTemplateNameMask, + WorkGroupMask = unusedJob.WorkGroupMask, + ResponseAreaMask = unusedJob.ResponseAreaMask, + TnkId = unusedJob.TnkId, + GroupId = unusedJob.GroupId, + Group = unusedJob.Group, + Tnk = unusedJob.Tnk, + UnitFilters = unusedJob.UnitFilters, + Templates = unusedJob.Templates, + AutoControl = unusedJob.AutoControl + }; + + var templateForName = new Template + { + Id = template.Id, + Name = template.Name, + JobId = unusedJob.Id, + UnitId = targetUnit.Id, + Index = null, + Job = jobForName, + Unit = targetUnit, + UnitsInTemplate = new List() + }; + + var expectedName = await _templateNameNormalizer.GetNormalizedTemplateNameAsync(templateForName); + + return new TemplateUpdaterMessage + { + TemplateId = template.Id, + JobId = unusedJob.Id, + UnitId = targetUnit.Id, + Name = expectedName, + IsActiveTemplate = UnusedTemplateConstants.DefaultUnusedTemplateState, + IsActiveSchedule = UnusedTemplateConstants.DefaultUnusedScheduleState, + IsNew = false, + Index = null, + StatusTypeId = TemplateStatusTypeEnum.Unused, + Initiator = initiator, + UnitsInTemplate = new List() + }; + } +} \ No newline at end of file diff --git a/PARR.TemplateMatcher/Services/Implementations/UnusedTemplateTargetUnitResolver.cs b/PARR.TemplateMatcher/Services/Implementations/UnusedTemplateTargetUnitResolver.cs new file mode 100644 index 00000000..d6744506 --- /dev/null +++ b/PARR.TemplateMatcher/Services/Implementations/UnusedTemplateTargetUnitResolver.cs @@ -0,0 +1,209 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using PARR.Core.Repositories.Interfaces.Unit; +using PARR.Domain.Entities; +using PARR.Domain.Entities.Unit; +using PARR.TemplateMatcher.Constants; +using PARR.TemplateMatcher.Services.Interfaces; + +namespace PARR.TemplateMatcher.Services.Implementations; + +internal class UnusedTemplateTargetUnitResolver : IUnusedTemplateTargetUnitResolver +{ + private readonly IUnitFieldRepository _unitFieldRepository; + private readonly IUnitInValueRepository _unitInValueRepository; + private readonly IUnitRepository _unitRepository; + private readonly ILogger _logger; + + public UnusedTemplateTargetUnitResolver( + IUnitFieldRepository unitFieldRepository, + IUnitInValueRepository unitInValueRepository, + IUnitRepository unitRepository, + ILogger logger) + { + _unitFieldRepository = unitFieldRepository; + _unitInValueRepository = unitInValueRepository; + _unitRepository = unitRepository; + _logger = logger; + } + + public async Task> ResolveAsync( + IReadOnlyCollection