Защита от "дурака" спасает только от неизобретательного дурака.
(С) Постулаты Трумена по программированию.
Любая система, зависящая от человеческой надежности, ненадежна.
(С) Законы ненадежности Джилба.
Отправляю документ по типовому маршруту, нельзя быть абсолютно уверенным, что все его исполнители выполнят только те действия, которые от них требуются. И вероятность выполнения ненужных или неправильных действий только увеличивается с количеством исполнителей.
Рассмотрим 2 метода исключения достаточно серьезного случая вероятного нарушения логики любого типового маршрута и, как следствие, построения листов согласования.
1. Запрет создания новой версии документа, вложенного в задачу (с разрешением в определенных заданиях).
Для запрета создания новой версии нам будет необходимы свойства 2го табличного раздела карточки документа (Информация о версиях хранится во 2ой табличной части карточки документа).
Добавляем в событие "Добавление После" Таблицы 2 карточки электронного документа:
CanCreateVersion = TRUE // изначально, при создании документа, новые версии создавать можно
if not Object.Inserted // необходимое условие для создания первой версии
// Поиск задач "в работе"
Search = Searches.Load('ATTACHED_TO_TASK_SEARCH')
EDocInfo = EDocuments.ObjectInfo(Object.ID)
Search.InitializeSearch(EDocInfo)
Criteria = Search.SearchCriteria
StateCriterion = Criteria.Add("TaskState")
StateCriterion.Add("В работе")
StateCriterion.ValuesBuildType = btOnly
StandardRouteCriterion = Criteria.Add("StandardRoute")
// код ТМ, по которому ищем вложенным наш документ
StandardRouteCriterion.Add(Конст("CMAgreementStandardRoute"))
StandardRouteCriterion.ValuesBuildType = btOnly
TasksInWork = Searches.Execute(Search)
// Анализ
if TasksInWork.Count > 0
CanCreateVersion = FALSE // если есть задачи в работе - запретим создавать новые версии
// пройдемся по всем найденным задачам
foreach TaskInfo in TasksInWork
Task = TaskInfo.Task
Jobss = Task.DetailDataSet(3)
if Jobss.RecordCount > 0
Jobss.First()
While not Jobss.EOF
// разрешим создание новых версий только на определенных этапах ТМ
if ((SubString(Jobss.Subject; ' '; 1) == 'Доработка')
or (SubString(Jobss.Subject; ' '; 1) == 'Контроль'))
and (Jobss.JobState == "В работе")
CanCreateVersion = TRUE
endif
Jobss.Next()
endwhile
endif
endforeach
endif
endif
// Запретим создание новых версий документа
if not CanCreateVersion
Raise(CreateException('';
'Создавать новые версии можно только на этапах доработки документа по ТМ.'; ecWarning))
endif
2. Запрет создания новой версии документа.
Запретим создавать новые версии документам по произвольным условиям без привязки к типовым маршрутам.
а) Набор реквизитов карточки электронного документа:
Добавить новый реквизит типа Признак со значениями "Да/Нет", допустим, "ДаНет5".
б) Событие "Добавление После" карточки электронного документа:
Object.ДаНет5 = 'Да' // Разрешим создавать новые версии документа
в) Событие "Добавление После" Таблицы 2 карточки электронного документа:
if Object.ДаНет5 == 'Нет'
Raise(CreateException(''; 'Создание новых версий запрещено.'; ecWarning))
endif
г) В необходимых вычислениях, например, при расчете какого-либо реквизита, присваеваем реквизиту "ДаНет5" значение "Нет", это не позволит пользователям создавать новые версии документов.
Алексей, поясните пожалуйста, как создание версии документа приводит к "нарушению логики любого типового маршрута и построению листов согласования"?
Больше к построению листа согласования.
Приведу пример: лист согласования строится по ЭЦП на документе по определенной его версии и примечаниям выполненных заданий из ТМ. Пользователь перед подписанием может запросто создать еще одну версию документу, к примеру, его не устроил текст, а так как документ наверняка уже подписан другими, он внесет корректировки через новую версию. Или инициатор проявил инициативу и мониторил после каждого согласующего их комментарии в задаче и сразу вносил корректировки новыми версиями. При этом общий список ЭЦП будет разделен по нескольким версиям документа и при построении листа согласования он будет только из тех подписей, что на указанной версии документа.
Нарушение логики ТМ может быть в организационном понимании, например, при согласованиях договора должна подписываться ЭЦП последняя версия документа, но согласующий по предыдущему примеру может создать еще одну версию документа и последующие согласующие уже будут ставить ЭЦП не на той версии.
У меня не реализуется выполнения данного кода по первому варианту, система ошибки не выдает.
В своей организации вторым методом пользуемся уже давно и это избавило нас от многих проблем, связанных с созданием новой версии в процессе согласования документа. НО! При импорте документа в новую версию любым из предоставляемых системой способов (из файла, из шаблона, из документа), исключение, прописанное в коде табличной части карточки, не срабатывает. На экране появляется замечательная ошибка "Access violation at address 058F99AD in module sbedms.bpl", новая версия не создается, но пользователь пугается и начинает звонить в службу поддержки организации с недоуменным вопросом "а чо это?" :) Кто уже сталкивался с подобной проблемой и нашел путь/пути ее решения, коллеги?
А в службу поддержки обращались? Мне кажется это платформенный глюк.
Некоторое время назад тоже понадобилось запретить создание новых версий документа на определенной стадии ЖЦ. Тоже решил использовать событие Таблица2.ДобавлениеДо, и тоже столкнулся с ошибкой "Access violation..." при импорте. Попробовал использовать два события Запись.СохранениеДо (для проверки и выдачи исключения) и Запись.Открытие (для запоминания количества версий). Но столкнулся с другой бедой - если пользователь после получения сообщения о невозможности создания новой версии еще раз нажмет на ОК в том же самом диалоге создания версии (ведь он в этот момент все еще остается открыт), то возникает ошибка "В списке методов добавляемый метод уже существует".
Поразмыслив, решил использовать оба метода, но каждый - только для "своих" случаев. Таким образом, пришлось вставить код в три события (при открытии запоминается количество). Сработало. Посмотрите, что получилось (комментарии в коде поясняют то же самое, что я написал выше, специально оставил, чтобы потом не ломать голову, зачем такие ухищрения :)
Обработчик события Запись.Открытие
Обработчик события Запись.СохранениеДо
Обработчик события Таблица2.ДобавлениеДо
"В списке методов добавляемый метод уже существует" данная ошибка всё равно остается. :(
> "В списке методов добавляемый метод уже существует" данная ошибка всё равно остается. :(
Ильдус, Вы делали по моей рекомендации (добавили приведенный код в обработчики трех событий)?
Дополнительные вопросы:
// Запрет создания новой версии документа, находящегося в стадии ЖЦ, отличной от "Инициализация".
// Реализован сразу двумя способами:
// 1. Для случаев, когда версия создается на основе одной из предыдущих версий этого же документа,
// запрет реализован в событии "Таблица2.ДобавлениеДо" (т.е.здесь)
// 2. Для остальных случаев запрет реализован в событии "Запись.СохранениеДо"
//
// Такой подход нужен для обхода следующих ограничений:
// 1. Если реализовать только в событии "Запись.СохранениеДо", то если при попытке создания новой версии пользователь
// после получения сообщения еще раз нажмет на ОК, возникает ошибка "В списке методов добавляемый метод уже существует".
// 2. Если при импорте из файла, шаблона или другого документа в событии "Таблица2.ДобавлениеДо" сгенерировать исключение,
// то возникает ошибка "Access violation at address ... in module 'sbedms.bpl'. Read of address 00000000"
// (известный дефект платформы)
//
if Object.ISBEDocLifeStageName <<>> "Initialization"
ShowMessage(EDocumentVersionSource.SourceType)
if EDocumentVersionSource.SourceType == edvstEDocumentVersionCopy
if EDocumentVersionSource.Value.Parent.ID = Object.ID
Raise(CreateException("excNewVersionsNotAllowed"; "Создание новой версии возможно только в стадии инициализации/доработки!"; ecWarning))
endif
endif
endif
Авторизуйтесь, чтобы написать комментарий