Добрый день!
Подскажите, пожалуйста, возможно ли извлечь изображения из пакетов раздела Images?
фото

Нравится

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

Добрый день!

В общем данный вопрос обсуждался в этом топике - http://www.community.terrasoft.ru/forum/topic/12709
Ответ на свой вопрос можете найти в этом комментарии - http://www.community.terrasoft.ru/forum/topic/12709#comment-54014

Дмитрий, спасибо большое!

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

Доброго дня
Чому у версії BPM 7.7.0.2186_SalesEnterprise такі модулі як AccountPage, ContactPage, CtiPanel я не можу відкрити і відлагодити в браузері???

Нравится

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

Доброго дня, Сергій!
У версії 7.7 з’явився модуль SectionBundleModule в котрому лежать коди всіх схем разділів і карточок (базовых). А ще є ConfigurationBootstrap в нього входять базові схемы, необхідні для роботи системи.

Дуже дякую.

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

Доброго времени суток!
Тема связна с вот этой
Хочу вызвать БП из новосозданной кнопки вот так:

define('SFPropertySection', ['GridUtilitiesV2'],
function() {
        return {
                entitySchemaName: 'SFProperty',
                contextHelpId: '1001',
                diff: /**SCHEMA_DIFF*/[
                                        {
                                                "operation": "insert",
                                                "parentName": "CombinedModeActionButtonsCardLeftContainer",
                                                "propertyName": "items",
                                                "name": "TestButton",
                                                "values": {
                                                        "itemType": Terrasoft.ViewItemType.BUTTON,
                                                        "caption": "test method сombined",
                                                        "click": {
                                                                "bindTo": "showInfo"
                                                        }
                                                }
                                        }              
                ]/**SCHEMA_DIFF*/,
                messages: {},
                methods: {
           showInfo: function() {
                                        var test = this.get("ActiveRow");;
                                        this.showInformationDialog(test);
                                                                                var processArgs = {
                                                                                    sysProcessName: 'Process2',
                                                                                    parameters: {
                                                                                        RecordId: test
                                                                                    }
                                                                                };
                                                                                this.runProcess(processArgs.sysProcessName, processArgs.parameters, this);                                                                             
                                }              
                }
        };
});

При сохранении видим вот такие ошибки(прикрепил)
Может вызывать процесс из раздела надо по другому?

Нравится

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

Виктор, добрый день!

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

define("SFPropertySection", ["GridUtilitiesV2"], function() {
	return {
		entitySchemaName: "SFProperty",
		contextHelpId: "1001",
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"parentName": "CombinedModeActionButtonsCardLeftContainer",
				"propertyName": "items",
				"name": "TestButton",
				"values": {
					"itemType": Terrasoft.ViewItemType.BUTTON,
					"caption": "test method сombined",
					"click": {"bindTo": "showInfo"}
				}
			}
		]/**SCHEMA_DIFF*/,
		messages: {},
		methods: {
			showInfo: function() {
				var test = this.get("ActiveRow");
				this.showInformationDialog(test);
				var processArgs = {
					sysProcessName: "Process2",
					parameters: {
						RecordId: test
					}
				};
				this.runProcess(processArgs.sysProcessName, processArgs.parameters, this);
			}
		}
	};
});

то большинство из этих сообщений должны устраниться.

А вот с самим вызовом this.runProcess могут быть нюансы в зависимости от версии. Насколько я вижу в версии 7.6.0, вызов this.runProcess из базового раздела или страницы должен принимать всего один параметр tag, который равен идентификатору процесса:

runProcess: function(tag) {
	ProcessModuleUtilities.executeProcess({
		sysProcessId: tag
	});
}

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

define("SFPropertySection", ["ProcessModuleUtilities", "GridUtilitiesV2"], function(ProcessModuleUtilities) {
......................................
				var processArgs = {
					sysProcessName: "Process2",
					parameters: {
						RecordId: test
					}
				};
				ProcessModuleUtilities.executeProcess(processArgs);
......................................
});

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

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

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

