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

Создал деталь: Объект унаследован от базового (2 поля: связь с разделом, поле справочник), схема детали унаследована от "Базовая схема детали с реестром ( NUI )". Зарегестрировал ее в SysDetail, через мастер разделал добавил в раздел. Все работает.
Целью было создать деталь с редактируемым реестром, реализацию и зависимости смотрел в детали "Продукт в заказе", деталь отображается как обычная, видимо что то упустил.

Что нужно сделать что бы создать деталь с редактируемым реестром?

Нравится

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

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

Деталь с редактируемым реестром это сложная разработка примером которой является деталь "Деталь графика поставок и оплат" (SupplyPaymentDetailV2), и ее вспомогательные схемы в пакете "Passport".

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

P.S.
Всю информацию по использованию мастеров и дизайнеров вы можете найти в SDK
http://academy.terrasoft.ru/documents/?product=SDK&ver=7.6.0

Нет, вопрос в том "Как создать деталь с редактируемым реестром?" с обычными деталями проблем нет и про изменить я ничего не писал, страницу регестрировал что бы проверить работает ли сама деталь, потом ее удалил (и из БД) так как нужна именно деталь с редактируемым реестром.
Так подскажите как создать деталь с редактируемым реестром? На примере детали "Продукт в заказе" (смотрел в omnichanel) не разобрался.

С версии продукта и стоило начинать, да, в omnichanel эту деталь сделали редактируемой.
Для того, чтобы сделать реестр детали редактируемым, в соответствующей схеме необходимо:
- добавить зависимости от модулей ConfigurationGrid (Конфигурационный реестр), ConfigurationGridGenerator, ConfigurationGridUtilities,
- подключить "миксин" ConfigurationGridUtilites,
- установить аттрибут IsEditable в значение true
- базовому реестру указать свойства:
className: "Terrasoft.ConfigurationGrid",
generator: "ConfigurationGridGenerator.generatePartial",
generateControlsConfig: {bindTo: "generateActiveRowControlsConfig"},
changeRow: {bindTo: "changeRow"},
unSelectRow: {bindTo: "unSelectRow"},
onGridClick: {bindTo: "onGridClick"},
initActiveRowKeyMap: {bindTo: "initActiveRowKeyMap"},
для добавления действий активной записи добавить:
activeRowActions: [...],
activeRowAction: {bindTo: "onActiveRowAction"}

Зависимости нужно указать не только параметром requirejs но и в настройках схемы, в конфигураторе.
Итоговый код простейшей редактируемой детали будет выглядеть следующим образом:

define("UsrSchema1Detail", ["ConfigurationGrid", "ConfigurationGridGenerator",
		"ConfigurationGridUtilities"], function() {
	return {
		entitySchemaName: "Contact",
		attributes: {
			"IsEditable": {
				dataValueType: Terrasoft.DataValueType.BOOLEAN,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				value: true
			}
		},
		details: {},
		diff: [
				{
					"operation": "merge",
					"name": "DataGrid",
					"values": {
						"className": "Terrasoft.ConfigurationGrid",
						"generator": "ConfigurationGridGenerator.generatePartial",
						"generateControlsConfig": {"bindTo": "generatActiveRowControlsConfig"},
						"changeRow": {"bindTo": "changeRow"},
						"unSelectRow": {"bindTo": "unSelectRow"},
						"onGridClick": {"bindTo": "onGridClick"},
						"activeRowActions": [
							{
								"className": "Terrasoft.Button",
								"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
								"tag": "save",
								"markerValue": "save",
								"imageConfig": {"bindTo": "Resources.Images.SaveIcon"}
							},
							{
								"className": "Terrasoft.Button",
								"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
								"tag": "cancel",
								"markerValue": "cancel",
								"imageConfig": {"bindTo": "Resources.Images.CancelIcon"}
							},
							{
								"className": "Terrasoft.Button",
								"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
								"tag": "remove",
								"markerValue": "remove",
								"imageConfig": {"bindTo": "Resources.Images.RemoveIcon"}
							}
						],
						"initActiveRowKeyMap": {"bindTo": "initActiveRowKeyMap"},
						"activeRowAction": {"bindTo": "onActiveRowAction"},
						"multiSelect": false
					}
				}
			],
		mixins: {
			ConfigurationGridUtilites: "Terrasoft.ConfigurationGridUtilities",
			OrderUtilities: "Terrasoft.OrderUtilities"
		},
		methods: {}
	};
});

