using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using PARR.DAL.Contracts; using PARR.DAL.DomainServices.Interfaces; using PARR.DAL.Models.Job; using PARR.DAL.Models.Unit; using PARR.DAL.Services.Interfaces.Job; using PARR.DAL.Services.Interfaces.Unit; using System.Text.RegularExpressions; namespace PARR.DAL.DomainServices.Implementations { internal class ShortcodesService : IShortcodesService { private const string shortcodePattern = "%[^%\\s]+%"; private static readonly HashSet SupportedShortcodes = new(StringComparer.OrdinalIgnoreCase) { "%ЭК%", "%ГРУППА_РАБОТ%", "%РАБОТА%", "%ТНК%", "%СВЯЗИ%", "%ТНК-КРАТКО%" }; private readonly ILogger logger; private readonly SettingsFromDb settingsFromDb; private readonly IJobService jobService; private readonly IUnitService unitService; private readonly IUnitFilterService unitFilterService; public ShortcodesService( ILogger logger, SettingsFromDb settingsFromDb, IJobService jobService, IUnitService unitService, IUnitFilterService unitFilterService ) { this.logger = logger; this.settingsFromDb = settingsFromDb; this.jobService = jobService; this.unitService = unitService; this.unitFilterService = unitFilterService; } public async Task ApplyShortcodesAsync(string str, Guid unitId, Guid jobId) { var nameConstants = settingsFromDb.TemplateNameConstantPartsList; var job = await jobService .Get().AsNoTracking() .Include(j => j.Tnk) .Include(j => j.Group) .Include(j => j.UnitFilters) .ThenInclude(uf => uf.RelationshipFilters) .FirstOrDefaultAsync(j => j.Id == jobId); var unit = await unitService.Get().AsNoTracking().FirstOrDefaultAsync(u => u.Id == unitId); if (job == null || unit == null || string.IsNullOrEmpty(str)) { logger.LogError("Переданы некорректные данные для подстановки динамических записей"); return str; } var resultName = str; var shortcodesInMask = GetShortCodes(resultName); // 1. Статические константы if (shortcodesInMask.Any(m => nameConstants.Any(c => $"%{c.Name}%".Equals(m.Value, StringComparison.OrdinalIgnoreCase)))) { resultName = ReplaceConstants(nameConstants, resultName); } // 2. Стандартные шорткоды (%ЭК%, %РАБОТА% и т.д.) if (shortcodesInMask.Any(m => SupportedShortcodes.Contains(m.Value))) { resultName = ReplaceStandardShortcodes(job, unit, resultName); } // 3. %СВЯЗИ% — отдельная обработка if (shortcodesInMask.Any(m => string.Equals(m.Value, "%СВЯЗИ%", StringComparison.OrdinalIgnoreCase))) { var relatedUnitNames = await unitFilterService.GetRelatedUnitNamesAsync(jobId, unitId);//GetRelatedUnitNamesAsync(job, unit); var linksText = string.Join("\n", relatedUnitNames); resultName = Regex.Replace(resultName, "%СВЯЗИ%", linksText, RegexOptions.IgnoreCase); } // 4. Поля (оставшиеся %FIELD_NAME%) shortcodesInMask = GetShortCodes(resultName); if (shortcodesInMask.Count > 0) { resultName = await ReplaceFieldValues(unitId, resultName, shortcodesInMask); } return resultName; } public bool isAnyShortcodes(string str) { return Regex.IsMatch(str, shortcodePattern); } private async Task ReplaceFieldValues(Guid unitId, string resultName, List shortcodesInMask) { var unitWithFields = await unitService.Get() .AsNoTracking() .Include(u => u.UnitValues) .ThenInclude(uv => uv.Field) .Include(u => u.UnitValues) .ThenInclude(uv => uv.Value) .FirstOrDefaultAsync(t => t.Id == unitId); foreach (var item in shortcodesInMask) { var fieldName = item.Value.Replace("%", "").ToUpper(); var value = unitWithFields!.UnitValues!.FirstOrDefault(t => t.Field!.AihitName!.ToUpper() == fieldName!); if (value != null) resultName = resultName.Replace(item.Value, value!.Value!.Value); } return resultName; } private static string ReplaceStandardShortcodes(Job job, Unit unit, string input) { return input .Replace("%ЭК%", unit.Name, StringComparison.OrdinalIgnoreCase) .Replace("%ГРУППА_РАБОТ%", job.Group?.GroupName ?? "", StringComparison.OrdinalIgnoreCase) .Replace("%РАБОТА%", job.WorkName, StringComparison.OrdinalIgnoreCase) .Replace("%ТНК%", job.Tnk?.Name ?? "", StringComparison.OrdinalIgnoreCase) .Replace("%ТНК-КРАТКО%", job.Tnk?.ShortName ?? "", StringComparison.OrdinalIgnoreCase); } private static string ReplaceConstants(List nameConstants, string resultName) { foreach (var item in nameConstants) { resultName = resultName.Replace($"%{item.Name}%", item.Value); } return resultName; } private static List GetShortCodes(string resultName) { var shortcodesInMask = Regex.Matches(resultName, shortcodePattern).ToList(); return shortcodesInMask; } } }