1) Нужно передать значение (Id выбранной записи) со страницы детали в страницу проекта, задействованной в бизнес процессе. Я так понял нужно использовать sandbox и messages. Подскажите подробнее как их использовать?

2) Добавил на деталь свою кнопку. Как по нажатию этой кнопки осуществить дальнейшее прохождение страницы проекта по бизнес процессу. Банальный this.acceptProcessElement(); не помогает.

Скриншот во вложении.

Нравится

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

Добрый день!

Посмотрите похожие темы на community. Подобные задачи уже решались.
http://www.community.terrasoft.ru/forum/topic/11626
http://www.community.terrasoft.ru/forum/topic/13314
http://www.community.terrasoft.ru/blogs/12691
http://www.community.terrasoft.ru/forum/topic/10554

Здравствуйте. С первым вопросом разобрался. Удалось передать сообщение по нажатию кнопки. Но это не удобно. Скажите, а можно передать сообщение по событию выделения записи в детали(событие типа onClick)? Функцию получения выделенной строки - this.getActiveRow() нашел. А где прописать событие не разобрался.

И еще вопрос по messages. Как отловить на основной странице, что сообщение из детали пришло? Т.е есть ли такое событие прихода сообщения?

Решил реализовать следующим образом: добавить кнопку в активную строку и по нажатию послать сообщение основной форме. В основной форме отловит сообщение и отправиться дальше по процессу. Что удалось найти:

Нашел на форуме, что можно добавить кнопку в активную строку.

{
	"operation": "insert",
	"name": "DataGridActiveRowTestAction",
	"parentName": "DataGrid",
	"propertyName": "activeRowActions",
	"values": {
		"className": "Terrasoft.Button",
		"style": Terrasoft.controls.ButtonEnums.style.BLUE,
		"caption": {"bindTo": "Resources.Strings.TestRowButtonCaption"},
		"visible": true,
		"tag": "call"
	}
}

И потом переопределить метод onActiveRowAction:

onActiveRowAction: function(buttonTag, primaryColumnValue) {
	switch (buttonTag) {
		// замещение базового метода посылаем сообщение основной странице
		case "call":
			this.sandbox.publish("GetContactDetailActiveRecordId", this.get("TestParameter"),       [this.sandbox.id]);
			break;
		default:
			this.callParent(arguments);
			break;
	}
},

Который объявлен в BaseSectionV2 (Базовая схема раздела).

Проблема:
1) при объявлении кнопки выходит сообщение, что DataGrid не является контейнером для других объектов. Подскажите, что делаю не так?

2) Как отловить в основной форме, что пришло сообщение из детали?
За ранее спасибо.

Добрый день!

Для получения идентификатора текущей записи детали в родительской карточке редактирования используя механизм подписки/публикации сообщений между соответствующими модулями - алгоритм будет примерно следующий:

Для начала необходимо в коде карточки и детали добавить адресное сообщение с одним и тем же названием, но в карточке с типом "Подписка", а в детали - с типом "Публикация". Например, для карточки редактирования:

messages: {
"GetContactDetailActiveRecordId": {
mode: Terrasoft.MessageMode.PTP,
direction: Terrasoft.MessageDirectionType.SUBSCRIBE
}
}

Для детали точно так же, только в свойстве direction необходимо указать Terrasoft.MessageDirectionType.PUBLISH.

Далее при инициализации карточки редактирования (метод init) нужно подписаться на это сообщение, а в функции обратного вызова получить значение из детали и сохранить его в атрибут модели карточки:

init: function() {
this.callParent(arguments);
this.sandbox.subscribe("GetContactDetailActiveRecordId", function(recordId) {
this.set("ContactDetailActiveRecordId", recordId);
}, this, [contactDetailSandboxId]);
}

Значение contactDetailSandboxId Вам необходимо определить самостоятельно (оно формируется в зависимости от названия детали). В коде детали оно хранится в свойстве this.sandbox.id.

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

