Какие есть средства для того, чтобы узнать, кто заблокировал (открыл) обращение ?

Нужно отображать разным цветом открытые и не открытые обращения.
При открытии обращения, которое отмечено как открытое, нужно отображать имя того, кто открыл (заблокировал) обращение.

Вопрос: какие средства есть для решения данной задачи ?

Нравится

17 комментариев

По второму пункту - добавляйте новую колонку в объект, и заполняйте её текущим пользователем при смене состояния обращения (придется писать код в процессе карточки).
По первому (выделение цветом):
http://www.community.terrasoft.ru/forum/topic/8493

Наверное не при смене состояния, а при открытии окна с обращением ?
Если пусто - прописывать текущего пользователя, а если пользователь прописан, то оставлять без изменения. А при закрытии, если текущий пользователь совпадает с прописанным, то очищать поле, а если отличается, то оставлять без изменений.

Тогда возникает вопрос, как отследить закрытие окна обращения ?

Это нужно на нажатие OkButtonClick и CancelButtonClick сгенерировать линейки с обработкой ?

Похожий алгоритм события на кнопку "OkButtonClick" упоминалось в следующих темах:

- http://www.community.terrasoft.ua/forum/topic/11155
- http://www.community.terrasoft.ua/forum/topic/9582
- http://www.community.terrasoft.ua/blogs/9855

Если возникнут дополнительные вопросы или сложности, пожалуйста, сообщите.

Если обращение никем не занято, то в запись обращения, в соответствующее поле (добавил LockedById), нужно прописать текущего пользователя.
Это нужно делать на этапе инициализации окна обращения ?

Далее, если обращение занято, то нужно заблокировать возможность внесения изменений, как это сделать ?

И еще,- в скрипте инициализации, чтобы посмотреть, добавил строку:

Page.BaseMessagePanel.AddMessage(Warning, "Обращение заблокировано пользователем ["+LockedById.ToString()+"]", MessageType.Warning);

Получился странный эффект: вывелось сообщение, которое потом начало периодически повторяться.
Возможно в скрипте инициализации не место для вывода таких сообщений ?

"Ігор Андрусенко" написал:Получился странный эффект: вывелось сообщение, которое потом начало периодически повторяться.
Возможно в скрипте инициализации не место для вывода таких сообщений ?

Таки да, - в скрипте ChildPageLoadCompleteScriptExecute никаких повторений не возникает.

Такая вот неожиданность:
нажатие кнопки CancelButtonClick не запускает процесс обработки.
OkButtonClick запускает.

Я для отладки пишу в текстовый файл информацию.

Собственно, на данный момент решаю такую задачу:
при открытии обращения пишется текущий пользователь в поле LockedById;

при закрытии если (lockedById == UserConnection.CurrentUser.ContactId), то
LockedById нужно обнулить.

Для фиксирования блокирующего пользователя воспользовался событием [DataSourceBeforeSave], в котором пишу:

var lockedById = Page.DataSource.ActiveRow.GetTypedColumnValue<Guid>("LockedById");
if (lockedById == UserConnection.CurrentUser.ContactId) {
	Page.DataSource.ActiveRow.SetColumnValue("LockedById", null);
}
return true;

Это срабатывает.

А вот отработку закрытия окна обращения начал с попытки отработать нажатие на [CancelButton]:

var update = new
Update(UserConnection, "ServiceRequest").
Set("LockedById", Column.Parameter(Guid.Empty)).
	Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue));
update.Execute();
 
string logString = @"
[" + System.DateTime.Now.ToString() + @"] [CancelButtonClickIncidentScriptExecute]:
LockedById ==>> null" + (char)13 + (char)10;
System.IO.File.AppendAllText("C:\\inetpub\\wwwroot\\BPMOnline\\ServiceRequestCardOpenLog\\Log.txt", logString);
 
return true;

Пока что пытаюсь безусловно сбрасывать блокирующего пользователя.
Но увы, скрипт обработки нажатия [CancelButton] не отрабатывает.
Кстати, не отрабатывает и событие [DataSourceCanceled].

Почему так ?

PS. А еще нужно отработать и закрытие окна по крестику.

Как лучше решить данную задачку ?

Сделайте все пошагово. Сначала проверьте, чтоб у вас отрабатывало само событие клика на CancelButton, а затем смотреть дальше происходит в коде

Ось шлях до визначення хто заблокував карточку звернення користуючись базовою логікою:

В [IncidentEditPageEventsProcess] є скрипт [BlockScriptTask]. Вньому є такий код:

Page.BaseMessagePanel.AddMessage("Внимание!", "Данная запись заблокирована, так как возможно уже открыта для редактирования в другом месте.", MessageType.Warning);

Я добавив визначення особи блокувальника наступним чином:

