Доброго времени суток всем!
Уверен, не раз перед Вами вставала задача копирования подчиненных записей вместе с копированием родительской!
Вот и я недавно реализовал подобный функционал. Конечно, пошел сначала с самого сложного и громоздкого решения: определил новый датасет-источник, отфильтровал его по ID родительской записи. Объявил новый датасет - "прототип" копии. В цикле прошел по источнику, и скопировал все поля (благо их не много их было, всего лишь десяток ) из источника в "прототип". После каждого такого прохода постил датасет "прототипа".
Посмотрел потом на всю это красоту в полторы страницы кода, и подумал: "А не сделать ли мне все это еще красивей?". И сделал...
Покопавшись немного в конфигурации, открыл для себя удивительную вещь! Разработчики уже почти все до меня придумали! ДЛЯ меня! Бери и пользуйся!
Вот базовый сервис Common\Library\scr_DocumentUtils, а в нем готовый метод: function CopySimpleDetail( ... тут мы чего-то принимаем ) - запомним это.
Итак, конкретная задача: копировать контакты задачи, при копировании самой задачи путем перетаскивания ее графического элемента на контроле "Расписание задач". Т.е.: заходим в расписание, зажимаем CTRL и цепляем мышкой какую-нибудь задачку. Тянем ее в удобное или нужное нам место, и там отпускаем. При таком действии, контакты задачи не будут скопированы. Соответственно новую копию у себя в расписании увидит только ее Ответственный. Но если я не ответственный, а автор. И тоже хочу новую задачку видеть и контролировать?
Выход есть. Идем в админку. В модуле задач, находим группу сервисов ShedulerArea - где-то здесь находится то, что нам нужно.
Открываем Tasks\General\SchedulerArea\wnd_SchedulerArea, становимся в нем на элемент ScheduleControl и смотрим в список событий, которые им поддерживаются: находим OnCopyEvent.
Переходим по событию, и попадаем в обработчик: сервис Tasks\General\SchedulerArea\scr_SchedulerArea, функция function CopyEvent(Event).
Здесь, пробежав быстренько по коду глазами, сразу видим что к чему: вот у нас датасет новой задачки обяавился
var Dataset = SchedulerArea.EventsDataset;
А вот мы его запостили и обновили деталь:
Dataset.Post();
RefreshDataset(SchedulerArea.EventsDataset);
Вот между постом и обновлением-то, давайте вставим наше копирование. Вернемся к функции function CopySimpleDetail( ...) - по принимаемым аргументам сразу видно что мы ей должны "подкинуть". Давайте же зададим ей входные переменные:
var SourceDataset = GetSingleItemByCode('ds_ContactInTask');
//Датасет-источник. Получаем его, вызвав базовый метод.
ApplyDatasetFilter(SourceDataset, 'TaskID', SourceRecordID, true);
//Источник отфильтруем по родительскому полю.
var SourceParentItemIDFieldName = 'TaskID';
//Ну, тут без лишних слов ясно, чем мы здесь занимаемся...
var DestinationDataset = Services.GetNewItemByUSI('ds_ContactInTask');
//Датасет получатель - объект. Вызываем метод объекта ядра (Services), который который умеет создавать клоны датасетов.
var DestinationParentItemIDFieldName = 'TaskID';
var DestinationItemID = Dataset.ValAsGUID('ID');
//Тут тоже все прозрачно и понятно.
На этом подготовительные работы закончены. Переходим к самому интересному: добавим немного логики - "а не спросить ли нам пользователя, точно ли он хочет скопировать контакты?" - в старых добрых традициях Windows , очень природно и естественно в работе с приложением.
var Result = ShowConfirmationDialog('Копировать контакты задачи?')
А в каком случае спрашивать-то будем? Можно всегда. Но мне важно было в случае, если Автор и Ответственный разные люди. Совместив вопрос пользователю и условие на выполнение получим:
if ((Dataset.Values('AuthorID') != Dataset.Values('OwnerID')) && (Result == mrYes)) {
//подготовительная прелюдия...
//вызов функции копирования:
CopySimpleDetail(SourceDataset, DestinationDataset,
SourceParentItemIDFieldName, DestinationParentItemIDFieldName,
DestinationItemID)
}
Не хватает еще последней детали: сервису Tasks\General\SchedulerArea\scr_SchedulerArea ничего не известно о таком замечательном методе как CopySimpleDetail() - его надо подключить к scr_SchedulerArea из Common\Library\scr_DocumentUtils.
Ну, теперь можно собрать все воедино! Новое "лицо" обработчика события:
function CopyEvent(Event){
var Dataset = SchedulerArea.EventsDataset;
Dataset.DisableGettingDisplayValues();
try {
var SourceRecordID = SchedulerArea.EventsDataset.ValAsStr('ID');
try {
Dataset.Copy(SourceRecordID);
} catch (E){
ShowWarningDialog(E.message);
Dataset.Close();
return;
}
Dataset.ValAsGUID('ID') = Connector.GenGUID();
Dataset.Values('StartDate') = Event.Start;
Dataset.Values('DueDate') = Event.Finish;
Dataset.Post();
var Result = ShowConfirmationDialog('Копировать контакты задачи?')
if ((Dataset.Values('AuthorID') != Dataset.Values('OwnerID')) && (Result == mrYes)) {
var SourceDataset = GetSingleItemByCode('ds_ContactInTask');
ApplyDatasetFilter(SourceDataset, 'TaskID', SourceRecordID, true);
var SourceParentItemIDFieldName = 'TaskID';
var DestinationDataset = Services.GetNewItemByUSI('ds_ContactInTask');
var DestinationParentItemIDFieldName = 'TaskID';
var DestinationItemID = Dataset.ValAsGUID('ID');
CopySimpleDetail(SourceDataset, DestinationDataset,
SourceParentItemIDFieldName, DestinationParentItemIDFieldName,
DestinationItemID)
}
RefreshDataset(SchedulerArea.EventsDataset);
} finally {
Dataset.EnableGettingDisplayValues();
}
}
Чем не красота?
Приятной Вам работы, творческих успехов!