Здравствуйте, коллеги!

Столкнулся с проблемой описанной здесь:

На страницу редактирования товара добавляю кнопку. Сохраняю схему, делаю очистку кеша и аппаратную перезагрузку, перехожу на страницу редактирования какого-нибудь товара - кнопки нет. Снова делаю очистку кеша и аппаратную перезагрузку - кнопка появляется и при нажатии работает как надо. Но стоит перейти, например, в другой раздел, потом снова вернуться на страницу редактирования товара, то кнопки снова нет. 

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

Также добавлял кнопку на страницу секции (ProductSectionV2) со свойством visible: false (так как на странице раздела она не должна быть видна), но при переходе на страницу товара (ProductPageV2) кнопка остается невидимой, хотя свойство visible: true.

Может кто-нибудь объяснит, в чем проблема. Заранее благодарен.

Нравится

7 комментариев
Лучший ответ

Ну собственно, вам необходимо воспользоваться вот этими 2-мя статьями:

https://academy.terrasoft.ru/documents/technic-sdk/7-14/kak-dobavit-knopku-na-stranicu-redaktirovaniya-v-sovmeshchennom-rezhime

https://academy.terrasoft.ru/documents/technic-sdk/7-14/kak-dobavit-knopku-v-rezhime-dobavleniya-novoy-zapisi

Тогда она и не будет исчезать при обновлении страницы.

Ну собственно, вам необходимо воспользоваться вот этими 2-мя статьями:

https://academy.terrasoft.ru/documents/technic-sdk/7-14/kak-dobavit-knopku-na-stranicu-redaktirovaniya-v-sovmeshchennom-rezhime

https://academy.terrasoft.ru/documents/technic-sdk/7-14/kak-dobavit-knopku-v-rezhime-dobavleniya-novoy-zapisi

Тогда она и не будет исчезать при обновлении страницы.

ProductSectionV2 не означает что это раздел, он так же используется и при просмотре карточки, так что там тоже нужно кнопку делать

Здравствуйте, спасибо за ответ. А метод onClick этой кнопки тоже в обоих местах прописывать? Если да - в ProductSectionV2 не доступны необходимые мне поля/действия карточки (даже через getActiveRow. А если описать только в ProductPage то переходе в карточку из раздела кнопка не активна.

Страница карточки и страница раздела — две разные схемы и кнопки на них — тоже разные. Если кнопка находится на странице раздела, то её обработчик пишется на этой странице, аналогично и с кнопкой на странице карточки. 

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

Спасибо за ответ. Ситуация такая: Если добавляю кнопку в схему карточки и, там же, её обработчик - после перехода в карточку со страницы раздела кнопки нет, но если обновить страницу карточки - кнопка есть и функционирует как надо.

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

Сама кнопка (Сохранить и отправить) должна сохранять и менять стадию продукта на другую. В схеме раздела я не знаю как получить доступ к атрибуту карточки Stage.

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

Решил проблему при помощи https://academy.terrasoft.ru/documents/technic-sdk/7-14/obmen-soobshcheniyami-mezhdu-modulyami-komponent-sandbox. Если кнопка рендерится со страницы раздела то при нажатии на нее отправляется сообщение на страницу карточки где запускается нужный обработчик кнопки. Параметры видимости кнопки также передаются по сообщению.

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

Добрый день.

Возникла потребность реализовать кнопку, аналогичную кнопке со стадиями в разделе Обращения:

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

Коллеги, был ли у кого-то опыт реализации данной задачи?

 

Пробовала делать следующим образом: в секции diff прописала

{
	"operation": "insert",
	"parentName": "ActionButtonsContainer",
	"propertyName": "items",
	"name": "TestButton1",
	"values": {
		"itemType": this.Terrasoft.ViewItemType.BUTTON,
		"style": this.Terrasoft.controls.ButtonEnums.style.GREEN,
		"caption": "Test!!!!!!",
		"click": {"bindTo": "onResolvedButtonTest"},
		"classes": {
			"textClass": ["actions-button-margin-right"],
			"wrapperClass": ["actions-button-margin-right"]
		},
		"menu": {
			"items": {"bindTo": "ButtonMenu"}
		}
	}
}

В секции attributes прописала:

"ButtonMenu": {
	dataValueType: this.Terrasoft.DataValueType.COLLECTION
}

Но я не совсем понимаю как мне наполнить коллекцию ButtonMenu значениями, которые должны отображаться в выпадающем списке на кнопке?

 

Нравится

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

Вообще добавление подменю выглядит так:

var MenueItems = this.Ext.create("Terrasoft.BaseViewModelCollection");
this.getButtonMenuItem({
	"Click": { "bindTo": "ClickEvent" },
	"Tag": tag,
	"Caption": caption,
	"Enabled": true,
	"Visible": true
})
this.set("ButtonMenu", MenueItems);

 

В моём случае я заполнял выпадающий список значениями справочника по этому добавил функцию initMenueItems в init страницы

initMenueItems:function(){
	var self = this;
	var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
		rootSchemaName: "SchemaName"
	});
	esq.addColumn("Name", "Name");
	esq.addColumn("Id", "Id");
	esq.filters.add("Type", this.Terrasoft.createColumnFilterWithParameter(this.Terrasoft.ComparisonType.EQUAL, "Type", "{TypeId}"));
	esq.getEntityCollection(function (response) {
		if (!response.success) return;
		var data = response.collection;
		var MenueItems = self.Ext.create("Terrasoft.BaseViewModelCollection");
		data.collection.items.forEach(function (item) {
			MenueItems.addItem(self.getButtonMenuItem({
				"Click": { "bindTo": "ClickEvent" },
				"Tag": item.values.Id,
				"Caption": item.values.Name,
				"Enabled": true,
				"Visible": true
			}));
		});
		self.set("ButtonMenu", MenueItems);
	});
}

 

