Всем доброго времени суток.

Версия 7.9 sales.

При создании или изменении, допустим, основного телефона на странице Контрагента (также Контакта и др., но для примера рассмотрим контрагента) у нас создаётся (изменяется) запись на детали Средств связи.

Для других задач (интеграция) пришлось на детали средства связи заменить стандартные колонки телефонов на свои (см. скриншот).

Вопрос - как восстановить синхронизацию между колонками?

В атрибутах схемы AccountPageV2 нашёл вот такой метод:

"Phone": {
        "dependencies": [
                {
                        "columns": ["Phone"],
                        "methodName": "syncEntityWithCommunicationDetail"
                }
        ]
},

Этого метода не могу найти в схемах. Кроме того, есть и обратная синхронизация при изменении телефона на детали.

Как настроить связь?

Нравится

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

Вроде нашёл, что где-то есть таблица соответствия типов:

var typeId = config.communicationTypeId ||
							this.getMappingValue("CommunicationType", "MasterEntityColumn", config.syncColumnName);
getMappingValue: function(getParamName, byParamName, byParamValue) {
					byParamValue = byParamValue.value || byParamValue;
					var masterDetailColumnMapping = this.get("MasterDetailColumnMapping");
					var typeMapping = this.Ext.Array.findBy(masterDetailColumnMapping, function(item) {
						return item[byParamName] === byParamValue;
					});
					return typeMapping ? typeMapping[getParamName] : "";
				},

Соответственно, вопрос получается - где следует её искать, и можно ли добавить свои изменения?

Здравствуйте,
Метод syncEntityWithCommunicationDetail находится в схеме: CommunicationSynchronizerMixin в пакете NUI. Метод публикует сообщение, которое слушает схема базовой детали комуникаций и вызывается метод который вы нашли: syncMasterEntityWithDetail. Таблица же соответствия типов, это не таблица, а атрибут MasterDetailColumnMapping который заполняется для каждой из типов детали средств связи, методом initMasterDetailColumnMapping
Посмотрите пакет NUI, схему: AccountCommunicationDetail там в этом методе вы увидите:

			initMasterDetailColumnMapping: function() {
				this.set("MasterDetailColumnMapping",[
					{
						"CommunicationType": ConfigurationConstants.CommunicationTypes.MainPhone,
						"MasterEntityColumn": "Phone"
					},
					{
						"CommunicationType": ConfigurationConstants.CommunicationTypes.AdditionalPhone,
						"MasterEntityColumn": "AdditionalPhone"
					},
					{
						"CommunicationType": ConfigurationConstants.CommunicationTypes.Fax,
						"MasterEntityColumn": "Fax"
					},
					{
						"CommunicationType": ConfigurationConstants.CommunicationTypes.Web,
						"MasterEntityColumn": "Web"
					}
				]);
			}

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

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

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