Максим, спасибо, получилось.

"Щиголь Максим" написал:

Здравствуйте, Максим. Подскажите пожалуйста в процессе к детали нужно просто вписать код и всё она заработает, конечно изменив при этом версию схемы детали? Просто в программировании не разбираюсь, пока что. Создал деталь и у неё реестр должен быть редактированным. По возможности схожим с деталью график поставок и оплаты.
Версия bpm'online sales enterprise 7.6

Не совсем понятно, что вы подразумеваете под фразой "в процессе к детали", возможно, вы хотели сказать "в схеме детали". Код конечно, нельзя взять прямо из этой темы, но можно писать по примеру и подобию.
Как минимум на строчке
entitySchemaName: "Contact",
вместо контакта, вам нужно будет указать ваш объект, на основе которого сделана схема вашей детали.

В общем, да, алгоритм достаточно прост, но знания по разработке в bpm'online все же понадобятся. Хотя бы на уровне реализации более простых кейсов из академии. Если в процессе реализации у вас возникнут другие вопросы, пишите, постараемся ответить.

"Щиголь Максим" написал:

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

Как минимум на строчке

entitySchemaName: "Contact",

вместо контакта, вам нужно будет указать ваш объект, на основе которого сделана схема вашей детали.

В общем, да, алгоритм достаточно прост, но знания по разработке в bpm'online все же понадобятся. Хотя бы на уровне реализации более простых кейсов из академии. Если в процессе реализации у вас возникнут другие вопросы, пишите, постараемся ответить.


Да ошибся, извините. Нашёл схему и прописал код, который вы прикрепляли и нужные изменения сделал. Всё заработало спасибо!

Хотел сделать то же самое с деталью продукты в Лиде. Только там чёрт ногу сломит. Добавил данный код, добавил всё чего не хватало, но сама делать теперь не отображается. Код довольно громоздкий. Помогите пожалуйста разобраться с ним