Если вопрос еще актуален, статично можно добавить так:

{
                "operation": "insert",
                "parentName": "OpportunityPageOfferTabContentGroup",
                "propertyName": "items",
                "name": "getOfferEngButton",
                "values": {
                    "itemType": Terrasoft.ViewItemType.BUTTON,
                    //"classes": {textClass: "actions-button-margin-right"},
                    "style": Terrasoft.controls.ButtonEnums.style.GREEN,
                    "caption": {bindTo: "Resources.Strings.UsrGetOfferButtonCaption"},
                    "menu": {
                        "items": [{
                            "caption": {"bindTo": "Resources.Strings.UsrGetOfferEngButtonCaption"},
                            "click": {"bindTo": "getOfferEng"}
                        }, {
                            "caption": {"bindTo": "Resources.Strings.UsrGetOfferRusButtonCaption"},
                            "click": {"bindTo": "getOfferRus"}
                        }]
                    }
                }
            },

Спасибо. Попробовала сделать обоими способами, все получилось!

Всё можно сделать еще прозаичнее, к обычной кнопке в diff добавляем свойство 

"menu": {
	"items": {"bindTo": "ButtonMenuItems"}
},

где ButtonMenuItems это атрибут 

attributes: {
	"ButtonMenuItems": {
		dataValueType: this.Terrasoft.DataValueType.COLLECTION
	}
},

куда в свою очередь, необходимо добавлять через метод addItem, элементы вот как-то так

var collection = this.get("ButtonMenuItems");
var menuItem = this.Ext.create("Terrasoft.BaseViewModel", {
	values: {
		"Caption": "Заголовок пункта меню",
		"Click": {bindTo: "actionMethod"}
	}
});
collection.addItem(menuItem);

 

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

Здравствуйте! Необходимо добавить красную кнопку “Удалить” на страницу Лида, что-то в таком роде:
!
Делаем по документации (https://academy.terrasoft.ru/documents/technic-sdk/7-9/kak-dobavit-knopk...),
добавили код в замещающую схему LeadPageV2, кэш чистили, но кнопка все равно не отображается.

 diff: [
            {
                "operation": "insert",
                "parentName": "CombinedModeActionButtonsCardLeftContainer",
                "propertyName": "items",
                "name": "DeleteLeadButton",
                "values": {
                    "itemType": Terrasoft.ViewItemType.BUTTON,
                    "caption": {bindTo: "Resources.Strings.DeleteLeadButtonCaption"},
                    "click": {bindTo: "onDeleteLeadClick"},
                    "style": Terrasoft.controls.ButtonEnums.style.RED,
                }
            }
        ]

Подскажите, пожалуйста, в чем может быть ошибка, версия 7.9.1

Нравится

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

Если режим совмещённый, то добавлять нужно в схему LeadSectionV2. Вы же добавили кнопку в схему страницы редактирования в, скорее всего, несуществующий там контейнер "CombinedModeActionButtonsCardLeftContainer"

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

Если рекомендация от Данилы не помогла, то просьба предоставить полный листинг кода.

Большое спасибо за помощь, после добавления кода в LeadSectionV2 кнопка появилась. :smile:
Подскажите пожалуйста, как должна выглядеть функция для удаления записи. Сперва вытягиваем id лида:

var leadId = this.get("Id");

а как в дальнейшем его можно удалить?

Мария, здравствуйте!

Наглядный пример реализации Вы можете посмотреть в обработчике кнопки "Удалить" в реестре раздела.

Спасибо, получилось реализовать удаление с помощью функции deleteRecords из GridUtilitiesV2.
Добавили таким образом кнопку в 3 раздела, всё работает, только в разделе “Контакты” кнопка не отображается :sad:. В контактах 3 вида страниц, ссылка на страницу редактирования контакта имеет вид:

ViewModule.aspx#CardModuleV2/BtcContactType1Page/edit/deafe024-a148-4ba6-a4b1-cb8fce5b8443

, может ли это как-то влиять на способ добавления кнопки?

Попробуйте этот же код добавить и в Section и на Page (если их несколько, то во все).

Мария, а что делает кнопка "Удалить"? Если правильно поняли, то она удаляет текущую запись. Тогда хотелось бы посоветовать продумать удаление более глобально, так как нужно учесть все возможные моменты. Например:

- что должно произойти после нажатия;
- что делать с деталями;
- что будет если после нажатия "Удалить", нажать на "Сохранить" и т.д;
- процессная ли карточка или нет.

Спасибо, кнопка в контактах появилась. :smile:

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

Но возникла проблема с удалением на отдельной странице, если допустим перейти с лида в контакт, или из контакта в лид, или даже просто перезагрузить страницу из раздела, то кнопка удаления не срабатывает. Подскажите, пожалуйста, как в Page можно осуществить удаление? Не можем найти пример в стандартных схемах.

Или можно как-то самому принудительно запускать совмещенный режим при переходе на другую страницу, в плане: сделать, что при нажатии на кнопку “удалить” перекидывало в карточку, но в совмещенном режиме и автоматически нажималась кнопка удалить сразу?

Для исправления - продублируйте код метода, связанного с кнопкой "удалить" в схеме карточки. Также смотрите в сторону использования Terrasoft.DeleteQuery для удаления записи по Id. Для перехода обратно в раздел - воспользуйтесь сообщением PushHistoryState.

Спасибо за помощь,
Функция удаления из раздела:

deleteRecords: function() {
        var activeRow = this.getActiveRow();
        if (activeRow && activeRow.isNew) {
            this.removeGridRecords([activeRow.get("Id")]);
        } else {
            var items = this.getSelectedItems();
            if (!items || !items.length) {
                return;
            }
            this.checkCanDelete(items, this.checkCanDeleteCallback, this);
        }
    },
 
    handleAfterDelete: function() {
        this.sandbox.unRegisterMessages(["MultiDeleteFinished"]);
        this.registerMultiDeleteMessages();
        this.reloadGridData();
        this.onDeleted({
            Success: true
        });
        this.onDataChanged();
        var requestUrl = "SectionModuleV2/UsrInterestSection";
        this.sandbox.publish("PushHistoryState", {
            hash: requestUrl
        });
    }

Код функции удаления со страницы редактирования:

delete: function() {
    var recId = this.get("Id");
    var deleteQuery = Ext.create("Terrasoft.DeleteQuery", {
        rootSchemaName: "UsrInterest"
    });
    deleteQuery.filters.add("userFilter",
        deleteQuery.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Id", recId));
    deleteQuery.execute(function() {});
 
    var requestUrl = "SectionModuleV2/UsrInterestSection";
    this.sandbox.publish("PushHistoryState", {
        hash: requestUrl
    });
}

На странице записи удаление происходит, но не выходит выполнить каскадное удаление, подскажите пожалуйста, как проще реализовать удаление связанных записей?

Добрый день.

Удалить записи каскадно через DeleteQuery у Вас не выйдет. Возможны только следующие два варианта:

1) Перед удалением основной записи выполнять SELECT для получения Id связанных записей. Удалять их, а только затем выполнять DELETE основной.

2) На уровне объекта установить чекбокс "каскадная связь".