define("UsrNewProject1Page", [], function () {
    return {
        entitySchemaName: "UsrNewProject",
        details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
        diff: /**SCHEMA_DIFF*/[
        {
            "operation": "insert",
            "name": "UsrName775893ec-c3ee-4b03-ac06-5ca0e94ff464",
            "values": {
                "layout": {
                    "colSpan": 24,
                    "rowSpan": 1,
                    "column": 0,
                    "row": 0,
                    "layoutName": "ProfileContainer"
                },
                "bindTo": "UsrName"
            },
            "parentName": "ProfileContainer",
            "propertyName": "items",
            "index": 0
        },
        {
            "operation": "insert",
            "name": "UsrExpiredDaye043ad41-e3b7-46d1-b221-3a1cf5d64146",
            "values": {
                "layout": {
                    "colSpan": 24,
                    "rowSpan": 1,
                    "column": 0,
                    "row": 1,
                    "layoutName": "ProfileContainer"
                },
                "labelConfig": {},
                "enabled": true,
                "bindTo": "UsrExpiredDay"
            },
            "parentName": "ProfileContainer",
            "propertyName": "items",
            "index": 1
        },
        {
            "operation": "insert",
            "name": "UsrName5843e32c-549d-48aa-8d7d-c07e5584aeca",
            "values": {
                "layout": {
                    "colSpan": 24,
                    "rowSpan": 1,
                    "column": 0,
                    "row": 0,
                    "layoutName": "Header"
                },
                "bindTo": "UsrName"
            },
            "parentName": "Header",
            "propertyName": "items",
            "index": 0
        },
        {
            "operation": "insert",
            "name": "UsrStartDate200b3c57-08fe-4665-b708-c4336f718188",
            "values": {
                "layout": {
                    "colSpan": 12,
                    "rowSpan": 1,
                    "column": 0,
                    "row": 1,
                    "layoutName": "Header"
                },
                "labelConfig": {},
                "enabled": true,
                "bindTo": "UsrStartDate"
            },
            "parentName": "Header",
            "propertyName": "items",
            "index": 1
        },
        {
            "operation": "insert",
            "name": "UsrEndDate4cde4389-4e4e-4ca0-9b76-ad1f13ca558e",
            "values": {
                "layout": {
                    "colSpan": 12,
                    "rowSpan": 1,
                    "column": 12,
                    "row": 1,
                    "layoutName": "Header"
                },
                "labelConfig": {},
                "enabled": true,
                "bindTo": "UsrEndDate"
            },
            "parentName": "Header",
            "propertyName": "items",
            "index": 2
        },
        {
            "operation": "insert",
            "name": "UsrAccount7384ebef-b099-488f-8080-10f796183284",
            "values": {
                "layout": {
                    "colSpan": 12,
                    "rowSpan": 1,
                    "column": 0,
                    "row": 2,
                    "layoutName": "Header"
                },
                "labelConfig": {},
                "enabled": true,
                "contentType": 5,
                "bindTo": "UsrAccount"
            },
            "parentName": "Header",
            "propertyName": "items",
            "index": 3
        },
        {
            "operation": "insert",
            "name": "UsrOpportunity30132ad3-ba84-48a5-95dd-fe7c67b8e730",
            "values": {
                "layout": {
                    "colSpan": 12,
                    "rowSpan": 1,
                    "column": 12,
                    "row": 2,
                    "layoutName": "Header"
                },
                "labelConfig": {},
                "enabled": true,
                "contentType": 5,
                "bindTo": "UsrOpportunity"
            },
            "parentName": "Header",
            "propertyName": "items",
            "index": 4
        },
        {
            "operation": "insert",
            "name": "UsrStatus342c5df5-b3dd-45b3-a0b8-85744e37e684",
            "values": {
                "layout": {
                    "colSpan": 12,
                    "rowSpan": 1,
                    "column": 0,
                    "row": 3,
                    "layoutName": "Header"
                },
                "bindTo": "UsrStatus"
            },
            "parentName": "Header",
            "propertyName": "items",
            "index": 5
        },
    { // добавление панели
        "operation": "insert",
        "name": "ActionsDashboardModule",
        "values": {
            "classes": {
                "wrapClassName": [
                                        "actions-dashboard-module"
                ]
            },
            "itemType": 4
        },
        "parentName": "ActionDashboardContainer",
        "propertyName": "items",
        "index": 0
    }
        ]/**SCHEMA_DIFF*/,
        methods: {},
        rules: {},
        modules: /**SCHEMA_MODULES*/{
            "ActionsDashboardModule": {
                "config": {
                    "isSchemaConfigInitialized": true,
                    // Имя схемы.
                    "schemaName": "NewProjectActionsDashboard",
                    "useHistoryState": false,
                    "parameters": {
                        // Конфигурационный объект схемы модуля.
                        "viewModelConfig": {
                            // Имя схемы сущности страницы.
                            "entitySchemaName": "UsrNewProject",
                            // Конфигурационный объект блока Actions.
                            "actionsConfig": {
                                // Имя схемы для загрузки элементов в Actions.
                                "schemaName": "UsrNewProjectStatus",
                                // Имя колонки в родительской схеме, ссылающейся на схему, содержащую элементы Actions.
                                // Если не указана, берет значение равное schemaName.
                                "columnName": "UsrStatus",
                                // Имя колонки для сортировки элементов.
                                "orderColumnName": "Position",
                                // Имя колонки для сортировки элементов в меню элемента.
                                "innerOrderColumnName": "Position"
                            },
                            // Отвечает за отображение модуля панели действий, значение [true] по умолчанию.
                            "useDashboard": true,
                            // Отвечает за отображение блока Content, значение [true] по умолчанию.
                            "contentVisible": true,
                            // Отвечает за отображение блока Header, значение [true] по умолчанию.
                            "headerVisible": true,
                            "dashboardConfig": {
                                // Связь активностей с объектом страницы.
                                "Activity": {
                                    // Имя колонки объекта страницы.
                                    "masterColumnName": "Id",
                                    // Имя колонки в объекте [Activity].
                                    "referenceColumnName": "UsrNewProject"
                                }
                            }
                        }
                    }
                }
            }
        }/**SCHEMA_MODULES*/
    };
});

