добрый день!

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

я сделала событийный подпроцесс на inserting, выглядит он следующим образом

int size = Entity.GetTypedColumnValue("Size");

if (size > 1048576)

    throw new Exception("Размер вложенного файла превышает 1 Мб");

return true;

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



 как сделать так, чтобы пользователь видел текст ошибки из кода ?

может есть иные способы накладывания ограничений на размер файла?

Нравится

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

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

сделала следующее:

заместила filedetail, отловила ошибку в xhr в методе onFileComplete  и сделала свою обработку. 

можно ограничить средствами самого веб-сервера.

в файле конфигурации приложения

Terrasoft.WebApp\Web.config

смотрите ноду 

<requestLimits maxAllowedContentLength="104857600" />

это лимит для загружаемых на сервер данных в байтах

Севостьянов Илья Сергеевич пишет:

можно ограничить средствами самого веб-сервера.

спасибо.

правильно понимаю, что это ограничение на все загружаемые файлы? если ограничения разные для разных разделов( для контрагентов-1мб, для обращений -10мб и тд), то этот метод не подойдет? 

 

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

Здравствуйте. Столкнулся с проблемой получения дополнительных данных.

Например, создал активность в мобильном приложении, указав контрагента. На карточке просмотра активности есть необходимость скрывать некоторые поля, в зависимости от типа контрагента. Но на карточку просмотра активности о контрагенте загрузилась минимальная информация в виде Id и Name, а мне необходимо ещё значение Type.

Пробовал решить двумя способами.

В первом добавил бизнес правило на событие загрузки записи и внутри метода обработчика сделал следующий вызов:

var modelName = "Account";
var model = Ext.ClassManager.get(modelName);
 
var queryConfig = Ext.create("Terrasoft.QueryConfig", {
    modelName: modelName,
    columns: ["Id", "Name", "Type"]
});
 
model.load(account.get("Id"), {
    queryConfig: queryConfig,
    success: function(record) {
     // ???
    },
    failure: function(record, operation) {
        // ???
    },
    scope: this
});

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

Ext.callback(callbackConfig.success, callbackConfig.scope, [true]);

Вторым способом заместил View и Controller и в Controller-классе в методе onLoadRecord попытался вызвать безрезультатно Account.Store.getById.

Хотя, при прочих равных в файле PharmaMobileActionScheduleVisit пакета PharmaMobile аналогичная строка с "волшебным" Store работает.

var type = ActivityType.Store.getById(Terrasoft.Configuration.ActivityTypes.Visit);

Может код из первого варинта поместить в замещенный onLoadRecord? Или есть другие варианты? Прошу помощи в решении задачи.

Нравится

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

Отвечу сам на вопрос решением. Оно оказалось простым.

При добавлении custom-правила вызовом 

Terrasoft.sdk.Model.addBusinessRule

(функция executeFn), в месте возврата данных model.load (success) необходимо вставить Ext.callback. Полным решение выглядит примерно следующим образом:

var modelName = "Account";
var model = Ext.ClassManager.get(modelName);
 
var queryConfig = Ext.create("Terrasoft.QueryConfig", {
	modelName: modelName,
	columns: ["Id", "Name", "Type"]
});
 
var failureFn = function(exception) {
	Ext.callback(callbackConfig.failure, callbackConfig.scope, [exception]);
};
 
model.load(account.get("Id"), {
	queryConfig: queryConfig,
	success: function(rec) {
 
		var type = rec.get("Type");
 
		record.changeProperty("FIELD-NAME", {
			hidden: type === "TYPE-VALUE"
		});
 
		Ext.callback(callbackConfig.success, callbackConfig.scope, [true]);
	},
	failure: failureFn,
	scope: this
});

Также, для загрузки данных, вместо model.load можно использовать и другую функцию

Terrasoft.DataUtils.loadRecords

 

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

Добрый день.