define("LeadProductDetailV2", ["ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities", "configurationEnums"],
function(configurationEnums, ConfigurationGrid, ConfigurationGridGenerator, ConfigurationGridUtilities) {
return {
entitySchemaName: "LeadProduct",
attributes: {
"IsEditable": {
dataValueType: Terrasoft.DataValueType.BOOLEAN,
type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
value: true
}
},
details: {},
diff: [
{
"operation": "merge",
"name": "DataGrid",
"values": {
"className": "Terrasoft.ConfigurationGrid",
"generator": "ConfigurationGridGenerator.generatePartial",
"generateControlsConfig": {"bindTo": "generatActiveRowControlsConfig"},
"changeRow": {"bindTo": "changeRow"},
"unSelectRow": {"bindTo": "unSelectRow"},
"onGridClick": {"bindTo": "onGridClick"},
"activeRowActions": [
{
"className": "Terrasoft.Button",
"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
"tag": "save",
"markerValue": "save",
"imageConfig": {"bindTo": "Resources.Images.SaveIcon"}
},
{
"className": "Terrasoft.Button",
"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
"tag": "cancel",
"markerValue": "cancel",
"imageConfig": {"bindTo": "Resources.Images.CancelIcon"}
},
{
"className": "Terrasoft.Button",
"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
"tag": "remove",
"markerValue": "remove",
"imageConfig": {"bindTo": "Resources.Images.RemoveIcon"}
}
],
"initActiveRowKeyMap": {"bindTo": "initActiveRowKeyMap"},
"activeRowAction": {"bindTo": "onActiveRowAction"},
"multiSelect": false
}
}
],
mixins: {
ConfigurationGridUtilites: "Terrasoft.ConfigurationGridUtilities",
OrderUtilities: "Terrasoft.OrderUtilities"
},
//данный кусочек был добавлен:smile:
methods: {
/**
* Возвращает колонки, которые всегда выбираются запросом
* @return {Object} Возвращает массив объектов-конфигураций колонок
*/
getGridDataColumns: function() {
return {
"Id": {path: "Id"},
"Product": {path: "Product"},
"Product.Name": {path: "Product.Name"}
};
},

/**
* Открывает справочник продуктов
* @private
*/
openProductLookup: function() {
var config = {
entitySchemaName: "Product",
multiSelect: true,
columns: ["Name", "Price", "Currency"]
};
var leadId = this.get("MasterRecordId");
if (this.Ext.isEmpty(leadId)) {
return;
}
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: this.entitySchemaName
});
esq.addColumn("Id");
esq.addColumn("Product.Id", "ProductId");
esq.filters.add("filterLead", this.Terrasoft.createColumnFilterWithParameter(
this.Terrasoft.ComparisonType.EQUAL, "Lead", leadId));
esq.getEntityCollection(function(result) {
var existsProductsCollection = [];
if (result.success) {
result.collection.each(function(item) {
existsProductsCollection.push(item.get("ProductId"));
});
}
if (existsProductsCollection.length > 0) {
var existsFilter = this.Terrasoft.createColumnInFilterWithParameters("Id",
existsProductsCollection);
existsFilter.comparisonType = this.Terrasoft.ComparisonType.NOT_EQUAL;
existsFilter.Name = "existsFilter";
config.filters = existsFilter;
}
this.openLookup(config, this.addCallBack, this);
}, this);
},

/**
* @overridden
*/
onCardSaved: function() {
this.openProductLookup();
},

/*
* Открывает справочник продуктов в случае если карточка лида была ранее сохранена
* @overridden
* */
addRecord: function() {
var masterCardState = this.sandbox.publish("GetCardState", null, [this.sandbox.id]);
var isNewRecord = (masterCardState.state === configurationEnums.CardStateV2.ADD ||
masterCardState.state === configurationEnums.CardStateV2.COPY);
if (isNewRecord === true) {
var args = {
isSilent: true,
messageTags: [this.sandbox.id]
};
this.sandbox.publish("SaveRecord", args, [this.sandbox.id]);
return;
}
this.openProductLookup();
},

/*
* Добавление выбраных продуктов
* @private
* */
addCallBack: function(args) {
var bq = this.Ext.create("Terrasoft.BatchQuery");
var leadId = this.get("MasterRecordId");
this.selectedRows = args.selectedRows.getItems();
this.selectedItems = [];
this.selectedRows.forEach(function(item) {
item.LeadId = leadId;
item.ProductId = item.value;
bq.add(this.getProductInsertQuery(item));
this.selectedItems.push(item.value);
}, this);
if (bq.queries.length) {
this.showBodyMask.call(this);
bq.execute(this.onProductInsert, this);
}
},

/*
* Возвращает запрос на добавление продукта
* @param item {Object} идентификатор лида и выбранный в справочнике продукт {LeadId, value}
* @private
* */
getProductInsertQuery: function(item) {
var insert = Ext.create("Terrasoft.InsertQuery", {
rootSchemaName: this.entitySchemaName
});
insert.setParameterValue("Lead", item.LeadId, this.Terrasoft.DataValueType.GUID);
insert.setParameterValue("Product", item.ProductId, this.Terrasoft.DataValueType.GUID);
return insert;
},

/*
* Загрузка добавленых продуктов в реестр
* @private
* */
onProductInsert: function(response) {
this.hideBodyMask.call(this);
this.beforeLoadGridData();
var filterCollection = [];
response.queryResults.forEach(function(item) {
filterCollection.push(item.id);
});
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
rootSchemaName: this.entitySchemaName
});
this.initQueryColumns(esq);
esq.filters.add("recordId", Terrasoft.createColumnInFilterWithParameters("Id", filterCollection));
esq.getEntityCollection(function(response) {
this.afterLoadGridData();
if (response.success) {
var responseCollection = response.collection;
this.prepareResponseCollection(responseCollection);
this.getGridData().loadAll(responseCollection);
}
}, this);
},