Нравится

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

Дмитрий, здравствуйте!

Непонятно зачем вы замещаете базовую схему BaseActionsDashboard. В инструкции о ней ни слова.
Там достаточно создать схему модели представления, унаследованную от SectionActionsDashboard. и Создать замещающую схему страницы раздела (если ее нет).

"Мотков Илья" написал:

Дмитрий, здравствуйте!

Непонятно зачем вы замещаете базовую схему BaseActionsDashboard. В инструкции о ней ни слова.

Там достаточно создать схему модели представления, унаследованную от SectionActionsDashboard. и Создать замещающую схему страницы раздела (если ее нет).


Здравствуйте Илья,
В списке Родительских объектов нету SectionActionsDashboard я нашел ее в пакете ActionsDashboard она наследуется от BaseActionsDashboard думал что пойдет если сделать наследование от него

"Головачев Дмитрий Александрович" написал:
Мотков Илья пишет:

Дмитрий, здравствуйте!

Непонятно зачем вы замещаете базовую схему BaseActionsDashboard. В инструкции о ней ни слова.

Там достаточно создать схему модели представления, унаследованную от SectionActionsDashboard. и Создать замещающую схему страницы раздела (если ее нет).

Здравствуйте Илья,

В списке Родительских объектов нету SectionActionsDashboard я нашел ее в пакете ActionsDashboard она наследуется от BaseActionsDashboard думал что пойдет если сделать наследование от него

А какую версию продукта Вы используйте? Так как в родительских объектах она есть. Убедитесь, что Вы вводите название без пробелов.

"Головачев Дмитрий Александрович" написал:

7.8.0 SalesEnterprise

Проверил. В 7.8. отображается BaseActionsDashboard (фильтрация происходит по Title объекта). В 7.9 видимо переименовали.

Но увидел, что Вы замещаете (признак "Замещать") а не наследуете (это разные вещи). Это может приводить к ошибкам.
На SDK рекомендую ознакомиться.

Примечание. Используйте последнюю версию приложения Там много всяких "плюшек".

"Мотков Илья" написал:
Головачев Дмитрий Александрович пишет:

7.8.0 SalesEnterprise

Проверил. В 7.8. отображается BaseActionsDashboard (фильтрация происходит по Title объекта). В 7.9 видимо переименовали.

Но увидел, что Вы замещаете (признак "Замещать") а не наследуете (это разные вещи). Это может приводить к ошибкам.

На SDK рекомендую ознакомиться.

Примечание. Используйте последнюю версию приложения Там много всяких "плюшек".


Спасибо Илья, действительно проблема была в том что я замещал а не наследовался от BaseActionsDashboard

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

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