При выполнении установки пакета из приложения постоянно выпадает ошибка: "Не удалось загрузить файл на сервер". Подозреваю, что отсутствует какая-то настройка или в Web.config или в системных настройках самой базы. Подскажите чего не хватает?

Нравится

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

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

Проверьте в ConnectionStrings.config параметр  

<add name="tempDirectoryPath" connectionString="%TEMP%\%APPLICATION%\%WORKSPACE%\" />

Там должен быть указан корректный путь.

 

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

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

Путь в лоб 

attributes: {
			"CreatedOffer": {
				dataValueType: Terrasoft.DataValueType.LOOKUP,
				type: Terrasoft.ViewModelColumnType.CALCULATED_COLUMN,
				caption: "Коммерческое предложение",
				referenceSchemaName: "UsrDocument"
			},

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

Нравится

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

а что есть у Вас "разные типы документов" - 

это разные страницы для одного и того же раздела или это разные объекты в принципе ?

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

Рискну предположить что такое поведение обуславливается наличием дополнительной записи в SysModuleEdit нескольких записей для одного Entity

 

Разные страницы, конечно. Там где разные объекты, нет вопросов. У меня не кнопка. У меня LOOKUP, который не доступен для редактирования, по сути, ссылка. И ссылка формируется системой неправильно.

Вопрос снят. Если кому интересно, сделал так. Добавил UsrType.

scope.set("CreatedOffer",
{
	value: item.get("Id"),
	displayValue: item.get("UsrNumber"),
	UsrType: {value: "e76200fd-6a52-4b54-b8d2-a2f1454a3a36"}
});

 

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

В версии приложения 7.10 появилась возможность устанавливать пакеты оформленные в архивы (zip/gz) 

Вопрос:

А как в этот формат отдельно взятый пакет оформить ?

Нравится

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

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

Инструкция:

1) Перейти в конфигурацию

2) Выделить необходимый пакет

3) Правой кнопкой мыши вызвать контекстное меню

4) Выбрать "Выгрузить пакет".

7.10.0.1742

такой пункт в контекстном меню отсутствует

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

н/п настроить приложение для разработки в файловой системе ?

а если это cloud ?

вообщем не понятно.

Этот пункт появился только в 7.10.2. В 7.10.0 это точно не возможно.

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

Есть в БП автогенерируемая страница, за которой идет завершение. 

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

Нравится

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

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

Добавьте рекомендации на странице, что ожидается от пользователя на этом этапе.

нажал закрыть или закрыл окно

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

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

Как вариант решения кейса - заменить автогенерируемую страницу - преднастроенной.

Зарицкий Олег,

Значит в этой базовой схеме "баг" - ее логика не правильная. Как разработчику ее исправить? Или как построить БП, так чтобы обойти этот момент?

Может, как-то можно поймать сигнал, что БП показал страницу? И по этому сигналу завершить БП?

Владимир Соколов,

можно перед автогенерируемой страницей параллельную пустить ветку с таймером в 1 минуту.

Вне зависимости от того, что пользователь выберет на странице (и выберет ли что-то вообще), процесс будет завершен.

Севостьянов Илья Сергеевич пишет:

Как вариант решения кейса - заменить автогенерируемую страницу - преднастроенной.

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

1) Преднастроеная страница - сразу после открытия, элемент считается выполненным и БП двигается дальше

2) Страница редактирования - присутствует специальная настройка

можно задать условие - всегда выполняющееся.

БП - двинется дальше после любого пользовательского действия с карточкой: "Сохранить" / "Закрыть" / "Отмена"

Как-то так...



У Вас кейс какой: Вам необходимо чтобы пользователь что-то сделал, и только потом БП продолжился, или вне зависимости от этого ?

Демьяник Алексей пишет:

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

А если этот пользователь сейчас не в системе? И когда он появится в системе, то БП уже завершится, и он не увидит страницу 

Демьяник Алексей,Спасибо!

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

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