Обратите внимание, что после использования второго варианта - записи каскадно будут удаляться и при стандартном удалении из раздела.

Спасибо, для пользовательского раздела с галочкой "каскадная связь" всё получилось.
Не подскажите, пожалуйста, где для лидов ставить это свойство для каскадного удаления в процессах и для контактов в лидах?

!

Данная деталь создается на основании view VwEntityInProcess. Код самой вьюхи:

ALTER VIEW [dbo].[VwEntityInProcess] (
	[Id],
	[CreatedOn],
	[CreatedById],
	[ModifiedOn],
	[ModifiedById],
	[ProcessListeners],
	[EntitySchemaName],
	[RecordId],
	[ProcessCaption],
	[ProcessDescription]
)
AS
SELECT DISTINCT
	ss.[Id],
	ss.[CreatedOn],
	ss.[CreatedById],
	ss.[ModifiedOn],
	ss.[ModifiedById],
	ss.[ProcessListeners],
	ss.[Name],
	secpe.[RecordId],
	ssProcess.[Caption],
	ssProcess.[Description]
FROM [SysEntityCommonPrcEl] secpe
	JOIN [SysSchema] ss ON ss.UId = secpe.[EntitySchemaUId]
	JOIN [SysProcessElementData] sped ON secpe.[ProcessElementId] = sped.[Id]
	JOIN [SysProcessData] spd ON spd.[Id] = sped.[SysProcessId]
	JOIN [SysProcessData] spdParent ON COALESCE(spd.ParentId, spd.Id) = spdParent.[Id]
	JOIN [SysSchema] ssProcess ON ssProcess.[Id] = spdParent.[SysSchemaId]
	JOIN [SysProcessLog] spl ON spl.[SysSchemaId] = spdParent.[SysSchemaId]
WHERE spl.[StatusId] = 'ed2ae277-b6e2-df11-971b-001d60e938c6'
GO

Спасибо за помощь. С изначальным удалением из VwEntityInProcess не получилось, появляется ошибка: "Uncaught View or function 'dbo.VwEntityInProcess' is not updatable because the modification affects multiple base tables."
А удалять "без связанных записей" с помощью DeleteQuery, или как можно выполнить sql запрос на удаление по нажатию кнопки ?

"Maria H" написал:как можно выполнить sql запрос на удаление по нажатию кнопки ?

Это можно сделать на бекенде, тоесть вам нужно сделать свой конфигурационный веб сервис:
https://academy.terrasoft.ru/documents/technic-sdk/7-8/kak-sozdat-svoy-…
В теле которого уже формировать произвольный sql запрос, пример:

var test = new CustomQuery(UserConnection, DBEngine.GetIndexQuerySqlText())
.WithParameter("DBSchemaName", DBEngine.CurrentSchemaName)
.WithParameter("EntitySchemaQualifierName", null, "DBObjectName")
.WithParameter("EntitySchemaName", entitySchemaName)
.WithParameter("IndexName", indexName);

