среда, 30 сентября 2009 г.

Интеграция DocsVision и Outlook

Как можно скрестить DocsVision и Outlook, чтобы работая только с одним приложением выполнять операции сразу в двух.


Опыт первый. Работаем с DocsVision через Outlook.

Создаем папку в Outlook


В свойствах на вкладке "Домашняя страница" указываем адрес сервера DocsVision.



Готово. В папке теперь показывается DocsVision Навигатор.



Опыт второй. "Переносим" Outlook внутрь DocsVision
Данный вариант требует, чтобы в организации был сервер Exchange и развернут Outlook Web Access

Создаем папку в DocsVision и в свойствах указываем адрес Outlook Web Access и опцию "По умолчанию отображать URL"


Готово. В папке теперь показывается Outlook.




Так же можно сделать папку с любым почтовым сервером. Например с GMail.


понедельник, 28 сентября 2009 г.

T-SQL Скрипт для рассчета количества рабочих часов между двумя датами с учетом бизнес-календаря

Новая версия функции рассчета рабочих часов между двумя датами с учетом бизнес-календаря. Предыдущие версии содержали ошибку.

Итак напомню.


Бизнес календарь имеет 3 секции (лучше посмотреть в CardManager)

1. Основная информация (только одно поле Name, понятно для чего оно нужно)
2. Года (Years). Имеет отдно поле Year в котором указывается год
2.1 Подсекция Days. Имеет поля Day - номер дня от начала года и Type тип
2.1.1 Подсекция WorkTime. Поля StartTime и EndTime - временной диапазон
3. DefaultTimeSettings. Поля StartTime и EndTime - временной диапазон


В календаре можно делать несколько настроек.

1. Настрока рабочего времени по умолчанию.
Данная настройка будет храниться в секции DefaultTimeSettings. Строки секции будут содержать временные интервалы.

2. Настройка конкретного дня.
В этом случае будет создана строка в секции Years, в подсекции Days, в подсекции WorkTime с указанием интервала.
Например, 02.01.2009 должен быть рабочим днем, с рабочим времением с 12:00 до 15:00.
При сохранении данные будут хранится следующим образом (названия секций в квадратных скобках):
[Years]: Year = 2009
[Days]: Day = 2
[WorkTime]: StartTime=12:00, EndTime=15:00

3. Настройка календаря по умолчанию
Данные настройки будут храниться в той же секции Years (аналогично п.2), но в году 1796.

Если для конкретного дня нет сохраненных настроек, берется следующее рабочее время:
Рабочие дни: с понедельника по пятницу
Рабочий график: с 9:00 до 13:00, и с 14:00 до 18:00

Скрипт состоит из 3х функций
1. Проверка, является ли данный день рабочим FIsWorkTime
2. Ф-ция рассчета длительности рабочего времени для одного дня FGetDayDuration
3. Основная ф-ция рассчета длительности между двумя датами FBusinessHours2

Алгоритм следующий.
Ф-ция FBusinessHours2 вычисляет при помощи FGetDayDuration длительность рабочего времени в первом дне интервала (до конца первого рабочего дня). Длительность рабочего времени в последнем дне интервала (от начала рабочего дня до конечного времени), и длительность во всех днях между начальным и конечным.

Поскольку данные хранятся для конкретных дней, а не для всех, то единственным способом подсчета является перебор всех дней в цикле. Это крайне не оптимальный способ. Альтернативным вариантом было бы периодическое создание "карты" рабочего расписания для абсолютно всех дней в интервале, с хранением времени в UTC в отдельной таблице. Тогда расчет длительности можно будет выполнить несколькими SELECT'ами за доли секунды.

Ф-ция FBusinessHours2 может возвращать данные в минутах или часах в зависимости от 3-го параметра @Mode.

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

пятница, 25 сентября 2009 г.

Настройки карточек в Справочнике типов

Довольно популярный вопрос.
Добавляем свойство в вид карточки в справочнике, и данное свойство присутствует только у вновь созданных карточек. Старые карточки не имеют этого свойства. А если добавить кнопку - функцию в виде, то данная кнопка появляется как вновых так и в старых карточках. Почему так происходит?

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


p.s. А как все таки добавить новое свойство в ранее созданные карточки?
Сделать это можно, например, бизнес-процессом.

Добавление своей карточки в стандартную библиотеку

Велик соблазн добавить свою библиотеку в стандартную, например "Делопроизводство". Делать этого нельзя. Как я уже писал ранее, схема карточки хранится в двух местах: базе данных и в компоненте библиотеки. Схему в базу добавить можно, через CardManager, а вот в скомпилированный компонент библиотеки добавить ничего нельзя.
Единственным правильным способом будет создание своей библиотеки.

четверг, 24 сентября 2009 г.

Фиксированный размер карточки

Как сделать так, чтобы у разработанной карточки был фиксированный размер окна.