onButtonClick: function() {
this.sandbox.publish("GetContactDetailActiveRecordId", this.get("ActiveRow"), [this.sandbox.id]);
}

Здравствуйте, Олег.
Да, все получилось именно так, спасибо.

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

Подскажите, как передать сообщение не по кнопке, а при выборе записи в DataGrid?

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

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

"Демьяник Алексей Олегович" написал: В случае выбора записи в DataGrid, сообщение будет генерироваться при выборе любой записи в любом гриде, что замедлит работоспособность системы.

Здравствуйте, Алексей.
Хорошо. Понял. Подскажите а можно кнопку в DataGrid встроить? И как?

Добрый день!

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

Здравствуйте, Олег. Я так реализовал уже. Но это не совсем удобно. Подскажите как встроить кнопку в датагрид? В предыдущих версиях можно было. В крайнем случае, если нельзя, как кнопку в детали выделить? Другим цветом например?

Олег, добрый день!

Попробуйте следующий вариант реализации:

в скрипте детали в блок diff добавить дополнительные свойства для DataGrid (название и заголовок кнопки привожу в качестве примера, Вы можете изменить их на свои):

{
	"operation": "merge",
	"name": "DataGrid",
	"values": {
		"activeRowAction": {"bindTo": "onActiveRowAction"},
		"activeRowActions": [
			{
				"className": "Terrasoft.Button",
				"style": this.Terrasoft.controls.ButtonEnums.style.BLUE,
				"markerValue": "myButtonAction",
				"tag": "myAction",
				"caption": "MyButton"
			}
		]
	}
}

После этого при выделении активной строки в детали должна появиться синяя кнопка с заголовком MyButton.

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

Далее в методах той же детали необходимо реализовать метод onActiveRowAction. Данный метод в качестве аргументов принимает тэг кнопки и значение ключевой колонки выделенной строки. Насколько я понял из предыдущих сообщений, Вам этой информации достаточно, но если необходимо получить какие-либо другие значения выделенной строки, можно вызвать метод this.getActiveRow(), который возвращает всю модель выделенной строки:

methods: {
	onActiveRowAction: function(buttonTag, primaryColumnValue) {
		if (buttonTag === "myAction") {
			// весь код ниже можно убрать, он демонстрирует, что значения
			// primaryColumnValue и activeRowId равны
			var activeRow = this.getActiveRow();
			var activeRowId = activeRow.get("Id");
			console.log(primaryColumnValue);
			console.log(activeRowId);
			// дальше Ваша реализация
			...
		}
	},
	...
}

Здравствуйте, Олег.
Спасибо. Получилось то, что нужно. Скрин во вложении.

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

Добрый день!

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

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

Нравится

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

Добрый день, Николай! По структуре данных всё осталось как и раньше: в объекте находятся оба поля: и Контрагент, и Контакт. А вот на странице используется специальный контрол. Вся логика прописана в схеме страницы. Можете взять за пример счет или заказ и скопировать в любую нужную вам сущность.

Юлия, спасибо! Буду пробовать.

Николай, необходимо сделать следующее:
- Добавить аттрибут Client с колонками Contact, Account (можно посмотреть в InvoicePageV2)
- В diff добавить поле Клиент и скрыть поля Account и Contact
- Настроить правила фильтрации (несколько полей в договорах вроде по Account фильтруются)

Еще раз спасибо за информацию - все получилось.
Но, столкнулся с одним нюансом. При выборе в поле Client записи из таблицы Contact, у которой в свою очередь проинициализировано поле Account, происходит заполнение поля Account в договоре, но согласно нашей бизнес-логике, такого не должно происходить.
Как я понимаю, это "дело рук" одного из унаследованных бизнес-правил. В связи с этим вопрос - как правильно отключать унаследованные бизнес-правила?
Пока вышел из ситуации переопределением данного бизнес-правила:

"Contact": {
  "FiltrationContactByAccount": {
    "ruleType": BusinessRuleModule.enums.RuleType.FILTRATION,
    "autocomplete": false,
    "autoClean": false,
    "baseAttributePatch": "Account",
    "comparisonType": this.Terrasoft.ComparisonType.EQUAL,
    "type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
    "attribute": "Account"
  }
}

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

Вам необходимо заместить базовое правило его переопределением.

Хм... оказалось, не все так просто...
При вводе текста непосредственно в данное поле, происходит поиск по контрагентам и контактам - тут все ОК. Но, при попытке открыть окно выбора (при нажатии кнопки с лупой) на экране появляется пустое окно без контролов, а в консоле браузера наблюдается следующее сообщение об ошибке:

message: Cannot read property 'split' of undefined 
 date: Tue Dec 15 2015 23:53:11 GMT+1000 (VLAT)
 moduleId: SectionModuleV2_ContractSectionV2_CardModuleV2_chain00000000-0000-0000-0000-000000000000_LookupPage
 moduleName: LookupPage

Я так понимаю, где-то нужно указать правильный LookupPage. Вопрос - где?

Хм... оказалось, не все так просто...
При вводе текста непосредственно в данное поле, происходит поиск по контрагентам и контактам - тут все ОК. Но, при попытке открыть окно выбора (при нажатии кнопки с лупой) на экране появляется пустое окно без контролов, а в консоле браузера наблюдается следующее сообщение об ошибке:

message: Cannot read property 'split' of undefined 
 date: Tue Dec 15 2015 23:53:11 GMT+1000 (VLAT)
 moduleId: SectionModuleV2_ContractSectionV2_CardModuleV2_chain00000000-0000-0000-0000-000000000000_LookupPage
 moduleName: LookupPage

Я так понимаю, где-то нужно указать правильный LookupPage. Вопрос - где?

Проверил данный способ как на Документах, так и на Договорах. Опишу по пунктам действия:

1. Мастером раздела добавил любое существующее поле, что бы система создала замещающую схему страницы. Что не обязательно, если у вас уже есть в пользовательском пакете замещающая схема для страницы.

2. Убедился что в объекте есть колонки как "Контакт" так и "Контрагент".

3. Добавил зависимость на бизнес правила:

define('ContractPageV2', ['ContractPageV2Resources', 'GeneralDetails', "BusinessRuleModule"],
function(resources, GeneralDetails, BusinessRuleModule) {

4. Добавил атрибут:

attributes: {
   "Client": {
	"caption": "TestClient",
	"dataValueType": this.Terrasoft.DataValueType.LOOKUP,
	"multiLookupColumns": ["Contact", "Account"],
	"isRequired": false
   }
},

5. Вывел поле на форму:

diff: /**SCHEMA_DIFF*/[
	{
		"operation": "insert",
		"parentName": "Header",
		"propertyName": "items",
		"name": "Client",
		"values": {
			"layout": {"column": 0, "row": 3, "colSpan": 12},
			"controlConfig": {
				"enableLeftIcon": true,
				"leftIconConfig": {"bindTo": "getMultiLookupIconConfig"}
			}
		}
	}
]/**SCHEMA_DIFF*/,

6. Добавил правило:

rules: {
	"Contact": {
		"FiltrationContactByAccount": {
			"ruleType": BusinessRuleModule.enums.RuleType.FILTRATION,
			"autocomplete": false,
			"autoClean": false,
			"baseAttributePatch": "Account",
			"comparisonType": this.Terrasoft.ComparisonType.EQUAL,
			"type": BusinessRuleModule.enums.ValueType.ATTRIBUTE,
			"attribute": "Account"
		}
	}
},

7. В расчет не беру того факта что поле "Контрагент" по умолчанию обязательное к заполнению в договоре, но отключить это условие, не должно составить проблем, если то позволяет ваша бизнес логика.

Как итог, все работает:

Возможно причина ошибки в дополнительных действиях. Логика же добавления мультиполя верна.
Версия: 7.7.0.2161
Полный код схемы: https://jsfiddle.net/4x35pknd/

Причину ошибки удалось установить совместными усилиями с техподдержкой.
Дело оказалось в том, что пакете SalesContracts переопределен метод loadVocabulary, из-за этой подмены, карточка не открывалась. Нужно было вернуть методу исходный вид из карточки BasePageV2 и проблема ушла.
На всякий случай, вдруг кому-то еще пригодится, вот этот фрагмент кода:

methods: {
  loadVocabulary: function(args, columnName) {
    var multiLookupColumns = this.getMultiLookupColumns(columnName);
    var config = (Ext.isEmpty(multiLookupColumns))
      ? this.getLookupPageConfig(args, columnName)
	: this.getMultiLookupPageConfig(args, columnName);
    this.openLookup(config, this.onLookupResult, this);
  }
}
Показать все комментарии

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

На википедии написано:
Bpm'online has been developed using Microsoft .Net architecture in combination with AJAX and HTML. Combined with RESTful APIs, it provides developers with a well-constructed SaaS architecture.

Есть ли где-нибудь задокументированный REST API? Всё, что я смог с большим трудом найти, это вот эта страница:
http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/RequestAuth...

Нравится

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

Здравствуйте!
Система поддерживает интеграцию через Odata.
Детальнее можно прочитать тут: http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/Integratio…
Это в той же ветке, что и ваша ссылка. Вот ссылка на корень ветки, посвященной интеграциям: http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/Integratio…

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

Не поверите :) Сейчас как раз в процессе перевода на новый движок. Планируем за 1,5-2 мес обновиться. Так что релиз 7.8 будет с новой Академией.

Кстати, если есть еще пожелания по Академии - тут их тоже можно писать.

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

Актальная документация доступна по ссылке https://academy.terrasoft.ru/documents/technic-sdk/7-12/integraciya-s-s…

Из этой документации абсолютно непонятно каким образом делать добавление заказа? какой использовать SchemaRoot? Какие поля передавать? Хотелось бы получить ответы на эти вопросы.

Это не «документация по добавлению заказа», а информация для разработчиков по разработке интеграции с другими системами. Названия таблиц и их полей можно увидеть в разделе «Конфигурация», открыв нужную схему. Заказы хранятся в таблице «Order».

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

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

Доброго дня суток.
Начал учится делать бизнес правила.
Нашел неплохую статью:
http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/AddFiltrati...

Но как применить в моем варианте я не понял.
Опишу ситуацию.
Есть на Продаже два поля(справочника)
1. Заявка("Requests")
2. Заявка в банк("zajavkabank")

В справочнике Заявка в банк есть два поля(справочника)
1a. Заявка("Requests")
2a. Контрагент("Account")

Надо сделать вот такую фильтрацию:
Доступны для выбора пользователем только те заявка в банк, у которых 1a. Заявка("Requests") равно 1. Заявка("Requests")

Нравится

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

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

Илюстрация наполнения справочника "Заявка в банк":

Вот код бизнес правила:

Код отвечающий за элемент "Заявка в банк":

Код отвечающий за элемент "Заявка":

Подключение модуля отвечающего за бизнес правила (без него бизнес правила не заработают):

Результат:

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

Спасибо большое!

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

Доброго времени суток!
Делаю кастомный класс(ничего не замещает).
Есть вопросы:
1. Как вызвать его из Js?
Я так понимаю что вот так:

var substituteObject = ClassFactory.GetMyClass>();

верно?
2. Как сделать выборку и получить данные из БД в сдк описано, а вот как вставить новую запись?

Нравится

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

Создал такой класс:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using Terrasoft.Common;
using Terrasoft.Core;
using Terrasoft.Core.DB;
using Terrasoft.Core.Entities; 
public class ConvertPropertyToListing
{
	public ConvertPropertyToListing(String a)
	{
 
	}
	public ConvertPropertyToListing()
	{
 
	}	
	public String Response()
	{
		return "Abrakadabra";
	}
}

на кнопку в схеме повесил вот такой код:

			showInfo: function() {			
							var substituteObject = ClassFactory.Get<ConvertPropertyToListing>();
							this.showInformationDialog(substituteObject.Response());
			        }	

В итоге js выдает ошибку:
Метка времени: 09.12.2015 13:42:24
Ошибка: SyntaxError: expected expression, got ')'
Источник: https://ipotekansk-test.bpmonline.com/0/configuration/b2db0922da8d4c427…
Строка 856, символ 73
Исходный код:

var substituteObject = ClassFactory.Get<ConvertPropertyToListing>();

Что не так?

Как минимум, впервые слышу про ClassFactory в контексте js кода.
Если вы хотите что бы по какому-то событию на страничке выполнялся именно c# (серверный) код, а судя по тому что вы спрашиваете в своем втором вопросе, вам нужен именно серверный код. Т.к. создать новые объекты в БД, можно только в контексте сервера. Вам нужно использовать бизнес-процессы. И в них уже писать свой c# код.
Подробнее про бизнес-процессы:
http://www.academy.terrasoft.ru/documents/?product=BPMS&ver=7.6.0

О том как потом вызвать БП из кода, было не мало тем на форуме, к примеру:
http://www.community.terrasoft.ru/forum/topic/10554#comment-47944
http://www.community.terrasoft.ru/forum/topic/13848

Еще раз кратко ответ на ваши 2 вопроса:
1. Через вызов БП.
2. Только на уровне c# кода, c помощью:
http://academy.terrasoft.ua/documents/docs/technic/SDK/7.4.0/Terrasoft…

P.S.
Примеры использования Insert можно посмотреть в исходных кодах схем с кодом на c#, либо выгрузив все доступные исходные коды, если вы on-site, с помощью:
http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/ServerCode…

В общем случае код Insert'а будет выглядеть примерно так:

Insert insertRelationshipQuery = new Insert(UserConnection);
    insertRelationshipQuery.Into("Relationship");
    insertRelationshipQuery.Set("Active", Column.Parameter(true));
    insertRelationshipQuery.Set("AccountBId", Column.Parameter(accountId));
    insertRelationshipQuery.Set("RelationTypeId", Column.Parameter(relationTypeId));
    insertRelationshipQuery.Set("AccountAId", Column.Parameter(parentId));
    insertRelationshipQuery.Set("ReverseRelationTypeId", Column.Parameter(reverseRelationTypeId));
insertRelationshipQuery.Execute(executor);

Я что то не нашел как из БП вызвать c# код...
Как это сделать?

Это есть в академии, в том разделе что указан выше, а именно, произвольный c# код, на странице:
http://academy.terrasoft.ua/documents/docs/technic/BPMS/7.6.0/BPMonline…
Так же видео:
http://www.community.terrasoft.ru/usr/video/10684
Видео немного устаревшее, но суть должно дополнить, к тому, что написано в академии.

Просмотрел данное видео.
Вопросы:
1. Это c# или таки js?
2. Можно ли оттуда вызвать свой класс созданный в конфигурации?
3. Как получить значение параметра пришедшего в БП?
4. Мне к примеру надо будет сделать выборку по RecordId(параметр), потом создать новую запись, и сообщить юзеру результат. Как это сделать?

Я понимаю что задаю много тупых вопросов, но найти нужную мне информацию в документации иногда не возможно.

К чему я это все спрашиваю. Есть у меня задача, надо написать job, который будет собирать все листинги по определенному параметру, сформировать xml и отправить на удалённый сервер. Это вообще возможно?

1. С#, там же даже на иконке элемента написано "C#".

2. Можно, только объявите его в Usings секции процесса. Старайтесь смотреть на уже созданные БП, и как там все это реализовано.

3. Просто по имени. Если вы создали в секции parameters, параметр с именем, к примеру TestParameter и типом строка. То так по коду к нему и обращайтесь "TestParameter"
К примеру, генерация события сообщения, с значением этой строки:
Terrasoft.Configuration.MsgChannelUtilities.PostMessage(UserConnection, "MyProcess", TestParameter);

4.a. Выборка данных решается применением EntitySchemaQuery http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/UsingEntit…

4.b. Сообщение пользователю из бп можно сделать предварительно сделав подписку в определенной схеме, которая будет открыта у пользователя в момент выполнения БП. К примеру, собственно, в схеме от куда этот БП и будет у вас запускаться. Данный вопрос рассматривался тут:
http://www.community.terrasoft.ru/forum/topic/11784

Так же обратите внимание на статью, в ней описан процесс вызова БП с параметрами из схемы:
http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/ExecutePro…

Вы отредактировали свой комментарий добавив еще один вопрос, и да, это c# код, и веб приложение. Конечно вы сможете формировать файл и дернуть апи своего удаленного сервера если он это позволяет. Но эти вопросы уже не касаются bpmonline.

"Щиголь Максим" написал:2. Можно, только объявите его в Usings секции процесса. Старайтесь смотреть на уже созданные БП, и как там все это реализовано.

Не совсем понял как его вызвать... БУду благодарен если вы дадите пример как из скрипт-сценария создать экземпляр моего класса.

Вызов экземпляра класса я уже показывал тут:
http://www.community.terrasoft.ua/forum/topic/14174#comment-57144
Объявление немспейса в Usings секции, нужно только если вы хотите обращаться к имени класса без приставки немспейса по коду.
К примеру, если писать полное обращение, вроде
var myClass = new MyNamespace.MyClass();
то выносить "MyNamespace" не нужно.

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

Доброго времени суток!
Делаю БП где из своего кастомного объекта создается Листинг.

Есть в нашем объекте поле Номер квартиры.
А в листинге данное поле доступно из детали параметры. И при маппинге отсутствует.
Вопрос как его замапить?

Нравится

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

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

Дело в том, что параметры листинга хранятся в другом объекте (параметр листинга или как-то так), а не в листинге:) Собственно нужно добавлять в этот объект, указав в поле "Листинг" Id листинга.

