Reminders: убрать Category из общей части DTO, добавить ReceiverEmail/ReceiverName, ограничить чтение испытательного срока последними партициями
- ReminderDto: базовый класс сузился до ReceiverEmail/ReceiverName/Url; RequestTypeId/RequestTypeName/RequestId/Status/RequestUniqueCode остались только в ApprovalOverdueReminderDto — ProbationEndingReminderDto они не нужны. Дискриминатор полиморфной сериализации ($type) больше не дублируется отдельным enum-полем Category. - ApprovalOverdueReminderDto: старый Email сохранён рядом с унаследованным ReceiverEmail (то же значение) — контракт можно переключать постепенно. - ApprovalRow/RowSelect: добавлен Title согласующего (TansuSiteApprover/Title) — заполняет ReceiverName для просроченных шагов, когда он есть в SharePoint. - EmployeeDirectorySnapshot.NameByEmail: обратный поиск ФИО руководителя по email — заполняет ReceiverName для напоминаний об испытательном сроке без лишнего похода в api.tnsu.kz (данные уже загружены для EmailOf). - GetProbationEndingAsync: испытательный срок не длиннее 6 месяцев, поэтому читаем только текущую и последнюю архивную партицию (не весь архив) и фильтруем строки по HireDate не старше 6 месяцев — экономим лишние запросы к SharePoint без потери актуальных заявок.
This commit is contained in:
@@ -31,12 +31,22 @@ internal sealed class EmployeeDirectorySnapshot
|
||||
{
|
||||
private readonly ILookup<string, EmployeeFullBaseInfo> _fullBaseByFio;
|
||||
private readonly ILookup<string, EmployeeContactInfo> _contactsByFio;
|
||||
private readonly IReadOnlyDictionary<string, string> _fioByEmail;
|
||||
|
||||
public EmployeeDirectorySnapshot(
|
||||
IReadOnlyList<EmployeeFullBaseInfo> fullBase, IReadOnlyList<EmployeeContactInfo> contacts)
|
||||
{
|
||||
_fullBaseByFio = fullBase.ToLookup(e => Normalize(e.Fio));
|
||||
_contactsByFio = contacts.ToLookup(e => Normalize(e.Fio));
|
||||
|
||||
// Обратный индекс email → ФИО — нужен, чтобы подписать напоминание именем
|
||||
// получателя, когда известен только его email (руководитель кандидата,
|
||||
// см. GetManagerAsync). При дублях email в справочнике побеждает первая
|
||||
// запись — этого достаточно для отображения имени, не для идентификации.
|
||||
_fioByEmail = contacts
|
||||
.Where(e => !string.IsNullOrWhiteSpace(e.Email))
|
||||
.GroupBy(e => e.Email!.Trim().ToLowerInvariant())
|
||||
.ToDictionary(g => g.Key, g => g.First().Fio);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -64,6 +74,10 @@ internal sealed class EmployeeDirectorySnapshot
|
||||
.Select(e => e.Email)
|
||||
.FirstOrDefault(email => !string.IsNullOrWhiteSpace(email));
|
||||
|
||||
/// <summary>ФИО по email — для ReceiverName, когда известен только email получателя (см. EmailOf).</summary>
|
||||
public string? NameByEmail(string email) =>
|
||||
_fioByEmail.GetValueOrDefault(email.Trim().ToLowerInvariant());
|
||||
|
||||
/// <summary>
|
||||
/// В справочнике и в заявке ФИО набирают руками, поэтому сравниваем без учёта
|
||||
/// регистра и лишних пробелов между словами (в живых данных встречаются и
|
||||
|
||||
Reference in New Issue
Block a user