Где второй параметр new CustomQuery, собственно текст самого запроса, с параметрами внутри через собаку, к пр. @param_name, если параметры конечно нужны.
Выполнить можно так:
test.Execute();
Если это запрос на чтение, то можно преобразавать его в стандартный IDataReader:
using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection()) {
IDataReader datareader = test.ExecuteReader(dbExecutor);
}
После чего данный сервис по удалению можно будет вызвать из ваших схема страниц\секций следующим образом:
https://academy.terrasoft.ru/documents/technic-sdk/7-8/kak-programmno-v…

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

Здравствуйте!
Так как я не являюсь программистом и уровень моих знаний в языках программирования (JScript и другие) равен «0» :(, обращаюсь с вопросом/просьбой к Вам, уважаемые специалисты в данной области.

Версия программы: Terrasoft Service Desk 3.3.2.182
В стандартном окне «Напоминания» (wnd_Remindings), есть потребность добавить новую кнопку «Комментарий» (wnd_IncidentCommentEdit, wnd_TaskCommentEdit), с помощью которой сотрудник сможет, не отвлекаясь при переключении между окнами, добавлять соответствующие комментарии к напоминанию по инциденту или задаче.

Новую кнопку в окне добавил без трудностей, но проблема в том, что я не могу ее заставить правильно работать, так как мне этого нужно.
Пробивал найти подобный код в разных сервисах, но его я не нашел. Пробивал разные вариации построения этого кода под мою потребность, с разных сервисов (скриптов) так же без результатов.
В скрипте «scr_Remindings» указано, что окно открывается от типа объекта (Задача или Инцидент), если использовать кнопку «Открыть». Так же мне нужно, что бы от типа объекта открывался тот или иной комментарий.

Подскажите, пожалуйста, как можно реализовать такой функционал.
Буду Вам очень признателен за помощь.

P.S. Подскажите, пожалуйста, литературу для начинающих по JScript’y :).
Спасибо.

Нравится

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

Насколько я представляю, реализовать Вам вопрос необходимо следующим образом:

1. При нажатии на кнопку записать в переменную ID (инцидента или задачи).
2. Прописать открытие окна добавления комментариев.
3. После добавления текста в поле и нажатия на ОК провести фильтрацию датасета по ID.
4. Сделать пост на деталь комментариев записи, которая у нас есть после фильтрации.

"Гакало Игорь Александрович" написал:

Насколько я представляю, реализовать Вам вопрос необходимо следующим образом:

1. При нажатии на кнопку записать в переменную ID (инцидента или задачи).
2. Прописать открытие окна добавления комментариев.
3. После добавления текста в поле и нажатия на ОК провести фильтрацию датасета по ID.
4. Сделать пост на деталь комментариев записи, которая у нас есть после фильтрации.

Здравствуйте, Игорь!
Спасибо Вам за ответ, но могли бы Вы поподробнее описать или показать где в сервисах есть подобные коды?
К сожалению, моих знаний в программировании не достаточно для того чтобы выполнить Ваши рекомендации. :sad:
Спасибо.

Внесу небольшие уточнения и пояснения по описанному мной варианту.
Запись, которая находится в таблице напоминаний, имеет кроме ID, описания, времени создания, объекта напоминания и подобных полей еще такие полезные данные, как SubjectTypeID и SubjectID.

К примеру, Вы создали запись в разделе "Инциденты" и добавили к ней напоминание кому-либо.
В SubjectTypeID будут данные о том, что запись относиться к разделу инцидентов, а в SubjectID будет находиться ID записи инцидента, к которой было создано напоминание.

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

Открыть окно добавления комментариев можно, к примеру, с помощью функции ShowEditWindowEx. Примеры ее использования в конфигурации есть.

Появляется окошко, вводится текст, нажимается ОК, происходит фильтрация датасета.
К примеру, ApplyDatasetFilter(IncidentDataset, 'ID', SubjectID, true);
Есть случаев использования такого фильтра в конфигурации :smile:

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

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

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

Здравствуйте, Игорь!
Спасибо Вам за пояснения, но разобраться до конца с этой задачей я не сумел.

Раньше у меня кнопка была вообще не активна при нажатии, но сейчас, с помощью Ваших рекомендаций, у меня уже открывается окно «Комментарий», но:
1.Таких окон, как комментарий у меня сразу же 2.
2.При нажатии на кнопку комментарий, отображается окно добавления комментария (новая запись).
Окно остается (2 окна) и в нем можно даже прописать текст, а сохранить не удается так, как отсутствует «Автор».
3.Ошибок никаких нет.
Собственно на этом этапе я и застрял :sad:
Не пойму, как исправить ошибку с 2 окнами, которые открываются одновременно и как привязать к записи (к новому комментарию) автора.
Покажу Вам «кашу» (код, если его можно так назвать:smile:), может быть с него Вам будет более понятней где ошибка:

function OpenIncidentCommentEdit(Window) {
var Attributes = GetNewDictionary();
Attributes.Add('IsNew', true);
var DefaultValues = GetNewDictionary();	
ShowEditWindowEx('wnd_IncidentCommentEdit', Attributes, DefaultValues);
var RemindingsDataset = GetSingleItemByCode('ds_IncidentComment');
ShowEditWindowEx('wnd_TaskCommentEdit', Attributes, DefaultValues);
var RemindingsDataset = GetSingleItemByCode('ds_TaskComment');
RemindingsDataset.Open();
	    if (!RemindingsDataset.IsEmptyPage) {
	        return;
	    }
ApplyDatasetFilter(IncidentCommentDataset, 'IncidentID', SubjectID, true);
ApplyDatasetFilter(TaskCommentDataset, 'TaskID', SubjectID, true);
}
 
