Поиск блогу

суббота, 12 февраля 2011 г.

Баг

Ошибка: Создаем несколько разметок для разных видов карточки. При редактировании каждой разметки (добавлении контролов), причем только в случае использования многозакладочности, имена контролам могут присвоиться одинаковые для разных разметок. КР сначала не видит ошибку. Но при закрытии КР и повторном входе выдает ошибку о нескольких контролах с одинаковым именем.
Способ решения: при добавлении контролов в разные разметки карточки нужно не допускать совпадания имен контролов, иначе карточка станет недоступна для редактирования. При перезагрузке КР и навигатора карточка загружается без последних изменений.

Продолжение рассмотрения пространства имен BusinessCalendar.

Пару постов назад я начал писать про пространство имен DocsVision.BackOffice.Model.BusinessCalendar.Entities. Упоминал, что в нем содержатся 2 перечислимых типа DayType и TimeType.

Для справки: Перечислимый тип - это тип данных, переменные которого могут принимать значения заранее заданные пользователем. Например, можно создать тип "Animals", и возможными значениями у этого типа сделать "Horse, Pig, Cat, Dog, Cow". Тогда переменная типа Animals сможет принять значение Animals.Horse или, к примеру, Animals.Cat.


Ниже приведу значения для типов DayType и TimeType.
    DayType
  • Holiday
  • NonWorking
  • Working
    TimeType
  • Work
  • NotWork

пятница, 11 февраля 2011 г.

Просмотр структуры карточки.

Иногда возникает потребность просмотреть, какие свойства содержит та, или иная карточка.
Для этого можно воспользоваться утилитой DVExplorer, входящей в SDK.

После запуска утилиты и подключения к базе выбираем пункт "Card Types..."


Обращение к карточке Бизнес-календаря. Примерная структура класса.

Ни для кого не секрет, что существует тип карточек "Бизнес-календарь". Они позволяют задать расписание работы, рабочие часы для подразделений и выполняют подобные этим функции.

Для того, чтобы обратиться к конкретной карточке календаря нужно узнать ее Guid. Проще всего это сделать, кликнув на бизнес-календарь правой кнопкой и зайти в свойства. Внизу будет указан URL карточки, он то и будет содержать легко узнаваемый Guid.


Далее в самой карточке нужно сделать следующее:
using DocsVision.BackOffice.Model.BusinessCalendar.DataAccess;
using DocsVision.BackOffice.Model.BusinessCalendar.Entities;
/*
.
.
.
*/
Guid calGuid = new Guid("F827960F-6E61-40AD-A7E4-63AF74FAB54A");  
Calendar cal = new CalendarMapper(Session).Find(calGuid);

В результате выполнения будет создан объект класса Calendar, имеющий весьма сложную структуру. Кроме свойств и методов, унаследованных от класса DomainObject, он включает в себя поле DefaultWorkTime типа IList (как я понял, так же представлены столбцы в табличном контроле). DefaultWorkTime содержит соответственно поля StartTime и EndTime, содержащие границы рабочего дня по-умолчанию. Они используются, если в календаре не приписаны рабочие часы, отличающиеся от них.
Если же рабочие часы заданы индивидуально для каждого дня, то нужно будет обращаться к полю Years (IDictionary), содержащему данные о каждом дне (int DayNumber,enum Type(Working,NonWorking,Holiday),IList WorkTime:(StartTime,EndTime)).

Также для работы с календарем может быть полезен класс WorkTimeCalculator, который содержит два метода: GetDayTimeWorkStatus(DateTime date) и GetDayWorkStatus(DayTime date), возвращающие значения типов TimeType и DayType соответственно.

Создать объект класса WorkTimeCalculator можно следующим способом:
using DocsVision.BackOffice.Model.BusinessCalendar;
using DocsVision.BackOffice.Model.BusinessCalendar.DataAccess;
using DocsVision.BackOffice.Model.BusinessCalendar.Entities;
/*
.
.
.
*/
Calendar cal = new CalendarMapper(Session).Find(new Guid("00000000-0000-0000-0000-000000000000"));
WorkTimeCalculator calc = new WorkTimeCalculator(cal);
Примечание: вместо 00000000-0000-0000-0000-000000000000 укажите нужный Guid.

среда, 9 февраля 2011 г.

Обращение к данным карточки сотрудника. Программирование действий в ответ на клик по кнопке.

Идея такова: мы выбираем сотрудника в соответствующем контроле типа "сотрудник", затем кликаем по контролу "кнопка", в ответ на что в отдельном свойстве появляется, к примеру, Email или Телефон сотрудника.

Эту задачу можно решить двумя способами:

1 способ (в обход объект-модели):