//	Визначаємо ім"я особи, що блокує поточне звернення
var blockedByUserName = "";
Guid recordId = Page.DataSource.ActiveRowPrimaryColumnValue;
if (recordId != Guid.Empty) {
	var selectSRU = new Select(UserConnection)
		.Column("SessionId")
		.From("SysRecordInUse")
		.Where("RecordId").IsEqual(Column.Parameter(recordId,"Guid"))
		as Select;
	string sessionId = selectSRU.ExecuteScalar<string>();
	if (!String.IsNullOrWhiteSpace(sessionId)) {
		EntitySchemaQuery esqSUS = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "SysUserSession");
		string idColumnName = esqSUS.AddColumn("ModifiedBy.Id").Name;
		string nameColumnName = esqSUS.AddColumn("ModifiedBy.Name").Name;
		EntitySchemaQuery subESQ = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "SysUserSession");
		subESQ.AddColumn(subESQ.CreateAggregationFunction(AggregationTypeStrict.Max, "ModifiedOn"));
 
		var filterSubSessionId = subESQ.CreateFilterWithParameters(FilterComparisonType.Equal, "SessionId", sessionId);
		subESQ.Filters.Add(filterSubSessionId);
 
		var filterSusMaxDate = esqSUS.CreateFilter(FilterComparisonType.Equal, "ModifiedOn", subESQ);
		esqSUS.Filters.Add(filterSusMaxDate);
 
		var filterSession = esqSUS.CreateFilterWithParameters(FilterComparisonType.Equal, "SessionId", sessionId);
		esqSUS.Filters.Add(filterSession);
		var entities = esqSUS.GetEntityCollection(UserConnection);
		if (entities.Count>0) {
			string name = entities[0].GetTypedColumnValue<string>(nameColumnName);
			Guid id = entities[0].GetTypedColumnValue<Guid>(idColumnName);
			blockedByUserName = (UserConnection.CurrentUser.ContactId != id) ? name:"";
		}
	}
}

І в код видачі інформаційного повідомлення також вніс зміни:

Page.BaseMessagePanel.AddMessage("Внимание!", "Данная запись заблокирована"+(!String.IsNullOrWhiteSpace(blockedByUserName))?(" пользователем ["+blockedByUserName+"]"):("")+", так как возможно уже открыта для редактирования в другом месте.", MessageType.Warning);

В результаті новостворене поле [LockedById], в якому я намагався фіксувати особу, що (!) відкриває карточку, виявляється непотрібним - цілком вистачає базового функціоналу.

Логіка вирішення наступна:
по Guid карточки в таблиці [SysRecordInUse] визначаю [SessionId],
по ньому з таблиці сесій [SysUserSession] визначаю [ModifiedById],
це і є особа, що заблокувала карточку звернення.

Функціонал блокування - базовий - в ньому при відкритті карточки перевіряється таблиця [SysRecordInUse] на присутність Guid карточки, якщо відсутній - добавляється, після чого вилучаються всі записи про блокування, що старіші за 2 хвилини (працює метод [SysRecordInUse()]).

В такій схемі є мінус, - коли карточка відкрита більше 2-х хвилин, потім її оновити (чи закрити-відкрити), то згідно з закладеною логікою вийде наступне:
- Guid в [SysRecordInUse] присутній - не добавляється;
- він старший за 2 хвилини - вилучається.
В результаті карточка відкрита, але не заблокована.

Поспішив похвалитися :(

Зміни в [BlockScriptTask] вніс, опублікував, а працює старий варіант.
Коли, для перевірки, цей же самий код вношу в [ChildPageLoadCompleteScript], то отримую наступну картинку:

То як все-таки внести зміни в [BlockScriptTask] базового варіанту, щоб вони спрацювали ?

Чи ніяк, і треба просто стерти повідомлення згенероване базовим варіантом і залишити своє, та на тому й заспокоїтись ?

Подписка на событие происходит в init базовой страницы редактирования.
Для подписки на закрытие окна, необходимо в клиентский javascript код добавить (Page.AddScript), в котором также добавить обработчик закрытия окна.
Обработчик должен отправить сообщение в процесс страницы (можно посмотреть по исходники приложения). Функция называется «throwMessage».

Останнє повідомлення, як я розумію, стосується теми "Не відпрацьовують події карточки "Обращения" CancelButtonClick, DataSourceCanceled." ?

Соррі, виправив назву теми :)

Как один из вариантов : в метод Init добавить такой код
window.onunload = function(){
//событие закрытие окна
}

То як все-таки внести зміни в [BlockScriptTask] базового варіанту, щоб вони (зміни) спрацювали ?

protected override void OnUnload(EventArgs e)
{
base.OnUnload(e);

// your code
}

Показать все комментарии