!

Переименовывали заголовок в схеме раздела у параметра AddRecordButtonCaption, не помогло.

Нравится

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

Как вариант изменить в БД:

Update SysModuleEdit set ActionKindCaption='Добавить лид тест' where id='BF373F96-F36B-1410-3393-1C6F65E16A07'

Спасибо!
Способ с sql тоже не сработал, у раздела в SysModuleEdit параметр был ActionKindCaption пустым, хотя в самом разделе значение указано, и при добавлении необходимого названия кнопка не меняется :sad:, а каким еще способом можно изменить название? :smile:

"Maria H" написал:а каким еще способом можно изменить название?

А какая версия системы? В старых версиях была еще табличка SELECT * FROM SysModuleEditLcz со связью на SysModuleEdit через колонку RecordId там тоже есть строка, её переименуйте.

Большое спасибо! Совет с SysModuleEditLczOld помог :smile:

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

Добрый день!
В процессе есть такой элемент "выполнить действие процесса", его можно выбрать и указать в нем пользовательское действие и указав необходимые параметры для действия
Скажите, пожалуйста, каким образом можно вызвать данное действия в элементе сценарий процесса?

Нравится

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

Здравствуйте, Дарья!

Один вопрос: зачем?

Добрый день!
Есть пользовательское действие "обработать шаблон сообщения с макросами"
У нас есть процесс, который в случае если критичное обращение не успевает выполняться в срок, то ряду людей(специальной группе, состоящей из 5-6 чел) отправляется письма-оповещения, что по такому-то обращению приближается срок реакции. Таким образом, каждому человеку из группы руководителей отправляется соответствующее письмо на e-mail, а также приходит уведомление в систему дополнительно. Для этого используется элемент-сценарий в процессе , т.е. составляется запрос-список людей(результат=5-6 человек), и каждому отправляется письмо по заранее обработанному шаблону в данном процессе и уведомление в систему. Хочется в начале письма писать не просто "Добрый день", а, например, "Добрый день, Василий Васильевич" (в зависимости от адресата).
Для этого, как вариант, возникла идея вызвать данное действие в элементе-сценарии.
Т.е. составляется запрос-список людей(5-6 человек), вызывается действие обработки шаблона для этого человека, отправляется письмо по этому шаблону и уведомление в систему.
Возможно, это слишком сложный способ и есть проще?
Продукт сервис-деск

Здравствуйте, Дарья!

Корректно будет сделать по другому. В элементе "Задание-сценарий" можно вызвать несколько экземпляров процесса, передавая в него параметры.

Подобная тема обсуждалась по ссылке:
http://www.community.terrasoft.ru/forum/topic/25071

Добрый день!
Вызываем вспомогательный процесс в элементе "Задание сценарий" главного процесса следующим образом:
(галка "интерп.процессы" отщелкнута, 7.9)

UserConnection userConnection = context.UserConnection;
var select =
new Select(userConnection)
.Column("UsrTest","UsrContactId")
.Column("UsrTest","UsrEmail")
.Column("UsrTest","Id")
.From("UsrTest")
.Where("UsrTest","UsrTestId").IsEqual(new QueryParameter(RecordId))
as Select;

var manager = userConnection.ProcessSchemaManager;
var processSchema = (ProcessSchema)manager.FindInstanceByName("UsrProcessMyMailSendSub");
if (processSchema == null)
{ return true;
}

using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection()) {
using (IDataReader dataReader = select.ExecuteReader(dbExecutor)) {
while (dataReader.Read()) {

var moduleProcess = processSchema.CreateProcess(userConnection);
moduleProcess.SetPropertyValue(@"contactId", (Guid)dataReader.GetColumnValue("UsrContactId"));
moduleProcess.SetPropertyValue(@"needEmail", (String)dataReader.GetColumnValue("UsrEmail"));
moduleProcess.SetPropertyValue(@"needId", (Guid)dataReader.GetColumnValue("Id"));
moduleProcess.Execute(userConnection);
}
}
}
return true;

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