/*
* Удаление выбранных записей
* @overridden
* */
deleteRecords: function() {
var selectedRows = this.getSelectedItems();
if (selectedRows.length > 0) {
this.set("SelectedRows", selectedRows);
this.callParent(arguments);
}
},

/**
* @inheritdoc Terrasoft.BaseGridDetailV2#getCopyRecordMenuItem
* @overridden
*/
getCopyRecordMenuItem: Terrasoft.emptyFn,

/**
* @inheritdoc Terrasoft.BaseGridDetailV2#getEditRecordMenuItem
* @overridden
*/
getEditRecordMenuItem: Terrasoft.emptyFn,

/**
* @inheritdoc Terrasoft.GridUtilitiesV2#getFilterDefaultColumnName
* @overridden
*/
getFilterDefaultColumnName: function() {
return "Product";
}
},
diff: /**SCHEMA_DIFF*/[
{
"operation": "merge",
"name": "DataGrid",
"values": {
"rowDataItemMarkerColumnName": "Product"
}
},
{
"operation": "merge",
"name": "AddRecordButton",
"values": {
"visible": {"bindTo": "getToolsVisible"}
}
}
]/**SCHEMA_DIFF*/
};
}
);

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

Во вторых миксин OrderUtilities: "Terrasoft.OrderUtilities" тут наверно лишний.
Вот у меня получилось в лидах сделать эту деталь редактируемой, почитайте:

define("LeadProductDetailV2", ["ConfigurationEnums", "ConfigurationGrid", "ConfigurationGridGenerator",
		"ConfigurationGridUtilities"],
	function(configurationEnums) {
		return {
			entitySchemaName: "LeadProduct",
			methods: {
			},
			mixins: {
				ConfigurationGridUtilites: "Terrasoft.ConfigurationGridUtilities"
			},
			attributes: {
         		"IsEditable": {
            	dataValueType: Terrasoft.DataValueType.BOOLEAN,
            	type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
            	value: true
         		}
      		},
			diff: /**SCHEMA_DIFF*/[
		{
            "operation": "merge",
            "name": "DataGrid",
            "values": {
               "className": "Terrasoft.ConfigurationGrid",
               "generator": "ConfigurationGridGenerator.generatePartial",
               "generateControlsConfig": {"bindTo": "generatActiveRowControlsConfig"},
               "changeRow": {"bindTo": "changeRow"},
               "unSelectRow": {"bindTo": "unSelectRow"},
               "onGridClick": {"bindTo": "onGridClick"},
               "activeRowActions": [
                  {
                     "className": "Terrasoft.Button",
                     "style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                     "tag": "save",
                     "markerValue": "save",
                     "imageConfig": {"bindTo": "Resources.Images.SaveIcon"}
                  },
                  {
                     "className": "Terrasoft.Button",
                     "style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                     "tag": "cancel",
                     "markerValue": "cancel",
                     "imageConfig": {"bindTo": "Resources.Images.CancelIcon"}
                  },
                  {
                     "className": "Terrasoft.Button",
                     "style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
                     "tag": "remove",
                     "markerValue": "remove",
                     "imageConfig": {"bindTo": "Resources.Images.RemoveIcon"}
                  }
               ],
               "initActiveRowKeyMap": {"bindTo": "initActiveRowKeyMap"},
               "activeRowAction": {"bindTo": "onActiveRowAction"},
               "multiSelect": false
            }
         }
			]/**SCHEMA_DIFF*/
		};
	}
);

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

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

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