Уже хорошо.
Что какой объект за это отвечает?
Тоесть будет так: Читаем данные, добавляем листинг, добавляем параметры?

Добрый день!

1. Объект - Значение параметра объекта или листинга/ AmenityInObject
2. Подход к решению верный.

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

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

Нравится

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

В Лабитеке решали такой вопрос. Можете попробовать связаться с ними.

Интересуют непосредственно варианты перевода справочников:)

Специально такое разрабатывать сейчас, скорее всего, никто не будет. Спросите у них.

Да никто не просит.
Я и спрошу, и разработаю:)
Вопрос был к тем, у кого был опыт и идеи для дальнейшей дискуссии по интересам.

По справочникам (правда, в другом продукте) делали дополнительную таблицу
-ObjectId
-RecordId
-LanguageId
-Name

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

Соответственно, в каждом справочнике деталь с языками и названиями

Ещё, говорят, были мысли о китайской локализации. Но вовремя одумались, осознав масштаб работ.

Владимир, аналогично себе это и представлял, вплоть до View.
Проект интересный, по результатам, либо возникающим вопросам - отпишусь:)

"Нестеров Артем Валерьевич" написал:Проект интересный, по результатам, либо возникающим вопросам - отпишусь:)

Проект интересный и очень объемный, так что можно блог писать :D