function btnCommentOnClick(Control) {
	var OwnerID = Connector.CurrentUser.ContactID;
	OpenIncidentCommentEdit();
}

Игорь, спасибо Вам за помощь.

Добрый день!

Роман, Вы прописали дважды открытие окна комментариев. Одно для инцидентов (ShowEditWindowEx('wnd_IncidentCommentEdit', Attributes, DefaultValues);), другое для задач (ShowEditWindowEx('wnd_TaskCommentEdit', Attributes, DefaultValues);).
Предлагаю перед открытием окон сделать проверку на то, к какому датасету относится запись и в зависимости от датасета открыть либо окно комментариев для инцидентов, либо окно для задач.

Подстановку пользователя в необходимое окно, в случае, если автор не заполняется, можно сделать при помощи DefaultValues.Add. Узнать текущего пользователя можно при помощи Connector.CurrentUser.ContactID;

А фильтрацию данных датасета (ApplyDatasetFilter) и добавление записи "повесьте" на ОК соответствующей карточки комментариев.

"Гакало Игорь Александрович" написал:

Добрый день!

Роман, Вы прописали дважды открытие окна комментариев. Одно для инцидентов (ShowEditWindowEx('wnd_IncidentCommentEdit', Attributes, DefaultValues);), другое для задач (ShowEditWindowEx('wnd_TaskCommentEdit', Attributes, DefaultValues);).
Предлагаю перед открытием окон сделать проверку на то, к какому датасету относится запись и в зависимости от датасета открыть либо окно комментариев для инцидентов, либо окно для задач.

Подстановку пользователя в необходимое окно, в случае, если автор не заполняется, можно сделать при помощи DefaultValues.Add. Узнать текущего пользователя можно при помощи Connector.CurrentUser.ContactID;

А фильтрацию данных датасета (ApplyDatasetFilter) и добавление записи "повесьте" на ОК соответствующей карточки комментариев.

Спасибо Игорь, за предоставленный ответ.
Я бы с радостью выполнил Ваши рекомендации, но не могу по той простой причине, что я не опытен в JScript’e, да и в других областях программирования. (учусь по мере возможностей)

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

К примеру, я понимаю, о чем Вы здесь написали:
«…Предлагаю перед открытием окон сделать проверку на то, к какому датасету относится запись и в зависимости от датасета открыть либо окно комментариев для инцидентов, либо окно для задач…»
Но как оно должно выглядеть в коде понятия не имею. Знаю как называются нужные для меня окна в сервисах, но....:sad:

Игорь, я прошу у Вас извинения за то, что Вас отвлекаю, но могли бы Вы мне «разжевать» то о чем Вы писали ранее.
Спасибо.

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

"Гакало Игорь Александрович" написал:

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

Спасибо большое, жду.

В окне напоминаний у нас есть колонка "Тип объекта" (по умолчанию крайняя права), в которой мы видим, к какому разделу относится данное напоминание.

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

if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Задача') 
{
sw = 0;
}
 
if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Инцидент') 
{
sw = 1;
}

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

"Гакало Игорь Александрович" написал:

В окне напоминаний у нас есть колонка "Тип объекта" (по умолчанию крайняя права), в которой мы видим, к какому разделу относится данное напоминание.

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

if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Задача')
{
sw = 0;
}

if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Инцидент')
{
sw = 1;
}

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

Игорь, спасибо Вам, но где находится "условие проверки", как оно изображено в коде?
И как правильно сделать подстановку пользователя в этом коде?

Сейчас у меня открываются 2 окна одновременно, без автора.

Проверьте, пожалуйста, что не правильно в этом коде (по идее - все не правильно:smile:):

function OpenIncidentCommentEdit(Dataset) {
 var IncidentID = Dataset.Values('IncidentID'); {
	var IncidentData = GetDatasetFieldValuesByID('ds_Incident', IncidentID,
		'OwnerID', 'ContactID');
	if (IncidentData == null) {
		return;
	}
  } 
}
 
function OpenTaskCommentEdit(Dataset) {
 var TaskID = Dataset.Values('TaskID'); {
	var TaskData = GetDatasetFieldValuesByID('ds_Task', TaskID,
		'OwnerID', 'ContactID');
	if (TaskData == null) {
		return;
	}
  }
} 
 
function OpenIncidentCommentEdit(Window) {
 if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Инцидент') 
{
sw = 1;
}
var Attributes = GetNewDictionary();
Attributes.Add('IsNew', true);
var DefaultValues = GetNewDictionary();	
/*if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Инцидент') 
{
sw = 1;
}*/
ShowEditWindowEx('wnd_IncidentCommentEdit', Attributes, DefaultValues);
var RemindingsDataset = GetSingleItemByCode('ds_IncidentComment');
RemindingsDataset.Open();
            if (!RemindingsDataset.IsEmptyPage) {
                return;
            }
ApplyDatasetFilter(IncidentCommentDataset, 'IncidentID', SubjectID, true);
ApplyDatasetFilter(Dataset, 'AuthorID', AuthorID, true);
 }
 