Подскажите, пожалуйста, что может быть не так

Добрый день, Дарья!

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

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

Добрый день, коллеги! Вероятно кто-то уже сталкивался с проблемой синхронизации календаря BPM с календарем других почтовых сервисов, отличных от google и MS Exchange. В нашем случае используется почтовый сервис Communigate PRO, на сайте рекомендуется использовать следующие методы и протоколы для синхронизации https://www.communigate.com/ru/guide/CalDAV.html#Access
Но, возможно вы знаете каким образом их возможно использовать для синхронизации в BPM, или наоборот, как использовать рекомендации из академии Terrasoft для синхронизации именно с этим почтовым сервисом?

Нравится

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

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

Базовая версия приложения не поддерживает протокол CalDAV.

Интеграцию с этим сервисом необходимо создавать отдельно.

Для реализации интеграции необходимо с bpm'online обратиться к сервису календаря и обработать полученный ответ.

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

Антон, ранее такую синхронизацию никто не делал.
Вы можете заказать её как проектную доработку, обратившись в Terrasoft или к кому-то из их партнеров.

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

В эту деталь (UsrLoyaltyObj)
Пустая Деталь

Надо программно добавить записи, чтобы стало так:
Заполненная деталь

Полазив на форуме, сказали что делается это через InsertQuery, и что я пробовал:

var insert = Ext.create("Terrasoft.InsertQuery", {
                                        rootSchemaName: "UsrLoyaltyObj"
                                });
insert.setParameterValue("UsrParam", item, Terrasoft.DataValueType.GUID);
insert.setParameterValue("UsrLoyalty", item.get("LoyaltyObj"), Terrasoft.DataValueType.GUID);
insert.execute();
this.updateDetails();

Где, UsrParam и UsrLoyalty - справочные поля детали. А Item элемент коллекции из EntitySchemaQuery.

Но, после вставки этого значения выдает ошибку в консоле:
Ошибка вставки

Означает, что я где-то что-то не так или не туда делаю вставку?

Нравится

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

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

Аналогично, записи исчезают после метода: this.updateDetails();

Значит я где-то не донастроил деталь?

А можно пример всего кода, ибо на первый взгляд все выглядит крайне неправильно)

"Варфоломеев Данила" написал:

А можно пример всего кода, ибо на первый взгляд все выгляди крайне неправильно)

getInsertLtyParamDetailQuery: function() {
				var insert = Ext.create("Terrasoft.InsertQuery", {
					rootSchemaName: "UsrLoyaltyObj"
				});
				var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
					rootSchemaName: "UsrRefLoyaltyParams"
				});
				esq.addColumn("Name", "ParamName");
				esq.addColumn("UsrContactLoyalty.Name", "ContactLoyalty");
				esq.addColumn("UsrContactLoyalty", "LoyaltyObj");
 
				var contactLty = this.get("UsrLoyalty");
				var esqLtyFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
					"UsrContactLoyalty.Name", contactLty.displayValue);
				esq.filters.add(esqLtyFilter);
				esq.getEntityCollection(function(result) {
					if (!result.success) {
 
					     result.collection.each(function(item) {
 
insert.setParameterValue("UsrParam", item, Terrasoft.DataValueType.LOOKUP);
insert.setParameterValue("UsrLoyalty", item.get("LoyaltyObj"), Terrasoft.DataValueType.LOOKUP);
					    });
                                       }
 
				}, this);
				insert.execute();
				return insert;
			}

Да, пока писал вроде понял, что 100% неверно здесь:

esq.addColumn("Name", "ParamName");
				esq.addColumn("UsrContactLoyalty.Name", "ContactLoyalty");
				esq.addColumn("UsrContactLoyalty", "LoyaltyObj");

Поле UsrParam, - ссылается на справочник с полями: Name, Description и справочным полем UsrLoyalty.