подробнее про добавление детали по ссылке:
http://academy.terrasoft.ru/documents/docs/product/bpm'online%20sales/t…

создание детали:
http://academy.terrasoft.ru/documents/docs/product/bpm'online%20sales/t…

Это мне нужно создать новую деталь? Просто в "Колонка детали" нету "Контакт"...

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

"Липатов Юрий Сергеевич" написал:

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

Не совсем понимаю про какой обьект детали идет речь? Можете написать более детальнее?

Пожалуйста, обратите внимание на ссылки, которые я Вам написал выше:

"Липатов Юрий Сергеевич" написал:

создание детали:

http://academy.terrasoft.ru/documents/docs/product/bpm'online%20sales/team/7.7.0/BPMonlineHelp/chapter_detail_wizard/chapter_detail_wizard.htm

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

Доброго дня!
Не смог найти нужного мануала. Прочитал в доках про: Создание замещающих классов в пакетах bpm'online но там не вся информация.

Можно ли создавать свои страницы используя html верстку? Можно ли присоединить к ней свой контролер?
К примеру мне надо сделать вот такую страницу(см. скрин)
Продукт: реалстейт

Нравится

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

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

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

http://www.community.terrasoft.ru/forum/topic/11520

Мне не надо изменить что то стандартное. Мне надо сделать полностью кастомною красивую страницу. Как css так и верстку.
Как можно это сделать через конфигурацию?
Если нажимаю на создать страницу в конфигурации, то открывается убогий "мастер форм" куда можно перетаскивать нужные блоки. Мне же это не совсем подходит.

Кто нить может мне подсказать?

Виктор,
"bpm'online не является программой для верстки сайта.
В конфигурации Вы можете использовать мастер раздела для создания собственных и редактирования существующих разделов, а также добавлять собственные стили:
http://www.community.terrasoft.ru/forum/topic/11520

Если Вам необходимо реализовать страницу, как на указанном Вами скриншоте, Вы можете использовать для этого любую общедоступную программу для верстки, на основе данной страницы "поднять" сайт, а затем реализовать обмен данными между Вашим сайтом и bpm'online при помощи протокола OData:
http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/Integratio…

Спасибо за ответ!

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

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

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

1) Cоздать новый раздел.
2) В Схеме страницы нового раздела (UsrNewSection) добавить метод в секцию методов:

methods: {
init: function() {
      window.location.replace("http://stackoverflow.com");
   }
},
Показать все комментарии

Доброго времени суток, коллеги.
Согласно этому в запросе в колонке с текстом SQL вроде как можно использовать конструкцию для автоматической замены таблицы на представление в зависимости от прав пользователя. Вопрос: в каких версиях Terrasoft это работает? На Terrasoft CRM 3.3.2.245 выдает ошибку "Оригинальное сообщение об ошибке: Incorrect syntax near ''. Incorrect syntax near the keyword 'SELECT'"

Нравится

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

Добрый день.

Начиная с версии 3.4.0

Ясно, спасибо.
А в 3.3.2 подобную задачу решить можно? Или сразу вместо имен таблиц вставлять имена представлений?

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

Также можно


делать в колонке вызов хранимой функции с нужным условием.

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

Добрый день!

Для того, чтобы процесс автоматически запускался раз в N минут, необходимо в процесс поместить элемент Сценарий вида:

