Для того, щоб зафіксувати користувача, що відкриває карточку звернення, вношу зміни в скрипт ChildPageLoadCompleteScriptExecute (повідомлення PageLoadComplete).
.Column("LockedById")
.From("ServiceRequest")
.Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue,"Guid"))
as Select;
using (var dbExecutor = UserConnection.EnsureDBConnection()) {
var needToCapture = false;
var contact = new Terrasoft.Configuration.Contact(Page.UserConnection);
var lockedByName = "Unknown";
var lockedById = selectSR.ExecuteScalarGuid>();
if (lockedById == Guid.Empty) {
lockedById = UserConnection.CurrentUser.ContactId;
needToCapture = true;
}
if (contact.FetchFromDB(lockedById)) {
lockedByName = contact.Name;
}
if (needToCapture) {
var update = new
Update(UserConnection, "ServiceRequest").
Set("LockedById", Column.Parameter(lockedById)).
Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue));
update.Execute();
} else
if (lockedById != UserConnection.CurrentUser.ContactId) {
Page.BaseMessagePanel.AddMessage(Warning, "Обращение заблокировано пользователем ["+lockedByName+"] [ "+lockedById.ToString()+" ] [ "+(UserConnection.CurrentUser.ContactId).ToString()+" ]", MessageType.Warning);
}
}
При натисненні плашки OK скрипт OKButtonClickScriptExecute відпрацьовує повідомлення OKButtonClick, при цьому очищається поле LockedById, в яком фіксується користувач, що тримає карточку:
.Column("LockedById")
.From("ServiceRequest")
.Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue,"Guid"))
as Select;
using (var dbExecutor = UserConnection.EnsureDBConnection()) {
dbExecutor.StartTransaction();
var lockedById = selectSR.ExecuteScalarGuid>();
if (UserConnection.CurrentUser.ContactId == lockedById) {
try {
var update = new
Update(UserConnection, "ServiceRequest").
Set("LockedById", Column.Parameter(null, "Guid")).
Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue));
update.Execute();
} catch (Exception e) {
System.IO.File.AppendAllText("C:\\inetpub\\wwwroot\\BPMOnline\\ServiceRequestCardOpenLog\\Log.txt", (char)13 + (char)10 + e.Message + (char)13 + (char)10);
}
lockedById = selectSR.ExecuteScalarGuid>();
}
dbExecutor.CommitTransaction();
lockedById = selectSR.ExecuteScalarGuid>();
}
Все добре, окрім одного моменту - інколи повідомлення PageLoadComplete повторно генерується після того, як вже була натиснута плашка OK. Відповідно ChildPageLoadCompleteScriptExecute відпрацьовує заново і в поле LockedById знову прописується поточний користувач.
Запитання: чому повідомлення PageLoadComplete генерується повторно ?
Нравится
Добрый день, Игорь!
Так как в bpm'online модель событий преимущественно заимствована из ASP.NET, то и ведет она себя аналогичным образом.
Цитирую:
"
В серверных элементах управления некоторые события (обычно событие нажатия) вызывают немедленную отправку страницы назад на сервер. События изменения в серверных элементах управления HTML и в серверных веб-элементах управления, например, элемент управления TextBox, захватываются, но не вызывают отправки. Вместо этого они создаются при следующем выполнении отправки.
...
После отправки страницы создаются события инициализации страницы (Page_Init и Page_Load), а затем обрабатываются события элементов управления. При отсутствии подробных сведений об обработке событий на странице не следует создавать логику приложения, которая опирается на события изменения, вызываемые в определенном порядке. Дополнительные сведения см. в разделе Общие сведения о жизненном цикле веб-страниц ASP.NET.
" (тыц)
Соответсвенно, PageLoadComplete вызывается каждый раз при нажатии на кнопку. Вам необходимо учесть данный аспект. Можно добавить параметр на страницу, который проверять и заполнять при первом вызове PageLoadComplete. Например:
if (!NeedLockaPage) { //установка блокировки } NeedLockPage = true;
Здесь NeedLockPage - это параметр страницы логического типа.
Мова про параметр в структурі IncidentEditPageEventsProcess ?
Чи в IncidentEditPage ?
Про параметр процесса страницы, то есть IncidentEditPageEventsProcess (первый вариант).
Я спробував так зробити, але при повторній обробці PageLoadComplete NeedLockPage виявляється знову false, хоча мав би бути true.
Ігор, а спробуйте в ChildPageLoadCompleteScriptExecute зробити перевірку на існування сессії. Якщо сессія відкрита, значить відразу вийти і нічого не робити і навпаки
Чудеса не припиняються.
На [OK] створив обробника:
var selectSR = new Select(UserConnection) .Column("LockedById") .From("ServiceRequest") .Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue,"Guid")) as Select; using (var dbExecutor = UserConnection.EnsureDBConnection()) { dbExecutor.StartTransaction(); var lockedById = selectSR.ExecuteScalar<Guid>(); if (UserConnection.CurrentUser.ContactId == lockedById) { var update = new Update(UserConnection, "ServiceRequest"). Set("LockedById", Column.Parameter(null, "Guid")). Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue)); update.Execute(); } lockedById = selectSR.ExecuteScalar<Guid>(); UserConnection.SessionData["NeedLockPage_"+EntityPrimaryColumnValue.ToString()] = 0; } return true;
На вході чітко виконується умова:
(UserConnection.CurrentUser.ContactId == lockedById)
Після UPDATE
lockedById = selectSR.ExecuteScalar<Guid>();
значення lockedById стає Guid.Empty (як і належить).
В профайлері знаходжу відповідний запит
exec sp_executesql N' UPDATE [dbo].[ServiceRequest] SET [LockedById] = @P2 WHERE [Id] = @P1',N'@P1 uniqueidentifier,@P2 uniqueidentifier',@P1='19717479-93BF-4AC9-9095-36D6A8F32583',@P2=NULL
Але після того, як закривається сторінка, значення поля [LockedById] у відповідному записі таблиці [ServiceRequest] залишається без змін.
Щось я явно випускаю з виду. Що саме ?
Наскільки я зрозумів, Значення [LockedById] змінюється на не NULL після того як сторінка закрилась? Якщо так то потрібно дивитися далі в профайлері, який запрос його змінює
Схоже, що проблема була в організації транзакцій. Наступний код вирішив проблему:
dbExecutor.StartTransaction(); try { var update = new Update(UserConnection, "ServiceRequest"). Set("LockedById", Column.Parameter(null, "Guid")). Where("Id").IsEqual(Column.Parameter(EntityPrimaryColumnValue)); update.Execute(); } catch (Exception e) { dbExecutor.RollbackTransaction(); System.IO.File.AppendAllText("C:\\inetpub\\wwwroot\\BPMOnline\\ServiceRequestCardOpenLog\\Log.txt", (char)13 + (char)10 + e.Message + (char)13 + (char)10); } dbExecutor.CommitTransaction();
Одна задача вирішилась, натомість виникла інша: при натисненні плашки [OK] в реєстрі звернень запис конкретного звернення оновлюється, - видно зміну по полю [LockedById], все добре. А от коли UPDATE виконується в рамках [ChildPageLoadCompleteScriptExecute], то в реєстрі запис цього звернення не оновлюється, а потрібно, щоб оновлювався.
Як це зробити ?
А ви пробували в дебагі дивитися що виконується в ChildPageLoadCompleteScriptExecute?
В дебагі не дивився, але чисто за логікою розумію, що обробка [OK] передбачає завершувальні операції щодо карточки. Саме завдяки цим операціям і здійснюється оновлення реєстру.
Питання якраз і полягає в тому, щоб заставити реєстр оновитись до натиснення [OK]
Це правильно, але натискання плашки ОК, як я розумію, визиває перезагрузку сторінки і тим самим визиває ChildPageLoadCompleteScriptExecute. Якщо я правильно розумію