Однако, в детали просто не получается сделать добавление неактивным. Вот такой код вызывается (проверено в отладчике), но не приводит ни к какому результату. Как правильно?

define("AccountAddressDetailV2", [], function() {
	return {
		entitySchemaName: "AccountAddress",
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
		methods: {
			getEditPages: function() {
				var menuItems = this.callParent(arguments);
				for (var i = 0; i < menuItems.collection.items.length; i++) {
					menuItems.collection.items[i].values.Enabled = false;
//						{bindTo: "AddressNotExists_" + menuItems.collection.items[i].values.Tag};
				}
				return menuItems;
			}
		}
	};
});



 

Нравится

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

деталь AccountAddressDetailV2 вероятнее всего является наследником базовой AccountCommunicationDetail или является отдельной ее имплементацией.

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

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

Приведу пример замещающей схемы которая решает кейс:

Ограничить возможность добавления более 1-го пункта с типом "Основной телефон"

define("AccountCommunicationDetail", [], function() {
	return {
		methods: {
			//Далее в коментариях, "элемент детали" это отдельно взятая запись в коллекции детали,
			//т.е. одно отдельное средство связи в детали.
			"init": function() {
				this.callParent(arguments);
				//Подписка на изменение атрибута-флага, который принимает значение в true после полной загрузки данных
				//Установим метод-обработчик см.листинг-метку TAG1
				this.on(
					"change:IsDataLoaded",
					function() {
						if (arguments[1] === true) {
							this.mainPhoneInSubMenuExistsController();
						}
					},
					this
				);
			},
			//метод вызываемый при реализации действия "Добавить" или "Изменить" элемент детали
			"createOrUpdateCommunicationItem": function(typeId, config) {
				this.callParent(arguments);
				this.mainPhoneInSubMenuExistsController();
			},
			//метод вызываемый при реализации действия "Удалить" элемент детали
			"deleteCommunicationItem": function() {
				this.callParent(arguments);
				this.mainPhoneInSubMenuExistsController();
			},
			//метод формирующий список элементов для viewModel контекствного меню отдельного элемента детали
			//вызывается единожды при инициализации детали
			"getTypeMenuItems": function() {
				//получим список сформированный родительским методом
				var typeMenuItems = this.callParent(arguments);
 
				//ДЛЯ КАЖДОГО: элемента меню
				for (var each in typeMenuItems) {
					//ЕСЛИ: заголовок элемента "Основной телефон"
					if (typeMenuItems[each].caption === "Основной телефон") {
						//ТО: Удаляем соответствующий элемент из массива
						typeMenuItems.splice(each, 1);
						//Прерываем перебор массива
						break;
					}
				}
 
				//возвращаем модифицированное меню
				return typeMenuItems;
			},
			//TAG1
			//Метод осуществляющий контроль пункта подменю: "+" -&gt; "Телефон" -&gt; "Основной телефон"
			//Основополагающая логика: пункт не должен быть доступен если запись с типом "Основной телефон"
			//присутствует в детали (в т.ч. состоянии view), и становиться доступным при его удалении (в т.ч. состоянии view)
			"mainPhoneInSubMenuExistsController": function() {
				//Получим коллекцию ранее внесенных в деталь средств связи
				var existsCommunicationsCollection = this.get("Collection"),
					//Получим коллекцию сформированных элементов меню
					MenuItemsCollection = this.get("ToolsMenuItems");
 
				//Определим флаг наличия в ранее внесенных средствах связи, средства с типом "Основной телефон"
				var    mainPhoneNumberExistsFlag = existsCommunicationsCollection.collection.find(function(item) {
						var targetCollection = item.values ? item.values : item.changedValues;
						if (targetCollection.CommunicationType.displayValue === "Основной телефон") {
							return true;
						}
					}, this) ? true : false;
				//Определим объект элемента меню "Телефон"
				var    phoneMenuCollection = MenuItemsCollection.collection.find(function(item) {
						if (item.values.Caption === "Телефон") {
							return true;
						}
					}, this);
 
				if (mainPhoneNumberExistsFlag) {
					//Найдем в его коллекции элементов подменю пункт с заголовком "Основной телефон"
					var mainPhoneMenuItem = phoneMenuCollection.values.Items.collection.find(function(item) {
						if (item.values.Caption === "Основной телефон") {
							return true;
						}
					}, this);
					//попытка выполняется в блоке try...catch т.к. в некоторых случаях вызов
					//метода remove приводит к ошибке исполнения JS которая не влияет на результат
					//выполнения метода относительно коллекции, тем не менее прерывает выполнение здесь.
					//Проявляется при добавлении единственной записи в деталь в новой карточке контрагента
					//через поле в карточке, а не через меню детали
					try {
						//Удалим этот пункт меню из колекции подпунктов viewModel
						phoneMenuCollection.values.Items.collection.remove(mainPhoneMenuItem);
					} catch (e) {}
					//инициируем перестроение viewModel по его измененной модели
					MenuItemsCollection.loadAll();
				} else {
					//Вернем этот пункт в меню
					//выполнив новое построение колекции пунктов меню для viewModel
					this.initToolsMenuItems();
				}
			}
		}
	};
});