string schedulerJobGroupName = "MyProcessGroupMyEmail1";//- Любое имя
string jobProcessName = "UsrProcess"; //- Название процесса
string schedulerJobName = "MyJobNameMyEmail1"; //- Любое имя
int startOffset = 3600; // интервал в секундах
AppScheduler.RemoveJob(schedulerJobName, schedulerJobGroupName);
var job = AppScheduler.CreateProcessJob(schedulerJobName, schedulerJobGroupName, jobProcessName, UserConnection.Workspace.Name, UserConnection.CurrentUser.Name);
var trigger = new SimpleTriggerImpl(schedulerJobName + "Trigger", schedulerJobGroupName, DateTime.UtcNow.AddSeconds(startOffset));
AppScheduler.Instance.ScheduleJob(job, trigger);
return true;

Это работает.

Скажите, пожалуйста, а можно ли сделать так, чтобы он запускался только в определенные часы
(например, с 8.00 до 20.00)

т.е. как можно здесь применить такую формулу ?
Если 20:00 - текущее время T (интервал запуска) то запуск установить в T+12 часов

Нравится

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

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

Пример использования планировщика в указанном интервале.

string schedulerJobGroupName = "ScheduleTest";
string jobProcessName = "UsrScheduleTest";
string schedulerJobName = "ScheduleTestJob";
TimeSpan start = TimeSpan.Parse("11:31");
TimeSpan end = TimeSpan.Parse("11:46");
TimeSpan currentTime = DateTime.Now.TimeOfDay;

if ((currentTime > start) && (currentTime < end))
{
int startOffset = 30;
AppScheduler.RemoveJob(schedulerJobName, schedulerJobGroupName);
var job = AppScheduler.CreateProcessJob(schedulerJobName, schedulerJobGroupName, jobProcessName, UserConnection.Workspace.Name, UserConnection.CurrentUser.Name);
var trigger = new SimpleTriggerImpl(schedulerJobName + "Trigger", schedulerJobGroupName, DateTime.UtcNow.AddSeconds(startOffset));
AppScheduler.Instance.ScheduleJob(job, trigger);
} else {
int startOffset = 12;
AppScheduler.RemoveJob(schedulerJobName, schedulerJobGroupName);
var job = AppScheduler.CreateProcessJob(schedulerJobName, schedulerJobGroupName, jobProcessName, UserConnection.Workspace.Name, UserConnection.CurrentUser.Name);
var trigger = new SimpleTriggerImpl(schedulerJobName + "Trigger", schedulerJobGroupName, DateTime.UtcNow.AddHours(startOffset));
AppScheduler.Instance.ScheduleJob(job, trigger);
}
return true;

Спасибо

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

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

Вы можете проверить существующие тригера выполнив запрос в БД:
select * from QRTZ_TRIGGERS
select * from QRTZ_SIMPLE_TRIGGERS

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

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

Как отправить письмо контакту по заданному шаблону - с изображением, вложением и макросами (персонализацией)?

Нравится

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

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

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

Для решения Вы можете задать значение по умолчанию полю "html body" объекта "Активность". Более подробно читайте здесь. Правда это решение будет создавать email без персонификации.

Вторым решением будет создание собственного шаблона в процессе. Это решение описано здесь.

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

Виктор,

Алексей предоставил Вам решение по второму пункту. Вот ссылка - http://www.community.terrasoft.ua/blogs/12527

Илья, это я читал. Как прикрепить вложение во втором варианте?

Второй вариант не предусматривает прикрепления вложений - элемент "Отправить email" не умеет с ними работать.

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

На форуме не нашел, решил написать.
Проблема такая:
-В расширенном модуле AccountSectionV2 нужно по нажатию кнопки еще проставлять true на галку.
При создание нового account(а именно на page) все без проблем "завелось", проблема встала именно на section, при редактирование из клиентской части уже имеющегося юр.лица.

Как я понял нужно использовать esq, т.к. this.set("bool",true); не работает, но не нашел как устанавливать значения через esq. Быть может надо по другому. Помогите пожалуйста.