function OpenTaskCommentEdit(Window) {
var Attributes = GetNewDictionary();
Attributes.Add('IsNew', true);
var DefaultValues = GetNewDictionary();	
/*if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Задача') 
{
sw = 0;
}  */
ShowEditWindowEx('wnd_TaskCommentEdit', Attributes, DefaultValues);
var RemindingsDataset = GetSingleItemByCode('ds_TaskComment');
RemindingsDataset.Open();
            if (!RemindingsDataset.IsEmptyPage) {
                return;
            }
ApplyDatasetFilter(TaskCommentDataset, 'TaskID', SubjectID, true);
ApplyDatasetFilter(Dataset, 'AuthorID', AuthorID, true);
}
 
function btnCommentOnClick(Control) {
	if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Инцидент') 
{
sw = 1;
}	
    OpenIncidentCommentEdit();
    if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Задача') 
{
sw = 0;
}
    OpenTaskCommentEdit();
}

Спасибо.

Роман, использование переменной sw было только для примера :smile: Использовать ее не стоит)

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

if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Задача') 
{
ShowEditWindowEx('wnd_TaskCommentEdit', Attributes, DefaultValues);
}
 
if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Инцидент') 
{
ShowEditWindowEx('wnd_IncidentCommentEdit', Attributes, DefaultValues);
}

:smile:
Да, действительно сейчас у меня добавляются комментарии в соответствии от выбранного поля, но автор не подтягивается. Пробивал так:

DefaultValues.Add('OwnerID', Connector.CurrentUser.ContactID);
// и так
var AuthorCommentID = Connector.CurrentUser.ContactID;
DefaultValues.Add('SubjectID', OwnerID);

Как видите - без результатов.

Игорь, для того что бы у меня в окно комментариев добавлялся автор, мне нужно в коде указать ID контакта (пользователя) и SubjectID или что то другое?
Спасибо.

Автора в окно добавил, как показано в коде ниже:

	var Attributes = GetNewDictionary();
	Attributes.Add('IsNew', true);
	var DefaultValues = GetNewDictionary(); 
	var OwnerID = Connector.CurrentUser.ContactID;
	var DefaultValues = GetNewDictionary();
	DefaultValues.Add('OwnerID', Connector.CurrentUser.ContactID);
	var IncidentID = dlData.Dataset.Values('SubjectID');
	var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID');
 
	if (SubjectType == 'Задача') 
	{
		ShowEditWindowEx('wnd_TaskCommentEdit', Attributes, DefaultValues);
	}
 
	if (SubjectType == 'Инцидент') 
	{
		ShowEditWindowEx('wnd_IncidentCommentEdit', Attributes, DefaultValues);
	}

Обратите внимание на то, что сравнение типа объекта было изменено через переменную (по совету добрых наблюдателей темы :wink:).
И есть еще один момент, который также можно улучшить - проверку не по DisplayValues, а по Values. Тип напоминания может быть переименован, ID останется прежним.
Посмотреть ID Вы можете в перечислении, как показано на скриншоте:

1

Вы можете опционально изменить запись в переменную так:

var SubjectType = dlData.Dataset.Values('{8E742F80-1C1A-4657-8D46-F189F0640544}');

Здравствуйте, Игорь!

Извините за то, что долго не отвечал, не было времени проверить.
Сейчас проверил, следуя Вашим рекомендациям и рекомендациям наблюдателей темы (спасибо:smile:), автор подтягивается, все отлично, но (как всегда:smile:) запись (комментарий) не сохраняется в реестре Инцидентов и Задач.
Как я понимаю, я не прописал фильтрацию данных датасета.
Вы ранее писали что: «фильтрацию данных датасета (ApplyDatasetFilter) и добавление записи "повесьте" на ОК соответствующей карточки комментариев.» Не пойму как мне это сделать.
Пробивал разные подобные коды в сервисах. Привожу пример (закомментированные поля, это те которые я пробивал):

function OpenIncidentCommentEdit(Window) {
var Attributes = GetNewDictionary();
Attributes.Add('IsNew', true);
        var DefaultValues = GetNewDictionary(); 
        var OwnerID = Connector.CurrentUser.ContactID;
        var DefaultValues = GetNewDictionary();
        DefaultValues.Add('OwnerID', Connector.CurrentUser.ContactID);
        var IncidentID = dlData.Dataset.Values('SubjectID');
        var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID');
if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Инцидент') 
{
ShowEditWindowEx('wnd_IncidentCommentEdit', Attributes, DefaultValues);
}
var RemindingsDataset = GetSingleItemByCode('ds_IncidentComment');
RemindingsDataset.Open();
            if (!RemindingsDataset.IsEmptyPage) {
                return;
            }
ApplyDatasetFilter(IncidentDataset, 'ID', SubjectID, true);          
//ApplyDatasetFilter(IncidentCommentDataset, 'IncidentID', SubjectID, true);
//ApplyDatasetFilter(Dataset, 'AuthorID', OwnerID, true);
 }
 