Реализация зависит о того, на чем написана эта карточка

COM компонент на VB6:
Private Sub ICardUI_GetWindowSize(ByVal ActivateFlags As DVCardHost.ActivateFlagEnum, CX As Long, CY As Long, MinCX As Long, MinCY As Long, CanResize As Boolean)
   ' размер
   CX = 7400 / Screen.TwipsPerPixelX
   CY = 4000 / Screen.TwipsPerPixelY
   MinCX = 4000 / Screen.TwipsPerPixelX
   MinCY = 3000 / Screen.TwipsPerPixelY
   ' запретить изменение
   CanResize = False
End Sub

Карточка на .Net
Достаточно в свойствах компонента карточки сделать равным MinSize и MaxSize

понедельник, 21 сентября 2009 г.

Связать сотрудника в SharePoint c сотрудником в DocsVision

При интеграциях DocsVision - SharePoint  частой задачей является перенос записи о сотруднике в DocsVision. Например пользователь создает запись в SharePoint, по этой записи должна создаться карточка DocsVision, и в поле "Автор", должен быть указан сотрудник, который создал запись.
Сотрудник в SharePoint и Сотрудник в DocsVision - разные сущности, и нельзя получив значение одного типа, присвоить переменной другого. Но есть общее, что их объединяет - учетная запись:

Таким образом, если нужно получить сотрудника SharePoint и связать его с записью в DocsVision, то.
1. Получаете в переменную типа "Сотрудник SP" значение из колонки sharepoint (или из любого другого источника)
2. Получаете из этой переменной строку - учетную запись сотрудника
3. Через ф-цию "Мониторинг DocsVision" ищете по секции "Сотрудники", карточки "Справочник сотрудников" запись, у которой учетная запись совпадает с записью, полученной из переменной "Сотрудник SP"
4. Из найденной строки секции получаете идентификатор строки, которая соответствует сотруднику.

Данный идентификатор можно записывать в карточку DocsVision.

пятница, 18 сентября 2009 г.

Замена стандартных карточек

Карточки в DocsVision состоят из двух сущностей: данных, структура которых описана схемой, и программного компонента, который реализует логику. Программный компонент вызывается при открытии карточки по clsid - идентификатору класса.
Если просуммировать эти факты, то возникает вопрос - можно ли подменить программный компонент стандартной карточки, которая поставляется, например, в Делопроизводстве? Ответ - да. Например, можно заменить справочник Контрагентов, реализовав свою собственную логику и интерфейс, оставив стандартную схему, что не приведет к нарушению работоспособности других карточек Делопроизводства.


 Так может выглядеть вариант справочника Контрагентов

Есть одна сложность. Как я уже описал, компонент вызывается по clsid, который находится в схеме карточки. При создании своего справочника нужно clsid его компонента записать в схему справочника Контрагентов и загрузить на сервер. Но XML схема, кроме сервера находится в компоненте библиотеки (*.dll) - и там произвести замену нельзя.
В этом случае лучше поступить так - заменить clsid своего справочника на clsid оригинального справочника Контрагентов. В этом случае, при открытии будет показываться разработанный вами компонент.

четверг, 17 сентября 2009 г.

Скриншоты DocsVision 5.0

Ниже несколько скриншотов функциональности новой версии DocsVision 5.0, находящейся сейчас в разработке.

Вы увидите это первыми!

Новый справочник ссылок:

Справочник ссылок

Изменение темы (темы будут поддерживаться для всех справочников):

Изменение темы

Форма редактирования ссылки:

Редактирование ссылки 1

Дополнительные параметры ссылки – параметры создания связанной карточки по ссылке и настройка правил сопоставления полей:

Редактирование ссылки 2

Новый справочник категорий:

Справочник категорий

Форма редактирования категории:

Форма категории

Справочник сотрудников:

Справочник сотрудников

Свойства сотрудника:

Форма сотрудника

Редактирование разметки формы сотрудника/подразделения. Встроенный редактор позволяет изменять местоположение, размеры, видимость, метки всех стандартных полей на всех вкладках; а также добавлять произвольное количество собственных полей (свойств), и писать для них обработчики событий (сценарии):

Редактирование разметки

Внимание! Представленные эскизы являются предварительными. В финальной версии функциональность может в той или иной степени измениться,. Компания DocsVision не несет никакой ответственности или обязательств в связи с публикацией данных экскизов.

среда, 16 сентября 2009 г.

Получение текущего пользователя

При разработке сценариев в карточках, новых карточек, внешних приложений и утилит для платформы DocsVision часто возникает задача программно получить идентификатор текущего пользователя из справочника сотрудников – например, чтобы автоматически заполнить поле “Автор” или “Регистратор” в создаваемой карточке.

Решение этой задачи не так просто, как кажется на первый взгляд, так как сессия DocsVision привязана только к доменной учетной записи пользователя; и никак не соотносится с записью этого пользователя в справочнике сотрудников (которой, кстати, может и не быть!).