define("AccountSectionV2", [],
        function() {
        return {
                entitySchemaName: "Account",
            // Коллекция методов модели представления страницы редактирования.
            methods: {
                                getChainCardModuleSandboxId: function(typeColumnValue) {
                                        return this.getCardModuleSandboxId() + "_chain" + typeColumnValue;
                                },
                                showExistingRecordSaveButton: function() {
                                        this.set("IsSendToFlextera", true);
                                        return this.get("IsCardInEditMode") && this.get("ShowSaveButton");
                                       
                                },
                                onClickSaveToFlex: function() {
                                   this.set("IsSendToFlextera", true);
                                        var tag = arguments[0] || arguments[3];
                                        this.sandbox.publish("OnCardAction", tag, [this.getCardModuleSandboxId()]);
                                       
                                }
                        },
                               
                        diff: [
                {
                                        "operation": "insert",
                                        "name": "FlexsaveRecordButton",
                                        "parentName": "CombinedModeActionButtonsCardLeftContainer",
                                        "propertyName": "items",
                                        "values": {
                                                "itemType": Terrasoft.ViewItemType.BUTTON,
                                                "caption": {"bindTo": "Resources.Strings.SaveToFlexteraCaption"},
                                                "click": {"bindTo": "IsSendToFlextera"},//"onClickSaveToFlex"},
                                                "visible": {"bindTo": "showExistingRecordSaveButton"},
                                                "classes": {"textClass": ["actions-button-margin-right"]},
                                                "tag": "save"
                                        }
                                }
            ]
                 
         };
        });

Нравится

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

Максим, добрый день!

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

var activeRow = this.getActiveRow();
activeRow.set("YourColumnName", columnValue);
activeRow.saveEntity();

Для работы этого кода необходимо, чтобы в коллекции activeRow.columns была колонка с названием YourColumnName и типом Terrasoft.ViewModelColumnType.ENTITY_COLUMN (данная константа равняется 0).

Также обновление значения можно выполнить через запрос примерно так:

var updateQuery = this.Ext.create("Terrasoft.UpdateQuery", {
	rootSchemaName: "EntitySchemaName"
});
var filters = updateQuery.filters;
filters.addItem(this.Terrasoft.createColumnFilterWithParameter(
	this.Terrasoft.ComparisonType.EQUAL, "Id", currentRecordId));
updateQuery.setParameterValue("YourColumnName", columnValue);
updateQuery.execute(callbackFunction, this);
Показать все комментарии

Добрый день,
Использую стандартный элемент БП Чтение данных, нужно выбрать звонки из Активностей, в которых начало меньше или равно текущей дате/времени, ставлю такое условие, но вытягиваются звонки у которых значение больше текущей даты/времени. Собственно вопрос в чем проблема, стандартный элемент не умеет сравнивать DateTime?
Причем дату сравнивает нормально, а вот по времени сравнение не идет.
1

Нравится

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

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

Элемент "Читать данные" умеет это делать. Проблема в другом:biggrin:

Поле "Ответственный" смотрит в [dbo].[Contact]. Значение "Текущий пользователь" берется из [dbo].[SysAdminUnit]. Поле "Ответственный" необходимо сравнивать со значением "Контакт текущего пользователя".

С этим фильтром хоть какие-то активности подтягиваются?

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

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

Правильно ли я понимаю, что "Текущее значение даты времени" - это параметр процесса? Каким значением заполняется этот параметр?

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

Доброго времени суток, коллеги.
Использую Terrasoft CRM 3.3.2.
Подскажите, есть ли возможность заставить стандартный элемент управления "Календарь" отображать более одного месяца одновременно? И можно ли на нем выделить (подсветить) несколько несвязанных диапазонов дат? Примерно как на картинке во вложении (часть дат выделена полужирным шрифтом).

Нравится

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

Добрый день.

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

Спасибо, буду смотреть.

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

Добрый день.