Но еще остается вопрос с пропадающими записями...

Здравствуйте, Илья.

1) Ошибка, показанная Вами на скриншоте, указывает на то, что в InsertQuery была добавлена колонка UsrParam несколько раз. Возможно это возникает по причине того, что this.UpdateQuery вызывается до того, как прошел INSERT запрос. Рекомендую Вам обновлять деталь в функции обратного вызова метода execute. Пример:

insert.execute(function() {
	this.updateDetails();
, this);

2) Записи на детали пропадать по следующим причинам: не настроенные колонки для реестра детали или же некорректное связывание детали и карточки (что более вероятно).

ого..... Всё, что можно было написать неправильно, тут неправильно xDD как оно вообще работает?)) должно же быть примерно так:

getInsertLtyParamDetailQuery: function() {
	var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {rootSchemaName: "UsrRefLoyaltyParams"});
	esq.addColumn("Name", "ParamName");
	esq.addColumn("UsrContactLoyalty.Name", "ContactLoyalty");
	esq.addColumn("UsrContactLoyalty", "LoyaltyObj");
 
	var contactLty = this.get("UsrLoyalty");
	esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "UsrContactLoyalty.Name", contactLty.displayValue));
	esq.getEntityCollection(function(result) {
		 if (result.success) {
				var batchQuery = Ext.create("Terrasoft.BatchQuery");
				result.collection.each(function(item) {
					var insertQuery = Ext.create("Terrasoft.InsertQuery", { rootSchemaName: "UsrLoyaltyObj" });
					insertQuery.setParameterValue("UsrParam", item.get("Id"), Terrasoft.DataValueType.GUID);
					insertQuery.setParameterValue("UsrLoyalty", item.get("LoyaltyObj").value, Terrasoft.DataValueType.GUID);
					batchQuery.add(insertQuery);
				 }, this);
				batchQuery.execute(this.insertQueryCallback, this);
			}
	}, this);
},
insertQueryCallback: function(result) {
	/*коллбэк вставки записей в бд*/
}

"Мотков Илья" написал:
2) Записи на детали пропадать по следующим причинам: не настроенные колонки для реестра детали или же некорректное связывание детали и карточки (что более вероятно).

Я создавал деталь через мастер деталей, по идее же все само должно было связаться.
Но если это не так, то каким образом это сделать?
Из этой статьи https://academy.terrasoft.ru/documents/technic-sdk/7-8/sozdanie-detali-…
не вариант, т.к. нет доступа к БД (или как это называется, локальный режим)...

"Варфоломеев Данила" написал:

ого..... Всё, что можно было написать неправильно, тут неправильно xDD как оно вообще работает?)) должно же быть примерно так:


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

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

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

Аналогично происходит и в Вашем случае, запись видна пока не будет обновлен реестр, поскольку запись не проходит фильтрацию.

Колонки, по которым происходит фильтрация можно посмотреть, как в Мастере разделов, так и в самой схеме карточки. Пример из схемы CasePage для детали Файлы и ссылки:

"Files": {
	"schemaName": "FileDetailV2",
	"entitySchemaName": "CaseFile",
	"filter": {
		"masterColumn": "Id",
		"detailColumn": "Case"
	}
},

В данном случае фильтрация происходит по колонке Id обращения и колонке Case детали.

"Мотков Илья" написал:

СПАСИБО!!! Назначил фильтр правильно по моим ячейкам, и все заработало.

И, что удивительно, 200+ записей было внесено, т.о. код выше работает, просто не отображался (фильтровался).

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

