Во-первых, спасибо за замечательный проект! Очень полезная модификация, делающая возможным настраивать оповещения для других. Также очень удачной оказалась доработка шаблонов оповещений с тем, чтобы в них можно было подставлять значения полей и методов табличного буфера, однако, эта подстановка получилась несколько... мощнее, чем то, что можно доверить пользователям
Вот как был доработан внутренний цикл поиска и "обсчета" макросов из шаблона - блок if (!keywords.exists(keyword)) метода createKeywordMap(), который вызывается из \Data Dictionary\Tables\EventInbox\Methods\initFromBuffer:
X++:
// по умолчанию вернем в виде значения сам token - так проще "отлаживать" шаблоны
keyword_value = #startReplaceToken + keyword + #endReplaceToken;
if (match(@"<[a-z_][a-z0-9_]*\(\)>", keyword))
{
switch (keyword)
{
case @"modifiedBy_Name()" :
keyword_value = getUserFIO(_buffer.modifiedBy);
break;
case @"createdBy_Name()" :
keyword_value = getUserFIO(_buffer.createdBy);
break;
default :
tblMethodName = strreplace(keyword, '()', '');
if (this.mayEvaluateTableMethodReturnValue(bufferTable.id(), tblMethodName))
{
keyword_value = strfmt("%1", bufferTable.callObject(tblMethodName, _buffer));
}
break;
}
}
else
{
bufferFldId = fieldname2Id(_buffer.tableid, keyword);
if (bufferFldId)
{
keyword_value = strfmt("%1", _buffer.(bufferFldId));
}
}
Изменения сделаны такие:
- немного строже проверяется что в шаблоне дергается метод таблицы;
- добавлены два "встроенных" метода, возвращающих имя автора создания/последнего изменения записи (getUserFIO() - "макрос", который возвращает имя по коду пользователя);
- добавлена проверка на то, можно ли собственно вызывать в данном контексте тот экземплярный табличный метод, который указан в шаблоне.
Последняя проверка сделана из тех соображений, чтобы не дать пользователям с помощью шаблона уведомлений вызывать методы, которые не являются display-ными и вообще могут что-то поменять в базе (например, метод delete()
). Проверка выглядит вот так:
X++:
// можно ли дернуть табличный метод для получения его возвращаемого значения и подстановки этого значения вместо имени метода в письмо?
private boolean mayEvaluateTableMethodReturnValue(tableId _tableId, SysMethodName _instanceMethodName)
{
Types returnType;
DictMethod dictMethod = new DictMethod(UtilElementType::TableInstanceMethod, _tableId, _instanceMethodName);
boolean ret = false;
;
if ( dictMethod
&& dictMethod.parameterCnt() == 0
&& dictMethod.displayType() == DisplayFunctionType::Get
)
{
if (dictMethod.returnType() == Types::UserType)
{
returnType = extendedTypeId2Type(dictMethod.returnId());
}
else
{
returnType = dictMethod.returnType();
}
// является ли тип возвращаемого значения значимым (т.е. не ссылочным)?
ret = returnType == Types::String
|| returnType == Types::RString
|| returnType == Types::VarString
|| returnType == Types::Integer
|| returnType == Types::Int64
|| returnType == Types::Real
|| returnType == Types::Date
|| returnType == Types::UtcDateTime
|| returnType == Types::Enum
|| returnType == Types::Guid
|| returnType == Types::Time
;
}
return ret;
}