Добрый день!

 

Подскажите, пожалуйста, совместимо ли решение Copy detail records с платформой под Linux (.Net Core)?

Возможно ли данное решение адаптировать под .Net Core? 

 

Заранее спасибо! 

 

Нравится

3 комментария

Наталья, добрый день!

 

решение разрабатывалось и тестировалось на платформе .Net Framework. Направила запрос ответственной команде по поводу совместимости с .Net Core.

Наталья, добрый день!

 

получила обратную связь от ответственной команды, что решение не совместимо с .Net Core. Планов по добавлению совместимости с .Net Core нет, поскольку в базовом продукте разработан механизм для копирования деталей. Этот механизм предусмотрен для разработчиков. В планах публикация статьи по этому механизму на Академии.

Лазоренко Ирина,

 Подскажите, пожалуйста, в какой версии платформы есть уже разработанный механизм копирования деталей? С помощью каких механизмов можно копировать записи деталей вместе с основной записью?

Показать все комментарии

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

Нравится

9 комментариев

Да, возможно. Сделайте БП, запуск по записи. Читать родительскую запись, далее добавить запись в раздел и открыть страницу на редактирование только что созданной записи. У меня так реализовано добавление доп.соглашения к договору. 

Можно развить дальше и сделать отдельную кнопку для запуска процесса.

Алексей Следь,

мне надо что бы все 100+ полей копировались одной коллекцией, добавлять вручную такое мне не особо по душе

Dima Avdoshin,

Не понял. Один раз настроить в БП элемент добавить данные и все. Все 100+ полей будут копировать автоматически при создании новой записи. Если сложно настроить элемент добавить данные, то можно все сделать добавление данных скриптом в том же процессе. Можно через InsertSelect

Алексей Следь,

InsertSelect не вызвет событийную модель, что не есть хорошо.

Dima Avdoshin,

Как вариант можно заместить логику нажатия по плюсу на детале.

И не открывать страницу в режиме добавления записи, а открывать страницу в режиме копирования записи, где источником данных будет текущая (родительская) запись, на которой и находится деталь.

А все колонки из родительской скопирует базовая логика системы:
В режиме копирования система сама копирует значения всех полей, которые на объекте отмечены признаком "Копировать".

Владислав Литвинчук пишет:
InsertSelect не вызвет событийную модель, что не есть хорошо.

Если проблема только в этом, можно создавать Entity, наполнять её поля и затем вызывать Save. Или, как изначально предложили, средствами стандартных элементов БП для работы с данными.

 

По изначальному вопросу темы:

Вы хотите копировать из одноимённых полей одного объекта в другой?

А то, если просто создать копию записи, то в реестре есть кнопка копирования записи, при нажатии на неё создаётся новая запись с заполненными полями, у которых в объекте включена галка «Копировать данные при копировании записи».

Зверев Александр,

то в реестре есть кнопка копирования записи, при нажатии на неё создаётся новая запись с заполненными полями, у которых в объекте включена галка «Копировать данные при копировании записи».
Да именно это мне нужно, каким образом я могу вызвать ее программно?

Зверев Александр,

можно пример пожалуйста

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

row = dataSource.Rows[0].Clone() as Terrasoft.Core.Entities.Entity;
Guid currentUserContactId = Page.UserConnection.CurrentUser.ContactId;
EntityPrimaryColumnValue = Guid.NewGuid();
row.SetColumnValue(primaryColumnName, EntityPrimaryColumnValue);
row.SetColumnValue("CreatedOn", DateTime.Now);
row.SetColumnValue("CreatedById", currentUserContactId);
row.SetColumnValue("ModifiedOn", DateTime.Now);
row.SetColumnValue("ModifiedById", currentUserContactId);
var columnNames = new List<string>();
foreach (var column in row.Schema.Columns) {
	if (column.HasDefValue && 
		((column.IsLookupType || column.IsMultiLookupType) &&
		column.ReferenceSchema.PrimaryDisplayColumn != null) &&
		!columnNames.Contains(column.Name)) {
		columnNames.Add(column.Name);
	}
}
row.LoadLookupDisplayValues(columnNames);
dataSource.Insert(row);

У объекта Entity есть метод .Clone() (или вызываемый им же конструктор Entity(Entity source)). Запускаем его, получаем новый объект в памяти. При необходимости заполняем текущими датой и пользователем стандартные 4 поля, затем те поля, значения которых в Вашей логике нужно поменять относительно образца. Все остальные поля, у которых в дизайнере есть галочка, скопировались автоматически. Id, естественно, будет уже новый.