Коллеги, доброе утро!
В C# блоке бизнес-процесса выполняется следующий скрипт:

 Select caseDeadlineResponseSelect = new Select(userConnection).
         Column("Case", "id").As("CaseId").
         From("Case").
         Where("Case", "StatusId").IsEqual(Column.Parameter(caseStatusNew))
         .And("Case", "NrbSentDeadlineResponse").IsEqual(Column.Parameter("0"))
         .And(Func.DateDiff(DateDiffQueryFunctionInterval.Minute, Column.Const(dateNow), new QueryColumnExpression("RegisteredOn"))/
         Func.DateDiff(DateDiffQueryFunctionInterval.Minute, new QueryColumnExpression("ResponseDate"), new QueryColumnExpression("RegisteredOn"))).IsGreaterOrEqual(Column.Parameter(0.9))
         as Select;

Проблема в том, что в блоке WHERE в частности где идет идет деление дат, происходит округление в большую сторону, т.о как правило результат выражения
Func.DateDiff(DateDiffQueryFunctionInterval.Minute, Column.Const(dateNow), new QueryColumnExpression("RegisteredOn"))/
         Func.DateDiff(DateDiffQueryFunctionInterval.Minute, new QueryColumnExpression("ResponseDate"), new QueryColumnExpression("RegisteredOn")))
всегда равен больше единицы. В обычном SQL, я бы произвел конвертацию делимого и делителя:
CONVERT(decimal(10,2),DATEDIFF(MINUTE, GETDATE(), RegisteredOn))/
CONVERT(decimal(10,2),DATEDIFF(MINUTE, ResponseDate, RegisteredOn))

Но как произвести конвертацию в C# блоке я не понял. Я использовал функцию CAST, но не смог подобрать DBDatValueType.
Подскажите, как все таки произвести вычислениях хотя бы до десятых долей.

Нравится

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

В принципе, можно вписать произвольный SQL-код через Column.SqlText.
Примеры работы с ним можно найти в конфигурации. Вот тут тоже работают с датами:

var campaignPurchaseQtyCountSelect = new Select(UserConnection)
		.Column(Func.Count("Id"))
		.From("CampaignPurchaseQtyCount")
		.Where("CampaignId").IsEqual("Campaign", "Id")
		.And("CardId").IsEqual(Column.Parameter(cardId))
		.And(Column.SqlText("DATEDIFF(D, 0, [PurchaseDate])")).IsEqual(Column.SqlText("DATEDIFF(D, 0, @purchaseDate)"));
if (purchaseEntity.GetTypedColumnValue<Guid>("TypeId").Equals(Terrasoft.Configuration.PurchaseConsts.ReturnTypeUId)) {
	campaignPurchaseQtyCountSelect
		.And("IsRewarded").IsEqual(Column.Parameter(false));
}

BEHOLD!!!!

DBDataValueType valueType = userConnection.DataValueTypeManager.GetInstanceByUId(DataValueType.FloatDataValueTypeUId) as DBDataValueType;
 
DateDiffQueryFunction diff1 = Func.DateDiff(DateDiffQueryFunctionInterval.Day, Column.Const(DateTime.UtcNow), new QueryColumnExpression("CreatedOn")),
	diff2 = Func.DateDiff(DateDiffQueryFunctionInterval.Day, new QueryColumnExpression("TmResponseDate"), new QueryColumnExpression("CreatedOn"));
 
QueryColumnExpression exp1 = new QueryColumnExpression(diff1), exp2 = new QueryColumnExpression(diff2);
CastQueryFunction cast1 = Func.Cast(exp1, valueType), cast2 = Func.Cast(exp2, valueType);
 
 
QueryColumnExpression exp3 = new QueryColumnExpression(cast1), exp4 = new QueryColumnExpression(cast2);
QueryColumnExpression result = QueryColumnExpression.Divide(exp3, exp4);
 
Select decSelect = new Select(userConnection).Top(1)
	.Column(result)
	.From("TmNews")
as Select;
return decSelect.ExecuteScalar<float>();

В итоге выдаёт 0.6666667 на тестовом примере. Но эт жесть, конечно:smile:

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

Коллеги, подскажите, пожалуйста, как в деталь передать значение по умолчанию из справочника?

