diff --git a/PARR.Core/Services/Shortcodes/Handlers/GroupedFieldShortcodeHandler.cs b/PARR.Core/Services/Shortcodes/Handlers/GroupedFieldShortcodeHandler.cs index 7fecb589..89c1cd03 100644 --- a/PARR.Core/Services/Shortcodes/Handlers/GroupedFieldShortcodeHandler.cs +++ b/PARR.Core/Services/Shortcodes/Handlers/GroupedFieldShortcodeHandler.cs @@ -50,7 +50,6 @@ internal class GroupedFieldShortcodeHandler : IShortcodeHandler var unitsList = template.UnitsInTemplate; if (unitsList.Count == 0) { - // Данные должны быть загружены оркестратором. Если пусто — значит в БД действительно нет связей. return input.Replace("%ГР_ПОЛЕ-ПН%", string.Empty, StringComparison.OrdinalIgnoreCase); } @@ -67,12 +66,16 @@ internal class GroupedFieldShortcodeHandler : IShortcodeHandler .Where(fv => fieldValueIds.Contains(fv.Id)) .ToDictionaryAsync(fv => fv.Id, fv => fv.Value ?? string.Empty, ct); - var lines = unitsList.Select((uit, i) => - { - var uName = unitNames.GetValueOrDefault(uit.UnitId, $"(UnitId={uit.UnitId})"); - var fVal = fieldValueStrings.GetValueOrDefault(uit.UnitFieldValueId, string.Empty); - return $"{i + 1}. {uName} ({fVal})"; - }); + // Сортировка по имени юнита для детерминированного результата + var lines = unitsList + .OrderBy(u => unitNames.GetValueOrDefault(u.UnitId, string.Empty), StringComparer.OrdinalIgnoreCase) + .ThenBy(u => fieldValueStrings.GetValueOrDefault(u.UnitFieldValueId, string.Empty), StringComparer.OrdinalIgnoreCase) + .Select((uit, i) => + { + var uName = unitNames.GetValueOrDefault(uit.UnitId, $"(UnitId={uit.UnitId})"); + var fVal = fieldValueStrings.GetValueOrDefault(uit.UnitFieldValueId, string.Empty); + return $"{i + 1}. {uName} ({fVal})"; + }); return input.Replace("%ГР_ПОЛЕ-ПН%", string.Join("\n", lines), StringComparison.OrdinalIgnoreCase); }