function OpenTaskCommentEdit(Window) {
var Attributes = GetNewDictionary();
Attributes.Add('IsNew', true);
var DefaultValues = GetNewDictionary();	
var OwnerID = Connector.CurrentUser.ContactID;
var DefaultValues = GetNewDictionary();
DefaultValues.Add('OwnerID', Connector.CurrentUser.ContactID);
var TaskID = dlData.Dataset.Values('SubjectID');
var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID');
if (dlData.Dataset.DisplayValues('SubjectTypeID') == 'Задача') 
{
ShowEditWindowEx('wnd_TaskCommentEdit', Attributes, DefaultValues);
}
var RemindingsDataset = GetSingleItemByCode('ds_TaskComment');
RemindingsDataset.Open();
            if (!RemindingsDataset.IsEmptyPage) {
                return;
ApplyDatasetFilter(TaskDataset, 'ID', NewCommentID, true);            }
//ApplyDatasetFilter(TaskCommentDataset, 'TaskID', SubjectID, true);
//ApplyDatasetFilter(Dataset, 'OwnerID', OwnerID, true);   
//ApplyDatasetFilter(Dataset, 'ID', RecordID, true);
}
 
function btnCommentOnClick(Control) {
    OpenIncidentCommentEdit();
    OpenTaskCommentEdit();
}

И еще одно, не понимаю, что Вы имели, введу: "И есть еще один момент, который также можно улучшить - проверку не по DisplayValues, а по Values. Тип напоминания может быть переименован, ID останется прежним.
Посмотреть ID Вы можете в перечислении, как показано на скриншоте:"

Можно поподробнее описать.
Спасибо.

Доброе утро, Роман!

На самом деле, комментарий сохраняется. В этом Вы можете убедиться, сделав выборку на базе данных:

select * from tbl_IncidentComment

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

То есть, в скрипте комментариев добавим условие, что если комментарий добавляется из окна напоминаний, то сделать запись IncidentID. Реализуемо с помощью атрибутов. Когда проверю этот вариант, напишу Вам.

P.S: Идея насчет ID довольно детально описана в предыдущем моем посте, если что-то детально не понятно, напишите.

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

	var CommentSource = Connector.Attributes('CommentSource');
	var Incident = Connector.Attributes('Incident');
	var Task = Connector.Attributes('Task');
 
	var Attributes = GetNewDictionary();
	Attributes.Add('IsNew', true);
	var DefaultValues = GetNewDictionary(); 
	var OwnerID = Connector.CurrentUser.ContactID;
	var DefaultValues = GetNewDictionary();
	DefaultValues.Add('OwnerID', Connector.CurrentUser.ContactID);
 
	Connector.Attributes('Incident') = dlData.Dataset.Values('SubjectID');
	var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID');
 
	if (SubjectType == 'Задача') 
	{
		ShowEditWindowEx('wnd_TaskCommentEdit', Attributes, DefaultValues);
		Connector.Attributes('CommentSource') = 'Task';  
	}
 
	if (SubjectType == 'Инцидент') 
	{
		ShowEditWindowEx('wnd_IncidentCommentEdit', Attributes, DefaultValues);
		Connector.Attributes('CommentSource') = 'Incident';
	}

Затем я создал событие ds_IncidentCommentOnDatasetBeforePost для ds_IncidentComment:

1

На обработку в него поместил код:

if (Connector.Attributes('CommentSource') == 'Incident'){
Dataset.Append();
Dataset.Values('IncidentID') = Connector.Attributes('Incident');
}

После этого комментарий добавлялся к необходимому инциденту :wink:

Здравствуйте, Игорь!
Спасибо Вам, спасибо Вам наблюдатели темы – кнопка работает, комментарий успешно добавляется.:biggrin:
Вот получившийся код:

function OpenIncidentCommentEdit(Window) {
var CommentSource = Connector.Attributes('CommentSource');
        var Incident = Connector.Attributes('Incident');
 
        var Attributes = GetNewDictionary();
        Attributes.Add('IsNew', true);
        var DefaultValues = GetNewDictionary();
        var OwnerID = Connector.CurrentUser.ContactID;
        var DefaultValues = GetNewDictionary();
        DefaultValues.Add('OwnerID', Connector.CurrentUser.ContactID);
 
        Connector.Attributes('Incident') = dlData.Dataset.Values('SubjectID');
        var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID');
        if (SubjectType == 'Инцидент')
        {
                ShowEditWindowEx('wnd_IncidentCommentEdit', Attributes, DefaultValues);
                Connector.Attributes('CommentSource') = 'Incident';
        }
}        
function OpenTaskCommentEdit(Window) {
var CommentSource = Connector.Attributes('CommentSource');
        var Task = Connector.Attributes('Task');
        var Attributes = GetNewDictionary();
        Attributes.Add('IsNew', true);
        var DefaultValues = GetNewDictionary();
        var OwnerID = Connector.CurrentUser.ContactID;
        var DefaultValues = GetNewDictionary();
        DefaultValues.Add('OwnerID', Connector.CurrentUser.ContactID);
        Connector.Attributes('Task') = dlData.Dataset.Values('SubjectID');
        var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID');
 
        if (SubjectType == 'Задача')
        {
                ShowEditWindowEx('wnd_TaskCommentEdit', Attributes, DefaultValues);
                Connector.Attributes('CommentSource') = 'Task';  
        }
}
function btnCommentOnClick(Control) {
    OpenIncidentCommentEdit();
    OpenTaskCommentEdit();
}