Поэтому наиболее универсальным алгоритмом получения записи справочника для текущего пользователя является следующий:

1) Получить доменное имя текущего пользователя (владельца сессии). Это имя хранится среди свойств сессии (Properties) и называется “AccountName”:

string account = UserSession.Properties[“AccountName”].Value.ToString();

2) Найти по доменному имени соответствующую запись в справочнике сотрудников (если она есть) с помощью поиска:

const string RefStaffID = "6710B92A-E148-4363-8A6F-1AA0EB18936C";
const string EmployeesID = "DBC8AE9D-C1D2-4D5E-978B-339D22B32482";

SectionQuery query = ses.CreateSectionQuery();
query.ConditionGroup.Conditions.AddNew("AccountName", FieldType.String, ConditionOperation.StrEquals, account);
string querytext = query.GetXml();

CardData refstaff = ses.CardManager.GetDictionaryData(new Guid(RefStaffID));
RowDataCollection users = refstaff.Sections[new Guid(EmployeesID)].FindRows(querytext);

System.Guid userID;
if (users.Count > 0)
{
userID = users[0].Id
}
else
{
// стоит предусмотреть ситуацию, когда пользователя нет в справочнике!
};


Дополнительно стоит иметь ввиду, что начиная с версии 4.1 в справочнике сотрудников допускается наличие нескольких сотрудников с одинаковой учетной записью (например, если один и тот же сотрудник числится на разных должностях в разных подразделениях). При этом, конкретная запись для работы выбирается пользователем в специальном диалоге при запуске Навигатора:



Выбор учетной записи



В этом случае, идентификатор текущего пользователя (выбранного в диалоге)записывается в специальное свойство сессии “CurrentUserID”:



string userID= UserSession.Properties[“CurrentUserID”].Value.ToString();


Однако нужно учитывать, что такой способ будет работать только для сессий, созданных в Навигаторе. Если сессия пользователя создана иным способом (например, из Личного Помощника или другого внешнего приложения) - то такого свойства сессии не будет существовать, и получать идентификатор пользователя нужно будет иным способом (например - описанным выше, с использованием поиска).


Запуск бизнес-процесса используя DocsVision.Platform.ObjectManager.dll

При использовании библиотеки DocsVision.Platform.ObjectManager.dll можно обнаружить, что в ней отсутствует класс WorkflowManager. Как в этом случае запустить бизнес-процесс?
Для этого нужно воспользоваться вызовом серверного расширения Workflow.StorageServerExtension

ExtensionMethod method = session.ExtensionManager.GetExtensionMethod("WorkflowExtension", "StartProcess");
method.Parameters.AddNew("processID", ParameterValueType.Guid).Value = processId.ToString();
method.Execute();

Способ определения какие вызовы можно делать такой же, как и с другими библиотеками. Нужно подключить сборку DocsVision.Workflow.StorageServerExtension.dll к VisualStudio и посмотреть список методов через ObjectBrowser

p.s. Все про серверные расширения можно прочитать в руководстве разработчика на платформе, параграф 4.18 "Серверные расширения"

вторник, 15 сентября 2009 г.

Получение автора экземпляра бизнес-процесса

Как получить пользователя, запустившего бизнес-процесс в самом экземпляре процесса.

Информация об авторе экземпляра хранится в секции "Общее описание", карточки бизнес-процесса. Поле "Автор экземпляра".
Получить карточку текущего экземпляра бизнес-процесса можно через универсальную функцию.
Затем, имея карточку экземпляра, прочитав, поле "Автор экземпляра", получаем учетную запись автора. По данной учетной записи в справочнике сотрудников можно найти строку, соответствующую сотруднику.



Скачать пример

P.s. Ого! Это уже 100й пост в нашем блоге. Небольшой юбилей :)

понедельник, 14 сентября 2009 г.

Обработка сервисом Workflow нескольких серверов

Давненько не было новых статей :) Продолжим с небольшой. Не все обращают внимание, что в каждом бизнес-процессе есть настройка шлюза в DocsVision (Свойства бизнес-процесса / Шлюзы). Если в данных настройках указать путь к другому серверу DocsVision, то в бизнес-процессе можно работать с карточками другого сервера. Т.е. разные процессы могут работать с разными серверами.

среда, 2 сентября 2009 г.

Загрузка схемы библиотеки карточек в базу 4.3

Симптом.
Загружаем  библиотеку карточек, через Card Manager, в базу 4.3. Библиотека не видна в ветке "Карточки" Навигатора. При этом, карточки видны в контекстном меню "Создать", а так же просматриваются в DVExplorer

В чем причина.
В 4.3. Навигатор не отображает библиотеку в ветке "Карточки", в случае если не указан clsid компонента библиотеки.

Что нужно сделать.
Создать компонент библиотеки и указать его clsid в свойствах библиотеки карточек.