Подскажите почему может быть такая ситуация:
В БП используется Таймер. Если в таймер идет один поток и из него один поток, то он работает корректно.
Но если добавить из таймера два исходящих потока или исключающее ИЛИ после таймера с двумя исходящими потоками, то БП работает некорректно.
Сделала тестовый БП:
1. В сценарии пишется лог в файл + уменьшается параметр, отвечающий за кол-во повторений БП
2. Чтение данных только для определения по какому маршруту идет процесс
3. В условном потоке идет проверка: завершить процесс (параметр Бп = 0)
Причем после первого выполнения сценария, он повторно не выполняется (то, что не выполняется знаю точно, потому что веду логирование в данном сценарии). Диаграмма БП на картинке 3.
Версия продукта 7.3.0.1910.

Нравится

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

Александра, судя по скриншотам журнала процессов, элемент «Задание-сценарий» не логируется. Пожалуйста, установите в дизайнере процессов признак «Журналировать» этому элементу.

Также, у процесса есть свойство «Максимальное количество повторений» - это количество повторений после которых процесс завершается вне зависимости от результата.

1. Устанавливала признак Журналировать. При этом в Диаграмме отмечается, что блок обрабатывался, но изменений в параметре и логах при этом нет. Такая ситуация наблюдается только со сценариями, при повторном запуске вычисления в них не срабатывают.
2. Так же пробовала другую ситуацию. Сделала два Бп:
первый состоит из таймера и подпроцесса (запуск второго БП)
второй содержит всю обработку.
При такой реализации все работает корректно. Получается каждый день будет появляться новый БП (2), созданный из БП (1). У таймера старт раз в сутки. Единственное Бп 2 содержит только один скрипт, это немного странно. Удобней было бы все реализовать в одном..
Насколько корректным будет такой вариант? Может есть какие-то "подводные камни"?
3. Так же есть вариант делать без сценария, а с использованием других элементов БП, но это сильно усложнит логику и в БП будет цикл с несколькими элементами процесса.

Максимальное число повторений при подходе 2. не сработало. Ставила 3 повторения, отработал 4, после чего пришлось выключить руками.

Александра, добрый день!

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

1. В БП добавить элемент “Задание сценарий”.
2. В сценарии прописать следующий код :
string schedulerJobGroupName = "ScheduleTest"; // произвольное название
string jobProcessName = "UsrScheduleTest"; // название бизнес-процесса
string schedulerJobName = "ScheduleTestJob"; // произвольное название
int startOffset = 60; // периодичность запуска (в секундах)
AppScheduler.RemoveJob(schedulerJobName, schedulerJobGroupName);
var job = AppScheduler.CreateProcessJob(schedulerJobName, schedulerJobGroupName, jobProcessName, UserConnection.Workspace.Name, UserConnection.CurrentUser.Name);
var trigger = new SimpleTriggerImpl(schedulerJobName + "Trigger", schedulerJobGroupName, DateTime.UtcNow.AddSeconds(startOffset));
AppScheduler.Instance.ScheduleJob(job, trigger);
return true;
3. Сохранить сценарий.

4. В пространство имен (Usings) процесса добавить:
- Quartz.Impl
- Quartz
- Quartz.Impl.Triggers
- Terrasoft.Core.Scheduler

5. Опубликовать процесс.

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

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

По поводу решения через Quartz, я верно понимаю, что необходимо предварительно настроить планировщик?

Здравствуйте, Александра! Планировщик в системе уже существует и настроен. Процесс создает Job, который запускается в указанное время. Запускаемые Job можно найти в таблице dbo.qrtz_triggers

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

Доброго времени суток!
Есть на стандартных объекта недвижимости галерея.
Хотелось бы добавить такую для свое кастомного раздела. Как это сделать?

Нравится

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

Виктор, добрый вечер!

Интересующий Вас функционал Вы можете реализовать по аналогии с базовыми разделами продукта Real Estate, такими как Объекты и Листинги, просмотрев объекты "Listing" или "Property", а также схемы "GalleryDetail", "ListingGalleryDetail", "PropertyGalleryDetail".

Спасибо.

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