Пробрасывание идентификатора завершённого задания в плейсхолдеры при отправке уведомлений
Пробрасывание идентификатора завершённого задания в плейсхолдеры при отправке уведомлений¶
Стандартные карточки уведомлений подразумевают автоматическое формирование тела и заголовка письма из плейсхолдеров. Отправка выполняется в бизнес-процессах или через API INotificationManager
.
Рассмотрим следующую ситуацию. Завершается задание, и заинтересованным участникам процесса надо предоставить информацию по этому заданию - на какую роль оно было назначено, кто являлся автором и др. Методы INotificationManager.Send()
принимают только идентификатор карточки, который может использоваться со стандартными плейсхолдерами {f:...}
, {t:...}
и др.
Если же помимо идентификатора карточки надо передать идентификатор завершённого задания (и любую другую информацию), то он указывается в методе отправки уведомлений (например, скрипт завершения задания):
Guid taskRowID = ...;
var info = new Dictionary<string, object> { { "TaskRowID", taskRowID } };
await this.Resolve<INotificationManager>()
.SendAsync("NotificationCardAlias", CardID, "Имя роли", info: info);
Информация будет доступна по ключу в context.Info из контекста плейсхолдеров, но стандартные плейсхолдеры не используют такой идентификатор задания. Надо написать свой плейсхолдер, который получит идентификатор задания по ключу из Info и вернёт определённое свойство этого задания, причём имя колонки в таблице он получит параметром (после двоеточия). Используется таблица TaskHistory, т.к. при выполнении расширения на завершение задания в бизнес-процессе строка в таблице Tasks уже удалена.
using System;
using System.Threading;
using System.Threading.Tasks;
using Tessa.Platform;
using Tessa.Platform.Data;
using Tessa.Platform.Placeholders;
using Tessa.Platform.Storage;
namespace Tessa.Extensions.Shared.Placeholders
{
public static class AbPlaceholderHelper
{
public static async Task<PlaceholderValue> ReplaceCustomPlaceholderAsync(
IPlaceholderReplacementContext context,
IPlaceholder placeholder,
CancellationToken cancellationToken = default)
{
IDbScope dbScope = context.TryGetDbScope();
if (dbScope == null || string.IsNullOrEmpty(placeholder.Parameters))
{
return null;
}
Guid? taskRowID = context.Info.TryGet<Guid?>("TaskRowID");
if (!taskRowID.HasValue)
{
return null;
}
using (dbScope.Create())
{
// для {tasks:RoleName} будет выполнен запрос вида:
// SELECT [RoleName] FROM [TaskHistory] WITH(NOLOCK) WHERE [RowID] = @RowID
DbManager db = dbScope.Db;
object result = await db
.SetCommand(
dbScope.BuilderFactory
.Select().C(placeholder.Parameters)
.From("TaskHistory").NoLock()
.Where().C("RowID").Equals().P("RowID")
.Build(),
db.Parameter("RowID", taskRowID.Value))
.ExecuteAsync<object>(cancellationToken).ConfigureAwait(false);
string text = FormattingHelper.FormatToString(result);
return await context.FormatFieldAsync(
placeholder, text, new PlaceholderField(result),
cancellationToken: cancellationToken).ConfigureAwait(false);
}
}
}
}
Плейсхолдер использует базу данных, поэтому зарегистрируем его на сервере в сборке Tessa.Extensions.Server
.
using Tessa.Platform;
using Tessa.Platform.Placeholders;
namespace Tessa.Extensions.Shared.Placeholders
{
[Registrator]
public sealed class Registrator : RegistratorBase
{
public override void FinalizeRegistration()
{
// в методе Register указывается true, потому что плейсхолдер всегда принимает
// параметр после двоеточия, например: {tasks:UserName}
this.UnityContainer
.TryResolve<IPlaceholderContainer>()
?.Register(new FieldPlaceholderType("tasks", true, AbPlaceholderHelper.ReplaceCustomPlaceholderAsync))
;
}
}
}
Пример использования плейсхолдера в теле письма уведомления:
<ul>
<li>Назначено на: {task:RoleName}</li>
<li>Завершил: {task:UserName}</li>
<li>Вариант завершения: {task:OptionCaption}</li>
</ul>