private void Свойство10_Click(System.Object sender, System.EventArgs e)  //Свойство10 - у меня имя кнопки
{
Guid? employeeId=(Guid?)PropertyController.GetPropertyValue("Автор"); //employeeId - ключ на карточку по свойству "Автор". "Автор" - имя контрола типа "сотрудник"
if (employeeId.HasValue) //проверка существования значения ключа employeeId
{
var empl=new DocsVision.BackOffice.Model.StaffModel.DataAccess.EmployeeMapper(Session).Find(employeeId.Value); //новая переменная, в которую записываем значение employeeId.Value
PropertyController.UpdateProperty("Свойство12",empl.Email); //Записываем в свойство типа "строка" значение empl.Email. Соответственно мы можем вытащить в качестве значение не только Email, а практически любое свойство карточки сотрудника
PropertyController.RefreshControls(); //обновляем контролы, чтобы отобразилось новое значение
}
else
{
MessageBox.Show("Ошибка"); //сообщение об ошибке, если employeeId не имеет значения
}
}



2 способ (через объект-модель):


private void Свойство10_Click(System.Object sender, System.EventArgs e)
{
Guid? employeeId=(Guid?)PropertyController.GetPropertyValue("Автор");
if (employeeId.HasValue)
{
RowData employeeData=Session.CardManager.GetDictionaryData(new Guid("6710B92A-E148-4363-8A6F-1AA0EB18936C")).Sections[new Guid("DBC8AE9D-C1D2-4D5E-978B-339D22B32482")].GetRow(employeeId.Value);
//RefStaffCardId = 6710B92A-E148-4363-8A6F-1AA0EB18936C (Правой кнопкой на справочник сотрудников, экспорт, XML карточки)
//Employee = DBC8AE9D-C1D2-4D5E-978B-339D22B32482 (C:\Program Files\DocsVision\Platform\4.5\Server\Tools\Database\TakeOffice\RefStaff.xml - строчка с employee)
PropertyController.UpdateProperty("Свойство12",employeeData["Phone"].ToString()); //Phone - стандартное имя ячейки в базе данных, хранящей значение "Телефон" определенного сотрудника
PropertyController.RefreshControls();
}
else
{
MessageBox.Show("Ошибка");
}
}

Скрипт из мануала.

для того, чтобы при открытии карточки,ей присваивался регистрационный номер автоматически, существует след скрипт:
отыскиваете в событиях карточки событие AfterActivate, жмете три точки и открывается скрипт,первая строка генерится автоматически,а далее копируем скрипт)

private void cardControl_AfterActivate(System.Object sender, System.EventArgs e)
{ 
var numeratorProperty = GetCardProperty("Нумератор"); //здесь в скобках идет настоящее имя вашего регистратора, у меня "нумератор"

if (numeratorProperty.Value != null)
{   
return;
}

var ruleAttribute = numeratorProperty.Description.GetAttribute("Rule"); //обратите внимание,что в этом месте как раз идет НЕ настояшее имя вашего правила для регистратора,а стандартное название Rule

Guid? ruleId = (Guid?)ruleAttribute.Value;

var numeratorMapper = new DocsVision.BackOffice.Model.CardProperties.DataAccess.NumeratorNumberMapper(Session, CardData.Id, DomainObject.NumbersSectionId.Value);

var number = numeratorMapper.Create(ruleId.Value);

numeratorProperty.Value = number;
PropertyController.RefreshControls();

}

private CardProperty GetCardProperty(string propertyName)
{
foreach (CardProperty property in PropertyController.CardProperties)
{
if (property.Name == propertyName)
return property;
}
return null;
}

Пара багов

При написании скрипта наткнулся на следующую ошибку:
Ошибка
Если на карточке лежит контрол "Время", то, если в него не было принудительно записано какое-то значение через скрипт (значение по-умолчанию не в счет), то при попытке считать значение контрола возвращается объект неправильного типа.
Способ решения
Задавать значения по-умолчанию для этого контрола в событии карточки CardInitialized.



Ошибка
Если на карточке есть скрытый контрол, то данные о изменении его значения будут также выводиться в истории.
Способ решения
Пока не придуман.

Получение типа значения контрола

Часто при считывании значения свойства карточки может возникнуть вопрос о том, какого типа нужно создать переменную для хранения этого значения.
Для того, чтобы узнать тип значения свойства, можно воспользоваться следующим методом:
MessageBox.Show(PropertyController.GetPropertyValue("ИмяСвойства").GetType().ToString());

В результате при выполнении скрипта будет показано окно сообщения с названием типа выбранного свойства.

Вступление

Всем привет!

Вот и возник наш блог) Дизайн и структура возможно будут дорабатываться по мере необходимости.

В данный момент оставлять сообщения и комментарии могут только участники блога, получившие приглашения, и у блога отключена индексация в поисковых системах.