Цикл из примера не нужен, ведь поля для отображения справочников нас сейчас не интересуют. И в конце запускаем у своего Entity метод .Save(), чтобы эта запись из памяти попала в базу. Кажется, ничего не упустил.

 

Но это всё на уровне C#-скрипта в процессе. Если надо в JS-логике, подобно кнопке копирования, нужно смотреть, как она устроена.

 

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

Показать все комментарии

Коллеги, доброго времени суток.

Задача состоит в следующем: есть страница Объекта недвижимости, на которой есть деталь "Строения" (со страницей добавления).

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

Необходимо скопировать туда и данные детали, отобразить колонки.

Как это возможно сделать? Я могу вытащить данные строений Объекта при помощи EntitySchemaQuery, но как правильно их подставить? InsrertQuery, насколько я понимаю, здесь не подходит - он сразу создаёт запись в базе, а существует вероятность, что пользователь не сохранит страницу Предложения после копирования.

Версия 7.8 sales.

Спасибо.

Нравится

2 комментария

На странице Предложения , после инициализации this.set ("Имя_поля_страницы")= значение;

Здравствуйте!

Переопределить метод onEntityInitialized() (вызывается при загрузке страницы редактирования), добавив нужную логику.

Показать все комментарии

Доброго времени суток всем!
Уверен, не раз перед Вами вставала задача копирования подчиненных записей вместе с копированием родительской!
Вот и я недавно реализовал подобный функционал. Конечно, пошел сначала с самого сложного и громоздкого решения: определил новый датасет-источник, отфильтровал его по ID родительской записи. Объявил новый датасет - "прототип" копии. В цикле прошел по источнику, и скопировал все поля (благо их не много их было, всего лишь десяток :exclaim: ) из источника в "прототип". После каждого такого прохода постил датасет "прототипа".

Посмотрел потом на всю это красоту в полторы страницы кода, и подумал: "А не сделать ли мне все это еще красивей?". И сделал...

Покопавшись немного в конфигурации, открыл для себя удивительную вещь! Разработчики уже почти все до меня придумали! ДЛЯ меня! :smile: Бери и пользуйся!
Вот базовый сервис Common\Library\scr_DocumentUtils, а в нем готовый метод: function CopySimpleDetail( ... тут мы чего-то принимаем ) - запомним это.

Итак, конкретная задача: копировать контакты задачи, при копировании самой задачи путем перетаскивания ее графического элемента на контроле "Расписание задач". Т.е.: заходим в расписание, зажимаем CTRL и цепляем мышкой какую-нибудь задачку. Тянем ее в удобное или нужное нам место, и там отпускаем. При таком действии, контакты задачи не будут скопированы. Соответственно новую копию у себя в расписании увидит только ее Ответственный. Но если я не ответственный, а автор. И тоже хочу новую задачку видеть и контролировать?
Выход есть. Идем в админку. В модуле задач, находим группу сервисов ShedulerArea - где-то здесь находится то, что нам нужно.
Открываем Tasks\General\SchedulerArea\wnd_SchedulerArea, становимся в нем на элемент ScheduleControl и смотрим в список событий, которые им поддерживаются: находим OnCopyEvent.

schedulecontrol.png

Переходим по событию, и попадаем в обработчик: сервис 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 :smile:, очень природно и естественно в работе с приложением.

   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();
        }
}

Чем не красота? :smile:
Приятной Вам работы, творческих успехов!

Нравится

Поделиться

4 комментария

Паша, всё хорошо. Но что будет если контактов по задаче будет хотя бы 50... или 100... а если 200?... ну ладно 500 ) Интересно за сколько отработает данное копирование?
Если не нужны события датасета, то необходимо писать просто insert на основе select. Копирование происходит мгновенно. Реализация 20 мин.

Ок, Спасибо за замечание, Иван! учту.
ну, для компаний средних размеров, с количеством пользователей до 20, надеюсь, подойдет :)
При необходимости усовершенствуем.

Паша, для большинства наших клиентов вопрос производительности очень важен!
Может insert'ами на основе select? :wink:

В идеале бы переписать функцию копирования детали под динамически создаваемый InsertSelect, аналогично Update-запросу в функции UpdateRecord.

Показать все комментарии