а в bpm'online 7 такой вопрос кто-то решал?

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

Владимир, мультиязычие пока что не предусмотрено. Данная задача будет реализована в версии 7.8.0.

"Демьяник Алексей Олегович" написал:Данная задача будет реализована в версии 7.8.0.

Какая отличная новость для нашего мулти-язычного региона!

Работа кипит.
Нужна функция, которая собирает все названия датасетов окна в массив.

Такой функции, скорее всего, нет. Можете её написать.
Можно по аналогии с функцией GetControlByDataFieldName из scr_DB, только в цикле искать не визуальные компоненты, а даталинки.

function IsDataControl(Control) {
	var DatasetLink = Control.DatasetLink;
	var DataFieldName = Control.DataFieldName;
	return ((DatasetLink != undefined) && (DataFieldName != undefined));
}
 
function GetControlByDataFieldName(Window, DataFieldName) {
	for (var i = 0; i < Window.ComponentCount; i++) {
		Component = Window.Components(i);
		if (IsDataControl(Component)) {			
			if (Component.DataFieldName == DataFieldName) {
				return Component;
			}
		}
	}
	return null;
}

Так как лучше сделать вывод перевода справочников?
Создан один большой общий глобальный справочник для джоина на него остальных -
ID (ид записи)
ItemID (ид записи присоединяемого справочника)
LanguageID (язык перевода)
Name - (Собственно сама строка перевода)

