Какие есть средства для того, чтобы узнать, кто заблокировал (открыл) обращение ?
Нужно отображать разным цветом открытые и не открытые обращения.
При открытии обращения, которое отмечено как открытое, нужно отображать имя того, кто открыл (заблокировал) обращение.
Вопрос: какие средства есть для решения данной задачи ?
Нравится
По второму пункту - добавляйте новую колонку в объект, и заполняйте её текущим пользователем при смене состояния обращения (придется писать код в процессе карточки).
По первому (выделение цветом):
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 хвилини - вилучається.
В результаті карточка відкрита, але не заблокована.
Чи ніяк, і треба просто стерти повідомлення згенероване базовим варіантом і залишити своє, та на тому й заспокоїтись ?
Подписка на событие происходит в init базовой страницы редактирования.
Для подписки на закрытие окна, необходимо в клиентский javascript код добавить (Page.AddScript), в котором также добавить обработчик закрытия окна.
Обработчик должен отправить сообщение в процесс страницы (можно посмотреть по исходники приложения). Функция называется «throwMessage».
Останнє повідомлення, як я розумію, стосується теми "Не відпрацьовують події карточки "Обращения" CancelButtonClick, DataSourceCanceled." ?
Соррі, виправив назву теми :)
Как один из вариантов : в метод Init добавить такой код
window.onunload = function(){
//событие закрытие окна
}
То як все-таки внести зміни в [BlockScriptTask] базового варіанту, щоб вони (зміни) спрацювали ?
protected override void OnUnload(EventArgs e)
{
base.OnUnload(e);
// your code
}