P.S.
С Вашего поста: «И есть еще один момент, который также можно улучшить - проверку не по DisplayValues, а по Values. Тип напоминания может быть переименован, ID останется прежним.
Посмотреть ID Вы можете в перечислении, как показано на скриншоте:»
Банальный вопрос:smile::
Зачем переименовивать тип напоминания?
Что в итоге поменяется, если проверку делать по Values?
Если я правильно понимаю, то я могу использовать этот код:

var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID')

Или этот (проверку делать по ID):

var SubjectType = dlData.Dataset.Values('{8E742F80-1C1A-4657-8D46-F189F0640544}');

А в чем разница?:smile:
Если подобные команды где-то описаны (руководство может) подскажите, пожалуйста, о них.
Спасибо.

Роман, только в том, что в первом случае мы обращаемся по имени, а во втором - по ID :)
Правильным тоном является обращение по ID.
Кроме случаев, если может быть несколько перечислений с одинаковыми именами или имя будет переименовываться, придумать причин не могу. Оба варианта исключает использование ID.

"Roman.Mykytenko" написал:Зачем переименовивать тип напоминания?
Что в итоге поменяется, если проверку делать по Values?
Если я правильно понимаю, то я могу использовать этот код:
var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID')

Или этот (проверку делать по ID):
var SubjectType = dlData.Dataset.Values('{8E742F80-1C1A-4657-8D46-F189F0640544}');

А в чем разница?


Не совсем:
Вы можете проверку выполнять так:

var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID');
if (SubjectType == "Задача") {// do something}

НО, если отображаемое значение будет изменено, то Ваш код просто перестанет работать. Зачем переименовывать Вас не должно сильно волновать, т.к. в этом конкретном случае, может, быть никто и не будет менять заголовок, но в общем случае справочники даются пользователю с возможностью их редактировать и задачу легко могут назвать активностью, а вот Id записи из интерфейса пользователя поменять не удастся, поэтому Ваша проверка станет надежнее, если проверять Вы будете значение, которое с меньшей вероятностью может быть изменено. Лучше всего, конечно, проверять по коду, если в справочнике есть такое поле, но давайте пока что остановимся на этом:

var taskSubjectTypeId = '{8E742F80-1C1A-4657-8D46-F189F0640544}';
var SubjectTypeId = dlData.Dataset.Values('SubjectTypeId');
if (SubjectTypeId == taskSubjectTypeId) {//do something} 

Спасибо Игорь.

В ходе тестирования комментариев с напоминаний, они успешно добавлялись к соответствующему Инциденту или Задаче.
Когда я добавлял комментарий не через напоминания, к примеру, создавал новый Инцидент (или существующий) комментарий к нему не добавлялся, а добавляется к тому Инциденту или Задаче к которому ранее добавил комментарий через напоминания.
Это через, то что мы обращаемся по имени, а не по ID?

"Раловец Ольга" написал:Roman.Mykytenko пишет:

Зачем переименовивать тип напоминания?
Что в итоге поменяется, если проверку делать по Values?
Если я правильно понимаю, то я могу использовать этот код:
var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID')

Или этот (проверку делать по ID):
var SubjectType = dlData.Dataset.Values('{8E742F80-1C1A-4657-8D46-F189F0640544}');

А в чем разница?

Не совсем:
Вы можете проверку выполнять так:
var SubjectType = dlData.Dataset.DisplayValues('SubjectTypeID');
if (SubjectType == "Задача") {// do something}
НО, если отображаемое значение будет изменено, то Ваш код просто перестанет работать. Зачем переименовывать Вас не должно сильно волновать, т.к. в этом конкретном случае, может, быть никто и не будет менять заголовок, но в общем случае справочники даются пользователю с возможностью их редактировать и задачу легко могут назвать активностью, а вот Id записи из интерфейса пользователя поменять не удастся, поэтому Ваша проверка станет надежнее, если проверять Вы будете значение, которое с меньшей вероятностью может быть изменено. Лучше всего, конечно, проверять по коду, если в справочнике есть такое поле, но давайте пока что остановимся на этом:
var taskSubjectTypeId = '{8E742F80-1C1A-4657-8D46-F189F0640544}';
var SubjectTypeId = dlData.Dataset.Values('SubjectTypeId');
if (SubjectTypeId == taskSubjectTypeId) {//do something}

Здравствуйте, Ольга!
Спасибо Вам за разъяснения.
Теперь я понял, зачем надо было делать проверку по ID.
Пробивал сделать по аналогии с тем, как Вы описали, к сожалению, код у меня вышел не рабочий.
Объект «DataField {Id Инцидента или Задачи}» не предназначен.
В принципе заголовки никто не будет менять, кроме меня, по этому, сейчас у меня нет нужды в том, чтобы проверку делать по ID.
Сейчас, я не пойму, почему у меня все новые записи (комментарии) добавляются к тому типу объекта, к которому я ранее добавил комментарий через напоминания. :smile:

Роман, дело в том, что значения атрибутов остались теми, которые использовались при заполнении напоминаний. То есть условие if (Connector.Attributes('CommentSource') == 'Incident') продолжает выполняться. Необходимо в них записать другие значения.

Измените код следующим образом:

if (Connector.Attributes('CommentSource') == 'Incident'){
Dataset.Append();
Dataset.Values('IncidentID') = Connector.Attributes('Incident');
}
    Connector.Attributes('CommentSource') = null;
    Connector.Attributes('Incident') = null;

Игорь, спасибо, все работает :smile:
В случае неработоспособности функционала, я отпишусь.

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