Тут всё понятно, без проблем.
А вот как сделать вывод перевода из этого справочника в необходимом окне, при этом и при этом не потерять стандартный функционал для заполнения - вопрос.
На текущий момент решение (но мне не очень нравится):
1.Джоиним каждый справочник на справочик переводов
2.В каждом переводимом справочнике создаём колоночку(TName, для того, чтобы не убивать стандартный Name из функционала заполнения. Эта колонка нужна для того, чтобы была возможность заджоинить сам справочник на необходимое окошко и подогнать в неё данные selectquery по параметрам джоина)
3.Используем данные из этой колоночки в сервисе окна

Можете несколько месяцев подождать и сделать структуру базы аналогично 7.8.

Готового решения нет, пробуйте сами разные варианты. Ещё можно для каждого языка создать view с одинаковым набором полей, ведущую себя как обычная таблица справочника. И подставлять одну из этих view. При добавлении данных в справочник триггер пишет в таблицу справочника и в общий справочник перевода. Если значение в справочнике есть, но нет локализоции на нужный язык — подставлять на базовом языке из таблицы. При попытке его редактировать — создавать новое значение в справочнике перевода и далее показывать его.

"Можете несколько месяцев подождать и сделать структуру базы аналогично 7.8."
Только здесь и сейчас :-D
Ок, значит будем первооткрывателями.

Как можно реализовать подмену данных Name в справочнике?
Если банально в справочнике писать SQL Text column(с идентичным запросом) вместо обычного типа Name, то террасофт вываливается с ошибкой OLE Error, хотя в SQL студии всё работает корректно.
Более того, данные в Lookup Data Control всё равно тянутся из первичной колонки для отображения, не с SQL запроса в подмене Name.

Можете сделать справочник по view вместо таблицы.

И что нам это даст?
У меня проблема сейчас в том, что я подменил выбор поля Name в справочнике текстом запроса.
При открытии самого справочника - всё хорошо и корректно данные подтягиваются, а вот при попытке вывалить список LookupDataControl - валится ошибка, непонятно с чего.

Почему, если скажем в tbl_Dictionary выбирать Name как обычной колонкой в сервисе, то все лукапдатаконтролы прогружаются нормально, а если написать выбор Name как SQL Text column [tbl_Dictionary].[Name], то в самом справочнике прогружается нормально, а вот при загрузке контроллов спровочника в других окнах всё валится с ошибкой?

Ну, значит так нельзя делать. Пробуйте другим способом. Возможно, получится с колонкой подзапроса или ещё как-то.

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

С колонкой подзапроса аналогично

В таком случае ищите другие способы. Штатно никто такое со справочниками не делал.

Господа из ТС ничего не ответят по данному вопросу?

Платформа 3.Х уже несколько лет не развивается, так что маловероятно, что господа из ТС будут что-то глобально переделывать в ядре под такое специфическое использование.

Мне фактического подтверждения ошибки и объяснения процесса было бы предостаточно.

Это не ошибка, в системе Terrasoft 3.X не предусматривалось использование нескольких языков в справочниках. Это уже Ваши разработки.

Сами же говорили, что:

Знаю, что не предусмотрено, знаю что много и долго, но...

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