Нашёл как передать значение из родительской карточки, но вот передача guid'а не срабатывает.

defaultValues: {
    UsrAccount: {masterColumn: "Account"}, //--- эта строка работает
    UsrRecordType: "772874ae-4265-4a9a-9393-5bdc12f670f7" // --- эта строка не срабатывает
}

Нравится

1 комментарий

Нашёл решение в статье: http://www.community.terrasoft.ru/blogs/12454
Корректный код будет таким:

defaultValues: {
    UsrAccount: {masterColumn: "Account"},
    UsrRecordType: {value: "772874ae-4265-4a9a-9393-5bdc12f670f7"}
}
Показать все комментарии

В карточке детали, есть справочное поле: UsrParametr (который строится к справочнику: UsrRefParameter, с полями: Name, Description и UsrStatus из справочника UsrRefStatus, с полями: Name, Description).

Как отфильтровать поле UsrParametr, по имени статуса, т.е. по полю UsrStatus из Справочника UsrRefStatus.

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

"ActivityCategory": {
     dataValueType: Terrasoft.DataValueType.LOOKUP,
     dependencies: [
      {
       columns: ["ActivityCategory"],
       methodName: "onActivityCategoryChange"
      }
     ]
    },
    "Result": {
     lookupListConfig: {
      filters: [
       function() {
        var type = this.get("ActivityCategory");
        var filterGroup = Ext.create("Terrasoft.FilterGroup");
        filterGroup.add("ActivityCategory",
         Terrasoft.createColumnFilterWithParameter(
          Terrasoft.ComparisonType.EQUAL,
          "[ActivityCategoryResultEntry:ActivityResult].ActivityCategory",
          type.value));
        filterGroup.add("BusinessProcessOnly",
         Terrasoft.createColumnFilterWithParameter(
          Terrasoft.ComparisonType.EQUAL,
          "BusinessProcessOnly",
          0));
        return filterGroup;
       }
      ]
     }
    },

Нравится

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

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

Детализирую:

"ActivityCategory": {
     dataValueType: Terrasoft.DataValueType.LOOKUP,
     dependencies: [
      {
       columns: ["ActivityCategory"],
       methodName: "onActivityCategoryChange"
      }
     ]
    },

При изменении значения в поле ActivityCategory вызывается метод onActivityCategoryChange. Реализация этого метода:

onActivityCategoryChange: function() {
	var activityCategory = this.get("ActivityCategory");
	if (activityCategory && activityCategory.value === ConfigurationConstants.Activity.ActivityCategory.Meeting) {
		this.set("ShowInScheduler", true);
	}
}

Согласно этому методу в поле ShowInScheduler (Отображать в расписании) устанавливается значение true, если выбранная категория - встреча.

Теперь по второй части кода:

    "Result": {
     lookupListConfig: {
      filters: [
       function() {
        var type = this.get("ActivityCategory");
        var filterGroup = Ext.create("Terrasoft.FilterGroup");
        filterGroup.add("ActivityCategory",
         Terrasoft.createColumnFilterWithParameter(
          Terrasoft.ComparisonType.EQUAL,
          "[ActivityCategoryResultEntry:ActivityResult].ActivityCategory",
          type.value));
        filterGroup.add("BusinessProcessOnly",
         Terrasoft.createColumnFilterWithParameter(
          Terrasoft.ComparisonType.EQUAL,
          "BusinessProcessOnly",
          0));
        return filterGroup;
       }
      ]
     }

Данный код фильтрует значения в поле "Результат". Для выбора доступны значения, для которых:

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

Благодарю.

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

Можно ли развернуть Bpmonline 7.X на windows 7 для тестирования демо-версии или обязательно на Windows Server 2012 Standard ?

Нравится

1 комментарий

Можно и на 7 если получиться развернуть Microsoft SQL Server 2012 Standard.

Стоит использовать актуальные ОС, так как Windows 7 уже перестали официально поддерживать - ссылка

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