далее 

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

Коллеги, добрый день! Пишу скорее от отчаяния :( В 10.2 нами была выявлены две фундаментальные проблемы:

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

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

В результате какие-либо изменения существующих процессов становятся практически невозможными. Мысли?

Нравится

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

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

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

Ваше заявление некорректно. Данное поведение в базовой вопроизводится, но в случае если базовая стандартными средствами обновлена с 10.1 на 10.2. Я не проверял (если надо могу) на это выглядит на 10.1,  но здесь присутствующие коллеги, которые еще на 10.1 работают легко подтвердят гипотезу. 

UPD. Проверил на клиентской 10.1 - воспроизводлится на ура:

1) Значение, присвоенное по умолчанию параметру элемента процесса можно истребить только вместе с элементом процесса.

2) Значение присвоенное по умолчанию параметру процесса можно истребить только с этим параметром

3) про "Отправить e-mail" вы и без меня все знаете!

Таким образом мы имеем неслабый косяк в 10.1 который при обновлении переехал и в 10.2.

Добрый день!

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

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

Кейс будет исправлен в 7.11.0.

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

При изменении бизнес-процесса накопилось большое количество версий. При попытке удаления версии процесса через конфигуратор система предлагает "Удалить все версии схемы и объекты процесса, запущенные ими". Как удалить только определенные версии процесса, а не весь процесс целиком?

Нравится

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

Да, и можно для процесса запомнить, что я никогда не хочу создавать его новые версии?

Здравствуйте, Александр.



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

 

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

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

Версия 7.10.

На странице списка Активностей есть такой фильтр:

Изображение удалено.

Как я понял, параметры фильтра задаются внутри функции initFixedFiltersConfig, в схеме ActivitySectionV2.

1. Я правильно понимаю, что фильтрация ведётся по детали Участники события?

2. Можно ли как-нибудь отменить множественный выбор по этому фильтру? Хотелось бы чтобы одномоментно показывался только один сотрудник.

3. Вообще, где генерится этот фильтр? Можно ли добавить свои пункты в меню?

Нравится

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

Здравствуйте, это фиксированные фильтры, а следовательно они сделаны по инструкции: https://academy.terrasoft.ru/documents/technic-sdk/7-10/dobavlenie-v-razdel-bloka-bystryh-filtrov



Почитайте код метода initFixedFiltersConfig в активити секции пакета NUI, там увидите код фильтров и по каким колонкам он фильтрует.



Что касается пунктов меню, они для Овнер фильтра запрограммированы в следующей схеме:​​​​​​​ 

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